[Pkg-puppet-devel] [SCM] Puppet packaging for Debian branch, upstream, updated. 0.25.5-639-g8f94f35
Markus Roberts
Markus at reality.com
Wed Jul 14 10:37:27 UTC 2010
The following commit has been merged in the upstream branch:
commit 3180b9d9b2c844dade1d361326600f7001ec66dd
Author: Markus Roberts <Markus at reality.com>
Date: Fri Jul 9 18:12:17 2010 -0700
Code smell: Two space indentation
Replaced 106806 occurances of ^( +)(.*$) with
The ruby community almost universally (i.e. everyone but Luke, Markus, and the other eleven people
who learned ruby in the 1900s) uses two-space indentation.
3 Examples:
The code:
end
# Tell getopt which arguments are valid
def test_get_getopt_args
element = Setting.new :name => "foo", :desc => "anything", :settings => Puppet::Util::Settings.new
assert_equal([["--foo", GetoptLong::REQUIRED_ARGUMENT]], element.getopt_args, "Did not produce appropriate getopt args")
becomes:
end
# Tell getopt which arguments are valid
def test_get_getopt_args
element = Setting.new :name => "foo", :desc => "anything", :settings => Puppet::Util::Settings.new
assert_equal([["--foo", GetoptLong::REQUIRED_ARGUMENT]], element.getopt_args, "Did not produce appropriate getopt args")
The code:
assert_equal(str, val)
assert_instance_of(Float, result)
end
# Now test it with a passed object
becomes:
assert_equal(str, val)
assert_instance_of(Float, result)
end
# Now test it with a passed object
The code:
end
assert_nothing_raised do
klass[:Yay] = "boo"
klass["Cool"] = :yayness
end
becomes:
end
assert_nothing_raised do
klass[:Yay] = "boo"
klass["Cool"] = :yayness
end
diff --git a/autotest/discover.rb b/autotest/discover.rb
index 528f6cc..0ac5637 100644
--- a/autotest/discover.rb
+++ b/autotest/discover.rb
@@ -1,9 +1,9 @@
require 'autotest'
Autotest.add_discovery do
- "rspec"
+ "rspec"
end
Autotest.add_discovery do
- "puppet"
+ "puppet"
end
diff --git a/autotest/puppet_rspec.rb b/autotest/puppet_rspec.rb
index 1504d45..eda9cb5 100644
--- a/autotest/puppet_rspec.rb
+++ b/autotest/puppet_rspec.rb
@@ -2,50 +2,50 @@ require 'autotest'
require 'autotest/rspec'
Autotest.add_hook :initialize do |at|
- at.clear_mappings
-
- # the libraries under lib/puppet
- at.add_mapping(%r{^lib/puppet/(.*)\.rb$}) { |filename, m|
- at.files_matching %r!spec/(unit|integration)/#{m[1]}.rb!
- }
-
- # the actual spec files themselves
- at.add_mapping(%r{^spec/(unit|integration)/.*\.rb$}) { |filename, _|
- filename
- }
-
- # force a complete re-run for all of these:
-
- # main puppet lib
- at.add_mapping(%r{^lib/puppet\.rb$}) { |filename, _|
- at.files_matching %r{spec/(unit|integration)/.*\.rb}
- }
-
- # the spec_helper
- at.add_mapping(%r{^spec/spec_helper\.rb$}) { |filename, _|
- at.files_matching %r{spec/(unit|integration)/.*\.rb}
- }
-
- # the puppet test libraries
- at.add_mapping(%r{^test/lib/puppettest/.*}) { |filename, _|
- at.files_matching %r{spec/(unit|integration)/.*\.rb}
- }
-
- # the puppet spec libraries
- at.add_mapping(%r{^spec/lib/spec.*}) { |filename, _|
- at.files_matching %r{spec/(unit|integration)/.*\.rb}
- }
-
- # the monkey patches for rspec
- at.add_mapping(%r{^spec/lib/monkey_patches/.*}) { |filename, _|
- at.files_matching %r{spec/(unit|integration)/.*\.rb}
- }
+ at.clear_mappings
+
+ # the libraries under lib/puppet
+ at.add_mapping(%r{^lib/puppet/(.*)\.rb$}) { |filename, m|
+ at.files_matching %r!spec/(unit|integration)/#{m[1]}.rb!
+ }
+
+ # the actual spec files themselves
+ at.add_mapping(%r{^spec/(unit|integration)/.*\.rb$}) { |filename, _|
+ filename
+ }
+
+ # force a complete re-run for all of these:
+
+ # main puppet lib
+ at.add_mapping(%r{^lib/puppet\.rb$}) { |filename, _|
+ at.files_matching %r{spec/(unit|integration)/.*\.rb}
+ }
+
+ # the spec_helper
+ at.add_mapping(%r{^spec/spec_helper\.rb$}) { |filename, _|
+ at.files_matching %r{spec/(unit|integration)/.*\.rb}
+ }
+
+ # the puppet test libraries
+ at.add_mapping(%r{^test/lib/puppettest/.*}) { |filename, _|
+ at.files_matching %r{spec/(unit|integration)/.*\.rb}
+ }
+
+ # the puppet spec libraries
+ at.add_mapping(%r{^spec/lib/spec.*}) { |filename, _|
+ at.files_matching %r{spec/(unit|integration)/.*\.rb}
+ }
+
+ # the monkey patches for rspec
+ at.add_mapping(%r{^spec/lib/monkey_patches/.*}) { |filename, _|
+ at.files_matching %r{spec/(unit|integration)/.*\.rb}
+ }
end
# a place for overrides when necessary.
class Autotest::PuppetRspec < Autotest::Rspec
- def spec_commands
- ENV["AUTOTEST"] = "true"
- ENV["PATH"].split(File::PATH_SEPARATOR).collect { |dir| File.join(dir, "spec") }
- end
+ def spec_commands
+ ENV["AUTOTEST"] = "true"
+ ENV["PATH"].split(File::PATH_SEPARATOR).collect { |dir| File.join(dir, "spec") }
+ end
end
diff --git a/autotest/rspec.rb b/autotest/rspec.rb
index 0c6334d..f97e966 100644
--- a/autotest/rspec.rb
+++ b/autotest/rspec.rb
@@ -1,74 +1,74 @@
require 'autotest'
Autotest.add_hook :initialize do |at|
- at.clear_mappings
- # watch out: Ruby bug (1.8.6):
- # %r{/} != /\//
- at.add_mapping(%r{^spec/.*\.rb$}) { |filename, _|
- filename
- }
- at.add_mapping(%r{^lib/(.*)\.rb$}) { |_, m|
- ["spec/#{m[1]}_spec.rb"]
- }
- at.add_mapping(%r{^spec/(spec_helper|shared/.*)\.rb$}) {
- at.files_matching %r{^spec/.*_spec\.rb$}
- }
+ at.clear_mappings
+ # watch out: Ruby bug (1.8.6):
+ # %r{/} != /\//
+ at.add_mapping(%r{^spec/.*\.rb$}) { |filename, _|
+ filename
+ }
+ at.add_mapping(%r{^lib/(.*)\.rb$}) { |_, m|
+ ["spec/#{m[1]}_spec.rb"]
+ }
+ at.add_mapping(%r{^spec/(spec_helper|shared/.*)\.rb$}) {
+ at.files_matching %r{^spec/.*_spec\.rb$}
+ }
end
class RspecCommandError < StandardError; end
class Autotest::Rspec < Autotest
- def initialize
- super
+ def initialize
+ super
- self.failed_results_re = /^\d+\)\n(?:\e\[\d*m)?(?:.*?Error in )?'([^\n]*)'(?: FAILED)?(?:\e\[\d*m)?\n(.*?)\n\n/m
- self.completed_re = /\Z/ # FIX: some sort of summary line at the end?
- end
+ self.failed_results_re = /^\d+\)\n(?:\e\[\d*m)?(?:.*?Error in )?'([^\n]*)'(?: FAILED)?(?:\e\[\d*m)?\n(.*?)\n\n/m
+ self.completed_re = /\Z/ # FIX: some sort of summary line at the end?
+ end
- def consolidate_failures(failed)
- filters = Hash.new { |h,k| h[k] = [] }
- failed.each do |spec, failed_trace|
- if f = test_files_for(failed).find { |f| failed_trace =~ Regexp.new(f) }
- filters[f] << spec
- break
- end
- end
- filters
+ def consolidate_failures(failed)
+ filters = Hash.new { |h,k| h[k] = [] }
+ failed.each do |spec, failed_trace|
+ if f = test_files_for(failed).find { |f| failed_trace =~ Regexp.new(f) }
+ filters[f] << spec
+ break
+ end
end
+ filters
+ end
- def make_test_cmd(files_to_test)
- "#{ruby} -S #{spec_command} #{add_options_if_present} #{files_to_test.keys.flatten.join(' ')}"
- end
+ def make_test_cmd(files_to_test)
+ "#{ruby} -S #{spec_command} #{add_options_if_present} #{files_to_test.keys.flatten.join(' ')}"
+ end
- def add_options_if_present
- File.exist?("spec/spec.opts") ? "-O spec/spec.opts " : ""
- end
+ def add_options_if_present
+ File.exist?("spec/spec.opts") ? "-O spec/spec.opts " : ""
+ end
- # Finds the proper spec command to use. Precendence is set in the
- # lazily-evaluated method spec_commands. Alias + Override that in
- # ~/.autotest to provide a different spec command then the default
- # paths provided.
- def spec_command(separator=File::ALT_SEPARATOR)
- unless defined?(@spec_command)
- @spec_command = spec_commands.find { |cmd| File.exists? cmd }
+ # Finds the proper spec command to use. Precendence is set in the
+ # lazily-evaluated method spec_commands. Alias + Override that in
+ # ~/.autotest to provide a different spec command then the default
+ # paths provided.
+ def spec_command(separator=File::ALT_SEPARATOR)
+ unless defined?(@spec_command)
+ @spec_command = spec_commands.find { |cmd| File.exists? cmd }
- raise RspecCommandError, "No spec command could be found!" unless @spec_command
+ raise RspecCommandError, "No spec command could be found!" unless @spec_command
- @spec_command.gsub! File::SEPARATOR, separator if separator
- end
- @spec_command
+ @spec_command.gsub! File::SEPARATOR, separator if separator
end
+ @spec_command
+ end
- # Autotest will look for spec commands in the following
- # locations, in this order:
- #
- # * bin/spec
- # * default spec bin/loader installed in Rubygems
- def spec_commands
- [
- File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'bin', 'spec')),
- File.join(Config::CONFIG['bindir'], 'spec')
- ]
- end
+ # Autotest will look for spec commands in the following
+ # locations, in this order:
+ #
+ # * bin/spec
+ # * default spec bin/loader installed in Rubygems
+ def spec_commands
+ [
+ File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'bin', 'spec')),
+ File.join(Config::CONFIG['bindir'], 'spec')
+ ]
+ end
end
diff --git a/autotest/watcher.rb b/autotest/watcher.rb
index 99a7d1b..9f89a44 100644
--- a/autotest/watcher.rb
+++ b/autotest/watcher.rb
@@ -2,137 +2,137 @@ ENV["WATCHR"] = "1"
ENV['AUTOTEST'] = 'true'
def run_comp(cmd)
- puts cmd
- results = []
- old_sync = $stdout.sync
- $stdout.sync = true
- line = []
- begin
- open("| #{cmd}", "r") do |f|
- until f.eof? do
- c = f.getc
- putc c
- line << c
- if c == ?\n
- results << if RUBY_VERSION >= "1.9" then
- line.join
- else
- line.pack "c*"
- end
- line.clear
- end
- end
+ puts cmd
+ results = []
+ old_sync = $stdout.sync
+ $stdout.sync = true
+ line = []
+ begin
+ open("| #{cmd}", "r") do |f|
+ until f.eof? do
+ c = f.getc
+ putc c
+ line << c
+ if c == ?\n
+ results << if RUBY_VERSION >= "1.9" then
+ line.join
+ else
+ line.pack "c*"
+ end
+ line.clear
end
- ensure
- $stdout.sync = old_sync
+ end
end
- results.join
+ ensure
+ $stdout.sync = old_sync
+ end
+ results.join
end
def clear
- #system("clear")
+ #system("clear")
end
def growl(message, status)
- # Strip the color codes
- message.gsub!(/\[\d+m/, '')
-
- growlnotify = `which growlnotify`.chomp
- return if growlnotify.empty?
- title = "Watchr Test Results"
- image = status == :pass ? "autotest/images/pass.png" : "autotest/images/fail.png"
- options = "-w -n Watchr --image '#{File.expand_path(image)}' -m '#{message}' '#{title}'"
- system %(#{growlnotify} #{options} &)
+ # Strip the color codes
+ message.gsub!(/\[\d+m/, '')
+
+ growlnotify = `which growlnotify`.chomp
+ return if growlnotify.empty?
+ title = "Watchr Test Results"
+ image = status == :pass ? "autotest/images/pass.png" : "autotest/images/fail.png"
+ options = "-w -n Watchr --image '#{File.expand_path(image)}' -m '#{message}' '#{title}'"
+ system %(#{growlnotify} #{options} &)
end
def file2specs(file)
- %w{spec/unit spec/integration}.collect { |d|
- file.sub('lib/puppet', d)
- }.find_all { |f|
- File.exist?(f)
- }
+ %w{spec/unit spec/integration}.collect { |d|
+ file.sub('lib/puppet', d)
+ }.find_all { |f|
+ File.exist?(f)
+ }
end
def file2test(file)
- result = file.sub('lib/puppet', 'test')
- return nil unless File.exist?(result)
- result
+ result = file.sub('lib/puppet', 'test')
+ return nil unless File.exist?(result)
+ result
end
def run_spec(command)
- clear
- result = run_comp(command).split("\n").last
- status = result.include?('0 failures') ? :pass : :fail
- growl result, status
+ clear
+ result = run_comp(command).split("\n").last
+ status = result.include?('0 failures') ? :pass : :fail
+ growl result, status
end
def run_test(command)
- clear
- result = run_comp(command).split("\n").last
- status = result.include?('0 failures, 0 errors') ? :pass : :fail
- growl result.split("\n").last rescue nil
+ clear
+ result = run_comp(command).split("\n").last
+ status = result.include?('0 failures, 0 errors') ? :pass : :fail
+ growl result.split("\n").last rescue nil
end
def run_test_file(file)
- run_test(%Q(#{file}))
+ run_test(%Q(#{file}))
end
def run_spec_files(files)
- files = Array(files)
- return if files.empty?
- opts = File.readlines('spec/spec.opts').collect { |l| l.chomp }.join(" ")
- run_spec("spec #{files.join(' ')}")
+ files = Array(files)
+ return if files.empty?
+ opts = File.readlines('spec/spec.opts').collect { |l| l.chomp }.join(" ")
+ run_spec("spec #{files.join(' ')}")
end
def run_all_tests
- run_test("rake unit")
+ run_test("rake unit")
end
def run_all_specs
- run_test("rake spec")
+ run_test("rake spec")
end
def run_suite
- run_all_tests
- run_all_specs
+ run_all_tests
+ run_all_specs
end
watch('spec/spec_helper.rb') { run_all_specs }
watch(%r{^spec/(unit|integration)/.*\.rb$}) { |md| run_spec_files(md[0]) }
watch(%r{^lib/puppet/(.*)\.rb$}) { |md|
- run_spec_files(file2specs(md[0]))
- if t = file2test(md[0])
- run_test_file(t)
- end
+ run_spec_files(file2specs(md[0]))
+ if t = file2test(md[0])
+ run_test_file(t)
+ end
}
watch(%r{^spec/lib/spec.*}) { |md| run_all_specs }
watch(%r{^spec/lib/monkey_patches/.*}) { |md| run_all_specs }
watch(%r{test/.+\.rb}) { |md|
- if md[0] =~ /\/lib\//
- run_all_tests
- else
- run_test_file(md[0])
- end
+ if md[0] =~ /\/lib\//
+ run_all_tests
+ else
+ run_test_file(md[0])
+ end
}
# Ctrl-\
Signal.trap 'QUIT' do
- puts " --- Running all tests ---\n\n"
- run_suite
+ puts " --- Running all tests ---\n\n"
+ run_suite
end
@interrupted = false
# Ctrl-C
Signal.trap 'INT' do
- if @interrupted
- @wants_to_quit = true
- abort("\n")
- else
- puts "Interrupt a second time to quit; wait for rerun of tests"
- @interrupted = true
- Kernel.sleep 1.5
- # raise Interrupt, nil # let the run loop catch it
- run_suite
- end
+ if @interrupted
+ @wants_to_quit = true
+ abort("\n")
+ else
+ puts "Interrupt a second time to quit; wait for rerun of tests"
+ @interrupted = true
+ Kernel.sleep 1.5
+ # raise Interrupt, nil # let the run loop catch it
+ run_suite
+ end
end
diff --git a/examples/modules/sample-module/lib/puppet/parser/functions/hostname_to_dn.rb b/examples/modules/sample-module/lib/puppet/parser/functions/hostname_to_dn.rb
index fdeeff1..34ab280 100644
--- a/examples/modules/sample-module/lib/puppet/parser/functions/hostname_to_dn.rb
+++ b/examples/modules/sample-module/lib/puppet/parser/functions/hostname_to_dn.rb
@@ -30,7 +30,7 @@
# See: http://reductivelabs.com/trac/puppet/wiki/WritingYourOwnFunctions
module Puppet::Parser::Functions
- newfunction(:hostname_to_dn, :type => :rvalue, :doc => "Given 'foo.bar.com', return 'dc=foo,dc=bar,dc=com'.") do |args|
- args[0].split(/\./).map do |s| "dc=#{s}" end.join(",")
- end
+ newfunction(:hostname_to_dn, :type => :rvalue, :doc => "Given 'foo.bar.com', return 'dc=foo,dc=bar,dc=com'.") do |args|
+ args[0].split(/\./).map do |s| "dc=#{s}" end.join(",")
+ end
end
diff --git a/ext/extlookup.rb b/ext/extlookup.rb
index 24b161e..b72fc12 100644
--- a/ext/extlookup.rb
+++ b/ext/extlookup.rb
@@ -80,102 +80,102 @@
require 'csv'
module Puppet::Parser::Functions
- newfunction(:extlookup, :type => :rvalue) do |args|
- key = args[0]
- default = "_ExtUNSET_"
- datafile = "_ExtUNSET_"
-
- default = args[1] if args[1]
- datafile = args[2] if args[2]
-
- extlookup_datadir = lookupvar('extlookup_datadir')
- extlookup_precedence = Array.new
-
- # precedence values can have variables embedded in them
- # in the form %{fqdn}, you could for example do
- #
- # $extlookup_precedence = ["hosts/%{fqdn}", "common"]
- #
- # this will result in /path/to/extdata/hosts/your.box.com.csv
- # being searched.
- #
- # we parse the precedence here because the best place to specify
- # it would be in site.pp but site.pp is only evaluated at startup
- # so $fqdn etc would have no meaning there, this way it gets evaluated
- # each run and has access to the right variables for that run
- lookupvar('extlookup_precedence').each do |prec|
- while prec =~ /%\{(.+?)\}/
- prec.gsub!(/%\{#{$1}\}/, lookupvar($1))
- end
+ newfunction(:extlookup, :type => :rvalue) do |args|
+ key = args[0]
+ default = "_ExtUNSET_"
+ datafile = "_ExtUNSET_"
+
+ default = args[1] if args[1]
+ datafile = args[2] if args[2]
+
+ extlookup_datadir = lookupvar('extlookup_datadir')
+ extlookup_precedence = Array.new
+
+ # precedence values can have variables embedded in them
+ # in the form %{fqdn}, you could for example do
+ #
+ # $extlookup_precedence = ["hosts/%{fqdn}", "common"]
+ #
+ # this will result in /path/to/extdata/hosts/your.box.com.csv
+ # being searched.
+ #
+ # we parse the precedence here because the best place to specify
+ # it would be in site.pp but site.pp is only evaluated at startup
+ # so $fqdn etc would have no meaning there, this way it gets evaluated
+ # each run and has access to the right variables for that run
+ lookupvar('extlookup_precedence').each do |prec|
+ while prec =~ /%\{(.+?)\}/
+ prec.gsub!(/%\{#{$1}\}/, lookupvar($1))
+ end
+
+ extlookup_precedence << prec
+ end
- extlookup_precedence << prec
- end
+ datafiles = Array.new
- datafiles = Array.new
+ # if we got a custom data file, put it first in the array of search files
+ if datafile != ""
+ datafiles << extlookup_datadir + "/#{datafile}.csv" if File.exists?(extlookup_datadir + "/#{datafile}.csv")
+ end
- # if we got a custom data file, put it first in the array of search files
- if datafile != ""
- datafiles << extlookup_datadir + "/#{datafile}.csv" if File.exists?(extlookup_datadir + "/#{datafile}.csv")
- end
+ extlookup_precedence.each do |d|
+ datafiles << extlookup_datadir + "/#{d}.csv"
+ end
- extlookup_precedence.each do |d|
- datafiles << extlookup_datadir + "/#{d}.csv"
- end
+ desired = "_ExtUNSET_"
+
+ datafiles.each do |file|
+ parser.watch_file(file) if File.exists?(file)
+
+ if desired == "_ExtUNSET_"
+ if File.exists?(file)
+ result = CSV.read(file).find_all do |r|
+ r[0] == key
+ end
- desired = "_ExtUNSET_"
-
- datafiles.each do |file|
- parser.watch_file(file) if File.exists?(file)
-
- if desired == "_ExtUNSET_"
- if File.exists?(file)
- result = CSV.read(file).find_all do |r|
- r[0] == key
- end
-
-
- # return just the single result if theres just one,
- # else take all the fields in the csv and build an array
- if result.length > 0
- if result[0].length == 2
- val = result[0][1].to_s
-
- # parse %{}'s in the CSV into local variables using lookupvar()
- while val =~ /%\{(.+?)\}/
- val.gsub!(/%\{#{$1}\}/, lookupvar($1))
- end
-
- desired = val
- elsif result[0].length > 1
- length = result[0].length
- cells = result[0][1,length]
-
- # Individual cells in a CSV result are a weird data type and throws
- # puppets yaml parsing, so just map it all to plain old strings
- desired = cells.map do |c|
- # parse %{}'s in the CSV into local variables using lookupvar()
- while c =~ /%\{(.+?)\}/
- c.gsub!(/%\{#{$1}\}/, lookupvar($1))
- end
-
- c.to_s
- end
- end
- end
+
+ # return just the single result if theres just one,
+ # else take all the fields in the csv and build an array
+ if result.length > 0
+ if result[0].length == 2
+ val = result[0][1].to_s
+
+ # parse %{}'s in the CSV into local variables using lookupvar()
+ while val =~ /%\{(.+?)\}/
+ val.gsub!(/%\{#{$1}\}/, lookupvar($1))
+ end
+
+ desired = val
+ elsif result[0].length > 1
+ length = result[0].length
+ cells = result[0][1,length]
+
+ # Individual cells in a CSV result are a weird data type and throws
+ # puppets yaml parsing, so just map it all to plain old strings
+ desired = cells.map do |c|
+ # parse %{}'s in the CSV into local variables using lookupvar()
+ while c =~ /%\{(.+?)\}/
+ c.gsub!(/%\{#{$1}\}/, lookupvar($1))
end
- end
- end
- # don't accidently return nil's and such rather throw a parse error
- if desired == "_ExtUNSET_" && default == "_ExtUNSET_"
- raise Puppet::ParseError, "No match found for '#{key}' in any data file during extlookup()"
- else
- desired = default if desired == "_ExtUNSET_"
+ c.to_s
+ end
+ end
+ end
end
+ end
+ end
- desired
+ # don't accidently return nil's and such rather throw a parse error
+ if desired == "_ExtUNSET_" && default == "_ExtUNSET_"
+ raise Puppet::ParseError, "No match found for '#{key}' in any data file during extlookup()"
+ else
+ desired = default if desired == "_ExtUNSET_"
end
+
+ desired
+ end
end
# vi:tabstop=4:expandtab:ai
diff --git a/ext/nagios/check_puppet.rb b/ext/nagios/check_puppet.rb
index 4873c03..85807f1 100755
--- a/ext/nagios/check_puppet.rb
+++ b/ext/nagios/check_puppet.rb
@@ -6,114 +6,114 @@ include Sys
class CheckPuppet
- VERSION = '0.1'
- script_name = File.basename($0)
+ VERSION = '0.1'
+ script_name = File.basename($0)
- # default options
- OPTIONS = {
- :statefile => "/var/lib/puppet/state/state.yaml",
- :process => "puppetd",
- :interval => 30,
- }
+ # default options
+ OPTIONS = {
+ :statefile => "/var/lib/puppet/state/state.yaml",
+ :process => "puppetd",
+ :interval => 30,
+ }
- o = OptionParser.new do |o|
- o.set_summary_indent(' ')
- o.banner = "Usage: #{script_name} [OPTIONS]"
- o.define_head "The check_puppet Nagios plug-in checks that specified Puppet process is running and the state file is no older than specified interval."
- o.separator ""
- o.separator "Mandatory arguments to long options are mandatory for short options too."
+ o = OptionParser.new do |o|
+ o.set_summary_indent(' ')
+ o.banner = "Usage: #{script_name} [OPTIONS]"
+ o.define_head "The check_puppet Nagios plug-in checks that specified Puppet process is running and the state file is no older than specified interval."
+ o.separator ""
+ o.separator "Mandatory arguments to long options are mandatory for short options too."
- o.on(
- "-s", "--statefile=statefile", String, "The state file",
+ o.on(
+ "-s", "--statefile=statefile", String, "The state file",
- "Default: #{OPTIONS[:statefile]}") { |OPTIONS[:statefile]| }
+ "Default: #{OPTIONS[:statefile]}") { |OPTIONS[:statefile]| }
- o.on(
- "-p", "--process=processname", String, "The process to check",
+ o.on(
+ "-p", "--process=processname", String, "The process to check",
- "Default: #{OPTIONS[:process]}") { |OPTIONS[:process]| }
+ "Default: #{OPTIONS[:process]}") { |OPTIONS[:process]| }
- o.on(
- "-i", "--interval=value", Integer,
+ o.on(
+ "-i", "--interval=value", Integer,
- "Default: #{OPTIONS[:interval]} minutes") { |OPTIONS[:interval]| }
+ "Default: #{OPTIONS[:interval]} minutes") { |OPTIONS[:interval]| }
- o.separator ""
- o.on_tail("-h", "--help", "Show this help message.") do
- puts o
- exit
- end
+ o.separator ""
+ o.on_tail("-h", "--help", "Show this help message.") do
+ puts o
+ exit
+ end
+
+ o.parse!(ARGV)
+ end
- o.parse!(ARGV)
+ def check_proc
+
+ unless ProcTable.ps.find { |p| p.name == OPTIONS[:process]}
+ @proc = 2
+ else
+ @proc = 0
end
- def check_proc
+ end
+
+ def check_state
- unless ProcTable.ps.find { |p| p.name == OPTIONS[:process]}
- @proc = 2
- else
- @proc = 0
- end
+ # Set variables
+ curt = Time.now
+ intv = OPTIONS[:interval] * 60
+ # Check file time
+ begin
+ @modt = File.mtime("#{OPTIONS[:statefile]}")
+ rescue
+ @file = 3
end
- def check_state
+ diff = (curt - @modt).to_i
- # Set variables
- curt = Time.now
- intv = OPTIONS[:interval] * 60
+ if diff > intv
+ @file = 2
+ else
+ @file = 0
+ end
- # Check file time
- begin
- @modt = File.mtime("#{OPTIONS[:statefile]}")
- rescue
- @file = 3
- end
+ end
- diff = (curt - @modt).to_i
+ def output_status
- if diff > intv
- @file = 2
- else
- @file = 0
- end
+ case @file
+ when 0
+ state = "state file status okay updated on " + @modt.strftime("%m/%d/%Y at %H:%M:%S")
+ when 2
+ state = "state fille is not up to date and is older than #{OPTIONS[:interval]} minutes"
+ when 3
+ state = "state file status unknown"
+ end
+ case @proc
+ when 0
+ process = "process #{OPTIONS[:process]} is running"
+ when 2
+ process = "process #{OPTIONS[:process]} is not running"
end
- def output_status
-
- case @file
- when 0
- state = "state file status okay updated on " + @modt.strftime("%m/%d/%Y at %H:%M:%S")
- when 2
- state = "state fille is not up to date and is older than #{OPTIONS[:interval]} minutes"
- when 3
- state = "state file status unknown"
- end
-
- case @proc
- when 0
- process = "process #{OPTIONS[:process]} is running"
- when 2
- process = "process #{OPTIONS[:process]} is not running"
- end
-
- case @proc or @file
- when 0
- status = "OK"
- exitcode = 0
- when 2
- status = "CRITICAL"
- exitcode = 2
- when 3
- status = "UNKNOWN"
- exitcide = 3
- end
-
- puts "PUPPET #{status}: #{process}, #{state}"
- exit(exitcode)
+ case @proc or @file
+ when 0
+ status = "OK"
+ exitcode = 0
+ when 2
+ status = "CRITICAL"
+ exitcode = 2
+ when 3
+ status = "UNKNOWN"
+ exitcide = 3
end
+
+ puts "PUPPET #{status}: #{process}, #{state}"
+ exit(exitcode)
+ end
end
cp = CheckPuppet.new
diff --git a/ext/puppetlisten/puppetlisten.rb b/ext/puppetlisten/puppetlisten.rb
index fd187c8..9c1709c 100755
--- a/ext/puppetlisten/puppetlisten.rb
+++ b/ext/puppetlisten/puppetlisten.rb
@@ -25,24 +25,24 @@ ctx.ca_file = Puppet[:localcacert]
allowed_servers = Array.new
runner = false;
File.open(Puppet[:authconfig]).each do |line|
- case line
- when /^\s*#/: next # skip comments
- when /^\s*$/: next # skip blank lines
- when /\[puppetrunner\]/: # puppetrunner section
- runner=true
- when /^\s*(\w+)\s+(.+)$/:
- var = $1
- value = $2
- case var
- when "allow":
- value.split(/\s*,\s*/).each { |val|
- allowed_servers << val
- puts "allowing #{val} access"
- } if runner==true
- end
- else
- runner=false
+ case line
+ when /^\s*#/: next # skip comments
+ when /^\s*$/: next # skip blank lines
+ when /\[puppetrunner\]/: # puppetrunner section
+ runner=true
+ when /^\s*(\w+)\s+(.+)$/:
+ var = $1
+ value = $2
+ case var
+ when "allow":
+ value.split(/\s*,\s*/).each { |val|
+ allowed_servers << val
+ puts "allowing #{val} access"
+ } if runner==true
end
+ else
+ runner=false
+ end
end
# be a daemon
@@ -50,27 +50,27 @@ sock = TCPServer.new(port)
ssls = OpenSSL::SSL::SSLServer.new(sock, ctx)
loop do
- begin
- ns = ssls.accept # start SSL session
- af, port, host, ip = ns.peeraddr
- print "connection from #{host+"("+ip+")"} "
- if allowed_servers.include?(host)
- #TODO add support for tags and other command line arguments
- puts "accepted"
- ns.puts "Executing #{cmd} on #{Facter.fqdn}.\n*******OUTPUT********\n\n"
- IO.popen(cmd) do |f|
- while line = f.gets
- ns.puts line
- end
- end
- ns.puts "\n*********DONE**********"
- else
- ns.puts "denied\n"
- puts "denied"
+ begin
+ ns = ssls.accept # start SSL session
+ af, port, host, ip = ns.peeraddr
+ print "connection from #{host+"("+ip+")"} "
+ if allowed_servers.include?(host)
+ #TODO add support for tags and other command line arguments
+ puts "accepted"
+ ns.puts "Executing #{cmd} on #{Facter.fqdn}.\n*******OUTPUT********\n\n"
+ IO.popen(cmd) do |f|
+ while line = f.gets
+ ns.puts line
end
- ns.close
- rescue
- ns.close
- next
+ end
+ ns.puts "\n*********DONE**********"
+ else
+ ns.puts "denied\n"
+ puts "denied"
end
+ ns.close
+ rescue
+ ns.close
+ next
+ end
end
diff --git a/ext/puppetlisten/puppetrun.rb b/ext/puppetlisten/puppetrun.rb
index 7aa0919..2fe31b7 100755
--- a/ext/puppetlisten/puppetrun.rb
+++ b/ext/puppetlisten/puppetrun.rb
@@ -6,10 +6,10 @@
port = 8139
if ARGV[0].nil?
- warn "Usage: hostname to run against"
- exit 1
+ warn "Usage: hostname to run against"
+ exit 1
else
- host = ARGV[0]
+ host = ARGV[0]
end
require 'puppet/sslcertificates/support'
@@ -33,7 +33,7 @@ ssl.connect # start SSL session
ssl.sync_close = true # if true the underlying socket will be
# closed in SSLSocket#close. (default: false)
while (line = ssl.gets)
- puts line
+ puts line
end
ssl.close
diff --git a/ext/puppetstoredconfigclean.rb b/ext/puppetstoredconfigclean.rb
index 4d7350c..34dd72f 100644
--- a/ext/puppetstoredconfigclean.rb
+++ b/ext/puppetstoredconfigclean.rb
@@ -11,42 +11,42 @@ require 'getoptlong'
config = '/etc/puppet/puppet.conf'
def printusage(error_code)
- puts "Usage: #{$0} [ list of hostnames as stored in hosts table ]"
- puts "\n Options:"
- puts "--config <puppet config file>"
- exit(error_code)
+ puts "Usage: #{$0} [ list of hostnames as stored in hosts table ]"
+ puts "\n Options:"
+ puts "--config <puppet config file>"
+ exit(error_code)
end
- opts = GetoptLong.new(
+ opts = GetoptLong.new(
- [ "--config", "-c", GetoptLong::REQUIRED_ARGUMENT ],
- [ "--help", "-h", GetoptLong::NO_ARGUMENT ],
- [ "--usage", "-u", GetoptLong::NO_ARGUMENT ],
+ [ "--config", "-c", GetoptLong::REQUIRED_ARGUMENT ],
+ [ "--help", "-h", GetoptLong::NO_ARGUMENT ],
+ [ "--usage", "-u", GetoptLong::NO_ARGUMENT ],
- [ "--version", "-v", GetoptLong::NO_ARGUMENT ]
+ [ "--version", "-v", GetoptLong::NO_ARGUMENT ]
)
begin
- opts.each do |opt, arg|
- case opt
- when "--config"
- config = arg
+ opts.each do |opt, arg|
+ case opt
+ when "--config"
+ config = arg
- when "--help"
- printusage(0)
+ when "--help"
+ printusage(0)
- when "--usage"
- printusage(0)
+ when "--usage"
+ printusage(0)
- when "--version"
- puts "#{Puppet.version}"
- exit
- end
+ when "--version"
+ puts "#{Puppet.version}"
+ exit
end
+ end
rescue GetoptLong::InvalidOption => detail
- $stderr.puts "Try '#{$0} --help'"
- exit(1)
+ $stderr.puts "Try '#{$0} --help'"
+ exit(1)
end
printusage(1) unless ARGV.size > 0
@@ -60,20 +60,20 @@ adapter = pm_conf[:dbadapter]
args = {:adapter => adapter, :log_level => pm_conf[:rails_loglevel]}
case adapter
- when "sqlite3"
- args[:dbfile] = pm_conf[:dblocation]
- when "mysql", "postgresql"
- args[:host] = pm_conf[:dbserver] unless pm_conf[:dbserver].to_s.empty?
- args[:username] = pm_conf[:dbuser] unless pm_conf[:dbuser].to_s.empty?
- args[:password] = pm_conf[:dbpassword] unless pm_conf[:dbpassword].to_s.empty?
- args[:database] = pm_conf[:dbname] unless pm_conf[:dbname].to_s.empty?
- args[:port] = pm_conf[:dbport] unless pm_conf[:dbport].to_s.empty?
- socket = pm_conf[:dbsocket]
- args[:socket] = socket unless socket.to_s.empty?
- connections = pm_conf[:dbconnections].to_i
- args[:pool] = connections if connections > 0
- else
- raise ArgumentError, "Invalid db adapter #{adapter}"
+ when "sqlite3"
+ args[:dbfile] = pm_conf[:dblocation]
+ when "mysql", "postgresql"
+ args[:host] = pm_conf[:dbserver] unless pm_conf[:dbserver].to_s.empty?
+ args[:username] = pm_conf[:dbuser] unless pm_conf[:dbuser].to_s.empty?
+ args[:password] = pm_conf[:dbpassword] unless pm_conf[:dbpassword].to_s.empty?
+ args[:database] = pm_conf[:dbname] unless pm_conf[:dbname].to_s.empty?
+ args[:port] = pm_conf[:dbport] unless pm_conf[:dbport].to_s.empty?
+ socket = pm_conf[:dbsocket]
+ args[:socket] = socket unless socket.to_s.empty?
+ connections = pm_conf[:dbconnections].to_i
+ args[:pool] = connections if connections > 0
+ else
+ raise ArgumentError, "Invalid db adapter #{adapter}"
end
args[:database] = "puppet" unless not args[:database].to_s.empty?
@@ -81,13 +81,13 @@ args[:database] = "puppet" unless not args[:database].to_s.empty?
ActiveRecord::Base.establish_connection(args)
ARGV.each { |hostname|
- if @host = Puppet::Rails::Host.find_by_name(hostname.strip)
- print "Killing #{hostname}..."
- $stdout.flush
- @host.destroy
- puts "done."
- else
- puts "Can't find host #{hostname}."
- end
+ if @host = Puppet::Rails::Host.find_by_name(hostname.strip)
+ print "Killing #{hostname}..."
+ $stdout.flush
+ @host.destroy
+ puts "done."
+ else
+ puts "Can't find host #{hostname}."
+ end
}
exit 0
diff --git a/ext/pure_ruby_dsl/dsl_test.rb b/ext/pure_ruby_dsl/dsl_test.rb
index 6eff298..97bb7cc 100644
--- a/ext/pure_ruby_dsl/dsl_test.rb
+++ b/ext/pure_ruby_dsl/dsl_test.rb
@@ -1,7 +1,7 @@
hostclass "foobar" do
- notify "this is a test", "loglevel" => "warning"
+ notify "this is a test", "loglevel" => "warning"
end
node "default" do
- acquire "foobar"
+ acquire "foobar"
end
diff --git a/ext/regexp_nodes/regexp_nodes.rb b/ext/regexp_nodes/regexp_nodes.rb
index 7633e5c..e234985 100644
--- a/ext/regexp_nodes/regexp_nodes.rb
+++ b/ext/regexp_nodes/regexp_nodes.rb
@@ -58,129 +58,129 @@ WORKINGDIR = Dir.pwd
# and a special version of to_yaml
class ExternalNode
- # Make these instance variables get/set-able with eponymous methods
- attr_accessor :classes, :parameters, :hostname
-
- # initialize takes three arguments:
- # hostname:: usually passed in via ARGV[0] but it could be anything
- # classdir:: directory under WORKINGDIR to look for files named after
- # classes
- # parameterdir:: directory under WORKINGDIR to look for directories to set
- # parameters
- def initialize(hostname, classdir = 'classes/', parameterdir = 'parameters/')
- # instance variables that contain the lists of classes and parameters
- @hostname
- @classes = Set.new ["baseclass"]
- @parameters = Hash.new("unknown") # sets a default value of "unknown"
-
- self.parse_argv(hostname)
- self.match_classes(WORKINGDIR + "/#{classdir}")
- self.match_parameters(WORKINGDIR + "/#{parameterdir}")
+ # Make these instance variables get/set-able with eponymous methods
+ attr_accessor :classes, :parameters, :hostname
+
+ # initialize takes three arguments:
+ # hostname:: usually passed in via ARGV[0] but it could be anything
+ # classdir:: directory under WORKINGDIR to look for files named after
+ # classes
+ # parameterdir:: directory under WORKINGDIR to look for directories to set
+ # parameters
+ def initialize(hostname, classdir = 'classes/', parameterdir = 'parameters/')
+ # instance variables that contain the lists of classes and parameters
+ @hostname
+ @classes = Set.new ["baseclass"]
+ @parameters = Hash.new("unknown") # sets a default value of "unknown"
+
+ self.parse_argv(hostname)
+ self.match_classes(WORKINGDIR + "/#{classdir}")
+ self.match_parameters(WORKINGDIR + "/#{parameterdir}")
+ end
+
+ # private method called by initialize which sanity-checks our hostname.
+ # good candidate for overriding in a subclass if you need different checks
+ def parse_argv(hostname)
+ if hostname =~ /^([-\w]+?)\.([-\w\.]+)/ # non-greedy up to the first . is hostname
+ @hostname = $1
+ elsif hostname =~ /^([-\w]+)$/ # sometimes puppet's @name is just a name
+ @hostname = hostname
+ else
+ $LOG.fatal("didn't receive parsable hostname, got: [#{hostname}]")
+ exit(1)
end
-
- # private method called by initialize which sanity-checks our hostname.
- # good candidate for overriding in a subclass if you need different checks
- def parse_argv(hostname)
- if hostname =~ /^([-\w]+?)\.([-\w\.]+)/ # non-greedy up to the first . is hostname
- @hostname = $1
- elsif hostname =~ /^([-\w]+)$/ # sometimes puppet's @name is just a name
- @hostname = hostname
- else
- $LOG.fatal("didn't receive parsable hostname, got: [#{hostname}]")
- exit(1)
- end
+ end
+
+ # to_yaml massages a copy of the object and outputs clean yaml so we don't
+ # feed weird things back to puppet []<
+ def to_yaml
+ classes = self.classes.to_a
+ if self.parameters.empty? # otherwise to_yaml prints "parameters: {}"
+ parameters = nil
+ else
+ parameters = self.parameters
end
-
- # to_yaml massages a copy of the object and outputs clean yaml so we don't
- # feed weird things back to puppet []<
- def to_yaml
- classes = self.classes.to_a
- if self.parameters.empty? # otherwise to_yaml prints "parameters: {}"
- parameters = nil
- else
- parameters = self.parameters
- end
- ({ 'classes' => classes, 'parameters' => parameters}).to_yaml
+ ({ 'classes' => classes, 'parameters' => parameters}).to_yaml
+ end
+
+ # Private method that expects an absolute path to a file and a string to
+ # match - it returns true if the string was matched by any of the lines in
+ # the file
+ def matched_in_patternfile?(filepath, matchthis)
+
+ patternlist = []
+
+ begin
+ open(filepath).each { |l|
+ pattern = %r{#{l.chomp!}}
+ patternlist << pattern
+ $LOG.debug("appending [#{pattern}] to patternlist for [#{filepath}]")
+ }
+ rescue Exception
+ $LOG.fatal("Problem reading #{filepath}: #{$ERROR_INFO}")
+ exit(1)
end
- # Private method that expects an absolute path to a file and a string to
- # match - it returns true if the string was matched by any of the lines in
- # the file
- def matched_in_patternfile?(filepath, matchthis)
-
- patternlist = []
-
- begin
- open(filepath).each { |l|
- pattern = %r{#{l.chomp!}}
- patternlist << pattern
- $LOG.debug("appending [#{pattern}] to patternlist for [#{filepath}]")
- }
- rescue Exception
- $LOG.fatal("Problem reading #{filepath}: #{$ERROR_INFO}")
- exit(1)
- end
-
- $LOG.debug("list of patterns for #{filepath}: #{patternlist}")
+ $LOG.debug("list of patterns for #{filepath}: #{patternlist}")
- if matchthis =~ Regexp.union(patternlist)
- $LOG.debug("matched #{$~.to_s} in #{matchthis}, returning true")
- return true
-
- else # hostname didn't match anything in patternlist
- $LOG.debug("#{matchthis} unmatched, returning false")
- return nil
- end
+ if matchthis =~ Regexp.union(patternlist)
+ $LOG.debug("matched #{$~.to_s} in #{matchthis}, returning true")
+ return true
+ else # hostname didn't match anything in patternlist
+ $LOG.debug("#{matchthis} unmatched, returning false")
+ return nil
end
- # private method - takes a path to look for files, iterates through all
- # readable, regular files it finds, and matches this instance's @hostname
- # against each line; if any match, the class will be set for this node.
- def match_classes(fullpath)
- Dir.foreach(fullpath) do |patternfile|
- filepath = "#{fullpath}/#{patternfile}"
- next unless File.file?(filepath) and
- File.readable?(filepath)
- $LOG.debug("Attempting to match [#{@hostname}] in [#{filepath}]")
- if matched_in_patternfile?(filepath, at hostname)
- @classes << patternfile.to_s
- $LOG.debug("Appended #{patternfile.to_s} to classes instance variable")
- end
- end
+ end
+
+ # private method - takes a path to look for files, iterates through all
+ # readable, regular files it finds, and matches this instance's @hostname
+ # against each line; if any match, the class will be set for this node.
+ def match_classes(fullpath)
+ Dir.foreach(fullpath) do |patternfile|
+ filepath = "#{fullpath}/#{patternfile}"
+ next unless File.file?(filepath) and
+ File.readable?(filepath)
+ $LOG.debug("Attempting to match [#{@hostname}] in [#{filepath}]")
+ if matched_in_patternfile?(filepath, at hostname)
+ @classes << patternfile.to_s
+ $LOG.debug("Appended #{patternfile.to_s} to classes instance variable")
+ end
end
-
- # Parameters are handled slightly differently; we make another level of
- # directories to get the parameter name, then use the names of the files
- # contained in there for the values of those parameters.
- #
- # ex: cat /var/lib/puppet/bin/parameters/environment/production
- # ^prodweb
- # would set parameters["environment"] = "production" for prodweb001
- def match_parameters(fullpath)
- Dir.foreach(fullpath) do |parametername|
-
- filepath = "#{fullpath}/#{parametername}"
- next if File.basename(filepath) =~ /^\./ # skip over dotfiles
-
- next unless File.directory?(filepath) and
- File.readable?(filepath) # skip over non-directories
-
- $LOG.debug "Considering contents of #{filepath}"
-
- Dir.foreach("#{filepath}") do |patternfile|
- secondlevel = "#{filepath}/#{patternfile}"
- $LOG.debug "Found parameters patternfile at #{secondlevel}"
- next unless File.file?(secondlevel) and
- File.readable?(secondlevel)
- $LOG.debug("Attempting to match [#{@hostname}] in [#{secondlevel}]")
- if matched_in_patternfile?(secondlevel, @hostname)
- @parameters[ parametername.to_s ] = patternfile.to_s
- $LOG.debug("Set @parameters[#{parametername.to_s}] = #{patternfile.to_s}")
- end
- end
+ end
+
+ # Parameters are handled slightly differently; we make another level of
+ # directories to get the parameter name, then use the names of the files
+ # contained in there for the values of those parameters.
+ #
+ # ex: cat /var/lib/puppet/bin/parameters/environment/production
+ # ^prodweb
+ # would set parameters["environment"] = "production" for prodweb001
+ def match_parameters(fullpath)
+ Dir.foreach(fullpath) do |parametername|
+
+ filepath = "#{fullpath}/#{parametername}"
+ next if File.basename(filepath) =~ /^\./ # skip over dotfiles
+
+ next unless File.directory?(filepath) and
+ File.readable?(filepath) # skip over non-directories
+
+ $LOG.debug "Considering contents of #{filepath}"
+
+ Dir.foreach("#{filepath}") do |patternfile|
+ secondlevel = "#{filepath}/#{patternfile}"
+ $LOG.debug "Found parameters patternfile at #{secondlevel}"
+ next unless File.file?(secondlevel) and
+ File.readable?(secondlevel)
+ $LOG.debug("Attempting to match [#{@hostname}] in [#{secondlevel}]")
+ if matched_in_patternfile?(secondlevel, @hostname)
+ @parameters[ parametername.to_s ] = patternfile.to_s
+ $LOG.debug("Set @parameters[#{parametername.to_s}] = #{patternfile.to_s}")
end
+ end
end
+ end
end
@@ -188,22 +188,22 @@ end
# happen as we initialize a subclass
class MyExternalNode < ExternalNode
- def initialize(hostname, classdir = 'classes/', parameterdir = 'parameters/')
+ def initialize(hostname, classdir = 'classes/', parameterdir = 'parameters/')
- super
+ super
- # Set "hostclass" parameter based on hostname,
- # stripped of leading environment prefix and numeric suffix
- if @hostname =~ /^(\w*?)-?(\D+)(\d{2,3})$/
- match = Regexp.last_match
+ # Set "hostclass" parameter based on hostname,
+ # stripped of leading environment prefix and numeric suffix
+ if @hostname =~ /^(\w*?)-?(\D+)(\d{2,3})$/
+ match = Regexp.last_match
- hostclass = match[2]
- $LOG.debug("matched hostclass #{hostclass}")
- @parameters[ "hostclass" ] = hostclass
- else
- $LOG.debug("hostclass couldn't figure out class from #{@hostname}")
- end
+ hostclass = match[2]
+ $LOG.debug("matched hostclass #{hostclass}")
+ @parameters[ "hostclass" ] = hostclass
+ else
+ $LOG.debug("hostclass couldn't figure out class from #{@hostname}")
end
+ end
end
diff --git a/ext/yaml_nodes.rb b/ext/yaml_nodes.rb
index b6c191a..2174da0 100755
--- a/ext/yaml_nodes.rb
+++ b/ext/yaml_nodes.rb
@@ -39,27 +39,27 @@ BASEDIR = Dir.chdir(File.dirname(__FILE__) + "/..") { Dir.getwd }
options = {:yamldir => File.join(BASEDIR, "yaml")}
OptionParser.new do |opts|
- opts.banner = "Usage: yaml-nodes [options] <host>"
+ opts.banner = "Usage: yaml-nodes [options] <host>"
- opts.on("-y dir", "--yamldir dir", "Specify the directory with the YAML files") do |arg|
- raise "YAML directory #{arg} does not exist or is not a directory" unless FileTest.directory?(arg)
- options[:yamldir] = arg
- end
+ opts.on("-y dir", "--yamldir dir", "Specify the directory with the YAML files") do |arg|
+ raise "YAML directory #{arg} does not exist or is not a directory" unless FileTest.directory?(arg)
+ options[:yamldir] = arg
+ end
- opts.on("-h", "--help", "Print this help") do
- puts opts.help
- exit(0)
- end
+ opts.on("-h", "--help", "Print this help") do
+ puts opts.help
+ exit(0)
+ end
end.parse!
# Read in a pure yaml representation of our node.
def read_node(node)
- nodefile = File.join(YAMLDIR, "#{node}.yaml")
- if FileTest.exist?(nodefile)
- return YAML.load_file(nodefile)
- else
- raise "Could not find information for #{node}"
- end
+ nodefile = File.join(YAMLDIR, "#{node}.yaml")
+ if FileTest.exist?(nodefile)
+ return YAML.load_file(nodefile)
+ else
+ raise "Could not find information for #{node}"
+ end
end
node = ARGV[0]
@@ -69,31 +69,31 @@ info = read_node(node)
# Iterate over any provided parents, merging in there information.
parents_seen = []
while parent = info["parent"]
- raise "Found inheritance loop with parent #{parent}" if parents_seen.include?(parent)
+ raise "Found inheritance loop with parent #{parent}" if parents_seen.include?(parent)
- parents_seen << parent
+ parents_seen << parent
- info.delete("parent")
+ info.delete("parent")
- parent_info = read_node(parent)
+ parent_info = read_node(parent)
- # Include any parent classes in our list.
- if pclasses = parent_info["classes"]
- info["classes"] += pclasses
- info["classes"].uniq!
- end
+ # Include any parent classes in our list.
+ if pclasses = parent_info["classes"]
+ info["classes"] += pclasses
+ info["classes"].uniq!
+ end
- # And inherit parameters from our parent, while preferring our own values.
- if pparams = parent_info["parameters"]
- # When using Hash#merge, the hash being merged in wins, and we
- # want the subnode parameters to be the parent node parameters.
- info["parameters"] = pparams.merge(info["parameters"])
- end
+ # And inherit parameters from our parent, while preferring our own values.
+ if pparams = parent_info["parameters"]
+ # When using Hash#merge, the hash being merged in wins, and we
+ # want the subnode parameters to be the parent node parameters.
+ info["parameters"] = pparams.merge(info["parameters"])
+ end
- # Copy over any parent node name.
- if pparent = parent_info["parent"]
- info["parent"] = pparent
- end
+ # Copy over any parent node name.
+ if pparent = parent_info["parent"]
+ info["parent"] = pparent
+ end
end
puts YAML.dump(info)
diff --git a/install.rb b/install.rb
index 42c62f1..d35aaa0 100755
--- a/install.rb
+++ b/install.rb
@@ -36,33 +36,33 @@ require 'rbconfig'
require 'find'
require 'fileutils'
begin
- require 'ftools' # apparently on some system ftools doesn't get loaded
- $haveftools = true
+ require 'ftools' # apparently on some system ftools doesn't get loaded
+ $haveftools = true
rescue LoadError
- puts "ftools not found. Using FileUtils instead.."
- $haveftools = false
+ puts "ftools not found. Using FileUtils instead.."
+ $haveftools = false
end
require 'optparse'
require 'ostruct'
begin
- require 'rdoc/rdoc'
- $haverdoc = true
+ require 'rdoc/rdoc'
+ $haverdoc = true
rescue LoadError
- puts "Missing rdoc; skipping documentation"
- $haverdoc = false
+ puts "Missing rdoc; skipping documentation"
+ $haverdoc = false
end
begin
- if $haverdoc
- rst2man = %x{which rst2man.py}
- $haveman = true
- else
- $haveman = false
- end
-rescue
- puts "Missing rst2man; skipping man page creation"
+ if $haverdoc
+ rst2man = %x{which rst2man.py}
+ $haveman = true
+ else
$haveman = false
+ end
+rescue
+ puts "Missing rst2man; skipping man page creation"
+ $haveman = false
end
PREREQS = %w{openssl facter xmlrpc/client xmlrpc/server cgi}
@@ -71,11 +71,11 @@ MIN_FACTER_VERSION = 1.5
InstallOptions = OpenStruct.new
def glob(list)
- g = list.map { |i| Dir.glob(i) }
- g.flatten!
- g.compact!
- g.reject! { |e| e =~ /\.svn/ }
- g
+ g = list.map { |i| Dir.glob(i) }
+ g.flatten!
+ g.compact!
+ g.reject! { |e| e =~ /\.svn/ }
+ g
end
# Set these values to what you want installed.
@@ -88,305 +88,305 @@ libs = glob(%w{lib/**/*.rb lib/**/*.py})
tests = glob(%w{test/**/*.rb})
def do_bins(bins, target, strip = 's?bin/')
- bins.each do |bf|
- obf = bf.gsub(/#{strip}/, '')
- install_binfile(bf, obf, target)
- end
+ bins.each do |bf|
+ obf = bf.gsub(/#{strip}/, '')
+ install_binfile(bf, obf, target)
+ end
end
def do_libs(libs, strip = 'lib/')
- libs.each do |lf|
- olf = File.join(InstallOptions.site_dir, lf.gsub(/#{strip}/, ''))
- op = File.dirname(olf)
- if $haveftools
- File.makedirs(op, true)
- File.chmod(0755, op)
- File.install(lf, olf, 0644, true)
- else
- FileUtils.makedirs(op, {:mode => 0755, :verbose => true})
- FileUtils.chmod(0755, op)
- FileUtils.install(lf, olf, {:mode => 0644, :verbose => true})
- end
+ libs.each do |lf|
+ olf = File.join(InstallOptions.site_dir, lf.gsub(/#{strip}/, ''))
+ op = File.dirname(olf)
+ if $haveftools
+ File.makedirs(op, true)
+ File.chmod(0755, op)
+ File.install(lf, olf, 0644, true)
+ else
+ FileUtils.makedirs(op, {:mode => 0755, :verbose => true})
+ FileUtils.chmod(0755, op)
+ FileUtils.install(lf, olf, {:mode => 0644, :verbose => true})
end
+ end
end
def do_man(man, strip = 'man/')
- man.each do |mf|
- omf = File.join(InstallOptions.man_dir, mf.gsub(/#{strip}/, ''))
- om = File.dirname(omf)
- if $haveftools
- File.makedirs(om, true)
- File.chmod(0755, om)
- File.install(mf, omf, 0644, true)
- else
- FileUtils.makedirs(om, {:mode => 0755, :verbose => true})
- FileUtils.chmod(0755, om)
- FileUtils.install(mf, omf, {:mode => 0644, :verbose => true})
- end
- gzip = %x{which gzip}
- gzip.chomp!
- %x{#{gzip} -f #{omf}}
+ man.each do |mf|
+ omf = File.join(InstallOptions.man_dir, mf.gsub(/#{strip}/, ''))
+ om = File.dirname(omf)
+ if $haveftools
+ File.makedirs(om, true)
+ File.chmod(0755, om)
+ File.install(mf, omf, 0644, true)
+ else
+ FileUtils.makedirs(om, {:mode => 0755, :verbose => true})
+ FileUtils.chmod(0755, om)
+ FileUtils.install(mf, omf, {:mode => 0644, :verbose => true})
end
+ gzip = %x{which gzip}
+ gzip.chomp!
+ %x{#{gzip} -f #{omf}}
+ end
end
# Verify that all of the prereqs are installed
def check_prereqs
- PREREQS.each { |pre|
- begin
- require pre
- if pre == "facter"
- # to_f isn't quite exact for strings like "1.5.1" but is good
- # enough for this purpose.
- facter_version = Facter.version.to_f
- if facter_version < MIN_FACTER_VERSION
- puts "Facter version: #{facter_version}; minimum required: #{MIN_FACTER_VERSION}; cannot install"
- exit -1
- end
- end
- rescue LoadError
- puts "Could not load #{pre}; cannot install"
- exit -1
+ PREREQS.each { |pre|
+ begin
+ require pre
+ if pre == "facter"
+ # to_f isn't quite exact for strings like "1.5.1" but is good
+ # enough for this purpose.
+ facter_version = Facter.version.to_f
+ if facter_version < MIN_FACTER_VERSION
+ puts "Facter version: #{facter_version}; minimum required: #{MIN_FACTER_VERSION}; cannot install"
+ exit -1
end
- }
+ end
+ rescue LoadError
+ puts "Could not load #{pre}; cannot install"
+ exit -1
+ end
+ }
end
##
# Prepare the file installation.
#
def prepare_installation
- # Only try to do docs if we're sure they have rdoc
- if $haverdoc
- InstallOptions.rdoc = true
- InstallOptions.ri = RUBY_PLATFORM != "i386-mswin32"
- else
- InstallOptions.rdoc = false
- InstallOptions.ri = false
+ # Only try to do docs if we're sure they have rdoc
+ if $haverdoc
+ InstallOptions.rdoc = true
+ InstallOptions.ri = RUBY_PLATFORM != "i386-mswin32"
+ else
+ InstallOptions.rdoc = false
+ InstallOptions.ri = false
+ end
+
+
+ if $haveman
+ InstallOptions.man = true
+ if RUBY_PLATFORM == "i386-mswin32"
+ InstallOptions.man = false
end
+ else
+ InstallOptions.man = false
+ end
+ InstallOptions.tests = true
- if $haveman
- InstallOptions.man = true
- if RUBY_PLATFORM == "i386-mswin32"
- InstallOptions.man = false
- end
- else
- InstallOptions.man = false
+ if $haveman
+ InstallOptions.man = true
+ if RUBY_PLATFORM == "i386-mswin32"
+ InstallOptions.man = false
end
-
- InstallOptions.tests = true
-
- if $haveman
- InstallOptions.man = true
- if RUBY_PLATFORM == "i386-mswin32"
- InstallOptions.man = false
- end
- else
- InstallOptions.man = false
+ else
+ InstallOptions.man = false
+ end
+
+ ARGV.options do |opts|
+ opts.banner = "Usage: #{File.basename($0)} [options]"
+ opts.separator ""
+ opts.on('--[no-]rdoc', 'Prevents the creation of RDoc output.', 'Default on.') do |onrdoc|
+ InstallOptions.rdoc = onrdoc
end
-
- ARGV.options do |opts|
- opts.banner = "Usage: #{File.basename($0)} [options]"
- opts.separator ""
- opts.on('--[no-]rdoc', 'Prevents the creation of RDoc output.', 'Default on.') do |onrdoc|
- InstallOptions.rdoc = onrdoc
- end
- opts.on('--[no-]ri', 'Prevents the creation of RI output.', 'Default off on mswin32.') do |onri|
- InstallOptions.ri = onri
- end
- opts.on('--[no-]man', 'Prevents the creation of man pages.', 'Default on.') do |onman|
- InstallOptions.man = onman
- end
- opts.on('--[no-]tests', 'Prevents the execution of unit tests.', 'Default on.') do |ontest|
- InstallOptions.tests = ontest
- end
- opts.on('--destdir[=OPTIONAL]', 'Installation prefix for all targets', 'Default essentially /') do |destdir|
- InstallOptions.destdir = destdir
- end
- opts.on('--bindir[=OPTIONAL]', 'Installation directory for binaries', 'overrides Config::CONFIG["bindir"]') do |bindir|
- InstallOptions.bindir = bindir
- end
- opts.on('--sbindir[=OPTIONAL]', 'Installation directory for system binaries', 'overrides Config::CONFIG["sbindir"]') do |sbindir|
- InstallOptions.sbindir = sbindir
- end
- opts.on('--sitelibdir[=OPTIONAL]', 'Installation directory for libraries', 'overrides Config::CONFIG["sitelibdir"]') do |sitelibdir|
- InstallOptions.sitelibdir = sitelibdir
- end
- opts.on('--mandir[=OPTIONAL]', 'Installation directory for man pages', 'overrides Config::CONFIG["mandir"]') do |mandir|
- InstallOptions.mandir = mandir
- end
- opts.on('--quick', 'Performs a quick installation. Only the', 'installation is done.') do |quick|
- InstallOptions.rdoc = false
- InstallOptions.ri = false
- InstallOptions.tests = false
- end
- opts.on('--full', 'Performs a full installation. All', 'optional installation steps are run.') do |full|
- InstallOptions.rdoc = true
- InstallOptions.man = true
- InstallOptions.ri = true
- InstallOptions.tests = true
- end
- opts.separator("")
- opts.on_tail('--help', "Shows this help text.") do
- $stderr.puts opts
- exit
- end
-
- opts.parse!
+ opts.on('--[no-]ri', 'Prevents the creation of RI output.', 'Default off on mswin32.') do |onri|
+ InstallOptions.ri = onri
end
-
- tmpdirs = [ENV['TMP'], ENV['TEMP'], "/tmp", "/var/tmp", "."]
-
- version = [Config::CONFIG["MAJOR"], Config::CONFIG["MINOR"]].join(".")
- libdir = File.join(Config::CONFIG["libdir"], "ruby", version)
-
- # Mac OS X 10.5 and higher declare bindir and sbindir as
- # /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin
- # /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/sbin
- # which is not generally where people expect executables to be installed
- # These settings are appropriate defaults for all OS X versions.
- if RUBY_PLATFORM =~ /^universal-darwin[\d\.]+$/
- Config::CONFIG['bindir'] = "/usr/bin"
- Config::CONFIG['sbindir'] = "/usr/sbin"
+ opts.on('--[no-]man', 'Prevents the creation of man pages.', 'Default on.') do |onman|
+ InstallOptions.man = onman
end
-
- if not InstallOptions.bindir.nil?
- bindir = InstallOptions.bindir
- else
- bindir = Config::CONFIG['bindir']
+ opts.on('--[no-]tests', 'Prevents the execution of unit tests.', 'Default on.') do |ontest|
+ InstallOptions.tests = ontest
end
-
- if not InstallOptions.sbindir.nil?
- sbindir = InstallOptions.sbindir
- else
- sbindir = Config::CONFIG['sbindir']
+ opts.on('--destdir[=OPTIONAL]', 'Installation prefix for all targets', 'Default essentially /') do |destdir|
+ InstallOptions.destdir = destdir
end
-
- if not InstallOptions.sitelibdir.nil?
- sitelibdir = InstallOptions.sitelibdir
- else
- sitelibdir = Config::CONFIG["sitelibdir"]
- if sitelibdir.nil?
- sitelibdir = $LOAD_PATH.find { |x| x =~ /site_ruby/ }
- if sitelibdir.nil?
- sitelibdir = File.join(libdir, "site_ruby")
- elsif sitelibdir !~ Regexp.quote(version)
- sitelibdir = File.join(sitelibdir, version)
- end
- end
+ opts.on('--bindir[=OPTIONAL]', 'Installation directory for binaries', 'overrides Config::CONFIG["bindir"]') do |bindir|
+ InstallOptions.bindir = bindir
end
-
- if not InstallOptions.mandir.nil?
- mandir = InstallOptions.mandir
- else
- mandir = Config::CONFIG['mandir']
+ opts.on('--sbindir[=OPTIONAL]', 'Installation directory for system binaries', 'overrides Config::CONFIG["sbindir"]') do |sbindir|
+ InstallOptions.sbindir = sbindir
end
-
- # To be deprecated once people move over to using --destdir option
- if (destdir = ENV['DESTDIR'])
- bindir = "#{destdir}#{bindir}"
- sbindir = "#{destdir}#{sbindir}"
- mandir = "#{destdir}#{mandir}"
- sitelibdir = "#{destdir}#{sitelibdir}"
-
- FileUtils.makedirs(bindir)
- FileUtils.makedirs(sbindir)
- FileUtils.makedirs(mandir)
- FileUtils.makedirs(sitelibdir)
- # This is the new way forward
- elsif (destdir = InstallOptions.destdir)
- bindir = "#{destdir}#{bindir}"
- sbindir = "#{destdir}#{sbindir}"
- mandir = "#{destdir}#{mandir}"
- sitelibdir = "#{destdir}#{sitelibdir}"
-
- FileUtils.makedirs(bindir)
- FileUtils.makedirs(sbindir)
- FileUtils.makedirs(mandir)
- FileUtils.makedirs(sitelibdir)
+ opts.on('--sitelibdir[=OPTIONAL]', 'Installation directory for libraries', 'overrides Config::CONFIG["sitelibdir"]') do |sitelibdir|
+ InstallOptions.sitelibdir = sitelibdir
+ end
+ opts.on('--mandir[=OPTIONAL]', 'Installation directory for man pages', 'overrides Config::CONFIG["mandir"]') do |mandir|
+ InstallOptions.mandir = mandir
+ end
+ opts.on('--quick', 'Performs a quick installation. Only the', 'installation is done.') do |quick|
+ InstallOptions.rdoc = false
+ InstallOptions.ri = false
+ InstallOptions.tests = false
+ end
+ opts.on('--full', 'Performs a full installation. All', 'optional installation steps are run.') do |full|
+ InstallOptions.rdoc = true
+ InstallOptions.man = true
+ InstallOptions.ri = true
+ InstallOptions.tests = true
+ end
+ opts.separator("")
+ opts.on_tail('--help', "Shows this help text.") do
+ $stderr.puts opts
+ exit
end
- tmpdirs << bindir
-
- InstallOptions.tmp_dirs = tmpdirs.compact
- InstallOptions.site_dir = sitelibdir
- InstallOptions.bin_dir = bindir
- InstallOptions.sbin_dir = sbindir
- InstallOptions.lib_dir = libdir
- InstallOptions.man_dir = mandir
+ opts.parse!
+ end
+
+ tmpdirs = [ENV['TMP'], ENV['TEMP'], "/tmp", "/var/tmp", "."]
+
+ version = [Config::CONFIG["MAJOR"], Config::CONFIG["MINOR"]].join(".")
+ libdir = File.join(Config::CONFIG["libdir"], "ruby", version)
+
+ # Mac OS X 10.5 and higher declare bindir and sbindir as
+ # /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin
+ # /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/sbin
+ # which is not generally where people expect executables to be installed
+ # These settings are appropriate defaults for all OS X versions.
+ if RUBY_PLATFORM =~ /^universal-darwin[\d\.]+$/
+ Config::CONFIG['bindir'] = "/usr/bin"
+ Config::CONFIG['sbindir'] = "/usr/sbin"
+ end
+
+ if not InstallOptions.bindir.nil?
+ bindir = InstallOptions.bindir
+ else
+ bindir = Config::CONFIG['bindir']
+ end
+
+ if not InstallOptions.sbindir.nil?
+ sbindir = InstallOptions.sbindir
+ else
+ sbindir = Config::CONFIG['sbindir']
+ end
+
+ if not InstallOptions.sitelibdir.nil?
+ sitelibdir = InstallOptions.sitelibdir
+ else
+ sitelibdir = Config::CONFIG["sitelibdir"]
+ if sitelibdir.nil?
+ sitelibdir = $LOAD_PATH.find { |x| x =~ /site_ruby/ }
+ if sitelibdir.nil?
+ sitelibdir = File.join(libdir, "site_ruby")
+ elsif sitelibdir !~ Regexp.quote(version)
+ sitelibdir = File.join(sitelibdir, version)
+ end
+ end
+ end
+
+ if not InstallOptions.mandir.nil?
+ mandir = InstallOptions.mandir
+ else
+ mandir = Config::CONFIG['mandir']
+ end
+
+ # To be deprecated once people move over to using --destdir option
+ if (destdir = ENV['DESTDIR'])
+ bindir = "#{destdir}#{bindir}"
+ sbindir = "#{destdir}#{sbindir}"
+ mandir = "#{destdir}#{mandir}"
+ sitelibdir = "#{destdir}#{sitelibdir}"
+
+ FileUtils.makedirs(bindir)
+ FileUtils.makedirs(sbindir)
+ FileUtils.makedirs(mandir)
+ FileUtils.makedirs(sitelibdir)
+ # This is the new way forward
+ elsif (destdir = InstallOptions.destdir)
+ bindir = "#{destdir}#{bindir}"
+ sbindir = "#{destdir}#{sbindir}"
+ mandir = "#{destdir}#{mandir}"
+ sitelibdir = "#{destdir}#{sitelibdir}"
+
+ FileUtils.makedirs(bindir)
+ FileUtils.makedirs(sbindir)
+ FileUtils.makedirs(mandir)
+ FileUtils.makedirs(sitelibdir)
+ end
+
+ tmpdirs << bindir
+
+ InstallOptions.tmp_dirs = tmpdirs.compact
+ InstallOptions.site_dir = sitelibdir
+ InstallOptions.bin_dir = bindir
+ InstallOptions.sbin_dir = sbindir
+ InstallOptions.lib_dir = libdir
+ InstallOptions.man_dir = mandir
end
##
# Build the rdoc documentation. Also, try to build the RI documentation.
#
def build_rdoc(files)
- return unless $haverdoc
- begin
- r = RDoc::RDoc.new
- r.document(["--main", "README", "--title", "Puppet -- Site Configuration Management", "--line-numbers"] + files)
- rescue RDoc::RDocError => e
- $stderr.puts e.message
- rescue Exception => e
- $stderr.puts "Couldn't build RDoc documentation\n#{e.message}"
- end
+ return unless $haverdoc
+ begin
+ r = RDoc::RDoc.new
+ r.document(["--main", "README", "--title", "Puppet -- Site Configuration Management", "--line-numbers"] + files)
+ rescue RDoc::RDocError => e
+ $stderr.puts e.message
+ rescue Exception => e
+ $stderr.puts "Couldn't build RDoc documentation\n#{e.message}"
+ end
end
def build_ri(files)
- return unless $haverdoc
- begin
- ri = RDoc::RDoc.new
- #ri.document(["--ri-site", "--merge"] + files)
- ri.document(["--ri-site"] + files)
- rescue RDoc::RDocError => e
- $stderr.puts e.message
- rescue Exception => e
- $stderr.puts "Couldn't build Ri documentation\n#{e.message}"
- $stderr.puts "Continuing with install..."
- end
+ return unless $haverdoc
+ begin
+ ri = RDoc::RDoc.new
+ #ri.document(["--ri-site", "--merge"] + files)
+ ri.document(["--ri-site"] + files)
+ rescue RDoc::RDocError => e
+ $stderr.puts e.message
+ rescue Exception => e
+ $stderr.puts "Couldn't build Ri documentation\n#{e.message}"
+ $stderr.puts "Continuing with install..."
+ end
end
def build_man(bins, sbins)
- return unless $haveman
- begin
- # Locate rst2man
- rst2man = %x{which rst2man.py}
- rst2man.chomp!
- # Create puppet.conf.5 man page
- %x{bin/puppetdoc --reference configuration > ./puppet.conf.rst}
- %x{#{rst2man} ./puppet.conf.rst ./man/man5/puppet.conf.5}
- File.unlink("./puppet.conf.rst")
-
- # Create binary man pages
- binary = bins + sbins
- binary.each do |bin|
- b = bin.gsub( /(bin|sbin)\//, "")
- %x{#{bin} --help > ./#{b}.rst}
- %x{#{rst2man} ./#{b}.rst ./man/man8/#{b}.8}
- File.unlink("./#{b}.rst")
- end
+ return unless $haveman
+ begin
+ # Locate rst2man
+ rst2man = %x{which rst2man.py}
+ rst2man.chomp!
+ # Create puppet.conf.5 man page
+ %x{bin/puppetdoc --reference configuration > ./puppet.conf.rst}
+ %x{#{rst2man} ./puppet.conf.rst ./man/man5/puppet.conf.5}
+ File.unlink("./puppet.conf.rst")
+
+ # Create binary man pages
+ binary = bins + sbins
+ binary.each do |bin|
+ b = bin.gsub( /(bin|sbin)\//, "")
+ %x{#{bin} --help > ./#{b}.rst}
+ %x{#{rst2man} ./#{b}.rst ./man/man8/#{b}.8}
+ File.unlink("./#{b}.rst")
+ end
rescue SystemCallError
- $stderr.puts "Couldn't build man pages: " + $ERROR_INFO
- $stderr.puts "Continuing with install..."
- end
+ $stderr.puts "Couldn't build man pages: " + $ERROR_INFO
+ $stderr.puts "Continuing with install..."
+ end
end
def run_tests(test_list)
- require 'test/unit/ui/console/testrunner'
- $LOAD_PATH.unshift "lib"
- test_list.each do |test|
- next if File.directory?(test)
- require test
- end
+ require 'test/unit/ui/console/testrunner'
+ $LOAD_PATH.unshift "lib"
+ test_list.each do |test|
+ next if File.directory?(test)
+ require test
+ end
- tests = []
- ObjectSpace.each_object { |o| tests << o if o.kind_of?(Class) }
- tests.delete_if { |o| !o.ancestors.include?(Test::Unit::TestCase) }
- tests.delete_if { |o| o == Test::Unit::TestCase }
+ tests = []
+ ObjectSpace.each_object { |o| tests << o if o.kind_of?(Class) }
+ tests.delete_if { |o| !o.ancestors.include?(Test::Unit::TestCase) }
+ tests.delete_if { |o| o == Test::Unit::TestCase }
- tests.each { |test| Test::Unit::UI::Console::TestRunner.run(test) }
- $LOAD_PATH.shift
+ tests.each { |test| Test::Unit::UI::Console::TestRunner.run(test) }
+ $LOAD_PATH.shift
rescue LoadError
- puts "Missing testrunner library; skipping tests"
+ puts "Missing testrunner library; skipping tests"
end
##
@@ -395,55 +395,55 @@ end
# (e.g., bin/rdoc becomes rdoc); the shebang line handles running it. Under
# windows, we add an '.rb' extension and let file associations do their stuff.
def install_binfile(from, op_file, target)
- tmp_dir = nil
- InstallOptions.tmp_dirs.each do |t|
- if File.directory?(t) and File.writable?(t)
- tmp_dir = t
- break
- end
+ tmp_dir = nil
+ InstallOptions.tmp_dirs.each do |t|
+ if File.directory?(t) and File.writable?(t)
+ tmp_dir = t
+ break
end
-
- fail "Cannot find a temporary directory" unless tmp_dir
- tmp_file = File.join(tmp_dir, '_tmp')
- ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
-
- File.open(from) do |ip|
- File.open(tmp_file, "w") do |op|
- ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
- op.puts "#!#{ruby}"
- contents = ip.readlines
- contents.shift if contents[0] =~ /^#!/
- op.write contents.join
- end
+ end
+
+ fail "Cannot find a temporary directory" unless tmp_dir
+ tmp_file = File.join(tmp_dir, '_tmp')
+ ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
+
+ File.open(from) do |ip|
+ File.open(tmp_file, "w") do |op|
+ ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
+ op.puts "#!#{ruby}"
+ contents = ip.readlines
+ contents.shift if contents[0] =~ /^#!/
+ op.write contents.join
end
+ end
- if Config::CONFIG["target_os"] =~ /win/io and Config::CONFIG["target_os"] !~ /darwin/io
- installed_wrapper = false
+ if Config::CONFIG["target_os"] =~ /win/io and Config::CONFIG["target_os"] !~ /darwin/io
+ installed_wrapper = false
- if File.exists?("#{from}.bat")
- FileUtils.install("#{from}.bat", File.join(target, "#{op_file}.bat"), :mode => 0755, :verbose => true)
- installed_wrapper = true
- end
+ if File.exists?("#{from}.bat")
+ FileUtils.install("#{from}.bat", File.join(target, "#{op_file}.bat"), :mode => 0755, :verbose => true)
+ installed_wrapper = true
+ end
- if File.exists?("#{from}.cmd")
- FileUtils.install("#{from}.cmd", File.join(target, "#{op_file}.cmd"), :mode => 0755, :verbose => true)
- installed_wrapper = true
- end
+ if File.exists?("#{from}.cmd")
+ FileUtils.install("#{from}.cmd", File.join(target, "#{op_file}.cmd"), :mode => 0755, :verbose => true)
+ installed_wrapper = true
+ end
- if not installed_wrapper
- tmp_file2 = File.join(tmp_dir, '_tmp_wrapper')
- cwn = File.join(Config::CONFIG['bindir'], op_file)
- cwv = CMD_WRAPPER.gsub('<ruby>', ruby.gsub(%r{/}) { "\\" }).gsub!('<command>', cwn.gsub(%r{/}) { "\\" } )
+ if not installed_wrapper
+ tmp_file2 = File.join(tmp_dir, '_tmp_wrapper')
+ cwn = File.join(Config::CONFIG['bindir'], op_file)
+ cwv = CMD_WRAPPER.gsub('<ruby>', ruby.gsub(%r{/}) { "\\" }).gsub!('<command>', cwn.gsub(%r{/}) { "\\" } )
- File.open(tmp_file2, "wb") { |cw| cw.puts cwv }
- FileUtils.install(tmp_file2, File.join(target, "#{op_file}.bat"), :mode => 0755, :verbose => true)
+ File.open(tmp_file2, "wb") { |cw| cw.puts cwv }
+ FileUtils.install(tmp_file2, File.join(target, "#{op_file}.bat"), :mode => 0755, :verbose => true)
- File.unlink(tmp_file2)
- installed_wrapper = true
- end
+ File.unlink(tmp_file2)
+ installed_wrapper = true
end
- FileUtils.install(tmp_file, File.join(target, op_file), :mode => 0755, :verbose => true)
- File.unlink(tmp_file)
+ end
+ FileUtils.install(tmp_file, File.join(target, op_file), :mode => 0755, :verbose => true)
+ File.unlink(tmp_file)
end
CMD_WRAPPER = <<-EOS
diff --git a/lib/puppet.rb b/lib/puppet.rb
index dc14c87..902f5bf 100644
--- a/lib/puppet.rb
+++ b/lib/puppet.rb
@@ -1,6 +1,6 @@
# Try to load rubygems. Hey rubygems, I hate you.
begin
- require 'rubygems'
+ require 'rubygems'
rescue LoadError
end
@@ -24,134 +24,134 @@ require 'puppet/util/run_mode'
# it's also a place to find top-level commands like 'debug'
module Puppet
- PUPPETVERSION = '2.6.0'
+ PUPPETVERSION = '2.6.0'
- def Puppet.version
- PUPPETVERSION
- end
-
- class << self
- include Puppet::Util
- attr_reader :features
- attr_writer :name
- end
+ def Puppet.version
+ PUPPETVERSION
+ end
- # the hash that determines how our system behaves
- @@settings = Puppet::Util::Settings.new
+ class << self
+ include Puppet::Util
+ attr_reader :features
+ attr_writer :name
+ end
- # The services running in this process.
- @services ||= []
+ # the hash that determines how our system behaves
+ @@settings = Puppet::Util::Settings.new
- require 'puppet/util/logging'
+ # The services running in this process.
+ @services ||= []
- extend Puppet::Util::Logging
+ require 'puppet/util/logging'
- # The feature collection
- @features = Puppet::Util::Feature.new('puppet/feature')
+ extend Puppet::Util::Logging
- # Load the base features.
- require 'puppet/feature/base'
+ # The feature collection
+ @features = Puppet::Util::Feature.new('puppet/feature')
- # Store a new default value.
- def self.setdefaults(section, hash)
- @@settings.setdefaults(section, hash)
- end
+ # Load the base features.
+ require 'puppet/feature/base'
- # configuration parameter access and stuff
- def self.[](param)
- case param
- when :debug
- return Puppet::Util::Log.level == :debug
- else
- return @@settings[param]
- end
- end
+ # Store a new default value.
+ def self.setdefaults(section, hash)
+ @@settings.setdefaults(section, hash)
+ end
- # configuration parameter access and stuff
- def self.[]=(param,value)
- @@settings[param] = value
- end
-
- def self.clear
- @@settings.clear
- end
-
- def self.debug=(value)
- if value
- Puppet::Util::Log.level=(:debug)
- else
- Puppet::Util::Log.level=(:notice)
- end
+ # configuration parameter access and stuff
+ def self.[](param)
+ case param
+ when :debug
+ return Puppet::Util::Log.level == :debug
+ else
+ return @@settings[param]
end
-
- def self.settings
- @@settings
+ end
+
+ # configuration parameter access and stuff
+ def self.[]=(param,value)
+ @@settings[param] = value
+ end
+
+ def self.clear
+ @@settings.clear
+ end
+
+ def self.debug=(value)
+ if value
+ Puppet::Util::Log.level=(:debug)
+ else
+ Puppet::Util::Log.level=(:notice)
end
+ end
- def self.run_mode
- $puppet_application_mode || Puppet::Util::RunMode[:user]
- end
+ def self.settings
+ @@settings
+ end
- def self.application_name
- $puppet_application_name ||= "apply"
- end
+ def self.run_mode
+ $puppet_application_mode || Puppet::Util::RunMode[:user]
+ end
- # Load all of the configuration parameters.
- require 'puppet/defaults'
+ def self.application_name
+ $puppet_application_name ||= "apply"
+ end
- def self.genmanifest
- if Puppet[:genmanifest]
- puts Puppet.settings.to_manifest
- exit(0)
- end
- end
+ # Load all of the configuration parameters.
+ require 'puppet/defaults'
- # Parse the config file for this process.
- def self.parse_config
- Puppet.settings.parse
+ def self.genmanifest
+ if Puppet[:genmanifest]
+ puts Puppet.settings.to_manifest
+ exit(0)
end
-
- # XXX this should all be done using puppet objects, not using
- # normal mkdir
- def self.recmkdir(dir,mode = 0755)
- if FileTest.exist?(dir)
+ end
+
+ # Parse the config file for this process.
+ def self.parse_config
+ Puppet.settings.parse
+ end
+
+ # XXX this should all be done using puppet objects, not using
+ # normal mkdir
+ def self.recmkdir(dir,mode = 0755)
+ if FileTest.exist?(dir)
+ return false
+ else
+ tmp = dir.sub(/^\//,'')
+ path = [File::SEPARATOR]
+ tmp.split(File::SEPARATOR).each { |dir|
+ path.push dir
+ if ! FileTest.exist?(File.join(path))
+ begin
+ Dir.mkdir(File.join(path), mode)
+ rescue Errno::EACCES => detail
+ Puppet.err detail.to_s
return false
- else
- tmp = dir.sub(/^\//,'')
- path = [File::SEPARATOR]
- tmp.split(File::SEPARATOR).each { |dir|
- path.push dir
- if ! FileTest.exist?(File.join(path))
- begin
- Dir.mkdir(File.join(path), mode)
- rescue Errno::EACCES => detail
- Puppet.err detail.to_s
- return false
- rescue => detail
- Puppet.err "Could not create #{path}: #{detail}"
- return false
- end
- elsif FileTest.directory?(File.join(path))
- next
- else FileTest.exist?(File.join(path))
- raise Puppet::Error, "Cannot create #{dir}: basedir #{File.join(path)} is a file"
- end
- }
- return true
+ rescue => detail
+ Puppet.err "Could not create #{path}: #{detail}"
+ return false
+ end
+ elsif FileTest.directory?(File.join(path))
+ next
+ else FileTest.exist?(File.join(path))
+ raise Puppet::Error, "Cannot create #{dir}: basedir #{File.join(path)} is a file"
end
+ }
+ return true
end
-
- # Create a new type. Just proxy to the Type class.
- def self.newtype(name, options = {}, &block)
- Puppet::Type.newtype(name, options, &block)
- end
-
- # Retrieve a type by name. Just proxy to the Type class.
- def self.type(name)
- # LAK:DEP Deprecation notice added 12/17/2008
- Puppet.warning "Puppet.type is deprecated; use Puppet::Type.type"
- Puppet::Type.type(name)
- end
+ end
+
+ # Create a new type. Just proxy to the Type class.
+ def self.newtype(name, options = {}, &block)
+ Puppet::Type.newtype(name, options, &block)
+ end
+
+ # Retrieve a type by name. Just proxy to the Type class.
+ def self.type(name)
+ # LAK:DEP Deprecation notice added 12/17/2008
+ Puppet.warning "Puppet.type is deprecated; use Puppet::Type.type"
+ Puppet::Type.type(name)
+ end
end
require 'puppet/type'
diff --git a/lib/puppet/agent.rb b/lib/puppet/agent.rb
index a01da48..52acc64 100644
--- a/lib/puppet/agent.rb
+++ b/lib/puppet/agent.rb
@@ -5,101 +5,101 @@ require 'puppet/application'
# A general class for triggering a run of another
# class.
class Puppet::Agent
- require 'puppet/agent/locker'
- include Puppet::Agent::Locker
+ require 'puppet/agent/locker'
+ include Puppet::Agent::Locker
- attr_reader :client_class, :client, :splayed
+ attr_reader :client_class, :client, :splayed
- # Just so we can specify that we are "the" instance.
- def initialize(client_class)
- @splayed = false
+ # Just so we can specify that we are "the" instance.
+ def initialize(client_class)
+ @splayed = false
- @client_class = client_class
- end
-
- def lockfile_path
- client_class.lockfile_path
- end
-
- def needing_restart?
- Puppet::Application.restart_requested?
- end
+ @client_class = client_class
+ end
- # Perform a run with our client.
- def run(*args)
- if running?
- Puppet.notice "Run of #{client_class} already in progress; skipping"
- return
- end
- result = nil
- block_run = Puppet::Application.controlled_run do
- splay
- with_client do |client|
- begin
- sync.synchronize { lock { result = client.run(*args) } }
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Could not run #{client_class}: #{detail}"
- end
- end
- true
- end
- Puppet.notice "Shutdown/restart in progress; skipping run" unless block_run
- result
- end
+ def lockfile_path
+ client_class.lockfile_path
+ end
- def stopping?
- Puppet::Application.stop_requested?
- end
+ def needing_restart?
+ Puppet::Application.restart_requested?
+ end
- # Have we splayed already?
- def splayed?
- splayed
+ # Perform a run with our client.
+ def run(*args)
+ if running?
+ Puppet.notice "Run of #{client_class} already in progress; skipping"
+ return
end
-
- # Sleep when splay is enabled; else just return.
- def splay
- return unless Puppet[:splay]
- return if splayed?
-
- time = rand(Integer(Puppet[:splaylimit]) + 1)
- Puppet.info "Sleeping for #{time} seconds (splay is enabled)"
- sleep(time)
- @splayed = true
- end
-
- # Start listening for events. We're pretty much just listening for
- # timer events here.
- def start
- # Create our timer. Puppet will handle observing it and such.
- timer = EventLoop::Timer.new(:interval => Puppet[:runinterval], :tolerance => 1, :start? => true) do
- run
+ result = nil
+ block_run = Puppet::Application.controlled_run do
+ splay
+ with_client do |client|
+ begin
+ sync.synchronize { lock { result = client.run(*args) } }
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Could not run #{client_class}: #{detail}"
end
-
- # Run once before we start following the timer
- timer.sound_alarm
+ end
+ true
end
-
- def sync
- @sync ||= Sync.new
+ Puppet.notice "Shutdown/restart in progress; skipping run" unless block_run
+ result
+ end
+
+ def stopping?
+ Puppet::Application.stop_requested?
+ end
+
+ # Have we splayed already?
+ def splayed?
+ splayed
+ end
+
+ # Sleep when splay is enabled; else just return.
+ def splay
+ return unless Puppet[:splay]
+ return if splayed?
+
+ time = rand(Integer(Puppet[:splaylimit]) + 1)
+ Puppet.info "Sleeping for #{time} seconds (splay is enabled)"
+ sleep(time)
+ @splayed = true
+ end
+
+ # Start listening for events. We're pretty much just listening for
+ # timer events here.
+ def start
+ # Create our timer. Puppet will handle observing it and such.
+ timer = EventLoop::Timer.new(:interval => Puppet[:runinterval], :tolerance => 1, :start? => true) do
+ run
end
- private
-
- # Create and yield a client instance, keeping a reference
- # to it during the yield.
- def with_client
- begin
- @client = client_class.new
- rescue SystemExit,NoMemoryError
- raise
- rescue Exception => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Could not create instance of #{client_class}: #{detail}"
- return
- end
- yield @client
- ensure
- @client = nil
+ # Run once before we start following the timer
+ timer.sound_alarm
+ end
+
+ def sync
+ @sync ||= Sync.new
+ end
+
+ private
+
+ # Create and yield a client instance, keeping a reference
+ # to it during the yield.
+ def with_client
+ begin
+ @client = client_class.new
+ rescue SystemExit,NoMemoryError
+ raise
+ rescue Exception => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Could not create instance of #{client_class}: #{detail}"
+ return
end
+ yield @client
+ ensure
+ @client = nil
+ end
end
diff --git a/lib/puppet/agent/locker.rb b/lib/puppet/agent/locker.rb
index 52f3002..98f5b38 100644
--- a/lib/puppet/agent/locker.rb
+++ b/lib/puppet/agent/locker.rb
@@ -3,38 +3,38 @@ require 'puppet/util/pidlock'
# Break out the code related to locking the agent. This module is just
# included into the agent, but having it here makes it easier to test.
module Puppet::Agent::Locker
- # Let the daemon run again, freely in the filesystem.
- def enable
- lockfile.unlock(:anonymous => true)
- end
+ # Let the daemon run again, freely in the filesystem.
+ def enable
+ lockfile.unlock(:anonymous => true)
+ end
- # Stop the daemon from making any catalog runs.
- def disable
- lockfile.lock(:anonymous => true)
- end
+ # Stop the daemon from making any catalog runs.
+ def disable
+ lockfile.lock(:anonymous => true)
+ end
- # Yield if we get a lock, else do nothing. Return
- # true/false depending on whether we get the lock.
- def lock
- if lockfile.lock
- begin
- yield
- ensure
- lockfile.unlock
- end
- return true
- else
- return false
- end
+ # Yield if we get a lock, else do nothing. Return
+ # true/false depending on whether we get the lock.
+ def lock
+ if lockfile.lock
+ begin
+ yield
+ ensure
+ lockfile.unlock
+ end
+ return true
+ else
+ return false
end
+ end
- def lockfile
- @lockfile ||= Puppet::Util::Pidlock.new(lockfile_path)
+ def lockfile
+ @lockfile ||= Puppet::Util::Pidlock.new(lockfile_path)
- @lockfile
- end
+ @lockfile
+ end
- def running?
- lockfile.locked?
- end
+ def running?
+ lockfile.locked?
+ end
end
diff --git a/lib/puppet/application.rb b/lib/puppet/application.rb
index a32650a..05b7d46 100644
--- a/lib/puppet/application.rb
+++ b/lib/puppet/application.rb
@@ -115,291 +115,291 @@ require 'optparse'
# end
module Puppet
class Application
- require 'puppet/util'
- include Puppet::Util
-
- DOCPATTERN = File.expand_path(File.dirname(__FILE__) + "/util/command_line/*" )
-
- class << self
- include Puppet::Util
-
- attr_accessor :run_status
+ require 'puppet/util'
+ include Puppet::Util
- def clear!
- self.run_status = nil
- end
-
- def stop!
- self.run_status = :stop_requested
- end
+ DOCPATTERN = File.expand_path(File.dirname(__FILE__) + "/util/command_line/*" )
- def restart!
- self.run_status = :restart_requested
- end
-
- # Indicates that Puppet::Application.restart! has been invoked and components should
- # do what is necessary to facilitate a restart.
- def restart_requested?
- :restart_requested == run_status
- end
-
- # Indicates that Puppet::Application.stop! has been invoked and components should do what is necessary
- # for a clean stop.
- def stop_requested?
- :stop_requested == run_status
- end
+ class << self
+ include Puppet::Util
- # Indicates that one of stop! or start! was invoked on Puppet::Application, and some kind of process
- # shutdown/short-circuit may be necessary.
- def interrupted?
- [:restart_requested, :stop_requested].include? run_status
- end
+ attr_accessor :run_status
- # Indicates that Puppet::Application believes that it's in usual running run_mode (no stop/restart request
- # currently active).
- def clear?
- run_status.nil?
- end
+ def clear!
+ self.run_status = nil
+ end
- # Only executes the given block if the run status of Puppet::Application is clear (no restarts, stops,
- # etc. requested).
- # Upon block execution, checks the run status again; if a restart has been requested during the block's
- # execution, then controlled_run will send a new HUP signal to the current process.
- # Thus, long-running background processes can potentially finish their work before a restart.
- def controlled_run(&block)
- return unless clear?
- result = block.call
- Process.kill(:HUP, $PID) if restart_requested?
- result
- end
+ def stop!
+ self.run_status = :stop_requested
+ end
- def should_parse_config
- @parse_config = true
- end
+ def restart!
+ self.run_status = :restart_requested
+ end
- def should_not_parse_config
- @parse_config = false
- end
+ # Indicates that Puppet::Application.restart! has been invoked and components should
+ # do what is necessary to facilitate a restart.
+ def restart_requested?
+ :restart_requested == run_status
+ end
- def should_parse_config?
- @parse_config = true if ! defined?(@parse_config)
- @parse_config
- end
+ # Indicates that Puppet::Application.stop! has been invoked and components should do what is necessary
+ # for a clean stop.
+ def stop_requested?
+ :stop_requested == run_status
+ end
- # used to declare code that handle an option
- def option(*options, &block)
- long = options.find { |opt| opt =~ /^--/ }.gsub(/^--(?:\[no-\])?([^ =]+).*$/, '\1' ).gsub('-','_')
- fname = symbolize("handle_#{long}")
- if (block_given?)
- define_method(fname, &block)
- else
- define_method(fname) do |value|
- self.options["#{long}".to_sym] = value
- end
- end
- self.option_parser_commands << [options, fname]
- end
+ # Indicates that one of stop! or start! was invoked on Puppet::Application, and some kind of process
+ # shutdown/short-circuit may be necessary.
+ def interrupted?
+ [:restart_requested, :stop_requested].include? run_status
+ end
- def banner(banner = nil)
- @banner ||= banner
- end
+ # Indicates that Puppet::Application believes that it's in usual running run_mode (no stop/restart request
+ # currently active).
+ def clear?
+ run_status.nil?
+ end
- def option_parser_commands
- @option_parser_commands ||= (
- superclass.respond_to?(:option_parser_commands) ? superclass.option_parser_commands.dup : []
- )
- @option_parser_commands
- end
+ # Only executes the given block if the run status of Puppet::Application is clear (no restarts, stops,
+ # etc. requested).
+ # Upon block execution, checks the run status again; if a restart has been requested during the block's
+ # execution, then controlled_run will send a new HUP signal to the current process.
+ # Thus, long-running background processes can potentially finish their work before a restart.
+ def controlled_run(&block)
+ return unless clear?
+ result = block.call
+ Process.kill(:HUP, $PID) if restart_requested?
+ result
+ end
- def find(name)
- self.const_get(name.to_s.capitalize)
- rescue
- puts "Unable to find application '#{name.to_s}'."
- Kernel::exit(1)
- end
+ def should_parse_config
+ @parse_config = true
+ end
- def [](name)
- find(name).new
- end
+ def should_not_parse_config
+ @parse_config = false
+ end
- # Sets or gets the run_mode name. Sets the run_mode name if a mode_name is
- # passed. Otherwise, gets the run_mode or a default run_mode
- #
- def run_mode( mode_name = nil)
- return @run_mode if @run_mode and not mode_name
+ def should_parse_config?
+ @parse_config = true if ! defined?(@parse_config)
+ @parse_config
+ end
- require 'puppet/util/run_mode'
- @run_mode = Puppet::Util::RunMode[ mode_name || :user ]
+ # used to declare code that handle an option
+ def option(*options, &block)
+ long = options.find { |opt| opt =~ /^--/ }.gsub(/^--(?:\[no-\])?([^ =]+).*$/, '\1' ).gsub('-','_')
+ fname = symbolize("handle_#{long}")
+ if (block_given?)
+ define_method(fname, &block)
+ else
+ define_method(fname) do |value|
+ self.options["#{long}".to_sym] = value
end
+ end
+ self.option_parser_commands << [options, fname]
end
- attr_reader :options, :command_line
-
- # Every app responds to --version
- option("--version", "-V") do |arg|
- puts "#{Puppet.version}"
- exit
+ def banner(banner = nil)
+ @banner ||= banner
end
- # Every app responds to --help
- option("--help", "-h") do |v|
- help
+ def option_parser_commands
+ @option_parser_commands ||= (
+ superclass.respond_to?(:option_parser_commands) ? superclass.option_parser_commands.dup : []
+ )
+ @option_parser_commands
end
- def should_parse_config?
- self.class.should_parse_config?
+ def find(name)
+ self.const_get(name.to_s.capitalize)
+ rescue
+ puts "Unable to find application '#{name.to_s}'."
+ Kernel::exit(1)
end
- # override to execute code before running anything else
- def preinit
+ def [](name)
+ find(name).new
end
- def option_parser
- return @option_parser if defined?(@option_parser)
-
- @option_parser = OptionParser.new(self.class.banner)
+ # Sets or gets the run_mode name. Sets the run_mode name if a mode_name is
+ # passed. Otherwise, gets the run_mode or a default run_mode
+ #
+ def run_mode( mode_name = nil)
+ return @run_mode if @run_mode and not mode_name
- self.class.option_parser_commands.each do |options, fname|
- @option_parser.on(*options) do |value|
- self.send(fname, value)
- end
- end
- @option_parser.default_argv = self.command_line.args
- @option_parser
+ require 'puppet/util/run_mode'
+ @run_mode = Puppet::Util::RunMode[ mode_name || :user ]
end
+ end
- def initialize(command_line = nil)
- require 'puppet/util/command_line'
- @command_line = command_line || Puppet::Util::CommandLine.new
- @run_mode = self.class.run_mode
- @options = {}
-
- $puppet_application_mode = @run_mode
- $puppet_application_name = name
-
- if Puppet.respond_to? :settings
- # This is to reduce the amount of confusion in rspec
- # because it might have loaded defaults.rb before the globals were set
- # and thus have the wrong defaults for the current application
- Puppet.settings.set_value(:confdir, Puppet.run_mode.conf_dir, :mutable_defaults)
- Puppet.settings.set_value(:vardir, Puppet.run_mode.var_dir, :mutable_defaults)
- Puppet.settings.set_value(:name, Puppet.application_name.to_s, :mutable_defaults)
- Puppet.settings.set_value(:logdir, Puppet.run_mode.logopts, :mutable_defaults)
- Puppet.settings.set_value(:rundir, Puppet.run_mode.run_dir, :mutable_defaults)
- Puppet.settings.set_value(:mode, Puppet.run_mode.name.to_s, :mutable_defaults)
- end
+ attr_reader :options, :command_line
- require 'puppet'
- end
+ # Every app responds to --version
+ option("--version", "-V") do |arg|
+ puts "#{Puppet.version}"
+ exit
+ end
- # This is the main application entry point
- def run
- exit_on_fail("initialize") { preinit }
- exit_on_fail("parse options") { parse_options }
- exit_on_fail("parse configuration file") { Puppet.settings.parse } if should_parse_config?
- exit_on_fail("prepare for execution") { setup }
- exit_on_fail("run") { run_command }
- end
+ # Every app responds to --help
+ option("--help", "-h") do |v|
+ help
+ end
- def main
- raise NotImplementedError, "No valid command or main"
- end
+ def should_parse_config?
+ self.class.should_parse_config?
+ end
- def run_command
- main
- end
+ # override to execute code before running anything else
+ def preinit
+ end
- def setup
- # Handle the logging settings
- if options[:debug] or options[:verbose]
- Puppet::Util::Log.newdestination(:console)
- if options[:debug]
- Puppet::Util::Log.level = :debug
- else
- Puppet::Util::Log.level = :info
- end
- end
+ def option_parser
+ return @option_parser if defined?(@option_parser)
- Puppet::Util::Log.newdestination(:syslog) unless options[:setdest]
+ @option_parser = OptionParser.new(self.class.banner)
+
+ self.class.option_parser_commands.each do |options, fname|
+ @option_parser.on(*options) do |value|
+ self.send(fname, value)
+ end
+ end
+ @option_parser.default_argv = self.command_line.args
+ @option_parser
+ end
+
+ def initialize(command_line = nil)
+ require 'puppet/util/command_line'
+ @command_line = command_line || Puppet::Util::CommandLine.new
+ @run_mode = self.class.run_mode
+ @options = {}
+
+ $puppet_application_mode = @run_mode
+ $puppet_application_name = name
+
+ if Puppet.respond_to? :settings
+ # This is to reduce the amount of confusion in rspec
+ # because it might have loaded defaults.rb before the globals were set
+ # and thus have the wrong defaults for the current application
+ Puppet.settings.set_value(:confdir, Puppet.run_mode.conf_dir, :mutable_defaults)
+ Puppet.settings.set_value(:vardir, Puppet.run_mode.var_dir, :mutable_defaults)
+ Puppet.settings.set_value(:name, Puppet.application_name.to_s, :mutable_defaults)
+ Puppet.settings.set_value(:logdir, Puppet.run_mode.logopts, :mutable_defaults)
+ Puppet.settings.set_value(:rundir, Puppet.run_mode.run_dir, :mutable_defaults)
+ Puppet.settings.set_value(:mode, Puppet.run_mode.name.to_s, :mutable_defaults)
end
- def parse_options
- # get all puppet options
- optparse_opt = []
- optparse_opt = Puppet.settings.optparse_addargs(optparse_opt)
+ require 'puppet'
+ end
+
+ # This is the main application entry point
+ def run
+ exit_on_fail("initialize") { preinit }
+ exit_on_fail("parse options") { parse_options }
+ exit_on_fail("parse configuration file") { Puppet.settings.parse } if should_parse_config?
+ exit_on_fail("prepare for execution") { setup }
+ exit_on_fail("run") { run_command }
+ end
+
+ def main
+ raise NotImplementedError, "No valid command or main"
+ end
+
+ def run_command
+ main
+ end
+
+ def setup
+ # Handle the logging settings
+ if options[:debug] or options[:verbose]
+ Puppet::Util::Log.newdestination(:console)
+ if options[:debug]
+ Puppet::Util::Log.level = :debug
+ else
+ Puppet::Util::Log.level = :info
+ end
+ end
- # convert them to OptionParser format
- optparse_opt.each do |option|
- self.option_parser.on(*option) do |arg|
- handlearg(option[0], arg)
- end
- end
+ Puppet::Util::Log.newdestination(:syslog) unless options[:setdest]
+ end
- # scan command line argument
- begin
- self.option_parser.parse!
- rescue OptionParser::ParseError => detail
- $stderr.puts detail
- $stderr.puts "Try 'puppet #{command_line.subcommand_name} --help'"
- exit(1)
- end
- end
+ def parse_options
+ # get all puppet options
+ optparse_opt = []
+ optparse_opt = Puppet.settings.optparse_addargs(optparse_opt)
- def handlearg(opt, arg)
- # rewrite --[no-]option to --no-option if that's what was given
- if opt =~ /\[no-\]/ and !arg
- opt = opt.gsub(/\[no-\]/,'no-')
- end
- # otherwise remove the [no-] prefix to not confuse everybody
- opt = opt.gsub(/\[no-\]/, '')
- unless respond_to?(:handle_unknown) and send(:handle_unknown, opt, arg)
- # Puppet.settings.handlearg doesn't handle direct true/false :-)
- if arg.is_a?(FalseClass)
- arg = "false"
- elsif arg.is_a?(TrueClass)
- arg = "true"
- end
- Puppet.settings.handlearg(opt, arg)
- end
+ # convert them to OptionParser format
+ optparse_opt.each do |option|
+ self.option_parser.on(*option) do |arg|
+ handlearg(option[0], arg)
+ end
end
- # this is used for testing
- def self.exit(code)
- exit(code)
+ # scan command line argument
+ begin
+ self.option_parser.parse!
+ rescue OptionParser::ParseError => detail
+ $stderr.puts detail
+ $stderr.puts "Try 'puppet #{command_line.subcommand_name} --help'"
+ exit(1)
end
+ end
- def name
- self.class.to_s.sub(/.*::/,"").downcase.to_sym
+ def handlearg(opt, arg)
+ # rewrite --[no-]option to --no-option if that's what was given
+ if opt =~ /\[no-\]/ and !arg
+ opt = opt.gsub(/\[no-\]/,'no-')
end
-
- def help
- if Puppet.features.usage?
- # RH:FIXME: My goodness, this is ugly.
- ::RDoc.const_set("PuppetSourceFile", name)
- #:stopdoc: # Issue #4161
- def (::RDoc).caller
- docfile = `grep -l 'Puppet::Application\\[:#{::RDoc::PuppetSourceFile}\\]' #{DOCPATTERN}`.chomp
- super << "#{docfile}:0"
- end
- #:startdoc:
- ::RDoc::usage && exit
- else
- puts "No help available unless you have RDoc::usage installed"
- exit
- end
- rescue Errno::ENOENT
- puts "No help available for puppet #{name}"
- exit
+ # otherwise remove the [no-] prefix to not confuse everybody
+ opt = opt.gsub(/\[no-\]/, '')
+ unless respond_to?(:handle_unknown) and send(:handle_unknown, opt, arg)
+ # Puppet.settings.handlearg doesn't handle direct true/false :-)
+ if arg.is_a?(FalseClass)
+ arg = "false"
+ elsif arg.is_a?(TrueClass)
+ arg = "true"
+ end
+ Puppet.settings.handlearg(opt, arg)
end
-
- private
-
- def exit_on_fail(message, code = 1)
- yield
- rescue RuntimeError, NotImplementedError => detail
- puts detail.backtrace if Puppet[:trace]
- $stderr.puts "Could not #{message}: #{detail}"
- exit(code)
+ end
+
+ # this is used for testing
+ def self.exit(code)
+ exit(code)
+ end
+
+ def name
+ self.class.to_s.sub(/.*::/,"").downcase.to_sym
+ end
+
+ def help
+ if Puppet.features.usage?
+ # RH:FIXME: My goodness, this is ugly.
+ ::RDoc.const_set("PuppetSourceFile", name)
+ #:stopdoc: # Issue #4161
+ def (::RDoc).caller
+ docfile = `grep -l 'Puppet::Application\\[:#{::RDoc::PuppetSourceFile}\\]' #{DOCPATTERN}`.chomp
+ super << "#{docfile}:0"
+ end
+ #:startdoc:
+ ::RDoc::usage && exit
+ else
+ puts "No help available unless you have RDoc::usage installed"
+ exit
end
+ rescue Errno::ENOENT
+ puts "No help available for puppet #{name}"
+ exit
+ end
+
+ private
+
+ def exit_on_fail(message, code = 1)
+ yield
+ rescue RuntimeError, NotImplementedError => detail
+ puts detail.backtrace if Puppet[:trace]
+ $stderr.puts "Could not #{message}: #{detail}"
+ exit(code)
+ end
end
end
diff --git a/lib/puppet/application/agent.rb b/lib/puppet/application/agent.rb
index 2d7ac1b..b90bdd4 100644
--- a/lib/puppet/application/agent.rb
+++ b/lib/puppet/application/agent.rb
@@ -2,268 +2,268 @@ require 'puppet/application'
class Puppet::Application::Agent < Puppet::Application
- should_parse_config
- run_mode :agent
-
- attr_accessor :explicit_waitforcert, :args, :agent, :daemon, :host
-
- def preinit
- # Do an initial trap, so that cancels don't get a stack trace.
- trap(:INT) do
- $stderr.puts "Cancelling startup"
- exit(0)
- end
-
- {
- :waitforcert => 120, # Default to checking for certs every 5 minutes
- :detailed_exitcodes => false,
- :verbose => false,
- :debug => false,
- :centrallogs => false,
- :setdest => false,
- :enable => false,
- :disable => false,
- :client => true,
- :fqdn => nil,
- :serve => [],
- :digest => :MD5,
- :fingerprint => false,
- }.each do |opt,val|
- options[opt] = val
- end
-
- @explicit_waitforcert = false
- @args = {}
- require 'puppet/daemon'
- @daemon = Puppet::Daemon.new
- @daemon.argv = ARGV.dup
- end
+ should_parse_config
+ run_mode :agent
- option("--centrallogging")
- option("--disable")
- option("--enable")
- option("--debug","-d")
- option("--fqdn FQDN","-f")
- option("--test","-t")
- option("--verbose","-v")
-
- option("--fingerprint")
- option("--digest DIGEST")
-
- option("--serve HANDLER", "-s") do |arg|
- if Puppet::Network::Handler.handler(arg)
- options[:serve] << arg.to_sym
- else
- raise "Could not find handler for #{arg}"
- end
- end
+ attr_accessor :explicit_waitforcert, :args, :agent, :daemon, :host
- option("--no-client") do |arg|
- options[:client] = false
+ def preinit
+ # Do an initial trap, so that cancels don't get a stack trace.
+ trap(:INT) do
+ $stderr.puts "Cancelling startup"
+ exit(0)
end
- option("--onetime", "-o") do |arg|
- Puppet[:onetime] = true
- options[:waitforcert] = 0 unless @explicit_waitforcert
+ {
+ :waitforcert => 120, # Default to checking for certs every 5 minutes
+ :detailed_exitcodes => false,
+ :verbose => false,
+ :debug => false,
+ :centrallogs => false,
+ :setdest => false,
+ :enable => false,
+ :disable => false,
+ :client => true,
+ :fqdn => nil,
+ :serve => [],
+ :digest => :MD5,
+ :fingerprint => false,
+ }.each do |opt,val|
+ options[opt] = val
end
- option("--detailed-exitcodes") do |arg|
- options[:detailed_exitcodes] = true
+ @explicit_waitforcert = false
+ @args = {}
+ require 'puppet/daemon'
+ @daemon = Puppet::Daemon.new
+ @daemon.argv = ARGV.dup
+ end
+
+ option("--centrallogging")
+ option("--disable")
+ option("--enable")
+ option("--debug","-d")
+ option("--fqdn FQDN","-f")
+ option("--test","-t")
+ option("--verbose","-v")
+
+ option("--fingerprint")
+ option("--digest DIGEST")
+
+ option("--serve HANDLER", "-s") do |arg|
+ if Puppet::Network::Handler.handler(arg)
+ options[:serve] << arg.to_sym
+ else
+ raise "Could not find handler for #{arg}"
end
-
- option("--logdest DEST", "-l DEST") do |arg|
- begin
- Puppet::Util::Log.newdestination(arg)
- options[:setdest] = true
- rescue => detail
- puts detail.backtrace if Puppet[:debug]
- $stderr.puts detail.to_s
- end
+ end
+
+ option("--no-client") do |arg|
+ options[:client] = false
+ end
+
+ option("--onetime", "-o") do |arg|
+ Puppet[:onetime] = true
+ options[:waitforcert] = 0 unless @explicit_waitforcert
+ end
+
+ option("--detailed-exitcodes") do |arg|
+ options[:detailed_exitcodes] = true
+ end
+
+ option("--logdest DEST", "-l DEST") do |arg|
+ begin
+ Puppet::Util::Log.newdestination(arg)
+ options[:setdest] = true
+ rescue => detail
+ puts detail.backtrace if Puppet[:debug]
+ $stderr.puts detail.to_s
end
-
- option("--waitforcert WAITFORCERT", "-w") do |arg|
- options[:waitforcert] = arg.to_i
- @explicit_waitforcert = true
+ end
+
+ option("--waitforcert WAITFORCERT", "-w") do |arg|
+ options[:waitforcert] = arg.to_i
+ @explicit_waitforcert = true
+ end
+
+ option("--port PORT","-p") do |arg|
+ @args[:Port] = arg
+ end
+
+ def run_command
+ return fingerprint if options[:fingerprint]
+ return onetime if Puppet[:onetime]
+ main
+ end
+
+ def fingerprint
+ unless cert = host.certificate || host.certificate_request
+ $stderr.puts "Fingerprint asked but no certificate nor certificate request have yet been issued"
+ exit(1)
+ return
end
-
- option("--port PORT","-p") do |arg|
- @args[:Port] = arg
+ unless fingerprint = cert.fingerprint(options[:digest])
+ raise ArgumentError, "Could not get fingerprint for digest '#{options[:digest]}'"
end
-
- def run_command
- return fingerprint if options[:fingerprint]
- return onetime if Puppet[:onetime]
- main
+ Puppet.notice fingerprint
+ end
+
+ def onetime
+ unless options[:client]
+ $stderr.puts "onetime is specified but there is no client"
+ exit(43)
+ return
end
- def fingerprint
- unless cert = host.certificate || host.certificate_request
- $stderr.puts "Fingerprint asked but no certificate nor certificate request have yet been issued"
- exit(1)
- return
- end
- unless fingerprint = cert.fingerprint(options[:digest])
- raise ArgumentError, "Could not get fingerprint for digest '#{options[:digest]}'"
- end
- Puppet.notice fingerprint
- end
+ @daemon.set_signal_traps
- def onetime
- unless options[:client]
- $stderr.puts "onetime is specified but there is no client"
- exit(43)
- return
- end
-
- @daemon.set_signal_traps
-
- begin
- report = @agent.run
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err detail.to_s
- end
-
- if not report
- exit(1)
- elsif not Puppet[:noop] and options[:detailed_exitcodes] then
- exit(report.exit_status)
- else
- exit(0)
- end
+ begin
+ report = @agent.run
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err detail.to_s
end
- def main
- Puppet.notice "Starting Puppet client version #{Puppet.version}"
-
- @daemon.start
+ if not report
+ exit(1)
+ elsif not Puppet[:noop] and options[:detailed_exitcodes] then
+ exit(report.exit_status)
+ else
+ exit(0)
end
-
- # Enable all of the most common test options.
- def setup_test
- Puppet.settings.handlearg("--ignorecache")
- Puppet.settings.handlearg("--no-usecacheonfailure")
- Puppet.settings.handlearg("--no-splay")
- Puppet.settings.handlearg("--show_diff")
- Puppet.settings.handlearg("--no-daemonize")
- options[:verbose] = true
- Puppet[:onetime] = true
- options[:detailed_exitcodes] = true
- options[:waitforcert] = 0 unless @explicit_waitforcert
+ end
+
+ def main
+ Puppet.notice "Starting Puppet client version #{Puppet.version}"
+
+ @daemon.start
+ end
+
+ # Enable all of the most common test options.
+ def setup_test
+ Puppet.settings.handlearg("--ignorecache")
+ Puppet.settings.handlearg("--no-usecacheonfailure")
+ Puppet.settings.handlearg("--no-splay")
+ Puppet.settings.handlearg("--show_diff")
+ Puppet.settings.handlearg("--no-daemonize")
+ options[:verbose] = true
+ Puppet[:onetime] = true
+ options[:detailed_exitcodes] = true
+ options[:waitforcert] = 0 unless @explicit_waitforcert
+ end
+
+ # Handle the logging settings.
+ def setup_logs
+ if options[:debug] or options[:verbose]
+ Puppet::Util::Log.newdestination(:console)
+ if options[:debug]
+ Puppet::Util::Log.level = :debug
+ else
+ Puppet::Util::Log.level = :info
+ end
end
- # Handle the logging settings.
- def setup_logs
- if options[:debug] or options[:verbose]
- Puppet::Util::Log.newdestination(:console)
- if options[:debug]
- Puppet::Util::Log.level = :debug
- else
- Puppet::Util::Log.level = :info
- end
- end
-
- Puppet::Util::Log.newdestination(:syslog) unless options[:setdest]
+ Puppet::Util::Log.newdestination(:syslog) unless options[:setdest]
+ end
+
+ def enable_disable_client(agent)
+ if options[:enable]
+ agent.enable
+ elsif options[:disable]
+ agent.disable
end
+ exit(0)
+ end
- def enable_disable_client(agent)
- if options[:enable]
- agent.enable
- elsif options[:disable]
- agent.disable
- end
- exit(0)
+ def setup_listen
+ unless FileTest.exists?(Puppet[:authconfig])
+ Puppet.err "Will not start without authorization file #{Puppet[:authconfig]}"
+ exit(14)
end
- def setup_listen
- unless FileTest.exists?(Puppet[:authconfig])
- Puppet.err "Will not start without authorization file #{Puppet[:authconfig]}"
- exit(14)
- end
+ handlers = nil
- handlers = nil
+ if options[:serve].empty?
+ handlers = [:Runner]
+ else
+ handlers = options[:serve]
+ end
- if options[:serve].empty?
- handlers = [:Runner]
- else
- handlers = options[:serve]
- end
+ require 'puppet/network/server'
+ # No REST handlers yet.
+ server = Puppet::Network::Server.new(:xmlrpc_handlers => handlers, :port => Puppet[:puppetport])
- require 'puppet/network/server'
- # No REST handlers yet.
- server = Puppet::Network::Server.new(:xmlrpc_handlers => handlers, :port => Puppet[:puppetport])
+ @daemon.server = server
+ end
- @daemon.server = server
- end
+ def setup
+ setup_test if options[:test]
- def setup
- setup_test if options[:test]
+ setup_logs
- setup_logs
+ exit(Puppet.settings.print_configs ? 0 : 1) if Puppet.settings.print_configs?
- exit(Puppet.settings.print_configs ? 0 : 1) if Puppet.settings.print_configs?
+ # If noop is set, then also enable diffs
+ Puppet[:show_diff] = true if Puppet[:noop]
- # If noop is set, then also enable diffs
- Puppet[:show_diff] = true if Puppet[:noop]
-
- args[:Server] = Puppet[:server]
- if options[:fqdn]
- args[:FQDN] = options[:fqdn]
- Puppet[:certname] = options[:fqdn]
- end
+ args[:Server] = Puppet[:server]
+ if options[:fqdn]
+ args[:FQDN] = options[:fqdn]
+ Puppet[:certname] = options[:fqdn]
+ end
- if options[:centrallogs]
- logdest = args[:Server]
+ if options[:centrallogs]
+ logdest = args[:Server]
- logdest += ":" + args[:Port] if args.include?(:Port)
- Puppet::Util::Log.newdestination(logdest)
- end
+ logdest += ":" + args[:Port] if args.include?(:Port)
+ Puppet::Util::Log.newdestination(logdest)
+ end
- Puppet.settings.use :main, :agent, :ssl
+ Puppet.settings.use :main, :agent, :ssl
- # We need to specify a ca location for all of the SSL-related i
- # indirected classes to work; in fingerprint mode we just need
- # access to the local files and we don't need a ca.
- Puppet::SSL::Host.ca_location = options[:fingerprint] ? :none : :remote
+ # We need to specify a ca location for all of the SSL-related i
+ # indirected classes to work; in fingerprint mode we just need
+ # access to the local files and we don't need a ca.
+ Puppet::SSL::Host.ca_location = options[:fingerprint] ? :none : :remote
- Puppet::Transaction::Report.terminus_class = :rest
+ Puppet::Transaction::Report.terminus_class = :rest
- # Override the default; puppetd needs this, usually.
- # You can still override this on the command-line with, e.g., :compiler.
- Puppet[:catalog_terminus] = :rest
+ # Override the default; puppetd needs this, usually.
+ # You can still override this on the command-line with, e.g., :compiler.
+ Puppet[:catalog_terminus] = :rest
- # Override the default.
- Puppet[:facts_terminus] = :facter
+ # Override the default.
+ Puppet[:facts_terminus] = :facter
- Puppet::Resource::Catalog.cache_class = :yaml
+ Puppet::Resource::Catalog.cache_class = :yaml
- # We need tomake the client either way, we just don't start it
- # if --no-client is set.
- require 'puppet/agent'
- require 'puppet/configurer'
- @agent = Puppet::Agent.new(Puppet::Configurer)
+ # We need tomake the client either way, we just don't start it
+ # if --no-client is set.
+ require 'puppet/agent'
+ require 'puppet/configurer'
+ @agent = Puppet::Agent.new(Puppet::Configurer)
- enable_disable_client(@agent) if options[:enable] or options[:disable]
+ enable_disable_client(@agent) if options[:enable] or options[:disable]
- @daemon.agent = agent if options[:client]
+ @daemon.agent = agent if options[:client]
- # It'd be nice to daemonize later, but we have to daemonize before the
- # waitforcert happens.
- @daemon.daemonize if Puppet[:daemonize]
+ # It'd be nice to daemonize later, but we have to daemonize before the
+ # waitforcert happens.
+ @daemon.daemonize if Puppet[:daemonize]
- @host = Puppet::SSL::Host.new
- cert = @host.wait_for_cert(options[:waitforcert]) unless options[:fingerprint]
+ @host = Puppet::SSL::Host.new
+ cert = @host.wait_for_cert(options[:waitforcert]) unless options[:fingerprint]
- @objects = []
+ @objects = []
- # This has to go after the certs are dealt with.
- if Puppet[:listen]
- unless Puppet[:onetime]
- setup_listen
- else
- Puppet.notice "Ignoring --listen on onetime run"
- end
- end
+ # This has to go after the certs are dealt with.
+ if Puppet[:listen]
+ unless Puppet[:onetime]
+ setup_listen
+ else
+ Puppet.notice "Ignoring --listen on onetime run"
+ end
end
+ end
end
diff --git a/lib/puppet/application/apply.rb b/lib/puppet/application/apply.rb
index cd4c75d..bb4186d 100644
--- a/lib/puppet/application/apply.rb
+++ b/lib/puppet/application/apply.rb
@@ -2,164 +2,164 @@ require 'puppet/application'
class Puppet::Application::Apply < Puppet::Application
- should_parse_config
-
- option("--debug","-d")
- option("--execute EXECUTE","-e") do |arg|
- options[:code] = arg
+ should_parse_config
+
+ option("--debug","-d")
+ option("--execute EXECUTE","-e") do |arg|
+ options[:code] = arg
+ end
+ option("--loadclasses","-L")
+ option("--verbose","-v")
+ option("--use-nodes")
+ option("--detailed-exitcodes")
+
+ option("--apply catalog", "-a catalog") do |arg|
+ options[:catalog] = arg
+ end
+
+ option("--logdest LOGDEST", "-l") do |arg|
+ begin
+ Puppet::Util::Log.newdestination(arg)
+ options[:logset] = true
+ rescue => detail
+ $stderr.puts detail.to_s
end
- option("--loadclasses","-L")
- option("--verbose","-v")
- option("--use-nodes")
- option("--detailed-exitcodes")
-
- option("--apply catalog", "-a catalog") do |arg|
- options[:catalog] = arg
+ end
+
+ def run_command
+ if options[:catalog]
+ apply
+ elsif Puppet[:parseonly]
+ parseonly
+ else
+ main
end
+ end
- option("--logdest LOGDEST", "-l") do |arg|
- begin
- Puppet::Util::Log.newdestination(arg)
- options[:logset] = true
- rescue => detail
- $stderr.puts detail.to_s
- end
+ def apply
+ if options[:catalog] == "-"
+ text = $stdin.read
+ else
+ text = File.read(options[:catalog])
end
- def run_command
- if options[:catalog]
- apply
- elsif Puppet[:parseonly]
- parseonly
- else
- main
- end
+ begin
+ catalog = Puppet::Resource::Catalog.convert_from(Puppet::Resource::Catalog.default_format,text)
+ catalog = Puppet::Resource::Catalog.pson_create(catalog) unless catalog.is_a?(Puppet::Resource::Catalog)
+ rescue => detail
+ raise Puppet::Error, "Could not deserialize catalog from pson: #{detail}"
end
- def apply
- if options[:catalog] == "-"
- text = $stdin.read
- else
- text = File.read(options[:catalog])
- end
+ catalog = catalog.to_ral
- begin
- catalog = Puppet::Resource::Catalog.convert_from(Puppet::Resource::Catalog.default_format,text)
- catalog = Puppet::Resource::Catalog.pson_create(catalog) unless catalog.is_a?(Puppet::Resource::Catalog)
- rescue => detail
- raise Puppet::Error, "Could not deserialize catalog from pson: #{detail}"
- end
+ require 'puppet/configurer'
+ configurer = Puppet::Configurer.new
+ configurer.run :catalog => catalog
+ end
- catalog = catalog.to_ral
-
- require 'puppet/configurer'
- configurer = Puppet::Configurer.new
- configurer.run :catalog => catalog
+ def parseonly
+ # Set our code or file to use.
+ if options[:code] or command_line.args.length == 0
+ Puppet[:code] = options[:code] || STDIN.read
+ else
+ Puppet[:manifest] = command_line.args.shift
end
-
- def parseonly
- # Set our code or file to use.
- if options[:code] or command_line.args.length == 0
- Puppet[:code] = options[:code] || STDIN.read
- else
- Puppet[:manifest] = command_line.args.shift
- end
- begin
- Puppet::Node::Environment.new(Puppet[:environment]).known_resource_types
- rescue => detail
- Puppet.err detail
- exit 1
- end
- exit 0
+ begin
+ Puppet::Node::Environment.new(Puppet[:environment]).known_resource_types
+ rescue => detail
+ Puppet.err detail
+ exit 1
+ end
+ exit 0
+ end
+
+ def main
+ # Set our code or file to use.
+ if options[:code] or command_line.args.length == 0
+ Puppet[:code] = options[:code] || STDIN.read
+ else
+ Puppet[:manifest] = command_line.args.shift
end
- def main
- # Set our code or file to use.
- if options[:code] or command_line.args.length == 0
- Puppet[:code] = options[:code] || STDIN.read
- else
- Puppet[:manifest] = command_line.args.shift
- end
+ # Collect our facts.
+ unless facts = Puppet::Node::Facts.find(Puppet[:certname])
+ raise "Could not find facts for #{Puppet[:certname]}"
+ end
- # Collect our facts.
- unless facts = Puppet::Node::Facts.find(Puppet[:certname])
- raise "Could not find facts for #{Puppet[:certname]}"
- end
+ # Find our Node
+ unless node = Puppet::Node.find(Puppet[:certname])
+ raise "Could not find node #{Puppet[:certname]}"
+ end
- # Find our Node
- unless node = Puppet::Node.find(Puppet[:certname])
- raise "Could not find node #{Puppet[:certname]}"
- end
+ # Merge in the facts.
+ node.merge(facts.values)
- # Merge in the facts.
- node.merge(facts.values)
-
- # Allow users to load the classes that puppet agent creates.
- if options[:loadclasses]
- file = Puppet[:classfile]
- if FileTest.exists?(file)
- unless FileTest.readable?(file)
- $stderr.puts "#{file} is not readable"
- exit(63)
- end
- node.classes = File.read(file).split(/[\s\n]+/)
- end
+ # Allow users to load the classes that puppet agent creates.
+ if options[:loadclasses]
+ file = Puppet[:classfile]
+ if FileTest.exists?(file)
+ unless FileTest.readable?(file)
+ $stderr.puts "#{file} is not readable"
+ exit(63)
end
+ node.classes = File.read(file).split(/[\s\n]+/)
+ end
+ end
- begin
- # Compile our catalog
- starttime = Time.now
- catalog = Puppet::Resource::Catalog.find(node.name, :use_node => node)
+ begin
+ # Compile our catalog
+ starttime = Time.now
+ catalog = Puppet::Resource::Catalog.find(node.name, :use_node => node)
- # Translate it to a RAL catalog
- catalog = catalog.to_ral
+ # Translate it to a RAL catalog
+ catalog = catalog.to_ral
- catalog.finalize
+ catalog.finalize
- catalog.retrieval_duration = Time.now - starttime
+ catalog.retrieval_duration = Time.now - starttime
- require 'puppet/configurer'
- configurer = Puppet::Configurer.new
- configurer.execute_prerun_command
+ require 'puppet/configurer'
+ configurer = Puppet::Configurer.new
+ configurer.execute_prerun_command
- # And apply it
- transaction = catalog.apply
+ # And apply it
+ transaction = catalog.apply
- configurer.execute_postrun_command
+ configurer.execute_postrun_command
- status = 0
- if not Puppet[:noop] and options[:detailed_exitcodes]
- transaction.generate_report
- exit(transaction.report.exit_status)
- else
- exit(0)
- end
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- $stderr.puts detail.message
- exit(1)
- end
+ status = 0
+ if not Puppet[:noop] and options[:detailed_exitcodes]
+ transaction.generate_report
+ exit(transaction.report.exit_status)
+ else
+ exit(0)
+ end
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ $stderr.puts detail.message
+ exit(1)
end
+ end
- def setup
- exit(Puppet.settings.print_configs ? 0 : 1) if Puppet.settings.print_configs?
+ def setup
+ exit(Puppet.settings.print_configs ? 0 : 1) if Puppet.settings.print_configs?
- # If noop is set, then also enable diffs
- Puppet[:show_diff] = true if Puppet[:noop]
+ # If noop is set, then also enable diffs
+ Puppet[:show_diff] = true if Puppet[:noop]
- Puppet::Util::Log.newdestination(:console) unless options[:logset]
- client = nil
- server = nil
+ Puppet::Util::Log.newdestination(:console) unless options[:logset]
+ client = nil
+ server = nil
- trap(:INT) do
- $stderr.puts "Exiting"
- exit(1)
- end
+ trap(:INT) do
+ $stderr.puts "Exiting"
+ exit(1)
+ end
- if options[:debug]
- Puppet::Util::Log.level = :debug
- elsif options[:verbose]
- Puppet::Util::Log.level = :info
- end
+ if options[:debug]
+ Puppet::Util::Log.level = :debug
+ elsif options[:verbose]
+ Puppet::Util::Log.level = :info
end
+ end
end
diff --git a/lib/puppet/application/cert.rb b/lib/puppet/application/cert.rb
index af90429..467b0c8 100644
--- a/lib/puppet/application/cert.rb
+++ b/lib/puppet/application/cert.rb
@@ -2,84 +2,84 @@ require 'puppet/application'
class Puppet::Application::Cert < Puppet::Application
- should_parse_config
- run_mode :master
-
- attr_accessor :cert_mode, :all, :ca, :digest, :signed
-
- def find_mode(opt)
- require 'puppet/ssl/certificate_authority'
- modes = Puppet::SSL::CertificateAuthority::Interface::INTERFACE_METHODS
- tmp = opt.sub("--", '').to_sym
- @cert_mode = modes.include?(tmp) ? tmp : nil
- end
-
- option("--clean", "-c") do
- @cert_mode = :destroy
+ should_parse_config
+ run_mode :master
+
+ attr_accessor :cert_mode, :all, :ca, :digest, :signed
+
+ def find_mode(opt)
+ require 'puppet/ssl/certificate_authority'
+ modes = Puppet::SSL::CertificateAuthority::Interface::INTERFACE_METHODS
+ tmp = opt.sub("--", '').to_sym
+ @cert_mode = modes.include?(tmp) ? tmp : nil
+ end
+
+ option("--clean", "-c") do
+ @cert_mode = :destroy
+ end
+
+ option("--all", "-a") do
+ @all = true
+ end
+
+ option("--digest DIGEST") do |arg|
+ @digest = arg
+ end
+
+ option("--signed", "-s") do
+ @signed = true
+ end
+
+ option("--debug", "-d") do |arg|
+ Puppet::Util::Log.level = :debug
+ end
+
+ require 'puppet/ssl/certificate_authority/interface'
+ Puppet::SSL::CertificateAuthority::Interface::INTERFACE_METHODS.reject {|m| m == :destroy }.each do |method|
+ option("--#{method}", "-#{method.to_s[0,1]}") do
+ find_mode("--#{method}")
end
-
- option("--all", "-a") do
- @all = true
+ end
+
+ option("--verbose", "-v") do
+ Puppet::Util::Log.level = :info
+ end
+
+ def main
+ if @all
+ hosts = :all
+ elsif @signed
+ hosts = :signed
+ else
+ hosts = command_line.args.collect { |h| h.downcase }
end
-
- option("--digest DIGEST") do |arg|
- @digest = arg
+ begin
+ @ca.apply(:revoke, :to => hosts) if @cert_mode == :destroy
+ @ca.apply(@cert_mode, :to => hosts, :digest => @digest)
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ puts detail.to_s
+ exit(24)
end
+ end
- option("--signed", "-s") do
- @signed = true
- end
+ def setup
+ exit(Puppet.settings.print_configs ? 0 : 1) if Puppet.settings.print_configs?
- option("--debug", "-d") do |arg|
- Puppet::Util::Log.level = :debug
- end
+ Puppet::Util::Log.newdestination :console
- require 'puppet/ssl/certificate_authority/interface'
- Puppet::SSL::CertificateAuthority::Interface::INTERFACE_METHODS.reject {|m| m == :destroy }.each do |method|
- option("--#{method}", "-#{method.to_s[0,1]}") do
- find_mode("--#{method}")
- end
+ if [:generate, :destroy].include? @cert_mode
+ Puppet::SSL::Host.ca_location = :local
+ else
+ Puppet::SSL::Host.ca_location = :only
end
- option("--verbose", "-v") do
- Puppet::Util::Log.level = :info
- end
-
- def main
- if @all
- hosts = :all
- elsif @signed
- hosts = :signed
- else
- hosts = command_line.args.collect { |h| h.downcase }
- end
- begin
- @ca.apply(:revoke, :to => hosts) if @cert_mode == :destroy
- @ca.apply(@cert_mode, :to => hosts, :digest => @digest)
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- puts detail.to_s
- exit(24)
- end
- end
-
- def setup
- exit(Puppet.settings.print_configs ? 0 : 1) if Puppet.settings.print_configs?
-
- Puppet::Util::Log.newdestination :console
-
- if [:generate, :destroy].include? @cert_mode
- Puppet::SSL::Host.ca_location = :local
- else
- Puppet::SSL::Host.ca_location = :only
- end
-
- begin
- @ca = Puppet::SSL::CertificateAuthority.new
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- puts detail.to_s
- exit(23)
- end
+ begin
+ @ca = Puppet::SSL::CertificateAuthority.new
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ puts detail.to_s
+ exit(23)
end
+ end
end
diff --git a/lib/puppet/application/describe.rb b/lib/puppet/application/describe.rb
index 64246d1..5abe3ea 100644
--- a/lib/puppet/application/describe.rb
+++ b/lib/puppet/application/describe.rb
@@ -2,202 +2,202 @@ require 'puppet/application'
class Formatter
- def initialize(width)
- @width = width
+ def initialize(width)
+ @width = width
+ end
+
+ def wrap(txt, opts)
+ return "" unless txt && !txt.empty?
+ work = (opts[:scrub] ? scrub(txt) : txt)
+ indent = (opts[:indent] ? opts[:indent] : 0)
+ textLen = @width - indent
+ patt = Regexp.new("^(.{0,#{textLen}})[ \n]")
+ prefix = " " * indent
+
+ res = []
+
+ while work.length > textLen
+ if work =~ patt
+ res << $1
+ work.slice!(0, $MATCH.length)
+ else
+ res << work.slice!(0, textLen)
+ end
end
-
- def wrap(txt, opts)
- return "" unless txt && !txt.empty?
- work = (opts[:scrub] ? scrub(txt) : txt)
- indent = (opts[:indent] ? opts[:indent] : 0)
- textLen = @width - indent
- patt = Regexp.new("^(.{0,#{textLen}})[ \n]")
- prefix = " " * indent
-
- res = []
-
- while work.length > textLen
- if work =~ patt
- res << $1
- work.slice!(0, $MATCH.length)
- else
- res << work.slice!(0, textLen)
- end
- end
- res << work if work.length.nonzero?
- prefix + res.join("\n#{prefix}")
- end
-
- def header(txt, sep = "-")
- "\n#{txt}\n" + sep * txt.size
- end
-
- private
-
- def scrub(text)
- # For text with no carriage returns, there's nothing to do.
- return text if text !~ /\n/
- indent = nil
-
- # If we can match an indentation, then just remove that same level of
- # indent from every line.
- if text =~ /^(\s+)/
- indent = $1
- return text.gsub(/^#{indent}/,'')
- else
- return text
- end
+ res << work if work.length.nonzero?
+ prefix + res.join("\n#{prefix}")
+ end
+
+ def header(txt, sep = "-")
+ "\n#{txt}\n" + sep * txt.size
+ end
+
+ private
+
+ def scrub(text)
+ # For text with no carriage returns, there's nothing to do.
+ return text if text !~ /\n/
+ indent = nil
+
+ # If we can match an indentation, then just remove that same level of
+ # indent from every line.
+ if text =~ /^(\s+)/
+ indent = $1
+ return text.gsub(/^#{indent}/,'')
+ else
+ return text
end
+ end
end
class TypeDoc
- def initialize
- @format = Formatter.new(76)
- @types = {}
- Puppet::Type.loadall
- Puppet::Type.eachtype { |type|
- next if type.name == :component
- @types[type.name] = type
- }
+ def initialize
+ @format = Formatter.new(76)
+ @types = {}
+ Puppet::Type.loadall
+ Puppet::Type.eachtype { |type|
+ next if type.name == :component
+ @types[type.name] = type
+ }
+ end
+
+ def list_types
+ puts "These are the types known to puppet:\n"
+ @types.keys.sort { |a, b|
+ a.to_s <=> b.to_s
+ }.each do |name|
+ type = @types[name]
+ s = type.doc.gsub(/\s+/, " ")
+ n = s.index(".")
+ if n.nil?
+ s = ".. no documentation .."
+ elsif n > 45
+ s = s[0, 45] + " ..."
+ else
+ s = s[0, n]
+ end
+ printf "%-15s - %s\n", name, s
end
+ end
- def list_types
- puts "These are the types known to puppet:\n"
- @types.keys.sort { |a, b|
- a.to_s <=> b.to_s
- }.each do |name|
- type = @types[name]
- s = type.doc.gsub(/\s+/, " ")
- n = s.index(".")
- if n.nil?
- s = ".. no documentation .."
- elsif n > 45
- s = s[0, 45] + " ..."
- else
- s = s[0, n]
- end
- printf "%-15s - %s\n", name, s
- end
+ def format_type(name, opts)
+ name = name.to_sym
+ unless @types.has_key?(name)
+ puts "Unknown type #{name}"
+ return
end
-
- def format_type(name, opts)
- name = name.to_sym
- unless @types.has_key?(name)
- puts "Unknown type #{name}"
- return
- end
- type = @types[name]
- puts @format.header(name.to_s, "=")
- puts @format.wrap(type.doc, :indent => 0, :scrub => true) + "\n\n"
-
- puts @format.header("Parameters")
- if opts[:parameters]
- format_attrs(type, [:property, :param])
- else
- list_attrs(type, [:property, :param])
- end
-
- if opts[:meta]
- puts @format.header("Meta Parameters")
- if opts[:parameters]
- format_attrs(type, [:meta])
- else
- list_attrs(type, [:meta])
- end
- end
-
- if type.providers.size > 0
- puts @format.header("Providers")
- if opts[:providers]
- format_providers(type)
- else
- list_providers(type)
- end
- end
+ type = @types[name]
+ puts @format.header(name.to_s, "=")
+ puts @format.wrap(type.doc, :indent => 0, :scrub => true) + "\n\n"
+
+ puts @format.header("Parameters")
+ if opts[:parameters]
+ format_attrs(type, [:property, :param])
+ else
+ list_attrs(type, [:property, :param])
end
- # List details about attributes
- def format_attrs(type, attrs)
- docs = {}
- type.allattrs.each do |name|
- kind = type.attrtype(name)
- docs[name] = type.attrclass(name).doc if attrs.include?(kind) && name != :provider
- end
-
- docs.sort { |a,b|
- a[0].to_s <=> b[0].to_s
- }.each { |name, doc|
- print "\n- **#{name}**"
- if type.namevar == name and name != :name
- puts " (*namevar*)"
- else
- puts ""
- end
- puts @format.wrap(doc, :indent => 4, :scrub => true)
- }
+ if opts[:meta]
+ puts @format.header("Meta Parameters")
+ if opts[:parameters]
+ format_attrs(type, [:meta])
+ else
+ list_attrs(type, [:meta])
+ end
end
- # List the names of attributes
- def list_attrs(type, attrs)
- params = []
- type.allattrs.each do |name|
- kind = type.attrtype(name)
- params << name.to_s if attrs.include?(kind) && name != :provider
- end
- puts @format.wrap(params.sort.join(", "), :indent => 4)
+ if type.providers.size > 0
+ puts @format.header("Providers")
+ if opts[:providers]
+ format_providers(type)
+ else
+ list_providers(type)
+ end
end
-
- def format_providers(type)
- type.providers.sort { |a,b|
- a.to_s <=> b.to_s
- }.each { |prov|
- puts "\n- **#{prov}**"
- puts @format.wrap(type.provider(prov).doc, :indent => 4, :scrub => true)
- }
+ end
+
+ # List details about attributes
+ def format_attrs(type, attrs)
+ docs = {}
+ type.allattrs.each do |name|
+ kind = type.attrtype(name)
+ docs[name] = type.attrclass(name).doc if attrs.include?(kind) && name != :provider
end
- def list_providers(type)
- list = type.providers.sort { |a,b|
- a.to_s <=> b.to_s
- }.join(", ")
- puts @format.wrap(list, :indent => 4)
+ docs.sort { |a,b|
+ a[0].to_s <=> b[0].to_s
+ }.each { |name, doc|
+ print "\n- **#{name}**"
+ if type.namevar == name and name != :name
+ puts " (*namevar*)"
+ else
+ puts ""
+ end
+ puts @format.wrap(doc, :indent => 4, :scrub => true)
+ }
+ end
+
+ # List the names of attributes
+ def list_attrs(type, attrs)
+ params = []
+ type.allattrs.each do |name|
+ kind = type.attrtype(name)
+ params << name.to_s if attrs.include?(kind) && name != :provider
end
+ puts @format.wrap(params.sort.join(", "), :indent => 4)
+ end
+
+ def format_providers(type)
+ type.providers.sort { |a,b|
+ a.to_s <=> b.to_s
+ }.each { |prov|
+ puts "\n- **#{prov}**"
+ puts @format.wrap(type.provider(prov).doc, :indent => 4, :scrub => true)
+ }
+ end
+
+ def list_providers(type)
+ list = type.providers.sort { |a,b|
+ a.to_s <=> b.to_s
+ }.join(", ")
+ puts @format.wrap(list, :indent => 4)
+ end
end
class Puppet::Application::Describe < Puppet::Application
- banner "puppet describe [options] [type]"
+ banner "puppet describe [options] [type]"
- should_not_parse_config
+ should_not_parse_config
- option("--short", "-s", "Only list parameters without detail") do |arg|
- options[:parameters] = false
- end
+ option("--short", "-s", "Only list parameters without detail") do |arg|
+ options[:parameters] = false
+ end
- option("--providers","-p")
- option("--list", "-l")
- option("--meta","-m")
+ option("--providers","-p")
+ option("--list", "-l")
+ option("--meta","-m")
- def preinit
- options[:parameters] = true
- end
+ def preinit
+ options[:parameters] = true
+ end
- def main
- doc = TypeDoc.new
+ def main
+ doc = TypeDoc.new
- if options[:list]
- doc.list_types
- else
- options[:types].each { |name| doc.format_type(name, options) }
- end
+ if options[:list]
+ doc.list_types
+ else
+ options[:types].each { |name| doc.format_type(name, options) }
end
+ end
- def setup
- options[:types] = command_line.args.dup
- handle_help(nil) unless options[:list] || options[:types].size > 0
- $stderr.puts "Warning: ignoring types when listing all types" if options[:list] && options[:types].size > 0
- end
+ def setup
+ options[:types] = command_line.args.dup
+ handle_help(nil) unless options[:list] || options[:types].size > 0
+ $stderr.puts "Warning: ignoring types when listing all types" if options[:list] && options[:types].size > 0
+ end
end
diff --git a/lib/puppet/application/doc.rb b/lib/puppet/application/doc.rb
index ba07f73..66aa6c8 100644
--- a/lib/puppet/application/doc.rb
+++ b/lib/puppet/application/doc.rb
@@ -2,214 +2,214 @@ require 'puppet/application'
class Puppet::Application::Doc < Puppet::Application
- should_not_parse_config
- run_mode :master
+ should_not_parse_config
+ run_mode :master
- attr_accessor :unknown_args, :manifest
+ attr_accessor :unknown_args, :manifest
- def preinit
- {:references => [], :mode => :text, :format => :to_rest }.each do |name,value|
- options[name] = value
- end
- @unknown_args = []
- @manifest = false
+ def preinit
+ {:references => [], :mode => :text, :format => :to_rest }.each do |name,value|
+ options[name] = value
end
-
- option("--all","-a")
- option("--outputdir OUTPUTDIR","-o")
- option("--verbose","-v")
- option("--debug","-d")
- option("--charset CHARSET")
-
- option("--format FORMAT", "-f") do |arg|
- method = "to_#{arg}"
- require 'puppet/util/reference'
- if Puppet::Util::Reference.method_defined?(method)
- options[:format] = method
- else
- raise "Invalid output format #{arg}"
- end
+ @unknown_args = []
+ @manifest = false
+ end
+
+ option("--all","-a")
+ option("--outputdir OUTPUTDIR","-o")
+ option("--verbose","-v")
+ option("--debug","-d")
+ option("--charset CHARSET")
+
+ option("--format FORMAT", "-f") do |arg|
+ method = "to_#{arg}"
+ require 'puppet/util/reference'
+ if Puppet::Util::Reference.method_defined?(method)
+ options[:format] = method
+ else
+ raise "Invalid output format #{arg}"
end
-
- option("--mode MODE", "-m") do |arg|
- require 'puppet/util/reference'
- if Puppet::Util::Reference.modes.include?(arg) or arg.intern==:rdoc
- options[:mode] = arg.intern
- else
- raise "Invalid output mode #{arg}"
- end
+ end
+
+ option("--mode MODE", "-m") do |arg|
+ require 'puppet/util/reference'
+ if Puppet::Util::Reference.modes.include?(arg) or arg.intern==:rdoc
+ options[:mode] = arg.intern
+ else
+ raise "Invalid output mode #{arg}"
end
-
- option("--list", "-l") do |arg|
- require 'puppet/util/reference'
- puts Puppet::Util::Reference.references.collect { |r| Puppet::Util::Reference.reference(r).doc }.join("\n")
- exit(0)
- end
-
- option("--reference REFERENCE", "-r") do |arg|
- options[:references] << arg.intern
+ end
+
+ option("--list", "-l") do |arg|
+ require 'puppet/util/reference'
+ puts Puppet::Util::Reference.references.collect { |r| Puppet::Util::Reference.reference(r).doc }.join("\n")
+ exit(0)
+ end
+
+ option("--reference REFERENCE", "-r") do |arg|
+ options[:references] << arg.intern
+ end
+
+ def handle_unknown( opt, arg )
+ @unknown_args << {:opt => opt, :arg => arg }
+ true
+ end
+
+ def run_command
+ return[:rdoc, :trac, :markdown].include?(options[:mode]) ? send(options[:mode]) : other
+ end
+
+ def rdoc
+ exit_code = 0
+ files = []
+ unless @manifest
+ env = Puppet::Node::Environment.new
+ files += env.modulepath
+ files << File.dirname(env[:manifest])
end
+ files += command_line.args
+ Puppet.info "scanning: #{files.inspect}"
- def handle_unknown( opt, arg )
- @unknown_args << {:opt => opt, :arg => arg }
- true
- end
-
- def run_command
- return[:rdoc, :trac, :markdown].include?(options[:mode]) ? send(options[:mode]) : other
- end
-
- def rdoc
- exit_code = 0
- files = []
- unless @manifest
- env = Puppet::Node::Environment.new
- files += env.modulepath
- files << File.dirname(env[:manifest])
- end
- files += command_line.args
- Puppet.info "scanning: #{files.inspect}"
-
- Puppet.settings.setdefaults(
- "puppetdoc",
+ Puppet.settings.setdefaults(
+ "puppetdoc",
- "document_all" => [false, "Document all resources"]
- )
- Puppet.settings[:document_all] = options[:all] || false
- begin
- require 'puppet/util/rdoc'
- if @manifest
- Puppet::Util::RDoc.manifestdoc(files)
- else
- options[:outputdir] = "doc" unless options[:outputdir]
- Puppet::Util::RDoc.rdoc(options[:outputdir], files, options[:charset])
- end
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- $stderr.puts "Could not generate documentation: #{detail}"
- exit_code = 1
- end
- exit exit_code
+ "document_all" => [false, "Document all resources"]
+ )
+ Puppet.settings[:document_all] = options[:all] || false
+ begin
+ require 'puppet/util/rdoc'
+ if @manifest
+ Puppet::Util::RDoc.manifestdoc(files)
+ else
+ options[:outputdir] = "doc" unless options[:outputdir]
+ Puppet::Util::RDoc.rdoc(options[:outputdir], files, options[:charset])
+ end
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ $stderr.puts "Could not generate documentation: #{detail}"
+ exit_code = 1
end
-
- def trac
- require 'puppet/util/reference'
- options[:references].each do |name|
- section = Puppet::Util::Reference.reference(name) or raise "Could not find section #{name}"
- section.trac unless options[:mode] == :pdf
- end
+ exit exit_code
+ end
+
+ def trac
+ require 'puppet/util/reference'
+ options[:references].each do |name|
+ section = Puppet::Util::Reference.reference(name) or raise "Could not find section #{name}"
+ section.trac unless options[:mode] == :pdf
end
-
- def markdown
+ end
+
+ def markdown
+ text = ""
+ with_contents = false
+ exit_code = 0
+ require 'puppet/util/reference'
+ options[:references].sort { |a,b| a.to_s <=> b.to_s }.each do |name|
+ raise "Could not find reference #{name}" unless section = Puppet::Util::Reference.reference(name)
+
+ begin
+ # Add the per-section text, but with no ToC
+ text += section.send(options[:format], with_contents)
+ text += Puppet::Util::Reference.footer
+ text.gsub!(/`\w+\s+([^`]+)`:trac:/) { |m| $1 }
+ Puppet::Util::Reference.markdown(name, text)
text = ""
- with_contents = false
- exit_code = 0
- require 'puppet/util/reference'
- options[:references].sort { |a,b| a.to_s <=> b.to_s }.each do |name|
- raise "Could not find reference #{name}" unless section = Puppet::Util::Reference.reference(name)
-
- begin
- # Add the per-section text, but with no ToC
- text += section.send(options[:format], with_contents)
- text += Puppet::Util::Reference.footer
- text.gsub!(/`\w+\s+([^`]+)`:trac:/) { |m| $1 }
- Puppet::Util::Reference.markdown(name, text)
- text = ""
- rescue => detail
- puts detail.backtrace
- $stderr.puts "Could not generate reference #{name}: #{detail}"
- exit_code = 1
- next
- end
- end
-
- exit exit_code
+ rescue => detail
+ puts detail.backtrace
+ $stderr.puts "Could not generate reference #{name}: #{detail}"
+ exit_code = 1
+ next
+ end
end
- def other
- text = ""
- with_contents = options[:references].length <= 1
- exit_code = 0
- require 'puppet/util/reference'
- options[:references].sort { |a,b| a.to_s <=> b.to_s }.each do |name|
- raise "Could not find reference #{name}" unless section = Puppet::Util::Reference.reference(name)
-
- begin
- # Add the per-section text, but with no ToC
- text += section.send(options[:format], with_contents)
- rescue => detail
- puts detail.backtrace
- $stderr.puts "Could not generate reference #{name}: #{detail}"
- exit_code = 1
- next
- end
- end
+ exit exit_code
+ end
+
+ def other
+ text = ""
+ with_contents = options[:references].length <= 1
+ exit_code = 0
+ require 'puppet/util/reference'
+ options[:references].sort { |a,b| a.to_s <=> b.to_s }.each do |name|
+ raise "Could not find reference #{name}" unless section = Puppet::Util::Reference.reference(name)
+
+ begin
+ # Add the per-section text, but with no ToC
+ text += section.send(options[:format], with_contents)
+ rescue => detail
+ puts detail.backtrace
+ $stderr.puts "Could not generate reference #{name}: #{detail}"
+ exit_code = 1
+ next
+ end
+ end
- text += Puppet::Util::Reference.footer unless with_contents # We've only got one reference
+ text += Puppet::Util::Reference.footer unless with_contents # We've only got one reference
- # Replace the trac links, since they're invalid everywhere else
- text.gsub!(/`\w+\s+([^`]+)`:trac:/) { |m| $1 }
+ # Replace the trac links, since they're invalid everywhere else
+ text.gsub!(/`\w+\s+([^`]+)`:trac:/) { |m| $1 }
- if options[:mode] == :pdf
- Puppet::Util::Reference.pdf(text)
- else
- puts text
- end
-
- exit exit_code
+ if options[:mode] == :pdf
+ Puppet::Util::Reference.pdf(text)
+ else
+ puts text
end
- def setup
- # sole manifest documentation
- if command_line.args.size > 0
- options[:mode] = :rdoc
- @manifest = true
- end
+ exit exit_code
+ end
- if options[:mode] == :rdoc
- setup_rdoc
- else
- setup_reference
- end
+ def setup
+ # sole manifest documentation
+ if command_line.args.size > 0
+ options[:mode] = :rdoc
+ @manifest = true
end
- def setup_reference
- if options[:all]
- # Don't add dynamic references to the "all" list.
- require 'puppet/util/reference'
- options[:references] = Puppet::Util::Reference.references.reject do |ref|
- Puppet::Util::Reference.reference(ref).dynamic?
- end
- end
-
- options[:references] << :type if options[:references].empty?
+ if options[:mode] == :rdoc
+ setup_rdoc
+ else
+ setup_reference
+ end
+ end
+
+ def setup_reference
+ if options[:all]
+ # Don't add dynamic references to the "all" list.
+ require 'puppet/util/reference'
+ options[:references] = Puppet::Util::Reference.references.reject do |ref|
+ Puppet::Util::Reference.reference(ref).dynamic?
+ end
end
- def setup_rdoc(dummy_argument=:work_arround_for_ruby_GC_bug)
- # consume the unknown options
- # and feed them as settings
- if @unknown_args.size > 0
- @unknown_args.each do |option|
- # force absolute path for modulepath when passed on commandline
- if option[:opt]=="--modulepath" or option[:opt] == "--manifestdir"
- option[:arg] = option[:arg].split(':').collect { |p| File.expand_path(p) }.join(':')
- end
- Puppet.settings.handlearg(option[:opt], option[:arg])
- end
+ options[:references] << :type if options[:references].empty?
+ end
+
+ def setup_rdoc(dummy_argument=:work_arround_for_ruby_GC_bug)
+ # consume the unknown options
+ # and feed them as settings
+ if @unknown_args.size > 0
+ @unknown_args.each do |option|
+ # force absolute path for modulepath when passed on commandline
+ if option[:opt]=="--modulepath" or option[:opt] == "--manifestdir"
+ option[:arg] = option[:arg].split(':').collect { |p| File.expand_path(p) }.join(':')
end
+ Puppet.settings.handlearg(option[:opt], option[:arg])
+ end
+ end
- # Now parse the config
- Puppet.parse_config
+ # Now parse the config
+ Puppet.parse_config
- # Handle the logging settings.
- if options[:debug] or options[:verbose]
- if options[:debug]
- Puppet::Util::Log.level = :debug
- else
- Puppet::Util::Log.level = :info
- end
+ # Handle the logging settings.
+ if options[:debug] or options[:verbose]
+ if options[:debug]
+ Puppet::Util::Log.level = :debug
+ else
+ Puppet::Util::Log.level = :info
+ end
- Puppet::Util::Log.newdestination(:console)
- end
+ Puppet::Util::Log.newdestination(:console)
end
+ end
end
diff --git a/lib/puppet/application/filebucket.rb b/lib/puppet/application/filebucket.rb
index 8da2d01..9c3c79b 100644
--- a/lib/puppet/application/filebucket.rb
+++ b/lib/puppet/application/filebucket.rb
@@ -2,86 +2,86 @@ require 'puppet/application'
class Puppet::Application::Filebucket < Puppet::Application
- should_not_parse_config
-
- option("--bucket BUCKET","-b")
- option("--debug","-d")
- option("--local","-l")
- option("--remote","-r")
- option("--verbose","-v")
+ should_not_parse_config
+
+ option("--bucket BUCKET","-b")
+ option("--debug","-d")
+ option("--local","-l")
+ option("--remote","-r")
+ option("--verbose","-v")
+
+ attr :args
+
+ def run_command
+ @args = command_line.args
+ command = args.shift
+ return send(command) if %w{get backup restore}.include? command
+ help
+ end
+
+ def get
+ md5 = args.shift
+ out = @client.getfile(md5)
+ print out
+ end
+
+ def backup
+ args.each do |file|
+ unless FileTest.exists?(file)
+ $stderr.puts "#{file}: no such file"
+ next
+ end
+ unless FileTest.readable?(file)
+ $stderr.puts "#{file}: cannot read file"
+ next
+ end
+ md5 = @client.backup(file)
+ puts "#{file}: #{md5}"
+ end
+ end
- attr :args
+ def restore
+ file = args.shift
+ md5 = args.shift
+ @client.restore(file, md5)
+ end
- def run_command
- @args = command_line.args
- command = args.shift
- return send(command) if %w{get backup restore}.include? command
- help
- end
+ def setup
+ Puppet::Log.newdestination(:console)
- def get
- md5 = args.shift
- out = @client.getfile(md5)
- print out
- end
+ @client = nil
+ @server = nil
- def backup
- args.each do |file|
- unless FileTest.exists?(file)
- $stderr.puts "#{file}: no such file"
- next
- end
- unless FileTest.readable?(file)
- $stderr.puts "#{file}: cannot read file"
- next
- end
- md5 = @client.backup(file)
- puts "#{file}: #{md5}"
- end
+ trap(:INT) do
+ $stderr.puts "Cancelling"
+ exit(1)
end
- def restore
- file = args.shift
- md5 = args.shift
- @client.restore(file, md5)
+ if options[:debug]
+ Puppet::Log.level = :debug
+ elsif options[:verbose]
+ Puppet::Log.level = :info
end
- def setup
- Puppet::Log.newdestination(:console)
-
- @client = nil
- @server = nil
-
- trap(:INT) do
- $stderr.puts "Cancelling"
- exit(1)
- end
-
- if options[:debug]
- Puppet::Log.level = :debug
- elsif options[:verbose]
- Puppet::Log.level = :info
- end
-
- # Now parse the config
- Puppet.parse_config
-
- exit(Puppet.settings.print_configs ? 0 : 1) if Puppet.settings.print_configs?
-
- require 'puppet/file_bucket/dipper'
- begin
- if options[:local] or options[:bucket]
- path = options[:bucket] || Puppet[:bucketdir]
- @client = Puppet::FileBucket::Dipper.new(:Path => path)
- else
- @client = Puppet::FileBucket::Dipper.new(:Server => Puppet[:server])
- end
- rescue => detail
- $stderr.puts detail
- puts detail.backtrace if Puppet[:trace]
- exit(1)
- end
+ # Now parse the config
+ Puppet.parse_config
+
+ exit(Puppet.settings.print_configs ? 0 : 1) if Puppet.settings.print_configs?
+
+ require 'puppet/file_bucket/dipper'
+ begin
+ if options[:local] or options[:bucket]
+ path = options[:bucket] || Puppet[:bucketdir]
+ @client = Puppet::FileBucket::Dipper.new(:Path => path)
+ else
+ @client = Puppet::FileBucket::Dipper.new(:Server => Puppet[:server])
+ end
+ rescue => detail
+ $stderr.puts detail
+ puts detail.backtrace if Puppet[:trace]
+ exit(1)
end
+ end
end
diff --git a/lib/puppet/application/kick.rb b/lib/puppet/application/kick.rb
index 6c77e74..37aeb1e 100644
--- a/lib/puppet/application/kick.rb
+++ b/lib/puppet/application/kick.rb
@@ -2,211 +2,211 @@ require 'puppet/application'
class Puppet::Application::Kick < Puppet::Application
- should_not_parse_config
+ should_not_parse_config
+
+ attr_accessor :hosts, :tags, :classes
+
+ option("--all","-a")
+ option("--foreground","-f")
+ option("--debug","-d")
+ option("--ping","-P")
+ option("--test")
+
+ option("--host HOST") do |arg|
+ @hosts << arg
+ end
+
+ option("--tag TAG", "-t") do |arg|
+ @tags << arg
+ end
+
+ option("--class CLASS", "-c") do |arg|
+ @classes << arg
+ end
+
+ option("--no-fqdn", "-n") do |arg|
+ options[:fqdn] = false
+ end
+
+ option("--parallel PARALLEL", "-p") do |arg|
+ begin
+ options[:parallel] = Integer(arg)
+ rescue
+ $stderr.puts "Could not convert #{arg.inspect} to an integer"
+ exit(23)
+ end
+ end
- attr_accessor :hosts, :tags, :classes
+ def run_command
+ @hosts += command_line.args
+ options[:test] ? test : main
+ end
- option("--all","-a")
- option("--foreground","-f")
- option("--debug","-d")
- option("--ping","-P")
- option("--test")
+ def test
+ puts "Skipping execution in test mode"
+ exit(0)
+ end
- option("--host HOST") do |arg|
- @hosts << arg
- end
+ def main
+ require 'puppet/network/client'
- option("--tag TAG", "-t") do |arg|
- @tags << arg
- end
+ Puppet.warning "Failed to load ruby LDAP library. LDAP functionality will not be available" unless Puppet.features.ldap?
+ require 'puppet/util/ldap/connection'
- option("--class CLASS", "-c") do |arg|
- @classes << arg
- end
+ todo = @hosts.dup
- option("--no-fqdn", "-n") do |arg|
- options[:fqdn] = false
- end
+ failures = []
- option("--parallel PARALLEL", "-p") do |arg|
+ # Now do the actual work
+ go = true
+ while go
+ # If we don't have enough children in process and we still have hosts left to
+ # do, then do the next host.
+ if @children.length < options[:parallel] and ! todo.empty?
+ host = todo.shift
+ pid = fork do
+ run_for_host(host)
+ end
+ @children[pid] = host
+ else
+ # Else, see if we can reap a process.
begin
- options[:parallel] = Integer(arg)
- rescue
- $stderr.puts "Could not convert #{arg.inspect} to an integer"
- exit(23)
+ pid = Process.wait
+
+ if host = @children[pid]
+ # Remove our host from the list of children, so the parallelization
+ # continues working.
+ @children.delete(pid)
+ failures << host if $CHILD_STATUS.exitstatus != 0
+ print "#{host} finished with exit code #{$CHILD_STATUS.exitstatus}\n"
+ else
+ $stderr.puts "Could not find host for PID #{pid} with status #{$CHILD_STATUS.exitstatus}"
+ end
+ rescue Errno::ECHILD
+ # There are no children left, so just exit unless there are still
+ # children left to do.
+ next unless todo.empty?
+
+ if failures.empty?
+ puts "Finished"
+ exit(0)
+ else
+ puts "Failed: #{failures.join(", ")}"
+ exit(3)
+ end
end
+ end
end
-
- def run_command
- @hosts += command_line.args
- options[:test] ? test : main
+ end
+
+ def run_for_host(host)
+ if options[:ping]
+ out = %x{ping -c 1 #{host}}
+ unless $CHILD_STATUS == 0
+ $stderr.print "Could not contact #{host}\n"
+ next
+ end
end
- def test
- puts "Skipping execution in test mode"
- exit(0)
+ require 'puppet/run'
+ Puppet::Run.indirection.terminus_class = :rest
+ port = Puppet[:puppetport]
+ url = ["https://#{host}:#{port}", "production", "run", host].join('/')
+
+ print "Triggering #{host}\n"
+ begin
+ run_options = {
+ :tags => @tags,
+ :background => ! options[:foreground],
+ :ignoreschedules => options[:ignoreschedules]
+ }
+ run = Puppet::Run.new( run_options ).save( url )
+ puts "Getting status"
+ result = run.status
+ puts "status is #{result}"
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ $stderr.puts "Host #{host} failed: #{detail}\n"
+ exit(2)
end
- def main
- require 'puppet/network/client'
-
- Puppet.warning "Failed to load ruby LDAP library. LDAP functionality will not be available" unless Puppet.features.ldap?
- require 'puppet/util/ldap/connection'
-
- todo = @hosts.dup
-
- failures = []
-
- # Now do the actual work
- go = true
- while go
- # If we don't have enough children in process and we still have hosts left to
- # do, then do the next host.
- if @children.length < options[:parallel] and ! todo.empty?
- host = todo.shift
- pid = fork do
- run_for_host(host)
- end
- @children[pid] = host
- else
- # Else, see if we can reap a process.
- begin
- pid = Process.wait
-
- if host = @children[pid]
- # Remove our host from the list of children, so the parallelization
- # continues working.
- @children.delete(pid)
- failures << host if $CHILD_STATUS.exitstatus != 0
- print "#{host} finished with exit code #{$CHILD_STATUS.exitstatus}\n"
- else
- $stderr.puts "Could not find host for PID #{pid} with status #{$CHILD_STATUS.exitstatus}"
- end
- rescue Errno::ECHILD
- # There are no children left, so just exit unless there are still
- # children left to do.
- next unless todo.empty?
-
- if failures.empty?
- puts "Finished"
- exit(0)
- else
- puts "Failed: #{failures.join(", ")}"
- exit(3)
- end
- end
- end
- end
+ case result
+ when "success";
+ exit(0)
+ when "running"
+ $stderr.puts "Host #{host} is already running"
+ exit(3)
+ else
+ $stderr.puts "Host #{host} returned unknown answer '#{result}'"
+ exit(12)
end
-
- def run_for_host(host)
- if options[:ping]
- out = %x{ping -c 1 #{host}}
- unless $CHILD_STATUS == 0
- $stderr.print "Could not contact #{host}\n"
- next
- end
- end
-
- require 'puppet/run'
- Puppet::Run.indirection.terminus_class = :rest
- port = Puppet[:puppetport]
- url = ["https://#{host}:#{port}", "production", "run", host].join('/')
-
- print "Triggering #{host}\n"
- begin
- run_options = {
- :tags => @tags,
- :background => ! options[:foreground],
- :ignoreschedules => options[:ignoreschedules]
- }
- run = Puppet::Run.new( run_options ).save( url )
- puts "Getting status"
- result = run.status
- puts "status is #{result}"
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- $stderr.puts "Host #{host} failed: #{detail}\n"
- exit(2)
- end
-
- case result
- when "success";
- exit(0)
- when "running"
- $stderr.puts "Host #{host} is already running"
- exit(3)
- else
- $stderr.puts "Host #{host} returned unknown answer '#{result}'"
- exit(12)
- end
+ end
+
+ def initialize(*args)
+ super
+ @hosts = []
+ @classes = []
+ @tags = []
+ end
+
+ def preinit
+ [:INT, :TERM].each do |signal|
+ trap(signal) do
+ $stderr.puts "Cancelling"
+ exit(1)
+ end
+ end
+ options[:parallel] = 1
+ options[:verbose] = true
+ options[:fqdn] = true
+ options[:ignoreschedules] = false
+ options[:foreground] = false
+ end
+
+ def setup
+ if options[:debug]
+ Puppet::Util::Log.level = :debug
+ else
+ Puppet::Util::Log.level = :info
end
- def initialize(*args)
- super
+ # Now parse the config
+ Puppet.parse_config
+
+ if Puppet[:node_terminus] == "ldap" and (options[:all] or @classes)
+ if options[:all]
+ @hosts = Puppet::Node.search("whatever", :fqdn => options[:fqdn]).collect { |node| node.name }
+ puts "all: #{@hosts.join(", ")}"
+ else
@hosts = []
- @classes = []
- @tags = []
- end
+ @classes.each do |klass|
+ list = Puppet::Node.search("whatever", :fqdn => options[:fqdn], :class => klass).collect { |node| node.name }
+ puts "#{klass}: #{list.join(", ")}"
- def preinit
- [:INT, :TERM].each do |signal|
- trap(signal) do
- $stderr.puts "Cancelling"
- exit(1)
- end
+ @hosts += list
end
- options[:parallel] = 1
- options[:verbose] = true
- options[:fqdn] = true
- options[:ignoreschedules] = false
- options[:foreground] = false
+ end
+ elsif ! @classes.empty?
+ $stderr.puts "You must be using LDAP to specify host classes"
+ exit(24)
end
- def setup
- if options[:debug]
- Puppet::Util::Log.level = :debug
- else
- Puppet::Util::Log.level = :info
- end
+ @children = {}
- # Now parse the config
- Puppet.parse_config
-
- if Puppet[:node_terminus] == "ldap" and (options[:all] or @classes)
- if options[:all]
- @hosts = Puppet::Node.search("whatever", :fqdn => options[:fqdn]).collect { |node| node.name }
- puts "all: #{@hosts.join(", ")}"
- else
- @hosts = []
- @classes.each do |klass|
- list = Puppet::Node.search("whatever", :fqdn => options[:fqdn], :class => klass).collect { |node| node.name }
- puts "#{klass}: #{list.join(", ")}"
-
- @hosts += list
- end
- end
- elsif ! @classes.empty?
- $stderr.puts "You must be using LDAP to specify host classes"
- exit(24)
+ # If we get a signal, then kill all of our children and get out.
+ [:INT, :TERM].each do |signal|
+ trap(signal) do
+ Puppet.notice "Caught #{signal}; shutting down"
+ @children.each do |pid, host|
+ Process.kill("INT", pid)
end
- @children = {}
-
- # If we get a signal, then kill all of our children and get out.
- [:INT, :TERM].each do |signal|
- trap(signal) do
- Puppet.notice "Caught #{signal}; shutting down"
- @children.each do |pid, host|
- Process.kill("INT", pid)
- end
-
- waitall
-
- exit(1)
- end
- end
+ waitall
+ exit(1)
+ end
end
+ end
+
end
diff --git a/lib/puppet/application/master.rb b/lib/puppet/application/master.rb
index 7485dcb..777a50e 100644
--- a/lib/puppet/application/master.rb
+++ b/lib/puppet/application/master.rb
@@ -2,155 +2,155 @@ require 'puppet/application'
class Puppet::Application::Master < Puppet::Application
- should_parse_config
- run_mode :master
-
- option("--debug", "-d")
- option("--verbose", "-v")
-
- # internal option, only to be used by ext/rack/config.ru
- option("--rack")
+ should_parse_config
+ run_mode :master
+
+ option("--debug", "-d")
+ option("--verbose", "-v")
+
+ # internal option, only to be used by ext/rack/config.ru
+ option("--rack")
+
+ option("--compile host", "-c host") do |arg|
+ options[:node] = arg
+ end
+
+ option("--logdest DEST", "-l DEST") do |arg|
+ begin
+ Puppet::Util::Log.newdestination(arg)
+ options[:setdest] = true
+ rescue => detail
+ puts detail.backtrace if Puppet[:debug]
+ $stderr.puts detail.to_s
+ end
+ end
- option("--compile host", "-c host") do |arg|
- options[:node] = arg
+ def preinit
+ trap(:INT) do
+ $stderr.puts "Cancelling startup"
+ exit(0)
end
- option("--logdest DEST", "-l DEST") do |arg|
- begin
- Puppet::Util::Log.newdestination(arg)
- options[:setdest] = true
- rescue => detail
- puts detail.backtrace if Puppet[:debug]
- $stderr.puts detail.to_s
- end
+ # Create this first-off, so we have ARGV
+ require 'puppet/daemon'
+ @daemon = Puppet::Daemon.new
+ @daemon.argv = ARGV.dup
+ end
+
+ def run_command
+ if options[:node]
+ compile
+ elsif Puppet[:parseonly]
+ parseonly
+ else
+ main
+ end
+ end
+
+ def compile
+ Puppet::Util::Log.newdestination :console
+ raise ArgumentError, "Cannot render compiled catalogs without pson support" unless Puppet.features.pson?
+ begin
+ unless catalog = Puppet::Resource::Catalog.find(options[:node])
+ raise "Could not compile catalog for #{options[:node]}"
+ end
+
+ jj catalog.to_resource
+ rescue => detail
+ $stderr.puts detail
+ exit(30)
end
+ exit(0)
+ end
+
+ def parseonly
+ begin
+ Puppet::Node::Environment.new(Puppet[:environment]).known_resource_types
+ rescue => detail
+ Puppet.err detail
+ exit 1
+ end
+ exit(0)
+ end
- def preinit
- trap(:INT) do
- $stderr.puts "Cancelling startup"
- exit(0)
- end
+ def main
+ require 'etc'
+ require 'puppet/file_serving/content'
+ require 'puppet/file_serving/metadata'
- # Create this first-off, so we have ARGV
- require 'puppet/daemon'
- @daemon = Puppet::Daemon.new
- @daemon.argv = ARGV.dup
- end
+ xmlrpc_handlers = [:Status, :FileServer, :Master, :Report, :Filebucket]
- def run_command
- if options[:node]
- compile
- elsif Puppet[:parseonly]
- parseonly
- else
- main
- end
- end
+ xmlrpc_handlers << :CA if Puppet[:ca]
+
+ # Make sure we've got a localhost ssl cert
+ Puppet::SSL::Host.localhost
- def compile
- Puppet::Util::Log.newdestination :console
- raise ArgumentError, "Cannot render compiled catalogs without pson support" unless Puppet.features.pson?
- begin
- unless catalog = Puppet::Resource::Catalog.find(options[:node])
- raise "Could not compile catalog for #{options[:node]}"
- end
-
- jj catalog.to_resource
- rescue => detail
- $stderr.puts detail
- exit(30)
- end
- exit(0)
+ # And now configure our server to *only* hit the CA for data, because that's
+ # all it will have write access to.
+ Puppet::SSL::Host.ca_location = :only if Puppet::SSL::CertificateAuthority.ca?
+
+ if Puppet.features.root?
+ begin
+ Puppet::Util.chuser
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ $stderr.puts "Could not change user to #{Puppet[:user]}: #{detail}"
+ exit(39)
+ end
end
- def parseonly
- begin
- Puppet::Node::Environment.new(Puppet[:environment]).known_resource_types
- rescue => detail
- Puppet.err detail
- exit 1
- end
- exit(0)
+ unless options[:rack]
+ require 'puppet/network/server'
+ @daemon.server = Puppet::Network::Server.new(:xmlrpc_handlers => xmlrpc_handlers)
+ @daemon.daemonize if Puppet[:daemonize]
+ else
+ require 'puppet/network/http/rack'
+ @app = Puppet::Network::HTTP::Rack.new(:xmlrpc_handlers => xmlrpc_handlers, :protocols => [:rest, :xmlrpc])
end
- def main
- require 'etc'
- require 'puppet/file_serving/content'
- require 'puppet/file_serving/metadata'
-
- xmlrpc_handlers = [:Status, :FileServer, :Master, :Report, :Filebucket]
-
- xmlrpc_handlers << :CA if Puppet[:ca]
-
- # Make sure we've got a localhost ssl cert
- Puppet::SSL::Host.localhost
-
- # And now configure our server to *only* hit the CA for data, because that's
- # all it will have write access to.
- Puppet::SSL::Host.ca_location = :only if Puppet::SSL::CertificateAuthority.ca?
-
- if Puppet.features.root?
- begin
- Puppet::Util.chuser
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- $stderr.puts "Could not change user to #{Puppet[:user]}: #{detail}"
- exit(39)
- end
- end
-
- unless options[:rack]
- require 'puppet/network/server'
- @daemon.server = Puppet::Network::Server.new(:xmlrpc_handlers => xmlrpc_handlers)
- @daemon.daemonize if Puppet[:daemonize]
- else
- require 'puppet/network/http/rack'
- @app = Puppet::Network::HTTP::Rack.new(:xmlrpc_handlers => xmlrpc_handlers, :protocols => [:rest, :xmlrpc])
- end
-
- Puppet.notice "Starting Puppet master version #{Puppet.version}"
-
- unless options[:rack]
- @daemon.start
- else
- return @app
- end
+ Puppet.notice "Starting Puppet master version #{Puppet.version}"
+
+ unless options[:rack]
+ @daemon.start
+ else
+ return @app
end
+ end
+
+ def setup
+ # Handle the logging settings.
+ if options[:debug] or options[:verbose]
+ if options[:debug]
+ Puppet::Util::Log.level = :debug
+ else
+ Puppet::Util::Log.level = :info
+ end
+
+ unless Puppet[:daemonize] or options[:rack]
+ Puppet::Util::Log.newdestination(:console)
+ options[:setdest] = true
+ end
+ end
+
+ Puppet::Util::Log.newdestination(:syslog) unless options[:setdest]
+
+ exit(Puppet.settings.print_configs ? 0 : 1) if Puppet.settings.print_configs?
+
+ Puppet.settings.use :main, :master, :ssl
+
+ # A temporary solution, to at least make the master work for now.
+ Puppet::Node::Facts.terminus_class = :yaml
+
+ # Cache our nodes in yaml. Currently not configurable.
+ Puppet::Node.cache_class = :yaml
- def setup
- # Handle the logging settings.
- if options[:debug] or options[:verbose]
- if options[:debug]
- Puppet::Util::Log.level = :debug
- else
- Puppet::Util::Log.level = :info
- end
-
- unless Puppet[:daemonize] or options[:rack]
- Puppet::Util::Log.newdestination(:console)
- options[:setdest] = true
- end
- end
-
- Puppet::Util::Log.newdestination(:syslog) unless options[:setdest]
-
- exit(Puppet.settings.print_configs ? 0 : 1) if Puppet.settings.print_configs?
-
- Puppet.settings.use :main, :master, :ssl
-
- # A temporary solution, to at least make the master work for now.
- Puppet::Node::Facts.terminus_class = :yaml
-
- # Cache our nodes in yaml. Currently not configurable.
- Puppet::Node.cache_class = :yaml
-
- # Configure all of the SSL stuff.
- if Puppet::SSL::CertificateAuthority.ca?
- Puppet::SSL::Host.ca_location = :local
- Puppet.settings.use :ca
- Puppet::SSL::CertificateAuthority.instance
- else
- Puppet::SSL::Host.ca_location = :none
- end
+ # Configure all of the SSL stuff.
+ if Puppet::SSL::CertificateAuthority.ca?
+ Puppet::SSL::Host.ca_location = :local
+ Puppet.settings.use :ca
+ Puppet::SSL::CertificateAuthority.instance
+ else
+ Puppet::SSL::Host.ca_location = :none
end
+ end
end
diff --git a/lib/puppet/application/queue.rb b/lib/puppet/application/queue.rb
index 6531f6f..6df825d 100644
--- a/lib/puppet/application/queue.rb
+++ b/lib/puppet/application/queue.rb
@@ -2,90 +2,90 @@ require 'puppet/application'
require 'puppet/util'
class Puppet::Application::Queue < Puppet::Application
- should_parse_config
+ should_parse_config
- attr_accessor :daemon
+ attr_accessor :daemon
- def preinit
- require 'puppet/daemon'
- @daemon = Puppet::Daemon.new
- @daemon.argv = ARGV.dup
- Puppet::Util::Log.newdestination(:console)
+ def preinit
+ require 'puppet/daemon'
+ @daemon = Puppet::Daemon.new
+ @daemon.argv = ARGV.dup
+ Puppet::Util::Log.newdestination(:console)
- # Do an initial trap, so that cancels don't get a stack trace.
+ # Do an initial trap, so that cancels don't get a stack trace.
- # This exits with exit code 1
- trap(:INT) do
- $stderr.puts "Caught SIGINT; shutting down"
- exit(1)
- end
-
- # This is a normal shutdown, so code 0
- trap(:TERM) do
- $stderr.puts "Caught SIGTERM; shutting down"
- exit(0)
- end
+ # This exits with exit code 1
+ trap(:INT) do
+ $stderr.puts "Caught SIGINT; shutting down"
+ exit(1)
+ end
- {
- :verbose => false,
- :debug => false
- }.each do |opt,val|
- options[opt] = val
- end
+ # This is a normal shutdown, so code 0
+ trap(:TERM) do
+ $stderr.puts "Caught SIGTERM; shutting down"
+ exit(0)
end
- option("--debug","-d")
- option("--verbose","-v")
-
- def main
- Puppet.notice "Starting puppetqd #{Puppet.version}"
- Puppet::Resource::Catalog::Queue.subscribe do |catalog|
- # Once you have a Puppet::Resource::Catalog instance, calling save on it should suffice
- # to put it through to the database via its active_record indirector (which is determined
- # by the terminus_class = :active_record setting above)
- Puppet::Util.benchmark(:notice, "Processing queued catalog for #{catalog.name}") do
- begin
- catalog.save
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Could not save queued catalog for #{catalog.name}: #{detail}"
- end
- end
+ {
+ :verbose => false,
+ :debug => false
+ }.each do |opt,val|
+ options[opt] = val
+ end
+ end
+
+ option("--debug","-d")
+ option("--verbose","-v")
+
+ def main
+ Puppet.notice "Starting puppetqd #{Puppet.version}"
+ Puppet::Resource::Catalog::Queue.subscribe do |catalog|
+ # Once you have a Puppet::Resource::Catalog instance, calling save on it should suffice
+ # to put it through to the database via its active_record indirector (which is determined
+ # by the terminus_class = :active_record setting above)
+ Puppet::Util.benchmark(:notice, "Processing queued catalog for #{catalog.name}") do
+ begin
+ catalog.save
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Could not save queued catalog for #{catalog.name}: #{detail}"
end
-
- Thread.list.each { |thread| thread.join }
+ end
end
- # Handle the logging settings.
- def setup_logs
- if options[:debug] or options[:verbose]
- Puppet::Util::Log.newdestination(:console)
- if options[:debug]
- Puppet::Util::Log.level = :debug
- else
- Puppet::Util::Log.level = :info
- end
- end
+ Thread.list.each { |thread| thread.join }
+ end
+
+ # Handle the logging settings.
+ def setup_logs
+ if options[:debug] or options[:verbose]
+ Puppet::Util::Log.newdestination(:console)
+ if options[:debug]
+ Puppet::Util::Log.level = :debug
+ else
+ Puppet::Util::Log.level = :info
+ end
end
+ end
- def setup
- unless Puppet.features.stomp?
- raise ArgumentError, "Could not load the 'stomp' library, which must be present for queueing to work. You must install the required library."
- end
+ def setup
+ unless Puppet.features.stomp?
+ raise ArgumentError, "Could not load the 'stomp' library, which must be present for queueing to work. You must install the required library."
+ end
- setup_logs
+ setup_logs
- exit(Puppet.settings.print_configs ? 0 : 1) if Puppet.settings.print_configs?
+ exit(Puppet.settings.print_configs ? 0 : 1) if Puppet.settings.print_configs?
- require 'puppet/resource/catalog'
- Puppet::Resource::Catalog.terminus_class = :active_record
+ require 'puppet/resource/catalog'
+ Puppet::Resource::Catalog.terminus_class = :active_record
- daemon.daemonize if Puppet[:daemonize]
+ daemon.daemonize if Puppet[:daemonize]
- # We want to make sure that we don't have a cache
- # class set up, because if storeconfigs is enabled,
- # we'll get a loop of continually caching the catalog
- # for storage again.
- Puppet::Resource::Catalog.cache_class = nil
- end
+ # We want to make sure that we don't have a cache
+ # class set up, because if storeconfigs is enabled,
+ # we'll get a loop of continually caching the catalog
+ # for storage again.
+ Puppet::Resource::Catalog.cache_class = nil
+ end
end
diff --git a/lib/puppet/application/resource.rb b/lib/puppet/application/resource.rb
index 9e1efe2..f55caa5 100644
--- a/lib/puppet/application/resource.rb
+++ b/lib/puppet/application/resource.rb
@@ -2,117 +2,117 @@ require 'puppet/application'
class Puppet::Application::Resource < Puppet::Application
- should_not_parse_config
-
- attr_accessor :host, :extra_params
-
- def preinit
- @extra_params = []
- @host = nil
- Facter.loadfacts
+ should_not_parse_config
+
+ attr_accessor :host, :extra_params
+
+ def preinit
+ @extra_params = []
+ @host = nil
+ Facter.loadfacts
+ end
+
+ option("--debug","-d")
+ option("--verbose","-v")
+ option("--edit","-e")
+
+ option("--host HOST","-H") do |arg|
+ @host = arg
+ end
+
+ option("--types", "-t") do |arg|
+ types = []
+ Puppet::Type.loadall
+ Puppet::Type.eachtype do |t|
+ next if t.name == :component
+ types << t.name.to_s
end
-
- option("--debug","-d")
- option("--verbose","-v")
- option("--edit","-e")
-
- option("--host HOST","-H") do |arg|
- @host = arg
+ puts types.sort
+ exit
+ end
+
+ option("--param PARAM", "-p") do |arg|
+ @extra_params << arg.to_sym
+ end
+
+ def main
+ args = command_line.args
+ type = args.shift or raise "You must specify the type to display"
+ typeobj = Puppet::Type.type(type) or raise "Could not find type #{type}"
+ name = args.shift
+ params = {}
+ args.each do |setting|
+ if setting =~ /^(\w+)=(.+)$/
+ params[$1] = $2
+ else
+ raise "Invalid parameter setting #{setting}"
+ end
end
- option("--types", "-t") do |arg|
- types = []
- Puppet::Type.loadall
- Puppet::Type.eachtype do |t|
- next if t.name == :component
- types << t.name.to_s
- end
- puts types.sort
- exit
- end
+ raise "You cannot edit a remote host" if options[:edit] and @host
- option("--param PARAM", "-p") do |arg|
- @extra_params << arg.to_sym
- end
+ properties = typeobj.properties.collect { |s| s.name }
- def main
- args = command_line.args
- type = args.shift or raise "You must specify the type to display"
- typeobj = Puppet::Type.type(type) or raise "Could not find type #{type}"
- name = args.shift
- params = {}
- args.each do |setting|
- if setting =~ /^(\w+)=(.+)$/
- params[$1] = $2
- else
- raise "Invalid parameter setting #{setting}"
- end
+ format = proc {|trans|
+ trans.dup.collect do |param, value|
+ if value.nil? or value.to_s.empty?
+ trans.delete(param)
+ elsif value.to_s == "absent" and param.to_s != "ensure"
+ trans.delete(param)
end
- raise "You cannot edit a remote host" if options[:edit] and @host
-
- properties = typeobj.properties.collect { |s| s.name }
-
- format = proc {|trans|
- trans.dup.collect do |param, value|
- if value.nil? or value.to_s.empty?
- trans.delete(param)
- elsif value.to_s == "absent" and param.to_s != "ensure"
- trans.delete(param)
- end
-
- trans.delete(param) unless properties.include?(param) or @extra_params.include?(param)
- end
- trans.to_manifest
- }
-
- if @host
- Puppet::Resource.indirection.terminus_class = :rest
- port = Puppet[:puppetport]
- key = ["https://#{host}:#{port}", "production", "resources", type, name].join('/')
- else
- key = [type, name].join('/')
- end
+ trans.delete(param) unless properties.include?(param) or @extra_params.include?(param)
+ end
+ trans.to_manifest
+ }
+
+ if @host
+ Puppet::Resource.indirection.terminus_class = :rest
+ port = Puppet[:puppetport]
+ key = ["https://#{host}:#{port}", "production", "resources", type, name].join('/')
+ else
+ key = [type, name].join('/')
+ end
- text = if name
- if params.empty?
- [ Puppet::Resource.find( key ) ]
- else
- [ Puppet::Resource.new( type, name, :parameters => params ).save( key ) ]
- end
- else
- Puppet::Resource.search( key, {} )
- end.map(&format).join("\n")
-
- if options[:edit]
- file = "/tmp/x2puppet-#{Process.pid}.pp"
- begin
- File.open(file, "w") do |f|
- f.puts text
- end
- ENV["EDITOR"] ||= "vi"
- system(ENV["EDITOR"], file)
- system("puppet -v #{file}")
- ensure
- #if FileTest.exists? file
- # File.unlink(file)
- #end
- end
- else
- puts text
+ text = if name
+ if params.empty?
+ [ Puppet::Resource.find( key ) ]
+ else
+ [ Puppet::Resource.new( type, name, :parameters => params ).save( key ) ]
+ end
+ else
+ Puppet::Resource.search( key, {} )
+ end.map(&format).join("\n")
+
+ if options[:edit]
+ file = "/tmp/x2puppet-#{Process.pid}.pp"
+ begin
+ File.open(file, "w") do |f|
+ f.puts text
end
+ ENV["EDITOR"] ||= "vi"
+ system(ENV["EDITOR"], file)
+ system("puppet -v #{file}")
+ ensure
+ #if FileTest.exists? file
+ # File.unlink(file)
+ #end
+ end
+ else
+ puts text
end
+ end
- def setup
- Puppet::Util::Log.newdestination(:console)
+ def setup
+ Puppet::Util::Log.newdestination(:console)
- # Now parse the config
- Puppet.parse_config
+ # Now parse the config
+ Puppet.parse_config
- if options[:debug]
- Puppet::Util::Log.level = :debug
- elsif options[:verbose]
- Puppet::Util::Log.level = :info
- end
+ if options[:debug]
+ Puppet::Util::Log.level = :debug
+ elsif options[:verbose]
+ Puppet::Util::Log.level = :info
end
+ end
end
diff --git a/lib/puppet/configurer.rb b/lib/puppet/configurer.rb
index 5b81745..327955b 100644
--- a/lib/puppet/configurer.rb
+++ b/lib/puppet/configurer.rb
@@ -5,231 +5,231 @@ require 'puppet/network/http_pool'
require 'puppet/util'
class Puppet::Configurer
- class CommandHookError < RuntimeError; end
+ class CommandHookError < RuntimeError; end
- require 'puppet/configurer/fact_handler'
- require 'puppet/configurer/plugin_handler'
+ require 'puppet/configurer/fact_handler'
+ require 'puppet/configurer/plugin_handler'
- include Puppet::Configurer::FactHandler
- include Puppet::Configurer::PluginHandler
+ include Puppet::Configurer::FactHandler
+ include Puppet::Configurer::PluginHandler
- # For benchmarking
- include Puppet::Util
-
- attr_reader :compile_time
-
- # Provide more helpful strings to the logging that the Agent does
- def self.to_s
- "Puppet configuration client"
- end
-
- class << self
- # Puppetd should only have one instance running, and we need a way
- # to retrieve it.
- attr_accessor :instance
- include Puppet::Util
- end
-
- # How to lock instances of this class.
- def self.lockfile_path
- Puppet[:puppetdlockfile]
- end
-
- def clear
- @catalog.clear(true) if @catalog
- @catalog = nil
- end
-
- def execute_postrun_command
- execute_from_setting(:postrun_command)
- end
-
- def execute_prerun_command
- execute_from_setting(:prerun_command)
- end
-
- # Initialize and load storage
- def dostorage
- Puppet::Util::Storage.load
- @compile_time ||= Puppet::Util::Storage.cache(:configuration)[:compile_time]
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Corrupt state file #{Puppet[:statefile]}: #{detail}"
- begin
- ::File.unlink(Puppet[:statefile])
- retry
- rescue => detail
- raise Puppet::Error.new("Cannot remove #{Puppet[:statefile]}: #{detail}")
- end
- end
-
- # Just so we can specify that we are "the" instance.
- def initialize
- Puppet.settings.use(:main, :ssl, :agent)
-
- self.class.instance = self
- @running = false
- @splayed = false
- end
-
- def initialize_report
- Puppet::Transaction::Report.new
- end
+ # For benchmarking
+ include Puppet::Util
- # Prepare for catalog retrieval. Downloads everything necessary, etc.
- def prepare
- dostorage
+ attr_reader :compile_time
- download_plugins
+ # Provide more helpful strings to the logging that the Agent does
+ def self.to_s
+ "Puppet configuration client"
+ end
- download_fact_plugins
-
- execute_prerun_command
+ class << self
+ # Puppetd should only have one instance running, and we need a way
+ # to retrieve it.
+ attr_accessor :instance
+ include Puppet::Util
+ end
+
+ # How to lock instances of this class.
+ def self.lockfile_path
+ Puppet[:puppetdlockfile]
+ end
+
+ def clear
+ @catalog.clear(true) if @catalog
+ @catalog = nil
+ end
+
+ def execute_postrun_command
+ execute_from_setting(:postrun_command)
+ end
+
+ def execute_prerun_command
+ execute_from_setting(:prerun_command)
+ end
+
+ # Initialize and load storage
+ def dostorage
+ Puppet::Util::Storage.load
+ @compile_time ||= Puppet::Util::Storage.cache(:configuration)[:compile_time]
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Corrupt state file #{Puppet[:statefile]}: #{detail}"
+ begin
+ ::File.unlink(Puppet[:statefile])
+ retry
+ rescue => detail
+ raise Puppet::Error.new("Cannot remove #{Puppet[:statefile]}: #{detail}")
+ end
+ end
+
+ # Just so we can specify that we are "the" instance.
+ def initialize
+ Puppet.settings.use(:main, :ssl, :agent)
+
+ self.class.instance = self
+ @running = false
+ @splayed = false
+ end
+
+ def initialize_report
+ Puppet::Transaction::Report.new
+ end
+
+ # Prepare for catalog retrieval. Downloads everything necessary, etc.
+ def prepare
+ dostorage
+
+ download_plugins
+
+ download_fact_plugins
+
+ execute_prerun_command
+ end
+
+ # Get the remote catalog, yo. Returns nil if no catalog can be found.
+ def retrieve_catalog
+ if Puppet::Resource::Catalog.indirection.terminus_class == :rest
+ # This is a bit complicated. We need the serialized and escaped facts,
+ # and we need to know which format they're encoded in. Thus, we
+ # get a hash with both of these pieces of information.
+ fact_options = facts_for_uploading
+ else
+ fact_options = {}
+ end
+
+ # First try it with no cache, then with the cache.
+ unless (Puppet[:use_cached_catalog] and result = retrieve_catalog_from_cache(fact_options)) or result = retrieve_new_catalog(fact_options)
+ if ! Puppet[:usecacheonfailure]
+ Puppet.warning "Not using cache on failed catalog"
+ return nil
+ end
+ result = retrieve_catalog_from_cache(fact_options)
+ end
+
+ return nil unless result
+
+ convert_catalog(result, @duration)
+ end
+
+ # Convert a plain resource catalog into our full host catalog.
+ def convert_catalog(result, duration)
+ catalog = result.to_ral
+ catalog.finalize
+ catalog.retrieval_duration = duration
+ catalog.write_class_file
+ catalog
+ end
+
+ # The code that actually runs the catalog.
+ # This just passes any options on to the catalog,
+ # which accepts :tags and :ignoreschedules.
+ def run(options = {})
+ begin
+ prepare
+ rescue SystemExit,NoMemoryError
+ raise
+ rescue Exception => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Failed to prepare catalog: #{detail}"
end
- # Get the remote catalog, yo. Returns nil if no catalog can be found.
- def retrieve_catalog
- if Puppet::Resource::Catalog.indirection.terminus_class == :rest
- # This is a bit complicated. We need the serialized and escaped facts,
- # and we need to know which format they're encoded in. Thus, we
- # get a hash with both of these pieces of information.
- fact_options = facts_for_uploading
- else
- fact_options = {}
- end
-
- # First try it with no cache, then with the cache.
- unless (Puppet[:use_cached_catalog] and result = retrieve_catalog_from_cache(fact_options)) or result = retrieve_new_catalog(fact_options)
- if ! Puppet[:usecacheonfailure]
- Puppet.warning "Not using cache on failed catalog"
- return nil
- end
- result = retrieve_catalog_from_cache(fact_options)
- end
-
- return nil unless result
-
- convert_catalog(result, @duration)
- end
+ options[:report] ||= initialize_report
+ report = options[:report]
+ Puppet::Util::Log.newdestination(report)
- # Convert a plain resource catalog into our full host catalog.
- def convert_catalog(result, duration)
- catalog = result.to_ral
- catalog.finalize
- catalog.retrieval_duration = duration
- catalog.write_class_file
- catalog
+ if catalog = options[:catalog]
+ options.delete(:catalog)
+ elsif ! catalog = retrieve_catalog
+ Puppet.err "Could not retrieve catalog; skipping run"
+ return
end
- # The code that actually runs the catalog.
- # This just passes any options on to the catalog,
- # which accepts :tags and :ignoreschedules.
- def run(options = {})
- begin
- prepare
- rescue SystemExit,NoMemoryError
- raise
- rescue Exception => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Failed to prepare catalog: #{detail}"
- end
-
- options[:report] ||= initialize_report
- report = options[:report]
- Puppet::Util::Log.newdestination(report)
-
- if catalog = options[:catalog]
- options.delete(:catalog)
- elsif ! catalog = retrieve_catalog
- Puppet.err "Could not retrieve catalog; skipping run"
- return
- end
-
- transaction = nil
-
- begin
- benchmark(:notice, "Finished catalog run") do
- transaction = catalog.apply(options)
- end
- report
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Failed to apply catalog: #{detail}"
- return
- end
- ensure
- # Now close all of our existing http connections, since there's no
- # reason to leave them lying open.
- Puppet::Network::HttpPool.clear_http_instances
- execute_postrun_command
-
- Puppet::Util::Log.close(report)
-
- send_report(report, transaction)
- end
+ transaction = nil
- def send_report(report, trans = nil)
- trans.generate_report if trans
- puts report.summary if Puppet[:summarize]
- report.save if Puppet[:report]
+ begin
+ benchmark(:notice, "Finished catalog run") do
+ transaction = catalog.apply(options)
+ end
+ report
rescue => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Could not send report: #{detail}"
- end
-
- private
-
- def self.timeout
- timeout = Puppet[:configtimeout]
- case timeout
- when String
- if timeout =~ /^\d+$/
- timeout = Integer(timeout)
- else
- raise ArgumentError, "Configuration timeout must be an integer"
- end
- when Integer # nothing
- else
- raise ArgumentError, "Configuration timeout must be an integer"
- end
-
- timeout
- end
-
- def execute_from_setting(setting)
- return if (command = Puppet[setting]) == ""
-
- begin
- Puppet::Util.execute([command])
- rescue => detail
- raise CommandHookError, "Could not run command from #{setting}: #{detail}"
- end
- end
-
- def retrieve_catalog_from_cache(fact_options)
- result = nil
- @duration = thinmark do
- result = Puppet::Resource::Catalog.find(Puppet[:certname], fact_options.merge(:ignore_terminus => true))
- end
- Puppet.notice "Using cached catalog"
- result
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Failed to apply catalog: #{detail}"
+ return
+ end
+ ensure
+ # Now close all of our existing http connections, since there's no
+ # reason to leave them lying open.
+ Puppet::Network::HttpPool.clear_http_instances
+ execute_postrun_command
+
+ Puppet::Util::Log.close(report)
+
+ send_report(report, transaction)
+ end
+
+ def send_report(report, trans = nil)
+ trans.generate_report if trans
+ puts report.summary if Puppet[:summarize]
+ report.save if Puppet[:report]
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Could not send report: #{detail}"
+ end
+
+ private
+
+ def self.timeout
+ timeout = Puppet[:configtimeout]
+ case timeout
+ when String
+ if timeout =~ /^\d+$/
+ timeout = Integer(timeout)
+ else
+ raise ArgumentError, "Configuration timeout must be an integer"
+ end
+ when Integer # nothing
+ else
+ raise ArgumentError, "Configuration timeout must be an integer"
+ end
+
+ timeout
+ end
+
+ def execute_from_setting(setting)
+ return if (command = Puppet[setting]) == ""
+
+ begin
+ Puppet::Util.execute([command])
rescue => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Could not retrieve catalog from cache: #{detail}"
- return nil
- end
-
- def retrieve_new_catalog(fact_options)
- result = nil
- @duration = thinmark do
- result = Puppet::Resource::Catalog.find(Puppet[:certname], fact_options.merge(:ignore_cache => true))
- end
- result
- rescue SystemExit,NoMemoryError
- raise
- rescue Exception => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Could not retrieve catalog from remote server: #{detail}"
- return nil
- end
+ raise CommandHookError, "Could not run command from #{setting}: #{detail}"
+ end
+ end
+
+ def retrieve_catalog_from_cache(fact_options)
+ result = nil
+ @duration = thinmark do
+ result = Puppet::Resource::Catalog.find(Puppet[:certname], fact_options.merge(:ignore_terminus => true))
+ end
+ Puppet.notice "Using cached catalog"
+ result
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Could not retrieve catalog from cache: #{detail}"
+ return nil
+ end
+
+ def retrieve_new_catalog(fact_options)
+ result = nil
+ @duration = thinmark do
+ result = Puppet::Resource::Catalog.find(Puppet[:certname], fact_options.merge(:ignore_cache => true))
+ end
+ result
+ rescue SystemExit,NoMemoryError
+ raise
+ rescue Exception => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Could not retrieve catalog from remote server: #{detail}"
+ return nil
+ end
end
diff --git a/lib/puppet/configurer/downloader.rb b/lib/puppet/configurer/downloader.rb
index 8f8dda5..1b587ed 100644
--- a/lib/puppet/configurer/downloader.rb
+++ b/lib/puppet/configurer/downloader.rb
@@ -2,78 +2,78 @@ require 'puppet/configurer'
require 'puppet/resource/catalog'
class Puppet::Configurer::Downloader
- attr_reader :name, :path, :source, :ignore
+ attr_reader :name, :path, :source, :ignore
- # Determine the timeout value to use.
- def self.timeout
- timeout = Puppet[:configtimeout]
- case timeout
- when String
- if timeout =~ /^\d+$/
- timeout = Integer(timeout)
- else
- raise ArgumentError, "Configuration timeout must be an integer"
- end
- when Integer # nothing
- else
- raise ArgumentError, "Configuration timeout must be an integer"
- end
-
- timeout
+ # Determine the timeout value to use.
+ def self.timeout
+ timeout = Puppet[:configtimeout]
+ case timeout
+ when String
+ if timeout =~ /^\d+$/
+ timeout = Integer(timeout)
+ else
+ raise ArgumentError, "Configuration timeout must be an integer"
+ end
+ when Integer # nothing
+ else
+ raise ArgumentError, "Configuration timeout must be an integer"
end
- # Evaluate our download, returning the list of changed values.
- def evaluate
- Puppet.info "Retrieving #{name}"
+ timeout
+ end
- files = []
- begin
- Timeout.timeout(self.class.timeout) do
- catalog.apply do |trans|
- trans.changed?.find_all do |resource|
- yield resource if block_given?
- files << resource[:path]
- end
- end
- end
- rescue Puppet::Error, Timeout::Error => detail
- puts detail.backtrace if Puppet[:debug]
- Puppet.err "Could not retrieve #{name}: #{detail}"
- end
+ # Evaluate our download, returning the list of changed values.
+ def evaluate
+ Puppet.info "Retrieving #{name}"
- files
+ files = []
+ begin
+ Timeout.timeout(self.class.timeout) do
+ catalog.apply do |trans|
+ trans.changed?.find_all do |resource|
+ yield resource if block_given?
+ files << resource[:path]
+ end
+ end
+ end
+ rescue Puppet::Error, Timeout::Error => detail
+ puts detail.backtrace if Puppet[:debug]
+ Puppet.err "Could not retrieve #{name}: #{detail}"
end
- def initialize(name, path, source, ignore = nil)
- @name, @path, @source, @ignore = name, path, source, ignore
- end
+ files
+ end
- def catalog
- catalog = Puppet::Resource::Catalog.new
- catalog.add_resource(file)
- catalog
- end
+ def initialize(name, path, source, ignore = nil)
+ @name, @path, @source, @ignore = name, path, source, ignore
+ end
- def file
- args = default_arguments.merge(:path => path, :source => source)
- args[:ignore] = ignore.split if ignore
- Puppet::Type.type(:file).new(args)
- end
+ def catalog
+ catalog = Puppet::Resource::Catalog.new
+ catalog.add_resource(file)
+ catalog
+ end
- private
+ def file
+ args = default_arguments.merge(:path => path, :source => source)
+ args[:ignore] = ignore.split if ignore
+ Puppet::Type.type(:file).new(args)
+ end
- def default_arguments
- {
- :path => path,
- :recurse => true,
- :source => source,
- :tag => name,
- :owner => Process.uid,
- :group => Process.gid,
- :purge => true,
- :force => true,
- :backup => false,
- :noop => false
- }
- end
+ private
+
+ def default_arguments
+ {
+ :path => path,
+ :recurse => true,
+ :source => source,
+ :tag => name,
+ :owner => Process.uid,
+ :group => Process.gid,
+ :purge => true,
+ :force => true,
+ :backup => false,
+ :noop => false
+ }
+ end
end
diff --git a/lib/puppet/configurer/fact_handler.rb b/lib/puppet/configurer/fact_handler.rb
index 2d1565a..075a594 100644
--- a/lib/puppet/configurer/fact_handler.rb
+++ b/lib/puppet/configurer/fact_handler.rb
@@ -6,67 +6,67 @@ require 'puppet/configurer/downloader'
# just included into the agent, but having it here makes it
# easier to test.
module Puppet::Configurer::FactHandler
- def download_fact_plugins?
- Puppet[:factsync]
- end
+ def download_fact_plugins?
+ Puppet[:factsync]
+ end
- def find_facts
- # This works because puppet agent configures Facts to use 'facter' for
- # finding facts and the 'rest' terminus for caching them. Thus, we'll
- # compile them and then "cache" them on the server.
- begin
- reload_facter
- Puppet::Node::Facts.find(Puppet[:certname])
- rescue SystemExit,NoMemoryError
- raise
- rescue Exception => detail
- puts detail.backtrace if Puppet[:trace]
- raise Puppet::Error, "Could not retrieve local facts: #{detail}"
- end
+ def find_facts
+ # This works because puppet agent configures Facts to use 'facter' for
+ # finding facts and the 'rest' terminus for caching them. Thus, we'll
+ # compile them and then "cache" them on the server.
+ begin
+ reload_facter
+ Puppet::Node::Facts.find(Puppet[:certname])
+ rescue SystemExit,NoMemoryError
+ raise
+ rescue Exception => detail
+ puts detail.backtrace if Puppet[:trace]
+ raise Puppet::Error, "Could not retrieve local facts: #{detail}"
end
+ end
- def facts_for_uploading
- facts = find_facts
- #format = facts.class.default_format
-
- if facts.support_format?(:b64_zlib_yaml)
- format = :b64_zlib_yaml
- else
- format = :yaml
- end
-
- text = facts.render(format)
+ def facts_for_uploading
+ facts = find_facts
+ #format = facts.class.default_format
- {:facts_format => format, :facts => CGI.escape(text)}
+ if facts.support_format?(:b64_zlib_yaml)
+ format = :b64_zlib_yaml
+ else
+ format = :yaml
end
- # Retrieve facts from the central server.
- def download_fact_plugins
- return unless download_fact_plugins?
+ text = facts.render(format)
- # Deprecated prior to 0.25, as of 5/19/2008
- Puppet.warning "Fact syncing is deprecated as of 0.25 -- use 'pluginsync' instead"
+ {:facts_format => format, :facts => CGI.escape(text)}
+ end
- Puppet::Configurer::Downloader.new("fact", Puppet[:factdest], Puppet[:factsource], Puppet[:factsignore]).evaluate
- end
+ # Retrieve facts from the central server.
+ def download_fact_plugins
+ return unless download_fact_plugins?
+
+ # Deprecated prior to 0.25, as of 5/19/2008
+ Puppet.warning "Fact syncing is deprecated as of 0.25 -- use 'pluginsync' instead"
- # Clear out all of the loaded facts and reload them from disk.
- # NOTE: This is clumsy and shouldn't be required for later (1.5.x) versions
- # of Facter.
- def reload_facter
- Facter.clear
+ Puppet::Configurer::Downloader.new("fact", Puppet[:factdest], Puppet[:factsource], Puppet[:factsignore]).evaluate
+ end
- # Reload everything.
- if Facter.respond_to? :loadfacts
- Facter.loadfacts
- elsif Facter.respond_to? :load
- Facter.load
- else
- Puppet.warning "You should upgrade your version of Facter to at least 1.3.8"
- end
+ # Clear out all of the loaded facts and reload them from disk.
+ # NOTE: This is clumsy and shouldn't be required for later (1.5.x) versions
+ # of Facter.
+ def reload_facter
+ Facter.clear
- # This loads all existing facts and any new ones. We have to remove and
- # reload because there's no way to unload specific facts.
- Puppet::Node::Facts::Facter.load_fact_plugins
+ # Reload everything.
+ if Facter.respond_to? :loadfacts
+ Facter.loadfacts
+ elsif Facter.respond_to? :load
+ Facter.load
+ else
+ Puppet.warning "You should upgrade your version of Facter to at least 1.3.8"
end
+
+ # This loads all existing facts and any new ones. We have to remove and
+ # reload because there's no way to unload specific facts.
+ Puppet::Node::Facts::Facter.load_fact_plugins
+ end
end
diff --git a/lib/puppet/configurer/plugin_handler.rb b/lib/puppet/configurer/plugin_handler.rb
index 98c8de3..539441e 100644
--- a/lib/puppet/configurer/plugin_handler.rb
+++ b/lib/puppet/configurer/plugin_handler.rb
@@ -2,27 +2,27 @@
# just included into the agent, but having it here makes it
# easier to test.
module Puppet::Configurer::PluginHandler
- def download_plugins?
- Puppet[:pluginsync]
- end
+ def download_plugins?
+ Puppet[:pluginsync]
+ end
- # Retrieve facts from the central server.
- def download_plugins
- return nil unless download_plugins?
- Puppet::Configurer::Downloader.new("plugin", Puppet[:plugindest], Puppet[:pluginsource], Puppet[:pluginsignore]).evaluate.each { |file| load_plugin(file) }
- end
+ # Retrieve facts from the central server.
+ def download_plugins
+ return nil unless download_plugins?
+ Puppet::Configurer::Downloader.new("plugin", Puppet[:plugindest], Puppet[:pluginsource], Puppet[:pluginsignore]).evaluate.each { |file| load_plugin(file) }
+ end
- def load_plugin(file)
- return unless FileTest.exist?(file)
- return if FileTest.directory?(file)
+ def load_plugin(file)
+ return unless FileTest.exist?(file)
+ return if FileTest.directory?(file)
- begin
- Puppet.info "Loading downloaded plugin #{file}"
- load file
- rescue SystemExit,NoMemoryError
- raise
- rescue Exception => detail
- Puppet.err "Could not load downloaded file #{file}: #{detail}"
- end
+ begin
+ Puppet.info "Loading downloaded plugin #{file}"
+ load file
+ rescue SystemExit,NoMemoryError
+ raise
+ rescue Exception => detail
+ Puppet.err "Could not load downloaded file #{file}: #{detail}"
end
+ end
end
diff --git a/lib/puppet/daemon.rb b/lib/puppet/daemon.rb
index b0c2b56..aa4a12b 100755
--- a/lib/puppet/daemon.rb
+++ b/lib/puppet/daemon.rb
@@ -6,125 +6,125 @@ require 'puppet/application'
# A module that handles operations common to all daemons. This is included
# into the Server and Client base classes.
class Puppet::Daemon
- attr_accessor :agent, :server, :argv
+ attr_accessor :agent, :server, :argv
- def daemonname
- Puppet[:name]
- end
+ def daemonname
+ Puppet[:name]
+ end
- # Put the daemon into the background.
- def daemonize
- if pid = fork
- Process.detach(pid)
- exit(0)
- end
-
- create_pidfile
-
- # Get rid of console logging
- Puppet::Util::Log.close(:console)
-
- Process.setsid
- Dir.chdir("/")
- begin
- $stdin.reopen "/dev/null"
- $stdout.reopen "/dev/null", "a"
- $stderr.reopen $stdout
- Puppet::Util::Log.reopen
- rescue => detail
- Puppet.err "Could not start #{Puppet[:name]}: #{detail}"
- Puppet::Util::secure_open("/tmp/daemonout", "w") { |f|
- f.puts "Could not start #{Puppet[:name]}: #{detail}"
- }
- exit(12)
- end
+ # Put the daemon into the background.
+ def daemonize
+ if pid = fork
+ Process.detach(pid)
+ exit(0)
end
- # Create a pidfile for our daemon, so we can be stopped and others
- # don't try to start.
- def create_pidfile
- Puppet::Util.sync(Puppet[:name]).synchronize(Sync::EX) do
- raise "Could not create PID file: #{pidfile}" unless Puppet::Util::Pidlock.new(pidfile).lock
- end
+ create_pidfile
+
+ # Get rid of console logging
+ Puppet::Util::Log.close(:console)
+
+ Process.setsid
+ Dir.chdir("/")
+ begin
+ $stdin.reopen "/dev/null"
+ $stdout.reopen "/dev/null", "a"
+ $stderr.reopen $stdout
+ Puppet::Util::Log.reopen
+ rescue => detail
+ Puppet.err "Could not start #{Puppet[:name]}: #{detail}"
+ Puppet::Util::secure_open("/tmp/daemonout", "w") { |f|
+ f.puts "Could not start #{Puppet[:name]}: #{detail}"
+ }
+ exit(12)
end
+ end
- # Provide the path to our pidfile.
- def pidfile
- Puppet[:pidfile]
+ # Create a pidfile for our daemon, so we can be stopped and others
+ # don't try to start.
+ def create_pidfile
+ Puppet::Util.sync(Puppet[:name]).synchronize(Sync::EX) do
+ raise "Could not create PID file: #{pidfile}" unless Puppet::Util::Pidlock.new(pidfile).lock
end
-
- def reexec
- raise Puppet::DevError, "Cannot reexec unless ARGV arguments are set" unless argv
- command = $0 + " " + argv.join(" ")
- Puppet.notice "Restarting with '#{command}'"
- stop(:exit => false)
- exec(command)
+ end
+
+ # Provide the path to our pidfile.
+ def pidfile
+ Puppet[:pidfile]
+ end
+
+ def reexec
+ raise Puppet::DevError, "Cannot reexec unless ARGV arguments are set" unless argv
+ command = $0 + " " + argv.join(" ")
+ Puppet.notice "Restarting with '#{command}'"
+ stop(:exit => false)
+ exec(command)
+ end
+
+ def reload
+ return unless agent
+ if agent.running?
+ Puppet.notice "Not triggering already-running agent"
+ return
end
- def reload
- return unless agent
- if agent.running?
- Puppet.notice "Not triggering already-running agent"
- return
- end
+ agent.run
+ end
- agent.run
+ # Remove the pid file for our daemon.
+ def remove_pidfile
+ Puppet::Util.sync(Puppet[:name]).synchronize(Sync::EX) do
+ locker = Puppet::Util::Pidlock.new(pidfile)
+ locker.unlock or Puppet.err "Could not remove PID file #{pidfile}" if locker.locked?
end
-
- # Remove the pid file for our daemon.
- def remove_pidfile
- Puppet::Util.sync(Puppet[:name]).synchronize(Sync::EX) do
- locker = Puppet::Util::Pidlock.new(pidfile)
- locker.unlock or Puppet.err "Could not remove PID file #{pidfile}" if locker.locked?
- end
+ end
+
+ def restart
+ Puppet::Application.restart!
+ reexec unless agent and agent.running?
+ end
+
+ def reopen_logs
+ Puppet::Util::Log.reopen
+ end
+
+ # Trap a couple of the main signals. This should probably be handled
+ # in a way that anyone else can register callbacks for traps, but, eh.
+ def set_signal_traps
+ signals = {:INT => :stop, :TERM => :stop }
+ # extended signals not supported under windows
+ signals.update({:HUP => :restart, :USR1 => :reload, :USR2 => :reopen_logs }) unless Puppet.features.microsoft_windows?
+ signals.each do |signal, method|
+ trap(signal) do
+ Puppet.notice "Caught #{signal}; calling #{method}"
+ send(method)
+ end
end
+ end
- def restart
- Puppet::Application.restart!
- reexec unless agent and agent.running?
- end
+ # Stop everything
+ def stop(args = {:exit => true})
+ Puppet::Application.stop!
- def reopen_logs
- Puppet::Util::Log.reopen
- end
+ server.stop if server
- # Trap a couple of the main signals. This should probably be handled
- # in a way that anyone else can register callbacks for traps, but, eh.
- def set_signal_traps
- signals = {:INT => :stop, :TERM => :stop }
- # extended signals not supported under windows
- signals.update({:HUP => :restart, :USR1 => :reload, :USR2 => :reopen_logs }) unless Puppet.features.microsoft_windows?
- signals.each do |signal, method|
- trap(signal) do
- Puppet.notice "Caught #{signal}; calling #{method}"
- send(method)
- end
- end
- end
+ remove_pidfile
- # Stop everything
- def stop(args = {:exit => true})
- Puppet::Application.stop!
+ Puppet::Util::Log.close_all
- server.stop if server
+ exit if args[:exit]
+ end
- remove_pidfile
+ def start
+ set_signal_traps
- Puppet::Util::Log.close_all
+ create_pidfile
- exit if args[:exit]
- end
-
- def start
- set_signal_traps
-
- create_pidfile
+ raise Puppet::DevError, "Daemons must have an agent, server, or both" unless agent or server
+ agent.start if agent
+ server.start if server
- raise Puppet::DevError, "Daemons must have an agent, server, or both" unless agent or server
- agent.start if agent
- server.start if server
-
- EventLoop.current.run
- end
+ EventLoop.current.run
+ end
end
diff --git a/lib/puppet/defaults.rb b/lib/puppet/defaults.rb
index 18d0456..0af40f2 100644
--- a/lib/puppet/defaults.rb
+++ b/lib/puppet/defaults.rb
@@ -1,795 +1,795 @@
# The majority of the system configuration parameters are set in this file.
module Puppet
- setdefaults(:main,
- :confdir => [Puppet.run_mode.conf_dir, "The main Puppet configuration directory. The default for this parameter is calculated based on the user. If the process
- is running as root or the user that ``puppet master`` is supposed to run as, it defaults to a system directory, but if it's running as any other user,
- it defaults to being in ``~``."],
- :vardir => [Puppet.run_mode.var_dir, "Where Puppet stores dynamic and growing data. The default for this parameter is calculated specially, like `confdir`_."],
- :name => [Puppet.application_name.to_s, "The name of the application, if we are running as one. The
- default is essentially $0 without the path or ``.rb``."],
- :mode => [Puppet.run_mode.name.to_s, "The effective 'run mode' of the application: master, agent, or user."]
- )
-
- setdefaults(:main, :logdir => Puppet.run_mode.logopts)
-
- setdefaults(:main,
- :trace => [false, "Whether to print stack traces on some errors"],
- :autoflush => [false, "Whether log files should always flush to disk."],
- :syslogfacility => ["daemon", "What syslog facility to use when logging to
- syslog. Syslog has a fixed list of valid facilities, and you must
- choose one of those; you cannot just make one up."],
- :statedir => { :default => "$vardir/state",
- :mode => 01755,
- :desc => "The directory where Puppet state is stored. Generally,
- this directory can be removed without causing harm (although it
- might result in spurious service restarts)."
- },
- :rundir => {
- :default => Puppet.run_mode.run_dir,
- :mode => 01777,
- :desc => "Where Puppet PID files are kept."
- },
- :genconfig => [false,
- "Whether to just print a configuration to stdout and exit. Only makes
- sense when used interactively. Takes into account arguments specified
- on the CLI."],
- :genmanifest => [false,
- "Whether to just print a manifest to stdout and exit. Only makes
- sense when used interactively. Takes into account arguments specified
- on the CLI."],
- :configprint => ["",
- "Print the value of a specific configuration parameter. If a
- parameter is provided for this, then the value is printed and puppet
- exits. Comma-separate multiple values. For a list of all values,
- specify 'all'. This feature is only available in Puppet versions
- higher than 0.18.4."],
- :color => ["ansi", "Whether to use colors when logging to the console.
- Valid values are ``ansi`` (equivalent to ``true``), ``html`` (mostly
- used during testing with TextMate), and ``false``, which produces
- no color."],
- :mkusers => [false,
- "Whether to create the necessary user and group that puppet agent will
- run as."],
- :manage_internal_file_permissions => [true,
- "Whether Puppet should manage the owner, group, and mode of files
- it uses internally"
- ],
- :onetime => [false,
- "Run the configuration once, rather than as a long-running
- daemon. This is useful for interactively running puppetd."
- ],
- :path => {:default => "none",
- :desc => "The shell search path. Defaults to whatever is inherited
- from the parent process.",
- :call_on_define => true, # Call our hook with the default value, so we always get the libdir set.
- :hook => proc do |value|
- ENV["PATH"] = "" if ENV["PATH"].nil?
- ENV["PATH"] = value unless value == "none"
- paths = ENV["PATH"].split(File::PATH_SEPARATOR)
- %w{/usr/sbin /sbin}.each do |path|
- ENV["PATH"] += File::PATH_SEPARATOR + path unless paths.include?(path)
- end
- value
- end
- },
- :libdir => {:default => "$vardir/lib",
- :desc => "An extra search path for Puppet. This is only useful
- for those files that Puppet will load on demand, and is only
- guaranteed to work for those cases. In fact, the autoload
- mechanism is responsible for making sure this directory
- is in Ruby's search path",
- :call_on_define => true, # Call our hook with the default value, so we always get the libdir set.
- :hook => proc do |value|
- $LOAD_PATH.delete(@oldlibdir) if defined?(@oldlibdir) and $LOAD_PATH.include?(@oldlibdir)
- @oldlibdir = value
- $LOAD_PATH << value
- end
- },
- :ignoreimport => [false, "A parameter that can be used in commit
- hooks, since it enables you to parse-check a single file rather
- than requiring that all files exist."],
- :authconfig => [ "$confdir/namespaceauth.conf",
- "The configuration file that defines the rights to the different
- namespaces and methods. This can be used as a coarse-grained
- authorization system for both ``puppet agent`` and ``puppet master``."
- ],
- :environment => {:default => "production", :desc => "The environment Puppet is running in. For clients
- (e.g., ``puppet agent``) this determines the environment itself, which
- is used to find modules and much more. For servers (i.e., ``puppet master``) this provides the default environment for nodes
- we know nothing about."
- },
- :diff_args => ["-u", "Which arguments to pass to the diff command when printing differences between files."],
- :diff => ["diff", "Which diff command to use when printing differences between files."],
- :show_diff => [false, "Whether to print a contextual diff when files are being replaced. The diff
- is printed on stdout, so this option is meaningless unless you are running Puppet interactively.
- This feature currently requires the ``diff/lcs`` Ruby library."],
- :daemonize => { :default => true,
- :desc => "Send the process into the background. This is the default.",
- :short => "D"
- },
- :maximum_uid => [4294967290, "The maximum allowed UID. Some platforms use negative UIDs
- but then ship with tools that do not know how to handle signed ints, so the UIDs show up as
- huge numbers that can then not be fed back into the system. This is a hackish way to fail in a
- slightly more useful way when that happens."],
- :node_terminus => ["plain", "Where to find information about nodes."],
- :catalog_terminus => ["compiler", "Where to get node catalogs. This is useful to change if, for instance,
- you'd like to pre-compile catalogs and store them in memcached or some other easily-accessed store."],
- :facts_terminus => ["facter", "Where to get node facts."],
- :httplog => { :default => "$logdir/http.log",
- :owner => "root",
- :mode => 0640,
- :desc => "Where the puppet agent web server logs."
- },
- :http_proxy_host => ["none",
- "The HTTP proxy host to use for outgoing connections. Note: You
- may need to use a FQDN for the server hostname when using a proxy."],
- :http_proxy_port => [3128, "The HTTP proxy port to use for outgoing connections"],
- :filetimeout => [ 15,
- "The minimum time to wait (in seconds) between checking for updates in
- configuration files. This timeout determines how quickly Puppet checks whether
- a file (such as manifests or templates) has changed on disk."
- ],
- :queue_type => ["stomp", "Which type of queue to use for asynchronous processing."],
- :queue_type => ["stomp", "Which type of queue to use for asynchronous processing."],
- :queue_source => ["stomp://localhost:61613/", "Which type of queue to use for asynchronous processing. If your stomp server requires
- authentication, you can include it in the URI as long as your stomp client library is at least 1.1.1"],
- :async_storeconfigs => {:default => false, :desc => "Whether to use a queueing system to provide asynchronous database integration.
- Requires that ``puppetqd`` be running and that 'PSON' support for ruby be installed.",
- :hook => proc do |value|
- if value
- # This reconfigures the terminii for Node, Facts, and Catalog
- Puppet.settings[:storeconfigs] = true
-
- # But then we modify the configuration
- Puppet::Resource::Catalog.cache_class = :queue
- else
- raise "Cannot disable asynchronous storeconfigs in a running process"
- end
- end
- },
- :thin_storeconfigs => {:default => false, :desc =>
- "Boolean; wether storeconfigs store in the database only the facts and exported resources.
- If true, then storeconfigs performance will be higher and still allow exported/collected
- resources, but other usage external to Puppet might not work",
- :hook => proc do |value|
- Puppet.settings[:storeconfigs] = true if value
- end
- },
- :config_version => ["", "How to determine the configuration version. By default, it will be the
- time that the configuration is parsed, but you can provide a shell script to override how the
- version is determined. The output of this script will be added to every log message in the
- reports, allowing you to correlate changes on your hosts to the source version on the server."],
- :zlib => [true,
- "Boolean; whether to use the zlib library",
- ],
- :prerun_command => ["", "A command to run before every agent run. If this command returns a non-zero
- return code, the entire Puppet run will fail."],
- :postrun_command => ["", "A command to run after every agent run. If this command returns a non-zero
- return code, the entire Puppet run will be considered to have failed, even though it might have
- performed work during the normal run."],
- :freeze_main => [false, "Freezes the 'main' class, disallowing any code to be added to it. This
- essentially means that you can't have any code outside of a node, class, or definition other
- than in the site manifest."]
- )
-
- hostname = Facter["hostname"].value
- domain = Facter["domain"].value
- if domain and domain != ""
- fqdn = [hostname, domain].join(".")
- else
- fqdn = hostname
- end
-
-
- Puppet.setdefaults(
- :main,
-
- # We have to downcase the fqdn, because the current ssl stuff (as oppsed to in master) doesn't have good facilities for
- # manipulating naming.
- :certname => {:default => fqdn.downcase, :desc => "The name to use when handling certificates. Defaults
- to the fully qualified domain name.",
- :call_on_define => true, # Call our hook with the default value, so we're always downcased
- :hook => proc { |value| raise(ArgumentError, "Certificate names must be lower case; see #1168") unless value == value.downcase }},
- :certdnsnames => ['', "The DNS names on the Server certificate as a colon-separated list.
- If it's anything other than an empty string, it will be used as an alias in the created
- certificate. By default, only the server gets an alias set up, and only for 'puppet'."],
- :certdir => {
- :default => "$ssldir/certs",
- :owner => "service",
- :desc => "The certificate directory."
- },
- :ssldir => {
- :default => "$confdir/ssl",
- :mode => 0771,
- :owner => "service",
- :desc => "Where SSL certificates are kept."
- },
- :publickeydir => {
- :default => "$ssldir/public_keys",
- :owner => "service",
- :desc => "The public key directory."
- },
- :requestdir => {
- :default => "$ssldir/certificate_requests",
- :owner => "service",
- :desc => "Where host certificate requests are stored."
- },
- :privatekeydir => { :default => "$ssldir/private_keys",
- :mode => 0750,
- :owner => "service",
- :desc => "The private key directory."
- },
- :privatedir => { :default => "$ssldir/private",
- :mode => 0750,
- :owner => "service",
- :desc => "Where the client stores private certificate information."
- },
- :passfile => { :default => "$privatedir/password",
- :mode => 0640,
- :owner => "service",
- :desc => "Where puppet agent stores the password for its private key.
- Generally unused."
- },
- :hostcsr => { :default => "$ssldir/csr_$certname.pem",
- :mode => 0644,
- :owner => "service",
- :desc => "Where individual hosts store and look for their certificate requests."
- },
- :hostcert => { :default => "$certdir/$certname.pem",
- :mode => 0644,
- :owner => "service",
- :desc => "Where individual hosts store and look for their certificates."
- },
- :hostprivkey => { :default => "$privatekeydir/$certname.pem",
- :mode => 0600,
- :owner => "service",
- :desc => "Where individual hosts store and look for their private key."
- },
- :hostpubkey => { :default => "$publickeydir/$certname.pem",
- :mode => 0644,
- :owner => "service",
- :desc => "Where individual hosts store and look for their public key."
- },
- :localcacert => { :default => "$certdir/ca.pem",
- :mode => 0644,
- :owner => "service",
- :desc => "Where each client stores the CA certificate."
- },
- :hostcrl => { :default => "$ssldir/crl.pem",
- :mode => 0644,
- :owner => "service",
- :desc => "Where the host's certificate revocation list can be found.
- This is distinct from the certificate authority's CRL."
- },
- :certificate_revocation => [true, "Whether certificate revocation should be supported by downloading a Certificate Revocation List (CRL)
- to all clients. If enabled, CA chaining will almost definitely not work."]
- )
+ setdefaults(:main,
+ :confdir => [Puppet.run_mode.conf_dir, "The main Puppet configuration directory. The default for this parameter is calculated based on the user. If the process
+ is running as root or the user that ``puppet master`` is supposed to run as, it defaults to a system directory, but if it's running as any other user,
+ it defaults to being in ``~``."],
+ :vardir => [Puppet.run_mode.var_dir, "Where Puppet stores dynamic and growing data. The default for this parameter is calculated specially, like `confdir`_."],
+ :name => [Puppet.application_name.to_s, "The name of the application, if we are running as one. The
+ default is essentially $0 without the path or ``.rb``."],
+ :mode => [Puppet.run_mode.name.to_s, "The effective 'run mode' of the application: master, agent, or user."]
+ )
+
+ setdefaults(:main, :logdir => Puppet.run_mode.logopts)
+
+ setdefaults(:main,
+ :trace => [false, "Whether to print stack traces on some errors"],
+ :autoflush => [false, "Whether log files should always flush to disk."],
+ :syslogfacility => ["daemon", "What syslog facility to use when logging to
+ syslog. Syslog has a fixed list of valid facilities, and you must
+ choose one of those; you cannot just make one up."],
+ :statedir => { :default => "$vardir/state",
+ :mode => 01755,
+ :desc => "The directory where Puppet state is stored. Generally,
+ this directory can be removed without causing harm (although it
+ might result in spurious service restarts)."
+ },
+ :rundir => {
+ :default => Puppet.run_mode.run_dir,
+ :mode => 01777,
+ :desc => "Where Puppet PID files are kept."
+ },
+ :genconfig => [false,
+ "Whether to just print a configuration to stdout and exit. Only makes
+ sense when used interactively. Takes into account arguments specified
+ on the CLI."],
+ :genmanifest => [false,
+ "Whether to just print a manifest to stdout and exit. Only makes
+ sense when used interactively. Takes into account arguments specified
+ on the CLI."],
+ :configprint => ["",
+ "Print the value of a specific configuration parameter. If a
+ parameter is provided for this, then the value is printed and puppet
+ exits. Comma-separate multiple values. For a list of all values,
+ specify 'all'. This feature is only available in Puppet versions
+ higher than 0.18.4."],
+ :color => ["ansi", "Whether to use colors when logging to the console.
+ Valid values are ``ansi`` (equivalent to ``true``), ``html`` (mostly
+ used during testing with TextMate), and ``false``, which produces
+ no color."],
+ :mkusers => [false,
+ "Whether to create the necessary user and group that puppet agent will
+ run as."],
+ :manage_internal_file_permissions => [true,
+ "Whether Puppet should manage the owner, group, and mode of files
+ it uses internally"
+ ],
+ :onetime => [false,
+ "Run the configuration once, rather than as a long-running
+ daemon. This is useful for interactively running puppetd."
+ ],
+ :path => {:default => "none",
+ :desc => "The shell search path. Defaults to whatever is inherited
+ from the parent process.",
+ :call_on_define => true, # Call our hook with the default value, so we always get the libdir set.
+ :hook => proc do |value|
+ ENV["PATH"] = "" if ENV["PATH"].nil?
+ ENV["PATH"] = value unless value == "none"
+ paths = ENV["PATH"].split(File::PATH_SEPARATOR)
+ %w{/usr/sbin /sbin}.each do |path|
+ ENV["PATH"] += File::PATH_SEPARATOR + path unless paths.include?(path)
+ end
+ value
+ end
+ },
+ :libdir => {:default => "$vardir/lib",
+ :desc => "An extra search path for Puppet. This is only useful
+ for those files that Puppet will load on demand, and is only
+ guaranteed to work for those cases. In fact, the autoload
+ mechanism is responsible for making sure this directory
+ is in Ruby's search path",
+ :call_on_define => true, # Call our hook with the default value, so we always get the libdir set.
+ :hook => proc do |value|
+ $LOAD_PATH.delete(@oldlibdir) if defined?(@oldlibdir) and $LOAD_PATH.include?(@oldlibdir)
+ @oldlibdir = value
+ $LOAD_PATH << value
+ end
+ },
+ :ignoreimport => [false, "A parameter that can be used in commit
+ hooks, since it enables you to parse-check a single file rather
+ than requiring that all files exist."],
+ :authconfig => [ "$confdir/namespaceauth.conf",
+ "The configuration file that defines the rights to the different
+ namespaces and methods. This can be used as a coarse-grained
+ authorization system for both ``puppet agent`` and ``puppet master``."
+ ],
+ :environment => {:default => "production", :desc => "The environment Puppet is running in. For clients
+ (e.g., ``puppet agent``) this determines the environment itself, which
+ is used to find modules and much more. For servers (i.e., ``puppet master``) this provides the default environment for nodes
+ we know nothing about."
+ },
+ :diff_args => ["-u", "Which arguments to pass to the diff command when printing differences between files."],
+ :diff => ["diff", "Which diff command to use when printing differences between files."],
+ :show_diff => [false, "Whether to print a contextual diff when files are being replaced. The diff
+ is printed on stdout, so this option is meaningless unless you are running Puppet interactively.
+ This feature currently requires the ``diff/lcs`` Ruby library."],
+ :daemonize => { :default => true,
+ :desc => "Send the process into the background. This is the default.",
+ :short => "D"
+ },
+ :maximum_uid => [4294967290, "The maximum allowed UID. Some platforms use negative UIDs
+ but then ship with tools that do not know how to handle signed ints, so the UIDs show up as
+ huge numbers that can then not be fed back into the system. This is a hackish way to fail in a
+ slightly more useful way when that happens."],
+ :node_terminus => ["plain", "Where to find information about nodes."],
+ :catalog_terminus => ["compiler", "Where to get node catalogs. This is useful to change if, for instance,
+ you'd like to pre-compile catalogs and store them in memcached or some other easily-accessed store."],
+ :facts_terminus => ["facter", "Where to get node facts."],
+ :httplog => { :default => "$logdir/http.log",
+ :owner => "root",
+ :mode => 0640,
+ :desc => "Where the puppet agent web server logs."
+ },
+ :http_proxy_host => ["none",
+ "The HTTP proxy host to use for outgoing connections. Note: You
+ may need to use a FQDN for the server hostname when using a proxy."],
+ :http_proxy_port => [3128, "The HTTP proxy port to use for outgoing connections"],
+ :filetimeout => [ 15,
+ "The minimum time to wait (in seconds) between checking for updates in
+ configuration files. This timeout determines how quickly Puppet checks whether
+ a file (such as manifests or templates) has changed on disk."
+ ],
+ :queue_type => ["stomp", "Which type of queue to use for asynchronous processing."],
+ :queue_type => ["stomp", "Which type of queue to use for asynchronous processing."],
+ :queue_source => ["stomp://localhost:61613/", "Which type of queue to use for asynchronous processing. If your stomp server requires
+ authentication, you can include it in the URI as long as your stomp client library is at least 1.1.1"],
+ :async_storeconfigs => {:default => false, :desc => "Whether to use a queueing system to provide asynchronous database integration.
+ Requires that ``puppetqd`` be running and that 'PSON' support for ruby be installed.",
+ :hook => proc do |value|
+ if value
+ # This reconfigures the terminii for Node, Facts, and Catalog
+ Puppet.settings[:storeconfigs] = true
+
+ # But then we modify the configuration
+ Puppet::Resource::Catalog.cache_class = :queue
+ else
+ raise "Cannot disable asynchronous storeconfigs in a running process"
+ end
+ end
+ },
+ :thin_storeconfigs => {:default => false, :desc =>
+ "Boolean; wether storeconfigs store in the database only the facts and exported resources.
+ If true, then storeconfigs performance will be higher and still allow exported/collected
+ resources, but other usage external to Puppet might not work",
+ :hook => proc do |value|
+ Puppet.settings[:storeconfigs] = true if value
+ end
+ },
+ :config_version => ["", "How to determine the configuration version. By default, it will be the
+ time that the configuration is parsed, but you can provide a shell script to override how the
+ version is determined. The output of this script will be added to every log message in the
+ reports, allowing you to correlate changes on your hosts to the source version on the server."],
+ :zlib => [true,
+ "Boolean; whether to use the zlib library",
+ ],
+ :prerun_command => ["", "A command to run before every agent run. If this command returns a non-zero
+ return code, the entire Puppet run will fail."],
+ :postrun_command => ["", "A command to run after every agent run. If this command returns a non-zero
+ return code, the entire Puppet run will be considered to have failed, even though it might have
+ performed work during the normal run."],
+ :freeze_main => [false, "Freezes the 'main' class, disallowing any code to be added to it. This
+ essentially means that you can't have any code outside of a node, class, or definition other
+ than in the site manifest."]
+ )
+
+ hostname = Facter["hostname"].value
+ domain = Facter["domain"].value
+ if domain and domain != ""
+ fqdn = [hostname, domain].join(".")
+ else
+ fqdn = hostname
+ end
+
+
+ Puppet.setdefaults(
+ :main,
+
+ # We have to downcase the fqdn, because the current ssl stuff (as oppsed to in master) doesn't have good facilities for
+ # manipulating naming.
+ :certname => {:default => fqdn.downcase, :desc => "The name to use when handling certificates. Defaults
+ to the fully qualified domain name.",
+ :call_on_define => true, # Call our hook with the default value, so we're always downcased
+ :hook => proc { |value| raise(ArgumentError, "Certificate names must be lower case; see #1168") unless value == value.downcase }},
+ :certdnsnames => ['', "The DNS names on the Server certificate as a colon-separated list.
+ If it's anything other than an empty string, it will be used as an alias in the created
+ certificate. By default, only the server gets an alias set up, and only for 'puppet'."],
+ :certdir => {
+ :default => "$ssldir/certs",
+ :owner => "service",
+ :desc => "The certificate directory."
+ },
+ :ssldir => {
+ :default => "$confdir/ssl",
+ :mode => 0771,
+ :owner => "service",
+ :desc => "Where SSL certificates are kept."
+ },
+ :publickeydir => {
+ :default => "$ssldir/public_keys",
+ :owner => "service",
+ :desc => "The public key directory."
+ },
+ :requestdir => {
+ :default => "$ssldir/certificate_requests",
+ :owner => "service",
+ :desc => "Where host certificate requests are stored."
+ },
+ :privatekeydir => { :default => "$ssldir/private_keys",
+ :mode => 0750,
+ :owner => "service",
+ :desc => "The private key directory."
+ },
+ :privatedir => { :default => "$ssldir/private",
+ :mode => 0750,
+ :owner => "service",
+ :desc => "Where the client stores private certificate information."
+ },
+ :passfile => { :default => "$privatedir/password",
+ :mode => 0640,
+ :owner => "service",
+ :desc => "Where puppet agent stores the password for its private key.
+ Generally unused."
+ },
+ :hostcsr => { :default => "$ssldir/csr_$certname.pem",
+ :mode => 0644,
+ :owner => "service",
+ :desc => "Where individual hosts store and look for their certificate requests."
+ },
+ :hostcert => { :default => "$certdir/$certname.pem",
+ :mode => 0644,
+ :owner => "service",
+ :desc => "Where individual hosts store and look for their certificates."
+ },
+ :hostprivkey => { :default => "$privatekeydir/$certname.pem",
+ :mode => 0600,
+ :owner => "service",
+ :desc => "Where individual hosts store and look for their private key."
+ },
+ :hostpubkey => { :default => "$publickeydir/$certname.pem",
+ :mode => 0644,
+ :owner => "service",
+ :desc => "Where individual hosts store and look for their public key."
+ },
+ :localcacert => { :default => "$certdir/ca.pem",
+ :mode => 0644,
+ :owner => "service",
+ :desc => "Where each client stores the CA certificate."
+ },
+ :hostcrl => { :default => "$ssldir/crl.pem",
+ :mode => 0644,
+ :owner => "service",
+ :desc => "Where the host's certificate revocation list can be found.
+ This is distinct from the certificate authority's CRL."
+ },
+ :certificate_revocation => [true, "Whether certificate revocation should be supported by downloading a Certificate Revocation List (CRL)
+ to all clients. If enabled, CA chaining will almost definitely not work."]
+ )
+
+
+ setdefaults(
+ :ca,
+ :ca_name => ["$certname", "The name to use the Certificate Authority certificate."],
+ :cadir => { :default => "$ssldir/ca",
+ :owner => "service",
+ :group => "service",
+ :mode => 0770,
+ :desc => "The root directory for the certificate authority."
+ },
+ :cacert => { :default => "$cadir/ca_crt.pem",
+ :owner => "service",
+ :group => "service",
+ :mode => 0660,
+ :desc => "The CA certificate."
+ },
+ :cakey => { :default => "$cadir/ca_key.pem",
+ :owner => "service",
+ :group => "service",
+ :mode => 0660,
+ :desc => "The CA private key."
+ },
+ :capub => { :default => "$cadir/ca_pub.pem",
+ :owner => "service",
+ :group => "service",
+ :desc => "The CA public key."
+ },
+ :cacrl => { :default => "$cadir/ca_crl.pem",
+ :owner => "service",
+ :group => "service",
+ :mode => 0664,
+
+ :desc => "The certificate revocation list (CRL) for the CA. Will be used if present but otherwise ignored.",
+ :hook => proc do |value|
+ if value == 'false'
+ Puppet.warning "Setting the :cacrl to 'false' is deprecated; Puppet will just ignore the crl if yours is missing"
+ end
+ end
+ },
+ :caprivatedir => { :default => "$cadir/private",
+ :owner => "service",
+ :group => "service",
+ :mode => 0770,
+ :desc => "Where the CA stores private certificate information."
+ },
+ :csrdir => { :default => "$cadir/requests",
+ :owner => "service",
+ :group => "service",
+ :desc => "Where the CA stores certificate requests"
+ },
+ :signeddir => { :default => "$cadir/signed",
+ :owner => "service",
+ :group => "service",
+ :mode => 0770,
+ :desc => "Where the CA stores signed certificates."
+ },
+ :capass => { :default => "$caprivatedir/ca.pass",
+ :owner => "service",
+ :group => "service",
+ :mode => 0660,
+ :desc => "Where the CA stores the password for the private key"
+ },
+ :serial => { :default => "$cadir/serial",
+ :owner => "service",
+ :group => "service",
+ :mode => 0644,
+ :desc => "Where the serial number for certificates is stored."
+ },
+ :autosign => { :default => "$confdir/autosign.conf",
+ :mode => 0644,
+ :desc => "Whether to enable autosign. Valid values are true (which
+ autosigns any key request, and is a very bad idea), false (which
+ never autosigns any key request), and the path to a file, which
+ uses that configuration file to determine which keys to sign."},
+ :ca_days => ["", "How long a certificate should be valid.
+ This parameter is deprecated, use ca_ttl instead"],
+ :ca_ttl => ["5y", "The default TTL for new certificates; valid values
+ must be an integer, optionally followed by one of the units
+ 'y' (years of 365 days), 'd' (days), 'h' (hours), or
+ 's' (seconds). The unit defaults to seconds. If this parameter
+ is set, ca_days is ignored. Examples are '3600' (one hour)
+ and '1825d', which is the same as '5y' (5 years) "],
+ :ca_md => ["md5", "The type of hash used in certificates."],
+ :req_bits => [2048, "The bit length of the certificates."],
+ :keylength => [1024, "The bit length of keys."],
+ :cert_inventory => {
+ :default => "$cadir/inventory.txt",
+ :mode => 0644,
+ :owner => "service",
+ :group => "service",
+ :desc => "A Complete listing of all certificates"
+ }
+ )
+
+ # Define the config default.
+
+ setdefaults(
+ Puppet.settings[:name],
+ :config => ["$confdir/puppet.conf",
+ "The configuration file for #{Puppet[:name]}."],
+ :pidfile => ["$rundir/$name.pid", "The pid file"],
+ :bindaddress => ["", "The address a listening server should bind to. Mongrel servers
+ default to 127.0.0.1 and WEBrick defaults to 0.0.0.0."],
+ :servertype => {:default => "webrick", :desc => "The type of server to use. Currently supported
+ options are webrick and mongrel. If you use mongrel, you will need
+ a proxy in front of the process or processes, since Mongrel cannot
+ speak SSL.",
+
+ :call_on_define => true, # Call our hook with the default value, so we always get the correct bind address set.
+ :hook => proc { |value| value == "webrick" ? Puppet.settings[:bindaddress] = "0.0.0.0" : Puppet.settings[:bindaddress] = "127.0.0.1" if Puppet.settings[:bindaddress] == "" }
+ }
+ )
+
+ setdefaults(:master,
+ :user => ["puppet", "The user puppet master should run as."],
+ :group => ["puppet", "The group puppet master should run as."],
+ :manifestdir => ["$confdir/manifests", "Where puppet master looks for its manifests."],
+ :manifest => ["$manifestdir/site.pp", "The entry-point manifest for puppet master."],
+ :code => ["", "Code to parse directly. This is essentially only used
+ by ``puppet``, and should only be set if you're writing your own Puppet
+ executable"],
+ :masterlog => { :default => "$logdir/puppetmaster.log",
+ :owner => "service",
+ :group => "service",
+ :mode => 0660,
+ :desc => "Where puppet master logs. This is generally not used,
+ since syslog is the default log destination."
+ },
+ :masterhttplog => { :default => "$logdir/masterhttp.log",
+ :owner => "service",
+ :group => "service",
+ :mode => 0660,
+ :create => true,
+ :desc => "Where the puppet master web server logs."
+ },
+ :masterport => [8140, "Which port puppet master listens on."],
+ :parseonly => [false, "Just check the syntax of the manifests."],
+ :node_name => ["cert", "How the puppetmaster determines the client's identity
+ and sets the 'hostname', 'fqdn' and 'domain' facts for use in the manifest,
+ in particular for determining which 'node' statement applies to the client.
+ Possible values are 'cert' (use the subject's CN in the client's
+ certificate) and 'facter' (use the hostname that the client
+ reported in its facts)"],
+ :bucketdir => {
+ :default => "$vardir/bucket",
+ :mode => 0750,
+ :owner => "service",
+ :group => "service",
+ :desc => "Where FileBucket files are stored."
+ },
+ :rest_authconfig => [ "$confdir/auth.conf",
+ "The configuration file that defines the rights to the different
+ rest indirections. This can be used as a fine-grained
+ authorization system for ``puppet master``."
+ ],
+ :ca => [true, "Wether the master should function as a certificate authority."],
+ :modulepath => {:default => "$confdir/modules:/usr/share/puppet/modules",
+ :desc => "The search path for modules as a colon-separated list of
+ directories.", :type => :setting }, # We don't want this to be considered a file, since it's multiple files.
+ :ssl_client_header => ["HTTP_X_CLIENT_DN", "The header containing an authenticated
+ client's SSL DN. Only used with Mongrel. This header must be set by the proxy
+ to the authenticated client's SSL DN (e.g., ``/CN=puppet.puppetlabs.com``).
+ See http://projects.puppetlabs.com/projects/puppet/wiki/Using_Mongrel for more information."],
+ :ssl_client_verify_header => ["HTTP_X_CLIENT_VERIFY", "The header containing the status
+ message of the client verification. Only used with Mongrel. This header must be set by the proxy
+ to 'SUCCESS' if the client successfully authenticated, and anything else otherwise.
+ See http://projects.puppetlabs.com/projects/puppet/wiki/Using_Mongrel for more information."],
+ # To make sure this directory is created before we try to use it on the server, we need
+ # it to be in the server section (#1138).
+ :yamldir => {:default => "$vardir/yaml", :owner => "service", :group => "service", :mode => "750",
+ :desc => "The directory in which YAML data is stored, usually in a subdirectory."},
+ :server_datadir => {:default => "$vardir/server_data", :owner => "service", :group => "service", :mode => "750",
+ :desc => "The directory in which serialized data is stored, usually in a subdirectory."},
+ :reports => ["store",
+ "The list of reports to generate. All reports are looked for
+ in puppet/reports/name.rb, and multiple report names should be
+ comma-separated (whitespace is okay)."
+ ],
+ :fileserverconfig => ["$confdir/fileserver.conf", "Where the fileserver configuration is stored."],
+ :rrddir => {:default => "$vardir/rrd",
+ :owner => "service",
+ :group => "service",
+ :desc => "The directory where RRD database files are stored.
+ Directories for each reporting host will be created under
+ this directory."
+ },
+ :rrdinterval => ["$runinterval", "How often RRD should expect data.
+ This should match how often the hosts report back to the server."],
+ :strict_hostname_checking => [false, "Whether to only search for the complete
+ hostname as it is in the certificate when searching for node information
+ in the catalogs."]
+ )
+
+ setdefaults(:agent,
+ :localconfig => { :default => "$statedir/localconfig",
+ :owner => "root",
+ :mode => 0660,
+ :desc => "Where puppet agent caches the local configuration. An
+ extension indicating the cache format is added automatically."},
+ :statefile => { :default => "$statedir/state.yaml",
+ :mode => 0660,
+ :desc => "Where puppet agent and puppet master store state associated
+ with the running configuration. In the case of puppet master,
+ this file reflects the state discovered through interacting
+ with clients."
+ },
+ :clientyamldir => {:default => "$vardir/client_yaml", :mode => "750", :desc => "The directory in which client-side YAML data is stored."},
+ :client_datadir => {:default => "$vardir/client_data", :mode => "750", :desc => "The directory in which serialized data is stored on the client."},
+ :classfile => { :default => "$statedir/classes.txt",
+ :owner => "root",
+ :mode => 0644,
+ :desc => "The file in which puppet agent stores a list of the classes
+ associated with the retrieved configuration. Can be loaded in
+ the separate ``puppet`` executable using the ``--loadclasses``
+ option."},
+ :puppetdlog => { :default => "$logdir/puppetd.log",
+ :owner => "root",
+ :mode => 0640,
+ :desc => "The log file for puppet agent. This is generally not used."
+ },
+ :server => ["puppet", "The server to which server puppet agent should connect"],
+ :ignoreschedules => [false,
+ "Boolean; whether puppet agent should ignore schedules. This is useful
+ for initial puppet agent runs."],
+ :puppetport => [8139, "Which port puppet agent listens on."],
+ :noop => [false, "Whether puppet agent should be run in noop mode."],
+ :runinterval => [1800, # 30 minutes
+ "How often puppet agent applies the client configuration; in seconds."],
+ :listen => [false, "Whether puppet agent should listen for
+ connections. If this is true, then by default only the
+ ``runner`` server is started, which allows remote authorized
+ and authenticated nodes to connect and trigger ``puppet agent``
+ runs."],
+ :ca_server => ["$server", "The server to use for certificate
+ authority requests. It's a separate server because it cannot
+ and does not need to horizontally scale."],
+ :ca_port => ["$masterport", "The port to use for the certificate authority."],
+ :catalog_format => {
+ :default => "",
+ :desc => "(Deprecated for 'preferred_serialization_format') What format to
+ use to dump the catalog. Only supports 'marshal' and 'yaml'. Only
+ matters on the client, since it asks the server for a specific format.",
+ :hook => proc { |value|
+ if value
+ Puppet.warning "Setting 'catalog_format' is deprecated; use 'preferred_serialization_format' instead."
+ Puppet.settings[:preferred_serialization_format] = value
+ end
+ }
+ },
+ :preferred_serialization_format => ["pson", "The preferred means of serializing
+ ruby instances for passing over the wire. This won't guarantee that all
+ instances will be serialized using this method, since not all classes
+ can be guaranteed to support this format, but it will be used for all
+ classes that support it."],
+ :puppetdlockfile => [ "$statedir/puppetdlock", "A lock file to temporarily stop puppet agent from doing anything."],
+ :usecacheonfailure => [true,
+ "Whether to use the cached configuration when the remote
+ configuration will not compile. This option is useful for testing
+ new configurations, where you want to fix the broken configuration
+ rather than reverting to a known-good one."
+ ],
+ :use_cached_catalog => [false,
+ "Whether to only use the cached catalog rather than compiling a new catalog
+ on every run. Puppet can be run with this enabled by default and then selectively
+ disabled when a recompile is desired."],
+ :ignorecache => [false,
+ "Ignore cache and always recompile the configuration. This is
+ useful for testing new configurations, where the local cache may in
+ fact be stale even if the timestamps are up to date - if the facts
+ change or if the server changes."
+ ],
+ :downcasefacts => [false, "Whether facts should be made all lowercase when sent to the server."],
+ :dynamicfacts => ["memorysize,memoryfree,swapsize,swapfree",
+ "Facts that are dynamic; these facts will be ignored when deciding whether
+ changed facts should result in a recompile. Multiple facts should be
+ comma-separated."],
+ :splaylimit => ["$runinterval",
+ "The maximum time to delay before runs. Defaults to being the same as the
+ run interval."],
+ :splay => [false,
+ "Whether to sleep for a pseudo-random (but consistent) amount of time before
+ a run."],
+ :clientbucketdir => {
+ :default => "$vardir/clientbucket",
+ :mode => 0750,
+ :desc => "Where FileBucket files are stored locally."
+ },
+ :configtimeout => [120,
+ "How long the client should wait for the configuration to be retrieved
+ before considering it a failure. This can help reduce flapping if too
+ many clients contact the server at one time."
+ ],
+ :reportserver => {
+ :default => "$server",
+ :call_on_define => false,
+ :desc => "(Deprecated for 'report_server') The server to which to send transaction reports.",
+ :hook => proc do |value|
+ Puppet.settings[:report_server] = value if value
+ end
+ },
+ :report_server => ["$server",
+ "The server to which to send transaction reports."
+ ],
+ :report_port => ["$masterport",
+ "The port to communicate with the report_server."
+ ],
+ :report => [false,
+ "Whether to send reports after every transaction."
+ ],
+ :graph => [false, "Whether to create dot graph files for the different
+ configuration graphs. These dot files can be interpreted by tools
+ like OmniGraffle or dot (which is part of ImageMagick)."],
+ :graphdir => ["$statedir/graphs", "Where to store dot-outputted graphs."],
+ :http_compression => [false, "Allow http compression in REST communication with the master.
+ This setting might improve performance for agent -> master communications over slow WANs.
+ Your puppetmaster needs to support compression (usually by activating some settings in a reverse-proxy
+ in front of the puppetmaster, which rules out webrick).
+ It is harmless to activate this settings if your master doesn't support
+ compression, but if it supports it, this setting might reduce performance on high-speed LANs."]
+ )
+
+ # Plugin information.
+
+ setdefaults(
+ :main,
+ :plugindest => ["$libdir",
+ "Where Puppet should store plugins that it pulls down from the central
+ server."],
+ :pluginsource => ["puppet://$server/plugins",
+ "From where to retrieve plugins. The standard Puppet ``file`` type
+ is used for retrieval, so anything that is a valid file source can
+ be used here."],
+ :pluginsync => [false, "Whether plugins should be synced with the central server."],
+
+ :pluginsignore => [".svn CVS .git", "What files to ignore when pulling down plugins."]
+ )
+
+ # Central fact information.
+
+ setdefaults(
+ :main,
+ :factpath => {:default => "$vardir/lib/facter/${File::PATH_SEPARATOR}$vardir/facts",
+ :desc => "Where Puppet should look for facts. Multiple directories should
+ be colon-separated, like normal PATH variables.",
+
+ :call_on_define => true, # Call our hook with the default value, so we always get the value added to facter.
+ :type => :setting, # Don't consider it a file, because it could be multiple colon-separated files
+ :hook => proc { |value| Facter.search(value) if Facter.respond_to?(:search) }},
+ :factdest => ["$vardir/facts/",
+ "Where Puppet should store facts that it pulls down from the central
+ server."],
+ :factsource => ["puppet://$server/facts/",
+ "From where to retrieve facts. The standard Puppet ``file`` type
+ is used for retrieval, so anything that is a valid file source can
+ be used here."],
+ :factsync => [false, "Whether facts should be synced with the central server."],
+ :factsignore => [".svn CVS", "What files to ignore when pulling down facts."],
+ :reportdir => {:default => "$vardir/reports",
+ :mode => 0750,
+ :owner => "service",
+ :group => "service",
+ :desc => "The directory in which to store reports
+ received from the client. Each client gets a separate
+ subdirectory."},
+ :reporturl => ["http://localhost:3000/reports",
+ "The URL used by the http reports processor to send reports"]
+ )
+
+
+ setdefaults(
+ :tagmail,
+ :tagmap => ["$confdir/tagmail.conf", "The mapping between reporting tags and email addresses."],
+ :sendmail => [%x{which sendmail 2>/dev/null}.chomp, "Where to find the sendmail binary with which to send email."],
+
+ :reportfrom => ["report@" + [Facter["hostname"].value, Facter["domain"].value].join("."), "The 'from' email address for the reports."],
+ :smtpserver => ["none", "The server through which to send email reports."]
+ )
+
+
+ setdefaults(
+ :rails,
+ :dblocation => { :default => "$statedir/clientconfigs.sqlite3",
+ :mode => 0660,
+ :owner => "service",
+ :group => "service",
+ :desc => "The database cache for client configurations. Used for
+ querying within the language."
+ },
+ :dbadapter => [ "sqlite3", "The type of database to use." ],
+ :dbmigrate => [ false, "Whether to automatically migrate the database." ],
+ :dbname => [ "puppet", "The name of the database to use." ],
+ :dbserver => [ "localhost", "The database server for caching. Only
+ used when networked databases are used."],
+ :dbport => [ "", "The database password for caching. Only
+ used when networked databases are used."],
+ :dbuser => [ "puppet", "The database user for caching. Only
+ used when networked databases are used."],
+ :dbpassword => [ "puppet", "The database password for caching. Only
+ used when networked databases are used."],
+ :dbsocket => [ "", "The database socket location. Only used when networked
+ databases are used. Will be ignored if the value is an empty string."],
+ :dbconnections => [ 0, "The number of database connections. Only used when
+ networked databases are used. Will be ignored if the value is an empty
+ string or is less than 1."],
+ :railslog => {:default => "$logdir/rails.log",
+ :mode => 0600,
+ :owner => "service",
+ :group => "service",
+ :desc => "Where Rails-specific logs are sent"
+ },
+
+ :rails_loglevel => ["info", "The log level for Rails connections. The value must be
+ a valid log level within Rails. Production environments normally use ``info``
+ and other environments normally use ``debug``."]
+ )
+
+
+ setdefaults(
+ :couchdb,
+
+ :couchdb_url => ["http://127.0.0.1:5984/puppet", "The url where the puppet couchdb database will be created"]
+ )
+
+
+ setdefaults(
+ :transaction,
+ :tags => ["", "Tags to use to find resources. If this is set, then
+ only resources tagged with the specified tags will be applied.
+ Values must be comma-separated."],
+ :evaltrace => [false, "Whether each resource should log when it is
+ being evaluated. This allows you to interactively see exactly
+ what is being done."],
+ :summarize => [false,
+
+ "Whether to print a transaction summary."
+ ]
+ )
+
+
+ setdefaults(
+ :main,
+ :external_nodes => ["none",
+
+ "An external command that can produce node information. The output
+ must be a YAML dump of a hash, and that hash must have one or both of
+ ``classes`` and ``parameters``, where ``classes`` is an array and
+ ``parameters`` is a hash. For unknown nodes, the commands should
+ exit with a non-zero exit code.
+
+ This command makes it straightforward to store your node mapping
+ information in other data sources like databases."])
setdefaults(
- :ca,
- :ca_name => ["$certname", "The name to use the Certificate Authority certificate."],
- :cadir => { :default => "$ssldir/ca",
- :owner => "service",
- :group => "service",
- :mode => 0770,
- :desc => "The root directory for the certificate authority."
- },
- :cacert => { :default => "$cadir/ca_crt.pem",
- :owner => "service",
- :group => "service",
- :mode => 0660,
- :desc => "The CA certificate."
- },
- :cakey => { :default => "$cadir/ca_key.pem",
- :owner => "service",
- :group => "service",
- :mode => 0660,
- :desc => "The CA private key."
- },
- :capub => { :default => "$cadir/ca_pub.pem",
- :owner => "service",
- :group => "service",
- :desc => "The CA public key."
- },
- :cacrl => { :default => "$cadir/ca_crl.pem",
- :owner => "service",
- :group => "service",
- :mode => 0664,
-
- :desc => "The certificate revocation list (CRL) for the CA. Will be used if present but otherwise ignored.",
- :hook => proc do |value|
- if value == 'false'
- Puppet.warning "Setting the :cacrl to 'false' is deprecated; Puppet will just ignore the crl if yours is missing"
- end
- end
- },
- :caprivatedir => { :default => "$cadir/private",
- :owner => "service",
- :group => "service",
- :mode => 0770,
- :desc => "Where the CA stores private certificate information."
- },
- :csrdir => { :default => "$cadir/requests",
- :owner => "service",
- :group => "service",
- :desc => "Where the CA stores certificate requests"
- },
- :signeddir => { :default => "$cadir/signed",
- :owner => "service",
- :group => "service",
- :mode => 0770,
- :desc => "Where the CA stores signed certificates."
- },
- :capass => { :default => "$caprivatedir/ca.pass",
- :owner => "service",
- :group => "service",
- :mode => 0660,
- :desc => "Where the CA stores the password for the private key"
- },
- :serial => { :default => "$cadir/serial",
- :owner => "service",
- :group => "service",
- :mode => 0644,
- :desc => "Where the serial number for certificates is stored."
- },
- :autosign => { :default => "$confdir/autosign.conf",
- :mode => 0644,
- :desc => "Whether to enable autosign. Valid values are true (which
- autosigns any key request, and is a very bad idea), false (which
- never autosigns any key request), and the path to a file, which
- uses that configuration file to determine which keys to sign."},
- :ca_days => ["", "How long a certificate should be valid.
- This parameter is deprecated, use ca_ttl instead"],
- :ca_ttl => ["5y", "The default TTL for new certificates; valid values
- must be an integer, optionally followed by one of the units
- 'y' (years of 365 days), 'd' (days), 'h' (hours), or
- 's' (seconds). The unit defaults to seconds. If this parameter
- is set, ca_days is ignored. Examples are '3600' (one hour)
- and '1825d', which is the same as '5y' (5 years) "],
- :ca_md => ["md5", "The type of hash used in certificates."],
- :req_bits => [2048, "The bit length of the certificates."],
- :keylength => [1024, "The bit length of keys."],
- :cert_inventory => {
- :default => "$cadir/inventory.txt",
- :mode => 0644,
- :owner => "service",
- :group => "service",
- :desc => "A Complete listing of all certificates"
- }
- )
-
- # Define the config default.
-
- setdefaults(
- Puppet.settings[:name],
- :config => ["$confdir/puppet.conf",
- "The configuration file for #{Puppet[:name]}."],
- :pidfile => ["$rundir/$name.pid", "The pid file"],
- :bindaddress => ["", "The address a listening server should bind to. Mongrel servers
- default to 127.0.0.1 and WEBrick defaults to 0.0.0.0."],
- :servertype => {:default => "webrick", :desc => "The type of server to use. Currently supported
- options are webrick and mongrel. If you use mongrel, you will need
- a proxy in front of the process or processes, since Mongrel cannot
- speak SSL.",
-
- :call_on_define => true, # Call our hook with the default value, so we always get the correct bind address set.
- :hook => proc { |value| value == "webrick" ? Puppet.settings[:bindaddress] = "0.0.0.0" : Puppet.settings[:bindaddress] = "127.0.0.1" if Puppet.settings[:bindaddress] == "" }
- }
- )
-
- setdefaults(:master,
- :user => ["puppet", "The user puppet master should run as."],
- :group => ["puppet", "The group puppet master should run as."],
- :manifestdir => ["$confdir/manifests", "Where puppet master looks for its manifests."],
- :manifest => ["$manifestdir/site.pp", "The entry-point manifest for puppet master."],
- :code => ["", "Code to parse directly. This is essentially only used
- by ``puppet``, and should only be set if you're writing your own Puppet
- executable"],
- :masterlog => { :default => "$logdir/puppetmaster.log",
- :owner => "service",
- :group => "service",
- :mode => 0660,
- :desc => "Where puppet master logs. This is generally not used,
- since syslog is the default log destination."
- },
- :masterhttplog => { :default => "$logdir/masterhttp.log",
- :owner => "service",
- :group => "service",
- :mode => 0660,
- :create => true,
- :desc => "Where the puppet master web server logs."
- },
- :masterport => [8140, "Which port puppet master listens on."],
- :parseonly => [false, "Just check the syntax of the manifests."],
- :node_name => ["cert", "How the puppetmaster determines the client's identity
- and sets the 'hostname', 'fqdn' and 'domain' facts for use in the manifest,
- in particular for determining which 'node' statement applies to the client.
- Possible values are 'cert' (use the subject's CN in the client's
- certificate) and 'facter' (use the hostname that the client
- reported in its facts)"],
- :bucketdir => {
- :default => "$vardir/bucket",
- :mode => 0750,
- :owner => "service",
- :group => "service",
- :desc => "Where FileBucket files are stored."
- },
- :rest_authconfig => [ "$confdir/auth.conf",
- "The configuration file that defines the rights to the different
- rest indirections. This can be used as a fine-grained
- authorization system for ``puppet master``."
- ],
- :ca => [true, "Wether the master should function as a certificate authority."],
- :modulepath => {:default => "$confdir/modules:/usr/share/puppet/modules",
- :desc => "The search path for modules as a colon-separated list of
- directories.", :type => :setting }, # We don't want this to be considered a file, since it's multiple files.
- :ssl_client_header => ["HTTP_X_CLIENT_DN", "The header containing an authenticated
- client's SSL DN. Only used with Mongrel. This header must be set by the proxy
- to the authenticated client's SSL DN (e.g., ``/CN=puppet.puppetlabs.com``).
- See http://projects.puppetlabs.com/projects/puppet/wiki/Using_Mongrel for more information."],
- :ssl_client_verify_header => ["HTTP_X_CLIENT_VERIFY", "The header containing the status
- message of the client verification. Only used with Mongrel. This header must be set by the proxy
- to 'SUCCESS' if the client successfully authenticated, and anything else otherwise.
- See http://projects.puppetlabs.com/projects/puppet/wiki/Using_Mongrel for more information."],
- # To make sure this directory is created before we try to use it on the server, we need
- # it to be in the server section (#1138).
- :yamldir => {:default => "$vardir/yaml", :owner => "service", :group => "service", :mode => "750",
- :desc => "The directory in which YAML data is stored, usually in a subdirectory."},
- :server_datadir => {:default => "$vardir/server_data", :owner => "service", :group => "service", :mode => "750",
- :desc => "The directory in which serialized data is stored, usually in a subdirectory."},
- :reports => ["store",
- "The list of reports to generate. All reports are looked for
- in puppet/reports/name.rb, and multiple report names should be
- comma-separated (whitespace is okay)."
- ],
- :fileserverconfig => ["$confdir/fileserver.conf", "Where the fileserver configuration is stored."],
- :rrddir => {:default => "$vardir/rrd",
- :owner => "service",
- :group => "service",
- :desc => "The directory where RRD database files are stored.
- Directories for each reporting host will be created under
- this directory."
- },
- :rrdinterval => ["$runinterval", "How often RRD should expect data.
- This should match how often the hosts report back to the server."],
- :strict_hostname_checking => [false, "Whether to only search for the complete
- hostname as it is in the certificate when searching for node information
- in the catalogs."]
- )
-
- setdefaults(:agent,
- :localconfig => { :default => "$statedir/localconfig",
- :owner => "root",
- :mode => 0660,
- :desc => "Where puppet agent caches the local configuration. An
- extension indicating the cache format is added automatically."},
- :statefile => { :default => "$statedir/state.yaml",
- :mode => 0660,
- :desc => "Where puppet agent and puppet master store state associated
- with the running configuration. In the case of puppet master,
- this file reflects the state discovered through interacting
- with clients."
- },
- :clientyamldir => {:default => "$vardir/client_yaml", :mode => "750", :desc => "The directory in which client-side YAML data is stored."},
- :client_datadir => {:default => "$vardir/client_data", :mode => "750", :desc => "The directory in which serialized data is stored on the client."},
- :classfile => { :default => "$statedir/classes.txt",
- :owner => "root",
- :mode => 0644,
- :desc => "The file in which puppet agent stores a list of the classes
- associated with the retrieved configuration. Can be loaded in
- the separate ``puppet`` executable using the ``--loadclasses``
- option."},
- :puppetdlog => { :default => "$logdir/puppetd.log",
- :owner => "root",
- :mode => 0640,
- :desc => "The log file for puppet agent. This is generally not used."
- },
- :server => ["puppet", "The server to which server puppet agent should connect"],
- :ignoreschedules => [false,
- "Boolean; whether puppet agent should ignore schedules. This is useful
- for initial puppet agent runs."],
- :puppetport => [8139, "Which port puppet agent listens on."],
- :noop => [false, "Whether puppet agent should be run in noop mode."],
- :runinterval => [1800, # 30 minutes
- "How often puppet agent applies the client configuration; in seconds."],
- :listen => [false, "Whether puppet agent should listen for
- connections. If this is true, then by default only the
- ``runner`` server is started, which allows remote authorized
- and authenticated nodes to connect and trigger ``puppet agent``
- runs."],
- :ca_server => ["$server", "The server to use for certificate
- authority requests. It's a separate server because it cannot
- and does not need to horizontally scale."],
- :ca_port => ["$masterport", "The port to use for the certificate authority."],
- :catalog_format => {
- :default => "",
- :desc => "(Deprecated for 'preferred_serialization_format') What format to
- use to dump the catalog. Only supports 'marshal' and 'yaml'. Only
- matters on the client, since it asks the server for a specific format.",
- :hook => proc { |value|
- if value
- Puppet.warning "Setting 'catalog_format' is deprecated; use 'preferred_serialization_format' instead."
- Puppet.settings[:preferred_serialization_format] = value
- end
- }
- },
- :preferred_serialization_format => ["pson", "The preferred means of serializing
- ruby instances for passing over the wire. This won't guarantee that all
- instances will be serialized using this method, since not all classes
- can be guaranteed to support this format, but it will be used for all
- classes that support it."],
- :puppetdlockfile => [ "$statedir/puppetdlock", "A lock file to temporarily stop puppet agent from doing anything."],
- :usecacheonfailure => [true,
- "Whether to use the cached configuration when the remote
- configuration will not compile. This option is useful for testing
- new configurations, where you want to fix the broken configuration
- rather than reverting to a known-good one."
- ],
- :use_cached_catalog => [false,
- "Whether to only use the cached catalog rather than compiling a new catalog
- on every run. Puppet can be run with this enabled by default and then selectively
- disabled when a recompile is desired."],
- :ignorecache => [false,
- "Ignore cache and always recompile the configuration. This is
- useful for testing new configurations, where the local cache may in
- fact be stale even if the timestamps are up to date - if the facts
- change or if the server changes."
- ],
- :downcasefacts => [false, "Whether facts should be made all lowercase when sent to the server."],
- :dynamicfacts => ["memorysize,memoryfree,swapsize,swapfree",
- "Facts that are dynamic; these facts will be ignored when deciding whether
- changed facts should result in a recompile. Multiple facts should be
- comma-separated."],
- :splaylimit => ["$runinterval",
- "The maximum time to delay before runs. Defaults to being the same as the
- run interval."],
- :splay => [false,
- "Whether to sleep for a pseudo-random (but consistent) amount of time before
- a run."],
- :clientbucketdir => {
- :default => "$vardir/clientbucket",
- :mode => 0750,
- :desc => "Where FileBucket files are stored locally."
- },
- :configtimeout => [120,
- "How long the client should wait for the configuration to be retrieved
- before considering it a failure. This can help reduce flapping if too
- many clients contact the server at one time."
- ],
- :reportserver => {
- :default => "$server",
- :call_on_define => false,
- :desc => "(Deprecated for 'report_server') The server to which to send transaction reports.",
- :hook => proc do |value|
- Puppet.settings[:report_server] = value if value
- end
- },
- :report_server => ["$server",
- "The server to which to send transaction reports."
- ],
- :report_port => ["$masterport",
- "The port to communicate with the report_server."
- ],
- :report => [false,
- "Whether to send reports after every transaction."
- ],
- :graph => [false, "Whether to create dot graph files for the different
- configuration graphs. These dot files can be interpreted by tools
- like OmniGraffle or dot (which is part of ImageMagick)."],
- :graphdir => ["$statedir/graphs", "Where to store dot-outputted graphs."],
- :http_compression => [false, "Allow http compression in REST communication with the master.
- This setting might improve performance for agent -> master communications over slow WANs.
- Your puppetmaster needs to support compression (usually by activating some settings in a reverse-proxy
- in front of the puppetmaster, which rules out webrick).
- It is harmless to activate this settings if your master doesn't support
- compression, but if it supports it, this setting might reduce performance on high-speed LANs."]
- )
-
- # Plugin information.
-
- setdefaults(
- :main,
- :plugindest => ["$libdir",
- "Where Puppet should store plugins that it pulls down from the central
- server."],
- :pluginsource => ["puppet://$server/plugins",
- "From where to retrieve plugins. The standard Puppet ``file`` type
- is used for retrieval, so anything that is a valid file source can
- be used here."],
- :pluginsync => [false, "Whether plugins should be synced with the central server."],
-
- :pluginsignore => [".svn CVS .git", "What files to ignore when pulling down plugins."]
- )
-
- # Central fact information.
-
- setdefaults(
- :main,
- :factpath => {:default => "$vardir/lib/facter/${File::PATH_SEPARATOR}$vardir/facts",
- :desc => "Where Puppet should look for facts. Multiple directories should
- be colon-separated, like normal PATH variables.",
-
- :call_on_define => true, # Call our hook with the default value, so we always get the value added to facter.
- :type => :setting, # Don't consider it a file, because it could be multiple colon-separated files
- :hook => proc { |value| Facter.search(value) if Facter.respond_to?(:search) }},
- :factdest => ["$vardir/facts/",
- "Where Puppet should store facts that it pulls down from the central
- server."],
- :factsource => ["puppet://$server/facts/",
- "From where to retrieve facts. The standard Puppet ``file`` type
- is used for retrieval, so anything that is a valid file source can
- be used here."],
- :factsync => [false, "Whether facts should be synced with the central server."],
- :factsignore => [".svn CVS", "What files to ignore when pulling down facts."],
- :reportdir => {:default => "$vardir/reports",
- :mode => 0750,
- :owner => "service",
- :group => "service",
- :desc => "The directory in which to store reports
- received from the client. Each client gets a separate
- subdirectory."},
- :reporturl => ["http://localhost:3000/reports",
- "The URL used by the http reports processor to send reports"]
- )
-
-
- setdefaults(
- :tagmail,
- :tagmap => ["$confdir/tagmail.conf", "The mapping between reporting tags and email addresses."],
- :sendmail => [%x{which sendmail 2>/dev/null}.chomp, "Where to find the sendmail binary with which to send email."],
-
- :reportfrom => ["report@" + [Facter["hostname"].value, Facter["domain"].value].join("."), "The 'from' email address for the reports."],
- :smtpserver => ["none", "The server through which to send email reports."]
- )
-
-
- setdefaults(
- :rails,
- :dblocation => { :default => "$statedir/clientconfigs.sqlite3",
- :mode => 0660,
- :owner => "service",
- :group => "service",
- :desc => "The database cache for client configurations. Used for
- querying within the language."
- },
- :dbadapter => [ "sqlite3", "The type of database to use." ],
- :dbmigrate => [ false, "Whether to automatically migrate the database." ],
- :dbname => [ "puppet", "The name of the database to use." ],
- :dbserver => [ "localhost", "The database server for caching. Only
- used when networked databases are used."],
- :dbport => [ "", "The database password for caching. Only
- used when networked databases are used."],
- :dbuser => [ "puppet", "The database user for caching. Only
- used when networked databases are used."],
- :dbpassword => [ "puppet", "The database password for caching. Only
- used when networked databases are used."],
- :dbsocket => [ "", "The database socket location. Only used when networked
- databases are used. Will be ignored if the value is an empty string."],
- :dbconnections => [ 0, "The number of database connections. Only used when
- networked databases are used. Will be ignored if the value is an empty
- string or is less than 1."],
- :railslog => {:default => "$logdir/rails.log",
- :mode => 0600,
- :owner => "service",
- :group => "service",
- :desc => "Where Rails-specific logs are sent"
- },
-
- :rails_loglevel => ["info", "The log level for Rails connections. The value must be
- a valid log level within Rails. Production environments normally use ``info``
- and other environments normally use ``debug``."]
- )
-
-
- setdefaults(
- :couchdb,
-
- :couchdb_url => ["http://127.0.0.1:5984/puppet", "The url where the puppet couchdb database will be created"]
- )
-
-
- setdefaults(
- :transaction,
- :tags => ["", "Tags to use to find resources. If this is set, then
- only resources tagged with the specified tags will be applied.
- Values must be comma-separated."],
- :evaltrace => [false, "Whether each resource should log when it is
- being evaluated. This allows you to interactively see exactly
- what is being done."],
- :summarize => [false,
-
- "Whether to print a transaction summary."
- ]
- )
-
-
- setdefaults(
- :main,
- :external_nodes => ["none",
-
- "An external command that can produce node information. The output
- must be a YAML dump of a hash, and that hash must have one or both of
- ``classes`` and ``parameters``, where ``classes`` is an array and
- ``parameters`` is a hash. For unknown nodes, the commands should
- exit with a non-zero exit code.
-
- This command makes it straightforward to store your node mapping
- information in other data sources like databases."])
-
-
- setdefaults(
- :ldap,
- :ldapnodes => [false,
- "Whether to search for node configurations in LDAP. See
- http://projects.puppetlabs.com/projects/puppet/wiki/LDAP_Nodes for more information."],
- :ldapssl => [false,
- "Whether SSL should be used when searching for nodes.
- Defaults to false because SSL usually requires certificates
- to be set up on the client side."],
- :ldaptls => [false,
- "Whether TLS should be used when searching for nodes.
- Defaults to false because TLS usually requires certificates
- to be set up on the client side."],
- :ldapserver => ["ldap",
- "The LDAP server. Only used if ``ldapnodes`` is enabled."],
- :ldapport => [389,
- "The LDAP port. Only used if ``ldapnodes`` is enabled."],
-
- :ldapstring => ["(&(objectclass=puppetClient)(cn=%s))",
- "The search string used to find an LDAP node."],
- :ldapclassattrs => ["puppetclass",
- "The LDAP attributes to use to define Puppet classes. Values
- should be comma-separated."],
- :ldapstackedattrs => ["puppetvar",
- "The LDAP attributes that should be stacked to arrays by adding
- the values in all hierarchy elements of the tree. Values
- should be comma-separated."],
- :ldapattrs => ["all",
- "The LDAP attributes to include when querying LDAP for nodes. All
- returned attributes are set as variables in the top-level scope.
- Multiple values should be comma-separated. The value 'all' returns
- all attributes."],
- :ldapparentattr => ["parentnode",
- "The attribute to use to define the parent node."],
- :ldapuser => ["",
- "The user to use to connect to LDAP. Must be specified as a
- full DN."],
- :ldappassword => ["", "The password to use to connect to LDAP."],
- :ldapbase => ["",
- "The search base for LDAP searches. It's impossible to provide
- a meaningful default here, although the LDAP libraries might
- have one already set. Generally, it should be the 'ou=Hosts'
- branch under your main directory."]
- )
-
- setdefaults(:master,
- :storeconfigs => {:default => false, :desc => "Whether to store each client's configuration. This
- requires ActiveRecord from Ruby on Rails.",
- :call_on_define => true, # Call our hook with the default value, so we always get the libdir set.
- :hook => proc do |value|
- require 'puppet/node'
- require 'puppet/node/facts'
- if value
- require 'puppet/rails'
- raise "StoreConfigs not supported without ActiveRecord 2.1 or higher" unless Puppet.features.rails?
- Puppet::Resource::Catalog.cache_class = :active_record unless Puppet.settings[:async_storeconfigs]
- Puppet::Node::Facts.cache_class = :active_record
- Puppet::Node.cache_class = :active_record
- end
- end
- }
- )
-
- # This doesn't actually work right now.
-
- setdefaults(
- :parser,
-
- :lexical => [false, "Whether to use lexical scoping (vs. dynamic)."],
- :templatedir => ["$vardir/templates",
- "Where Puppet looks for template files. Can be a list of colon-seperated
- directories."
- ]
- )
+ :ldap,
+ :ldapnodes => [false,
+ "Whether to search for node configurations in LDAP. See
+ http://projects.puppetlabs.com/projects/puppet/wiki/LDAP_Nodes for more information."],
+ :ldapssl => [false,
+ "Whether SSL should be used when searching for nodes.
+ Defaults to false because SSL usually requires certificates
+ to be set up on the client side."],
+ :ldaptls => [false,
+ "Whether TLS should be used when searching for nodes.
+ Defaults to false because TLS usually requires certificates
+ to be set up on the client side."],
+ :ldapserver => ["ldap",
+ "The LDAP server. Only used if ``ldapnodes`` is enabled."],
+ :ldapport => [389,
+ "The LDAP port. Only used if ``ldapnodes`` is enabled."],
+
+ :ldapstring => ["(&(objectclass=puppetClient)(cn=%s))",
+ "The search string used to find an LDAP node."],
+ :ldapclassattrs => ["puppetclass",
+ "The LDAP attributes to use to define Puppet classes. Values
+ should be comma-separated."],
+ :ldapstackedattrs => ["puppetvar",
+ "The LDAP attributes that should be stacked to arrays by adding
+ the values in all hierarchy elements of the tree. Values
+ should be comma-separated."],
+ :ldapattrs => ["all",
+ "The LDAP attributes to include when querying LDAP for nodes. All
+ returned attributes are set as variables in the top-level scope.
+ Multiple values should be comma-separated. The value 'all' returns
+ all attributes."],
+ :ldapparentattr => ["parentnode",
+ "The attribute to use to define the parent node."],
+ :ldapuser => ["",
+ "The user to use to connect to LDAP. Must be specified as a
+ full DN."],
+ :ldappassword => ["", "The password to use to connect to LDAP."],
+ :ldapbase => ["",
+ "The search base for LDAP searches. It's impossible to provide
+ a meaningful default here, although the LDAP libraries might
+ have one already set. Generally, it should be the 'ou=Hosts'
+ branch under your main directory."]
+ )
+
+ setdefaults(:master,
+ :storeconfigs => {:default => false, :desc => "Whether to store each client's configuration. This
+ requires ActiveRecord from Ruby on Rails.",
+ :call_on_define => true, # Call our hook with the default value, so we always get the libdir set.
+ :hook => proc do |value|
+ require 'puppet/node'
+ require 'puppet/node/facts'
+ if value
+ require 'puppet/rails'
+ raise "StoreConfigs not supported without ActiveRecord 2.1 or higher" unless Puppet.features.rails?
+ Puppet::Resource::Catalog.cache_class = :active_record unless Puppet.settings[:async_storeconfigs]
+ Puppet::Node::Facts.cache_class = :active_record
+ Puppet::Node.cache_class = :active_record
+ end
+ end
+ }
+ )
+
+ # This doesn't actually work right now.
+
+ setdefaults(
+ :parser,
+
+ :lexical => [false, "Whether to use lexical scoping (vs. dynamic)."],
+ :templatedir => ["$vardir/templates",
+ "Where Puppet looks for template files. Can be a list of colon-seperated
+ directories."
+ ]
+ )
end
diff --git a/lib/puppet/dsl.rb b/lib/puppet/dsl.rb
index 28f4a7e..abdb78f 100644
--- a/lib/puppet/dsl.rb
+++ b/lib/puppet/dsl.rb
@@ -7,5 +7,5 @@ require 'puppet/dsl/resource_type_api'
require 'puppet/dsl/resource_api'
class Object
- include Puppet::DSL::ResourceTypeAPI
+ include Puppet::DSL::ResourceTypeAPI
end
diff --git a/lib/puppet/dsl/resource_api.rb b/lib/puppet/dsl/resource_api.rb
index 3e56a55..9aa1ea0 100644
--- a/lib/puppet/dsl/resource_api.rb
+++ b/lib/puppet/dsl/resource_api.rb
@@ -4,117 +4,117 @@
require 'puppet/resource/type_collection_helper'
class Puppet::DSL::ResourceAPI
- include Puppet::Resource::TypeCollectionHelper
+ include Puppet::Resource::TypeCollectionHelper
- FUNCTION_MAP = {:acquire => :include}
+ FUNCTION_MAP = {:acquire => :include}
- attr_reader :scope, :resource, :block
+ attr_reader :scope, :resource, :block
- def environment
- scope.environment
- end
+ def environment
+ scope.environment
+ end
- def evaluate
- set_instance_variables
- instance_eval(&block)
- end
+ def evaluate
+ set_instance_variables
+ instance_eval(&block)
+ end
- def initialize(resource, scope, block)
- @scope = scope
- @resource = resource
- @block = block
- end
+ def initialize(resource, scope, block)
+ @scope = scope
+ @resource = resource
+ @block = block
+ end
- # Try to convert a missing method into a resource type or a function.
- def method_missing(name, *args)
- raise "MethodMissing loop when searching for #{name} with #{args.inspect}" if searching_for_method?
- @searching_for_method = true
- return create_resource(name, args[0], args[1]) if valid_type?(name)
+ # Try to convert a missing method into a resource type or a function.
+ def method_missing(name, *args)
+ raise "MethodMissing loop when searching for #{name} with #{args.inspect}" if searching_for_method?
+ @searching_for_method = true
+ return create_resource(name, args[0], args[1]) if valid_type?(name)
- name = map_function(name)
+ name = map_function(name)
- return call_function(name, args) if Puppet::Parser::Functions.function(name)
+ return call_function(name, args) if Puppet::Parser::Functions.function(name)
- super
- ensure
- @searching_for_method = true
- end
+ super
+ ensure
+ @searching_for_method = true
+ end
- def set_instance_variables
- resource.eachparam do |param|
- instance_variable_set("@#{param.name}", param.value)
- end
- @title = resource.title
- @name ||= resource.title
+ def set_instance_variables
+ resource.eachparam do |param|
+ instance_variable_set("@#{param.name}", param.value)
end
-
- def create_resource(type, names, arguments = nil)
- names = [names] unless names.is_a?(Array)
-
- arguments ||= {}
- raise ArgumentError, "Resource arguments must be provided as a hash" unless arguments.is_a?(Hash)
-
- names.collect do |name|
- resource = Puppet::Parser::Resource.new(type, name, :scope => scope)
- arguments.each do |param, value|
- resource[param] = value
- end
-
- resource.exported = true if exporting?
- resource.virtual = true if virtualizing?
- scope.compiler.add_resource(scope, resource)
- resource
- end
+ @title = resource.title
+ @name ||= resource.title
+ end
+
+ def create_resource(type, names, arguments = nil)
+ names = [names] unless names.is_a?(Array)
+
+ arguments ||= {}
+ raise ArgumentError, "Resource arguments must be provided as a hash" unless arguments.is_a?(Hash)
+
+ names.collect do |name|
+ resource = Puppet::Parser::Resource.new(type, name, :scope => scope)
+ arguments.each do |param, value|
+ resource[param] = value
+ end
+
+ resource.exported = true if exporting?
+ resource.virtual = true if virtualizing?
+ scope.compiler.add_resource(scope, resource)
+ resource
end
+ end
- def call_function(name, args)
- return false unless method = Puppet::Parser::Functions.function(name)
- scope.send(method, *args)
- end
-
- def export(resources = nil, &block)
- if resources
- resources.each { |resource| resource.exported = true }
- return resources
- end
- @exporting = true
- instance_eval(&block)
- ensure
- @exporting = false
- end
+ def call_function(name, args)
+ return false unless method = Puppet::Parser::Functions.function(name)
+ scope.send(method, *args)
+ end
- def virtual(resources = nil, &block)
- if resources
- resources.each { |resource| resource.virtual = true }
- return resources
- end
- @virtualizing = true
- instance_eval(&block)
- ensure
- @virtualizing = false
+ def export(resources = nil, &block)
+ if resources
+ resources.each { |resource| resource.exported = true }
+ return resources
end
-
- def valid_type?(name)
- return true if [:class, :node].include?(name)
- return true if Puppet::Type.type(name)
- return(known_resource_types.definition(name) ? true : false)
- end
-
- private
-
- def exporting?
- @exporting
- end
-
- def map_function(name)
- FUNCTION_MAP[name] || name
- end
-
- def searching_for_method?
- @searching_for_method
- end
-
- def virtualizing?
- @virtualizing
+ @exporting = true
+ instance_eval(&block)
+ ensure
+ @exporting = false
+ end
+
+ def virtual(resources = nil, &block)
+ if resources
+ resources.each { |resource| resource.virtual = true }
+ return resources
end
+ @virtualizing = true
+ instance_eval(&block)
+ ensure
+ @virtualizing = false
+ end
+
+ def valid_type?(name)
+ return true if [:class, :node].include?(name)
+ return true if Puppet::Type.type(name)
+ return(known_resource_types.definition(name) ? true : false)
+ end
+
+ private
+
+ def exporting?
+ @exporting
+ end
+
+ def map_function(name)
+ FUNCTION_MAP[name] || name
+ end
+
+ def searching_for_method?
+ @searching_for_method
+ end
+
+ def virtualizing?
+ @virtualizing
+ end
end
diff --git a/lib/puppet/dsl/resource_type_api.rb b/lib/puppet/dsl/resource_type_api.rb
index ba48968..487aab9 100644
--- a/lib/puppet/dsl/resource_type_api.rb
+++ b/lib/puppet/dsl/resource_type_api.rb
@@ -1,40 +1,40 @@
require 'puppet/resource/type'
module Puppet::DSL::ResourceTypeAPI
- def define(name, *args, &block)
- result = mk_resource_type(:definition, name, Hash.new, block)
- result.set_arguments(munge_type_arguments(args))
- result
- end
+ def define(name, *args, &block)
+ result = mk_resource_type(:definition, name, Hash.new, block)
+ result.set_arguments(munge_type_arguments(args))
+ result
+ end
- def hostclass(name, options = {}, &block)
- mk_resource_type(:hostclass, name, options, block)
- end
+ def hostclass(name, options = {}, &block)
+ mk_resource_type(:hostclass, name, options, block)
+ end
- def node(name, options = {}, &block)
- mk_resource_type(:node, name, options, block)
- end
+ def node(name, options = {}, &block)
+ mk_resource_type(:node, name, options, block)
+ end
- private
+ private
- def mk_resource_type(type, name, options, code)
- klass = Puppet::Resource::Type.new(type, name, options)
+ def mk_resource_type(type, name, options, code)
+ klass = Puppet::Resource::Type.new(type, name, options)
- klass.ruby_code = code if code
+ klass.ruby_code = code if code
- Puppet::Node::Environment.new.known_resource_types.add klass
+ Puppet::Node::Environment.new.known_resource_types.add klass
- klass
- end
+ klass
+ end
- def munge_type_arguments(args)
- args.inject([]) do |result, item|
- if item.is_a?(Hash)
- item.each { |p, v| result << [p, v] }
- else
- result << item
- end
- result
- end
+ def munge_type_arguments(args)
+ args.inject([]) do |result, item|
+ if item.is_a?(Hash)
+ item.each { |p, v| result << [p, v] }
+ else
+ result << item
+ end
+ result
end
+ end
end
diff --git a/lib/puppet/error.rb b/lib/puppet/error.rb
index 7be84d5..d0a0c9c 100644
--- a/lib/puppet/error.rb
+++ b/lib/puppet/error.rb
@@ -1,43 +1,43 @@
module Puppet # :nodoc:
- # The base class for all Puppet errors. We want to make it easy to add
- # line and file information. This probably isn't necessary for all
- # errors, but...
- class Error < RuntimeError
- attr_accessor :line, :file
+ # The base class for all Puppet errors. We want to make it easy to add
+ # line and file information. This probably isn't necessary for all
+ # errors, but...
+ class Error < RuntimeError
+ attr_accessor :line, :file
- def backtrace
- if defined?(@backtrace)
- return @backtrace
- else
- return super
- end
- end
+ def backtrace
+ if defined?(@backtrace)
+ return @backtrace
+ else
+ return super
+ end
+ end
- def initialize(message, line = nil, file = nil)
- @message = message
+ def initialize(message, line = nil, file = nil)
+ @message = message
- @line = line if line
- @file = file if file
- end
+ @line = line if line
+ @file = file if file
+ end
- def to_s
- str = nil
- if self.file and self.line
- str = "#{@message} at #{@file}:#{@line}"
- elsif self.line
- str = "#{@message} at line #{@line}"
- elsif self.file
- str = "#{@message} in #{self.file}"
- else
- str = @message.to_s
- end
+ def to_s
+ str = nil
+ if self.file and self.line
+ str = "#{@message} at #{@file}:#{@line}"
+ elsif self.line
+ str = "#{@message} at line #{@line}"
+ elsif self.file
+ str = "#{@message} in #{self.file}"
+ else
+ str = @message.to_s
+ end
- str
- end
+ str
end
+ end
- # An error class for when I don't know what happened. Automatically
- # prints a stack trace when in debug mode.
- class DevError < Puppet::Error
- end
+ # An error class for when I don't know what happened. Automatically
+ # prints a stack trace when in debug mode.
+ class DevError < Puppet::Error
+ end
end
diff --git a/lib/puppet/external/base64.rb b/lib/puppet/external/base64.rb
index 1005c8f..57359dc 100755
--- a/lib/puppet/external/base64.rb
+++ b/lib/puppet/external/base64.rb
@@ -7,13 +7,13 @@
require 'base64'
unless defined?(Base64)
- class Base64
- def Base64.encode64(*args)
- Object.method(:encode64).call(*args)
- end
+ class Base64
+ def Base64.encode64(*args)
+ Object.method(:encode64).call(*args)
+ end
- def Base64.decode64(*args)
- Object.method(:decode64).call(*args)
- end
+ def Base64.decode64(*args)
+ Object.method(:decode64).call(*args)
end
+ end
end
diff --git a/lib/puppet/external/dot.rb b/lib/puppet/external/dot.rb
index 5d89ddb..c0e770e 100644
--- a/lib/puppet/external/dot.rb
+++ b/lib/puppet/external/dot.rb
@@ -8,319 +8,319 @@
module DOT
- # These glogal vars are used to make nice graph source.
+ # These glogal vars are used to make nice graph source.
+
+ $tab = ' '
+ $tab2 = $tab * 2
+
+ # if we don't like 4 spaces, we can change it any time
+
+ def change_tab (t)
+ $tab = t
+ $tab2 = t * 2
+ end
+
+ # options for node declaration
+
+ NODE_OPTS = [
+ # attributes due to
+ # http://www.graphviz.org/Documentation/dotguide.pdf
+ # March, 26, 2005
+ 'bottomlabel', # auxiliary label for nodes of shape M*
+ 'color', # default: black; node shape color
+ 'comment', # any string (format-dependent)
+ 'distortion', # default: 0.0; node distortion for shape=polygon
+ 'fillcolor', # default: lightgrey/black; node fill color
+ 'fixedsize', # default: false; label text has no affect on node size
+ 'fontcolor', # default: black; type face color
+ 'fontname', # default: Times-Roman; font family
+ 'fontsize', # default: 14; point size of label
+ 'group', # name of nodes group
+ 'height', # default: .5; height in inches
+ 'label', # default: node name; any string
+ 'layer', # default: overlay range; all, id or id:id
+ 'orientation', # dafault: 0.0; node rotation angle
+ 'peripheries', # shape-dependent number of node boundaries
+ 'regular', # default: false; force polygon to be regular
+ 'shape', # default: ellipse; node shape; see Section 2.1 and Appendix E
+ 'shapefile', # external EPSF or SVG custom shape file
+ 'sides', # default: 4; number of sides for shape=polygon
+ 'skew' , # default: 0.0; skewing of node for shape=polygon
+ 'style', # graphics options, e.g. bold, dotted, filled; cf. Section 2.3
+ 'toplabel', # auxiliary label for nodes of shape M*
+ 'URL', # URL associated with node (format-dependent)
+ 'width', # default: .75; width in inches
+ 'z', # default: 0.0; z coordinate for VRML output
+
+ # maintained for backward compatibility or rdot internal
+ 'bgcolor',
+ 'rank'
+ ]
+
+ # options for edge declaration
+
+ EDGE_OPTS = [
+ 'arrowhead', # default: normal; style of arrowhead at head end
+ 'arrowsize', # default: 1.0; scaling factor for arrowheads
+ 'arrowtail', # default: normal; style of arrowhead at tail end
+ 'color', # default: black; edge stroke color
+ 'comment', # any string (format-dependent)
+ 'constraint', # default: true use edge to affect node ranking
+ 'decorate', # if set, draws a line connecting labels with their edges
+ 'dir', # default: forward; forward, back, both, or none
+ 'fontcolor', # default: black type face color
+ 'fontname', # default: Times-Roman; font family
+ 'fontsize', # default: 14; point size of label
+ 'headlabel', # label placed near head of edge
+ 'headport', # n,ne,e,se,s,sw,w,nw
+ 'headURL', # URL attached to head label if output format is ismap
+ 'label', # edge label
+ 'labelangle', # default: -25.0; angle in degrees which head or tail label is rotated off edge
+ 'labeldistance', # default: 1.0; scaling factor for distance of head or tail label from node
+ 'labelfloat', # default: false; lessen constraints on edge label placement
+ 'labelfontcolor', # default: black; type face color for head and tail labels
+ 'labelfontname', # default: Times-Roman; font family for head and tail labels
+ 'labelfontsize', # default: 14 point size for head and tail labels
+ 'layer', # default: overlay range; all, id or id:id
+ 'lhead', # name of cluster to use as head of edge
+ 'ltail', # name of cluster to use as tail of edge
+ 'minlen', # default: 1 minimum rank distance between head and tail
+ 'samehead', # tag for head node; edge heads with the same tag are merged onto the same port
+ 'sametail', # tag for tail node; edge tails with the same tag are merged onto the same port
+ 'style', # graphics options, e.g. bold, dotted, filled; cf. Section 2.3
+ 'taillabel', # label placed near tail of edge
+ 'tailport', # n,ne,e,se,s,sw,w,nw
+ 'tailURL', # URL attached to tail label if output format is ismap
+ 'weight', # default: 1; integer cost of stretching an edge
+
+ # maintained for backward compatibility or rdot internal
+ 'id'
+ ]
+
+ # options for graph declaration
+
+ GRAPH_OPTS = [
+ 'bgcolor',
+ 'center', 'clusterrank', 'color', 'concentrate',
+ 'fontcolor', 'fontname', 'fontsize',
+ 'label', 'layerseq',
+ 'margin', 'mclimit',
+ 'nodesep', 'nslimit',
+ 'ordering', 'orientation',
+ 'page',
+ 'rank', 'rankdir', 'ranksep', 'ratio',
+ 'size'
+ ]
+
+ # a root class for any element in dot notation
+
+ class DOTSimpleElement
+
+ attr_accessor :name
+
+ def initialize (params = {})
+ @label = params['name'] ? params['name'] : ''
+ end
+
+ def to_s
+ @name
+ end
+ end
+
+ # an element that has options ( node, edge, or graph )
- $tab = ' '
- $tab2 = $tab * 2
+ class DOTElement < DOTSimpleElement
- # if we don't like 4 spaces, we can change it any time
+ # attr_reader :parent
+ attr_accessor :name, :options
- def change_tab (t)
- $tab = t
- $tab2 = t * 2
+ def initialize (params = {}, option_list = [])
+ super(params)
+ @name = params['name'] ? params['name'] : nil
+ @parent = params['parent'] ? params['parent'] : nil
+ @options = {}
+ option_list.each{ |i|
+ @options[i] = params[i] if params[i]
+ }
+ @options['label'] ||= @name if @name != 'node'
end
- # options for node declaration
-
- NODE_OPTS = [
- # attributes due to
- # http://www.graphviz.org/Documentation/dotguide.pdf
- # March, 26, 2005
- 'bottomlabel', # auxiliary label for nodes of shape M*
- 'color', # default: black; node shape color
- 'comment', # any string (format-dependent)
- 'distortion', # default: 0.0; node distortion for shape=polygon
- 'fillcolor', # default: lightgrey/black; node fill color
- 'fixedsize', # default: false; label text has no affect on node size
- 'fontcolor', # default: black; type face color
- 'fontname', # default: Times-Roman; font family
- 'fontsize', # default: 14; point size of label
- 'group', # name of nodes group
- 'height', # default: .5; height in inches
- 'label', # default: node name; any string
- 'layer', # default: overlay range; all, id or id:id
- 'orientation', # dafault: 0.0; node rotation angle
- 'peripheries', # shape-dependent number of node boundaries
- 'regular', # default: false; force polygon to be regular
- 'shape', # default: ellipse; node shape; see Section 2.1 and Appendix E
- 'shapefile', # external EPSF or SVG custom shape file
- 'sides', # default: 4; number of sides for shape=polygon
- 'skew' , # default: 0.0; skewing of node for shape=polygon
- 'style', # graphics options, e.g. bold, dotted, filled; cf. Section 2.3
- 'toplabel', # auxiliary label for nodes of shape M*
- 'URL', # URL associated with node (format-dependent)
- 'width', # default: .75; width in inches
- 'z', # default: 0.0; z coordinate for VRML output
-
- # maintained for backward compatibility or rdot internal
- 'bgcolor',
- 'rank'
- ]
-
- # options for edge declaration
-
- EDGE_OPTS = [
- 'arrowhead', # default: normal; style of arrowhead at head end
- 'arrowsize', # default: 1.0; scaling factor for arrowheads
- 'arrowtail', # default: normal; style of arrowhead at tail end
- 'color', # default: black; edge stroke color
- 'comment', # any string (format-dependent)
- 'constraint', # default: true use edge to affect node ranking
- 'decorate', # if set, draws a line connecting labels with their edges
- 'dir', # default: forward; forward, back, both, or none
- 'fontcolor', # default: black type face color
- 'fontname', # default: Times-Roman; font family
- 'fontsize', # default: 14; point size of label
- 'headlabel', # label placed near head of edge
- 'headport', # n,ne,e,se,s,sw,w,nw
- 'headURL', # URL attached to head label if output format is ismap
- 'label', # edge label
- 'labelangle', # default: -25.0; angle in degrees which head or tail label is rotated off edge
- 'labeldistance', # default: 1.0; scaling factor for distance of head or tail label from node
- 'labelfloat', # default: false; lessen constraints on edge label placement
- 'labelfontcolor', # default: black; type face color for head and tail labels
- 'labelfontname', # default: Times-Roman; font family for head and tail labels
- 'labelfontsize', # default: 14 point size for head and tail labels
- 'layer', # default: overlay range; all, id or id:id
- 'lhead', # name of cluster to use as head of edge
- 'ltail', # name of cluster to use as tail of edge
- 'minlen', # default: 1 minimum rank distance between head and tail
- 'samehead', # tag for head node; edge heads with the same tag are merged onto the same port
- 'sametail', # tag for tail node; edge tails with the same tag are merged onto the same port
- 'style', # graphics options, e.g. bold, dotted, filled; cf. Section 2.3
- 'taillabel', # label placed near tail of edge
- 'tailport', # n,ne,e,se,s,sw,w,nw
- 'tailURL', # URL attached to tail label if output format is ismap
- 'weight', # default: 1; integer cost of stretching an edge
-
- # maintained for backward compatibility or rdot internal
- 'id'
- ]
-
- # options for graph declaration
-
- GRAPH_OPTS = [
- 'bgcolor',
- 'center', 'clusterrank', 'color', 'concentrate',
- 'fontcolor', 'fontname', 'fontsize',
- 'label', 'layerseq',
- 'margin', 'mclimit',
- 'nodesep', 'nslimit',
- 'ordering', 'orientation',
- 'page',
- 'rank', 'rankdir', 'ranksep', 'ratio',
- 'size'
- ]
-
- # a root class for any element in dot notation
-
- class DOTSimpleElement
-
- attr_accessor :name
-
- def initialize (params = {})
- @label = params['name'] ? params['name'] : ''
- end
-
- def to_s
- @name
- end
+ def each_option
+ @options.each{ |i| yield i }
end
- # an element that has options ( node, edge, or graph )
+ def each_option_pair
+ @options.each_pair{ |key, val| yield key, val }
+ end
- class DOTElement < DOTSimpleElement
+ #def parent=( thing )
+ # @parent.delete( self ) if defined?( @parent ) and @parent
+ # @parent = thing
+ #end
- # attr_reader :parent
- attr_accessor :name, :options
+ end
- def initialize (params = {}, option_list = [])
- super(params)
- @name = params['name'] ? params['name'] : nil
- @parent = params['parent'] ? params['parent'] : nil
- @options = {}
- option_list.each{ |i|
- @options[i] = params[i] if params[i]
- }
- @options['label'] ||= @name if @name != 'node'
- end
- def each_option
- @options.each{ |i| yield i }
- end
+ # This is used when we build nodes that have shape=record
+ # ports don't have options :)
- def each_option_pair
- @options.each_pair{ |key, val| yield key, val }
- end
+ class DOTPort < DOTSimpleElement
- #def parent=( thing )
- # @parent.delete( self ) if defined?( @parent ) and @parent
- # @parent = thing
- #end
+ attr_accessor :label
+ def initialize (params = {})
+ super(params)
+ @name = params['label'] ? params['label'] : ''
end
+ def to_s
+ ( @name && @name != "" ? "<#{@name}>" : "" ) + "#{@label}"
+ end
+ end
- # This is used when we build nodes that have shape=record
- # ports don't have options :)
+ # node element
- class DOTPort < DOTSimpleElement
+ class DOTNode < DOTElement
- attr_accessor :label
+ @ports
- def initialize (params = {})
- super(params)
- @name = params['label'] ? params['label'] : ''
- end
+ def initialize (params = {}, option_list = NODE_OPTS)
+ super(params, option_list)
+ @ports = params['ports'] ? params['ports'] : []
+ end
- def to_s
- ( @name && @name != "" ? "<#{@name}>" : "" ) + "#{@label}"
- end
+ def each_port
+ @ports.each { |i| yield i }
end
- # node element
+ def << (thing)
+ @ports << thing
+ end
- class DOTNode < DOTElement
+ def push (thing)
+ @ports.push(thing)
+ end
- @ports
+ def pop
+ @ports.pop
+ end
- def initialize (params = {}, option_list = NODE_OPTS)
- super(params, option_list)
- @ports = params['ports'] ? params['ports'] : []
- end
+ def to_s (t = '')
+
+ # This code is totally incomprehensible; it needs to be replaced!
+
+ label = @options['shape'] != 'record' && @ports.length == 0 ?
+ @options['label'] ?
+ t + $tab + "label = \"#{@options['label']}\"\n" :
+ '' :
+ t + $tab + 'label = "' + " \\\n" +
+ t + $tab2 + "#{@options['label']}| \\\n" +
+ @ports.collect{ |i|
+ t + $tab2 + i.to_s
+ }.join( "| \\\n" ) + " \\\n" +
+ t + $tab + '"' + "\n"
+
+ t + "#{@name} [\n" +
+ @options.to_a.collect{ |i|
+ i[1] && i[0] != 'label' ?
+ t + $tab + "#{i[0]} = #{i[1]}" : nil
+ }.compact.join( ",\n" ) + ( label != '' ? ",\n" : "\n" ) +
+ label +
+ t + "]\n"
+ end
- def each_port
- @ports.each { |i| yield i }
- end
+ end
- def << (thing)
- @ports << thing
- end
+ # A subgraph element is the same to graph, but has another header in dot
+ # notation.
- def push (thing)
- @ports.push(thing)
- end
+ class DOTSubgraph < DOTElement
- def pop
- @ports.pop
- end
+ @nodes
+ @dot_string
- def to_s (t = '')
+ def initialize (params = {}, option_list = GRAPH_OPTS)
+ super(params, option_list)
+ @nodes = params['nodes'] ? params['nodes'] : []
+ @dot_string = 'graph'
+ end
- # This code is totally incomprehensible; it needs to be replaced!
+ def each_node
+ @nodes.each{ |i| yield i }
+ end
- label = @options['shape'] != 'record' && @ports.length == 0 ?
- @options['label'] ?
- t + $tab + "label = \"#{@options['label']}\"\n" :
- '' :
- t + $tab + 'label = "' + " \\\n" +
- t + $tab2 + "#{@options['label']}| \\\n" +
- @ports.collect{ |i|
- t + $tab2 + i.to_s
- }.join( "| \\\n" ) + " \\\n" +
- t + $tab + '"' + "\n"
+ def << (thing)
+ @nodes << thing
+ end
- t + "#{@name} [\n" +
- @options.to_a.collect{ |i|
- i[1] && i[0] != 'label' ?
- t + $tab + "#{i[0]} = #{i[1]}" : nil
- }.compact.join( ",\n" ) + ( label != '' ? ",\n" : "\n" ) +
- label +
- t + "]\n"
- end
+ def push (thing)
+ @nodes.push( thing )
+ end
+ def pop
+ @nodes.pop
end
- # A subgraph element is the same to graph, but has another header in dot
- # notation.
+ def to_s (t = '')
+ hdr = t + "#{@dot_string} #{@name} {\n"
- class DOTSubgraph < DOTElement
+ options = @options.to_a.collect{ |name, val|
+ val && name != 'label' ?
+ t + $tab + "#{name} = #{val}" :
+ name ? t + $tab + "#{name} = \"#{val}\"" : nil
+ }.compact.join( "\n" ) + "\n"
- @nodes
- @dot_string
+ nodes = @nodes.collect{ |i|
+ i.to_s( t + $tab )
+ }.join( "\n" ) + "\n"
+ hdr + options + nodes + t + "}\n"
+ end
- def initialize (params = {}, option_list = GRAPH_OPTS)
- super(params, option_list)
- @nodes = params['nodes'] ? params['nodes'] : []
- @dot_string = 'graph'
- end
+ end
- def each_node
- @nodes.each{ |i| yield i }
- end
+ # This is a graph.
- def << (thing)
- @nodes << thing
- end
+ class DOTDigraph < DOTSubgraph
- def push (thing)
- @nodes.push( thing )
- end
+ def initialize (params = {}, option_list = GRAPH_OPTS)
+ super(params, option_list)
+ @dot_string = 'digraph'
+ end
- def pop
- @nodes.pop
- end
+ end
- def to_s (t = '')
- hdr = t + "#{@dot_string} #{@name} {\n"
+ # This is an edge.
- options = @options.to_a.collect{ |name, val|
- val && name != 'label' ?
- t + $tab + "#{name} = #{val}" :
- name ? t + $tab + "#{name} = \"#{val}\"" : nil
- }.compact.join( "\n" ) + "\n"
+ class DOTEdge < DOTElement
- nodes = @nodes.collect{ |i|
- i.to_s( t + $tab )
- }.join( "\n" ) + "\n"
- hdr + options + nodes + t + "}\n"
- end
+ attr_accessor :from, :to
+ def initialize (params = {}, option_list = EDGE_OPTS)
+ super(params, option_list)
+ @from = params['from'] ? params['from'] : nil
+ @to = params['to'] ? params['to'] : nil
end
- # This is a graph.
-
- class DOTDigraph < DOTSubgraph
-
- def initialize (params = {}, option_list = GRAPH_OPTS)
- super(params, option_list)
- @dot_string = 'digraph'
+ def edge_link
+ '--'
end
+ def to_s (t = '')
+ t + "#{@from} #{edge_link} #{to} [\n" +
+ @options.to_a.collect{ |i|
+ i[1] && i[0] != 'label' ?
+ t + $tab + "#{i[0]} = #{i[1]}" :
+ i[1] ? t + $tab + "#{i[0]} = \"#{i[1]}\"" : nil
+ }.compact.join( "\n" ) + "\n#{t}]\n"
end
- # This is an edge.
-
- class DOTEdge < DOTElement
+ end
- attr_accessor :from, :to
-
- def initialize (params = {}, option_list = EDGE_OPTS)
- super(params, option_list)
- @from = params['from'] ? params['from'] : nil
- @to = params['to'] ? params['to'] : nil
- end
-
- def edge_link
- '--'
- end
-
- def to_s (t = '')
- t + "#{@from} #{edge_link} #{to} [\n" +
- @options.to_a.collect{ |i|
- i[1] && i[0] != 'label' ?
- t + $tab + "#{i[0]} = #{i[1]}" :
- i[1] ? t + $tab + "#{i[0]} = \"#{i[1]}\"" : nil
- }.compact.join( "\n" ) + "\n#{t}]\n"
- end
+ class DOTDirectedEdge < DOTEdge
+ def edge_link
+ '->'
end
- class DOTDirectedEdge < DOTEdge
-
- def edge_link
- '->'
- end
-
- end
+ end
end
diff --git a/lib/puppet/external/event-loop/better-definers.rb b/lib/puppet/external/event-loop/better-definers.rb
index c600fc2..ef1d44c 100644
--- a/lib/puppet/external/event-loop/better-definers.rb
+++ b/lib/puppet/external/event-loop/better-definers.rb
@@ -18,350 +18,350 @@
# Boston, MA 02110-1301, USA.
class Symbol
- def predicate?
- to_s.include? "?" end
- def imperative?
- to_s.include? "!" end
- def writer?
- to_s.include? "=" end
-
- def punctuated?
- predicate? or imperative? or writer? end
- def without_punctuation
- to_s.delete("?!=").to_sym end
-
- def predicate
- without_punctuation.to_s + "?" end
- def imperative
- without_punctuation.to_s + "!" end
- def writer
- without_punctuation.to_s + "=" end
+ def predicate?
+ to_s.include? "?" end
+ def imperative?
+ to_s.include? "!" end
+ def writer?
+ to_s.include? "=" end
+
+ def punctuated?
+ predicate? or imperative? or writer? end
+ def without_punctuation
+ to_s.delete("?!=").to_sym end
+
+ def predicate
+ without_punctuation.to_s + "?" end
+ def imperative
+ without_punctuation.to_s + "!" end
+ def writer
+ without_punctuation.to_s + "=" end
end
class Hash
- def collect! (&block)
- replace Hash[*collect(&block).flatten]
- end
+ def collect! (&block)
+ replace Hash[*collect(&block).flatten]
+ end
- def flatten
- to_a.flatten
- end
+ def flatten
+ to_a.flatten
+ end
end
module Kernel
- def returning (value)
- yield value ; value
- end
+ def returning (value)
+ yield value ; value
+ end
end
class Module
- def define_hard_aliases (name_pairs)
- for new_aliases, existing_name in name_pairs do
- new_aliases.kind_of? Array or new_aliases = [new_aliases]
- for new_alias in new_aliases do
- alias_method(new_alias, existing_name)
- end
- end
- end
-
- def define_soft_aliases (name_pairs)
- for new_aliases, existing_name in name_pairs do
- new_aliases.kind_of? Array or new_aliases = [new_aliases]
- for new_alias in new_aliases do
- class_eval %{def #{new_alias}(*args, &block)
- #{existing_name}(*args, &block) end}
- end
- end
- end
-
- define_soft_aliases \
- :define_hard_alias => :define_hard_aliases,
- :define_soft_alias => :define_soft_aliases
-
- # This method lets you define predicates like :foo?,
- # which will be defined to return the value of @foo.
- def define_readers (*names)
- for name in names.map { |x| x.to_sym } do
- if name.punctuated?
- # There's no way to define an efficient reader whose
- # name is different from the instance variable.
- class_eval %{def #{name} ; @#{name.without_punctuation} end}
- else
- # Use `attr_reader' to define an efficient method.
- attr_reader(name)
- end
- end
- end
-
- def writer_defined? (name)
- method_defined?(name.to_sym.writer)
- end
-
- # If you pass a predicate symbol :foo? to this method, it'll first
- # define a regular writer method :foo, without a question mark.
- # Then it'll define an imperative writer method :foo! as a shorthand
- # for setting the property to true.
- def define_writers (*names, &body)
- for name in names.map { |x| x.to_sym } do
- if block_given?
- define_method(name.writer, &body)
- else
- attr_writer(name.without_punctuation)
- end
- if name.predicate?
- class_eval %{def #{name.imperative}
- self.#{name.writer} true end}
- end
- end
- end
-
- define_soft_aliases \
- :define_reader => :define_readers,
- :define_writer => :define_writers
-
- # We don't need a singular alias for `define_accessors',
- # because it always defines at least two methods.
-
- def define_accessors (*names)
- define_readers(*names)
- define_writers(*names)
- end
-
- def define_opposite_readers (name_pairs)
- name_pairs.collect! { |k, v| [k.to_sym, v.to_sym] }
- for opposite_name, name in name_pairs do
- define_reader(name) unless method_defined?(name)
- class_eval %{def #{opposite_name} ; not #{name} end}
- end
+ def define_hard_aliases (name_pairs)
+ for new_aliases, existing_name in name_pairs do
+ new_aliases.kind_of? Array or new_aliases = [new_aliases]
+ for new_alias in new_aliases do
+ alias_method(new_alias, existing_name)
+ end
end
-
- def define_opposite_writers (name_pairs)
- name_pairs.collect! { |k, v| [k.to_sym, v.to_sym] }
- for opposite_name, name in name_pairs do
- define_writer(name) unless writer_defined?(name)
- class_eval %{def #{opposite_name.writer} x
- self.#{name.writer} !x end}
- class_eval %{def #{opposite_name.imperative}
- self.#{name.writer} false end}
- end
+ end
+
+ def define_soft_aliases (name_pairs)
+ for new_aliases, existing_name in name_pairs do
+ new_aliases.kind_of? Array or new_aliases = [new_aliases]
+ for new_alias in new_aliases do
+ class_eval %{def #{new_alias}(*args, &block)
+ #{existing_name}(*args, &block) end}
+ end
end
-
- define_soft_aliases \
- :define_opposite_reader => :define_opposite_readers,
- :define_opposite_writer => :define_opposite_writers
-
- def define_opposite_accessors (name_pairs)
- define_opposite_readers name_pairs
- define_opposite_writers name_pairs
- end
-
- def define_reader_with_opposite (name_pair, &body)
- name, opposite_name = name_pair.flatten.collect { |x| x.to_sym }
- define_method(name, &body)
- define_opposite_reader(opposite_name => name)
+ end
+
+ define_soft_aliases \
+ :define_hard_alias => :define_hard_aliases,
+ :define_soft_alias => :define_soft_aliases
+
+ # This method lets you define predicates like :foo?,
+ # which will be defined to return the value of @foo.
+ def define_readers (*names)
+ for name in names.map { |x| x.to_sym } do
+ if name.punctuated?
+ # There's no way to define an efficient reader whose
+ # name is different from the instance variable.
+ class_eval %{def #{name} ; @#{name.without_punctuation} end}
+ else
+ # Use `attr_reader' to define an efficient method.
+ attr_reader(name)
+ end
end
-
- def define_writer_with_opposite (name_pair, &body)
- name, opposite_name = name_pair.flatten.collect { |x| x.to_sym }
- define_writer(name, &body)
- define_opposite_writer(opposite_name => name)
+ end
+
+ def writer_defined? (name)
+ method_defined?(name.to_sym.writer)
+ end
+
+ # If you pass a predicate symbol :foo? to this method, it'll first
+ # define a regular writer method :foo, without a question mark.
+ # Then it'll define an imperative writer method :foo! as a shorthand
+ # for setting the property to true.
+ def define_writers (*names, &body)
+ for name in names.map { |x| x.to_sym } do
+ if block_given?
+ define_method(name.writer, &body)
+ else
+ attr_writer(name.without_punctuation)
+ end
+ if name.predicate?
+ class_eval %{def #{name.imperative}
+ self.#{name.writer} true end}
+ end
end
+ end
- public :define_method
+ define_soft_aliases \
+ :define_reader => :define_readers,
+ :define_writer => :define_writers
- def define_methods (*names, &body)
- names.each { |name| define_method(name, &body) }
- end
+ # We don't need a singular alias for `define_accessors',
+ # because it always defines at least two methods.
- def define_private_methods (*names, &body)
- define_methods(*names, &body)
- names.each { |name| private name }
- end
+ def define_accessors (*names)
+ define_readers(*names)
+ define_writers(*names)
+ end
- def define_protected_methods (*names, &body)
- define_methods(*names, &body)
- names.each { |name| protected name }
+ def define_opposite_readers (name_pairs)
+ name_pairs.collect! { |k, v| [k.to_sym, v.to_sym] }
+ for opposite_name, name in name_pairs do
+ define_reader(name) unless method_defined?(name)
+ class_eval %{def #{opposite_name} ; not #{name} end}
end
-
- def define_private_method (name, &body)
- define_method(name, &body)
- private name
- end
-
- def define_protected_method (name, &body)
- define_method(name, &body)
- protected name
+ end
+
+ def define_opposite_writers (name_pairs)
+ name_pairs.collect! { |k, v| [k.to_sym, v.to_sym] }
+ for opposite_name, name in name_pairs do
+ define_writer(name) unless writer_defined?(name)
+ class_eval %{def #{opposite_name.writer} x
+ self.#{name.writer} !x end}
+ class_eval %{def #{opposite_name.imperative}
+ self.#{name.writer} false end}
end
+ end
+
+ define_soft_aliases \
+ :define_opposite_reader => :define_opposite_readers,
+ :define_opposite_writer => :define_opposite_writers
+
+ def define_opposite_accessors (name_pairs)
+ define_opposite_readers name_pairs
+ define_opposite_writers name_pairs
+ end
+
+ def define_reader_with_opposite (name_pair, &body)
+ name, opposite_name = name_pair.flatten.collect { |x| x.to_sym }
+ define_method(name, &body)
+ define_opposite_reader(opposite_name => name)
+ end
+
+ def define_writer_with_opposite (name_pair, &body)
+ name, opposite_name = name_pair.flatten.collect { |x| x.to_sym }
+ define_writer(name, &body)
+ define_opposite_writer(opposite_name => name)
+ end
+
+ public :define_method
+
+ def define_methods (*names, &body)
+ names.each { |name| define_method(name, &body) }
+ end
+
+ def define_private_methods (*names, &body)
+ define_methods(*names, &body)
+ names.each { |name| private name }
+ end
+
+ def define_protected_methods (*names, &body)
+ define_methods(*names, &body)
+ names.each { |name| protected name }
+ end
+
+ def define_private_method (name, &body)
+ define_method(name, &body)
+ private name
+ end
+
+ def define_protected_method (name, &body)
+ define_method(name, &body)
+ protected name
+ end
end
class ImmutableAttributeError < StandardError
- def initialize (attribute=nil, message=nil)
- super message
- @attribute = attribute
- end
-
- define_accessors :attribute
-
- def to_s
- if @attribute and @message
- "cannot change the value of `#@attribute': #@message"
- elsif @attribute
- "cannot change the value of `#@attribute'"
- elsif @message
- "cannot change the value of attribute: #@message"
- else
- "cannot change the value of attribute"
- end
+ def initialize (attribute=nil, message=nil)
+ super message
+ @attribute = attribute
+ end
+
+ define_accessors :attribute
+
+ def to_s
+ if @attribute and @message
+ "cannot change the value of `#@attribute': #@message"
+ elsif @attribute
+ "cannot change the value of `#@attribute'"
+ elsif @message
+ "cannot change the value of attribute: #@message"
+ else
+ "cannot change the value of attribute"
end
+ end
end
class Module
- # Guard each of the specified attributes by replacing the writer
- # method with a proxy that asks the supplied block before proceeding
- # with the change.
- #
- # If it's okay to change the attribute, the block should return
- # either nil or the symbol :mutable. If it isn't okay, the block
- # should return a string saying why the attribute can't be changed.
- # If you don't want to provide a reason, you can have the block
- # return just the symbol :immutable.
- def guard_writers(*names, &predicate)
- for name in names.map { |x| x.to_sym } do
- define_hard_alias("__unguarded_#{name.writer}" => name.writer)
- define_method(name.writer) do |new_value|
- case result = predicate.call
- when :mutable, nil
- __send__("__unguarded_#{name.writer}", new_value)
- when :immutable
- raise ImmutableAttributeError.new(name)
- else
- raise ImmutableAttributeError.new(name, result)
- end
- end
+ # Guard each of the specified attributes by replacing the writer
+ # method with a proxy that asks the supplied block before proceeding
+ # with the change.
+ #
+ # If it's okay to change the attribute, the block should return
+ # either nil or the symbol :mutable. If it isn't okay, the block
+ # should return a string saying why the attribute can't be changed.
+ # If you don't want to provide a reason, you can have the block
+ # return just the symbol :immutable.
+ def guard_writers(*names, &predicate)
+ for name in names.map { |x| x.to_sym } do
+ define_hard_alias("__unguarded_#{name.writer}" => name.writer)
+ define_method(name.writer) do |new_value|
+ case result = predicate.call
+ when :mutable, nil
+ __send__("__unguarded_#{name.writer}", new_value)
+ when :immutable
+ raise ImmutableAttributeError.new(name)
+ else
+ raise ImmutableAttributeError.new(name, result)
end
+ end
end
+ end
- def define_guarded_writers (*names, &block)
- define_writers(*names)
- guard_writers(*names, &block)
- end
+ def define_guarded_writers (*names, &block)
+ define_writers(*names)
+ guard_writers(*names, &block)
+ end
- define_soft_alias :guard_writer => :guard_writers
- define_soft_alias :define_guarded_writer => :define_guarded_writers
+ define_soft_alias :guard_writer => :guard_writers
+ define_soft_alias :define_guarded_writer => :define_guarded_writers
end
if __FILE__ == $0
- require "test/unit"
-
- class DefineAccessorsTest < Test::Unit::TestCase
- def setup
- @X = Class.new
- @Y = Class.new @X
- @x = @X.new
- @y = @Y.new
- end
+ require "test/unit"
+
+ class DefineAccessorsTest < Test::Unit::TestCase
+ def setup
+ @X = Class.new
+ @Y = Class.new @X
+ @x = @X.new
+ @y = @Y.new
+ end
- def test_define_hard_aliases
- @X.define_method(:foo) { 123 }
- @X.define_method(:baz) { 321 }
- @X.define_hard_aliases :bar => :foo, :quux => :baz
- assert_equal @x.foo, 123
- assert_equal @x.bar, 123
- assert_equal @y.foo, 123
- assert_equal @y.bar, 123
- assert_equal @x.baz, 321
- assert_equal @x.quux, 321
- assert_equal @y.baz, 321
- assert_equal @y.quux, 321
- @Y.define_method(:foo) { 456 }
- assert_equal @y.foo, 456
- assert_equal @y.bar, 123
- @Y.define_method(:quux) { 654 }
- assert_equal @y.baz, 321
- assert_equal @y.quux, 654
- end
+ def test_define_hard_aliases
+ @X.define_method(:foo) { 123 }
+ @X.define_method(:baz) { 321 }
+ @X.define_hard_aliases :bar => :foo, :quux => :baz
+ assert_equal @x.foo, 123
+ assert_equal @x.bar, 123
+ assert_equal @y.foo, 123
+ assert_equal @y.bar, 123
+ assert_equal @x.baz, 321
+ assert_equal @x.quux, 321
+ assert_equal @y.baz, 321
+ assert_equal @y.quux, 321
+ @Y.define_method(:foo) { 456 }
+ assert_equal @y.foo, 456
+ assert_equal @y.bar, 123
+ @Y.define_method(:quux) { 654 }
+ assert_equal @y.baz, 321
+ assert_equal @y.quux, 654
+ end
- def test_define_soft_aliases
- @X.define_method(:foo) { 123 }
- @X.define_method(:baz) { 321 }
- @X.define_soft_aliases :bar => :foo, :quux => :baz
- assert_equal @x.foo, 123
- assert_equal @x.bar, 123
- assert_equal @y.foo, 123
- assert_equal @y.bar, 123
- assert_equal @x.baz, 321
- assert_equal @x.quux, 321
- assert_equal @y.baz, 321
- assert_equal @y.quux, 321
- @Y.define_method(:foo) { 456 }
- assert_equal @y.foo, @y.bar, 456
- @Y.define_method(:quux) { 654 }
- assert_equal @y.baz, 321
- assert_equal @y.quux, 654
- end
+ def test_define_soft_aliases
+ @X.define_method(:foo) { 123 }
+ @X.define_method(:baz) { 321 }
+ @X.define_soft_aliases :bar => :foo, :quux => :baz
+ assert_equal @x.foo, 123
+ assert_equal @x.bar, 123
+ assert_equal @y.foo, 123
+ assert_equal @y.bar, 123
+ assert_equal @x.baz, 321
+ assert_equal @x.quux, 321
+ assert_equal @y.baz, 321
+ assert_equal @y.quux, 321
+ @Y.define_method(:foo) { 456 }
+ assert_equal @y.foo, @y.bar, 456
+ @Y.define_method(:quux) { 654 }
+ assert_equal @y.baz, 321
+ assert_equal @y.quux, 654
+ end
- def test_define_readers
- @X.define_readers :foo, :bar
- assert !@x.respond_to?(:foo=)
- assert !@x.respond_to?(:bar=)
- @x.instance_eval { @foo = 123 ; @bar = 456 }
- assert_equal @x.foo, 123
- assert_equal @x.bar, 456
- @X.define_readers :baz?, :quux?
- assert !@x.respond_to?(:baz=)
- assert !@x.respond_to?(:quux=)
- @x.instance_eval { @baz = false ; @quux = true }
- assert !@x.baz?
- assert @x.quux?
- end
+ def test_define_readers
+ @X.define_readers :foo, :bar
+ assert !@x.respond_to?(:foo=)
+ assert !@x.respond_to?(:bar=)
+ @x.instance_eval { @foo = 123 ; @bar = 456 }
+ assert_equal @x.foo, 123
+ assert_equal @x.bar, 456
+ @X.define_readers :baz?, :quux?
+ assert !@x.respond_to?(:baz=)
+ assert !@x.respond_to?(:quux=)
+ @x.instance_eval { @baz = false ; @quux = true }
+ assert !@x.baz?
+ assert @x.quux?
+ end
- def test_define_writers
- assert !@X.writer_defined?(:foo)
- assert !@X.writer_defined?(:bar)
- @X.define_writers :foo, :bar
- assert @X.writer_defined?(:foo)
- assert @X.writer_defined?(:bar)
- assert @X.writer_defined?(:foo=)
- assert @X.writer_defined?(:bar=)
- assert @X.writer_defined?(:foo?)
- assert @X.writer_defined?(:bar?)
- assert !@x.respond_to?(:foo)
- assert !@x.respond_to?(:bar)
- @x.foo = 123
- @x.bar = 456
- assert_equal @x.instance_eval { @foo }, 123
- assert_equal @x.instance_eval { @bar }, 456
- @X.define_writers :baz?, :quux?
- assert !@x.respond_to?(:baz?)
- assert !@x.respond_to?(:quux?)
- @x.baz = true
- @x.quux = false
- assert_equal @x.instance_eval { @baz }, true
- assert_equal @x.instance_eval { @quux }, false
- end
+ def test_define_writers
+ assert !@X.writer_defined?(:foo)
+ assert !@X.writer_defined?(:bar)
+ @X.define_writers :foo, :bar
+ assert @X.writer_defined?(:foo)
+ assert @X.writer_defined?(:bar)
+ assert @X.writer_defined?(:foo=)
+ assert @X.writer_defined?(:bar=)
+ assert @X.writer_defined?(:foo?)
+ assert @X.writer_defined?(:bar?)
+ assert !@x.respond_to?(:foo)
+ assert !@x.respond_to?(:bar)
+ @x.foo = 123
+ @x.bar = 456
+ assert_equal @x.instance_eval { @foo }, 123
+ assert_equal @x.instance_eval { @bar }, 456
+ @X.define_writers :baz?, :quux?
+ assert !@x.respond_to?(:baz?)
+ assert !@x.respond_to?(:quux?)
+ @x.baz = true
+ @x.quux = false
+ assert_equal @x.instance_eval { @baz }, true
+ assert_equal @x.instance_eval { @quux }, false
+ end
- def test_define_accessors
- @X.define_accessors :foo, :bar
- @x.foo = 123 ; @x.bar = 456
- assert_equal @x.foo, 123
- assert_equal @x.bar, 456
- end
+ def test_define_accessors
+ @X.define_accessors :foo, :bar
+ @x.foo = 123 ; @x.bar = 456
+ assert_equal @x.foo, 123
+ assert_equal @x.bar, 456
+ end
- def test_define_opposite_readers
- @X.define_opposite_readers :foo? => :bar?, :baz? => :quux?
- assert !@x.respond_to?(:foo=)
- assert !@x.respond_to?(:bar=)
- assert !@x.respond_to?(:baz=)
- assert !@x.respond_to?(:quux=)
- @x.instance_eval { @bar = true ; @quux = false }
- assert !@x.foo?
- assert @x.bar?
- assert @x.baz?
- assert !@x.quux?
- end
+ def test_define_opposite_readers
+ @X.define_opposite_readers :foo? => :bar?, :baz? => :quux?
+ assert !@x.respond_to?(:foo=)
+ assert !@x.respond_to?(:bar=)
+ assert !@x.respond_to?(:baz=)
+ assert !@x.respond_to?(:quux=)
+ @x.instance_eval { @bar = true ; @quux = false }
+ assert !@x.foo?
+ assert @x.bar?
+ assert @x.baz?
+ assert !@x.quux?
+ end
- def test_define_opposite_writers
- @X.define_opposite_writers :foo? => :bar?, :baz => :quux
- end
+ def test_define_opposite_writers
+ @X.define_opposite_writers :foo? => :bar?, :baz => :quux
end
+ end
end
diff --git a/lib/puppet/external/event-loop/event-loop.rb b/lib/puppet/external/event-loop/event-loop.rb
index bd27855..dc51a55 100644
--- a/lib/puppet/external/event-loop/event-loop.rb
+++ b/lib/puppet/external/event-loop/event-loop.rb
@@ -23,329 +23,329 @@ require "puppet/external/event-loop/signal-system"
require "fcntl"
class EventLoop
- include SignalEmitter
-
- IO_STATES = [:readable, :writable, :exceptional]
-
- class << self
- def default ; @default ||= new end
- def default= x ; @default = x end
-
- def current
- Thread.current["event-loop::current"] || default end
- def current= x
- Thread.current["event-loop::current"] = x end
-
- def with_current (new)
- if current == new
- yield
- else
- begin
- old = self.current
- self.current = new
- yield
- ensure
- self.current = old
- end
- end
- end
-
- def method_missing (name, *args, &block)
- if current.respond_to? name
- current.__send__(name, *args, &block)
- else
- super
- end
+ include SignalEmitter
+
+ IO_STATES = [:readable, :writable, :exceptional]
+
+ class << self
+ def default ; @default ||= new end
+ def default= x ; @default = x end
+
+ def current
+ Thread.current["event-loop::current"] || default end
+ def current= x
+ Thread.current["event-loop::current"] = x end
+
+ def with_current (new)
+ if current == new
+ yield
+ else
+ begin
+ old = self.current
+ self.current = new
+ yield
+ ensure
+ self.current = old
end
+ end
end
- define_signals :before_sleep, :after_sleep
-
- def initialize
- @running = false
- @awake = false
- @wakeup_time = nil
- @timers = []
-
- @io_arrays = [[], [], []]
- @ios = Hash.new do |h, k| raise ArgumentError,
- "invalid IO event: #{k}", caller(2) end
- IO_STATES.each_with_index { |x, i| @ios[x] = @io_arrays[i] }
-
- @notify_src, @notify_snk = IO.pipe
-
- # prevent file descriptor leaks
- @notify_src.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
- @notify_snk.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
-
- @notify_src.will_block = false
- @notify_snk.will_block = false
-
- # Each time a byte is sent through the notification pipe
- # we need to read it, or IO.select will keep returning.
- monitor_io(@notify_src, :readable)
- @notify_src.extend(Watchable)
- @notify_src.on_readable do
- begin
- @notify_src.sysread(256)
- rescue Errno::EAGAIN
- # The pipe wasn't readable after all.
- end
- end
+ def method_missing (name, *args, &block)
+ if current.respond_to? name
+ current.__send__(name, *args, &block)
+ else
+ super
+ end
end
-
- define_opposite_accessors \
- :stopped? => :running?,
- :sleeping? => :awake?
-
- def run
- if block_given?
- thread = Thread.new { run }
- yield ; quit ; thread.join
- else
- running!
- iterate while running?
- end
- ensure
- quit
+ end
+
+ define_signals :before_sleep, :after_sleep
+
+ def initialize
+ @running = false
+ @awake = false
+ @wakeup_time = nil
+ @timers = []
+
+ @io_arrays = [[], [], []]
+ @ios = Hash.new do |h, k| raise ArgumentError,
+ "invalid IO event: #{k}", caller(2) end
+ IO_STATES.each_with_index { |x, i| @ios[x] = @io_arrays[i] }
+
+ @notify_src, @notify_snk = IO.pipe
+
+ # prevent file descriptor leaks
+ @notify_src.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
+ @notify_snk.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
+
+ @notify_src.will_block = false
+ @notify_snk.will_block = false
+
+ # Each time a byte is sent through the notification pipe
+ # we need to read it, or IO.select will keep returning.
+ monitor_io(@notify_src, :readable)
+ @notify_src.extend(Watchable)
+ @notify_src.on_readable do
+ begin
+ @notify_src.sysread(256)
+ rescue Errno::EAGAIN
+ # The pipe wasn't readable after all.
+ end
end
-
- def iterate (user_timeout=nil)
- t1, t2 = user_timeout, max_timeout
- timeout = t1 && t2 ? [t1, t2].min : t1 || t2
- select(timeout).zip(IO_STATES) do |ios, state|
- ios.each { |x| x.signal(state) } if ios
- end
+ end
+
+ define_opposite_accessors \
+ :stopped? => :running?,
+ :sleeping? => :awake?
+
+ def run
+ if block_given?
+ thread = Thread.new { run }
+ yield ; quit ; thread.join
+ else
+ running!
+ iterate while running?
+ end
+ ensure
+ quit
+ end
+
+ def iterate (user_timeout=nil)
+ t1, t2 = user_timeout, max_timeout
+ timeout = t1 && t2 ? [t1, t2].min : t1 || t2
+ select(timeout).zip(IO_STATES) do |ios, state|
+ ios.each { |x| x.signal(state) } if ios
end
+ end
- private
+ private
- def select (timeout)
- @wakeup_time = timeout ? Time.now + timeout : nil
- # puts "waiting: #{timeout} seconds"
- signal :before_sleep ; sleeping!
- IO.select(*@io_arrays + [timeout]) || []
- ensure
- awake! ; signal :after_sleep
- @timers.each { |x| x.sound_alarm if x.ready? }
- end
+ def select (timeout)
+ @wakeup_time = timeout ? Time.now + timeout : nil
+ # puts "waiting: #{timeout} seconds"
+ signal :before_sleep ; sleeping!
+ IO.select(*@io_arrays + [timeout]) || []
+ ensure
+ awake! ; signal :after_sleep
+ @timers.each { |x| x.sound_alarm if x.ready? }
+ end
- public
+ public
- def quit ; stopped! ; wake_up ; self end
+ def quit ; stopped! ; wake_up ; self end
- def monitoring_io? (io, event)
- @ios[event].include? io end
- def monitoring_timer? (timer)
- @timers.include? timer end
+ def monitoring_io? (io, event)
+ @ios[event].include? io end
+ def monitoring_timer? (timer)
+ @timers.include? timer end
- def monitor_io (io, *events)
- for event in events do
- @ios[event] << io ; wake_up unless monitoring_io?(io, event)
- end
+ def monitor_io (io, *events)
+ for event in events do
+ @ios[event] << io ; wake_up unless monitoring_io?(io, event)
end
+ end
- def monitor_timer (timer)
- @timers << timer unless monitoring_timer? timer
- end
+ def monitor_timer (timer)
+ @timers << timer unless monitoring_timer? timer
+ end
- def check_timer (timer)
- wake_up if timer.end_time < @wakeup_time
- end
+ def check_timer (timer)
+ wake_up if timer.end_time < @wakeup_time
+ end
- def ignore_io (io, *events)
- events = IO_STATES if events.empty?
- for event in events do
- wake_up if @ios[event].delete(io)
- end
+ def ignore_io (io, *events)
+ events = IO_STATES if events.empty?
+ for event in events do
+ wake_up if @ios[event].delete(io)
end
+ end
- def ignore_timer (timer)
- # Don't need to wake up for this.
- @timers.delete(timer)
- end
+ def ignore_timer (timer)
+ # Don't need to wake up for this.
+ @timers.delete(timer)
+ end
- def max_timeout
- return nil if @timers.empty?
- [@timers.collect { |x| x.time_left }.min, 0].max
- end
+ def max_timeout
+ return nil if @timers.empty?
+ [@timers.collect { |x| x.time_left }.min, 0].max
+ end
- def wake_up
- @notify_snk.write('.') if sleeping?
- end
+ def wake_up
+ @notify_snk.write('.') if sleeping?
+ end
end
class Symbol
- def io_state?
- EventLoop::IO_STATES.include? self
- end
+ def io_state?
+ EventLoop::IO_STATES.include? self
+ end
end
module EventLoop::Watchable
- include SignalEmitter
+ include SignalEmitter
- define_signals :readable, :writable, :exceptional
+ define_signals :readable, :writable, :exceptional
- def monitor_events (*events)
- EventLoop.monitor_io(self, *events) end
- def ignore_events (*events)
- EventLoop.ignore_io(self, *events) end
+ def monitor_events (*events)
+ EventLoop.monitor_io(self, *events) end
+ def ignore_events (*events)
+ EventLoop.ignore_io(self, *events) end
- define_soft_aliases \
- :monitor_event => :monitor_events,
- :ignore_event => :ignore_events
+ define_soft_aliases \
+ :monitor_event => :monitor_events,
+ :ignore_event => :ignore_events
- def close ; super
- ignore_events end
- def close_read ; super
- ignore_event :readable end
- def close_write ; super
- ignore_event :writable end
+ def close ; super
+ ignore_events end
+ def close_read ; super
+ ignore_event :readable end
+ def close_write ; super
+ ignore_event :writable end
- module Automatic
- include EventLoop::Watchable
+ module Automatic
+ include EventLoop::Watchable
- def add_signal_handler (name, &handler) super
- monitor_event(name) if name.io_state?
- end
+ def add_signal_handler (name, &handler) super
+ monitor_event(name) if name.io_state?
+ end
- def remove_signal_handler (name, handler) super
- if @signal_handlers[name].empty?
- ignore_event(name) if name.io_state?
- end
- end
+ def remove_signal_handler (name, handler) super
+ if @signal_handlers[name].empty?
+ ignore_event(name) if name.io_state?
+ end
end
+ end
end
class IO
- def on_readable &block
- extend EventLoop::Watchable::Automatic
- on_readable(&block)
- end
-
- def on_writable &block
- extend EventLoop::Watchable::Automatic
- on_writable(&block)
- end
-
- def on_exceptional &block
- extend EventLoop::Watchable::Automatic
- on_exceptional(&block)
- end
-
- def will_block?
- require "fcntl"
- fcntl(Fcntl::F_GETFL, 0) & Fcntl::O_NONBLOCK == 0
- end
-
- def will_block= (wants_blocking)
- require "fcntl"
- flags = fcntl(Fcntl::F_GETFL, 0)
- if wants_blocking
- flags &= ~Fcntl::O_NONBLOCK
- else
- flags |= Fcntl::O_NONBLOCK
- end
- fcntl(Fcntl::F_SETFL, flags)
+ def on_readable &block
+ extend EventLoop::Watchable::Automatic
+ on_readable(&block)
+ end
+
+ def on_writable &block
+ extend EventLoop::Watchable::Automatic
+ on_writable(&block)
+ end
+
+ def on_exceptional &block
+ extend EventLoop::Watchable::Automatic
+ on_exceptional(&block)
+ end
+
+ def will_block?
+ require "fcntl"
+ fcntl(Fcntl::F_GETFL, 0) & Fcntl::O_NONBLOCK == 0
+ end
+
+ def will_block= (wants_blocking)
+ require "fcntl"
+ flags = fcntl(Fcntl::F_GETFL, 0)
+ if wants_blocking
+ flags &= ~Fcntl::O_NONBLOCK
+ else
+ flags |= Fcntl::O_NONBLOCK
end
+ fcntl(Fcntl::F_SETFL, flags)
+ end
end
class EventLoop::Timer
- include SignalEmitter
+ include SignalEmitter
- DEFAULT_INTERVAL = 0.0
- DEFAULT_TOLERANCE = 0.001
+ DEFAULT_INTERVAL = 0.0
+ DEFAULT_TOLERANCE = 0.001
- def initialize (options={}, &handler)
- @running = false
- @start_time = nil
+ def initialize (options={}, &handler)
+ @running = false
+ @start_time = nil
- options = { :interval => options } if options.kind_of? Numeric
+ options = { :interval => options } if options.kind_of? Numeric
- if options[:interval]
- @interval = options[:interval].to_f
- else
- @interval = DEFAULT_INTERVAL
- end
-
- if options[:tolerance]
- @tolerance = options[:tolerance].to_f
- elsif DEFAULT_TOLERANCE < @interval
- @tolerance = DEFAULT_TOLERANCE
- else
- @tolerance = 0.0
- end
-
- @event_loop = options[:event_loop] || EventLoop.current
-
- if block_given?
- add_signal_handler(:alarm, &handler)
- start unless options[:start?] == false
- else
- start if options[:start?]
- end
+ if options[:interval]
+ @interval = options[:interval].to_f
+ else
+ @interval = DEFAULT_INTERVAL
end
- define_readers :interval, :tolerance
- define_signal :alarm
-
- def stopped? ; @start_time == nil end
- def running? ; @start_time != nil end
-
- def interval= (new_interval)
- old_interval = @interval
- @interval = new_interval
- @event_loop.check_timer(self) if new_interval < old_interval
- end
-
- def end_time
- @start_time + @interval end
- def time_left
- end_time - Time.now end
- def ready?
- time_left <= @tolerance end
-
- def restart
- @start_time = Time.now
+ if options[:tolerance]
+ @tolerance = options[:tolerance].to_f
+ elsif DEFAULT_TOLERANCE < @interval
+ @tolerance = DEFAULT_TOLERANCE
+ else
+ @tolerance = 0.0
end
- def sound_alarm
- signal :alarm
- restart if running?
- end
+ @event_loop = options[:event_loop] || EventLoop.current
- def start
- @start_time = Time.now
- @event_loop.monitor_timer(self)
- end
-
- def stop
- @start_time = nil
- @event_loop.ignore_timer(self)
+ if block_given?
+ add_signal_handler(:alarm, &handler)
+ start unless options[:start?] == false
+ else
+ start if options[:start?]
end
+ end
+
+ define_readers :interval, :tolerance
+ define_signal :alarm
+
+ def stopped? ; @start_time == nil end
+ def running? ; @start_time != nil end
+
+ def interval= (new_interval)
+ old_interval = @interval
+ @interval = new_interval
+ @event_loop.check_timer(self) if new_interval < old_interval
+ end
+
+ def end_time
+ @start_time + @interval end
+ def time_left
+ end_time - Time.now end
+ def ready?
+ time_left <= @tolerance end
+
+ def restart
+ @start_time = Time.now
+ end
+
+ def sound_alarm
+ signal :alarm
+ restart if running?
+ end
+
+ def start
+ @start_time = Time.now
+ @event_loop.monitor_timer(self)
+ end
+
+ def stop
+ @start_time = nil
+ @event_loop.ignore_timer(self)
+ end
end
if __FILE__ == $0
- require "test/unit"
+ require "test/unit"
- class TimerTest < Test::Unit::TestCase
- def setup
- @timer = EventLoop::Timer.new(:interval => 0.001)
- end
+ class TimerTest < Test::Unit::TestCase
+ def setup
+ @timer = EventLoop::Timer.new(:interval => 0.001)
+ end
- def test_timer
- @timer.on_alarm do
- puts "[#{@timer.time_left} seconds left after alarm]"
- EventLoop.quit
- end
- 8.times do
- t0 = Time.now
- @timer.start ; EventLoop.run
- t1 = Time.now
- assert(t1 - t0 > @timer.interval - @timer.tolerance)
- end
- end
+ def test_timer
+ @timer.on_alarm do
+ puts "[#{@timer.time_left} seconds left after alarm]"
+ EventLoop.quit
+ end
+ 8.times do
+ t0 = Time.now
+ @timer.start ; EventLoop.run
+ t1 = Time.now
+ assert(t1 - t0 > @timer.interval - @timer.tolerance)
+ end
end
+ end
end
## event-loop.rb ends here.
diff --git a/lib/puppet/external/event-loop/signal-system.rb b/lib/puppet/external/event-loop/signal-system.rb
index 09498c9..d3c924b 100644
--- a/lib/puppet/external/event-loop/signal-system.rb
+++ b/lib/puppet/external/event-loop/signal-system.rb
@@ -20,84 +20,84 @@
require "puppet/external/event-loop/better-definers"
module SignalEmitterModule
- def self.extended (object)
- if object.kind_of? Module and not object < SignalEmitter
- if object.respond_to? :fcall
- # This is the way to call private methods
- # in Ruby 1.9 as of November 16.
- object.fcall :include, SignalEmitter
- else
- object.__send__ :include, SignalEmitter
- end
- end
- end
-
- def define_signal (name, slot=:before, &body)
- # Can't use `define_method' and take a block pre-1.9.
- class_eval %{ def on_#{name} &block
- add_signal_handler(:#{name}, &block) end }
- define_signal_handler(name, :before, &lambda {|*a|})
- define_signal_handler(name, :after, &lambda {|*a|})
- define_signal_handler(name, slot, &body) if block_given?
- end
-
- def define_signals (*names, &body)
- names.each { |x| define_signal(x, &body) }
- end
-
- def define_signal_handler (name, slot=:before, &body)
- case slot
- when :before
- define_protected_method "handle_#{name}", &body
- when :after
- define_protected_method "after_handle_#{name}", &body
- else
- raise ArgumentError, "invalid slot `#{slot.inspect}'; " +
- "should be `:before' or `:after'", caller(1)
- end
- end
+ def self.extended (object)
+ if object.kind_of? Module and not object < SignalEmitter
+ if object.respond_to? :fcall
+ # This is the way to call private methods
+ # in Ruby 1.9 as of November 16.
+ object.fcall :include, SignalEmitter
+ else
+ object.__send__ :include, SignalEmitter
+ end
+ end
+ end
+
+ def define_signal (name, slot=:before, &body)
+ # Can't use `define_method' and take a block pre-1.9.
+ class_eval %{ def on_#{name} &block
+ add_signal_handler(:#{name}, &block) end }
+ define_signal_handler(name, :before, &lambda {|*a|})
+ define_signal_handler(name, :after, &lambda {|*a|})
+ define_signal_handler(name, slot, &body) if block_given?
+ end
+
+ def define_signals (*names, &body)
+ names.each { |x| define_signal(x, &body) }
+ end
+
+ def define_signal_handler (name, slot=:before, &body)
+ case slot
+ when :before
+ define_protected_method "handle_#{name}", &body
+ when :after
+ define_protected_method "after_handle_#{name}", &body
+ else
+ raise ArgumentError, "invalid slot `#{slot.inspect}'; " +
+ "should be `:before' or `:after'", caller(1)
+ end
+ end
end
# This is an old name for the same thing.
SignalEmitterClass = SignalEmitterModule
module SignalEmitter
- def self.included (includer)
- includer.extend SignalEmitterClass if not includer.kind_of? SignalEmitterClass
- end
-
- def __maybe_initialize_signal_emitter
- @signal_handlers ||= Hash.new { |h, k| h[k] = Array.new }
- @allow_dynamic_signals ||= false
- end
-
- define_accessors :allow_dynamic_signals?
-
- def add_signal_handler (name, &handler)
- __maybe_initialize_signal_emitter
- @signal_handlers[name] << handler
- handler
- end
-
- define_soft_aliases [:on, :on_signal] => :add_signal_handler
-
- def remove_signal_handler (name, handler)
- __maybe_initialize_signal_emitter
- @signal_handlers[name].delete(handler)
- end
-
- def __signal__ (name, *args, &block)
- __maybe_initialize_signal_emitter
- respond_to? "on_#{name}" or allow_dynamic_signals? or
- fail "undefined signal `#{name}' for #{self}:#{self.class}"
- __send__("handle_#{name}", *args, &block) if
- respond_to? "handle_#{name}"
- @signal_handlers[name].each { |x| x.call(*args, &block) }
- __send__("after_handle_#{name}", *args, &block) if
- respond_to? "after_handle_#{name}"
- end
-
- define_soft_alias :signal => :__signal__
+ def self.included (includer)
+ includer.extend SignalEmitterClass if not includer.kind_of? SignalEmitterClass
+ end
+
+ def __maybe_initialize_signal_emitter
+ @signal_handlers ||= Hash.new { |h, k| h[k] = Array.new }
+ @allow_dynamic_signals ||= false
+ end
+
+ define_accessors :allow_dynamic_signals?
+
+ def add_signal_handler (name, &handler)
+ __maybe_initialize_signal_emitter
+ @signal_handlers[name] << handler
+ handler
+ end
+
+ define_soft_aliases [:on, :on_signal] => :add_signal_handler
+
+ def remove_signal_handler (name, handler)
+ __maybe_initialize_signal_emitter
+ @signal_handlers[name].delete(handler)
+ end
+
+ def __signal__ (name, *args, &block)
+ __maybe_initialize_signal_emitter
+ respond_to? "on_#{name}" or allow_dynamic_signals? or
+ fail "undefined signal `#{name}' for #{self}:#{self.class}"
+ __send__("handle_#{name}", *args, &block) if
+ respond_to? "handle_#{name}"
+ @signal_handlers[name].each { |x| x.call(*args, &block) }
+ __send__("after_handle_#{name}", *args, &block) if
+ respond_to? "after_handle_#{name}"
+ end
+
+ define_soft_alias :signal => :__signal__
end
# This module is indended to be a convenience mixin to be used by
@@ -111,108 +111,108 @@ end
# XXX: This has not seen much use, and I'd like to provide a
# better solution for the problem in the future.
module SignalObserver
- def __maybe_initialize_signal_observer
- @observed_signals ||= Hash.new do |signals, object|
- signals[object] = Hash.new do |handlers, name|
- handlers[name] = Array.new
- end
- end
- end
-
- def observe_signal (subject, name, &handler)
- __maybe_initialize_signal_observer
- @observed_signals[subject][name] << handler
- subject.add_signal_handler(name, &handler)
- end
+ def __maybe_initialize_signal_observer
+ @observed_signals ||= Hash.new do |signals, object|
+ signals[object] = Hash.new do |handlers, name|
+ handlers[name] = Array.new
+ end
+ end
+ end
+
+ def observe_signal (subject, name, &handler)
+ __maybe_initialize_signal_observer
+ @observed_signals[subject][name] << handler
+ subject.add_signal_handler(name, &handler)
+ end
+
+ def map_signals (source, pairs={})
+ pairs.each do |src_name, dst_name|
+ observe_signal(source, src_name) do |*args|
+ __signal__(dst_name, *args)
+ end
+ end
+ end
+
+ def absorb_signals (subject, *names)
+ names.each do |name|
+ observe_signal(subject, name) do |*args|
+ __signal__(name, *args)
+ end
+ end
+ end
+
+ define_soft_aliases \
+ :map_signal => :map_signals,
+ :absorb_signal => :absorb_signals
+
+ def ignore_signal (subject, name)
+ __maybe_initialize_signal_observer
+ __ignore_signal_1(subject, name)
+ @observed_signals.delete(subject) if
+ @observed_signals[subject].empty?
+ end
+
+ def ignore_signals (subject, *names)
+ __maybe_initialize_signal_observer
+ names = @observed_signals[subject] if names.empty?
+ names.each { |x| __ignore_signal_1(subject, x) }
+ end
+
+ private
+
+ def __ignore_signal_1(subject, name)
+ @observed_signals[subject][name].each do |handler|
+ subject.remove_signal_handler(name, handler) end
+ @observed_signals[subject].delete(name)
+ end
+end
- def map_signals (source, pairs={})
- pairs.each do |src_name, dst_name|
- observe_signal(source, src_name) do |*args|
- __signal__(dst_name, *args)
- end
- end
+if __FILE__ == $0
+ require "test/unit"
+ class SignalEmitterTest < Test::Unit::TestCase
+ class X
+ include SignalEmitter
+ define_signal :foo
end
- def absorb_signals (subject, *names)
- names.each do |name|
- observe_signal(subject, name) do |*args|
- __signal__(name, *args)
- end
- end
+ def setup
+ @x = X.new
end
- define_soft_aliases \
- :map_signal => :map_signals,
- :absorb_signal => :absorb_signals
-
- def ignore_signal (subject, name)
- __maybe_initialize_signal_observer
- __ignore_signal_1(subject, name)
- @observed_signals.delete(subject) if
- @observed_signals[subject].empty?
+ def test_on_signal
+ moomin = 0
+ @x.on_signal(:foo) { moomin = 1 }
+ @x.signal :foo
+ assert moomin == 1
end
- def ignore_signals (subject, *names)
- __maybe_initialize_signal_observer
- names = @observed_signals[subject] if names.empty?
- names.each { |x| __ignore_signal_1(subject, x) }
+ def test_on_foo
+ moomin = 0
+ @x.on_foo { moomin = 1 }
+ @x.signal :foo
+ assert moomin == 1
end
- private
-
- def __ignore_signal_1(subject, name)
- @observed_signals[subject][name].each do |handler|
- subject.remove_signal_handler(name, handler) end
- @observed_signals[subject].delete(name)
+ def test_multiple_on_signal
+ moomin = 0
+ @x.on_signal(:foo) { moomin += 1 }
+ @x.on_signal(:foo) { moomin += 2 }
+ @x.on_signal(:foo) { moomin += 4 }
+ @x.on_signal(:foo) { moomin += 8 }
+ @x.signal :foo
+ assert moomin == 15
end
-end
-if __FILE__ == $0
- require "test/unit"
- class SignalEmitterTest < Test::Unit::TestCase
- class X
- include SignalEmitter
- define_signal :foo
- end
-
- def setup
- @x = X.new
- end
-
- def test_on_signal
- moomin = 0
- @x.on_signal(:foo) { moomin = 1 }
- @x.signal :foo
- assert moomin == 1
- end
-
- def test_on_foo
- moomin = 0
- @x.on_foo { moomin = 1 }
- @x.signal :foo
- assert moomin == 1
- end
-
- def test_multiple_on_signal
- moomin = 0
- @x.on_signal(:foo) { moomin += 1 }
- @x.on_signal(:foo) { moomin += 2 }
- @x.on_signal(:foo) { moomin += 4 }
- @x.on_signal(:foo) { moomin += 8 }
- @x.signal :foo
- assert moomin == 15
- end
-
- def test_multiple_on_foo
- moomin = 0
- @x.on_foo { moomin += 1 }
- @x.on_foo { moomin += 2 }
- @x.on_foo { moomin += 4 }
- @x.on_foo { moomin += 8 }
- @x.signal :foo
- assert moomin == 15
- end
+ def test_multiple_on_foo
+ moomin = 0
+ @x.on_foo { moomin += 1 }
+ @x.on_foo { moomin += 2 }
+ @x.on_foo { moomin += 4 }
+ @x.on_foo { moomin += 8 }
+ @x.signal :foo
+ assert moomin == 15
end
+ end
end
## application-signals.rb ends here.
diff --git a/lib/puppet/external/lock.rb b/lib/puppet/external/lock.rb
index 785ecd6..024fedf 100644
--- a/lib/puppet/external/lock.rb
+++ b/lib/puppet/external/lock.rb
@@ -15,49 +15,49 @@ require 'sync'
$reader_count = Hash.new(0)
class File
- # Get an exclusive (i.e., write) lock on the file, and yield to the block.
- # If the lock is not available, wait for it without blocking other ruby
- # threads.
- def lock_exclusive
- if Thread.list.size == 1
- flock(LOCK_EX)
- else
- # ugly hack because waiting for a lock in a Ruby thread blocks the
- # process
- period = 0.001
- until flock(LOCK_EX|LOCK_NB)
- sleep period
- period *= 2 if period < 1
- end
- end
-
- yield self
- ensure
- flush
- flock(LOCK_UN)
+ # Get an exclusive (i.e., write) lock on the file, and yield to the block.
+ # If the lock is not available, wait for it without blocking other ruby
+ # threads.
+ def lock_exclusive
+ if Thread.list.size == 1
+ flock(LOCK_EX)
+ else
+ # ugly hack because waiting for a lock in a Ruby thread blocks the
+ # process
+ period = 0.001
+ until flock(LOCK_EX|LOCK_NB)
+ sleep period
+ period *= 2 if period < 1
+ end
end
- # Get a shared (i.e., read) lock on the file, and yield to the block.
- # If the lock is not available, wait for it without blocking other ruby
- # threads.
- def lock_shared
- if Thread.list.size == 1
- flock(LOCK_SH)
- else
- # ugly hack because waiting for a lock in a Ruby thread blocks the
- # process
- period = 0.001
- until flock(LOCK_SH|LOCK_NB)
- sleep period
- period *= 2 if period < 1
- end
- end
-
- yield self
- ensure
- Thread.exclusive {flock(LOCK_UN) if $reader_count[self.stat.ino] == 1}
- ## for solaris, no need to unlock here--closing does it
- ## but this has no effect on the bug
+ yield self
+ ensure
+ flush
+ flock(LOCK_UN)
+ end
+
+ # Get a shared (i.e., read) lock on the file, and yield to the block.
+ # If the lock is not available, wait for it without blocking other ruby
+ # threads.
+ def lock_shared
+ if Thread.list.size == 1
+ flock(LOCK_SH)
+ else
+ # ugly hack because waiting for a lock in a Ruby thread blocks the
+ # process
+ period = 0.001
+ until flock(LOCK_SH|LOCK_NB)
+ sleep period
+ period *= 2 if period < 1
+ end
end
+
+ yield self
+ ensure
+ Thread.exclusive {flock(LOCK_UN) if $reader_count[self.stat.ino] == 1}
+ ## for solaris, no need to unlock here--closing does it
+ ## but this has no effect on the bug
+ end
end
diff --git a/lib/puppet/external/nagios.rb b/lib/puppet/external/nagios.rb
index 2dd040d..6b8852e 100755
--- a/lib/puppet/external/nagios.rb
+++ b/lib/puppet/external/nagios.rb
@@ -12,39 +12,39 @@ require 'puppet/external/nagios/parser.rb'
require 'puppet/external/nagios/base.rb'
module Nagios
- NAGIOSVERSION = '1.1'
- # yay colors
- PINK = "[0;31m"
- GREEN = "[0;32m"
- YELLOW = "[0;33m"
- SLATE = "[0;34m"
- ORANGE = "[0;35m"
- BLUE = "[0;36m"
- NOCOLOR = "[0m"
- RESET = "[0m"
-
- def self.version
- NAGIOSVERSION
+ NAGIOSVERSION = '1.1'
+ # yay colors
+ PINK = "[0;31m"
+ GREEN = "[0;32m"
+ YELLOW = "[0;33m"
+ SLATE = "[0;34m"
+ ORANGE = "[0;35m"
+ BLUE = "[0;36m"
+ NOCOLOR = "[0m"
+ RESET = "[0m"
+
+ def self.version
+ NAGIOSVERSION
+ end
+
+ class Config
+ def Config.import(config)
+
+ text = String.new
+
+ File.open(config) { |file|
+ file.each { |line|
+ text += line
+ }
+ }
+ parser = Nagios::Parser.new
+ parser.parse(text)
end
- class Config
- def Config.import(config)
-
- text = String.new
-
- File.open(config) { |file|
- file.each { |line|
- text += line
- }
- }
- parser = Nagios::Parser.new
- parser.parse(text)
- end
-
- def Config.each
- Nagios::Object.objects.each { |object|
- yield object
- }
- end
+ def Config.each
+ Nagios::Object.objects.each { |object|
+ yield object
+ }
end
+ end
end
diff --git a/lib/puppet/external/nagios/base.rb b/lib/puppet/external/nagios/base.rb
index 6e3b003..ac1d25e 100755
--- a/lib/puppet/external/nagios/base.rb
+++ b/lib/puppet/external/nagios/base.rb
@@ -2,472 +2,472 @@
# is mostly just data.
class Nagios::Base
- class UnknownNagiosType < RuntimeError # When an unknown type is asked for by name.
- end
-
- include Enumerable
-
- class << self
- attr_accessor :parameters, :derivatives, :ocs, :name, :att
- attr_accessor :ldapbase
-
- attr_writer :namevar
-
- attr_reader :superior
- end
-
- # Attach one class to another.
- def self.attach(hash)
- @attach ||= {}
- hash.each do |n, v| @attach[n] = v end
- end
-
- # Convert a parameter to camelcase
- def self.camelcase(param)
- param.gsub(/_./) do |match|
- match.sub(/_/,'').capitalize
- end
- end
-
- # Uncamelcase a parameter.
- def self.decamelcase(param)
- param.gsub(/[A-Z]/) do |match|
- "_#{match.downcase}"
- end
- end
-
- # Create a new instance of a given class.
- def self.create(name, args = {})
- name = name.intern if name.is_a? String
-
- if @types.include?(name)
- @types[name].new(args)
- else
- raise UnknownNagiosType, "Unknown type #{name}"
- end
- end
-
- # Yield each type in turn.
- def self.eachtype
- @types.each do |name, type|
- yield [name, type]
- end
- end
-
- # Create a mapping.
- def self.map(hash)
- @map ||= {}
- hash.each do |n, v| @map[n] = v end
- end
-
- # Return a mapping (or nil) for a param
- def self.mapping(name)
- name = name.intern if name.is_a? String
- if defined?(@map)
- @map[name]
- else
- nil
- end
- end
-
- # Return the namevar for the canonical name.
- def self.namevar
- if defined?(@namevar)
- return @namevar
- else
- if parameter?(:name)
- return :name
- elsif tmp = (self.name.to_s + "_name").intern and parameter?(tmp)
- @namevar = tmp
- return @namevar
- else
- raise "Type #{self.name} has no name var"
- end
- end
- end
-
- # Create a new type.
- def self.newtype(name, &block)
- name = name.intern if name.is_a? String
-
- @types ||= {}
-
- # Create the class, with the correct name.
- t = Class.new(self)
- t.name = name
-
- # Everyone gets this. There should probably be a better way, and I
- # should probably hack the attribute system to look things up based on
- # this "use" setting, but, eh.
- t.parameters = [:use]
-
- const_set(name.to_s.capitalize,t)
-
- # Evaluate the passed block. This should usually define all of the work.
- t.class_eval(&block)
-
- @types[name] = t
- end
-
- # Define both the normal case and camelcase method for a parameter
- def self.paramattr(name)
- camel = camelcase(name)
- param = name
-
- [name, camel].each do |method|
- define_method(method) do
- @parameters[param]
- end
-
- define_method(method.to_s + "=") do |value|
- @parameters[param] = value
- end
- end
-
- end
-
- # Is the specified name a valid parameter?
- def self.parameter?(name)
- name = name.intern if name.is_a? String
- @parameters.include?(name)
- end
-
- # Manually set the namevar
- def self.setnamevar(name)
- name = name.intern if name.is_a? String
- @namevar = name
- end
-
- # Set the valid parameters for this class
- def self.setparameters(*array)
- @parameters += array
- end
-
- # Set the superior ldap object class. Seems silly to include this
- # in this class, but, eh.
- def self.setsuperior(name)
- @superior = name
- end
-
- # Parameters to suppress in output.
- def self.suppress(name)
- @suppress ||= []
- @suppress << name
- end
-
- # Whether a given parameter is suppressed.
- def self.suppress?(name)
- defined?(@suppress) and @suppress.include?(name)
- end
-
- # Return our name as the string.
- def self.to_s
- self.name.to_s
- end
-
- # Return a type by name.
- def self.type(name)
- name = name.intern if name.is_a? String
-
- @types[name]
- end
+ class UnknownNagiosType < RuntimeError # When an unknown type is asked for by name.
+ end
- # Convenience methods.
- def [](param)
- send(param)
- end
-
- # Convenience methods.
- def []=(param,value)
- send(param.to_s + "=", value)
- end
+ include Enumerable
- # Iterate across all ofour set parameters.
- def each
- @parameters.each { |param,value|
- yield(param,value)
- }
- end
+ class << self
+ attr_accessor :parameters, :derivatives, :ocs, :name, :att
+ attr_accessor :ldapbase
- # Initialize our object, optionally with a list of parameters.
- def initialize(args = {})
- @parameters = {}
+ attr_writer :namevar
- args.each { |param,value|
- self[param] = value
- }
- if @namevar == :_naginator_name
- self['_naginator_name'] = self['name']
- end
- end
+ attr_reader :superior
+ end
- # Handle parameters like attributes.
- def method_missing(mname, *args)
- pname = mname.to_s
- pname.sub!(/=/, '')
-
- if self.class.parameter?(pname)
- if pname =~ /A-Z/
- pname = self.class.decamelcase(pname)
- end
- self.class.paramattr(pname)
-
- # Now access the parameters directly, to make it at least less
- # likely we'll end up in an infinite recursion.
- if mname.to_s =~ /=$/
- @parameters[pname] = *args
- else
- return @parameters[mname]
- end
- else
- super
- end
+ # Attach one class to another.
+ def self.attach(hash)
+ @attach ||= {}
+ hash.each do |n, v| @attach[n] = v end
+ end
+
+ # Convert a parameter to camelcase
+ def self.camelcase(param)
+ param.gsub(/_./) do |match|
+ match.sub(/_/,'').capitalize
end
+ end
- # Retrieve our name, through a bit of redirection.
- def name
- send(self.class.namevar)
+ # Uncamelcase a parameter.
+ def self.decamelcase(param)
+ param.gsub(/[A-Z]/) do |match|
+ "_#{match.downcase}"
end
+ end
- # This is probably a bad idea.
- def name=(value)
- unless self.class.namevar.to_s == "name"
- send(self.class.namevar.to_s + "=", value)
- end
- end
+ # Create a new instance of a given class.
+ def self.create(name, args = {})
+ name = name.intern if name.is_a? String
- def namevar
- (self.type + "_name").intern
+ if @types.include?(name)
+ @types[name].new(args)
+ else
+ raise UnknownNagiosType, "Unknown type #{name}"
end
-
- def parammap(param)
- unless defined?(@map)
- map = {
- self.namevar => "cn"
- }
- map.update(self.class.map) if self.class.map
- end
- if map.include?(param)
- return map[param]
+ end
+
+ # Yield each type in turn.
+ def self.eachtype
+ @types.each do |name, type|
+ yield [name, type]
+ end
+ end
+
+ # Create a mapping.
+ def self.map(hash)
+ @map ||= {}
+ hash.each do |n, v| @map[n] = v end
+ end
+
+ # Return a mapping (or nil) for a param
+ def self.mapping(name)
+ name = name.intern if name.is_a? String
+ if defined?(@map)
+ @map[name]
+ else
+ nil
+ end
+ end
+
+ # Return the namevar for the canonical name.
+ def self.namevar
+ if defined?(@namevar)
+ return @namevar
+ else
+ if parameter?(:name)
+ return :name
+ elsif tmp = (self.name.to_s + "_name").intern and parameter?(tmp)
+ @namevar = tmp
+ return @namevar
+ else
+ raise "Type #{self.name} has no name var"
+ end
+ end
+ end
+
+ # Create a new type.
+ def self.newtype(name, &block)
+ name = name.intern if name.is_a? String
+
+ @types ||= {}
+
+ # Create the class, with the correct name.
+ t = Class.new(self)
+ t.name = name
+
+ # Everyone gets this. There should probably be a better way, and I
+ # should probably hack the attribute system to look things up based on
+ # this "use" setting, but, eh.
+ t.parameters = [:use]
+
+ const_set(name.to_s.capitalize,t)
+
+ # Evaluate the passed block. This should usually define all of the work.
+ t.class_eval(&block)
+
+ @types[name] = t
+ end
+
+ # Define both the normal case and camelcase method for a parameter
+ def self.paramattr(name)
+ camel = camelcase(name)
+ param = name
+
+ [name, camel].each do |method|
+ define_method(method) do
+ @parameters[param]
+ end
+
+ define_method(method.to_s + "=") do |value|
+ @parameters[param] = value
+ end
+ end
+
+ end
+
+ # Is the specified name a valid parameter?
+ def self.parameter?(name)
+ name = name.intern if name.is_a? String
+ @parameters.include?(name)
+ end
+
+ # Manually set the namevar
+ def self.setnamevar(name)
+ name = name.intern if name.is_a? String
+ @namevar = name
+ end
+
+ # Set the valid parameters for this class
+ def self.setparameters(*array)
+ @parameters += array
+ end
+
+ # Set the superior ldap object class. Seems silly to include this
+ # in this class, but, eh.
+ def self.setsuperior(name)
+ @superior = name
+ end
+
+ # Parameters to suppress in output.
+ def self.suppress(name)
+ @suppress ||= []
+ @suppress << name
+ end
+
+ # Whether a given parameter is suppressed.
+ def self.suppress?(name)
+ defined?(@suppress) and @suppress.include?(name)
+ end
+
+ # Return our name as the string.
+ def self.to_s
+ self.name.to_s
+ end
+
+ # Return a type by name.
+ def self.type(name)
+ name = name.intern if name.is_a? String
+
+ @types[name]
+ end
+
+ # Convenience methods.
+ def [](param)
+ send(param)
+ end
+
+ # Convenience methods.
+ def []=(param,value)
+ send(param.to_s + "=", value)
+ end
+
+ # Iterate across all ofour set parameters.
+ def each
+ @parameters.each { |param,value|
+ yield(param,value)
+ }
+ end
+
+ # Initialize our object, optionally with a list of parameters.
+ def initialize(args = {})
+ @parameters = {}
+
+ args.each { |param,value|
+ self[param] = value
+ }
+ if @namevar == :_naginator_name
+ self['_naginator_name'] = self['name']
+ end
+ end
+
+ # Handle parameters like attributes.
+ def method_missing(mname, *args)
+ pname = mname.to_s
+ pname.sub!(/=/, '')
+
+ if self.class.parameter?(pname)
+ if pname =~ /A-Z/
+ pname = self.class.decamelcase(pname)
+ end
+ self.class.paramattr(pname)
+
+ # Now access the parameters directly, to make it at least less
+ # likely we'll end up in an infinite recursion.
+ if mname.to_s =~ /=$/
+ @parameters[pname] = *args
+ else
+ return @parameters[mname]
+ end
+ else
+ super
+ end
+ end
+
+ # Retrieve our name, through a bit of redirection.
+ def name
+ send(self.class.namevar)
+ end
+
+ # This is probably a bad idea.
+ def name=(value)
+ unless self.class.namevar.to_s == "name"
+ send(self.class.namevar.to_s + "=", value)
+ end
+ end
+
+ def namevar
+ (self.type + "_name").intern
+ end
+
+ def parammap(param)
+ unless defined?(@map)
+ map = {
+ self.namevar => "cn"
+ }
+ map.update(self.class.map) if self.class.map
+ end
+ if map.include?(param)
+ return map[param]
+ else
+ return "nagios-" + param.id2name.gsub(/_/,'-')
+ end
+ end
+
+ def parent
+ unless defined?(self.class.attached)
+ puts "Duh, you called parent on an unattached class"
+ return
+ end
+
+ klass,param = self.class.attached
+ unless @parameters.include?(param)
+ puts "Huh, no attachment param"
+ return
+ end
+ klass[@parameters[param]]
+ end
+
+ # okay, this sucks
+ # how do i get my list of ocs?
+ def to_ldif
+ base = self.class.ldapbase
+ str = self.dn + "\n"
+ ocs = Array.new
+ if self.class.ocs
+ # i'm storing an array, so i have to flatten it and stuff
+ kocs = self.class.ocs
+ ocs.push(*kocs)
+ end
+ ocs.push "top"
+ oc = self.class.to_s
+ oc.sub!(/Nagios/,'nagios')
+ oc.sub!(/::/,'')
+ ocs.push oc
+ ocs.each { |oc|
+ str += "objectclass: #{oc}\n"
+ }
+ @parameters.each { |name,value|
+ next if self.class.suppress.include?(name)
+ ldapname = self.parammap(name)
+ str += ldapname + ": #{value}\n"
+ }
+ str += "\n"
+ end
+
+ def to_s
+ str = "define #{self.type} {\n"
+
+ self.each { |param,value|
+ str += %{\t%-30s %s\n} % [ param,
+ if value.is_a? Array
+ value.join(",")
else
- return "nagios-" + param.id2name.gsub(/_/,'-')
- end
- end
-
- def parent
- unless defined?(self.class.attached)
- puts "Duh, you called parent on an unattached class"
- return
- end
-
- klass,param = self.class.attached
- unless @parameters.include?(param)
- puts "Huh, no attachment param"
- return
- end
- klass[@parameters[param]]
- end
-
- # okay, this sucks
- # how do i get my list of ocs?
- def to_ldif
- base = self.class.ldapbase
- str = self.dn + "\n"
- ocs = Array.new
- if self.class.ocs
- # i'm storing an array, so i have to flatten it and stuff
- kocs = self.class.ocs
- ocs.push(*kocs)
+ value
end
- ocs.push "top"
- oc = self.class.to_s
- oc.sub!(/Nagios/,'nagios')
- oc.sub!(/::/,'')
- ocs.push oc
- ocs.each { |oc|
- str += "objectclass: #{oc}\n"
- }
- @parameters.each { |name,value|
- next if self.class.suppress.include?(name)
- ldapname = self.parammap(name)
- str += ldapname + ": #{value}\n"
- }
- str += "\n"
- end
-
- def to_s
- str = "define #{self.type} {\n"
-
- self.each { |param,value|
- str += %{\t%-30s %s\n} % [ param,
- if value.is_a? Array
- value.join(",")
- else
- value
- end
- ]
- }
-
- str += "}\n"
-
- str
- end
-
- # The type of object we are.
- def type
- self.class.name
- end
-
- # object types
- newtype :host do
- setparameters :host_name, :alias, :display_name, :address, :parents,
- :hostgroups, :check_command, :initial_state, :max_check_attempts,
- :check_interval, :retry_interval, :active_checks_enabled,
- :passive_checks_enabled, :check_period, :obsess_over_host,
- :check_freshness, :freshness_threshold, :event_handler,
- :event_handler_enabled, :low_flap_threshold, :high_flap_threshold,
- :flap_detection_enabled, :flap_detection_options,
- :failure_prediction_enabled, :process_perf_data,
- :retain_status_information, :retain_nonstatus_information, :contacts,
- :contact_groups, :notification_interval, :first_notification_delay,
- :notification_period, :notification_options, :notifications_enabled,
- :stalking_options, :notes, :notes_url, :action_url, :icon_image,
- :icon_image_alt, :vrml_image, :statusmap_image, "2d_coords".intern,
- "3d_coords".intern,
- :register, :use
-
- setsuperior "person"
- map :address => "ipHostNumber"
- end
-
- newtype :hostgroup do
- setparameters :hostgroup_name, :alias, :members, :hostgroup_members, :notes,
- :notes_url, :action_url,
- :register, :use
- end
-
- newtype :service do
- attach :host => :host_name
- setparameters :host_name, :hostgroup_name, :service_description,
- :display_name, :servicegroups, :is_volatile, :check_command,
- :initial_state, :max_check_attempts, :check_interval, :retry_interval,
- :normal_check_interval, :retry_check_interval, :active_checks_enabled,
- :passive_checks_enabled, :parallelize_check, :check_period,
- :obsess_over_service, :check_freshness, :freshness_threshold,
- :event_handler, :event_handler_enabled, :low_flap_threshold,
- :high_flap_threshold, :flap_detection_enabled,:flap_detection_options,
- :process_perf_data, :failure_prediction_enabled, :retain_status_information,
- :retain_nonstatus_information, :notification_interval,
- :first_notification_delay, :notification_period, :notification_options,
- :notifications_enabled, :contacts, :contact_groups, :stalking_options,
- :notes, :notes_url, :action_url, :icon_image, :icon_image_alt,
- :register, :use,
- :_naginator_name
-
- suppress :host_name
-
- setnamevar :_naginator_name
- end
-
- newtype :servicegroup do
- setparameters :servicegroup_name, :alias, :members, :servicegroup_members,
- :notes, :notes_url, :action_url,
- :register, :use
- end
-
- newtype :contact do
- setparameters :contact_name, :alias, :contactgroups,
- :host_notifications_enabled, :service_notifications_enabled,
- :host_notification_period, :service_notification_period,
- :host_notification_options, :service_notification_options,
- :host_notification_commands, :service_notification_commands,
- :email, :pager, :address1, :address2, :address3, :address4,
- :address5, :address6, :can_submit_commands, :retain_status_information,
- :retain_nonstatus_information,
- :register, :use
-
- setsuperior "person"
- end
-
- newtype :contactgroup do
- setparameters :contactgroup_name, :alias, :members, :contactgroup_members,
- :register, :use
- end
-
- # TODO - We should support generic time periods here eg "day 1 - 15"
- newtype :timeperiod do
- setparameters :timeperiod_name, :alias, :sunday, :monday, :tuesday,
- :wednesday, :thursday, :friday, :saturday, :exclude,
- :register, :use
- end
-
- newtype :command do
- setparameters :command_name, :command_line
- end
-
- newtype :servicedependency do
- auxiliary = true
- setparameters :dependent_host_name, :dependent_hostgroup_name,
- :dependent_service_description, :host_name, :hostgroup_name,
- :service_description, :inherits_parent, :execution_failure_criteria,
- :notification_failure_criteria, :dependency_period,
- :register, :use,
- :_naginator_name
-
- setnamevar :_naginator_name
- end
-
- newtype :serviceescalation do
- setparameters :host_name, :hostgroup_name, :servicegroup_name,
- :service_description, :contacts, :contact_groups,
- :first_notification, :last_notification, :notification_interval,
- :escalation_period, :escalation_options,
- :register, :use,
- :_naginator_name
-
- setnamevar :_naginator_name
- end
-
- newtype :hostdependency do
- auxiliary = true
- setparameters :dependent_host_name, :dependent_hostgroup_name, :host_name,
- :hostgroup_name, :inherits_parent, :execution_failure_criteria,
- :notification_failure_criteria, :dependency_period,
- :register, :use,
- :_naginator_name
-
- setnamevar :_naginator_name
- end
-
- newtype :hostescalation do
- setparameters :host_name, :hostgroup_name, :contacts, :contact_groups,
- :first_notification, :last_notification, :notification_interval,
- :escalation_period, :escalation_options,
- :register, :use,
- :_naginator_name
-
- setnamevar :_naginator_name
- end
-
- newtype :hostextinfo do
- auxiliary = true
- setparameters :host_name, :notes, :notes_url, :icon_image, :icon_image_alt,
- :vrml_image, :statusmap_image, "2d_coords".intern, "3d_coords".intern,
- :register, :use
-
- setnamevar :host_name
- end
-
- newtype :serviceextinfo do
- auxiliary = true
-
- setparameters :host_name, :service_description, :notes, :notes_url,
- :action_url, :icon_image, :icon_image_alt,
- :register, :use,
- :_naginator_name
-
- setnamevar :_naginator_name
- end
+ ]
+ }
+
+ str += "}\n"
+
+ str
+ end
+
+ # The type of object we are.
+ def type
+ self.class.name
+ end
+
+ # object types
+ newtype :host do
+ setparameters :host_name, :alias, :display_name, :address, :parents,
+ :hostgroups, :check_command, :initial_state, :max_check_attempts,
+ :check_interval, :retry_interval, :active_checks_enabled,
+ :passive_checks_enabled, :check_period, :obsess_over_host,
+ :check_freshness, :freshness_threshold, :event_handler,
+ :event_handler_enabled, :low_flap_threshold, :high_flap_threshold,
+ :flap_detection_enabled, :flap_detection_options,
+ :failure_prediction_enabled, :process_perf_data,
+ :retain_status_information, :retain_nonstatus_information, :contacts,
+ :contact_groups, :notification_interval, :first_notification_delay,
+ :notification_period, :notification_options, :notifications_enabled,
+ :stalking_options, :notes, :notes_url, :action_url, :icon_image,
+ :icon_image_alt, :vrml_image, :statusmap_image, "2d_coords".intern,
+ "3d_coords".intern,
+ :register, :use
+
+ setsuperior "person"
+ map :address => "ipHostNumber"
+ end
+
+ newtype :hostgroup do
+ setparameters :hostgroup_name, :alias, :members, :hostgroup_members, :notes,
+ :notes_url, :action_url,
+ :register, :use
+ end
+
+ newtype :service do
+ attach :host => :host_name
+ setparameters :host_name, :hostgroup_name, :service_description,
+ :display_name, :servicegroups, :is_volatile, :check_command,
+ :initial_state, :max_check_attempts, :check_interval, :retry_interval,
+ :normal_check_interval, :retry_check_interval, :active_checks_enabled,
+ :passive_checks_enabled, :parallelize_check, :check_period,
+ :obsess_over_service, :check_freshness, :freshness_threshold,
+ :event_handler, :event_handler_enabled, :low_flap_threshold,
+ :high_flap_threshold, :flap_detection_enabled,:flap_detection_options,
+ :process_perf_data, :failure_prediction_enabled, :retain_status_information,
+ :retain_nonstatus_information, :notification_interval,
+ :first_notification_delay, :notification_period, :notification_options,
+ :notifications_enabled, :contacts, :contact_groups, :stalking_options,
+ :notes, :notes_url, :action_url, :icon_image, :icon_image_alt,
+ :register, :use,
+ :_naginator_name
+
+ suppress :host_name
+
+ setnamevar :_naginator_name
+ end
+
+ newtype :servicegroup do
+ setparameters :servicegroup_name, :alias, :members, :servicegroup_members,
+ :notes, :notes_url, :action_url,
+ :register, :use
+ end
+
+ newtype :contact do
+ setparameters :contact_name, :alias, :contactgroups,
+ :host_notifications_enabled, :service_notifications_enabled,
+ :host_notification_period, :service_notification_period,
+ :host_notification_options, :service_notification_options,
+ :host_notification_commands, :service_notification_commands,
+ :email, :pager, :address1, :address2, :address3, :address4,
+ :address5, :address6, :can_submit_commands, :retain_status_information,
+ :retain_nonstatus_information,
+ :register, :use
+
+ setsuperior "person"
+ end
+
+ newtype :contactgroup do
+ setparameters :contactgroup_name, :alias, :members, :contactgroup_members,
+ :register, :use
+ end
+
+ # TODO - We should support generic time periods here eg "day 1 - 15"
+ newtype :timeperiod do
+ setparameters :timeperiod_name, :alias, :sunday, :monday, :tuesday,
+ :wednesday, :thursday, :friday, :saturday, :exclude,
+ :register, :use
+ end
+
+ newtype :command do
+ setparameters :command_name, :command_line
+ end
+
+ newtype :servicedependency do
+ auxiliary = true
+ setparameters :dependent_host_name, :dependent_hostgroup_name,
+ :dependent_service_description, :host_name, :hostgroup_name,
+ :service_description, :inherits_parent, :execution_failure_criteria,
+ :notification_failure_criteria, :dependency_period,
+ :register, :use,
+ :_naginator_name
+
+ setnamevar :_naginator_name
+ end
+
+ newtype :serviceescalation do
+ setparameters :host_name, :hostgroup_name, :servicegroup_name,
+ :service_description, :contacts, :contact_groups,
+ :first_notification, :last_notification, :notification_interval,
+ :escalation_period, :escalation_options,
+ :register, :use,
+ :_naginator_name
+
+ setnamevar :_naginator_name
+ end
+
+ newtype :hostdependency do
+ auxiliary = true
+ setparameters :dependent_host_name, :dependent_hostgroup_name, :host_name,
+ :hostgroup_name, :inherits_parent, :execution_failure_criteria,
+ :notification_failure_criteria, :dependency_period,
+ :register, :use,
+ :_naginator_name
+
+ setnamevar :_naginator_name
+ end
+
+ newtype :hostescalation do
+ setparameters :host_name, :hostgroup_name, :contacts, :contact_groups,
+ :first_notification, :last_notification, :notification_interval,
+ :escalation_period, :escalation_options,
+ :register, :use,
+ :_naginator_name
+
+ setnamevar :_naginator_name
+ end
+
+ newtype :hostextinfo do
+ auxiliary = true
+ setparameters :host_name, :notes, :notes_url, :icon_image, :icon_image_alt,
+ :vrml_image, :statusmap_image, "2d_coords".intern, "3d_coords".intern,
+ :register, :use
+
+ setnamevar :host_name
+ end
+
+ newtype :serviceextinfo do
+ auxiliary = true
+
+ setparameters :host_name, :service_description, :notes, :notes_url,
+ :action_url, :icon_image, :icon_image_alt,
+ :register, :use,
+ :_naginator_name
+
+ setnamevar :_naginator_name
+ end
end
diff --git a/lib/puppet/external/nagios/parser.rb b/lib/puppet/external/nagios/parser.rb
index 43444cc..5504f58 100644
--- a/lib/puppet/external/nagios/parser.rb
+++ b/lib/puppet/external/nagios/parser.rb
@@ -27,420 +27,420 @@ self.class.module_eval <<'..end racc/parser.rb modeval..id5256434e8a', 'racc/par
NotImplementedError = NotImplementError unless defined?(NotImplementedError)
module Racc
- class ParseError < StandardError; end
+ class ParseError < StandardError; end
end
ParseError = Racc::ParseError unless defined?(::ParseError)
module Racc
- Racc_No_Extentions = false unless defined?(Racc_No_Extentions)
-
- class Parser
-
- Racc_Runtime_Version = '1.4.5'
- Racc_Runtime_Revision = '$Revision: 1.7 $'.split[1]
-
- Racc_Runtime_Core_Version_R = '1.4.5'
- Racc_Runtime_Core_Revision_R = '$Revision: 1.7 $'.split[1]
- begin
- require 'racc/cparse'
- # Racc_Runtime_Core_Version_C = (defined in extention)
- Racc_Runtime_Core_Revision_C = Racc_Runtime_Core_Id_C.split[2]
- raise LoadError, 'old cparse.so' unless new.respond_to?(:_racc_do_parse_c, true)
- raise LoadError, 'selecting ruby version of racc runtime core' if Racc_No_Extentions
-
- Racc_Main_Parsing_Routine = :_racc_do_parse_c
- Racc_YY_Parse_Method = :_racc_yyparse_c
- Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_C
- Racc_Runtime_Core_Revision = Racc_Runtime_Core_Revision_C
- Racc_Runtime_Type = 'c'
- rescue LoadError
- Racc_Main_Parsing_Routine = :_racc_do_parse_rb
- Racc_YY_Parse_Method = :_racc_yyparse_rb
- Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_R
- Racc_Runtime_Core_Revision = Racc_Runtime_Core_Revision_R
- Racc_Runtime_Type = 'ruby'
- end
-
- def Parser.racc_runtime_type
- Racc_Runtime_Type
- end
+ Racc_No_Extentions = false unless defined?(Racc_No_Extentions)
+
+ class Parser
+
+ Racc_Runtime_Version = '1.4.5'
+ Racc_Runtime_Revision = '$Revision: 1.7 $'.split[1]
+
+ Racc_Runtime_Core_Version_R = '1.4.5'
+ Racc_Runtime_Core_Revision_R = '$Revision: 1.7 $'.split[1]
+ begin
+ require 'racc/cparse'
+ # Racc_Runtime_Core_Version_C = (defined in extention)
+ Racc_Runtime_Core_Revision_C = Racc_Runtime_Core_Id_C.split[2]
+ raise LoadError, 'old cparse.so' unless new.respond_to?(:_racc_do_parse_c, true)
+ raise LoadError, 'selecting ruby version of racc runtime core' if Racc_No_Extentions
+
+ Racc_Main_Parsing_Routine = :_racc_do_parse_c
+ Racc_YY_Parse_Method = :_racc_yyparse_c
+ Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_C
+ Racc_Runtime_Core_Revision = Racc_Runtime_Core_Revision_C
+ Racc_Runtime_Type = 'c'
+ rescue LoadError
+ Racc_Main_Parsing_Routine = :_racc_do_parse_rb
+ Racc_YY_Parse_Method = :_racc_yyparse_rb
+ Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_R
+ Racc_Runtime_Core_Revision = Racc_Runtime_Core_Revision_R
+ Racc_Runtime_Type = 'ruby'
+ end
- private
+ def Parser.racc_runtime_type
+ Racc_Runtime_Type
+ end
- def _racc_setup
- @yydebug = false unless self.class::Racc_debug_parser
- @yydebug ||= false
- if @yydebug
- @racc_debug_out ||= $stderr
- @racc_debug_out ||= $stderr
- end
- arg = self.class::Racc_arg
- arg[13] = true if arg.size < 14
- arg
- end
+ private
+
+ def _racc_setup
+ @yydebug = false unless self.class::Racc_debug_parser
+ @yydebug ||= false
+ if @yydebug
+ @racc_debug_out ||= $stderr
+ @racc_debug_out ||= $stderr
+ end
+ arg = self.class::Racc_arg
+ arg[13] = true if arg.size < 14
+ arg
+ end
- def _racc_init_sysvars
- @racc_state = [0]
- @racc_tstack = []
- @racc_vstack = []
+ def _racc_init_sysvars
+ @racc_state = [0]
+ @racc_tstack = []
+ @racc_vstack = []
- @racc_t = nil
- @racc_val = nil
+ @racc_t = nil
+ @racc_val = nil
- @racc_read_next = true
+ @racc_read_next = true
- @racc_user_yyerror = false
- @racc_error_status = 0
- end
+ @racc_user_yyerror = false
+ @racc_error_status = 0
+ end
- ###
- ### do_parse
- ###
+ ###
+ ### do_parse
+ ###
- def do_parse
- __send__(Racc_Main_Parsing_Routine, _racc_setup, false)
- end
+ def do_parse
+ __send__(Racc_Main_Parsing_Routine, _racc_setup, false)
+ end
- def next_token
- raise NotImplementedError, "#{self.class}\#next_token is not defined"
- end
+ def next_token
+ raise NotImplementedError, "#{self.class}\#next_token is not defined"
+ end
- def _racc_do_parse_rb(arg, in_debug)
- action_table, action_check, action_default, action_pointer,
- goto_table, goto_check, goto_default, goto_pointer,
- nt_base, reduce_table, token_table, shift_n,
- reduce_n, use_result, * = arg
-
- _racc_init_sysvars
- tok = act = i = nil
- nerr = 0
-
- catch(:racc_end_parse) {
- while true
- if i = action_pointer[@racc_state[-1]]
- if @racc_read_next
- if @racc_t != 0 # not EOF
- tok, @racc_val = next_token
- unless tok # EOF
- @racc_t = 0
- else
- @racc_t = (token_table[tok] or 1) # error token
- end
- racc_read_token(@racc_t, tok, @racc_val) if @yydebug
- @racc_read_next = false
- end
- end
- i += @racc_t
- unless i >= 0 and
- act = action_table[i] and
- action_check[i] == @racc_state[-1]
- act = action_default[@racc_state[-1]]
- end
- else
- act = action_default[@racc_state[-1]]
- end
- while act = _racc_evalact(act, arg)
- ;
- end
+ def _racc_do_parse_rb(arg, in_debug)
+ action_table, action_check, action_default, action_pointer,
+ goto_table, goto_check, goto_default, goto_pointer,
+ nt_base, reduce_table, token_table, shift_n,
+ reduce_n, use_result, * = arg
+
+ _racc_init_sysvars
+ tok = act = i = nil
+ nerr = 0
+
+ catch(:racc_end_parse) {
+ while true
+ if i = action_pointer[@racc_state[-1]]
+ if @racc_read_next
+ if @racc_t != 0 # not EOF
+ tok, @racc_val = next_token
+ unless tok # EOF
+ @racc_t = 0
+ else
+ @racc_t = (token_table[tok] or 1) # error token
+ end
+ racc_read_token(@racc_t, tok, @racc_val) if @yydebug
+ @racc_read_next = false
end
- }
+ end
+ i += @racc_t
+ unless i >= 0 and
+ act = action_table[i] and
+ action_check[i] == @racc_state[-1]
+ act = action_default[@racc_state[-1]]
+ end
+ else
+ act = action_default[@racc_state[-1]]
end
+ while act = _racc_evalact(act, arg)
+ ;
+ end
+ end
+ }
+ end
+
+ ###
+ ### yyparse
+ ###
- ###
- ### yyparse
- ###
+ def yyparse(recv, mid)
+ __send__(Racc_YY_Parse_Method, recv, mid, _racc_setup, true)
+ end
- def yyparse(recv, mid)
- __send__(Racc_YY_Parse_Method, recv, mid, _racc_setup, true)
+ def _racc_yyparse_rb(recv, mid, arg, c_debug)
+ action_table, action_check, action_default, action_pointer,
+ goto_table, goto_check, goto_default, goto_pointer,
+ nt_base, reduce_table, token_table, shift_n,
+ reduce_n, use_result, * = arg
+
+ _racc_init_sysvars
+ tok = nil
+ act = nil
+ i = nil
+ nerr = 0
+
+ catch(:racc_end_parse) {
+ until i = action_pointer[@racc_state[-1]]
+ while act = _racc_evalact(action_default[@racc_state[-1]], arg)
+ ;
+ end
+ end
+ recv.__send__(mid) do |tok, val|
+ unless tok
+ @racc_t = 0
+ else
+ @racc_t = (token_table[tok] or 1) # error token
+ end
+ @racc_val = val
+ @racc_read_next = false
+
+ i += @racc_t
+ unless i >= 0 and
+ act = action_table[i] and
+ action_check[i] == @racc_state[-1]
+ act = action_default[@racc_state[-1]]
+ end
+ while act = _racc_evalact(act, arg)
+ ;
end
- def _racc_yyparse_rb(recv, mid, arg, c_debug)
- action_table, action_check, action_default, action_pointer,
- goto_table, goto_check, goto_default, goto_pointer,
- nt_base, reduce_table, token_table, shift_n,
- reduce_n, use_result, * = arg
-
- _racc_init_sysvars
- tok = nil
- act = nil
- i = nil
- nerr = 0
-
- catch(:racc_end_parse) {
- until i = action_pointer[@racc_state[-1]]
- while act = _racc_evalact(action_default[@racc_state[-1]], arg)
- ;
- end
- end
- recv.__send__(mid) do |tok, val|
- unless tok
- @racc_t = 0
- else
- @racc_t = (token_table[tok] or 1) # error token
- end
- @racc_val = val
- @racc_read_next = false
-
- i += @racc_t
- unless i >= 0 and
- act = action_table[i] and
- action_check[i] == @racc_state[-1]
- act = action_default[@racc_state[-1]]
- end
- while act = _racc_evalact(act, arg)
- ;
- end
-
- while not (i = action_pointer[@racc_state[-1]]) or
- not @racc_read_next or
- @racc_t == 0 # $
- unless i and i += @racc_t and
- i >= 0 and
- act = action_table[i] and
- action_check[i] == @racc_state[-1]
- act = action_default[@racc_state[-1]]
- end
- while act = _racc_evalact(act, arg)
- ;
- end
- end
- end
- }
+ while not (i = action_pointer[@racc_state[-1]]) or
+ not @racc_read_next or
+ @racc_t == 0 # $
+ unless i and i += @racc_t and
+ i >= 0 and
+ act = action_table[i] and
+ action_check[i] == @racc_state[-1]
+ act = action_default[@racc_state[-1]]
+ end
+ while act = _racc_evalact(act, arg)
+ ;
+ end
end
+ end
+ }
+ end
- ###
- ### common
- ###
-
- def _racc_evalact(act, arg)
- action_table, action_check, action_default, action_pointer,
- goto_table, goto_check, goto_default, goto_pointer,
- nt_base, reduce_table, token_table, shift_n,
- reduce_n, use_result, * = arg
- nerr = 0 # tmp
-
- if act > 0 and act < shift_n
- #
- # shift
- #
- if @racc_error_status > 0
- @racc_error_status -= 1 unless @racc_t == 1 # error token
- end
- @racc_vstack.push @racc_val
- @racc_state.push act
- @racc_read_next = true
- if @yydebug
- @racc_tstack.push @racc_t
- racc_shift @racc_t, @racc_tstack, @racc_vstack
- end
-
- elsif act < 0 and act > -reduce_n
- #
- # reduce
- #
- code = catch(:racc_jump) {
- @racc_state.push _racc_do_reduce(arg, act)
- false
- }
- if code
- case code
- when 1 # yyerror
- @racc_user_yyerror = true # user_yyerror
- return -reduce_n
- when 2 # yyaccept
- return shift_n
- else
- raise '[Racc Bug] unknown jump code'
- end
- end
-
- elsif act == shift_n
- #
- # accept
- #
- racc_accept if @yydebug
- throw :racc_end_parse, @racc_vstack[0]
-
- elsif act == -reduce_n
- #
- # error
- #
- case @racc_error_status
- when 0
- unless arg[21] # user_yyerror
- nerr += 1
- on_error @racc_t, @racc_val, @racc_vstack
- end
- when 3
- if @racc_t == 0 # is $
- throw :racc_end_parse, nil
- end
- @racc_read_next = true
- end
- @racc_user_yyerror = false
- @racc_error_status = 3
- while true
- if i = action_pointer[@racc_state[-1]]
- i += 1 # error token
- if i >= 0 and
- (act = action_table[i]) and
- action_check[i] == @racc_state[-1]
- break
- end
- end
- throw :racc_end_parse, nil if @racc_state.size <= 1
- @racc_state.pop
- @racc_vstack.pop
- if @yydebug
- @racc_tstack.pop
- racc_e_pop @racc_state, @racc_tstack, @racc_vstack
- end
- end
- return act
-
- else
- raise "[Racc Bug] unknown action #{act.inspect}"
- end
+ ###
+ ### common
+ ###
- racc_next_state(@racc_state[-1], @racc_state) if @yydebug
+ def _racc_evalact(act, arg)
+ action_table, action_check, action_default, action_pointer,
+ goto_table, goto_check, goto_default, goto_pointer,
+ nt_base, reduce_table, token_table, shift_n,
+ reduce_n, use_result, * = arg
+ nerr = 0 # tmp
- nil
+ if act > 0 and act < shift_n
+ #
+ # shift
+ #
+ if @racc_error_status > 0
+ @racc_error_status -= 1 unless @racc_t == 1 # error token
+ end
+ @racc_vstack.push @racc_val
+ @racc_state.push act
+ @racc_read_next = true
+ if @yydebug
+ @racc_tstack.push @racc_t
+ racc_shift @racc_t, @racc_tstack, @racc_vstack
end
- def _racc_do_reduce(arg, act)
- action_table, action_check, action_default, action_pointer,
- goto_table, goto_check, goto_default, goto_pointer,
- nt_base, reduce_table, token_table, shift_n,
- reduce_n, use_result, * = arg
- state = @racc_state
- vstack = @racc_vstack
- tstack = @racc_tstack
-
- i = act * -3
- len = reduce_table[i]
- reduce_to = reduce_table[i+1]
- method_id = reduce_table[i+2]
- void_array = []
-
- tmp_t = tstack[-len, len] if @yydebug
- tmp_v = vstack[-len, len]
- tstack[-len, len] = void_array if @yydebug
- vstack[-len, len] = void_array
- state[-len, len] = void_array
-
- # tstack must be updated AFTER method call
- if use_result
- vstack.push __send__(method_id, tmp_v, vstack, tmp_v[0])
- else
- vstack.push __send__(method_id, tmp_v, vstack)
- end
- tstack.push reduce_to
+ elsif act < 0 and act > -reduce_n
+ #
+ # reduce
+ #
+ code = catch(:racc_jump) {
+ @racc_state.push _racc_do_reduce(arg, act)
+ false
+ }
+ if code
+ case code
+ when 1 # yyerror
+ @racc_user_yyerror = true # user_yyerror
+ return -reduce_n
+ when 2 # yyaccept
+ return shift_n
+ else
+ raise '[Racc Bug] unknown jump code'
+ end
+ end
- racc_reduce(tmp_t, reduce_to, tstack, vstack) if @yydebug
+ elsif act == shift_n
+ #
+ # accept
+ #
+ racc_accept if @yydebug
+ throw :racc_end_parse, @racc_vstack[0]
- k1 = reduce_to - nt_base
- if i = goto_pointer[k1]
- i += state[-1]
- if i >= 0 and (curstate = goto_table[i]) and goto_check[i] == k1
- return curstate
- end
+ elsif act == -reduce_n
+ #
+ # error
+ #
+ case @racc_error_status
+ when 0
+ unless arg[21] # user_yyerror
+ nerr += 1
+ on_error @racc_t, @racc_val, @racc_vstack
+ end
+ when 3
+ if @racc_t == 0 # is $
+ throw :racc_end_parse, nil
+ end
+ @racc_read_next = true
+ end
+ @racc_user_yyerror = false
+ @racc_error_status = 3
+ while true
+ if i = action_pointer[@racc_state[-1]]
+ i += 1 # error token
+ if i >= 0 and
+ (act = action_table[i]) and
+ action_check[i] == @racc_state[-1]
+ break
end
- goto_default[k1]
+ end
+ throw :racc_end_parse, nil if @racc_state.size <= 1
+ @racc_state.pop
+ @racc_vstack.pop
+ if @yydebug
+ @racc_tstack.pop
+ racc_e_pop @racc_state, @racc_tstack, @racc_vstack
+ end
end
+ return act
- def on_error(t, val, vstack)
- raise ParseError, sprintf("\nparse error on value %s (%s)", val.inspect, token_to_str(t) || '?')
- end
+ else
+ raise "[Racc Bug] unknown action #{act.inspect}"
+ end
- def yyerror
- throw :racc_jump, 1
- end
+ racc_next_state(@racc_state[-1], @racc_state) if @yydebug
- def yyaccept
- throw :racc_jump, 2
- end
+ nil
+ end
- def yyerrok
- @racc_error_status = 0
+ def _racc_do_reduce(arg, act)
+ action_table, action_check, action_default, action_pointer,
+ goto_table, goto_check, goto_default, goto_pointer,
+ nt_base, reduce_table, token_table, shift_n,
+ reduce_n, use_result, * = arg
+ state = @racc_state
+ vstack = @racc_vstack
+ tstack = @racc_tstack
+
+ i = act * -3
+ len = reduce_table[i]
+ reduce_to = reduce_table[i+1]
+ method_id = reduce_table[i+2]
+ void_array = []
+
+ tmp_t = tstack[-len, len] if @yydebug
+ tmp_v = vstack[-len, len]
+ tstack[-len, len] = void_array if @yydebug
+ vstack[-len, len] = void_array
+ state[-len, len] = void_array
+
+ # tstack must be updated AFTER method call
+ if use_result
+ vstack.push __send__(method_id, tmp_v, vstack, tmp_v[0])
+ else
+ vstack.push __send__(method_id, tmp_v, vstack)
+ end
+ tstack.push reduce_to
+
+ racc_reduce(tmp_t, reduce_to, tstack, vstack) if @yydebug
+
+ k1 = reduce_to - nt_base
+ if i = goto_pointer[k1]
+ i += state[-1]
+ if i >= 0 and (curstate = goto_table[i]) and goto_check[i] == k1
+ return curstate
end
+ end
+ goto_default[k1]
+ end
- #
- # for debugging output
- #
+ def on_error(t, val, vstack)
+ raise ParseError, sprintf("\nparse error on value %s (%s)", val.inspect, token_to_str(t) || '?')
+ end
- def racc_read_token(t, tok, val)
- @racc_debug_out.print 'read '
- @racc_debug_out.print tok.inspect, '(', racc_token2str(t), ') '
- @racc_debug_out.puts val.inspect
- @racc_debug_out.puts
- end
+ def yyerror
+ throw :racc_jump, 1
+ end
- def racc_shift(tok, tstack, vstack)
- @racc_debug_out.puts "shift #{racc_token2str tok}"
- racc_print_stacks tstack, vstack
- @racc_debug_out.puts
- end
+ def yyaccept
+ throw :racc_jump, 2
+ end
- def racc_reduce(toks, sim, tstack, vstack)
- out = @racc_debug_out
- out.print 'reduce '
- if toks.empty?
- out.print ' <none>'
- else
- toks.each {|t| out.print ' ', racc_token2str(t) }
- end
- out.puts " --> #{racc_token2str(sim)}"
+ def yyerrok
+ @racc_error_status = 0
+ end
- racc_print_stacks tstack, vstack
- @racc_debug_out.puts
- end
+ #
+ # for debugging output
+ #
- def racc_accept
- @racc_debug_out.puts 'accept'
- @racc_debug_out.puts
- end
+ def racc_read_token(t, tok, val)
+ @racc_debug_out.print 'read '
+ @racc_debug_out.print tok.inspect, '(', racc_token2str(t), ') '
+ @racc_debug_out.puts val.inspect
+ @racc_debug_out.puts
+ end
- def racc_e_pop(state, tstack, vstack)
- @racc_debug_out.puts 'error recovering mode: pop token'
- racc_print_states state
- racc_print_stacks tstack, vstack
- @racc_debug_out.puts
- end
+ def racc_shift(tok, tstack, vstack)
+ @racc_debug_out.puts "shift #{racc_token2str tok}"
+ racc_print_stacks tstack, vstack
+ @racc_debug_out.puts
+ end
- def racc_next_state(curstate, state)
- @racc_debug_out.puts "goto #{curstate}"
- racc_print_states state
- @racc_debug_out.puts
- end
+ def racc_reduce(toks, sim, tstack, vstack)
+ out = @racc_debug_out
+ out.print 'reduce '
+ if toks.empty?
+ out.print ' <none>'
+ else
+ toks.each {|t| out.print ' ', racc_token2str(t) }
+ end
+ out.puts " --> #{racc_token2str(sim)}"
+
+ racc_print_stacks tstack, vstack
+ @racc_debug_out.puts
+ end
- def racc_print_stacks(t, v)
- out = @racc_debug_out
- out.print ' ['
- t.each_index do |i|
- out.print ' (', racc_token2str(t[i]), ' ', v[i].inspect, ')'
- end
- out.puts ' ]'
- end
+ def racc_accept
+ @racc_debug_out.puts 'accept'
+ @racc_debug_out.puts
+ end
- def racc_print_states(s)
- out = @racc_debug_out
- out.print ' ['
- s.each {|st| out.print ' ', st }
- out.puts ' ]'
- end
+ def racc_e_pop(state, tstack, vstack)
+ @racc_debug_out.puts 'error recovering mode: pop token'
+ racc_print_states state
+ racc_print_stacks tstack, vstack
+ @racc_debug_out.puts
+ end
- def racc_token2str(tok)
- self.class::Racc_token_to_s_table[tok] or
- raise "[Racc Bug] can't convert token #{tok} to string"
- end
+ def racc_next_state(curstate, state)
+ @racc_debug_out.puts "goto #{curstate}"
+ racc_print_states state
+ @racc_debug_out.puts
+ end
- def token_to_str(t)
- self.class::Racc_token_to_s_table[t]
- end
+ def racc_print_stacks(t, v)
+ out = @racc_debug_out
+ out.print ' ['
+ t.each_index do |i|
+ out.print ' (', racc_token2str(t[i]), ' ', v[i].inspect, ')'
+ end
+ out.puts ' ]'
+ end
+
+ def racc_print_states(s)
+ out = @racc_debug_out
+ out.print ' ['
+ s.each {|st| out.print ' ', st }
+ out.puts ' ]'
+ end
+
+ def racc_token2str(tok)
+ self.class::Racc_token_to_s_table[tok] or
+ raise "[Racc Bug] can't convert token #{tok} to string"
+ end
+ def token_to_str(t)
+ self.class::Racc_token_to_s_table[t]
end
+ end
+
end
..end racc/parser.rb modeval..id5256434e8a
end
@@ -449,172 +449,172 @@ end
module Nagios
- class Parser < Racc::Parser
+ class Parser < Racc::Parser
module_eval <<'..end grammar.ry modeval..idcb2ea30b34', 'grammar.ry', 57
class ::Nagios::Parser::SyntaxError < RuntimeError; end
def parse(src)
- @src = src
+ @src = src
- # state variables
- @invar = false
- @inobject = false
- @done = false
+ # state variables
+ @invar = false
+ @inobject = false
+ @done = false
- @line = 0
- @yydebug = true
+ @line = 0
+ @yydebug = true
- do_parse
+ do_parse
end
# The lexer. Very simple.
def token
- @src.sub!(/\A\n/,'')
- if $MATCH
- @line += 1
- return [ :RETURN, "\n" ]
- end
+ @src.sub!(/\A\n/,'')
+ if $MATCH
+ @line += 1
+ return [ :RETURN, "\n" ]
+ end
- return nil if @done
- yytext = String.new
+ return nil if @done
+ yytext = String.new
- # remove comments from this line
- @src.sub!(/\A[ \t]*;.*\n/,"\n")
- return [:INLINECOMMENT, ""] if $MATCH
+ # remove comments from this line
+ @src.sub!(/\A[ \t]*;.*\n/,"\n")
+ return [:INLINECOMMENT, ""] if $MATCH
- @src.sub!(/\A#.*\n/,"\n")
- return [:COMMENT, ""] if $MATCH
+ @src.sub!(/\A#.*\n/,"\n")
+ return [:COMMENT, ""] if $MATCH
- @src.sub!(/#.*/,'')
+ @src.sub!(/#.*/,'')
- if @src.length == 0
- @done = true
- return [false, '$']
- end
+ if @src.length == 0
+ @done = true
+ return [false, '$']
+ end
- if @invar
- @src.sub!(/\A[ \t]+/,'')
- @src.sub!(/\A([^;\n]+)(\n|;)/,'\2')
- if $1
- yytext += $1
- end
- @invar = false
- return [:VALUE, yytext]
- else
- @src.sub!(/\A[\t ]*(\S+)([\t ]*|$)/,'')
- if $1
- yytext = $1
- case yytext
- when 'define'
- #puts "got define"
- return [:DEFINE, yytext]
- when '{'
- #puts "got {"
- @inobject = true
- return [:LCURLY, yytext]
- else
- unless @inobject
- #puts "got type: #{yytext}"
- if yytext =~ /\W/
- giveback = yytext.dup
- giveback.sub!(/^\w+/,'')
- #puts "giveback #{giveback}"
- #puts "yytext #{yytext}"
- yytext.sub!(/\W.*$/,'')
- #puts "yytext #{yytext}"
- #puts "all [#{giveback} #{yytext} #{orig}]"
- @src = giveback + @src
- end
- return [:NAME, yytext]
- else
- if yytext == '}'
- #puts "got closure: #{yytext}"
- @inobject = false
- return [:RCURLY, '}']
- end
-
- unless @invar
- @invar = true
- return [:PARAM, $1]
- else
- end
- end
- end
+ if @invar
+ @src.sub!(/\A[ \t]+/,'')
+ @src.sub!(/\A([^;\n]+)(\n|;)/,'\2')
+ if $1
+ yytext += $1
end
+ @invar = false
+ return [:VALUE, yytext]
+ else
+ @src.sub!(/\A[\t ]*(\S+)([\t ]*|$)/,'')
+ if $1
+ yytext = $1
+ case yytext
+ when 'define'
+ #puts "got define"
+ return [:DEFINE, yytext]
+ when '{'
+ #puts "got {"
+ @inobject = true
+ return [:LCURLY, yytext]
+ else
+ unless @inobject
+ #puts "got type: #{yytext}"
+ if yytext =~ /\W/
+ giveback = yytext.dup
+ giveback.sub!(/^\w+/,'')
+ #puts "giveback #{giveback}"
+ #puts "yytext #{yytext}"
+ yytext.sub!(/\W.*$/,'')
+ #puts "yytext #{yytext}"
+ #puts "all [#{giveback} #{yytext} #{orig}]"
+ @src = giveback + @src
+ end
+ return [:NAME, yytext]
+ else
+ if yytext == '}'
+ #puts "got closure: #{yytext}"
+ @inobject = false
+ return [:RCURLY, '}']
+ end
+
+ unless @invar
+ @invar = true
+ return [:PARAM, $1]
+ else
+ end
end
+ end
+ end
+ end
end
def next_token
- token
+ token
end
def yydebug
- 1
+ 1
end
def yywrap
- 0
+ 0
end
def on_error(token, value, vstack )
- msg = ""
- unless value.nil?
- msg = "line #{@line}: syntax error at '#{value}'"
- else
- msg = "line #{@line}: syntax error at '#{token}'"
- end
- msg = "line #{@line}: Unexpected end of file" unless @src.size > 0
- if token == '$end'.intern
- puts "okay, this is silly"
- else
- raise ::Nagios::Parser::SyntaxError, msg
- end
+ msg = ""
+ unless value.nil?
+ msg = "line #{@line}: syntax error at '#{value}'"
+ else
+ msg = "line #{@line}: syntax error at '#{token}'"
+ end
+ msg = "line #{@line}: Unexpected end of file" unless @src.size > 0
+ if token == '$end'.intern
+ puts "okay, this is silly"
+ else
+ raise ::Nagios::Parser::SyntaxError, msg
+ end
end
..end grammar.ry modeval..idcb2ea30b34
##### racc 1.4.5 generates ###
racc_reduce_table = [
- 0, 0, :racc_error,
- 1, 13, :_reduce_1,
- 2, 13, :_reduce_2,
- 1, 14, :_reduce_3,
- 1, 14, :_reduce_4,
- 1, 14, :_reduce_none,
- 2, 16, :_reduce_6,
- 6, 15, :_reduce_7,
- 1, 17, :_reduce_none,
- 2, 17, :_reduce_9,
- 4, 18, :_reduce_10,
- 1, 20, :_reduce_none,
- 2, 20, :_reduce_none,
- 0, 19, :_reduce_none,
- 1, 19, :_reduce_none ]
+ 0, 0, :racc_error,
+ 1, 13, :_reduce_1,
+ 2, 13, :_reduce_2,
+ 1, 14, :_reduce_3,
+ 1, 14, :_reduce_4,
+ 1, 14, :_reduce_none,
+ 2, 16, :_reduce_6,
+ 6, 15, :_reduce_7,
+ 1, 17, :_reduce_none,
+ 2, 17, :_reduce_9,
+ 4, 18, :_reduce_10,
+ 1, 20, :_reduce_none,
+ 2, 20, :_reduce_none,
+ 0, 19, :_reduce_none,
+ 1, 19, :_reduce_none ]
racc_reduce_n = 15
racc_shift_n = 26
racc_action_table = [
- 9, 15, 1, 20, 1, 14, 12, 13, 11, 6,
- 7, 6, 7, 15, 18, 8, 21, 23, 25 ]
+ 9, 15, 1, 20, 1, 14, 12, 13, 11, 6,
+ 7, 6, 7, 15, 18, 8, 21, 23, 25 ]
racc_action_check = [
- 2, 16, 2, 16, 0, 12, 8, 9, 7, 2,
- 2, 0, 0, 14, 15, 1, 18, 22, 24 ]
+ 2, 16, 2, 16, 0, 12, 8, 9, 7, 2,
+ 2, 0, 0, 14, 15, 1, 18, 22, 24 ]
racc_action_pointer = [
- 2, 12, 0, nil, nil, nil, nil, -1, 0, 7,
- nil, nil, -4, nil, 8, 6, -4, nil, 5, nil,
- nil, nil, 8, nil, 9, nil ]
+ 2, 12, 0, nil, nil, nil, nil, -1, 0, 7,
+ nil, nil, -4, nil, 8, 6, -4, nil, 5, nil,
+ nil, nil, 8, nil, 9, nil ]
racc_action_default = [
- -15, -15, -15, -1, -3, -5, -4, -15, -15, -15,
- -2, -6, -15, 26, -15, -15, -15, -8, -13, -9,
- -7, -14, -15, -11, -10, -12 ]
+ -15, -15, -15, -1, -3, -5, -4, -15, -15, -15,
+ -2, -6, -15, 26, -15, -15, -15, -8, -13, -9,
+ -7, -14, -15, -11, -10, -12 ]
racc_goto_table = [ 17, 3, 19, 10, 2, 16, 22, 24 ]
@@ -625,38 +625,38 @@ racc_goto_pointer = [ nil, 4, 1, nil, nil, -9, -14, -12, -1
racc_goto_default = [ nil, nil, nil, 4, 5, nil, nil, nil, nil ]
racc_token_table = {
- false => 0,
- Object.new => 1,
- :DEFINE => 2,
- :NAME => 3,
- :STRING => 4,
- :PARAM => 5,
- :LCURLY => 6,
- :RCURLY => 7,
- :VALUE => 8,
- :RETURN => 9,
- :COMMENT => 10,
- :INLINECOMMENT => 11 }
+ false => 0,
+ Object.new => 1,
+ :DEFINE => 2,
+ :NAME => 3,
+ :STRING => 4,
+ :PARAM => 5,
+ :LCURLY => 6,
+ :RCURLY => 7,
+ :VALUE => 8,
+ :RETURN => 9,
+ :COMMENT => 10,
+ :INLINECOMMENT => 11 }
racc_use_result_var = true
racc_nt_base = 12
Racc_arg = [
- racc_action_table,
- racc_action_check,
- racc_action_default,
- racc_action_pointer,
- racc_goto_table,
- racc_goto_check,
- racc_goto_default,
- racc_goto_pointer,
- racc_nt_base,
- racc_reduce_table,
- racc_token_table,
- racc_shift_n,
- racc_reduce_n,
- racc_use_result_var ]
+ racc_action_table,
+ racc_action_check,
+ racc_action_default,
+ racc_action_pointer,
+ racc_goto_table,
+ racc_goto_check,
+ racc_goto_default,
+ racc_goto_pointer,
+ racc_nt_base,
+ racc_reduce_table,
+ racc_token_table,
+ racc_shift_n,
+ racc_reduce_n,
+ racc_use_result_var ]
Racc_token_to_s_table = [
'$end',
@@ -688,73 +688,73 @@ Racc_debug_parser = false
# reduce 0 omitted
module_eval <<'.,.,', 'grammar.ry', 6
- def _reduce_1( val, _values, result )
+ def _reduce_1( val, _values, result )
return val[0] if val[0]
- result
+ result
end
.,.,
module_eval <<'.,.,', 'grammar.ry', 18
- def _reduce_2( val, _values, result )
- if val[1].nil?
- result = val[0]
- else
- if val[0].nil?
- result = val[1]
- else
- result = [ val[0], val[1] ].flatten
- end
- end
- result
- end
+ def _reduce_2( val, _values, result )
+ if val[1].nil?
+ result = val[0]
+ else
+ if val[0].nil?
+ result = val[1]
+ else
+ result = [ val[0], val[1] ].flatten
+ end
+ end
+ result
+ end
.,.,
module_eval <<'.,.,', 'grammar.ry', 20
- def _reduce_3( val, _values, result )
+ def _reduce_3( val, _values, result )
result = [val[0]]
- result
+ result
end
.,.,
module_eval <<'.,.,', 'grammar.ry', 21
- def _reduce_4( val, _values, result )
+ def _reduce_4( val, _values, result )
result = nil
- result
+ result
end
.,.,
# reduce 5 omitted
module_eval <<'.,.,', 'grammar.ry', 25
- def _reduce_6( val, _values, result )
+ def _reduce_6( val, _values, result )
result = nil
- result
+ result
end
.,.,
module_eval <<'.,.,', 'grammar.ry', 31
- def _reduce_7( val, _values, result )
- result = Nagios::Base.create(val[1],val[4])
- result
- end
+ def _reduce_7( val, _values, result )
+ result = Nagios::Base.create(val[1],val[4])
+ result
+ end
.,.,
# reduce 8 omitted
module_eval <<'.,.,', 'grammar.ry', 40
- def _reduce_9( val, _values, result )
- val[1].each {|p,v|
- val[0][p] = v
- }
- result = val[0]
- result
- end
+ def _reduce_9( val, _values, result )
+ val[1].each {|p,v|
+ val[0][p] = v
+ }
+ result = val[0]
+ result
+ end
.,.,
module_eval <<'.,.,', 'grammar.ry', 42
- def _reduce_10( val, _values, result )
+ def _reduce_10( val, _values, result )
result = {val[0],val[1]}
- result
+ result
end
.,.,
@@ -767,9 +767,9 @@ end
# reduce 14 omitted
def _reduce_none( val, _values, result )
- result
+ result
end
- end
+ end
end
diff --git a/lib/puppet/external/pson/common.rb b/lib/puppet/external/pson/common.rb
index 17da5ad..160a502 100644
--- a/lib/puppet/external/pson/common.rb
+++ b/lib/puppet/external/pson/common.rb
@@ -1,370 +1,370 @@
require 'puppet/external/pson/version'
module PSON
- class << self
- # If _object_ is string-like parse the string and return the parsed result
- # as a Ruby data structure. Otherwise generate a PSON text from the Ruby
- # data structure object and return it.
- #
- # The _opts_ argument is passed through to generate/parse respectively, see
- # generate and parse for their documentation.
- def [](object, opts = {})
- if object.respond_to? :to_str
- PSON.parse(object.to_str, opts => {})
- else
- PSON.generate(object, opts => {})
- end
- end
-
- # Returns the PSON parser class, that is used by PSON. This might be either
- # PSON::Ext::Parser or PSON::Pure::Parser.
- attr_reader :parser
-
- # Set the PSON parser class _parser_ to be used by PSON.
- def parser=(parser) # :nodoc:
- @parser = parser
- remove_const :Parser if const_defined? :Parser
- const_set :Parser, parser
- end
-
- def registered_document_types
- @registered_document_types ||= {}
- end
-
- # Register a class-constant for deserializaion.
- def register_document_type(name,klass)
- registered_document_types[name.to_s] = klass
- end
-
- # Return the constant located at _path_.
- # Anything may be registered as a path by calling register_path, above.
- # Otherwise, the format of _path_ has to be either ::A::B::C or A::B::C.
- # In either of these cases A has to be defined in Object (e.g. the path
- # must be an absolute namespace path. If the constant doesn't exist at
- # the given path, an ArgumentError is raised.
- def deep_const_get(path) # :nodoc:
- path = path.to_s
- registered_document_types[path] || path.split(/::/).inject(Object) do |p, c|
- case
- when c.empty? then p
- when p.const_defined?(c) then p.const_get(c)
- else raise ArgumentError, "can't find const for unregistered document type #{path}"
- end
- end
- end
-
- # Set the module _generator_ to be used by PSON.
- def generator=(generator) # :nodoc:
- @generator = generator
- generator_methods = generator::GeneratorMethods
- for const in generator_methods.constants
- klass = deep_const_get(const)
- modul = generator_methods.const_get(const)
- klass.class_eval do
- instance_methods(false).each do |m|
- m.to_s == 'to_pson' and remove_method m
- end
- include modul
- end
- end
- self.state = generator::State
- const_set :State, self.state
- end
-
- # Returns the PSON generator modul, that is used by PSON. This might be
- # either PSON::Ext::Generator or PSON::Pure::Generator.
- attr_reader :generator
-
- # Returns the PSON generator state class, that is used by PSON. This might
- # be either PSON::Ext::Generator::State or PSON::Pure::Generator::State.
- attr_accessor :state
-
- # This is create identifier, that is used to decide, if the _pson_create_
- # hook of a class should be called. It defaults to 'document_type'.
- attr_accessor :create_id
- end
- self.create_id = 'document_type'
-
- NaN = (-1.0) ** 0.5
-
- Infinity = 1.0/0
-
- MinusInfinity = -Infinity
-
- # The base exception for PSON errors.
- class PSONError < StandardError; end
-
- # This exception is raised, if a parser error occurs.
- class ParserError < PSONError; end
-
- # This exception is raised, if the nesting of parsed datastructures is too
- # deep.
- class NestingError < ParserError; end
-
- # This exception is raised, if a generator or unparser error occurs.
- class GeneratorError < PSONError; end
- # For backwards compatibility
- UnparserError = GeneratorError
-
- # If a circular data structure is encountered while unparsing
- # this exception is raised.
- class CircularDatastructure < GeneratorError; end
-
- # This exception is raised, if the required unicode support is missing on the
- # system. Usually this means, that the iconv library is not installed.
- class MissingUnicodeSupport < PSONError; end
-
- module_function
-
- # Parse the PSON string _source_ into a Ruby data structure and return it.
+ class << self
+ # If _object_ is string-like parse the string and return the parsed result
+ # as a Ruby data structure. Otherwise generate a PSON text from the Ruby
+ # data structure object and return it.
#
- # _opts_ can have the following
- # keys:
- # * *max_nesting*: The maximum depth of nesting allowed in the parsed data
- # structures. Disable depth checking with :max_nesting => false, it defaults
- # to 19.
- # * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
- # defiance of RFC 4627 to be parsed by the Parser. This option defaults
- # to false.
- # * *create_additions*: If set to false, the Parser doesn't create
- # additions even if a matchin class and create_id was found. This option
- # defaults to true.
- def parse(source, opts = {})
- PSON.parser.new(source, opts).parse
+ # The _opts_ argument is passed through to generate/parse respectively, see
+ # generate and parse for their documentation.
+ def [](object, opts = {})
+ if object.respond_to? :to_str
+ PSON.parse(object.to_str, opts => {})
+ else
+ PSON.generate(object, opts => {})
+ end
end
- # Parse the PSON string _source_ into a Ruby data structure and return it.
- # The bang version of the parse method, defaults to the more dangerous values
- # for the _opts_ hash, so be sure only to parse trusted _source_ strings.
- #
- # _opts_ can have the following keys:
- # * *max_nesting*: The maximum depth of nesting allowed in the parsed data
- # structures. Enable depth checking with :max_nesting => anInteger. The parse!
- # methods defaults to not doing max depth checking: This can be dangerous,
- # if someone wants to fill up your stack.
- # * *allow_nan*: If set to true, allow NaN, Infinity, and -Infinity in
- # defiance of RFC 4627 to be parsed by the Parser. This option defaults
- # to true.
- # * *create_additions*: If set to false, the Parser doesn't create
- # additions even if a matchin class and create_id was found. This option
- # defaults to true.
- def parse!(source, opts = {})
- opts = {
- :max_nesting => false,
- :allow_nan => true
- }.update(opts)
- PSON.parser.new(source, opts).parse
- end
+ # Returns the PSON parser class, that is used by PSON. This might be either
+ # PSON::Ext::Parser or PSON::Pure::Parser.
+ attr_reader :parser
- # Unparse the Ruby data structure _obj_ into a single line PSON string and
- # return it. _state_ is
- # * a PSON::State object,
- # * or a Hash like object (responding to to_hash),
- # * an object convertible into a hash by a to_h method,
- # that is used as or to configure a State object.
- #
- # It defaults to a state object, that creates the shortest possible PSON text
- # in one line, checks for circular data structures and doesn't allow NaN,
- # Infinity, and -Infinity.
- #
- # A _state_ hash can have the following keys:
- # * *indent*: a string used to indent levels (default: ''),
- # * *space*: a string that is put after, a : or , delimiter (default: ''),
- # * *space_before*: a string that is put before a : pair delimiter (default: ''),
- # * *object_nl*: a string that is put at the end of a PSON object (default: ''),
- # * *array_nl*: a string that is put at the end of a PSON array (default: ''),
- # * *check_circular*: true if checking for circular data structures
- # should be done (the default), false otherwise.
- # * *allow_nan*: true if NaN, Infinity, and -Infinity should be
- # generated, otherwise an exception is thrown, if these values are
- # encountered. This options defaults to false.
- # * *max_nesting*: The maximum depth of nesting allowed in the data
- # structures from which PSON is to be generated. Disable depth checking
- # with :max_nesting => false, it defaults to 19.
- #
- # See also the fast_generate for the fastest creation method with the least
- # amount of sanity checks, and the pretty_generate method for some
- # defaults for a pretty output.
- def generate(obj, state = nil)
- if state
- state = State.from_state(state)
- else
- state = State.new
- end
- obj.to_pson(state)
+ # Set the PSON parser class _parser_ to be used by PSON.
+ def parser=(parser) # :nodoc:
+ @parser = parser
+ remove_const :Parser if const_defined? :Parser
+ const_set :Parser, parser
end
- # :stopdoc:
- # I want to deprecate these later, so I'll first be silent about them, and
- # later delete them.
- alias unparse generate
- module_function :unparse
- # :startdoc:
-
- # Unparse the Ruby data structure _obj_ into a single line PSON string and
- # return it. This method disables the checks for circles in Ruby objects, and
- # also generates NaN, Infinity, and, -Infinity float values.
- #
- # *WARNING*: Be careful not to pass any Ruby data structures with circles as
- # _obj_ argument, because this will cause PSON to go into an infinite loop.
- def fast_generate(obj)
- obj.to_pson(nil)
+ def registered_document_types
+ @registered_document_types ||= {}
end
- # :stopdoc:
- # I want to deprecate these later, so I'll first be silent about them, and later delete them.
- alias fast_unparse fast_generate
- module_function :fast_unparse
- # :startdoc:
-
- # Unparse the Ruby data structure _obj_ into a PSON string and return it. The
- # returned string is a prettier form of the string returned by #unparse.
- #
- # The _opts_ argument can be used to configure the generator, see the
- # generate method for a more detailed explanation.
- def pretty_generate(obj, opts = nil)
-
- state = PSON.state.new(
-
- :indent => ' ',
- :space => ' ',
- :object_nl => "\n",
- :array_nl => "\n",
-
- :check_circular => true
- )
- if opts
- if opts.respond_to? :to_hash
- opts = opts.to_hash
- elsif opts.respond_to? :to_h
- opts = opts.to_h
- else
- raise TypeError, "can't convert #{opts.class} into Hash"
- end
- state.configure(opts)
- end
- obj.to_pson(state)
+ # Register a class-constant for deserializaion.
+ def register_document_type(name,klass)
+ registered_document_types[name.to_s] = klass
end
- # :stopdoc:
- # I want to deprecate these later, so I'll first be silent about them, and later delete them.
- alias pretty_unparse pretty_generate
- module_function :pretty_unparse
- # :startdoc:
-
- # Load a ruby data structure from a PSON _source_ and return it. A source can
- # either be a string-like object, an IO like object, or an object responding
- # to the read method. If _proc_ was given, it will be called with any nested
- # Ruby object as an argument recursively in depth first order.
- #
- # This method is part of the implementation of the load/dump interface of
- # Marshal and YAML.
- def load(source, proc = nil)
- if source.respond_to? :to_str
- source = source.to_str
- elsif source.respond_to? :to_io
- source = source.to_io.read
- else
- source = source.read
+ # Return the constant located at _path_.
+ # Anything may be registered as a path by calling register_path, above.
+ # Otherwise, the format of _path_ has to be either ::A::B::C or A::B::C.
+ # In either of these cases A has to be defined in Object (e.g. the path
+ # must be an absolute namespace path. If the constant doesn't exist at
+ # the given path, an ArgumentError is raised.
+ def deep_const_get(path) # :nodoc:
+ path = path.to_s
+ registered_document_types[path] || path.split(/::/).inject(Object) do |p, c|
+ case
+ when c.empty? then p
+ when p.const_defined?(c) then p.const_get(c)
+ else raise ArgumentError, "can't find const for unregistered document type #{path}"
end
- result = parse(source, :max_nesting => false, :allow_nan => true)
- recurse_proc(result, &proc) if proc
- result
+ end
end
- def recurse_proc(result, &proc)
- case result
- when Array
- result.each { |x| recurse_proc x, &proc }
- proc.call result
- when Hash
- result.each { |x, y| recurse_proc x, &proc; recurse_proc y, &proc }
- proc.call result
- else
- proc.call result
+ # Set the module _generator_ to be used by PSON.
+ def generator=(generator) # :nodoc:
+ @generator = generator
+ generator_methods = generator::GeneratorMethods
+ for const in generator_methods.constants
+ klass = deep_const_get(const)
+ modul = generator_methods.const_get(const)
+ klass.class_eval do
+ instance_methods(false).each do |m|
+ m.to_s == 'to_pson' and remove_method m
+ end
+ include modul
end
+ end
+ self.state = generator::State
+ const_set :State, self.state
end
- private :recurse_proc
- module_function :recurse_proc
-
- alias restore load
- module_function :restore
- # Dumps _obj_ as a PSON string, i.e. calls generate on the object and returns
- # the result.
- #
- # If anIO (an IO like object or an object that responds to the write method)
- # was given, the resulting PSON is written to it.
- #
- # If the number of nested arrays or objects exceeds _limit_ an ArgumentError
- # exception is raised. This argument is similar (but not exactly the
- # same!) to the _limit_ argument in Marshal.dump.
- #
- # This method is part of the implementation of the load/dump interface of
- # Marshal and YAML.
- def dump(obj, anIO = nil, limit = nil)
- if anIO and limit.nil?
- anIO = anIO.to_io if anIO.respond_to?(:to_io)
- unless anIO.respond_to?(:write)
- limit = anIO
- anIO = nil
- end
- end
- limit ||= 0
- result = generate(obj, :allow_nan => true, :max_nesting => limit)
- if anIO
- anIO.write result
- anIO
- else
- result
- end
- rescue PSON::NestingError
- raise ArgumentError, "exceed depth limit"
+ # Returns the PSON generator modul, that is used by PSON. This might be
+ # either PSON::Ext::Generator or PSON::Pure::Generator.
+ attr_reader :generator
+
+ # Returns the PSON generator state class, that is used by PSON. This might
+ # be either PSON::Ext::Generator::State or PSON::Pure::Generator::State.
+ attr_accessor :state
+
+ # This is create identifier, that is used to decide, if the _pson_create_
+ # hook of a class should be called. It defaults to 'document_type'.
+ attr_accessor :create_id
+ end
+ self.create_id = 'document_type'
+
+ NaN = (-1.0) ** 0.5
+
+ Infinity = 1.0/0
+
+ MinusInfinity = -Infinity
+
+ # The base exception for PSON errors.
+ class PSONError < StandardError; end
+
+ # This exception is raised, if a parser error occurs.
+ class ParserError < PSONError; end
+
+ # This exception is raised, if the nesting of parsed datastructures is too
+ # deep.
+ class NestingError < ParserError; end
+
+ # This exception is raised, if a generator or unparser error occurs.
+ class GeneratorError < PSONError; end
+ # For backwards compatibility
+ UnparserError = GeneratorError
+
+ # If a circular data structure is encountered while unparsing
+ # this exception is raised.
+ class CircularDatastructure < GeneratorError; end
+
+ # This exception is raised, if the required unicode support is missing on the
+ # system. Usually this means, that the iconv library is not installed.
+ class MissingUnicodeSupport < PSONError; end
+
+ module_function
+
+ # Parse the PSON string _source_ into a Ruby data structure and return it.
+ #
+ # _opts_ can have the following
+ # keys:
+ # * *max_nesting*: The maximum depth of nesting allowed in the parsed data
+ # structures. Disable depth checking with :max_nesting => false, it defaults
+ # to 19.
+ # * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
+ # defiance of RFC 4627 to be parsed by the Parser. This option defaults
+ # to false.
+ # * *create_additions*: If set to false, the Parser doesn't create
+ # additions even if a matchin class and create_id was found. This option
+ # defaults to true.
+ def parse(source, opts = {})
+ PSON.parser.new(source, opts).parse
+ end
+
+ # Parse the PSON string _source_ into a Ruby data structure and return it.
+ # The bang version of the parse method, defaults to the more dangerous values
+ # for the _opts_ hash, so be sure only to parse trusted _source_ strings.
+ #
+ # _opts_ can have the following keys:
+ # * *max_nesting*: The maximum depth of nesting allowed in the parsed data
+ # structures. Enable depth checking with :max_nesting => anInteger. The parse!
+ # methods defaults to not doing max depth checking: This can be dangerous,
+ # if someone wants to fill up your stack.
+ # * *allow_nan*: If set to true, allow NaN, Infinity, and -Infinity in
+ # defiance of RFC 4627 to be parsed by the Parser. This option defaults
+ # to true.
+ # * *create_additions*: If set to false, the Parser doesn't create
+ # additions even if a matchin class and create_id was found. This option
+ # defaults to true.
+ def parse!(source, opts = {})
+ opts = {
+ :max_nesting => false,
+ :allow_nan => true
+ }.update(opts)
+ PSON.parser.new(source, opts).parse
+ end
+
+ # Unparse the Ruby data structure _obj_ into a single line PSON string and
+ # return it. _state_ is
+ # * a PSON::State object,
+ # * or a Hash like object (responding to to_hash),
+ # * an object convertible into a hash by a to_h method,
+ # that is used as or to configure a State object.
+ #
+ # It defaults to a state object, that creates the shortest possible PSON text
+ # in one line, checks for circular data structures and doesn't allow NaN,
+ # Infinity, and -Infinity.
+ #
+ # A _state_ hash can have the following keys:
+ # * *indent*: a string used to indent levels (default: ''),
+ # * *space*: a string that is put after, a : or , delimiter (default: ''),
+ # * *space_before*: a string that is put before a : pair delimiter (default: ''),
+ # * *object_nl*: a string that is put at the end of a PSON object (default: ''),
+ # * *array_nl*: a string that is put at the end of a PSON array (default: ''),
+ # * *check_circular*: true if checking for circular data structures
+ # should be done (the default), false otherwise.
+ # * *allow_nan*: true if NaN, Infinity, and -Infinity should be
+ # generated, otherwise an exception is thrown, if these values are
+ # encountered. This options defaults to false.
+ # * *max_nesting*: The maximum depth of nesting allowed in the data
+ # structures from which PSON is to be generated. Disable depth checking
+ # with :max_nesting => false, it defaults to 19.
+ #
+ # See also the fast_generate for the fastest creation method with the least
+ # amount of sanity checks, and the pretty_generate method for some
+ # defaults for a pretty output.
+ def generate(obj, state = nil)
+ if state
+ state = State.from_state(state)
+ else
+ state = State.new
+ end
+ obj.to_pson(state)
+ end
+
+ # :stopdoc:
+ # I want to deprecate these later, so I'll first be silent about them, and
+ # later delete them.
+ alias unparse generate
+ module_function :unparse
+ # :startdoc:
+
+ # Unparse the Ruby data structure _obj_ into a single line PSON string and
+ # return it. This method disables the checks for circles in Ruby objects, and
+ # also generates NaN, Infinity, and, -Infinity float values.
+ #
+ # *WARNING*: Be careful not to pass any Ruby data structures with circles as
+ # _obj_ argument, because this will cause PSON to go into an infinite loop.
+ def fast_generate(obj)
+ obj.to_pson(nil)
+ end
+
+ # :stopdoc:
+ # I want to deprecate these later, so I'll first be silent about them, and later delete them.
+ alias fast_unparse fast_generate
+ module_function :fast_unparse
+ # :startdoc:
+
+ # Unparse the Ruby data structure _obj_ into a PSON string and return it. The
+ # returned string is a prettier form of the string returned by #unparse.
+ #
+ # The _opts_ argument can be used to configure the generator, see the
+ # generate method for a more detailed explanation.
+ def pretty_generate(obj, opts = nil)
+
+ state = PSON.state.new(
+
+ :indent => ' ',
+ :space => ' ',
+ :object_nl => "\n",
+ :array_nl => "\n",
+
+ :check_circular => true
+ )
+ if opts
+ if opts.respond_to? :to_hash
+ opts = opts.to_hash
+ elsif opts.respond_to? :to_h
+ opts = opts.to_h
+ else
+ raise TypeError, "can't convert #{opts.class} into Hash"
+ end
+ state.configure(opts)
+ end
+ obj.to_pson(state)
+ end
+
+ # :stopdoc:
+ # I want to deprecate these later, so I'll first be silent about them, and later delete them.
+ alias pretty_unparse pretty_generate
+ module_function :pretty_unparse
+ # :startdoc:
+
+ # Load a ruby data structure from a PSON _source_ and return it. A source can
+ # either be a string-like object, an IO like object, or an object responding
+ # to the read method. If _proc_ was given, it will be called with any nested
+ # Ruby object as an argument recursively in depth first order.
+ #
+ # This method is part of the implementation of the load/dump interface of
+ # Marshal and YAML.
+ def load(source, proc = nil)
+ if source.respond_to? :to_str
+ source = source.to_str
+ elsif source.respond_to? :to_io
+ source = source.to_io.read
+ else
+ source = source.read
+ end
+ result = parse(source, :max_nesting => false, :allow_nan => true)
+ recurse_proc(result, &proc) if proc
+ result
+ end
+
+ def recurse_proc(result, &proc)
+ case result
+ when Array
+ result.each { |x| recurse_proc x, &proc }
+ proc.call result
+ when Hash
+ result.each { |x, y| recurse_proc x, &proc; recurse_proc y, &proc }
+ proc.call result
+ else
+ proc.call result
end
+ end
+ private :recurse_proc
+ module_function :recurse_proc
+
+ alias restore load
+ module_function :restore
+
+ # Dumps _obj_ as a PSON string, i.e. calls generate on the object and returns
+ # the result.
+ #
+ # If anIO (an IO like object or an object that responds to the write method)
+ # was given, the resulting PSON is written to it.
+ #
+ # If the number of nested arrays or objects exceeds _limit_ an ArgumentError
+ # exception is raised. This argument is similar (but not exactly the
+ # same!) to the _limit_ argument in Marshal.dump.
+ #
+ # This method is part of the implementation of the load/dump interface of
+ # Marshal and YAML.
+ def dump(obj, anIO = nil, limit = nil)
+ if anIO and limit.nil?
+ anIO = anIO.to_io if anIO.respond_to?(:to_io)
+ unless anIO.respond_to?(:write)
+ limit = anIO
+ anIO = nil
+ end
+ end
+ limit ||= 0
+ result = generate(obj, :allow_nan => true, :max_nesting => limit)
+ if anIO
+ anIO.write result
+ anIO
+ else
+ result
+ end
+ rescue PSON::NestingError
+ raise ArgumentError, "exceed depth limit"
+ end
end
module ::Kernel
- private
+ private
- # Outputs _objs_ to STDOUT as PSON strings in the shortest form, that is in
- # one line.
- def j(*objs)
- objs.each do |obj|
- puts PSON::generate(obj, :allow_nan => true, :max_nesting => false)
- end
- nil
+ # Outputs _objs_ to STDOUT as PSON strings in the shortest form, that is in
+ # one line.
+ def j(*objs)
+ objs.each do |obj|
+ puts PSON::generate(obj, :allow_nan => true, :max_nesting => false)
end
-
- # Ouputs _objs_ to STDOUT as PSON strings in a pretty format, with
- # indentation and over many lines.
- def jj(*objs)
- objs.each do |obj|
- puts PSON::pretty_generate(obj, :allow_nan => true, :max_nesting => false)
- end
- nil
+ nil
+ end
+
+ # Ouputs _objs_ to STDOUT as PSON strings in a pretty format, with
+ # indentation and over many lines.
+ def jj(*objs)
+ objs.each do |obj|
+ puts PSON::pretty_generate(obj, :allow_nan => true, :max_nesting => false)
end
-
- # If _object_ is string-like parse the string and return the parsed result as
- # a Ruby data structure. Otherwise generate a PSON text from the Ruby data
- # structure object and return it.
- #
- # The _opts_ argument is passed through to generate/parse respectively, see
- # generate and parse for their documentation.
- def PSON(object, opts = {})
- if object.respond_to? :to_str
- PSON.parse(object.to_str, opts)
- else
- PSON.generate(object, opts)
- end
+ nil
+ end
+
+ # If _object_ is string-like parse the string and return the parsed result as
+ # a Ruby data structure. Otherwise generate a PSON text from the Ruby data
+ # structure object and return it.
+ #
+ # The _opts_ argument is passed through to generate/parse respectively, see
+ # generate and parse for their documentation.
+ def PSON(object, opts = {})
+ if object.respond_to? :to_str
+ PSON.parse(object.to_str, opts)
+ else
+ PSON.generate(object, opts)
end
+ end
end
class ::Class
- # Returns true, if this class can be used to create an instance
- # from a serialised PSON string. The class has to implement a class
- # method _pson_create_ that expects a hash as first parameter, which includes
- # the required data.
- def pson_creatable?
- respond_to?(:pson_create)
- end
+ # Returns true, if this class can be used to create an instance
+ # from a serialised PSON string. The class has to implement a class
+ # method _pson_create_ that expects a hash as first parameter, which includes
+ # the required data.
+ def pson_creatable?
+ respond_to?(:pson_create)
+ end
end
diff --git a/lib/puppet/external/pson/pure.rb b/lib/puppet/external/pson/pure.rb
index dffd06d..53d1ea2 100644
--- a/lib/puppet/external/pson/pure.rb
+++ b/lib/puppet/external/pson/pure.rb
@@ -3,75 +3,75 @@ require 'puppet/external/pson/pure/parser'
require 'puppet/external/pson/pure/generator'
module PSON
+ begin
+ require 'iconv'
+ # An iconv instance to convert from UTF8 to UTF16 Big Endian.
+ UTF16toUTF8 = Iconv.new('utf-8', 'utf-16be') # :nodoc:
+ # An iconv instance to convert from UTF16 Big Endian to UTF8.
+ UTF8toUTF16 = Iconv.new('utf-16be', 'utf-8') # :nodoc:
+ UTF8toUTF16.iconv('no bom')
+ rescue LoadError
+ # We actually don't care
+ Puppet.warning "iconv couldn't be loaded, which is required for UTF-8/UTF-16 conversions"
+ rescue Errno::EINVAL, Iconv::InvalidEncoding
+ # Iconv doesn't support big endian utf-16. Let's try to hack this manually
+ # into the converters.
begin
- require 'iconv'
- # An iconv instance to convert from UTF8 to UTF16 Big Endian.
- UTF16toUTF8 = Iconv.new('utf-8', 'utf-16be') # :nodoc:
- # An iconv instance to convert from UTF16 Big Endian to UTF8.
- UTF8toUTF16 = Iconv.new('utf-16be', 'utf-8') # :nodoc:
- UTF8toUTF16.iconv('no bom')
- rescue LoadError
- # We actually don't care
- Puppet.warning "iconv couldn't be loaded, which is required for UTF-8/UTF-16 conversions"
- rescue Errno::EINVAL, Iconv::InvalidEncoding
- # Iconv doesn't support big endian utf-16. Let's try to hack this manually
- # into the converters.
- begin
- old_verbose, $VERBSOSE = $VERBOSE, nil
- # An iconv instance to convert from UTF8 to UTF16 Big Endian.
- UTF16toUTF8 = Iconv.new('utf-8', 'utf-16') # :nodoc:
- # An iconv instance to convert from UTF16 Big Endian to UTF8.
- UTF8toUTF16 = Iconv.new('utf-16', 'utf-8') # :nodoc:
- UTF8toUTF16.iconv('no bom')
- if UTF8toUTF16.iconv("\xe2\x82\xac") == "\xac\x20"
- swapper = Class.new do
- def initialize(iconv) # :nodoc:
- @iconv = iconv
- end
-
- def iconv(string) # :nodoc:
- result = @iconv.iconv(string)
- PSON.swap!(result)
- end
- end
- UTF8toUTF16 = swapper.new(UTF8toUTF16) # :nodoc:
- end
- if UTF16toUTF8.iconv("\xac\x20") == "\xe2\x82\xac"
- swapper = Class.new do
- def initialize(iconv) # :nodoc:
- @iconv = iconv
- end
+ old_verbose, $VERBSOSE = $VERBOSE, nil
+ # An iconv instance to convert from UTF8 to UTF16 Big Endian.
+ UTF16toUTF8 = Iconv.new('utf-8', 'utf-16') # :nodoc:
+ # An iconv instance to convert from UTF16 Big Endian to UTF8.
+ UTF8toUTF16 = Iconv.new('utf-16', 'utf-8') # :nodoc:
+ UTF8toUTF16.iconv('no bom')
+ if UTF8toUTF16.iconv("\xe2\x82\xac") == "\xac\x20"
+ swapper = Class.new do
+ def initialize(iconv) # :nodoc:
+ @iconv = iconv
+ end
- def iconv(string) # :nodoc:
- string = PSON.swap!(string.dup)
- @iconv.iconv(string)
- end
- end
- UTF16toUTF8 = swapper.new(UTF16toUTF8) # :nodoc:
- end
- rescue Errno::EINVAL, Iconv::InvalidEncoding
- Puppet.warning "iconv doesn't seem to support UTF-8/UTF-16 conversions"
- ensure
- $VERBOSE = old_verbose
+ def iconv(string) # :nodoc:
+ result = @iconv.iconv(string)
+ PSON.swap!(result)
+ end
end
- end
+ UTF8toUTF16 = swapper.new(UTF8toUTF16) # :nodoc:
+ end
+ if UTF16toUTF8.iconv("\xac\x20") == "\xe2\x82\xac"
+ swapper = Class.new do
+ def initialize(iconv) # :nodoc:
+ @iconv = iconv
+ end
- # Swap consecutive bytes of _string_ in place.
- def self.swap!(string) # :nodoc:
- 0.upto(string.size / 2) do |i|
- break unless string[2 * i + 1]
- string[2 * i], string[2 * i + 1] = string[2 * i + 1], string[2 * i]
+ def iconv(string) # :nodoc:
+ string = PSON.swap!(string.dup)
+ @iconv.iconv(string)
+ end
end
- string
+ UTF16toUTF8 = swapper.new(UTF16toUTF8) # :nodoc:
+ end
+ rescue Errno::EINVAL, Iconv::InvalidEncoding
+ Puppet.warning "iconv doesn't seem to support UTF-8/UTF-16 conversions"
+ ensure
+ $VERBOSE = old_verbose
end
+ end
- # This module holds all the modules/classes that implement PSON's
- # functionality in pure ruby.
- module Pure
- $DEBUG and warn "Using pure library for PSON."
- PSON.parser = Parser
- PSON.generator = Generator
+ # Swap consecutive bytes of _string_ in place.
+ def self.swap!(string) # :nodoc:
+ 0.upto(string.size / 2) do |i|
+ break unless string[2 * i + 1]
+ string[2 * i], string[2 * i + 1] = string[2 * i + 1], string[2 * i]
end
+ string
+ end
+
+ # This module holds all the modules/classes that implement PSON's
+ # functionality in pure ruby.
+ module Pure
+ $DEBUG and warn "Using pure library for PSON."
+ PSON.parser = Parser
+ PSON.generator = Generator
+ end
- PSON_LOADED = true
+ PSON_LOADED = true
end
diff --git a/lib/puppet/external/pson/pure/generator.rb b/lib/puppet/external/pson/pure/generator.rb
index 42981b9..ef8b36d 100644
--- a/lib/puppet/external/pson/pure/generator.rb
+++ b/lib/puppet/external/pson/pure/generator.rb
@@ -1,429 +1,429 @@
module PSON
- MAP = {
- "\x0" => '\u0000',
- "\x1" => '\u0001',
- "\x2" => '\u0002',
- "\x3" => '\u0003',
- "\x4" => '\u0004',
- "\x5" => '\u0005',
- "\x6" => '\u0006',
- "\x7" => '\u0007',
- "\b" => '\b',
- "\t" => '\t',
- "\n" => '\n',
- "\xb" => '\u000b',
- "\f" => '\f',
- "\r" => '\r',
- "\xe" => '\u000e',
- "\xf" => '\u000f',
- "\x10" => '\u0010',
- "\x11" => '\u0011',
- "\x12" => '\u0012',
- "\x13" => '\u0013',
- "\x14" => '\u0014',
- "\x15" => '\u0015',
- "\x16" => '\u0016',
- "\x17" => '\u0017',
- "\x18" => '\u0018',
- "\x19" => '\u0019',
- "\x1a" => '\u001a',
- "\x1b" => '\u001b',
- "\x1c" => '\u001c',
- "\x1d" => '\u001d',
- "\x1e" => '\u001e',
- "\x1f" => '\u001f',
- '"' => '\"',
- '\\' => '\\\\',
- } # :nodoc:
-
- # Convert a UTF8 encoded Ruby string _string_ to a PSON string, encoded with
- # UTF16 big endian characters as \u????, and return it.
- if String.method_defined?(:force_encoding)
- def utf8_to_pson(string) # :nodoc:
- string = string.dup
- string << '' # XXX workaround: avoid buffer sharing
- string.force_encoding(Encoding::ASCII_8BIT)
- string.gsub!(/["\\\x0-\x1f]/) { MAP[$MATCH] }
- string.gsub!(/(
- (?:
- [\xc2-\xdf][\x80-\xbf] |
- [\xe0-\xef][\x80-\xbf]{2} |
- [\xf0-\xf4][\x80-\xbf]{3}
- )+ |
- [\x80-\xc1\xf5-\xff] # invalid
- )/nx) { |c|
- c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
- s = PSON::UTF8toUTF16.iconv(c).unpack('H*')[0]
- s.gsub!(/.{4}/n, '\\\\u\&')
- }
- string.force_encoding(Encoding::UTF_8)
- string
- rescue Iconv::Failure => e
- raise GeneratorError, "Caught #{e.class}: #{e}"
- end
- else
- def utf8_to_pson(string) # :nodoc:
- string = string.gsub(/["\\\x0-\x1f]/) { MAP[$MATCH] }
- string.gsub!(/(
- (?:
- [\xc2-\xdf][\x80-\xbf] |
- [\xe0-\xef][\x80-\xbf]{2} |
- [\xf0-\xf4][\x80-\xbf]{3}
- )+ |
- [\x80-\xc1\xf5-\xff] # invalid
- )/nx) { |c|
+ MAP = {
+ "\x0" => '\u0000',
+ "\x1" => '\u0001',
+ "\x2" => '\u0002',
+ "\x3" => '\u0003',
+ "\x4" => '\u0004',
+ "\x5" => '\u0005',
+ "\x6" => '\u0006',
+ "\x7" => '\u0007',
+ "\b" => '\b',
+ "\t" => '\t',
+ "\n" => '\n',
+ "\xb" => '\u000b',
+ "\f" => '\f',
+ "\r" => '\r',
+ "\xe" => '\u000e',
+ "\xf" => '\u000f',
+ "\x10" => '\u0010',
+ "\x11" => '\u0011',
+ "\x12" => '\u0012',
+ "\x13" => '\u0013',
+ "\x14" => '\u0014',
+ "\x15" => '\u0015',
+ "\x16" => '\u0016',
+ "\x17" => '\u0017',
+ "\x18" => '\u0018',
+ "\x19" => '\u0019',
+ "\x1a" => '\u001a',
+ "\x1b" => '\u001b',
+ "\x1c" => '\u001c',
+ "\x1d" => '\u001d',
+ "\x1e" => '\u001e',
+ "\x1f" => '\u001f',
+ '"' => '\"',
+ '\\' => '\\\\',
+ } # :nodoc:
+
+ # Convert a UTF8 encoded Ruby string _string_ to a PSON string, encoded with
+ # UTF16 big endian characters as \u????, and return it.
+ if String.method_defined?(:force_encoding)
+ def utf8_to_pson(string) # :nodoc:
+ string = string.dup
+ string << '' # XXX workaround: avoid buffer sharing
+ string.force_encoding(Encoding::ASCII_8BIT)
+ string.gsub!(/["\\\x0-\x1f]/) { MAP[$MATCH] }
+ string.gsub!(/(
+ (?:
+ [\xc2-\xdf][\x80-\xbf] |
+ [\xe0-\xef][\x80-\xbf]{2} |
+ [\xf0-\xf4][\x80-\xbf]{3}
+ )+ |
+ [\x80-\xc1\xf5-\xff] # invalid
+ )/nx) { |c|
c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
s = PSON::UTF8toUTF16.iconv(c).unpack('H*')[0]
s.gsub!(/.{4}/n, '\\\\u\&')
- }
- string
- rescue Iconv::Failure => e
- raise GeneratorError, "Caught #{e.class}: #{e}"
- end
+ }
+ string.force_encoding(Encoding::UTF_8)
+ string
+ rescue Iconv::Failure => e
+ raise GeneratorError, "Caught #{e.class}: #{e}"
+ end
+ else
+ def utf8_to_pson(string) # :nodoc:
+ string = string.gsub(/["\\\x0-\x1f]/) { MAP[$MATCH] }
+ string.gsub!(/(
+ (?:
+ [\xc2-\xdf][\x80-\xbf] |
+ [\xe0-\xef][\x80-\xbf]{2} |
+ [\xf0-\xf4][\x80-\xbf]{3}
+ )+ |
+ [\x80-\xc1\xf5-\xff] # invalid
+ )/nx) { |c|
+ c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
+ s = PSON::UTF8toUTF16.iconv(c).unpack('H*')[0]
+ s.gsub!(/.{4}/n, '\\\\u\&')
+ }
+ string
+ rescue Iconv::Failure => e
+ raise GeneratorError, "Caught #{e.class}: #{e}"
end
- module_function :utf8_to_pson
-
- module Pure
- module Generator
- # This class is used to create State instances, that are use to hold data
- # while generating a PSON text from a a Ruby data structure.
- class State
- # Creates a State object from _opts_, which ought to be Hash to create
- # a new State instance configured by _opts_, something else to create
- # an unconfigured instance. If _opts_ is a State object, it is just
- # returned.
- def self.from_state(opts)
- case opts
- when self
- opts
- when Hash
- new(opts)
- else
- new
- end
- end
-
- # Instantiates a new State object, configured by _opts_.
- #
- # _opts_ can have the following keys:
- #
- # * *indent*: a string used to indent levels (default: ''),
- # * *space*: a string that is put after, a : or , delimiter (default: ''),
- # * *space_before*: a string that is put before a : pair delimiter (default: ''),
- # * *object_nl*: a string that is put at the end of a PSON object (default: ''),
- # * *array_nl*: a string that is put at the end of a PSON array (default: ''),
- # * *check_circular*: true if checking for circular data structures
- # should be done (the default), false otherwise.
- # * *check_circular*: true if checking for circular data structures
- # should be done, false (the default) otherwise.
- # * *allow_nan*: true if NaN, Infinity, and -Infinity should be
- # generated, otherwise an exception is thrown, if these values are
- # encountered. This options defaults to false.
- def initialize(opts = {})
- @seen = {}
- @indent = ''
- @space = ''
- @space_before = ''
- @object_nl = ''
- @array_nl = ''
- @check_circular = true
- @allow_nan = false
- configure opts
- end
-
- # This string is used to indent levels in the PSON text.
- attr_accessor :indent
-
- # This string is used to insert a space between the tokens in a PSON
- # string.
- attr_accessor :space
-
- # This string is used to insert a space before the ':' in PSON objects.
- attr_accessor :space_before
-
- # This string is put at the end of a line that holds a PSON object (or
- # Hash).
- attr_accessor :object_nl
-
- # This string is put at the end of a line that holds a PSON array.
- attr_accessor :array_nl
-
- # This integer returns the maximum level of data structure nesting in
- # the generated PSON, max_nesting = 0 if no maximum is checked.
- attr_accessor :max_nesting
-
- def check_max_nesting(depth) # :nodoc:
- return if @max_nesting.zero?
- current_nesting = depth + 1
- current_nesting > @max_nesting and
- raise NestingError, "nesting of #{current_nesting} is too deep"
- end
-
- # Returns true, if circular data structures should be checked,
- # otherwise returns false.
- def check_circular?
- @check_circular
- end
-
- # Returns true if NaN, Infinity, and -Infinity should be considered as
- # valid PSON and output.
- def allow_nan?
- @allow_nan
- end
-
- # Returns _true_, if _object_ was already seen during this generating
- # run.
- def seen?(object)
- @seen.key?(object.__id__)
- end
-
- # Remember _object_, to find out if it was already encountered (if a
- # cyclic data structure is if a cyclic data structure is rendered).
- def remember(object)
- @seen[object.__id__] = true
- end
-
- # Forget _object_ for this generating run.
- def forget(object)
- @seen.delete object.__id__
- end
-
- # Configure this State instance with the Hash _opts_, and return
- # itself.
- def configure(opts)
- @indent = opts[:indent] if opts.key?(:indent)
- @space = opts[:space] if opts.key?(:space)
- @space_before = opts[:space_before] if opts.key?(:space_before)
- @object_nl = opts[:object_nl] if opts.key?(:object_nl)
- @array_nl = opts[:array_nl] if opts.key?(:array_nl)
- @check_circular = !!opts[:check_circular] if opts.key?(:check_circular)
- @allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan)
- if !opts.key?(:max_nesting) # defaults to 19
- @max_nesting = 19
- elsif opts[:max_nesting]
- @max_nesting = opts[:max_nesting]
- else
- @max_nesting = 0
- end
- self
- end
-
- # Returns the configuration instance variables as a hash, that can be
- # passed to the configure method.
- def to_h
- result = {}
- for iv in %w{indent space space_before object_nl array_nl check_circular allow_nan max_nesting}
- result[iv.intern] = instance_variable_get("@#{iv}")
- end
- result
- end
+ end
+ module_function :utf8_to_pson
+
+ module Pure
+ module Generator
+ # This class is used to create State instances, that are use to hold data
+ # while generating a PSON text from a a Ruby data structure.
+ class State
+ # Creates a State object from _opts_, which ought to be Hash to create
+ # a new State instance configured by _opts_, something else to create
+ # an unconfigured instance. If _opts_ is a State object, it is just
+ # returned.
+ def self.from_state(opts)
+ case opts
+ when self
+ opts
+ when Hash
+ new(opts)
+ else
+ new
+ end
+ end
+
+ # Instantiates a new State object, configured by _opts_.
+ #
+ # _opts_ can have the following keys:
+ #
+ # * *indent*: a string used to indent levels (default: ''),
+ # * *space*: a string that is put after, a : or , delimiter (default: ''),
+ # * *space_before*: a string that is put before a : pair delimiter (default: ''),
+ # * *object_nl*: a string that is put at the end of a PSON object (default: ''),
+ # * *array_nl*: a string that is put at the end of a PSON array (default: ''),
+ # * *check_circular*: true if checking for circular data structures
+ # should be done (the default), false otherwise.
+ # * *check_circular*: true if checking for circular data structures
+ # should be done, false (the default) otherwise.
+ # * *allow_nan*: true if NaN, Infinity, and -Infinity should be
+ # generated, otherwise an exception is thrown, if these values are
+ # encountered. This options defaults to false.
+ def initialize(opts = {})
+ @seen = {}
+ @indent = ''
+ @space = ''
+ @space_before = ''
+ @object_nl = ''
+ @array_nl = ''
+ @check_circular = true
+ @allow_nan = false
+ configure opts
+ end
+
+ # This string is used to indent levels in the PSON text.
+ attr_accessor :indent
+
+ # This string is used to insert a space between the tokens in a PSON
+ # string.
+ attr_accessor :space
+
+ # This string is used to insert a space before the ':' in PSON objects.
+ attr_accessor :space_before
+
+ # This string is put at the end of a line that holds a PSON object (or
+ # Hash).
+ attr_accessor :object_nl
+
+ # This string is put at the end of a line that holds a PSON array.
+ attr_accessor :array_nl
+
+ # This integer returns the maximum level of data structure nesting in
+ # the generated PSON, max_nesting = 0 if no maximum is checked.
+ attr_accessor :max_nesting
+
+ def check_max_nesting(depth) # :nodoc:
+ return if @max_nesting.zero?
+ current_nesting = depth + 1
+ current_nesting > @max_nesting and
+ raise NestingError, "nesting of #{current_nesting} is too deep"
+ end
+
+ # Returns true, if circular data structures should be checked,
+ # otherwise returns false.
+ def check_circular?
+ @check_circular
+ end
+
+ # Returns true if NaN, Infinity, and -Infinity should be considered as
+ # valid PSON and output.
+ def allow_nan?
+ @allow_nan
+ end
+
+ # Returns _true_, if _object_ was already seen during this generating
+ # run.
+ def seen?(object)
+ @seen.key?(object.__id__)
+ end
+
+ # Remember _object_, to find out if it was already encountered (if a
+ # cyclic data structure is if a cyclic data structure is rendered).
+ def remember(object)
+ @seen[object.__id__] = true
+ end
+
+ # Forget _object_ for this generating run.
+ def forget(object)
+ @seen.delete object.__id__
+ end
+
+ # Configure this State instance with the Hash _opts_, and return
+ # itself.
+ def configure(opts)
+ @indent = opts[:indent] if opts.key?(:indent)
+ @space = opts[:space] if opts.key?(:space)
+ @space_before = opts[:space_before] if opts.key?(:space_before)
+ @object_nl = opts[:object_nl] if opts.key?(:object_nl)
+ @array_nl = opts[:array_nl] if opts.key?(:array_nl)
+ @check_circular = !!opts[:check_circular] if opts.key?(:check_circular)
+ @allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan)
+ if !opts.key?(:max_nesting) # defaults to 19
+ @max_nesting = 19
+ elsif opts[:max_nesting]
+ @max_nesting = opts[:max_nesting]
+ else
+ @max_nesting = 0
+ end
+ self
+ end
+
+ # Returns the configuration instance variables as a hash, that can be
+ # passed to the configure method.
+ def to_h
+ result = {}
+ for iv in %w{indent space space_before object_nl array_nl check_circular allow_nan max_nesting}
+ result[iv.intern] = instance_variable_get("@#{iv}")
+ end
+ result
+ end
+ end
+
+ module GeneratorMethods
+ module Object
+ # Converts this object to a string (calling #to_s), converts
+ # it to a PSON string, and returns the result. This is a fallback, if no
+ # special method #to_pson was defined for some object.
+ def to_pson(*) to_s.to_pson end
+ end
+
+ module Hash
+ # Returns a PSON string containing a PSON object, that is unparsed from
+ # this Hash instance.
+ # _state_ is a PSON::State object, that can also be used to configure the
+ # produced PSON string output further.
+ # _depth_ is used to find out nesting depth, to indent accordingly.
+ def to_pson(state = nil, depth = 0, *)
+ if state
+ state = PSON.state.from_state(state)
+ state.check_max_nesting(depth)
+ pson_check_circular(state) { pson_transform(state, depth) }
+ else
+ pson_transform(state, depth)
+ end
+ end
+
+ private
+
+ def pson_check_circular(state)
+ if state and state.check_circular?
+ state.seen?(self) and raise PSON::CircularDatastructure,
+ "circular data structures not supported!"
+ state.remember self
+ end
+ yield
+ ensure
+ state and state.forget self
+ end
+
+ def pson_shift(state, depth)
+ state and not state.object_nl.empty? or return ''
+ state.indent * depth
+ end
+
+ def pson_transform(state, depth)
+ delim = ','
+ if state
+ delim << state.object_nl
+ result = '{'
+ result << state.object_nl
+ result << map { |key,value|
+ s = pson_shift(state, depth + 1)
+ s << key.to_s.to_pson(state, depth + 1)
+ s << state.space_before
+ s << ':'
+ s << state.space
+ s << value.to_pson(state, depth + 1)
+ }.join(delim)
+ result << state.object_nl
+ result << pson_shift(state, depth)
+ result << '}'
+ else
+ result = '{'
+ result << map { |key,value|
+ key.to_s.to_pson << ':' << value.to_pson
+ }.join(delim)
+ result << '}'
+ end
+ result
+ end
+ end
+
+ module Array
+ # Returns a PSON string containing a PSON array, that is unparsed from
+ # this Array instance.
+ # _state_ is a PSON::State object, that can also be used to configure the
+ # produced PSON string output further.
+ # _depth_ is used to find out nesting depth, to indent accordingly.
+ def to_pson(state = nil, depth = 0, *)
+ if state
+ state = PSON.state.from_state(state)
+ state.check_max_nesting(depth)
+ pson_check_circular(state) { pson_transform(state, depth) }
+ else
+ pson_transform(state, depth)
+ end
+ end
+
+ private
+
+ def pson_check_circular(state)
+ if state and state.check_circular?
+ state.seen?(self) and raise PSON::CircularDatastructure,
+ "circular data structures not supported!"
+ state.remember self
+ end
+ yield
+ ensure
+ state and state.forget self
+ end
+
+ def pson_shift(state, depth)
+ state and not state.array_nl.empty? or return ''
+ state.indent * depth
+ end
+
+ def pson_transform(state, depth)
+ delim = ','
+ if state
+ delim << state.array_nl
+ result = '['
+ result << state.array_nl
+ result << map { |value|
+ pson_shift(state, depth + 1) << value.to_pson(state, depth + 1)
+ }.join(delim)
+ result << state.array_nl
+ result << pson_shift(state, depth)
+ result << ']'
+ else
+ '[' << map { |value| value.to_pson }.join(delim) << ']'
end
+ end
+ end
+
+ module Integer
+ # Returns a PSON string representation for this Integer number.
+ def to_pson(*) to_s end
+ end
- module GeneratorMethods
- module Object
- # Converts this object to a string (calling #to_s), converts
- # it to a PSON string, and returns the result. This is a fallback, if no
- # special method #to_pson was defined for some object.
- def to_pson(*) to_s.to_pson end
- end
-
- module Hash
- # Returns a PSON string containing a PSON object, that is unparsed from
- # this Hash instance.
- # _state_ is a PSON::State object, that can also be used to configure the
- # produced PSON string output further.
- # _depth_ is used to find out nesting depth, to indent accordingly.
- def to_pson(state = nil, depth = 0, *)
- if state
- state = PSON.state.from_state(state)
- state.check_max_nesting(depth)
- pson_check_circular(state) { pson_transform(state, depth) }
- else
- pson_transform(state, depth)
- end
- end
-
- private
-
- def pson_check_circular(state)
- if state and state.check_circular?
- state.seen?(self) and raise PSON::CircularDatastructure,
- "circular data structures not supported!"
- state.remember self
- end
- yield
- ensure
- state and state.forget self
- end
-
- def pson_shift(state, depth)
- state and not state.object_nl.empty? or return ''
- state.indent * depth
- end
-
- def pson_transform(state, depth)
- delim = ','
- if state
- delim << state.object_nl
- result = '{'
- result << state.object_nl
- result << map { |key,value|
- s = pson_shift(state, depth + 1)
- s << key.to_s.to_pson(state, depth + 1)
- s << state.space_before
- s << ':'
- s << state.space
- s << value.to_pson(state, depth + 1)
- }.join(delim)
- result << state.object_nl
- result << pson_shift(state, depth)
- result << '}'
- else
- result = '{'
- result << map { |key,value|
- key.to_s.to_pson << ':' << value.to_pson
- }.join(delim)
- result << '}'
- end
- result
- end
- end
-
- module Array
- # Returns a PSON string containing a PSON array, that is unparsed from
- # this Array instance.
- # _state_ is a PSON::State object, that can also be used to configure the
- # produced PSON string output further.
- # _depth_ is used to find out nesting depth, to indent accordingly.
- def to_pson(state = nil, depth = 0, *)
- if state
- state = PSON.state.from_state(state)
- state.check_max_nesting(depth)
- pson_check_circular(state) { pson_transform(state, depth) }
- else
- pson_transform(state, depth)
- end
- end
-
- private
-
- def pson_check_circular(state)
- if state and state.check_circular?
- state.seen?(self) and raise PSON::CircularDatastructure,
- "circular data structures not supported!"
- state.remember self
- end
- yield
- ensure
- state and state.forget self
- end
-
- def pson_shift(state, depth)
- state and not state.array_nl.empty? or return ''
- state.indent * depth
- end
-
- def pson_transform(state, depth)
- delim = ','
- if state
- delim << state.array_nl
- result = '['
- result << state.array_nl
- result << map { |value|
- pson_shift(state, depth + 1) << value.to_pson(state, depth + 1)
- }.join(delim)
- result << state.array_nl
- result << pson_shift(state, depth)
- result << ']'
- else
- '[' << map { |value| value.to_pson }.join(delim) << ']'
- end
- end
- end
-
- module Integer
- # Returns a PSON string representation for this Integer number.
- def to_pson(*) to_s end
- end
-
- module Float
- # Returns a PSON string representation for this Float number.
- def to_pson(state = nil, *)
- case
- when infinite?
- if !state || state.allow_nan?
- to_s
- else
- raise GeneratorError, "#{self} not allowed in PSON"
- end
- when nan?
- if !state || state.allow_nan?
- to_s
- else
- raise GeneratorError, "#{self} not allowed in PSON"
- end
- else
- to_s
- end
- end
- end
-
- module String
- # This string should be encoded with UTF-8 A call to this method
- # returns a PSON string encoded with UTF16 big endian characters as
- # \u????.
- def to_pson(*)
- '"' << PSON.utf8_to_pson(self) << '"'
- end
-
- # Module that holds the extinding methods if, the String module is
- # included.
- module Extend
- # Raw Strings are PSON Objects (the raw bytes are stored in an array for the
- # key "raw"). The Ruby String can be created by this module method.
- def pson_create(o)
- o['raw'].pack('C*')
- end
- end
-
- # Extends _modul_ with the String::Extend module.
- def self.included(modul)
- modul.extend Extend
- end
-
- # This method creates a raw object hash, that can be nested into
- # other data structures and will be unparsed as a raw string. This
- # method should be used, if you want to convert raw strings to PSON
- # instead of UTF-8 strings, e. g. binary data.
- def to_pson_raw_object
- {
- PSON.create_id => self.class.name,
- 'raw' => self.unpack('C*'),
- }
- end
-
- # This method creates a PSON text from the result of
- # a call to to_pson_raw_object of this String.
- def to_pson_raw(*args)
- to_pson_raw_object.to_pson(*args)
- end
- end
-
- module TrueClass
- # Returns a PSON string for true: 'true'.
- def to_pson(*) 'true' end
- end
-
- module FalseClass
- # Returns a PSON string for false: 'false'.
- def to_pson(*) 'false' end
- end
-
- module NilClass
- # Returns a PSON string for nil: 'null'.
- def to_pson(*) 'null' end
- end
+ module Float
+ # Returns a PSON string representation for this Float number.
+ def to_pson(state = nil, *)
+ case
+ when infinite?
+ if !state || state.allow_nan?
+ to_s
+ else
+ raise GeneratorError, "#{self} not allowed in PSON"
+ end
+ when nan?
+ if !state || state.allow_nan?
+ to_s
+ else
+ raise GeneratorError, "#{self} not allowed in PSON"
+ end
+ else
+ to_s
end
+ end
+ end
+
+ module String
+ # This string should be encoded with UTF-8 A call to this method
+ # returns a PSON string encoded with UTF16 big endian characters as
+ # \u????.
+ def to_pson(*)
+ '"' << PSON.utf8_to_pson(self) << '"'
+ end
+
+ # Module that holds the extinding methods if, the String module is
+ # included.
+ module Extend
+ # Raw Strings are PSON Objects (the raw bytes are stored in an array for the
+ # key "raw"). The Ruby String can be created by this module method.
+ def pson_create(o)
+ o['raw'].pack('C*')
+ end
+ end
+
+ # Extends _modul_ with the String::Extend module.
+ def self.included(modul)
+ modul.extend Extend
+ end
+
+ # This method creates a raw object hash, that can be nested into
+ # other data structures and will be unparsed as a raw string. This
+ # method should be used, if you want to convert raw strings to PSON
+ # instead of UTF-8 strings, e. g. binary data.
+ def to_pson_raw_object
+ {
+ PSON.create_id => self.class.name,
+ 'raw' => self.unpack('C*'),
+ }
+ end
+
+ # This method creates a PSON text from the result of
+ # a call to to_pson_raw_object of this String.
+ def to_pson_raw(*args)
+ to_pson_raw_object.to_pson(*args)
+ end
+ end
+
+ module TrueClass
+ # Returns a PSON string for true: 'true'.
+ def to_pson(*) 'true' end
+ end
+
+ module FalseClass
+ # Returns a PSON string for false: 'false'.
+ def to_pson(*) 'false' end
+ end
+
+ module NilClass
+ # Returns a PSON string for nil: 'null'.
+ def to_pson(*) 'null' end
end
+ end
end
+ end
end
diff --git a/lib/puppet/external/pson/pure/parser.rb b/lib/puppet/external/pson/pure/parser.rb
index 2d0a030..6048f67 100644
--- a/lib/puppet/external/pson/pure/parser.rb
+++ b/lib/puppet/external/pson/pure/parser.rb
@@ -1,264 +1,264 @@
require 'strscan'
module PSON
- module Pure
- # This class implements the PSON parser that is used to parse a PSON string
- # into a Ruby data structure.
- class Parser < StringScanner
- STRING = /" ((?:[^\x0-\x1f"\\] |
- # escaped special characters:
- \\["\\\/bfnrt] |
- \\u[0-9a-fA-F]{4} |
- # match all but escaped special characters:
- \\[\x20-\x21\x23-\x2e\x30-\x5b\x5d-\x61\x63-\x65\x67-\x6d\x6f-\x71\x73\x75-\xff])*)
- "/nx
- INTEGER = /(-?0|-?[1-9]\d*)/
- FLOAT = /(-?
- (?:0|[1-9]\d*)
- (?:
- \.\d+(?i:e[+-]?\d+) |
- \.\d+ |
- (?i:e[+-]?\d+)
- )
- )/x
- NAN = /NaN/
- INFINITY = /Infinity/
- MINUS_INFINITY = /-Infinity/
- OBJECT_OPEN = /\{/
- OBJECT_CLOSE = /\}/
- ARRAY_OPEN = /\[/
- ARRAY_CLOSE = /\]/
- PAIR_DELIMITER = /:/
- COLLECTION_DELIMITER = /,/
- TRUE = /true/
- FALSE = /false/
- NULL = /null/
- IGNORE = %r(
- (?:
- //[^\n\r]*[\n\r]| # line comments
- /\* # c-style comments
- (?:
- [^*/]| # normal chars
- /[^*]| # slashes that do not start a nested comment
- \*[^/]| # asterisks that do not end this comment
- /(?=\*/) # single slash before this comment's end
- )*
- \*/ # the End of this comment
- |[ \t\r\n]+ # whitespaces: space, horicontal tab, lf, cr
- )+
- )mx
+ module Pure
+ # This class implements the PSON parser that is used to parse a PSON string
+ # into a Ruby data structure.
+ class Parser < StringScanner
+ STRING = /" ((?:[^\x0-\x1f"\\] |
+ # escaped special characters:
+ \\["\\\/bfnrt] |
+ \\u[0-9a-fA-F]{4} |
+ # match all but escaped special characters:
+ \\[\x20-\x21\x23-\x2e\x30-\x5b\x5d-\x61\x63-\x65\x67-\x6d\x6f-\x71\x73\x75-\xff])*)
+ "/nx
+ INTEGER = /(-?0|-?[1-9]\d*)/
+ FLOAT = /(-?
+ (?:0|[1-9]\d*)
+ (?:
+ \.\d+(?i:e[+-]?\d+) |
+ \.\d+ |
+ (?i:e[+-]?\d+)
+ )
+ )/x
+ NAN = /NaN/
+ INFINITY = /Infinity/
+ MINUS_INFINITY = /-Infinity/
+ OBJECT_OPEN = /\{/
+ OBJECT_CLOSE = /\}/
+ ARRAY_OPEN = /\[/
+ ARRAY_CLOSE = /\]/
+ PAIR_DELIMITER = /:/
+ COLLECTION_DELIMITER = /,/
+ TRUE = /true/
+ FALSE = /false/
+ NULL = /null/
+ IGNORE = %r(
+ (?:
+ //[^\n\r]*[\n\r]| # line comments
+ /\* # c-style comments
+ (?:
+ [^*/]| # normal chars
+ /[^*]| # slashes that do not start a nested comment
+ \*[^/]| # asterisks that do not end this comment
+ /(?=\*/) # single slash before this comment's end
+ )*
+ \*/ # the End of this comment
+ |[ \t\r\n]+ # whitespaces: space, horicontal tab, lf, cr
+ )+
+ )mx
- UNPARSED = Object.new
+ UNPARSED = Object.new
- # Creates a new PSON::Pure::Parser instance for the string _source_.
- #
- # It will be configured by the _opts_ hash. _opts_ can have the following
- # keys:
- # * *max_nesting*: The maximum depth of nesting allowed in the parsed data
- # structures. Disable depth checking with :max_nesting => false|nil|0,
- # it defaults to 19.
- # * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
- # defiance of RFC 4627 to be parsed by the Parser. This option defaults
- # to false.
- # * *create_additions*: If set to false, the Parser doesn't create
- # additions even if a matchin class and create_id was found. This option
- # defaults to true.
- # * *object_class*: Defaults to Hash
- # * *array_class*: Defaults to Array
- def initialize(source, opts = {})
- super
- if !opts.key?(:max_nesting) # defaults to 19
- @max_nesting = 19
- elsif opts[:max_nesting]
- @max_nesting = opts[:max_nesting]
- else
- @max_nesting = 0
- end
- @allow_nan = !!opts[:allow_nan]
- ca = true
- ca = opts[:create_additions] if opts.key?(:create_additions)
- @create_id = ca ? PSON.create_id : nil
- @object_class = opts[:object_class] || Hash
- @array_class = opts[:array_class] || Array
- end
+ # Creates a new PSON::Pure::Parser instance for the string _source_.
+ #
+ # It will be configured by the _opts_ hash. _opts_ can have the following
+ # keys:
+ # * *max_nesting*: The maximum depth of nesting allowed in the parsed data
+ # structures. Disable depth checking with :max_nesting => false|nil|0,
+ # it defaults to 19.
+ # * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
+ # defiance of RFC 4627 to be parsed by the Parser. This option defaults
+ # to false.
+ # * *create_additions*: If set to false, the Parser doesn't create
+ # additions even if a matchin class and create_id was found. This option
+ # defaults to true.
+ # * *object_class*: Defaults to Hash
+ # * *array_class*: Defaults to Array
+ def initialize(source, opts = {})
+ super
+ if !opts.key?(:max_nesting) # defaults to 19
+ @max_nesting = 19
+ elsif opts[:max_nesting]
+ @max_nesting = opts[:max_nesting]
+ else
+ @max_nesting = 0
+ end
+ @allow_nan = !!opts[:allow_nan]
+ ca = true
+ ca = opts[:create_additions] if opts.key?(:create_additions)
+ @create_id = ca ? PSON.create_id : nil
+ @object_class = opts[:object_class] || Hash
+ @array_class = opts[:array_class] || Array
+ end
- alias source string
+ alias source string
- # Parses the current PSON string _source_ and returns the complete data
- # structure as a result.
- def parse
- reset
- obj = nil
- until eos?
- case
- when scan(OBJECT_OPEN)
- obj and raise ParserError, "source '#{peek(20)}' not in PSON!"
- @current_nesting = 1
- obj = parse_object
- when scan(ARRAY_OPEN)
- obj and raise ParserError, "source '#{peek(20)}' not in PSON!"
- @current_nesting = 1
- obj = parse_array
- when skip(IGNORE)
- ;
- else
- raise ParserError, "source '#{peek(20)}' not in PSON!"
- end
- end
- obj or raise ParserError, "source did not contain any PSON!"
- obj
- end
+ # Parses the current PSON string _source_ and returns the complete data
+ # structure as a result.
+ def parse
+ reset
+ obj = nil
+ until eos?
+ case
+ when scan(OBJECT_OPEN)
+ obj and raise ParserError, "source '#{peek(20)}' not in PSON!"
+ @current_nesting = 1
+ obj = parse_object
+ when scan(ARRAY_OPEN)
+ obj and raise ParserError, "source '#{peek(20)}' not in PSON!"
+ @current_nesting = 1
+ obj = parse_array
+ when skip(IGNORE)
+ ;
+ else
+ raise ParserError, "source '#{peek(20)}' not in PSON!"
+ end
+ end
+ obj or raise ParserError, "source did not contain any PSON!"
+ obj
+ end
- private
+ private
- # Unescape characters in strings.
- UNESCAPE_MAP = Hash.new { |h, k| h[k] = k.chr }
+ # Unescape characters in strings.
+ UNESCAPE_MAP = Hash.new { |h, k| h[k] = k.chr }
- UNESCAPE_MAP.update(
- {
- ?" => '"',
- ?\\ => '\\',
- ?/ => '/',
- ?b => "\b",
- ?f => "\f",
- ?n => "\n",
- ?r => "\r",
- ?t => "\t",
- ?u => nil,
+ UNESCAPE_MAP.update(
+ {
+ ?" => '"',
+ ?\\ => '\\',
+ ?/ => '/',
+ ?b => "\b",
+ ?f => "\f",
+ ?n => "\n",
+ ?r => "\r",
+ ?t => "\t",
+ ?u => nil,
- })
+ })
- def parse_string
- if scan(STRING)
- return '' if self[1].empty?
- string = self[1].gsub(%r{(?:\\[\\bfnrt"/]|(?:\\u(?:[A-Fa-f\d]{4}))+|\\[\x20-\xff])}n) do |c|
- if u = UNESCAPE_MAP[$MATCH[1]]
- u
- else # \uXXXX
- bytes = ''
- i = 0
- while c[6 * i] == ?\\ && c[6 * i + 1] == ?u
- bytes << c[6 * i + 2, 2].to_i(16) << c[6 * i + 4, 2].to_i(16)
- i += 1
- end
- PSON::UTF16toUTF8.iconv(bytes)
- end
- end
- string.force_encoding(Encoding::UTF_8) if string.respond_to?(:force_encoding)
- string
- else
- UNPARSED
- end
- rescue Iconv::Failure => e
- raise GeneratorError, "Caught #{e.class}: #{e}"
+ def parse_string
+ if scan(STRING)
+ return '' if self[1].empty?
+ string = self[1].gsub(%r{(?:\\[\\bfnrt"/]|(?:\\u(?:[A-Fa-f\d]{4}))+|\\[\x20-\xff])}n) do |c|
+ if u = UNESCAPE_MAP[$MATCH[1]]
+ u
+ else # \uXXXX
+ bytes = ''
+ i = 0
+ while c[6 * i] == ?\\ && c[6 * i + 1] == ?u
+ bytes << c[6 * i + 2, 2].to_i(16) << c[6 * i + 4, 2].to_i(16)
+ i += 1
+ end
+ PSON::UTF16toUTF8.iconv(bytes)
end
+ end
+ string.force_encoding(Encoding::UTF_8) if string.respond_to?(:force_encoding)
+ string
+ else
+ UNPARSED
+ end
+ rescue Iconv::Failure => e
+ raise GeneratorError, "Caught #{e.class}: #{e}"
+ end
- def parse_value
- case
- when scan(FLOAT)
- Float(self[1])
- when scan(INTEGER)
- Integer(self[1])
- when scan(TRUE)
- true
- when scan(FALSE)
- false
- when scan(NULL)
- nil
- when (string = parse_string) != UNPARSED
- string
- when scan(ARRAY_OPEN)
- @current_nesting += 1
- ary = parse_array
- @current_nesting -= 1
- ary
- when scan(OBJECT_OPEN)
- @current_nesting += 1
- obj = parse_object
- @current_nesting -= 1
- obj
- when @allow_nan && scan(NAN)
- NaN
- when @allow_nan && scan(INFINITY)
- Infinity
- when @allow_nan && scan(MINUS_INFINITY)
- MinusInfinity
- else
- UNPARSED
- end
- end
+ def parse_value
+ case
+ when scan(FLOAT)
+ Float(self[1])
+ when scan(INTEGER)
+ Integer(self[1])
+ when scan(TRUE)
+ true
+ when scan(FALSE)
+ false
+ when scan(NULL)
+ nil
+ when (string = parse_string) != UNPARSED
+ string
+ when scan(ARRAY_OPEN)
+ @current_nesting += 1
+ ary = parse_array
+ @current_nesting -= 1
+ ary
+ when scan(OBJECT_OPEN)
+ @current_nesting += 1
+ obj = parse_object
+ @current_nesting -= 1
+ obj
+ when @allow_nan && scan(NAN)
+ NaN
+ when @allow_nan && scan(INFINITY)
+ Infinity
+ when @allow_nan && scan(MINUS_INFINITY)
+ MinusInfinity
+ else
+ UNPARSED
+ end
+ end
- def parse_array
- raise NestingError, "nesting of #@current_nesting is too deep" if
- @max_nesting.nonzero? && @current_nesting > @max_nesting
- result = @array_class.new
- delim = false
- until eos?
- case
- when (value = parse_value) != UNPARSED
- delim = false
- result << value
- skip(IGNORE)
- if scan(COLLECTION_DELIMITER)
- delim = true
- elsif match?(ARRAY_CLOSE)
- ;
- else
- raise ParserError, "expected ',' or ']' in array at '#{peek(20)}'!"
- end
- when scan(ARRAY_CLOSE)
- raise ParserError, "expected next element in array at '#{peek(20)}'!" if delim
- break
- when skip(IGNORE)
- ;
- else
- raise ParserError, "unexpected token in array at '#{peek(20)}'!"
- end
- end
- result
+ def parse_array
+ raise NestingError, "nesting of #@current_nesting is too deep" if
+ @max_nesting.nonzero? && @current_nesting > @max_nesting
+ result = @array_class.new
+ delim = false
+ until eos?
+ case
+ when (value = parse_value) != UNPARSED
+ delim = false
+ result << value
+ skip(IGNORE)
+ if scan(COLLECTION_DELIMITER)
+ delim = true
+ elsif match?(ARRAY_CLOSE)
+ ;
+ else
+ raise ParserError, "expected ',' or ']' in array at '#{peek(20)}'!"
end
+ when scan(ARRAY_CLOSE)
+ raise ParserError, "expected next element in array at '#{peek(20)}'!" if delim
+ break
+ when skip(IGNORE)
+ ;
+ else
+ raise ParserError, "unexpected token in array at '#{peek(20)}'!"
+ end
+ end
+ result
+ end
- def parse_object
- raise NestingError, "nesting of #@current_nesting is too deep" if
- @max_nesting.nonzero? && @current_nesting > @max_nesting
- result = @object_class.new
- delim = false
- until eos?
- case
- when (string = parse_string) != UNPARSED
- skip(IGNORE)
- raise ParserError, "expected ':' in object at '#{peek(20)}'!" unless scan(PAIR_DELIMITER)
- skip(IGNORE)
- unless (value = parse_value).equal? UNPARSED
- result[string] = value
- delim = false
- skip(IGNORE)
- if scan(COLLECTION_DELIMITER)
- delim = true
- elsif match?(OBJECT_CLOSE)
- ;
- else
- raise ParserError, "expected ',' or '}' in object at '#{peek(20)}'!"
- end
- else
- raise ParserError, "expected value in object at '#{peek(20)}'!"
- end
- when scan(OBJECT_CLOSE)
- raise ParserError, "expected next name, value pair in object at '#{peek(20)}'!" if delim
- if @create_id and klassname = result[@create_id]
- klass = PSON.deep_const_get klassname
- break unless klass and klass.pson_creatable?
- result = klass.pson_create(result)
- end
- break
- when skip(IGNORE)
- ;
- else
- raise ParserError, "unexpected token in object at '#{peek(20)}'!"
- end
- end
- result
+ def parse_object
+ raise NestingError, "nesting of #@current_nesting is too deep" if
+ @max_nesting.nonzero? && @current_nesting > @max_nesting
+ result = @object_class.new
+ delim = false
+ until eos?
+ case
+ when (string = parse_string) != UNPARSED
+ skip(IGNORE)
+ raise ParserError, "expected ':' in object at '#{peek(20)}'!" unless scan(PAIR_DELIMITER)
+ skip(IGNORE)
+ unless (value = parse_value).equal? UNPARSED
+ result[string] = value
+ delim = false
+ skip(IGNORE)
+ if scan(COLLECTION_DELIMITER)
+ delim = true
+ elsif match?(OBJECT_CLOSE)
+ ;
+ else
+ raise ParserError, "expected ',' or '}' in object at '#{peek(20)}'!"
+ end
+ else
+ raise ParserError, "expected value in object at '#{peek(20)}'!"
+ end
+ when scan(OBJECT_CLOSE)
+ raise ParserError, "expected next name, value pair in object at '#{peek(20)}'!" if delim
+ if @create_id and klassname = result[@create_id]
+ klass = PSON.deep_const_get klassname
+ break unless klass and klass.pson_creatable?
+ result = klass.pson_create(result)
end
+ break
+ when skip(IGNORE)
+ ;
+ else
+ raise ParserError, "unexpected token in object at '#{peek(20)}'!"
+ end
end
+ result
+ end
end
+ end
end
diff --git a/lib/puppet/external/pson/version.rb b/lib/puppet/external/pson/version.rb
index 0bcfa4a..a5a8e47 100644
--- a/lib/puppet/external/pson/version.rb
+++ b/lib/puppet/external/pson/version.rb
@@ -1,8 +1,8 @@
module PSON
- # PSON version
- VERSION = '1.1.9'
- VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
- VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
- VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
- VERSION_BUILD = VERSION_ARRAY[2] # :nodoc:
+ # PSON version
+ VERSION = '1.1.9'
+ VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
+ VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
+ VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
+ VERSION_BUILD = VERSION_ARRAY[2] # :nodoc:
end
diff --git a/lib/puppet/feature/base.rb b/lib/puppet/feature/base.rb
index f11fb00..c153fba 100644
--- a/lib/puppet/feature/base.rb
+++ b/lib/puppet/feature/base.rb
@@ -37,8 +37,8 @@ Puppet.features.add(:syslog, :libs => ["syslog"])
# We can use POSIX user functions
Puppet.features.add(:posix) do
- require 'etc'
- Etc.getpwuid(0) != nil && Puppet.features.syslog?
+ require 'etc'
+ Etc.getpwuid(0) != nil && Puppet.features.syslog?
end
# We can use Microsoft Windows functions
diff --git a/lib/puppet/feature/pson.rb b/lib/puppet/feature/pson.rb
index 21576c6..0ebb280 100644
--- a/lib/puppet/feature/pson.rb
+++ b/lib/puppet/feature/pson.rb
@@ -1,6 +1,6 @@
Puppet.features.add(:pson) do
- require 'puppet/external/pson/common'
- require 'puppet/external/pson/version'
- require 'puppet/external/pson/pure'
- true
+ require 'puppet/external/pson/common'
+ require 'puppet/external/pson/version'
+ require 'puppet/external/pson/pure'
+ true
end
diff --git a/lib/puppet/feature/rack.rb b/lib/puppet/feature/rack.rb
index b91aa13..8d101ff 100644
--- a/lib/puppet/feature/rack.rb
+++ b/lib/puppet/feature/rack.rb
@@ -3,22 +3,22 @@ require 'puppet/util/feature'
# See if we have rack available, an HTTP Application Stack
# Explicitly depend on rack library version >= 1.0.0
Puppet.features.add(:rack) do
- begin
- require 'rack'
- rescue LoadError => detail
- require 'rubygems'
- require 'rack'
- end
+ begin
+ require 'rack'
+ rescue LoadError => detail
+ require 'rubygems'
+ require 'rack'
+ end
- if ! (defined?(::Rack) and defined?(::Rack.release))
- false
+ if ! (defined?(::Rack) and defined?(::Rack.release))
+ false
+ else
+ major_version = ::Rack.release.split('.')[0].to_i
+ if major_version >= 1
+ true
else
- major_version = ::Rack.release.split('.')[0].to_i
- if major_version >= 1
- true
- else
- false
- end
+ false
end
+ end
end
diff --git a/lib/puppet/feature/rails.rb b/lib/puppet/feature/rails.rb
index 05d416e..e0e14eb 100644
--- a/lib/puppet/feature/rails.rb
+++ b/lib/puppet/feature/rails.rb
@@ -6,30 +6,30 @@ require 'puppet/util/feature'
Puppet.features.rubygems?
Puppet.features.add(:rails) do
- begin
- require 'active_record'
- require 'active_record/version'
- rescue LoadError => detail
- if FileTest.exists?("/usr/share/rails")
- count = 0
- Dir.entries("/usr/share/rails").each do |dir|
- libdir = File.join("/usr/share/rails", dir, "lib")
- if FileTest.exists?(libdir) and ! $LOAD_PATH.include?(libdir)
- count += 1
- $LOAD_PATH << libdir
- end
- end
-
- retry if count > 0
+ begin
+ require 'active_record'
+ require 'active_record/version'
+ rescue LoadError => detail
+ if FileTest.exists?("/usr/share/rails")
+ count = 0
+ Dir.entries("/usr/share/rails").each do |dir|
+ libdir = File.join("/usr/share/rails", dir, "lib")
+ if FileTest.exists?(libdir) and ! $LOAD_PATH.include?(libdir)
+ count += 1
+ $LOAD_PATH << libdir
end
- end
+ end
- if ! (defined?(::ActiveRecord) and defined?(::ActiveRecord::VERSION) and defined?(::ActiveRecord::VERSION::MAJOR) and defined?(::ActiveRecord::VERSION::MINOR))
- false
- elsif ! (::ActiveRecord::VERSION::MAJOR == 2 and ::ActiveRecord::VERSION::MINOR >= 1)
- Puppet.info "ActiveRecord 2.1 or later required for StoreConfigs"
- false
- else
- true
+ retry if count > 0
end
+ end
+
+ if ! (defined?(::ActiveRecord) and defined?(::ActiveRecord::VERSION) and defined?(::ActiveRecord::VERSION::MAJOR) and defined?(::ActiveRecord::VERSION::MINOR))
+ false
+ elsif ! (::ActiveRecord::VERSION::MAJOR == 2 and ::ActiveRecord::VERSION::MINOR >= 1)
+ Puppet.info "ActiveRecord 2.1 or later required for StoreConfigs"
+ false
+ else
+ true
+ end
end
diff --git a/lib/puppet/file_bucket.rb b/lib/puppet/file_bucket.rb
index 881c81e..5eafcd2 100644
--- a/lib/puppet/file_bucket.rb
+++ b/lib/puppet/file_bucket.rb
@@ -1,4 +1,4 @@
# stub
module Puppet::FileBucket
- class BucketError < RuntimeError; end
+ class BucketError < RuntimeError; end
end
diff --git a/lib/puppet/file_bucket/dipper.rb b/lib/puppet/file_bucket/dipper.rb
index 08192aa..dbfcdcd 100644
--- a/lib/puppet/file_bucket/dipper.rb
+++ b/lib/puppet/file_bucket/dipper.rb
@@ -3,97 +3,97 @@ require 'puppet/file_bucket/file'
require 'puppet/indirector/request'
class Puppet::FileBucket::Dipper
- # This is a transitional implementation that uses REST
- # to access remote filebucket files.
+ # This is a transitional implementation that uses REST
+ # to access remote filebucket files.
- attr_accessor :name
+ attr_accessor :name
- # Create our bucket client
- def initialize(hash = {})
- # Emulate the XMLRPC client
- server = hash[:Server]
- port = hash[:Port] || Puppet[:masterport]
- environment = Puppet[:environment]
+ # Create our bucket client
+ def initialize(hash = {})
+ # Emulate the XMLRPC client
+ server = hash[:Server]
+ port = hash[:Port] || Puppet[:masterport]
+ environment = Puppet[:environment]
- if hash.include?(:Path)
- @local_path = hash[:Path]
- @rest_path = nil
- else
- @local_path = nil
- @rest_path = "https://#{server}:#{port}/#{environment}/file_bucket_file/"
- end
+ if hash.include?(:Path)
+ @local_path = hash[:Path]
+ @rest_path = nil
+ else
+ @local_path = nil
+ @rest_path = "https://#{server}:#{port}/#{environment}/file_bucket_file/"
end
+ end
- def local?
- !! @local_path
- end
+ def local?
+ !! @local_path
+ end
- # Back up a file to our bucket
- def backup(file)
- raise(ArgumentError, "File #{file} does not exist") unless ::File.exist?(file)
- contents = ::File.read(file)
- begin
- file_bucket_file = Puppet::FileBucket::File.new(contents, :bucket_path => @local_path, :path => absolutize_path(file) )
- dest_path = "#{@rest_path}#{file_bucket_file.name}"
+ # Back up a file to our bucket
+ def backup(file)
+ raise(ArgumentError, "File #{file} does not exist") unless ::File.exist?(file)
+ contents = ::File.read(file)
+ begin
+ file_bucket_file = Puppet::FileBucket::File.new(contents, :bucket_path => @local_path, :path => absolutize_path(file) )
+ dest_path = "#{@rest_path}#{file_bucket_file.name}"
- file_bucket_file.save(dest_path)
- return file_bucket_file.checksum_data
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- raise Puppet::Error, "Could not back up #{file}: #{detail}"
- end
+ file_bucket_file.save(dest_path)
+ return file_bucket_file.checksum_data
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ raise Puppet::Error, "Could not back up #{file}: #{detail}"
end
+ end
- # Retrieve a file by sum.
- def getfile(sum)
- source_path = "#{@rest_path}md5/#{sum}"
- file_bucket_file = Puppet::FileBucket::File.find(source_path, :bucket_path => @local_path)
+ # Retrieve a file by sum.
+ def getfile(sum)
+ source_path = "#{@rest_path}md5/#{sum}"
+ file_bucket_file = Puppet::FileBucket::File.find(source_path, :bucket_path => @local_path)
- raise Puppet::Error, "File not found" unless file_bucket_file
- file_bucket_file.to_s
- end
+ raise Puppet::Error, "File not found" unless file_bucket_file
+ file_bucket_file.to_s
+ end
- # Restore the file
- def restore(file,sum)
- restore = true
- if FileTest.exists?(file)
- cursum = Digest::MD5.hexdigest(::File.read(file))
+ # Restore the file
+ def restore(file,sum)
+ restore = true
+ if FileTest.exists?(file)
+ cursum = Digest::MD5.hexdigest(::File.read(file))
- # if the checksum has changed...
- # this might be extra effort
- if cursum == sum
- restore = false
- end
- end
+ # if the checksum has changed...
+ # this might be extra effort
+ if cursum == sum
+ restore = false
+ end
+ end
- if restore
- if newcontents = getfile(sum)
- tmp = ""
- newsum = Digest::MD5.hexdigest(newcontents)
- changed = nil
- if FileTest.exists?(file) and ! FileTest.writable?(file)
- changed = ::File.stat(file).mode
- ::File.chmod(changed | 0200, file)
- end
- ::File.open(file, ::File::WRONLY|::File::TRUNC|::File::CREAT) { |of|
- of.print(newcontents)
- }
- ::File.chmod(changed, file) if changed
- else
- Puppet.err "Could not find file with checksum #{sum}"
- return nil
- end
- return newsum
- else
- return nil
+ if restore
+ if newcontents = getfile(sum)
+ tmp = ""
+ newsum = Digest::MD5.hexdigest(newcontents)
+ changed = nil
+ if FileTest.exists?(file) and ! FileTest.writable?(file)
+ changed = ::File.stat(file).mode
+ ::File.chmod(changed | 0200, file)
end
+ ::File.open(file, ::File::WRONLY|::File::TRUNC|::File::CREAT) { |of|
+ of.print(newcontents)
+ }
+ ::File.chmod(changed, file) if changed
+ else
+ Puppet.err "Could not find file with checksum #{sum}"
+ return nil
+ end
+ return newsum
+ else
+ return nil
end
+ end
- private
- def absolutize_path( path )
- require 'pathname'
- Pathname.new(path).realpath
- end
+ private
+ def absolutize_path( path )
+ require 'pathname'
+ Pathname.new(path).realpath
+ end
end
diff --git a/lib/puppet/file_bucket/file.rb b/lib/puppet/file_bucket/file.rb
index 52ee4f7..96fd8e2 100644
--- a/lib/puppet/file_bucket/file.rb
+++ b/lib/puppet/file_bucket/file.rb
@@ -3,134 +3,134 @@ require 'puppet/indirector'
require 'puppet/util/checksums'
class Puppet::FileBucket::File
- include Puppet::Util::Checksums
-
- # This class handles the abstract notion of a file in a filebucket.
- # There are mechanisms to save and load this file locally and remotely in puppet/indirector/filebucketfile/*
- # There is a compatibility class that emulates pre-indirector filebuckets in Puppet::FileBucket::Dipper
- extend Puppet::Indirector
- require 'puppet/file_bucket/file/indirection_hooks'
- indirects :file_bucket_file, :terminus_class => :file, :extend => Puppet::FileBucket::File::IndirectionHooks
-
- attr :path, true
- attr :paths, true
- attr :contents, true
- attr :checksum_type
- attr :bucket_path, true
-
- def self.default_checksum_type
- "md5"
- end
-
- def initialize( contents, options = {} )
- @bucket_path = options[:bucket_path]
- @path = options[:path]
- @paths = options[:paths] || []
-
- @checksum = options[:checksum]
- @checksum_type = options[:checksum_type]
-
- self.contents = contents
-
- yield(self) if block_given?
-
- validate!
- end
-
- def validate!
- validate_checksum_type!(checksum_type)
- validate_checksum!(checksum) if checksum
- end
-
- def contents=(str)
- raise "You may not change the contents of a FileBucket File" if @contents
- validate_content!(str)
- @contents = str
- end
-
- def checksum
- return @checksum if @checksum
- @checksum = calculate_checksum if contents
- @checksum
- end
-
- def checksum=(checksum)
- validate_checksum!(checksum)
- @checksum = checksum
- end
-
- def checksum_type=( new_checksum_type )
- @checksum = nil
- @checksum_type = new_checksum_type
- end
-
- def checksum_type
- unless @checksum_type
- if @checksum
- @checksum_type = sumtype(checksum)
- else
- @checksum_type = self.class.default_checksum_type
- end
- end
- @checksum_type
- end
-
- def checksum_data
- sumdata(checksum)
- end
-
- def to_s
- contents
- end
-
- def name
- [checksum_type, checksum_data, path].compact.join('/')
- end
-
- def name=(name)
- data = name.split('/',3)
- self.path = data.pop
- @checksum_type = nil
- self.checksum = "{#{data[0]}}#{data[1]}"
- end
-
- def conflict_check?
- true
- end
-
- def self.from_s( contents )
- self.new( contents )
- end
-
- def to_pson
- hash = { "contents" => contents }
- hash["path"] = @path if @path
- hash.to_pson
- end
-
- def self.from_pson( pson )
- self.new( pson["contents"], :path => pson["path"] )
- end
-
- private
-
- def calculate_checksum
- "{#{checksum_type}}" + send(checksum_type, contents)
- end
-
- def validate_content!(content)
- raise ArgumentError, "Contents must be a string" if content and ! content.is_a?(String)
- end
-
- def validate_checksum!(new_checksum)
- newtype = sumtype(new_checksum)
-
- unless sumdata(new_checksum) == (calc_sum = send(newtype, contents))
- raise Puppet::Error, "Checksum #{new_checksum} does not match contents #{calc_sum}"
- end
- end
-
- def validate_checksum_type!(type)
- raise ArgumentError, "Invalid checksum type #{type}" unless respond_to?(type)
- end
+ include Puppet::Util::Checksums
+
+ # This class handles the abstract notion of a file in a filebucket.
+ # There are mechanisms to save and load this file locally and remotely in puppet/indirector/filebucketfile/*
+ # There is a compatibility class that emulates pre-indirector filebuckets in Puppet::FileBucket::Dipper
+ extend Puppet::Indirector
+ require 'puppet/file_bucket/file/indirection_hooks'
+ indirects :file_bucket_file, :terminus_class => :file, :extend => Puppet::FileBucket::File::IndirectionHooks
+
+ attr :path, true
+ attr :paths, true
+ attr :contents, true
+ attr :checksum_type
+ attr :bucket_path, true
+
+ def self.default_checksum_type
+ "md5"
+ end
+
+ def initialize( contents, options = {} )
+ @bucket_path = options[:bucket_path]
+ @path = options[:path]
+ @paths = options[:paths] || []
+
+ @checksum = options[:checksum]
+ @checksum_type = options[:checksum_type]
+
+ self.contents = contents
+
+ yield(self) if block_given?
+
+ validate!
+ end
+
+ def validate!
+ validate_checksum_type!(checksum_type)
+ validate_checksum!(checksum) if checksum
+ end
+
+ def contents=(str)
+ raise "You may not change the contents of a FileBucket File" if @contents
+ validate_content!(str)
+ @contents = str
+ end
+
+ def checksum
+ return @checksum if @checksum
+ @checksum = calculate_checksum if contents
+ @checksum
+ end
+
+ def checksum=(checksum)
+ validate_checksum!(checksum)
+ @checksum = checksum
+ end
+
+ def checksum_type=( new_checksum_type )
+ @checksum = nil
+ @checksum_type = new_checksum_type
+ end
+
+ def checksum_type
+ unless @checksum_type
+ if @checksum
+ @checksum_type = sumtype(checksum)
+ else
+ @checksum_type = self.class.default_checksum_type
+ end
+ end
+ @checksum_type
+ end
+
+ def checksum_data
+ sumdata(checksum)
+ end
+
+ def to_s
+ contents
+ end
+
+ def name
+ [checksum_type, checksum_data, path].compact.join('/')
+ end
+
+ def name=(name)
+ data = name.split('/',3)
+ self.path = data.pop
+ @checksum_type = nil
+ self.checksum = "{#{data[0]}}#{data[1]}"
+ end
+
+ def conflict_check?
+ true
+ end
+
+ def self.from_s( contents )
+ self.new( contents )
+ end
+
+ def to_pson
+ hash = { "contents" => contents }
+ hash["path"] = @path if @path
+ hash.to_pson
+ end
+
+ def self.from_pson( pson )
+ self.new( pson["contents"], :path => pson["path"] )
+ end
+
+ private
+
+ def calculate_checksum
+ "{#{checksum_type}}" + send(checksum_type, contents)
+ end
+
+ def validate_content!(content)
+ raise ArgumentError, "Contents must be a string" if content and ! content.is_a?(String)
+ end
+
+ def validate_checksum!(new_checksum)
+ newtype = sumtype(new_checksum)
+
+ unless sumdata(new_checksum) == (calc_sum = send(newtype, contents))
+ raise Puppet::Error, "Checksum #{new_checksum} does not match contents #{calc_sum}"
+ end
+ end
+
+ def validate_checksum_type!(type)
+ raise ArgumentError, "Invalid checksum type #{type}" unless respond_to?(type)
+ end
end
diff --git a/lib/puppet/file_bucket/file/indirection_hooks.rb b/lib/puppet/file_bucket/file/indirection_hooks.rb
index ab0912b..58c2927 100644
--- a/lib/puppet/file_bucket/file/indirection_hooks.rb
+++ b/lib/puppet/file_bucket/file/indirection_hooks.rb
@@ -3,7 +3,7 @@ require 'puppet/file_bucket/file'
# This module is used to pick the appropriate terminus
# in filebucket indirections.
module Puppet::FileBucket::File::IndirectionHooks
- def select_terminus(request)
- return(request.protocol == 'https' ? :rest : Puppet::FileBucket::File.indirection.terminus_class)
- end
+ def select_terminus(request)
+ return(request.protocol == 'https' ? :rest : Puppet::FileBucket::File.indirection.terminus_class)
+ end
end
diff --git a/lib/puppet/file_collection.rb b/lib/puppet/file_collection.rb
index 7db2600..a7bdd04 100644
--- a/lib/puppet/file_collection.rb
+++ b/lib/puppet/file_collection.rb
@@ -1,30 +1,30 @@
# A simple way to turn file names into singletons,
# so we don't have tons of copies of each file path around.
class Puppet::FileCollection
- require 'puppet/file_collection/lookup'
+ require 'puppet/file_collection/lookup'
- def self.collection
- @collection
- end
+ def self.collection
+ @collection
+ end
- def initialize
- @paths = []
- @inverse = {}
- end
+ def initialize
+ @paths = []
+ @inverse = {}
+ end
- def index(path)
- if i = @inverse[path]
- return i
- else
- @paths << path
- i = @inverse[path] = @paths.length - 1
- return i
- end
+ def index(path)
+ if i = @inverse[path]
+ return i
+ else
+ @paths << path
+ i = @inverse[path] = @paths.length - 1
+ return i
end
+ end
- def path(index)
- @paths[index]
- end
+ def path(index)
+ @paths[index]
+ end
- @collection = self.new
+ @collection = self.new
end
diff --git a/lib/puppet/file_collection/lookup.rb b/lib/puppet/file_collection/lookup.rb
index ddb0c84..3067948 100644
--- a/lib/puppet/file_collection/lookup.rb
+++ b/lib/puppet/file_collection/lookup.rb
@@ -3,18 +3,18 @@ require 'puppet/file_collection'
# A simple module for looking up file paths and indexes
# in a file collection.
module Puppet::FileCollection::Lookup
- attr_accessor :line, :file_index
+ attr_accessor :line, :file_index
- def file_collection
- Puppet::FileCollection.collection
- end
+ def file_collection
+ Puppet::FileCollection.collection
+ end
- def file=(path)
- @file_index = file_collection.index(path)
- end
+ def file=(path)
+ @file_index = file_collection.index(path)
+ end
- def file
- return nil unless file_index
- file_collection.path(file_index)
- end
+ def file
+ return nil unless file_index
+ file_collection.path(file_index)
+ end
end
diff --git a/lib/puppet/file_serving/base.rb b/lib/puppet/file_serving/base.rb
index 379012f..09cab97 100644
--- a/lib/puppet/file_serving/base.rb
+++ b/lib/puppet/file_serving/base.rb
@@ -7,82 +7,82 @@ require 'puppet/file_serving'
# The base class for Content and Metadata; provides common
# functionality like the behaviour around links.
class Puppet::FileServing::Base
- # This is for external consumers to store the source that was used
- # to retrieve the metadata.
- attr_accessor :source
+ # This is for external consumers to store the source that was used
+ # to retrieve the metadata.
+ attr_accessor :source
- # Does our file exist?
- def exist?
- stat
- return true
- rescue => detail
- return false
- end
+ # Does our file exist?
+ def exist?
+ stat
+ return true
+ rescue => detail
+ return false
+ end
- # Return the full path to our file. Fails if there's no path set.
- def full_path(dummy_argument=:work_arround_for_ruby_GC_bug)
- (if relative_path.nil? or relative_path == "" or relative_path == "."
- path
- else
- File.join(path, relative_path)
- end).gsub(%r{/+}, "/")
- end
+ # Return the full path to our file. Fails if there's no path set.
+ def full_path(dummy_argument=:work_arround_for_ruby_GC_bug)
+ (if relative_path.nil? or relative_path == "" or relative_path == "."
+ path
+ else
+ File.join(path, relative_path)
+ end).gsub(%r{/+}, "/")
+ end
- def initialize(path, options = {})
- self.path = path
- @links = :manage
+ def initialize(path, options = {})
+ self.path = path
+ @links = :manage
- options.each do |param, value|
- begin
- send param.to_s + "=", value
- rescue NoMethodError
- raise ArgumentError, "Invalid option #{param} for #{self.class}"
- end
- end
+ options.each do |param, value|
+ begin
+ send param.to_s + "=", value
+ rescue NoMethodError
+ raise ArgumentError, "Invalid option #{param} for #{self.class}"
+ end
end
+ end
- # Determine how we deal with links.
- attr_reader :links
- def links=(value)
- value = value.to_sym
- value = :manage if value == :ignore
- raise(ArgumentError, ":links can only be set to :manage or :follow") unless [:manage, :follow].include?(value)
- @links = value
- end
+ # Determine how we deal with links.
+ attr_reader :links
+ def links=(value)
+ value = value.to_sym
+ value = :manage if value == :ignore
+ raise(ArgumentError, ":links can only be set to :manage or :follow") unless [:manage, :follow].include?(value)
+ @links = value
+ end
- # Set our base path.
- attr_reader :path
- def path=(path)
- raise ArgumentError.new("Paths must be fully qualified") unless path =~ /^#{::File::SEPARATOR}/
- @path = path
- end
+ # Set our base path.
+ attr_reader :path
+ def path=(path)
+ raise ArgumentError.new("Paths must be fully qualified") unless path =~ /^#{::File::SEPARATOR}/
+ @path = path
+ end
- # Set a relative path; this is used for recursion, and sets
- # the file's path relative to the initial recursion point.
- attr_reader :relative_path
- def relative_path=(path)
- raise ArgumentError.new("Relative paths must not be fully qualified") if path =~ /^#{::File::SEPARATOR}/
- @relative_path = path
- end
+ # Set a relative path; this is used for recursion, and sets
+ # the file's path relative to the initial recursion point.
+ attr_reader :relative_path
+ def relative_path=(path)
+ raise ArgumentError.new("Relative paths must not be fully qualified") if path =~ /^#{::File::SEPARATOR}/
+ @relative_path = path
+ end
- # Stat our file, using the appropriate link-sensitive method.
- def stat
- @stat_method ||= self.links == :manage ? :lstat : :stat
- File.send(@stat_method, full_path)
- end
+ # Stat our file, using the appropriate link-sensitive method.
+ def stat
+ @stat_method ||= self.links == :manage ? :lstat : :stat
+ File.send(@stat_method, full_path)
+ end
- def to_pson_data_hash
- {
- # No 'document_type' since we don't send these bare
- 'data' => {
- 'path' => @path,
- 'relative_path' => @relative_path,
- 'links' => @links
- },
- 'metadata' => {
- 'api_version' => 1
- }
+ def to_pson_data_hash
+ {
+ # No 'document_type' since we don't send these bare
+ 'data' => {
+ 'path' => @path,
+ 'relative_path' => @relative_path,
+ 'links' => @links
+ },
+ 'metadata' => {
+ 'api_version' => 1
}
- end
+ }
+ end
end
diff --git a/lib/puppet/file_serving/configuration.rb b/lib/puppet/file_serving/configuration.rb
index 425213e..78e4de6 100644
--- a/lib/puppet/file_serving/configuration.rb
+++ b/lib/puppet/file_serving/configuration.rb
@@ -11,117 +11,117 @@ require 'puppet/file_serving/mount/plugins'
require 'puppet/util/cacher'
class Puppet::FileServing::Configuration
- require 'puppet/file_serving/configuration/parser'
+ require 'puppet/file_serving/configuration/parser'
- class << self
- include Puppet::Util::Cacher
- cached_attr(:configuration) { new }
- end
-
- Mount = Puppet::FileServing::Mount
+ class << self
+ include Puppet::Util::Cacher
+ cached_attr(:configuration) { new }
+ end
- # Create our singleton configuration.
- def self.create
- configuration
- end
+ Mount = Puppet::FileServing::Mount
- private_class_method :new
+ # Create our singleton configuration.
+ def self.create
+ configuration
+ end
- attr_reader :mounts
- #private :mounts
+ private_class_method :new
- # Find the right mount. Does some shenanigans to support old-style module
- # mounts.
- def find_mount(mount_name, environment)
- # Reparse the configuration if necessary.
- readconfig
+ attr_reader :mounts
+ #private :mounts
- if mount = mounts[mount_name]
- return mount
- end
+ # Find the right mount. Does some shenanigans to support old-style module
+ # mounts.
+ def find_mount(mount_name, environment)
+ # Reparse the configuration if necessary.
+ readconfig
- if environment.module(mount_name)
- Puppet::Util::Warnings.notice_once "DEPRECATION NOTICE: Files found in modules without specifying 'modules' in file path will be deprecated in the next major release. Please fix module '#{mount_name}' when no 0.24.x clients are present"
- return mounts["modules"]
- end
-
- # This can be nil.
- mounts[mount_name]
+ if mount = mounts[mount_name]
+ return mount
end
- def initialize
- @mounts = {}
- @config_file = nil
-
- # We don't check to see if the file is modified the first time,
- # because we always want to parse at first.
- readconfig(false)
+ if environment.module(mount_name)
+ Puppet::Util::Warnings.notice_once "DEPRECATION NOTICE: Files found in modules without specifying 'modules' in file path will be deprecated in the next major release. Please fix module '#{mount_name}' when no 0.24.x clients are present"
+ return mounts["modules"]
end
- # Is a given mount available?
- def mounted?(name)
- @mounts.include?(name)
- end
+ # This can be nil.
+ mounts[mount_name]
+ end
+
+ def initialize
+ @mounts = {}
+ @config_file = nil
- # Split the path into the separate mount point and path.
- def split_path(request)
- # Reparse the configuration if necessary.
- readconfig
+ # We don't check to see if the file is modified the first time,
+ # because we always want to parse at first.
+ readconfig(false)
+ end
- mount_name, path = request.key.split(File::Separator, 2)
+ # Is a given mount available?
+ def mounted?(name)
+ @mounts.include?(name)
+ end
- raise(ArgumentError, "Cannot find file: Invalid path '#{mount_name}'") unless mount_name =~ %r{^[-\w]+$}
+ # Split the path into the separate mount point and path.
+ def split_path(request)
+ # Reparse the configuration if necessary.
+ readconfig
- return nil unless mount = find_mount(mount_name, request.environment)
- if mount.name == "modules" and mount_name != "modules"
- # yay backward-compatibility
- path = "#{mount_name}/#{path}"
- end
+ mount_name, path = request.key.split(File::Separator, 2)
- if path == ""
- path = nil
- elsif path
- # Remove any double slashes that might have occurred
- path = path.gsub(/\/+/, "/")
- end
+ raise(ArgumentError, "Cannot find file: Invalid path '#{mount_name}'") unless mount_name =~ %r{^[-\w]+$}
- return mount, path
+ return nil unless mount = find_mount(mount_name, request.environment)
+ if mount.name == "modules" and mount_name != "modules"
+ # yay backward-compatibility
+ path = "#{mount_name}/#{path}"
end
- def umount(name)
- @mounts.delete(name) if @mounts.include? name
+ if path == ""
+ path = nil
+ elsif path
+ # Remove any double slashes that might have occurred
+ path = path.gsub(/\/+/, "/")
end
- private
+ return mount, path
+ end
- def mk_default_mounts
- @mounts["modules"] ||= Mount::Modules.new("modules")
- @mounts["modules"].allow('*') if @mounts["modules"].empty?
- @mounts["plugins"] ||= Mount::Plugins.new("plugins")
- @mounts["plugins"].allow('*') if @mounts["plugins"].empty?
- end
+ def umount(name)
+ @mounts.delete(name) if @mounts.include? name
+ end
- # Read the configuration file.
- def readconfig(check = true)
- config = Puppet[:fileserverconfig]
+ private
- return unless FileTest.exists?(config)
+ def mk_default_mounts
+ @mounts["modules"] ||= Mount::Modules.new("modules")
+ @mounts["modules"].allow('*') if @mounts["modules"].empty?
+ @mounts["plugins"] ||= Mount::Plugins.new("plugins")
+ @mounts["plugins"].allow('*') if @mounts["plugins"].empty?
+ end
- @parser ||= Puppet::FileServing::Configuration::Parser.new(config)
+ # Read the configuration file.
+ def readconfig(check = true)
+ config = Puppet[:fileserverconfig]
- return if check and ! @parser.changed?
+ return unless FileTest.exists?(config)
- # Don't assign the mounts hash until we're sure the parsing succeeded.
- begin
- newmounts = @parser.parse
- @mounts = newmounts
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Error parsing fileserver configuration: #{detail}; using old configuration"
- end
+ @parser ||= Puppet::FileServing::Configuration::Parser.new(config)
- ensure
- # Make sure we've got our plugins and modules.
- mk_default_mounts
+ return if check and ! @parser.changed?
+
+ # Don't assign the mounts hash until we're sure the parsing succeeded.
+ begin
+ newmounts = @parser.parse
+ @mounts = newmounts
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Error parsing fileserver configuration: #{detail}; using old configuration"
end
+
+ ensure
+ # Make sure we've got our plugins and modules.
+ mk_default_mounts
+ end
end
diff --git a/lib/puppet/file_serving/configuration/parser.rb b/lib/puppet/file_serving/configuration/parser.rb
index 8e25933..334201d 100644
--- a/lib/puppet/file_serving/configuration/parser.rb
+++ b/lib/puppet/file_serving/configuration/parser.rb
@@ -2,121 +2,121 @@ require 'puppet/file_serving/configuration'
require 'puppet/util/loadedfile'
class Puppet::FileServing::Configuration::Parser < Puppet::Util::LoadedFile
- Mount = Puppet::FileServing::Mount
- MODULES = 'modules'
+ Mount = Puppet::FileServing::Mount
+ MODULES = 'modules'
- # Parse our configuration file.
- def parse
- raise("File server configuration #{self.file} does not exist") unless FileTest.exists?(self.file)
- raise("Cannot read file server configuration #{self.file}") unless FileTest.readable?(self.file)
+ # Parse our configuration file.
+ def parse
+ raise("File server configuration #{self.file} does not exist") unless FileTest.exists?(self.file)
+ raise("Cannot read file server configuration #{self.file}") unless FileTest.readable?(self.file)
- @mounts = {}
- @count = 0
+ @mounts = {}
+ @count = 0
- File.open(self.file) { |f|
- mount = nil
- f.each { |line|
- # Have the count increment at the top, in case we throw exceptions.
- @count += 1
+ File.open(self.file) { |f|
+ mount = nil
+ f.each { |line|
+ # Have the count increment at the top, in case we throw exceptions.
+ @count += 1
- case line
- when /^\s*#/; next # skip comments
- when /^\s*$/; next # skip blank lines
- when /\[([-\w]+)\]/
- mount = newmount($1)
- when /^\s*(\w+)\s+(.+)$/
- var = $1
- value = $2
- raise(ArgumentError, "Fileserver configuration file does not use '=' as a separator") if value =~ /^=/
- case var
- when "path"
- path(mount, value)
- when "allow"
- allow(mount, value)
- when "deny"
- deny(mount, value)
- else
- raise ArgumentError.new("Invalid argument '#{var}'", @count, file)
- end
- else
- raise ArgumentError.new("Invalid line '#{line.chomp}'", @count, file)
- end
- }
- }
+ case line
+ when /^\s*#/; next # skip comments
+ when /^\s*$/; next # skip blank lines
+ when /\[([-\w]+)\]/
+ mount = newmount($1)
+ when /^\s*(\w+)\s+(.+)$/
+ var = $1
+ value = $2
+ raise(ArgumentError, "Fileserver configuration file does not use '=' as a separator") if value =~ /^=/
+ case var
+ when "path"
+ path(mount, value)
+ when "allow"
+ allow(mount, value)
+ when "deny"
+ deny(mount, value)
+ else
+ raise ArgumentError.new("Invalid argument '#{var}'", @count, file)
+ end
+ else
+ raise ArgumentError.new("Invalid line '#{line.chomp}'", @count, file)
+ end
+ }
+ }
- validate
+ validate
- @mounts
- end
+ @mounts
+ end
- private
+ private
- # Allow a given pattern access to a mount.
- def allow(mount, value)
- # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
- x = value.split(/\s*,\s*/).each { |val|
- begin
- mount.info "allowing #{val} access"
- mount.allow(val)
- rescue AuthStoreError => detail
+ # Allow a given pattern access to a mount.
+ def allow(mount, value)
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = value.split(/\s*,\s*/).each { |val|
+ begin
+ mount.info "allowing #{val} access"
+ mount.allow(val)
+ rescue AuthStoreError => detail
- raise ArgumentError.new(
- detail.to_s,
+ raise ArgumentError.new(
+ detail.to_s,
- @count, file)
- end
- }
- end
+ @count, file)
+ end
+ }
+ end
- # Deny a given pattern access to a mount.
- def deny(mount, value)
- # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
- x = value.split(/\s*,\s*/).each { |val|
- begin
- mount.info "denying #{val} access"
- mount.deny(val)
- rescue AuthStoreError => detail
+ # Deny a given pattern access to a mount.
+ def deny(mount, value)
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = value.split(/\s*,\s*/).each { |val|
+ begin
+ mount.info "denying #{val} access"
+ mount.deny(val)
+ rescue AuthStoreError => detail
- raise ArgumentError.new(
- detail.to_s,
+ raise ArgumentError.new(
+ detail.to_s,
- @count, file)
- end
- }
- end
+ @count, file)
+ end
+ }
+ end
- # Create a new mount.
- def newmount(name)
- raise ArgumentError, "#{@mounts[name]} is already mounted at #{name}", @count, file if @mounts.include?(name)
- case name
- when "modules"
- mount = Mount::Modules.new(name)
- when "plugins"
- mount = Mount::Plugins.new(name)
- else
- mount = Mount::File.new(name)
- end
- @mounts[name] = mount
- mount
+ # Create a new mount.
+ def newmount(name)
+ raise ArgumentError, "#{@mounts[name]} is already mounted at #{name}", @count, file if @mounts.include?(name)
+ case name
+ when "modules"
+ mount = Mount::Modules.new(name)
+ when "plugins"
+ mount = Mount::Plugins.new(name)
+ else
+ mount = Mount::File.new(name)
end
+ @mounts[name] = mount
+ mount
+ end
- # Set the path for a mount.
- def path(mount, value)
- if mount.respond_to?(:path=)
- begin
- mount.path = value
- rescue ArgumentError => detail
- Puppet.err "Removing mount #{mount.name}: #{detail}"
- @mounts.delete(mount.name)
- end
- else
- Puppet.warning "The '#{mount.name}' module can not have a path. Ignoring attempt to set it"
- end
+ # Set the path for a mount.
+ def path(mount, value)
+ if mount.respond_to?(:path=)
+ begin
+ mount.path = value
+ rescue ArgumentError => detail
+ Puppet.err "Removing mount #{mount.name}: #{detail}"
+ @mounts.delete(mount.name)
+ end
+ else
+ Puppet.warning "The '#{mount.name}' module can not have a path. Ignoring attempt to set it"
end
+ end
- # Make sure all of our mounts are valid. We have to do this after the fact
- # because details are added over time as the file is parsed.
- def validate
- @mounts.each { |name, mount| mount.validate }
- end
+ # Make sure all of our mounts are valid. We have to do this after the fact
+ # because details are added over time as the file is parsed.
+ def validate
+ @mounts.each { |name, mount| mount.validate }
+ end
end
diff --git a/lib/puppet/file_serving/content.rb b/lib/puppet/file_serving/content.rb
index a7fd204..9cfae7d 100644
--- a/lib/puppet/file_serving/content.rb
+++ b/lib/puppet/file_serving/content.rb
@@ -11,40 +11,40 @@ require 'puppet/file_serving/indirection_hooks'
# It only reads the file when its content is specifically
# asked for.
class Puppet::FileServing::Content < Puppet::FileServing::Base
- extend Puppet::Indirector
- indirects :file_content, :extend => Puppet::FileServing::IndirectionHooks
-
- attr_writer :content
-
- def self.supported_formats
- [:raw]
- end
-
- def self.from_raw(content)
- instance = new("/this/is/a/fake/path")
- instance.content = content
- instance
- end
-
- # BF: we used to fetch the file content here, but this is counter-productive
- # for puppetmaster streaming of file content. So collect just returns itself
- def collect
- return if stat.ftype == "directory"
- self
+ extend Puppet::Indirector
+ indirects :file_content, :extend => Puppet::FileServing::IndirectionHooks
+
+ attr_writer :content
+
+ def self.supported_formats
+ [:raw]
+ end
+
+ def self.from_raw(content)
+ instance = new("/this/is/a/fake/path")
+ instance.content = content
+ instance
+ end
+
+ # BF: we used to fetch the file content here, but this is counter-productive
+ # for puppetmaster streaming of file content. So collect just returns itself
+ def collect
+ return if stat.ftype == "directory"
+ self
+ end
+
+ # Read the content of our file in.
+ def content
+ unless @content
+ # This stat can raise an exception, too.
+ raise(ArgumentError, "Cannot read the contents of links unless following links") if stat.ftype == "symlink"
+
+ @content = ::File.read(full_path)
end
+ @content
+ end
- # Read the content of our file in.
- def content
- unless @content
- # This stat can raise an exception, too.
- raise(ArgumentError, "Cannot read the contents of links unless following links") if stat.ftype == "symlink"
-
- @content = ::File.read(full_path)
- end
- @content
- end
-
- def to_raw
- File.new(full_path, "r")
- end
+ def to_raw
+ File.new(full_path, "r")
+ end
end
diff --git a/lib/puppet/file_serving/fileset.rb b/lib/puppet/file_serving/fileset.rb
index 15d9f9a..fdbcf93 100644
--- a/lib/puppet/file_serving/fileset.rb
+++ b/lib/puppet/file_serving/fileset.rb
@@ -8,164 +8,164 @@ require 'puppet/file_serving/metadata'
# Operate recursively on a path, returning a set of file paths.
class Puppet::FileServing::Fileset
- attr_reader :path, :ignore, :links
- attr_accessor :recurse, :recurselimit, :checksum_type
-
- # Produce a hash of files, with merged so that earlier files
- # with the same postfix win. E.g., /dir1/subfile beats /dir2/subfile.
- # It's a hash because we need to know the relative path of each file,
- # and the base directory.
- # This will probably only ever be used for searching for plugins.
- def self.merge(*filesets)
- result = {}
-
- filesets.each do |fileset|
- fileset.files.each do |file|
- result[file] ||= fileset.path
- end
- end
-
- result
+ attr_reader :path, :ignore, :links
+ attr_accessor :recurse, :recurselimit, :checksum_type
+
+ # Produce a hash of files, with merged so that earlier files
+ # with the same postfix win. E.g., /dir1/subfile beats /dir2/subfile.
+ # It's a hash because we need to know the relative path of each file,
+ # and the base directory.
+ # This will probably only ever be used for searching for plugins.
+ def self.merge(*filesets)
+ result = {}
+
+ filesets.each do |fileset|
+ fileset.files.each do |file|
+ result[file] ||= fileset.path
+ end
end
- # Return a list of all files in our fileset. This is different from the
- # normal definition of find in that we support specific levels
- # of recursion, which means we need to know when we're going another
- # level deep, which Find doesn't do.
- def files
- files = perform_recursion
+ result
+ end
- # Now strip off the leading path, so each file becomes relative, and remove
- # any slashes that might end up at the beginning of the path.
- result = files.collect { |file| file.sub(%r{^#{Regexp.escape(@path)}/*}, '') }
+ # Return a list of all files in our fileset. This is different from the
+ # normal definition of find in that we support specific levels
+ # of recursion, which means we need to know when we're going another
+ # level deep, which Find doesn't do.
+ def files
+ files = perform_recursion
- # And add the path itself.
- result.unshift(".")
+ # Now strip off the leading path, so each file becomes relative, and remove
+ # any slashes that might end up at the beginning of the path.
+ result = files.collect { |file| file.sub(%r{^#{Regexp.escape(@path)}/*}, '') }
- result
- end
-
- # Should we ignore this path?
- def ignore?(path)
- return false if @ignore == [nil]
+ # And add the path itself.
+ result.unshift(".")
- # 'detect' normally returns the found result, whereas we just want true/false.
- ! @ignore.detect { |pattern| File.fnmatch?(pattern, path) }.nil?
- end
-
- def ignore=(values)
- values = [values] unless values.is_a?(Array)
- @ignore = values
- end
+ result
+ end
- def initialize(path, options = {})
- raise ArgumentError.new("Fileset paths must be fully qualified") unless File.expand_path(path) == path
+ # Should we ignore this path?
+ def ignore?(path)
+ return false if @ignore == [nil]
- @path = path
+ # 'detect' normally returns the found result, whereas we just want true/false.
+ ! @ignore.detect { |pattern| File.fnmatch?(pattern, path) }.nil?
+ end
- # Set our defaults.
- @ignore = []
- @links = :manage
- @recurse = false
- @recurselimit = :infinite
+ def ignore=(values)
+ values = [values] unless values.is_a?(Array)
+ @ignore = values
+ end
- if options.is_a?(Puppet::Indirector::Request)
- initialize_from_request(options)
- else
- initialize_from_hash(options)
- end
+ def initialize(path, options = {})
+ raise ArgumentError.new("Fileset paths must be fully qualified") unless File.expand_path(path) == path
- raise ArgumentError.new("Fileset paths must exist") unless stat = stat(path)
- raise ArgumentError.new("Fileset recurse parameter must not be a number anymore, please use recurselimit") if @recurse.is_a?(Integer)
- end
+ @path = path
- def links=(links)
- links = links.to_sym
- raise(ArgumentError, "Invalid :links value '#{links}'") unless [:manage, :follow].include?(links)
- @links = links
- @stat_method = links == :manage ? :lstat : :stat
- end
+ # Set our defaults.
+ @ignore = []
+ @links = :manage
+ @recurse = false
+ @recurselimit = :infinite
- # Should we recurse further? This is basically a single
- # place for all of the logic around recursion.
- def recurse?(depth)
- # recurse if told to, and infinite recursion or current depth not at the limit
- self.recurse and (self.recurselimit == :infinite or depth <= self.recurselimit)
+ if options.is_a?(Puppet::Indirector::Request)
+ initialize_from_request(options)
+ else
+ initialize_from_hash(options)
end
- def initialize_from_hash(options)
- options.each do |option, value|
- method = option.to_s + "="
- begin
- send(method, value)
- rescue NoMethodError
- raise ArgumentError, "Invalid option '#{option}'"
- end
- end
+ raise ArgumentError.new("Fileset paths must exist") unless stat = stat(path)
+ raise ArgumentError.new("Fileset recurse parameter must not be a number anymore, please use recurselimit") if @recurse.is_a?(Integer)
+ end
+
+ def links=(links)
+ links = links.to_sym
+ raise(ArgumentError, "Invalid :links value '#{links}'") unless [:manage, :follow].include?(links)
+ @links = links
+ @stat_method = links == :manage ? :lstat : :stat
+ end
+
+ # Should we recurse further? This is basically a single
+ # place for all of the logic around recursion.
+ def recurse?(depth)
+ # recurse if told to, and infinite recursion or current depth not at the limit
+ self.recurse and (self.recurselimit == :infinite or depth <= self.recurselimit)
+ end
+
+ def initialize_from_hash(options)
+ options.each do |option, value|
+ method = option.to_s + "="
+ begin
+ send(method, value)
+ rescue NoMethodError
+ raise ArgumentError, "Invalid option '#{option}'"
+ end
end
-
- def initialize_from_request(request)
- [:links, :ignore, :recurse, :recurselimit, :checksum_type].each do |param|
- if request.options.include?(param) # use 'include?' so the values can be false
- value = request.options[param]
- elsif request.options.include?(param.to_s)
- value = request.options[param.to_s]
- end
- next if value.nil?
- value = true if value == "true"
- value = false if value == "false"
- value = Integer(value) if value.is_a?(String) and value =~ /^\d+$/
- send(param.to_s + "=", value)
- end
+ end
+
+ def initialize_from_request(request)
+ [:links, :ignore, :recurse, :recurselimit, :checksum_type].each do |param|
+ if request.options.include?(param) # use 'include?' so the values can be false
+ value = request.options[param]
+ elsif request.options.include?(param.to_s)
+ value = request.options[param.to_s]
+ end
+ next if value.nil?
+ value = true if value == "true"
+ value = false if value == "false"
+ value = Integer(value) if value.is_a?(String) and value =~ /^\d+$/
+ send(param.to_s + "=", value)
end
+ end
- private
+ private
- # Pull the recursion logic into one place. It's moderately hairy, and this
- # allows us to keep the hairiness apart from what we do with the files.
- def perform_recursion
- # Start out with just our base directory.
- current_dirs = [@path]
+ # Pull the recursion logic into one place. It's moderately hairy, and this
+ # allows us to keep the hairiness apart from what we do with the files.
+ def perform_recursion
+ # Start out with just our base directory.
+ current_dirs = [@path]
- next_dirs = []
+ next_dirs = []
- depth = 1
+ depth = 1
- result = []
- return result unless recurse?(depth)
+ result = []
+ return result unless recurse?(depth)
- while dir_path = current_dirs.shift or ((depth += 1) and recurse?(depth) and current_dirs = next_dirs and next_dirs = [] and dir_path = current_dirs.shift)
- next unless stat = stat(dir_path)
- next unless stat.directory?
+ while dir_path = current_dirs.shift or ((depth += 1) and recurse?(depth) and current_dirs = next_dirs and next_dirs = [] and dir_path = current_dirs.shift)
+ next unless stat = stat(dir_path)
+ next unless stat.directory?
- Dir.entries(dir_path).each do |file_path|
- next if [".", ".."].include?(file_path)
+ Dir.entries(dir_path).each do |file_path|
+ next if [".", ".."].include?(file_path)
- # Note that this also causes matching directories not
- # to be recursed into.
- next if ignore?(file_path)
+ # Note that this also causes matching directories not
+ # to be recursed into.
+ next if ignore?(file_path)
- # Add it to our list of files to return
- result << File.join(dir_path, file_path)
+ # Add it to our list of files to return
+ result << File.join(dir_path, file_path)
- # And to our list of files/directories to iterate over.
- next_dirs << File.join(dir_path, file_path)
- end
- end
-
- result
+ # And to our list of files/directories to iterate over.
+ next_dirs << File.join(dir_path, file_path)
+ end
end
- public
- # Stat a given file, using the links-appropriate method.
- def stat(path)
- @stat_method ||= self.links == :manage ? :lstat : :stat
-
- begin
- return File.send(@stat_method, path)
- rescue
- # If this happens, it is almost surely because we're
- # trying to manage a link to a file that does not exist.
- return nil
- end
+
+ result
+ end
+ public
+ # Stat a given file, using the links-appropriate method.
+ def stat(path)
+ @stat_method ||= self.links == :manage ? :lstat : :stat
+
+ begin
+ return File.send(@stat_method, path)
+ rescue
+ # If this happens, it is almost surely because we're
+ # trying to manage a link to a file that does not exist.
+ return nil
end
+ end
end
diff --git a/lib/puppet/file_serving/indirection_hooks.rb b/lib/puppet/file_serving/indirection_hooks.rb
index f6f7d66..7e0c179 100644
--- a/lib/puppet/file_serving/indirection_hooks.rb
+++ b/lib/puppet/file_serving/indirection_hooks.rb
@@ -9,26 +9,26 @@ require 'puppet/file_serving'
# in file-serving indirections. This is necessary because
# the terminus varies based on the URI asked for.
module Puppet::FileServing::IndirectionHooks
- PROTOCOL_MAP = {"puppet" => :rest, "file" => :file}
+ PROTOCOL_MAP = {"puppet" => :rest, "file" => :file}
- # Pick an appropriate terminus based on the protocol.
- def select_terminus(request)
- # We rely on the request's parsing of the URI.
+ # Pick an appropriate terminus based on the protocol.
+ def select_terminus(request)
+ # We rely on the request's parsing of the URI.
- # Short-circuit to :file if it's a fully-qualified path or specifies a 'file' protocol.
- return PROTOCOL_MAP["file"] if request.key =~ /^#{::File::SEPARATOR}/
- return PROTOCOL_MAP["file"] if request.protocol == "file"
+ # Short-circuit to :file if it's a fully-qualified path or specifies a 'file' protocol.
+ return PROTOCOL_MAP["file"] if request.key =~ /^#{::File::SEPARATOR}/
+ return PROTOCOL_MAP["file"] if request.protocol == "file"
- # We're heading over the wire the protocol is 'puppet' and we've got a server name or we're not named 'puppet'
- if request.protocol == "puppet" and (request.server or Puppet.settings[:name] != "puppet")
- return PROTOCOL_MAP["puppet"]
- end
-
- if request.protocol and PROTOCOL_MAP[request.protocol].nil?
- raise(ArgumentError, "URI protocol '#{request.protocol}' is not currently supported for file serving")
- end
+ # We're heading over the wire the protocol is 'puppet' and we've got a server name or we're not named 'puppet'
+ if request.protocol == "puppet" and (request.server or Puppet.settings[:name] != "puppet")
+ return PROTOCOL_MAP["puppet"]
+ end
- # If we're still here, we're using the file_server or modules.
- :file_server
+ if request.protocol and PROTOCOL_MAP[request.protocol].nil?
+ raise(ArgumentError, "URI protocol '#{request.protocol}' is not currently supported for file serving")
end
+
+ # If we're still here, we're using the file_server or modules.
+ :file_server
+ end
end
diff --git a/lib/puppet/file_serving/metadata.rb b/lib/puppet/file_serving/metadata.rb
index ca58669..6656b12 100644
--- a/lib/puppet/file_serving/metadata.rb
+++ b/lib/puppet/file_serving/metadata.rb
@@ -12,107 +12,107 @@ require 'puppet/file_serving/indirection_hooks'
# A class that handles retrieving file metadata.
class Puppet::FileServing::Metadata < Puppet::FileServing::Base
- include Puppet::Util::Checksums
-
- extend Puppet::Indirector
- indirects :file_metadata, :extend => Puppet::FileServing::IndirectionHooks
-
- attr_reader :path, :owner, :group, :mode, :checksum_type, :checksum, :ftype, :destination
-
- PARAM_ORDER = [:mode, :ftype, :owner, :group]
-
- def attributes_with_tabs
- raise(ArgumentError, "Cannot manage files of type #{ftype}") unless ['file','directory','link'].include? ftype
- desc = []
- PARAM_ORDER.each { |check|
- check = :ftype if check == :type
- desc << send(check)
- }
-
- desc << checksum
- desc << @destination rescue nil if ftype == 'link'
-
- desc.join("\t")
+ include Puppet::Util::Checksums
+
+ extend Puppet::Indirector
+ indirects :file_metadata, :extend => Puppet::FileServing::IndirectionHooks
+
+ attr_reader :path, :owner, :group, :mode, :checksum_type, :checksum, :ftype, :destination
+
+ PARAM_ORDER = [:mode, :ftype, :owner, :group]
+
+ def attributes_with_tabs
+ raise(ArgumentError, "Cannot manage files of type #{ftype}") unless ['file','directory','link'].include? ftype
+ desc = []
+ PARAM_ORDER.each { |check|
+ check = :ftype if check == :type
+ desc << send(check)
+ }
+
+ desc << checksum
+ desc << @destination rescue nil if ftype == 'link'
+
+ desc.join("\t")
+ end
+
+ def checksum_type=(type)
+ raise(ArgumentError, "Unsupported checksum type #{type}") unless respond_to?("#{type}_file")
+
+ @checksum_type = type
+ end
+
+ # Retrieve the attributes for this file, relative to a base directory.
+ # Note that File.stat raises Errno::ENOENT if the file is absent and this
+ # method does not catch that exception.
+ def collect
+ real_path = full_path
+ stat = stat()
+ @owner = stat.uid
+ @group = stat.gid
+ @ftype = stat.ftype
+
+
+ # We have to mask the mode, yay.
+ @mode = stat.mode & 007777
+
+ case stat.ftype
+ when "file"
+ @checksum = ("{#{@checksum_type}}") + send("#{@checksum_type}_file", real_path).to_s
+ when "directory" # Always just timestamp the directory.
+ @checksum_type = "ctime"
+ @checksum = ("{#{@checksum_type}}") + send("#{@checksum_type}_file", path).to_s
+ when "link"
+ @destination = File.readlink(real_path)
+ @checksum = ("{#{@checksum_type}}") + send("#{@checksum_type}_file", real_path).to_s rescue nil
+ else
+ raise ArgumentError, "Cannot manage files of type #{stat.ftype}"
end
-
- def checksum_type=(type)
- raise(ArgumentError, "Unsupported checksum type #{type}") unless respond_to?("#{type}_file")
-
- @checksum_type = type
+ end
+
+ def initialize(path,data={})
+ @owner = data.delete('owner')
+ @group = data.delete('group')
+ @mode = data.delete('mode')
+ if checksum = data.delete('checksum')
+ @checksum_type = checksum['type']
+ @checksum = checksum['value']
end
-
- # Retrieve the attributes for this file, relative to a base directory.
- # Note that File.stat raises Errno::ENOENT if the file is absent and this
- # method does not catch that exception.
- def collect
- real_path = full_path
- stat = stat()
- @owner = stat.uid
- @group = stat.gid
- @ftype = stat.ftype
-
-
- # We have to mask the mode, yay.
- @mode = stat.mode & 007777
-
- case stat.ftype
- when "file"
- @checksum = ("{#{@checksum_type}}") + send("#{@checksum_type}_file", real_path).to_s
- when "directory" # Always just timestamp the directory.
- @checksum_type = "ctime"
- @checksum = ("{#{@checksum_type}}") + send("#{@checksum_type}_file", path).to_s
- when "link"
- @destination = File.readlink(real_path)
- @checksum = ("{#{@checksum_type}}") + send("#{@checksum_type}_file", real_path).to_s rescue nil
- else
- raise ArgumentError, "Cannot manage files of type #{stat.ftype}"
- end
- end
-
- def initialize(path,data={})
- @owner = data.delete('owner')
- @group = data.delete('group')
- @mode = data.delete('mode')
- if checksum = data.delete('checksum')
- @checksum_type = checksum['type']
- @checksum = checksum['value']
- end
- @checksum_type ||= "md5"
- @ftype = data.delete('type')
- @destination = data.delete('destination')
- super(path,data)
- end
-
- PSON.register_document_type('FileMetadata',self)
- def to_pson_data_hash
- {
- 'document_type' => 'FileMetadata',
-
- 'data' => super['data'].update(
- {
- 'owner' => owner,
- 'group' => group,
- 'mode' => mode,
- 'checksum' => {
- 'type' => checksum_type,
- 'value' => checksum
- },
- 'type' => ftype,
- 'destination' => destination,
-
- }),
- 'metadata' => {
- 'api_version' => 1
- }
+ @checksum_type ||= "md5"
+ @ftype = data.delete('type')
+ @destination = data.delete('destination')
+ super(path,data)
+ end
+
+ PSON.register_document_type('FileMetadata',self)
+ def to_pson_data_hash
+ {
+ 'document_type' => 'FileMetadata',
+
+ 'data' => super['data'].update(
+ {
+ 'owner' => owner,
+ 'group' => group,
+ 'mode' => mode,
+ 'checksum' => {
+ 'type' => checksum_type,
+ 'value' => checksum
+ },
+ 'type' => ftype,
+ 'destination' => destination,
+
+ }),
+ 'metadata' => {
+ 'api_version' => 1
}
- end
+ }
+ end
- def to_pson(*args)
- to_pson_data_hash.to_pson(*args)
- end
+ def to_pson(*args)
+ to_pson_data_hash.to_pson(*args)
+ end
- def self.from_pson(data)
- new(data.delete('path'), data)
- end
+ def self.from_pson(data)
+ new(data.delete('path'), data)
+ end
end
diff --git a/lib/puppet/file_serving/mount.rb b/lib/puppet/file_serving/mount.rb
index 420b6f7..37dd895 100644
--- a/lib/puppet/file_serving/mount.rb
+++ b/lib/puppet/file_serving/mount.rb
@@ -12,33 +12,33 @@ require 'puppet/file_serving/content'
# Broker access to the filesystem, converting local URIs into metadata
# or content objects.
class Puppet::FileServing::Mount < Puppet::Network::AuthStore
- include Puppet::Util::Logging
+ include Puppet::Util::Logging
- attr_reader :name
+ attr_reader :name
- def find(path, options)
- raise NotImplementedError
- end
-
- # Create our object. It must have a name.
- def initialize(name)
- unless name =~ %r{^[-\w]+$}
- raise ArgumentError, "Invalid mount name format '#{name}'"
- end
- @name = name
+ def find(path, options)
+ raise NotImplementedError
+ end
- super()
+ # Create our object. It must have a name.
+ def initialize(name)
+ unless name =~ %r{^[-\w]+$}
+ raise ArgumentError, "Invalid mount name format '#{name}'"
end
+ @name = name
- def search(path, options)
- raise NotImplementedError
- end
+ super()
+ end
- def to_s
- "mount[#{@name}]"
- end
+ def search(path, options)
+ raise NotImplementedError
+ end
- # A noop.
- def validate
- end
+ def to_s
+ "mount[#{@name}]"
+ end
+
+ # A noop.
+ def validate
+ end
end
diff --git a/lib/puppet/file_serving/mount/file.rb b/lib/puppet/file_serving/mount/file.rb
index 1daacea..7d622e4 100644
--- a/lib/puppet/file_serving/mount/file.rb
+++ b/lib/puppet/file_serving/mount/file.rb
@@ -3,122 +3,122 @@ require 'puppet/util/cacher'
require 'puppet/file_serving/mount'
class Puppet::FileServing::Mount::File < Puppet::FileServing::Mount
- class << self
- include Puppet::Util::Cacher
-
- cached_attr(:localmap) do
- { "h" => Facter.value("hostname"),
- "H" => [Facter.value("hostname"),
- Facter.value("domain")].join("."),
- "d" => Facter.value("domain")
- }
- end
+ class << self
+ include Puppet::Util::Cacher
+
+ cached_attr(:localmap) do
+ { "h" => Facter.value("hostname"),
+ "H" => [Facter.value("hostname"),
+ Facter.value("domain")].join("."),
+ "d" => Facter.value("domain")
+ }
end
+ end
- def complete_path(relative_path, node)
- full_path = path(node)
+ def complete_path(relative_path, node)
+ full_path = path(node)
- raise ArgumentError.new("Mounts without paths are not usable") unless full_path
+ raise ArgumentError.new("Mounts without paths are not usable") unless full_path
- # If there's no relative path name, then we're serving the mount itself.
- return full_path unless relative_path
+ # If there's no relative path name, then we're serving the mount itself.
+ return full_path unless relative_path
- file = ::File.join(full_path, relative_path)
+ file = ::File.join(full_path, relative_path)
- if !(FileTest.exist?(file) or FileTest.symlink?(file))
- Puppet.info("File does not exist or is not accessible: #{file}")
- return nil
- end
-
- file
+ if !(FileTest.exist?(file) or FileTest.symlink?(file))
+ Puppet.info("File does not exist or is not accessible: #{file}")
+ return nil
end
- # Return an instance of the appropriate class.
- def find(short_file, request)
- complete_path(short_file, request.node)
- end
+ file
+ end
- # Return the path as appropriate, expanding as necessary.
- def path(node = nil)
- if expandable?
- return expand(@path, node)
- else
- return @path
- end
- end
-
- # Set the path.
- def path=(path)
- # FIXME: For now, just don't validate paths with replacement
- # patterns in them.
- if path =~ /%./
- # Mark that we're expandable.
- @expandable = true
- else
- raise ArgumentError, "#{path} does not exist or is not a directory" unless FileTest.directory?(path)
- raise ArgumentError, "#{path} is not readable" unless FileTest.readable?(path)
- @expandable = false
- end
- @path = path
- end
+ # Return an instance of the appropriate class.
+ def find(short_file, request)
+ complete_path(short_file, request.node)
+ end
- def search(path, request)
- return nil unless path = complete_path(path, request.node)
- [path]
+ # Return the path as appropriate, expanding as necessary.
+ def path(node = nil)
+ if expandable?
+ return expand(@path, node)
+ else
+ return @path
end
-
- # Verify our configuration is valid. This should really check to
- # make sure at least someone will be allowed, but, eh.
- def validate
- raise ArgumentError.new("Mounts without paths are not usable") if @path.nil?
+ end
+
+ # Set the path.
+ def path=(path)
+ # FIXME: For now, just don't validate paths with replacement
+ # patterns in them.
+ if path =~ /%./
+ # Mark that we're expandable.
+ @expandable = true
+ else
+ raise ArgumentError, "#{path} does not exist or is not a directory" unless FileTest.directory?(path)
+ raise ArgumentError, "#{path} is not readable" unless FileTest.readable?(path)
+ @expandable = false
end
-
- private
-
- # Create a map for a specific node.
- def clientmap(node)
- {
- "h" => node.sub(/\..*$/, ""),
- "H" => node,
- "d" => node.sub(/[^.]+\./, "") # domain name
- }
+ @path = path
+ end
+
+ def search(path, request)
+ return nil unless path = complete_path(path, request.node)
+ [path]
+ end
+
+ # Verify our configuration is valid. This should really check to
+ # make sure at least someone will be allowed, but, eh.
+ def validate
+ raise ArgumentError.new("Mounts without paths are not usable") if @path.nil?
+ end
+
+ private
+
+ # Create a map for a specific node.
+ def clientmap(node)
+ {
+ "h" => node.sub(/\..*$/, ""),
+ "H" => node,
+ "d" => node.sub(/[^.]+\./, "") # domain name
+ }
+ end
+
+ # Replace % patterns as appropriate.
+ def expand(path, node = nil)
+ # This map should probably be moved into a method.
+ map = nil
+
+ if node
+ map = clientmap(node)
+ else
+ Puppet.notice "No client; expanding '#{path}' with local host"
+ # Else, use the local information
+ map = localmap
end
- # Replace % patterns as appropriate.
- def expand(path, node = nil)
- # This map should probably be moved into a method.
- map = nil
-
- if node
- map = clientmap(node)
- else
- Puppet.notice "No client; expanding '#{path}' with local host"
- # Else, use the local information
- map = localmap
- end
-
- path.gsub(/%(.)/) do |v|
- key = $1
- if key == "%"
- "%"
- else
- map[key] || v
- end
- end
+ path.gsub(/%(.)/) do |v|
+ key = $1
+ if key == "%"
+ "%"
+ else
+ map[key] || v
+ end
end
-
- # Do we have any patterns in our path, yo?
- def expandable?
- if defined?(@expandable)
- @expandable
- else
- false
- end
+ end
+
+ # Do we have any patterns in our path, yo?
+ def expandable?
+ if defined?(@expandable)
+ @expandable
+ else
+ false
end
+ end
- # Cache this manufactured map, since if it's used it's likely
- # to get used a lot.
- def localmap
- self.class.localmap
- end
+ # Cache this manufactured map, since if it's used it's likely
+ # to get used a lot.
+ def localmap
+ self.class.localmap
+ end
end
diff --git a/lib/puppet/file_serving/mount/modules.rb b/lib/puppet/file_serving/mount/modules.rb
index e5fe566..86b5e1c 100644
--- a/lib/puppet/file_serving/mount/modules.rb
+++ b/lib/puppet/file_serving/mount/modules.rb
@@ -3,23 +3,23 @@ require 'puppet/file_serving/mount'
# This is the modules-specific mount: it knows how to search through
# modules for files. Yay.
class Puppet::FileServing::Mount::Modules < Puppet::FileServing::Mount
- # Return an instance of the appropriate class.
- def find(path, request)
- module_name, relative_path = path.split("/", 2)
- return nil unless mod = request.environment.module(module_name)
+ # Return an instance of the appropriate class.
+ def find(path, request)
+ module_name, relative_path = path.split("/", 2)
+ return nil unless mod = request.environment.module(module_name)
- mod.file(relative_path)
- end
+ mod.file(relative_path)
+ end
- def search(path, request)
- module_name, relative_path = path.split("/", 2)
- return nil unless mod = request.environment.module(module_name)
+ def search(path, request)
+ module_name, relative_path = path.split("/", 2)
+ return nil unless mod = request.environment.module(module_name)
- return nil unless path = mod.file(relative_path)
- [path]
- end
+ return nil unless path = mod.file(relative_path)
+ [path]
+ end
- def valid?
- true
- end
+ def valid?
+ true
+ end
end
diff --git a/lib/puppet/file_serving/mount/plugins.rb b/lib/puppet/file_serving/mount/plugins.rb
index 5e9e49a..d21d6e9 100644
--- a/lib/puppet/file_serving/mount/plugins.rb
+++ b/lib/puppet/file_serving/mount/plugins.rb
@@ -4,23 +4,23 @@ require 'puppet/file_serving/mount'
# This is a very strange mount because it merges
# many directories into one.
class Puppet::FileServing::Mount::Plugins < Puppet::FileServing::Mount
- # Return an instance of the appropriate class.
- def find(relative_path, request)
- return nil unless mod = request.environment.modules.find { |mod| mod.plugin(relative_path) }
+ # Return an instance of the appropriate class.
+ def find(relative_path, request)
+ return nil unless mod = request.environment.modules.find { |mod| mod.plugin(relative_path) }
- path = mod.plugin(relative_path)
+ path = mod.plugin(relative_path)
- path
- end
+ path
+ end
- def search(relative_path, request)
- # We currently only support one kind of search on plugins - return
- # them all.
- paths = request.environment.modules.find_all { |mod| mod.plugins? }.collect { |mod| mod.plugin_directory }
- return(paths.empty? ? nil : paths)
- end
+ def search(relative_path, request)
+ # We currently only support one kind of search on plugins - return
+ # them all.
+ paths = request.environment.modules.find_all { |mod| mod.plugins? }.collect { |mod| mod.plugin_directory }
+ return(paths.empty? ? nil : paths)
+ end
- def valid?
- true
- end
+ def valid?
+ true
+ end
end
diff --git a/lib/puppet/file_serving/terminus_helper.rb b/lib/puppet/file_serving/terminus_helper.rb
index 6f5d52b..4da2852 100644
--- a/lib/puppet/file_serving/terminus_helper.rb
+++ b/lib/puppet/file_serving/terminus_helper.rb
@@ -7,19 +7,19 @@ require 'puppet/file_serving/fileset'
# Define some common methods for FileServing termini.
module Puppet::FileServing::TerminusHelper
- # Create model instances for all files in a fileset.
- def path2instances(request, *paths)
- filesets = paths.collect do |path|
- # Filesets support indirector requests as an options collection
- Puppet::FileServing::Fileset.new(path, request)
- end
+ # Create model instances for all files in a fileset.
+ def path2instances(request, *paths)
+ filesets = paths.collect do |path|
+ # Filesets support indirector requests as an options collection
+ Puppet::FileServing::Fileset.new(path, request)
+ end
- Puppet::FileServing::Fileset.merge(*filesets).collect do |file, base_path|
- inst = model.new(base_path, :relative_path => file)
- inst.checksum_type = request.options[:checksum_type] if request.options[:checksum_type]
- inst.links = request.options[:links] if request.options[:links]
- inst.collect
- inst
- end
+ Puppet::FileServing::Fileset.merge(*filesets).collect do |file, base_path|
+ inst = model.new(base_path, :relative_path => file)
+ inst.checksum_type = request.options[:checksum_type] if request.options[:checksum_type]
+ inst.links = request.options[:links] if request.options[:links]
+ inst.collect
+ inst
end
+ end
end
diff --git a/lib/puppet/indirector.rb b/lib/puppet/indirector.rb
index 1caad6c..5b73757 100644
--- a/lib/puppet/indirector.rb
+++ b/lib/puppet/indirector.rb
@@ -4,64 +4,64 @@
# +indirects+ method, which will be called by the class extending itself
# with this module.
module Puppet::Indirector
- # LAK:FIXME We need to figure out how to handle documentation for the
- # different indirection types.
+ # LAK:FIXME We need to figure out how to handle documentation for the
+ # different indirection types.
- require 'puppet/indirector/indirection'
- require 'puppet/indirector/terminus'
- require 'puppet/indirector/envelope'
- require 'puppet/network/format_handler'
+ require 'puppet/indirector/indirection'
+ require 'puppet/indirector/terminus'
+ require 'puppet/indirector/envelope'
+ require 'puppet/network/format_handler'
- # Declare that the including class indirects its methods to
- # this terminus. The terminus name must be the name of a Puppet
- # default, not the value -- if it's the value, then it gets
- # evaluated at parse time, which is before the user has had a chance
- # to override it.
- def indirects(indirection, options = {})
- raise(ArgumentError, "Already handling indirection for #{@indirection.name}; cannot also handle #{indirection}") if @indirection
- # populate this class with the various new methods
- extend ClassMethods
- include InstanceMethods
- include Puppet::Indirector::Envelope
- extend Puppet::Network::FormatHandler
+ # Declare that the including class indirects its methods to
+ # this terminus. The terminus name must be the name of a Puppet
+ # default, not the value -- if it's the value, then it gets
+ # evaluated at parse time, which is before the user has had a chance
+ # to override it.
+ def indirects(indirection, options = {})
+ raise(ArgumentError, "Already handling indirection for #{@indirection.name}; cannot also handle #{indirection}") if @indirection
+ # populate this class with the various new methods
+ extend ClassMethods
+ include InstanceMethods
+ include Puppet::Indirector::Envelope
+ extend Puppet::Network::FormatHandler
- # instantiate the actual Terminus for that type and this name (:ldap, w/ args :node)
- # & hook the instantiated Terminus into this class (Node: @indirection = terminus)
- @indirection = Puppet::Indirector::Indirection.new(self, indirection, options)
- end
+ # instantiate the actual Terminus for that type and this name (:ldap, w/ args :node)
+ # & hook the instantiated Terminus into this class (Node: @indirection = terminus)
+ @indirection = Puppet::Indirector::Indirection.new(self, indirection, options)
+ end
- module ClassMethods
- attr_reader :indirection
+ module ClassMethods
+ attr_reader :indirection
- def cache_class=(klass)
- indirection.cache_class = klass
- end
+ def cache_class=(klass)
+ indirection.cache_class = klass
+ end
- def terminus_class=(klass)
- indirection.terminus_class = klass
- end
+ def terminus_class=(klass)
+ indirection.terminus_class = klass
+ end
- # Expire any cached instance.
- def expire(*args)
- indirection.expire(*args)
- end
+ # Expire any cached instance.
+ def expire(*args)
+ indirection.expire(*args)
+ end
- def find(*args)
- indirection.find(*args)
- end
+ def find(*args)
+ indirection.find(*args)
+ end
- def destroy(*args)
- indirection.destroy(*args)
- end
+ def destroy(*args)
+ indirection.destroy(*args)
+ end
- def search(*args)
- indirection.search(*args)
- end
+ def search(*args)
+ indirection.search(*args)
end
+ end
- module InstanceMethods
- def save(key = nil)
- self.class.indirection.save key, self
- end
+ module InstanceMethods
+ def save(key = nil)
+ self.class.indirection.save key, self
end
+ end
end
diff --git a/lib/puppet/indirector/active_record.rb b/lib/puppet/indirector/active_record.rb
index 531109a..a9f05d6 100644
--- a/lib/puppet/indirector/active_record.rb
+++ b/lib/puppet/indirector/active_record.rb
@@ -1,28 +1,28 @@
require 'puppet/indirector'
class Puppet::Indirector::ActiveRecord < Puppet::Indirector::Terminus
- class << self
- attr_accessor :ar_model
- end
+ class << self
+ attr_accessor :ar_model
+ end
- def self.use_ar_model(klass)
- self.ar_model = klass
- end
+ def self.use_ar_model(klass)
+ self.ar_model = klass
+ end
- def ar_model
- self.class.ar_model
- end
+ def ar_model
+ self.class.ar_model
+ end
- def initialize
- Puppet::Rails.init
- end
+ def initialize
+ Puppet::Rails.init
+ end
- def find(request)
- return nil unless instance = ar_model.find_by_name(request.key)
- instance.to_puppet
- end
+ def find(request)
+ return nil unless instance = ar_model.find_by_name(request.key)
+ instance.to_puppet
+ end
- def save(request)
- ar_model.from_puppet(request.instance).save
- end
+ def save(request)
+ ar_model.from_puppet(request.instance).save
+ end
end
diff --git a/lib/puppet/indirector/catalog/active_record.rb b/lib/puppet/indirector/catalog/active_record.rb
index 575ce72..fabb08e 100644
--- a/lib/puppet/indirector/catalog/active_record.rb
+++ b/lib/puppet/indirector/catalog/active_record.rb
@@ -3,39 +3,39 @@ require 'puppet/indirector/active_record'
require 'puppet/resource/catalog'
class Puppet::Resource::Catalog::ActiveRecord < Puppet::Indirector::ActiveRecord
- use_ar_model Puppet::Rails::Host
+ use_ar_model Puppet::Rails::Host
- # If we can find the host, then return a catalog with the host's resources
- # as the vertices.
- def find(request)
- return nil unless request.options[:cache_integration_hack]
- return nil unless host = ar_model.find_by_name(request.key)
+ # If we can find the host, then return a catalog with the host's resources
+ # as the vertices.
+ def find(request)
+ return nil unless request.options[:cache_integration_hack]
+ return nil unless host = ar_model.find_by_name(request.key)
- catalog = Puppet::Resource::Catalog.new(host.name)
+ catalog = Puppet::Resource::Catalog.new(host.name)
- host.resources.each do |resource|
- catalog.add_resource resource.to_transportable
- end
-
- catalog
+ host.resources.each do |resource|
+ catalog.add_resource resource.to_transportable
end
- # Save the values from a Facts instance as the facts on a Rails Host instance.
- def save(request)
- catalog = request.instance
+ catalog
+ end
+
+ # Save the values from a Facts instance as the facts on a Rails Host instance.
+ def save(request)
+ catalog = request.instance
- host = ar_model.find_by_name(catalog.name) || ar_model.create(:name => catalog.name)
+ host = ar_model.find_by_name(catalog.name) || ar_model.create(:name => catalog.name)
- host.railsmark "Saved catalog to database" do
- host.merge_resources(catalog.vertices)
- host.last_compile = Time.now
+ host.railsmark "Saved catalog to database" do
+ host.merge_resources(catalog.vertices)
+ host.last_compile = Time.now
- if node = Puppet::Node.find(catalog.name)
- host.ip = node.parameters["ipaddress"]
- host.environment = node.environment
- end
+ if node = Puppet::Node.find(catalog.name)
+ host.ip = node.parameters["ipaddress"]
+ host.environment = node.environment
+ end
- host.save
- end
+ host.save
end
+ end
end
diff --git a/lib/puppet/indirector/catalog/compiler.rb b/lib/puppet/indirector/catalog/compiler.rb
index 4ceb25a..e85608e 100644
--- a/lib/puppet/indirector/catalog/compiler.rb
+++ b/lib/puppet/indirector/catalog/compiler.rb
@@ -4,163 +4,163 @@ require 'puppet/indirector/code'
require 'yaml'
class Puppet::Resource::Catalog::Compiler < Puppet::Indirector::Code
- desc "Puppet's catalog compilation interface, and its back-end is
- Puppet's compiler"
+ desc "Puppet's catalog compilation interface, and its back-end is
+ Puppet's compiler"
- include Puppet::Util
+ include Puppet::Util
- attr_accessor :code
+ attr_accessor :code
- def extract_facts_from_request(request)
- return unless text_facts = request.options[:facts]
- raise ArgumentError, "Facts but no fact format provided for #{request.name}" unless format = request.options[:facts_format]
+ def extract_facts_from_request(request)
+ return unless text_facts = request.options[:facts]
+ raise ArgumentError, "Facts but no fact format provided for #{request.name}" unless format = request.options[:facts_format]
- # If the facts were encoded as yaml, then the param reconstitution system
- # in Network::HTTP::Handler will automagically deserialize the value.
- if text_facts.is_a?(Puppet::Node::Facts)
- facts = text_facts
- else
- facts = Puppet::Node::Facts.convert_from(format, text_facts)
- end
- facts.save
+ # If the facts were encoded as yaml, then the param reconstitution system
+ # in Network::HTTP::Handler will automagically deserialize the value.
+ if text_facts.is_a?(Puppet::Node::Facts)
+ facts = text_facts
+ else
+ facts = Puppet::Node::Facts.convert_from(format, text_facts)
end
+ facts.save
+ end
- # Compile a node's catalog.
- def find(request)
- extract_facts_from_request(request)
+ # Compile a node's catalog.
+ def find(request)
+ extract_facts_from_request(request)
- node = node_from_request(request)
+ node = node_from_request(request)
- if catalog = compile(node)
- return catalog
- else
- # This shouldn't actually happen; we should either return
- # a config or raise an exception.
- return nil
- end
+ if catalog = compile(node)
+ return catalog
+ else
+ # This shouldn't actually happen; we should either return
+ # a config or raise an exception.
+ return nil
end
-
- # filter-out a catalog to remove exported resources
- def filter(catalog)
- return catalog.filter { |r| r.virtual? } if catalog.respond_to?(:filter)
- catalog
- end
-
- def initialize
- set_server_facts
- setup_database_backend if Puppet[:storeconfigs]
- end
-
- # Is our compiler part of a network, or are we just local?
- def networked?
- Puppet.run_mode.master?
- end
-
- private
-
- # Add any extra data necessary to the node.
- def add_node_data(node)
- # Merge in our server-side facts, so they can be used during compilation.
- node.merge(@server_facts)
+ end
+
+ # filter-out a catalog to remove exported resources
+ def filter(catalog)
+ return catalog.filter { |r| r.virtual? } if catalog.respond_to?(:filter)
+ catalog
+ end
+
+ def initialize
+ set_server_facts
+ setup_database_backend if Puppet[:storeconfigs]
+ end
+
+ # Is our compiler part of a network, or are we just local?
+ def networked?
+ Puppet.run_mode.master?
+ end
+
+ private
+
+ # Add any extra data necessary to the node.
+ def add_node_data(node)
+ # Merge in our server-side facts, so they can be used during compilation.
+ node.merge(@server_facts)
+ end
+
+ # Compile the actual catalog.
+ def compile(node)
+ str = "Compiled catalog for #{node.name}"
+ str += " in environment #{node.environment}" if node.environment
+ config = nil
+
+ loglevel = networked? ? :notice : :none
+
+ benchmark(loglevel, "Compiled catalog for #{node.name}") do
+ begin
+ return Puppet::Parser::Compiler.compile(node)
+ rescue Puppet::Error => detail
+ Puppet.err(detail.to_s) if networked?
+ raise
+ end
end
- # Compile the actual catalog.
- def compile(node)
- str = "Compiled catalog for #{node.name}"
- str += " in environment #{node.environment}" if node.environment
- config = nil
-
- loglevel = networked? ? :notice : :none
+ config
+ end
- benchmark(loglevel, "Compiled catalog for #{node.name}") do
- begin
- return Puppet::Parser::Compiler.compile(node)
- rescue Puppet::Error => detail
- Puppet.err(detail.to_s) if networked?
- raise
- end
- end
-
- config
+ # Turn our host name into a node object.
+ def find_node(name)
+ begin
+ return nil unless node = Puppet::Node.find(name)
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ raise Puppet::Error, "Failed when searching for node #{name}: #{detail}"
end
- # Turn our host name into a node object.
- def find_node(name)
- begin
- return nil unless node = Puppet::Node.find(name)
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- raise Puppet::Error, "Failed when searching for node #{name}: #{detail}"
- end
+ # Add any external data to the node.
+ add_node_data(node)
- # Add any external data to the node.
- add_node_data(node)
+ node
+ end
- node
+ # Extract the node from the request, or use the request
+ # to find the node.
+ def node_from_request(request)
+ if node = request.options[:use_node]
+ return node
end
- # Extract the node from the request, or use the request
- # to find the node.
- def node_from_request(request)
- if node = request.options[:use_node]
- return node
- end
-
- # If the request is authenticated, then the 'node' info will
- # be available; if not, then we use the passed-in key. We rely
- # on our authorization system to determine whether this is allowed.
- name = request.node || request.key
- if node = find_node(name)
- return node
- end
-
- raise ArgumentError, "Could not find node '#{name}'; cannot compile"
+ # If the request is authenticated, then the 'node' info will
+ # be available; if not, then we use the passed-in key. We rely
+ # on our authorization system to determine whether this is allowed.
+ name = request.node || request.key
+ if node = find_node(name)
+ return node
end
- # Initialize our server fact hash; we add these to each client, and they
- # won't change while we're running, so it's safe to cache the values.
- def set_server_facts
- @server_facts = {}
-
- # Add our server version to the fact list
- @server_facts["serverversion"] = Puppet.version.to_s
-
- # And then add the server name and IP
- {"servername" => "fqdn",
- "serverip" => "ipaddress"
- }.each do |var, fact|
- if value = Facter.value(fact)
- @server_facts[var] = value
- else
- Puppet.warning "Could not retrieve fact #{fact}"
- end
- end
-
- if @server_facts["servername"].nil?
- host = Facter.value(:hostname)
- if domain = Facter.value(:domain)
- @server_facts["servername"] = [host, domain].join(".")
- else
- @server_facts["servername"] = host
- end
- end
+ raise ArgumentError, "Could not find node '#{name}'; cannot compile"
+ end
+
+ # Initialize our server fact hash; we add these to each client, and they
+ # won't change while we're running, so it's safe to cache the values.
+ def set_server_facts
+ @server_facts = {}
+
+ # Add our server version to the fact list
+ @server_facts["serverversion"] = Puppet.version.to_s
+
+ # And then add the server name and IP
+ {"servername" => "fqdn",
+ "serverip" => "ipaddress"
+ }.each do |var, fact|
+ if value = Facter.value(fact)
+ @server_facts[var] = value
+ else
+ Puppet.warning "Could not retrieve fact #{fact}"
+ end
end
- def setup_database_backend
- raise Puppet::Error, "Rails is missing; cannot store configurations" unless Puppet.features.rails?
- Puppet::Rails.init
+ if @server_facts["servername"].nil?
+ host = Facter.value(:hostname)
+ if domain = Facter.value(:domain)
+ @server_facts["servername"] = [host, domain].join(".")
+ else
+ @server_facts["servername"] = host
+ end
end
-
- # Mark that the node has checked in. LAK:FIXME this needs to be moved into
- # the Node class, or somewhere that's got abstract backends.
- def update_node_check(node)
- if Puppet.features.rails? and Puppet[:storeconfigs]
- Puppet::Rails.connect
-
- host = Puppet::Rails::Host.find_or_create_by_name(node.name)
- host.last_freshcheck = Time.now
- host.save
- end
+ end
+
+ def setup_database_backend
+ raise Puppet::Error, "Rails is missing; cannot store configurations" unless Puppet.features.rails?
+ Puppet::Rails.init
+ end
+
+ # Mark that the node has checked in. LAK:FIXME this needs to be moved into
+ # the Node class, or somewhere that's got abstract backends.
+ def update_node_check(node)
+ if Puppet.features.rails? and Puppet[:storeconfigs]
+ Puppet::Rails.connect
+
+ host = Puppet::Rails::Host.find_or_create_by_name(node.name)
+ host.last_freshcheck = Time.now
+ host.save
end
+ end
end
diff --git a/lib/puppet/indirector/catalog/rest.rb b/lib/puppet/indirector/catalog/rest.rb
index b70775b..b7a00a3 100644
--- a/lib/puppet/indirector/catalog/rest.rb
+++ b/lib/puppet/indirector/catalog/rest.rb
@@ -2,5 +2,5 @@ require 'puppet/resource/catalog'
require 'puppet/indirector/rest'
class Puppet::Resource::Catalog::Rest < Puppet::Indirector::REST
- desc "Find resource catalogs over HTTP via REST."
+ desc "Find resource catalogs over HTTP via REST."
end
diff --git a/lib/puppet/indirector/catalog/yaml.rb b/lib/puppet/indirector/catalog/yaml.rb
index d6fc9b8..177b4e2 100644
--- a/lib/puppet/indirector/catalog/yaml.rb
+++ b/lib/puppet/indirector/catalog/yaml.rb
@@ -2,21 +2,21 @@ require 'puppet/resource/catalog'
require 'puppet/indirector/yaml'
class Puppet::Resource::Catalog::Yaml < Puppet::Indirector::Yaml
- desc "Store catalogs as flat files, serialized using YAML."
+ desc "Store catalogs as flat files, serialized using YAML."
- private
+ private
- # Override these, because yaml doesn't want to convert our self-referential
- # objects. This is hackish, but eh.
- def from_yaml(text)
- if config = YAML.load(text)
- return config
- end
+ # Override these, because yaml doesn't want to convert our self-referential
+ # objects. This is hackish, but eh.
+ def from_yaml(text)
+ if config = YAML.load(text)
+ return config
end
+ end
- def to_yaml(config)
- # We can't yaml-dump classes.
- #config.edgelist_class = nil
- YAML.dump(config)
- end
+ def to_yaml(config)
+ # We can't yaml-dump classes.
+ #config.edgelist_class = nil
+ YAML.dump(config)
+ end
end
diff --git a/lib/puppet/indirector/certificate/ca.rb b/lib/puppet/indirector/certificate/ca.rb
index b64080e..563bd3c 100644
--- a/lib/puppet/indirector/certificate/ca.rb
+++ b/lib/puppet/indirector/certificate/ca.rb
@@ -2,8 +2,8 @@ require 'puppet/indirector/ssl_file'
require 'puppet/ssl/certificate'
class Puppet::SSL::Certificate::Ca < Puppet::Indirector::SslFile
- desc "Manage the CA collection of signed SSL certificates on disk."
+ desc "Manage the CA collection of signed SSL certificates on disk."
- store_in :signeddir
- store_ca_at :cacert
+ store_in :signeddir
+ store_ca_at :cacert
end
diff --git a/lib/puppet/indirector/certificate/file.rb b/lib/puppet/indirector/certificate/file.rb
index c19d001..4ce18f8 100644
--- a/lib/puppet/indirector/certificate/file.rb
+++ b/lib/puppet/indirector/certificate/file.rb
@@ -2,8 +2,8 @@ require 'puppet/indirector/ssl_file'
require 'puppet/ssl/certificate'
class Puppet::SSL::Certificate::File < Puppet::Indirector::SslFile
- desc "Manage SSL certificates on disk."
+ desc "Manage SSL certificates on disk."
- store_in :certdir
- store_ca_at :localcacert
+ store_in :certdir
+ store_ca_at :localcacert
end
diff --git a/lib/puppet/indirector/certificate/rest.rb b/lib/puppet/indirector/certificate/rest.rb
index 6f47c25..921b857 100644
--- a/lib/puppet/indirector/certificate/rest.rb
+++ b/lib/puppet/indirector/certificate/rest.rb
@@ -2,14 +2,14 @@ require 'puppet/ssl/certificate'
require 'puppet/indirector/rest'
class Puppet::SSL::Certificate::Rest < Puppet::Indirector::REST
- desc "Find and save certificates over HTTP via REST."
+ desc "Find and save certificates over HTTP via REST."
- use_server_setting(:ca_server)
- use_port_setting(:ca_port)
+ use_server_setting(:ca_server)
+ use_port_setting(:ca_port)
- def find(request)
- return nil unless result = super
- result.name = request.key unless result.name == request.key
- result
- end
+ def find(request)
+ return nil unless result = super
+ result.name = request.key unless result.name == request.key
+ result
+ end
end
diff --git a/lib/puppet/indirector/certificate_request/ca.rb b/lib/puppet/indirector/certificate_request/ca.rb
index 25680fb..f4c924f 100644
--- a/lib/puppet/indirector/certificate_request/ca.rb
+++ b/lib/puppet/indirector/certificate_request/ca.rb
@@ -2,13 +2,13 @@ require 'puppet/indirector/ssl_file'
require 'puppet/ssl/certificate_request'
class Puppet::SSL::CertificateRequest::Ca < Puppet::Indirector::SslFile
- desc "Manage the CA collection of certificate requests on disk."
+ desc "Manage the CA collection of certificate requests on disk."
- store_in :csrdir
+ store_in :csrdir
- def save(request)
- result = super
- Puppet.notice "#{request.key} has a waiting certificate request"
- result
- end
+ def save(request)
+ result = super
+ Puppet.notice "#{request.key} has a waiting certificate request"
+ result
+ end
end
diff --git a/lib/puppet/indirector/certificate_request/file.rb b/lib/puppet/indirector/certificate_request/file.rb
index 274311e..9510e36 100644
--- a/lib/puppet/indirector/certificate_request/file.rb
+++ b/lib/puppet/indirector/certificate_request/file.rb
@@ -2,7 +2,7 @@ require 'puppet/indirector/ssl_file'
require 'puppet/ssl/certificate_request'
class Puppet::SSL::CertificateRequest::File < Puppet::Indirector::SslFile
- desc "Manage the collection of certificate requests on disk."
+ desc "Manage the collection of certificate requests on disk."
- store_in :requestdir
+ store_in :requestdir
end
diff --git a/lib/puppet/indirector/certificate_request/rest.rb b/lib/puppet/indirector/certificate_request/rest.rb
index eb9e8a9..8181055 100644
--- a/lib/puppet/indirector/certificate_request/rest.rb
+++ b/lib/puppet/indirector/certificate_request/rest.rb
@@ -2,8 +2,8 @@ require 'puppet/ssl/certificate_request'
require 'puppet/indirector/rest'
class Puppet::SSL::CertificateRequest::Rest < Puppet::Indirector::REST
- desc "Find and save certificate requests over HTTP via REST."
+ desc "Find and save certificate requests over HTTP via REST."
- use_server_setting(:ca_server)
- use_port_setting(:ca_port)
+ use_server_setting(:ca_server)
+ use_port_setting(:ca_port)
end
diff --git a/lib/puppet/indirector/certificate_revocation_list/ca.rb b/lib/puppet/indirector/certificate_revocation_list/ca.rb
index 66cc23e..1e2be6e 100644
--- a/lib/puppet/indirector/certificate_revocation_list/ca.rb
+++ b/lib/puppet/indirector/certificate_revocation_list/ca.rb
@@ -2,7 +2,7 @@ require 'puppet/indirector/ssl_file'
require 'puppet/ssl/certificate_revocation_list'
class Puppet::SSL::CertificateRevocationList::Ca < Puppet::Indirector::SslFile
- desc "Manage the CA collection of certificate requests on disk."
+ desc "Manage the CA collection of certificate requests on disk."
- store_at :cacrl
+ store_at :cacrl
end
diff --git a/lib/puppet/indirector/certificate_revocation_list/file.rb b/lib/puppet/indirector/certificate_revocation_list/file.rb
index 037aa6b..fbc4374 100644
--- a/lib/puppet/indirector/certificate_revocation_list/file.rb
+++ b/lib/puppet/indirector/certificate_revocation_list/file.rb
@@ -2,7 +2,7 @@ require 'puppet/indirector/ssl_file'
require 'puppet/ssl/certificate_revocation_list'
class Puppet::SSL::CertificateRevocationList::File < Puppet::Indirector::SslFile
- desc "Manage the global certificate revocation list."
+ desc "Manage the global certificate revocation list."
- store_at :hostcrl
+ store_at :hostcrl
end
diff --git a/lib/puppet/indirector/certificate_revocation_list/rest.rb b/lib/puppet/indirector/certificate_revocation_list/rest.rb
index 6d97ce1..06cbb19 100644
--- a/lib/puppet/indirector/certificate_revocation_list/rest.rb
+++ b/lib/puppet/indirector/certificate_revocation_list/rest.rb
@@ -2,8 +2,8 @@ require 'puppet/ssl/certificate_revocation_list'
require 'puppet/indirector/rest'
class Puppet::SSL::CertificateRevocationList::Rest < Puppet::Indirector::REST
- desc "Find and save certificate revocation lists over HTTP via REST."
+ desc "Find and save certificate revocation lists over HTTP via REST."
- use_server_setting(:ca_server)
- use_port_setting(:ca_port)
+ use_server_setting(:ca_server)
+ use_port_setting(:ca_port)
end
diff --git a/lib/puppet/indirector/couch.rb b/lib/puppet/indirector/couch.rb
index 417d6f9..fae934f 100644
--- a/lib/puppet/indirector/couch.rb
+++ b/lib/puppet/indirector/couch.rb
@@ -3,74 +3,74 @@ raise "Couch terminus not supported without couchrest gem" unless Puppet.feature
require 'couchrest'
class Puppet::Indirector::Couch < Puppet::Indirector::Terminus
- # The CouchRest database instance. One database instance per Puppet runtime
- # should be sufficient.
- #
- def self.db; @db ||= CouchRest.database! Puppet[:couchdb_url] end
- def db; self.class.db end
+ # The CouchRest database instance. One database instance per Puppet runtime
+ # should be sufficient.
+ #
+ def self.db; @db ||= CouchRest.database! Puppet[:couchdb_url] end
+ def db; self.class.db end
- def find(request)
- attributes_of get(request)
- end
+ def find(request)
+ attributes_of get(request)
+ end
- # Create or update the couchdb document with the request's data hash.
- #
- def save(request)
- raise ArgumentError, "PUT does not accept options" unless request.options.empty?
- update(request) || create(request)
- end
+ # Create or update the couchdb document with the request's data hash.
+ #
+ def save(request)
+ raise ArgumentError, "PUT does not accept options" unless request.options.empty?
+ update(request) || create(request)
+ end
- private
+ private
- # RKH:TODO: Do not depend on error handling, check if the document exists
- # first. (Does couchrest support this?)
- #
- def get(request)
- db.get(id_for(request))
- rescue RestClient::ResourceNotFound
- Puppet.debug "No couchdb document with id: #{id_for(request)}"
- return nil
- end
+ # RKH:TODO: Do not depend on error handling, check if the document exists
+ # first. (Does couchrest support this?)
+ #
+ def get(request)
+ db.get(id_for(request))
+ rescue RestClient::ResourceNotFound
+ Puppet.debug "No couchdb document with id: #{id_for(request)}"
+ return nil
+ end
- def update(request)
- doc = get request
- return unless doc
- doc.merge!(hash_from(request))
- doc.save
- true
- end
+ def update(request)
+ doc = get request
+ return unless doc
+ doc.merge!(hash_from(request))
+ doc.save
+ true
+ end
- def create(request)
- db.save_doc hash_from(request)
- end
+ def create(request)
+ db.save_doc hash_from(request)
+ end
- # The attributes hash that is serialized to CouchDB as JSON. It includes
- # metadata that is used to help aggregate data in couchdb. Add
- # model-specific attributes in subclasses.
- #
- def hash_from(request)
- {
- "_id" => id_for(request),
- "puppet_type" => document_type_for(request)
- }
- end
+ # The attributes hash that is serialized to CouchDB as JSON. It includes
+ # metadata that is used to help aggregate data in couchdb. Add
+ # model-specific attributes in subclasses.
+ #
+ def hash_from(request)
+ {
+ "_id" => id_for(request),
+ "puppet_type" => document_type_for(request)
+ }
+ end
- # The couchdb response stripped of metadata, used to instantiate the model
- # instance that is returned by save.
- #
- def attributes_of(response)
- response && response.reject{|k,v| k =~ /^(_rev|puppet_)/ }
- end
+ # The couchdb response stripped of metadata, used to instantiate the model
+ # instance that is returned by save.
+ #
+ def attributes_of(response)
+ response && response.reject{|k,v| k =~ /^(_rev|puppet_)/ }
+ end
- def document_type_for(request)
- request.indirection_name
- end
+ def document_type_for(request)
+ request.indirection_name
+ end
- # The id used to store the object in couchdb. Implemented in subclasses.
- #
- def id_for(request)
- raise NotImplementedError
- end
+ # The id used to store the object in couchdb. Implemented in subclasses.
+ #
+ def id_for(request)
+ raise NotImplementedError
+ end
end
diff --git a/lib/puppet/indirector/direct_file_server.rb b/lib/puppet/indirector/direct_file_server.rb
index ba5c7c4..80c84ea 100644
--- a/lib/puppet/indirector/direct_file_server.rb
+++ b/lib/puppet/indirector/direct_file_server.rb
@@ -7,17 +7,17 @@ require 'puppet/indirector/terminus'
class Puppet::Indirector::DirectFileServer < Puppet::Indirector::Terminus
- include Puppet::FileServing::TerminusHelper
+ include Puppet::FileServing::TerminusHelper
- def find(request)
- return nil unless FileTest.exists?(request.key)
- instance = model.new(request.key)
- instance.links = request.options[:links] if request.options[:links]
- instance
- end
+ def find(request)
+ return nil unless FileTest.exists?(request.key)
+ instance = model.new(request.key)
+ instance.links = request.options[:links] if request.options[:links]
+ instance
+ end
- def search(request)
- return nil unless FileTest.exists?(request.key)
- path2instances(request, request.key)
- end
+ def search(request)
+ return nil unless FileTest.exists?(request.key)
+ path2instances(request, request.key)
+ end
end
diff --git a/lib/puppet/indirector/envelope.rb b/lib/puppet/indirector/envelope.rb
index 5fdea70..73c33e9 100644
--- a/lib/puppet/indirector/envelope.rb
+++ b/lib/puppet/indirector/envelope.rb
@@ -3,9 +3,9 @@ require 'puppet/indirector'
# Provide any attributes or functionality needed for indirected
# instances.
module Puppet::Indirector::Envelope
- attr_accessor :expiration
+ attr_accessor :expiration
- def expired?
- expiration and expiration < Time.now
- end
+ def expired?
+ expiration and expiration < Time.now
+ end
end
diff --git a/lib/puppet/indirector/exec.rb b/lib/puppet/indirector/exec.rb
index 9d90d09..fa78944 100644
--- a/lib/puppet/indirector/exec.rb
+++ b/lib/puppet/indirector/exec.rb
@@ -2,48 +2,48 @@ require 'puppet/indirector/terminus'
require 'puppet/util'
class Puppet::Indirector::Exec < Puppet::Indirector::Terminus
- # Look for external node definitions.
- def find(request)
- # Run the command.
- unless output = query(request.key)
- return nil
- end
-
- # Translate the output to ruby.
- output
+ # Look for external node definitions.
+ def find(request)
+ # Run the command.
+ unless output = query(request.key)
+ return nil
end
- private
+ # Translate the output to ruby.
+ output
+ end
- # Proxy the execution, so it's easier to test.
- def execute(command)
- Puppet::Util.execute(command)
+ private
+
+ # Proxy the execution, so it's easier to test.
+ def execute(command)
+ Puppet::Util.execute(command)
+ end
+
+ # Call the external command and see if it returns our output.
+ def query(name)
+ external_command = command
+
+ # Make sure it's an arry
+ raise Puppet::DevError, "Exec commands must be an array" unless external_command.is_a?(Array)
+
+ # Make sure it's fully qualified.
+ raise ArgumentError, "You must set the exec parameter to a fully qualified command" unless external_command[0][0] == File::SEPARATOR[0]
+
+ # Add our name to it.
+ external_command << name
+ begin
+ output = execute(external_command)
+ rescue Puppet::ExecutionFailure => detail
+ Puppet.err "Failed to find #{name} via exec: #{detail}"
+ return nil
end
- # Call the external command and see if it returns our output.
- def query(name)
- external_command = command
-
- # Make sure it's an arry
- raise Puppet::DevError, "Exec commands must be an array" unless external_command.is_a?(Array)
-
- # Make sure it's fully qualified.
- raise ArgumentError, "You must set the exec parameter to a fully qualified command" unless external_command[0][0] == File::SEPARATOR[0]
-
- # Add our name to it.
- external_command << name
- begin
- output = execute(external_command)
- rescue Puppet::ExecutionFailure => detail
- Puppet.err "Failed to find #{name} via exec: #{detail}"
- return nil
- end
-
- if output =~ /\A\s*\Z/ # all whitespace
- Puppet.debug "Empty response for #{name} from exec #{self.name} terminus"
- return nil
- else
- return output
- end
+ if output =~ /\A\s*\Z/ # all whitespace
+ Puppet.debug "Empty response for #{name} from exec #{self.name} terminus"
+ return nil
+ else
+ return output
end
+ end
end
diff --git a/lib/puppet/indirector/facts/active_record.rb b/lib/puppet/indirector/facts/active_record.rb
index a2d3e77..96ed800 100644
--- a/lib/puppet/indirector/facts/active_record.rb
+++ b/lib/puppet/indirector/facts/active_record.rb
@@ -4,33 +4,33 @@ require 'puppet/rails/host'
require 'puppet/indirector/active_record'
class Puppet::Node::Facts::ActiveRecord < Puppet::Indirector::ActiveRecord
- use_ar_model Puppet::Rails::Host
-
- # Find the Rails host and pull its facts as a Facts instance.
- def find(request)
- return nil unless host = ar_model.find_by_name(request.key, :include => {:fact_values => :fact_name})
-
- facts = Puppet::Node::Facts.new(host.name)
- facts.values = host.get_facts_hash.inject({}) do |hash, ary|
- # Convert all single-member arrays into plain values.
- param = ary[0]
- values = ary[1].collect { |v| v.value }
- values = values[0] if values.length == 1
- hash[param] = values
- hash
- end
-
- facts
+ use_ar_model Puppet::Rails::Host
+
+ # Find the Rails host and pull its facts as a Facts instance.
+ def find(request)
+ return nil unless host = ar_model.find_by_name(request.key, :include => {:fact_values => :fact_name})
+
+ facts = Puppet::Node::Facts.new(host.name)
+ facts.values = host.get_facts_hash.inject({}) do |hash, ary|
+ # Convert all single-member arrays into plain values.
+ param = ary[0]
+ values = ary[1].collect { |v| v.value }
+ values = values[0] if values.length == 1
+ hash[param] = values
+ hash
end
- # Save the values from a Facts instance as the facts on a Rails Host instance.
- def save(request)
- facts = request.instance
+ facts
+ end
- host = ar_model.find_by_name(facts.name) || ar_model.create(:name => facts.name)
+ # Save the values from a Facts instance as the facts on a Rails Host instance.
+ def save(request)
+ facts = request.instance
- host.merge_facts(facts.values)
+ host = ar_model.find_by_name(facts.name) || ar_model.create(:name => facts.name)
- host.save
- end
+ host.merge_facts(facts.values)
+
+ host.save
+ end
end
diff --git a/lib/puppet/indirector/facts/couch.rb b/lib/puppet/indirector/facts/couch.rb
index 522fe33..fda2b91 100644
--- a/lib/puppet/indirector/facts/couch.rb
+++ b/lib/puppet/indirector/facts/couch.rb
@@ -2,30 +2,30 @@ require 'puppet/node/facts'
require 'puppet/indirector/couch'
class Puppet::Node::Facts::Couch < Puppet::Indirector::Couch
- # Return the facts object or nil if there is no document
- def find(request)
- doc = super
- doc ? model.new(doc['_id'], doc['facts']) : nil
- end
+ # Return the facts object or nil if there is no document
+ def find(request)
+ doc = super
+ doc ? model.new(doc['_id'], doc['facts']) : nil
+ end
- private
+ private
- # Facts values are stored to the document's 'facts' attribute. Hostname is
- # stored to 'name'
- #
- def hash_from(request)
- super.merge('facts' => request.instance.values)
- end
+ # Facts values are stored to the document's 'facts' attribute. Hostname is
+ # stored to 'name'
+ #
+ def hash_from(request)
+ super.merge('facts' => request.instance.values)
+ end
- # Facts are stored to the 'node' document.
- def document_type_for(request)
- 'node'
- end
+ # Facts are stored to the 'node' document.
+ def document_type_for(request)
+ 'node'
+ end
- # The id used to store the object in couchdb.
- def id_for(request)
- request.key.to_s
- end
+ # The id used to store the object in couchdb.
+ def id_for(request)
+ request.key.to_s
+ end
end
diff --git a/lib/puppet/indirector/facts/facter.rb b/lib/puppet/indirector/facts/facter.rb
index a3ce79b..ab7378a 100644
--- a/lib/puppet/indirector/facts/facter.rb
+++ b/lib/puppet/indirector/facts/facter.rb
@@ -2,82 +2,82 @@ require 'puppet/node/facts'
require 'puppet/indirector/code'
class Puppet::Node::Facts::Facter < Puppet::Indirector::Code
- desc "Retrieve facts from Facter. This provides a somewhat abstract interface
- between Puppet and Facter. It's only `somewhat` abstract because it always
- returns the local host's facts, regardless of what you attempt to find."
+ desc "Retrieve facts from Facter. This provides a somewhat abstract interface
+ between Puppet and Facter. It's only `somewhat` abstract because it always
+ returns the local host's facts, regardless of what you attempt to find."
- def self.load_fact_plugins
- # Add any per-module fact directories to the factpath
- module_fact_dirs = Puppet[:modulepath].split(":").collect do |d|
- ["lib", "plugins"].map do |subdirectory|
- Dir.glob("#{d}/*/#{subdirectory}/facter")
- end
- end.flatten
- dirs = module_fact_dirs + Puppet[:factpath].split(":")
- x = dirs.each do |dir|
- load_facts_in_dir(dir)
- end
+ def self.load_fact_plugins
+ # Add any per-module fact directories to the factpath
+ module_fact_dirs = Puppet[:modulepath].split(":").collect do |d|
+ ["lib", "plugins"].map do |subdirectory|
+ Dir.glob("#{d}/*/#{subdirectory}/facter")
+ end
+ end.flatten
+ dirs = module_fact_dirs + Puppet[:factpath].split(":")
+ x = dirs.each do |dir|
+ load_facts_in_dir(dir)
end
+ end
- def self.load_facts_in_dir(dir)
- return unless FileTest.directory?(dir)
+ def self.load_facts_in_dir(dir)
+ return unless FileTest.directory?(dir)
- Dir.chdir(dir) do
- Dir.glob("*.rb").each do |file|
- fqfile = ::File.join(dir, file)
- begin
- Puppet.info "Loading facts in #{::File.basename(file.sub(".rb",''))}"
- Timeout::timeout(self.timeout) do
- load file
- end
- rescue SystemExit,NoMemoryError
- raise
- rescue Exception => detail
- Puppet.warning "Could not load fact file #{fqfile}: #{detail}"
- end
- end
+ Dir.chdir(dir) do
+ Dir.glob("*.rb").each do |file|
+ fqfile = ::File.join(dir, file)
+ begin
+ Puppet.info "Loading facts in #{::File.basename(file.sub(".rb",''))}"
+ Timeout::timeout(self.timeout) do
+ load file
+ end
+ rescue SystemExit,NoMemoryError
+ raise
+ rescue Exception => detail
+ Puppet.warning "Could not load fact file #{fqfile}: #{detail}"
end
+ end
end
+ end
- def self.timeout
- timeout = Puppet[:configtimeout]
- case timeout
- when String
- if timeout =~ /^\d+$/
- timeout = Integer(timeout)
- else
- raise ArgumentError, "Configuration timeout must be an integer"
- end
- when Integer # nothing
- else
- raise ArgumentError, "Configuration timeout must be an integer"
- end
-
- timeout
+ def self.timeout
+ timeout = Puppet[:configtimeout]
+ case timeout
+ when String
+ if timeout =~ /^\d+$/
+ timeout = Integer(timeout)
+ else
+ raise ArgumentError, "Configuration timeout must be an integer"
+ end
+ when Integer # nothing
+ else
+ raise ArgumentError, "Configuration timeout must be an integer"
end
- def initialize(*args)
- super
- self.class.load_fact_plugins
- end
+ timeout
+ end
- def destroy(facts)
- raise Puppet::DevError, "You cannot destroy facts in the code store; it is only used for getting facts from Facter"
- end
+ def initialize(*args)
+ super
+ self.class.load_fact_plugins
+ end
- # Look a host's facts up in Facter.
- def find(request)
- result = Puppet::Node::Facts.new(request.key, Facter.to_hash)
+ def destroy(facts)
+ raise Puppet::DevError, "You cannot destroy facts in the code store; it is only used for getting facts from Facter"
+ end
- result.add_local_facts
- result.stringify
- result.downcase_if_necessary
+ # Look a host's facts up in Facter.
+ def find(request)
+ result = Puppet::Node::Facts.new(request.key, Facter.to_hash)
- result
- end
+ result.add_local_facts
+ result.stringify
+ result.downcase_if_necessary
- def save(facts)
- raise Puppet::DevError, "You cannot save facts to the code store; it is only used for getting facts from Facter"
- end
+ result
+ end
+
+ def save(facts)
+ raise Puppet::DevError, "You cannot save facts to the code store; it is only used for getting facts from Facter"
+ end
end
diff --git a/lib/puppet/indirector/facts/memory.rb b/lib/puppet/indirector/facts/memory.rb
index 3c10d59..c4ca19d 100644
--- a/lib/puppet/indirector/facts/memory.rb
+++ b/lib/puppet/indirector/facts/memory.rb
@@ -2,8 +2,8 @@ require 'puppet/node/facts'
require 'puppet/indirector/memory'
class Puppet::Node::Facts::Memory < Puppet::Indirector::Memory
- desc "Keep track of facts in memory but nowhere else. This is used for
- one-time compiles, such as what the stand-alone ``puppet`` does.
- To use this terminus, you must load it with the data you want it
- to contain."
+ desc "Keep track of facts in memory but nowhere else. This is used for
+ one-time compiles, such as what the stand-alone ``puppet`` does.
+ To use this terminus, you must load it with the data you want it
+ to contain."
end
diff --git a/lib/puppet/indirector/facts/rest.rb b/lib/puppet/indirector/facts/rest.rb
index cf26fba..07491fc 100644
--- a/lib/puppet/indirector/facts/rest.rb
+++ b/lib/puppet/indirector/facts/rest.rb
@@ -2,5 +2,5 @@ require 'puppet/node/facts'
require 'puppet/indirector/rest'
class Puppet::Node::Facts::Rest < Puppet::Indirector::REST
- desc "Find and save facts about nodes over HTTP via REST."
+ desc "Find and save facts about nodes over HTTP via REST."
end
diff --git a/lib/puppet/indirector/facts/yaml.rb b/lib/puppet/indirector/facts/yaml.rb
index b8a8e31..89feaf2 100644
--- a/lib/puppet/indirector/facts/yaml.rb
+++ b/lib/puppet/indirector/facts/yaml.rb
@@ -2,6 +2,6 @@ require 'puppet/node/facts'
require 'puppet/indirector/yaml'
class Puppet::Node::Facts::Yaml < Puppet::Indirector::Yaml
- desc "Store client facts as flat files, serialized using YAML, or
- return deserialized facts from disk."
+ desc "Store client facts as flat files, serialized using YAML, or
+ return deserialized facts from disk."
end
diff --git a/lib/puppet/indirector/file.rb b/lib/puppet/indirector/file.rb
index dab8fc7..b3746b7 100644
--- a/lib/puppet/indirector/file.rb
+++ b/lib/puppet/indirector/file.rb
@@ -2,78 +2,78 @@ require 'puppet/indirector/terminus'
# Store instances as files, usually serialized using some format.
class Puppet::Indirector::File < Puppet::Indirector::Terminus
- # Where do we store our data?
- def data_directory
- name = Puppet.run_mode.master? ? :server_datadir : :client_datadir
-
- File.join(Puppet.settings[name], self.class.indirection_name.to_s)
- end
-
- def file_format(path)
- path =~ /\.(\w+)$/ and return $1
- end
-
- def file_path(request)
- File.join(data_directory, request.key + ".#{serialization_format}")
- end
-
- def latest_path(request)
- files = Dir.glob(File.join(data_directory, request.key + ".*"))
- return nil if files.empty?
-
- # Return the newest file.
- files.sort { |a, b| File.stat(b).mtime <=> File.stat(a).mtime }[0]
- end
-
- def serialization_format
- model.default_format
+ # Where do we store our data?
+ def data_directory
+ name = Puppet.run_mode.master? ? :server_datadir : :client_datadir
+
+ File.join(Puppet.settings[name], self.class.indirection_name.to_s)
+ end
+
+ def file_format(path)
+ path =~ /\.(\w+)$/ and return $1
+ end
+
+ def file_path(request)
+ File.join(data_directory, request.key + ".#{serialization_format}")
+ end
+
+ def latest_path(request)
+ files = Dir.glob(File.join(data_directory, request.key + ".*"))
+ return nil if files.empty?
+
+ # Return the newest file.
+ files.sort { |a, b| File.stat(b).mtime <=> File.stat(a).mtime }[0]
+ end
+
+ def serialization_format
+ model.default_format
+ end
+
+ # Remove files on disk.
+ def destroy(request)
+ begin
+ removed = false
+ Dir.glob(File.join(data_directory, request.key.to_s + ".*")).each do |file|
+ removed = true
+ File.unlink(file)
+ end
+ rescue => detail
+ raise Puppet::Error, "Could not remove #{request.key}: #{detail}"
end
- # Remove files on disk.
- def destroy(request)
- begin
- removed = false
- Dir.glob(File.join(data_directory, request.key.to_s + ".*")).each do |file|
- removed = true
- File.unlink(file)
- end
- rescue => detail
- raise Puppet::Error, "Could not remove #{request.key}: #{detail}"
- end
-
- raise Puppet::Error, "Could not find files for #{request.key} to remove" unless removed
- end
+ raise Puppet::Error, "Could not find files for #{request.key} to remove" unless removed
+ end
- # Return a model instance for a given file on disk.
- def find(request)
- return nil unless path = latest_path(request)
- format = file_format(path)
+ # Return a model instance for a given file on disk.
+ def find(request)
+ return nil unless path = latest_path(request)
+ format = file_format(path)
- raise ArgumentError, "File format #{format} is not supported by #{self.class.indirection_name}" unless model.support_format?(format)
+ raise ArgumentError, "File format #{format} is not supported by #{self.class.indirection_name}" unless model.support_format?(format)
- begin
- return model.convert_from(format, File.read(path))
- rescue => detail
- raise Puppet::Error, "Could not convert path #{path} into a #{self.class.indirection_name}: #{detail}"
- end
+ begin
+ return model.convert_from(format, File.read(path))
+ rescue => detail
+ raise Puppet::Error, "Could not convert path #{path} into a #{self.class.indirection_name}: #{detail}"
end
+ end
- # Save a new file to disk.
- def save(request)
- path = file_path(request)
+ # Save a new file to disk.
+ def save(request)
+ path = file_path(request)
- dir = File.dirname(path)
+ dir = File.dirname(path)
- raise Puppet::Error.new("Cannot save #{request.key}; parent directory #{dir} does not exist") unless File.directory?(dir)
+ raise Puppet::Error.new("Cannot save #{request.key}; parent directory #{dir} does not exist") unless File.directory?(dir)
- begin
- File.open(path, "w") { |f| f.print request.instance.render(serialization_format) }
- rescue => detail
- raise Puppet::Error, "Could not write #{request.key}: #{detail}" % [request.key, detail]
- end
+ begin
+ File.open(path, "w") { |f| f.print request.instance.render(serialization_format) }
+ rescue => detail
+ raise Puppet::Error, "Could not write #{request.key}: #{detail}" % [request.key, detail]
end
+ end
- def path(key)
- key
- end
+ def path(key)
+ key
+ end
end
diff --git a/lib/puppet/indirector/file_bucket_file/file.rb b/lib/puppet/indirector/file_bucket_file/file.rb
index ed97869..318858a 100644
--- a/lib/puppet/indirector/file_bucket_file/file.rb
+++ b/lib/puppet/indirector/file_bucket_file/file.rb
@@ -4,143 +4,143 @@ require 'puppet/util/checksums'
require 'fileutils'
module Puppet::FileBucketFile
- class File < Puppet::Indirector::Code
- include Puppet::Util::Checksums
+ class File < Puppet::Indirector::Code
+ include Puppet::Util::Checksums
- desc "Store files in a directory set based on their checksums."
+ desc "Store files in a directory set based on their checksums."
- def initialize
- Puppet.settings.use(:filebucket)
- end
-
- def find( request )
- checksum, path = request_to_checksum_and_path( request )
- find_by_checksum( checksum, request.options )
- end
+ def initialize
+ Puppet.settings.use(:filebucket)
+ end
- def save( request )
- checksum, path = request_to_checksum_and_path( request )
+ def find( request )
+ checksum, path = request_to_checksum_and_path( request )
+ find_by_checksum( checksum, request.options )
+ end
- instance = request.instance
- instance.checksum = checksum if checksum
- instance.path = path if path
+ def save( request )
+ checksum, path = request_to_checksum_and_path( request )
- save_to_disk(instance)
- instance.to_s
- end
+ instance = request.instance
+ instance.checksum = checksum if checksum
+ instance.path = path if path
- private
+ save_to_disk(instance)
+ instance.to_s
+ end
- def find_by_checksum( checksum, options )
- model.new( nil, :checksum => checksum ) do |bucket_file|
- bucket_file.bucket_path = options[:bucket_path]
- filename = contents_path_for( bucket_file )
+ private
- return nil if ! ::File.exist? filename
+ def find_by_checksum( checksum, options )
+ model.new( nil, :checksum => checksum ) do |bucket_file|
+ bucket_file.bucket_path = options[:bucket_path]
+ filename = contents_path_for( bucket_file )
- begin
- contents = ::File.read filename
- Puppet.info "FileBucket read #{bucket_file.checksum}"
- rescue RuntimeError => e
- raise Puppet::Error, "file could not be read: #{e.message}"
- end
+ return nil if ! ::File.exist? filename
- if ::File.exist?(paths_path_for( bucket_file) )
- ::File.open(paths_path_for( bucket_file) ) do |f|
- bucket_file.paths = f.readlines.map { |l| l.chomp }
- end
- end
+ begin
+ contents = ::File.read filename
+ Puppet.info "FileBucket read #{bucket_file.checksum}"
+ rescue RuntimeError => e
+ raise Puppet::Error, "file could not be read: #{e.message}"
+ end
- bucket_file.contents = contents
- end
+ if ::File.exist?(paths_path_for( bucket_file) )
+ ::File.open(paths_path_for( bucket_file) ) do |f|
+ bucket_file.paths = f.readlines.map { |l| l.chomp }
+ end
end
- def save_to_disk( bucket_file )
- # If the file already exists, just return the md5 sum.
- if ::File.exist?(contents_path_for( bucket_file) )
- verify_identical_file!(bucket_file)
- else
- # Make the directories if necessary.
- unless ::File.directory?( path_for( bucket_file) )
- Puppet::Util.withumask(0007) do
- ::FileUtils.mkdir_p( path_for( bucket_file) )
- end
- end
-
- Puppet.info "FileBucket adding #{bucket_file.path} as #{bucket_file.checksum}"
-
- # Write the file to disk.
- Puppet::Util.withumask(0007) do
- ::File.open(contents_path_for(bucket_file), ::File::WRONLY|::File::CREAT, 0440) do |of|
- of.print bucket_file.contents
- end
- end
- end
-
- save_path_to_paths_file(bucket_file)
- bucket_file.checksum_data
+ bucket_file.contents = contents
+ end
+ end
+
+ def save_to_disk( bucket_file )
+ # If the file already exists, just return the md5 sum.
+ if ::File.exist?(contents_path_for( bucket_file) )
+ verify_identical_file!(bucket_file)
+ else
+ # Make the directories if necessary.
+ unless ::File.directory?( path_for( bucket_file) )
+ Puppet::Util.withumask(0007) do
+ ::FileUtils.mkdir_p( path_for( bucket_file) )
+ end
end
- def request_to_checksum_and_path( request )
- return [request.key, nil] if checksum?(request.key)
+ Puppet.info "FileBucket adding #{bucket_file.path} as #{bucket_file.checksum}"
- checksum_type, checksum, path = request.key.split(/\//, 3)
- return(checksum_type.to_s == "" ? nil : [ "{#{checksum_type}}#{checksum}", path ])
+ # Write the file to disk.
+ Puppet::Util.withumask(0007) do
+ ::File.open(contents_path_for(bucket_file), ::File::WRONLY|::File::CREAT, 0440) do |of|
+ of.print bucket_file.contents
+ end
end
+ end
- def path_for(bucket_file, subfile = nil)
- bucket_path = bucket_file.bucket_path || Puppet[:bucketdir]
- digest = bucket_file.checksum_data
+ save_path_to_paths_file(bucket_file)
+ bucket_file.checksum_data
+ end
- dir = ::File.join(digest[0..7].split(""))
- basedir = ::File.join(bucket_path, dir, digest)
+ def request_to_checksum_and_path( request )
+ return [request.key, nil] if checksum?(request.key)
- return basedir unless subfile
- ::File.join(basedir, subfile)
- end
+ checksum_type, checksum, path = request.key.split(/\//, 3)
+ return(checksum_type.to_s == "" ? nil : [ "{#{checksum_type}}#{checksum}", path ])
+ end
- def contents_path_for(bucket_file)
- path_for(bucket_file, "contents")
- end
+ def path_for(bucket_file, subfile = nil)
+ bucket_path = bucket_file.bucket_path || Puppet[:bucketdir]
+ digest = bucket_file.checksum_data
- def paths_path_for(bucket_file)
- path_for(bucket_file, "paths")
- end
+ dir = ::File.join(digest[0..7].split(""))
+ basedir = ::File.join(bucket_path, dir, digest)
- def content_check?
- true
- end
+ return basedir unless subfile
+ ::File.join(basedir, subfile)
+ end
- # If conflict_check is enabled, verify that the passed text is
- # the same as the text in our file.
- def verify_identical_file!(bucket_file)
- return unless content_check?
- disk_contents = ::File.read(contents_path_for(bucket_file))
-
- # If the contents don't match, then we've found a conflict.
- # Unlikely, but quite bad.
- if disk_contents != bucket_file.contents
- raise Puppet::FileBucket::BucketError, "Got passed new contents for sum #{bucket_file.checksum}", caller
- else
- Puppet.info "FileBucket got a duplicate file #{bucket_file.path} (#{bucket_file.checksum})"
- end
- end
+ def contents_path_for(bucket_file)
+ path_for(bucket_file, "contents")
+ end
- def save_path_to_paths_file(bucket_file)
- return unless bucket_file.path
+ def paths_path_for(bucket_file)
+ path_for(bucket_file, "paths")
+ end
+
+ def content_check?
+ true
+ end
- # check for dupes
- if ::File.exist?(paths_path_for( bucket_file) )
- ::File.open(paths_path_for( bucket_file) ) do |f|
- return if f.readlines.collect { |l| l.chomp }.include?(bucket_file.path)
- end
- end
+ # If conflict_check is enabled, verify that the passed text is
+ # the same as the text in our file.
+ def verify_identical_file!(bucket_file)
+ return unless content_check?
+ disk_contents = ::File.read(contents_path_for(bucket_file))
+
+ # If the contents don't match, then we've found a conflict.
+ # Unlikely, but quite bad.
+ if disk_contents != bucket_file.contents
+ raise Puppet::FileBucket::BucketError, "Got passed new contents for sum #{bucket_file.checksum}", caller
+ else
+ Puppet.info "FileBucket got a duplicate file #{bucket_file.path} (#{bucket_file.checksum})"
+ end
+ end
+
+ def save_path_to_paths_file(bucket_file)
+ return unless bucket_file.path
- # if it's a new file, or if our path isn't in the file yet, add it
- ::File.open(paths_path_for(bucket_file), ::File::WRONLY|::File::CREAT|::File::APPEND) do |of|
- of.puts bucket_file.path
- end
+ # check for dupes
+ if ::File.exist?(paths_path_for( bucket_file) )
+ ::File.open(paths_path_for( bucket_file) ) do |f|
+ return if f.readlines.collect { |l| l.chomp }.include?(bucket_file.path)
end
+ end
+ # if it's a new file, or if our path isn't in the file yet, add it
+ ::File.open(paths_path_for(bucket_file), ::File::WRONLY|::File::CREAT|::File::APPEND) do |of|
+ of.puts bucket_file.path
+ end
end
+
+ end
end
diff --git a/lib/puppet/indirector/file_bucket_file/rest.rb b/lib/puppet/indirector/file_bucket_file/rest.rb
index 15e4f33..783d435 100644
--- a/lib/puppet/indirector/file_bucket_file/rest.rb
+++ b/lib/puppet/indirector/file_bucket_file/rest.rb
@@ -2,7 +2,7 @@ require 'puppet/indirector/rest'
require 'puppet/file_bucket/file'
module Puppet::FileBucketFile
- class Rest < Puppet::Indirector::REST
- desc "This is a REST based mechanism to send/retrieve file to/from the filebucket"
- end
+ class Rest < Puppet::Indirector::REST
+ desc "This is a REST based mechanism to send/retrieve file to/from the filebucket"
+ end
end
diff --git a/lib/puppet/indirector/file_content/file.rb b/lib/puppet/indirector/file_content/file.rb
index 30c7958..75fc998 100644
--- a/lib/puppet/indirector/file_content/file.rb
+++ b/lib/puppet/indirector/file_content/file.rb
@@ -7,5 +7,5 @@ require 'puppet/indirector/file_content'
require 'puppet/indirector/direct_file_server'
class Puppet::Indirector::FileContent::File < Puppet::Indirector::DirectFileServer
- desc "Retrieve file contents from disk."
+ desc "Retrieve file contents from disk."
end
diff --git a/lib/puppet/indirector/file_content/file_server.rb b/lib/puppet/indirector/file_content/file_server.rb
index 2f50fcc..21cfe73 100644
--- a/lib/puppet/indirector/file_content/file_server.rb
+++ b/lib/puppet/indirector/file_content/file_server.rb
@@ -7,5 +7,5 @@ require 'puppet/indirector/file_content'
require 'puppet/indirector/file_server'
class Puppet::Indirector::FileContent::FileServer < Puppet::Indirector::FileServer
- desc "Retrieve file contents using Puppet's fileserver."
+ desc "Retrieve file contents using Puppet's fileserver."
end
diff --git a/lib/puppet/indirector/file_content/rest.rb b/lib/puppet/indirector/file_content/rest.rb
index 7b3cade..2fd39b7 100644
--- a/lib/puppet/indirector/file_content/rest.rb
+++ b/lib/puppet/indirector/file_content/rest.rb
@@ -7,5 +7,5 @@ require 'puppet/indirector/file_content'
require 'puppet/indirector/rest'
class Puppet::Indirector::FileContent::Rest < Puppet::Indirector::REST
- desc "Retrieve file contents via a REST HTTP interface."
+ desc "Retrieve file contents via a REST HTTP interface."
end
diff --git a/lib/puppet/indirector/file_metadata/file.rb b/lib/puppet/indirector/file_metadata/file.rb
index 9404748..4d6b0b3 100644
--- a/lib/puppet/indirector/file_metadata/file.rb
+++ b/lib/puppet/indirector/file_metadata/file.rb
@@ -7,20 +7,20 @@ require 'puppet/indirector/file_metadata'
require 'puppet/indirector/direct_file_server'
class Puppet::Indirector::FileMetadata::File < Puppet::Indirector::DirectFileServer
- desc "Retrieve file metadata directly from the local filesystem."
+ desc "Retrieve file metadata directly from the local filesystem."
- def find(request)
- return unless data = super
- data.collect
+ def find(request)
+ return unless data = super
+ data.collect
- data
- end
+ data
+ end
- def search(request)
- return unless result = super
+ def search(request)
+ return unless result = super
- result.each { |instance| instance.collect }
+ result.each { |instance| instance.collect }
- result
- end
+ result
+ end
end
diff --git a/lib/puppet/indirector/file_metadata/file_server.rb b/lib/puppet/indirector/file_metadata/file_server.rb
index 0b2e789..cef81f0 100644
--- a/lib/puppet/indirector/file_metadata/file_server.rb
+++ b/lib/puppet/indirector/file_metadata/file_server.rb
@@ -7,5 +7,5 @@ require 'puppet/indirector/file_metadata'
require 'puppet/indirector/file_server'
class Puppet::Indirector::FileMetadata::FileServer < Puppet::Indirector::FileServer
- desc "Retrieve file metadata using Puppet's fileserver."
+ desc "Retrieve file metadata using Puppet's fileserver."
end
diff --git a/lib/puppet/indirector/file_metadata/rest.rb b/lib/puppet/indirector/file_metadata/rest.rb
index 8cbf910..023edb8 100644
--- a/lib/puppet/indirector/file_metadata/rest.rb
+++ b/lib/puppet/indirector/file_metadata/rest.rb
@@ -7,5 +7,5 @@ require 'puppet/indirector/file_metadata'
require 'puppet/indirector/rest'
class Puppet::Indirector::FileMetadata::Rest < Puppet::Indirector::REST
- desc "Retrieve file metadata via a REST HTTP interface."
+ desc "Retrieve file metadata via a REST HTTP interface."
end
diff --git a/lib/puppet/indirector/file_server.rb b/lib/puppet/indirector/file_server.rb
index 833fc6f..46a08c9 100644
--- a/lib/puppet/indirector/file_server.rb
+++ b/lib/puppet/indirector/file_server.rb
@@ -9,61 +9,61 @@ require 'puppet/indirector/terminus'
# Look files up using the file server.
class Puppet::Indirector::FileServer < Puppet::Indirector::Terminus
- include Puppet::FileServing::TerminusHelper
+ include Puppet::FileServing::TerminusHelper
- # Is the client authorized to perform this action?
- def authorized?(request)
- return false unless [:find, :search].include?(request.method)
+ # Is the client authorized to perform this action?
+ def authorized?(request)
+ return false unless [:find, :search].include?(request.method)
- mount, file_path = configuration.split_path(request)
+ mount, file_path = configuration.split_path(request)
- # If we're not serving this mount, then access is denied.
- return false unless mount
- mount.allowed?(request.node, request.ip)
- end
+ # If we're not serving this mount, then access is denied.
+ return false unless mount
+ mount.allowed?(request.node, request.ip)
+ end
- # Find our key using the fileserver.
- def find(request)
- mount, relative_path = configuration.split_path(request)
+ # Find our key using the fileserver.
+ def find(request)
+ mount, relative_path = configuration.split_path(request)
- return nil unless mount
+ return nil unless mount
- # The mount checks to see if the file exists, and returns nil
- # if not.
- return nil unless path = mount.find(relative_path, request)
- result = model.new(path)
- result.links = request.options[:links] if request.options[:links]
- result.collect
- result
- end
+ # The mount checks to see if the file exists, and returns nil
+ # if not.
+ return nil unless path = mount.find(relative_path, request)
+ result = model.new(path)
+ result.links = request.options[:links] if request.options[:links]
+ result.collect
+ result
+ end
- # Search for files. This returns an array rather than a single
- # file.
- def search(request)
- mount, relative_path = configuration.split_path(request)
+ # Search for files. This returns an array rather than a single
+ # file.
+ def search(request)
+ mount, relative_path = configuration.split_path(request)
- unless mount and paths = mount.search(relative_path, request)
- Puppet.info "Could not find filesystem info for file '#{request.key}' in environment #{request.environment}"
- return nil
- end
+ unless mount and paths = mount.search(relative_path, request)
+ Puppet.info "Could not find filesystem info for file '#{request.key}' in environment #{request.environment}"
+ return nil
+ end
- filesets = paths.collect do |path|
- # Filesets support indirector requests as an options collection
- Puppet::FileServing::Fileset.new(path, request)
- end
+ filesets = paths.collect do |path|
+ # Filesets support indirector requests as an options collection
+ Puppet::FileServing::Fileset.new(path, request)
+ end
- Puppet::FileServing::Fileset.merge(*filesets).collect do |file, base_path|
- inst = model.new(base_path, :relative_path => file)
- inst.links = request.options[:links] if request.options[:links]
- inst.collect
- inst
- end
+ Puppet::FileServing::Fileset.merge(*filesets).collect do |file, base_path|
+ inst = model.new(base_path, :relative_path => file)
+ inst.links = request.options[:links] if request.options[:links]
+ inst.collect
+ inst
end
+ end
- private
+ private
- # Our fileserver configuration, if needed.
- def configuration
- Puppet::FileServing::Configuration.create
- end
+ # Our fileserver configuration, if needed.
+ def configuration
+ Puppet::FileServing::Configuration.create
+ end
end
diff --git a/lib/puppet/indirector/indirection.rb b/lib/puppet/indirector/indirection.rb
index 2b7da22..309eed7 100644
--- a/lib/puppet/indirector/indirection.rb
+++ b/lib/puppet/indirector/indirection.rb
@@ -7,302 +7,302 @@ require 'puppet/util/cacher'
# back-ends. Each indirection has a set of associated terminus classes,
# each of which is a subclass of Puppet::Indirector::Terminus.
class Puppet::Indirector::Indirection
- include Puppet::Util::Cacher
- include Puppet::Util::Docs
-
- @@indirections = []
-
- # Find an indirection by name. This is provided so that Terminus classes
- # can specifically hook up with the indirections they are associated with.
- def self.instance(name)
- @@indirections.find { |i| i.name == name }
+ include Puppet::Util::Cacher
+ include Puppet::Util::Docs
+
+ @@indirections = []
+
+ # Find an indirection by name. This is provided so that Terminus classes
+ # can specifically hook up with the indirections they are associated with.
+ def self.instance(name)
+ @@indirections.find { |i| i.name == name }
+ end
+
+ # Return a list of all known indirections. Used to generate the
+ # reference.
+ def self.instances
+ @@indirections.collect { |i| i.name }
+ end
+
+ # Find an indirected model by name. This is provided so that Terminus classes
+ # can specifically hook up with the indirections they are associated with.
+ def self.model(name)
+ return nil unless match = @@indirections.find { |i| i.name == name }
+ match.model
+ end
+
+ attr_accessor :name, :model
+
+ # Create and return our cache terminus.
+ def cache
+ raise(Puppet::DevError, "Tried to cache when no cache class was set") unless cache_class
+ terminus(cache_class)
+ end
+
+ # Should we use a cache?
+ def cache?
+ cache_class ? true : false
+ end
+
+ attr_reader :cache_class
+ # Define a terminus class to be used for caching.
+ def cache_class=(class_name)
+ validate_terminus_class(class_name) if class_name
+ @cache_class = class_name
+ end
+
+ # This is only used for testing.
+ def delete
+ @@indirections.delete(self) if @@indirections.include?(self)
+ end
+
+ # Set the time-to-live for instances created through this indirection.
+ def ttl=(value)
+ raise ArgumentError, "Indirection TTL must be an integer" unless value.is_a?(Fixnum)
+ @ttl = value
+ end
+
+ # Default to the runinterval for the ttl.
+ def ttl
+ @ttl ||= Puppet[:runinterval].to_i
+ end
+
+ # Calculate the expiration date for a returned instance.
+ def expiration
+ Time.now + ttl
+ end
+
+ # Generate the full doc string.
+ def doc
+ text = ""
+
+ text += scrub(@doc) + "\n\n" if @doc
+
+ if s = terminus_setting
+ text += "* **Terminus Setting**: #{terminus_setting}"
end
- # Return a list of all known indirections. Used to generate the
- # reference.
- def self.instances
- @@indirections.collect { |i| i.name }
- end
+ text
+ end
- # Find an indirected model by name. This is provided so that Terminus classes
- # can specifically hook up with the indirections they are associated with.
- def self.model(name)
- return nil unless match = @@indirections.find { |i| i.name == name }
- match.model
- end
-
- attr_accessor :name, :model
-
- # Create and return our cache terminus.
- def cache
- raise(Puppet::DevError, "Tried to cache when no cache class was set") unless cache_class
- terminus(cache_class)
- end
+ def initialize(model, name, options = {})
+ @model = model
+ @name = name
- # Should we use a cache?
- def cache?
- cache_class ? true : false
- end
+ @cache_class = nil
+ @terminus_class = nil
- attr_reader :cache_class
- # Define a terminus class to be used for caching.
- def cache_class=(class_name)
- validate_terminus_class(class_name) if class_name
- @cache_class = class_name
- end
+ raise(ArgumentError, "Indirection #{@name} is already defined") if @@indirections.find { |i| i.name == @name }
+ @@indirections << self
- # This is only used for testing.
- def delete
- @@indirections.delete(self) if @@indirections.include?(self)
+ if mod = options[:extend]
+ extend(mod)
+ options.delete(:extend)
end
- # Set the time-to-live for instances created through this indirection.
- def ttl=(value)
- raise ArgumentError, "Indirection TTL must be an integer" unless value.is_a?(Fixnum)
- @ttl = value
+ # This is currently only used for cache_class and terminus_class.
+ options.each do |name, value|
+ begin
+ send(name.to_s + "=", value)
+ rescue NoMethodError
+ raise ArgumentError, "#{name} is not a valid Indirection parameter"
+ end
end
-
- # Default to the runinterval for the ttl.
- def ttl
- @ttl ||= Puppet[:runinterval].to_i
+ end
+
+ # Set up our request object.
+ def request(*args)
+ Puppet::Indirector::Request.new(self.name, *args)
+ end
+
+ # Return the singleton terminus for this indirection.
+ def terminus(terminus_name = nil)
+ # Get the name of the terminus.
+ raise Puppet::DevError, "No terminus specified for #{self.name}; cannot redirect" unless terminus_name ||= terminus_class
+
+ termini[terminus_name] ||= make_terminus(terminus_name)
+ end
+
+ # This can be used to select the terminus class.
+ attr_accessor :terminus_setting
+
+ # Determine the terminus class.
+ def terminus_class
+ unless @terminus_class
+ if setting = self.terminus_setting
+ self.terminus_class = Puppet.settings[setting].to_sym
+ else
+ raise Puppet::DevError, "No terminus class nor terminus setting was provided for indirection #{self.name}"
+ end
end
-
- # Calculate the expiration date for a returned instance.
- def expiration
- Time.now + ttl
+ @terminus_class
+ end
+
+ def reset_terminus_class
+ @terminus_class = nil
+ end
+
+ # Specify the terminus class to use.
+ def terminus_class=(klass)
+ validate_terminus_class(klass)
+ @terminus_class = klass
+ end
+
+ # This is used by terminus_class= and cache=.
+ def validate_terminus_class(terminus_class)
+ raise ArgumentError, "Invalid terminus name #{terminus_class.inspect}" unless terminus_class and terminus_class.to_s != ""
+ unless Puppet::Indirector::Terminus.terminus_class(self.name, terminus_class)
+ raise ArgumentError, "Could not find terminus #{terminus_class} for indirection #{self.name}"
end
+ end
- # Generate the full doc string.
- def doc
- text = ""
+ # Expire a cached object, if one is cached. Note that we don't actually
+ # remove it, we expire it and write it back out to disk. This way people
+ # can still use the expired object if they want.
+ def expire(key, *args)
+ request = request(:expire, key, *args)
- text += scrub(@doc) + "\n\n" if @doc
+ return nil unless cache?
- if s = terminus_setting
- text += "* **Terminus Setting**: #{terminus_setting}"
- end
+ return nil unless instance = cache.find(request(:find, key, *args))
- text
- end
+ Puppet.info "Expiring the #{self.name} cache of #{instance.name}"
- def initialize(model, name, options = {})
- @model = model
- @name = name
-
- @cache_class = nil
- @terminus_class = nil
-
- raise(ArgumentError, "Indirection #{@name} is already defined") if @@indirections.find { |i| i.name == @name }
- @@indirections << self
-
- if mod = options[:extend]
- extend(mod)
- options.delete(:extend)
- end
-
- # This is currently only used for cache_class and terminus_class.
- options.each do |name, value|
- begin
- send(name.to_s + "=", value)
- rescue NoMethodError
- raise ArgumentError, "#{name} is not a valid Indirection parameter"
- end
- end
- end
+ # Set an expiration date in the past
+ instance.expiration = Time.now - 60
- # Set up our request object.
- def request(*args)
- Puppet::Indirector::Request.new(self.name, *args)
- end
+ cache.save(request(:save, instance, *args))
+ end
- # Return the singleton terminus for this indirection.
- def terminus(terminus_name = nil)
- # Get the name of the terminus.
- raise Puppet::DevError, "No terminus specified for #{self.name}; cannot redirect" unless terminus_name ||= terminus_class
+ # Search for an instance in the appropriate terminus, caching the
+ # results if caching is configured..
+ def find(key, *args)
+ request = request(:find, key, *args)
+ terminus = prepare(request)
- termini[terminus_name] ||= make_terminus(terminus_name)
+ begin
+ if result = find_in_cache(request)
+ return result
+ end
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Cached #{self.name} for #{request.key} failed: #{detail}"
end
- # This can be used to select the terminus class.
- attr_accessor :terminus_setting
-
- # Determine the terminus class.
- def terminus_class
- unless @terminus_class
- if setting = self.terminus_setting
- self.terminus_class = Puppet.settings[setting].to_sym
- else
- raise Puppet::DevError, "No terminus class nor terminus setting was provided for indirection #{self.name}"
- end
- end
- @terminus_class
- end
+ # Otherwise, return the result from the terminus, caching if appropriate.
+ if ! request.ignore_terminus? and result = terminus.find(request)
+ result.expiration ||= self.expiration
+ if cache? and request.use_cache?
+ Puppet.info "Caching #{self.name} for #{request.key}"
+ cache.save request(:save, result, *args)
+ end
- def reset_terminus_class
- @terminus_class = nil
+ return terminus.respond_to?(:filter) ? terminus.filter(result) : result
end
- # Specify the terminus class to use.
- def terminus_class=(klass)
- validate_terminus_class(klass)
- @terminus_class = klass
- end
+ nil
+ end
- # This is used by terminus_class= and cache=.
- def validate_terminus_class(terminus_class)
- raise ArgumentError, "Invalid terminus name #{terminus_class.inspect}" unless terminus_class and terminus_class.to_s != ""
- unless Puppet::Indirector::Terminus.terminus_class(self.name, terminus_class)
- raise ArgumentError, "Could not find terminus #{terminus_class} for indirection #{self.name}"
- end
+ def find_in_cache(request)
+ # See if our instance is in the cache and up to date.
+ return nil unless cache? and ! request.ignore_cache? and cached = cache.find(request)
+ if cached.expired?
+ Puppet.info "Not using expired #{self.name} for #{request.key} from cache; expired at #{cached.expiration}"
+ return nil
end
- # Expire a cached object, if one is cached. Note that we don't actually
- # remove it, we expire it and write it back out to disk. This way people
- # can still use the expired object if they want.
- def expire(key, *args)
- request = request(:expire, key, *args)
-
- return nil unless cache?
-
- return nil unless instance = cache.find(request(:find, key, *args))
+ Puppet.debug "Using cached #{self.name} for #{request.key}"
+ cached
+ end
- Puppet.info "Expiring the #{self.name} cache of #{instance.name}"
+ # Remove something via the terminus.
+ def destroy(key, *args)
+ request = request(:destroy, key, *args)
+ terminus = prepare(request)
- # Set an expiration date in the past
- instance.expiration = Time.now - 60
+ result = terminus.destroy(request)
- cache.save(request(:save, instance, *args))
+ if cache? and cached = cache.find(request(:find, key, *args))
+ # Reuse the existing request, since it's equivalent.
+ cache.destroy(request)
end
- # Search for an instance in the appropriate terminus, caching the
- # results if caching is configured..
- def find(key, *args)
- request = request(:find, key, *args)
- terminus = prepare(request)
-
- begin
- if result = find_in_cache(request)
- return result
- end
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Cached #{self.name} for #{request.key} failed: #{detail}"
- end
-
- # Otherwise, return the result from the terminus, caching if appropriate.
- if ! request.ignore_terminus? and result = terminus.find(request)
- result.expiration ||= self.expiration
- if cache? and request.use_cache?
- Puppet.info "Caching #{self.name} for #{request.key}"
- cache.save request(:save, result, *args)
- end
-
- return terminus.respond_to?(:filter) ? terminus.filter(result) : result
- end
-
- nil
- end
+ result
+ end
- def find_in_cache(request)
- # See if our instance is in the cache and up to date.
- return nil unless cache? and ! request.ignore_cache? and cached = cache.find(request)
- if cached.expired?
- Puppet.info "Not using expired #{self.name} for #{request.key} from cache; expired at #{cached.expiration}"
- return nil
- end
+ # Search for more than one instance. Should always return an array.
+ def search(key, *args)
+ request = request(:search, key, *args)
+ terminus = prepare(request)
- Puppet.debug "Using cached #{self.name} for #{request.key}"
- cached
+ if result = terminus.search(request)
+ raise Puppet::DevError, "Search results from terminus #{terminus.name} are not an array" unless result.is_a?(Array)
+ result.each do |instance|
+ instance.expiration ||= self.expiration
+ end
+ return result
end
+ end
- # Remove something via the terminus.
- def destroy(key, *args)
- request = request(:destroy, key, *args)
- terminus = prepare(request)
-
- result = terminus.destroy(request)
+ # Save the instance in the appropriate terminus. This method is
+ # normally an instance method on the indirected class.
+ def save(key, instance = nil)
+ request = request(:save, key, instance)
+ terminus = prepare(request)
- if cache? and cached = cache.find(request(:find, key, *args))
- # Reuse the existing request, since it's equivalent.
- cache.destroy(request)
- end
+ result = terminus.save(request)
- result
- end
+ # If caching is enabled, save our document there
+ cache.save(request) if cache?
- # Search for more than one instance. Should always return an array.
- def search(key, *args)
- request = request(:search, key, *args)
- terminus = prepare(request)
-
- if result = terminus.search(request)
- raise Puppet::DevError, "Search results from terminus #{terminus.name} are not an array" unless result.is_a?(Array)
- result.each do |instance|
- instance.expiration ||= self.expiration
- end
- return result
- end
- end
+ result
+ end
- # Save the instance in the appropriate terminus. This method is
- # normally an instance method on the indirected class.
- def save(key, instance = nil)
- request = request(:save, key, instance)
- terminus = prepare(request)
+ private
- result = terminus.save(request)
+ # Check authorization if there's a hook available; fail if there is one
+ # and it returns false.
+ def check_authorization(request, terminus)
+ # At this point, we're assuming authorization makes no sense without
+ # client information.
+ return unless request.node
- # If caching is enabled, save our document there
- cache.save(request) if cache?
+ # This is only to authorize via a terminus-specific authorization hook.
+ return unless terminus.respond_to?(:authorized?)
- result
+ unless terminus.authorized?(request)
+ msg = "Not authorized to call #{request.method} on #{request}"
+ msg += " with #{request.options.inspect}" unless request.options.empty?
+ raise ArgumentError, msg
end
-
- private
-
- # Check authorization if there's a hook available; fail if there is one
- # and it returns false.
- def check_authorization(request, terminus)
- # At this point, we're assuming authorization makes no sense without
- # client information.
- return unless request.node
-
- # This is only to authorize via a terminus-specific authorization hook.
- return unless terminus.respond_to?(:authorized?)
-
- unless terminus.authorized?(request)
- msg = "Not authorized to call #{request.method} on #{request}"
- msg += " with #{request.options.inspect}" unless request.options.empty?
- raise ArgumentError, msg
- end
+ end
+
+ # Setup a request, pick the appropriate terminus, check the request's authorization, and return it.
+ def prepare(request)
+ # Pick our terminus.
+ if respond_to?(:select_terminus)
+ unless terminus_name = select_terminus(request)
+ raise ArgumentError, "Could not determine appropriate terminus for #{request}"
+ end
+ else
+ terminus_name = terminus_class
end
- # Setup a request, pick the appropriate terminus, check the request's authorization, and return it.
- def prepare(request)
- # Pick our terminus.
- if respond_to?(:select_terminus)
- unless terminus_name = select_terminus(request)
- raise ArgumentError, "Could not determine appropriate terminus for #{request}"
- end
- else
- terminus_name = terminus_class
- end
-
- dest_terminus = terminus(terminus_name)
- check_authorization(request, dest_terminus)
-
- dest_terminus
- end
+ dest_terminus = terminus(terminus_name)
+ check_authorization(request, dest_terminus)
+
+ dest_terminus
+ end
- # Create a new terminus instance.
- def make_terminus(terminus_class)
- # Load our terminus class.
- unless klass = Puppet::Indirector::Terminus.terminus_class(self.name, terminus_class)
- raise ArgumentError, "Could not find terminus #{terminus_class} for indirection #{self.name}"
- end
- klass.new
+ # Create a new terminus instance.
+ def make_terminus(terminus_class)
+ # Load our terminus class.
+ unless klass = Puppet::Indirector::Terminus.terminus_class(self.name, terminus_class)
+ raise ArgumentError, "Could not find terminus #{terminus_class} for indirection #{self.name}"
end
+ klass.new
+ end
- # Cache our terminus instances indefinitely, but make it easy to clean them up.
- cached_attr(:termini) { Hash.new }
+ # Cache our terminus instances indefinitely, but make it easy to clean them up.
+ cached_attr(:termini) { Hash.new }
end
diff --git a/lib/puppet/indirector/key/ca.rb b/lib/puppet/indirector/key/ca.rb
index 62dd775..056d037 100644
--- a/lib/puppet/indirector/key/ca.rb
+++ b/lib/puppet/indirector/key/ca.rb
@@ -2,11 +2,11 @@ require 'puppet/indirector/ssl_file'
require 'puppet/ssl/key'
class Puppet::SSL::Key::Ca < Puppet::Indirector::SslFile
- desc "Manage the CA's private on disk. This terminus *only* works
- with the CA key, because that's the only key that the CA ever interacts
- with."
+ desc "Manage the CA's private on disk. This terminus *only* works
+ with the CA key, because that's the only key that the CA ever interacts
+ with."
- store_in :privatekeydir
+ store_in :privatekeydir
- store_ca_at :cakey
+ store_ca_at :cakey
end
diff --git a/lib/puppet/indirector/key/file.rb b/lib/puppet/indirector/key/file.rb
index 51b5cfd..1990f1a 100644
--- a/lib/puppet/indirector/key/file.rb
+++ b/lib/puppet/indirector/key/file.rb
@@ -2,41 +2,41 @@ require 'puppet/indirector/ssl_file'
require 'puppet/ssl/key'
class Puppet::SSL::Key::File < Puppet::Indirector::SslFile
- desc "Manage SSL private and public keys on disk."
-
- store_in :privatekeydir
- store_ca_at :cakey
-
- # Where should we store the public key?
- def public_key_path(name)
- if ca?(name)
- Puppet[:capub]
- else
- File.join(Puppet[:publickeydir], name.to_s + ".pem")
- end
+ desc "Manage SSL private and public keys on disk."
+
+ store_in :privatekeydir
+ store_ca_at :cakey
+
+ # Where should we store the public key?
+ def public_key_path(name)
+ if ca?(name)
+ Puppet[:capub]
+ else
+ File.join(Puppet[:publickeydir], name.to_s + ".pem")
end
+ end
- # Remove the public key, in addition to the private key
- def destroy(request)
- super
+ # Remove the public key, in addition to the private key
+ def destroy(request)
+ super
- return unless FileTest.exist?(public_key_path(request.key))
+ return unless FileTest.exist?(public_key_path(request.key))
- begin
- File.unlink(public_key_path(request.key))
- rescue => detail
- raise Puppet::Error, "Could not remove #{request.key} public key: #{detail}"
- end
+ begin
+ File.unlink(public_key_path(request.key))
+ rescue => detail
+ raise Puppet::Error, "Could not remove #{request.key} public key: #{detail}"
end
+ end
- # Save the public key, in addition to the private key.
- def save(request)
- super
+ # Save the public key, in addition to the private key.
+ def save(request)
+ super
- begin
- Puppet.settings.writesub(:publickeydir, public_key_path(request.key)) { |f| f.print request.instance.content.public_key.to_pem }
- rescue => detail
- raise Puppet::Error, "Could not write #{request.key}: #{detail}"
- end
+ begin
+ Puppet.settings.writesub(:publickeydir, public_key_path(request.key)) { |f| f.print request.instance.content.public_key.to_pem }
+ rescue => detail
+ raise Puppet::Error, "Could not write #{request.key}: #{detail}"
end
+ end
end
diff --git a/lib/puppet/indirector/ldap.rb b/lib/puppet/indirector/ldap.rb
index 3ccb21d..8d7cd07 100644
--- a/lib/puppet/indirector/ldap.rb
+++ b/lib/puppet/indirector/ldap.rb
@@ -2,77 +2,77 @@ require 'puppet/indirector/terminus'
require 'puppet/util/ldap/connection'
class Puppet::Indirector::Ldap < Puppet::Indirector::Terminus
- # Perform our ldap search and process the result.
- def find(request)
- ldapsearch(search_filter(request.key)) { |entry| return process(entry) } || nil
- end
+ # Perform our ldap search and process the result.
+ def find(request)
+ ldapsearch(search_filter(request.key)) { |entry| return process(entry) } || nil
+ end
- # Process the found entry. We assume that we don't just want the
- # ldap object.
- def process(entry)
- raise Puppet::DevError, "The 'process' method has not been overridden for the LDAP terminus for #{self.name}"
- end
+ # Process the found entry. We assume that we don't just want the
+ # ldap object.
+ def process(entry)
+ raise Puppet::DevError, "The 'process' method has not been overridden for the LDAP terminus for #{self.name}"
+ end
- # Default to all attributes.
- def search_attributes
- nil
- end
+ # Default to all attributes.
+ def search_attributes
+ nil
+ end
- def search_base
- Puppet[:ldapbase]
- end
+ def search_base
+ Puppet[:ldapbase]
+ end
- # The ldap search filter to use.
- def search_filter(name)
- raise Puppet::DevError, "No search string set for LDAP terminus for #{self.name}"
- end
-
- # Find the ldap node, return the class list and parent node specially,
- # and everything else in a parameter hash.
- def ldapsearch(filter)
- raise ArgumentError.new("You must pass a block to ldapsearch") unless block_given?
+ # The ldap search filter to use.
+ def search_filter(name)
+ raise Puppet::DevError, "No search string set for LDAP terminus for #{self.name}"
+ end
- found = false
- count = 0
+ # Find the ldap node, return the class list and parent node specially,
+ # and everything else in a parameter hash.
+ def ldapsearch(filter)
+ raise ArgumentError.new("You must pass a block to ldapsearch") unless block_given?
- begin
- connection.search(search_base, 2, filter, search_attributes) do |entry|
- found = true
- yield entry
- end
- rescue SystemExit,NoMemoryError
- raise
- rescue Exception => detail
- if count == 0
- # Try reconnecting to ldap if we get an exception and we haven't yet retried.
- count += 1
- @connection = nil
- Puppet.warning "Retrying LDAP connection"
- retry
- else
- error = Puppet::Error.new("LDAP Search failed")
- error.set_backtrace(detail.backtrace)
- raise error
- end
- end
+ found = false
+ count = 0
- found
+ begin
+ connection.search(search_base, 2, filter, search_attributes) do |entry|
+ found = true
+ yield entry
+ end
+ rescue SystemExit,NoMemoryError
+ raise
+ rescue Exception => detail
+ if count == 0
+ # Try reconnecting to ldap if we get an exception and we haven't yet retried.
+ count += 1
+ @connection = nil
+ Puppet.warning "Retrying LDAP connection"
+ retry
+ else
+ error = Puppet::Error.new("LDAP Search failed")
+ error.set_backtrace(detail.backtrace)
+ raise error
+ end
end
- # Create an ldap connection.
- def connection
- unless @connection
- raise Puppet::Error, "Could not set up LDAP Connection: Missing ruby/ldap libraries" unless Puppet.features.ldap?
- begin
- conn = Puppet::Util::Ldap::Connection.instance
- conn.start
- @connection = conn.connection
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- raise Puppet::Error, "Could not connect to LDAP: #{detail}"
- end
- end
+ found
+ end
- @connection
+ # Create an ldap connection.
+ def connection
+ unless @connection
+ raise Puppet::Error, "Could not set up LDAP Connection: Missing ruby/ldap libraries" unless Puppet.features.ldap?
+ begin
+ conn = Puppet::Util::Ldap::Connection.instance
+ conn.start
+ @connection = conn.connection
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ raise Puppet::Error, "Could not connect to LDAP: #{detail}"
+ end
end
+
+ @connection
+ end
end
diff --git a/lib/puppet/indirector/memory.rb b/lib/puppet/indirector/memory.rb
index 332e95b..c44d62d 100644
--- a/lib/puppet/indirector/memory.rb
+++ b/lib/puppet/indirector/memory.rb
@@ -2,20 +2,20 @@ require 'puppet/indirector/terminus'
# Manage a memory-cached list of instances.
class Puppet::Indirector::Memory < Puppet::Indirector::Terminus
- def initialize
- @instances = {}
- end
+ def initialize
+ @instances = {}
+ end
- def destroy(request)
- raise ArgumentError.new("Could not find #{request.key} to destroy") unless @instances.include?(request.key)
- @instances.delete(request.key)
- end
+ def destroy(request)
+ raise ArgumentError.new("Could not find #{request.key} to destroy") unless @instances.include?(request.key)
+ @instances.delete(request.key)
+ end
- def find(request)
- @instances[request.key]
- end
+ def find(request)
+ @instances[request.key]
+ end
- def save(request)
- @instances[request.key] = request.instance
- end
+ def save(request)
+ @instances[request.key] = request.instance
+ end
end
diff --git a/lib/puppet/indirector/node/active_record.rb b/lib/puppet/indirector/node/active_record.rb
index 7b1ef92..08bc7e6 100644
--- a/lib/puppet/indirector/node/active_record.rb
+++ b/lib/puppet/indirector/node/active_record.rb
@@ -3,11 +3,11 @@ require 'puppet/indirector/active_record'
require 'puppet/node'
class Puppet::Node::ActiveRecord < Puppet::Indirector::ActiveRecord
- use_ar_model Puppet::Rails::Host
+ use_ar_model Puppet::Rails::Host
- def find(request)
- node = super
- node.fact_merge
- node
- end
+ def find(request)
+ node = super
+ node.fact_merge
+ node
+ end
end
diff --git a/lib/puppet/indirector/node/exec.rb b/lib/puppet/indirector/node/exec.rb
index a30b755..c3e6909 100644
--- a/lib/puppet/indirector/node/exec.rb
+++ b/lib/puppet/indirector/node/exec.rb
@@ -2,47 +2,47 @@ require 'puppet/node'
require 'puppet/indirector/exec'
class Puppet::Node::Exec < Puppet::Indirector::Exec
- desc "Call an external program to get node information. See
- the `ExternalNodes`:trac: page for more information."
- include Puppet::Util
-
- def command
- command = Puppet[:external_nodes]
- raise ArgumentError, "You must set the 'external_nodes' parameter to use the external node terminus" unless command != "none"
- command.split
+ desc "Call an external program to get node information. See
+ the `ExternalNodes`:trac: page for more information."
+ include Puppet::Util
+
+ def command
+ command = Puppet[:external_nodes]
+ raise ArgumentError, "You must set the 'external_nodes' parameter to use the external node terminus" unless command != "none"
+ command.split
+ end
+
+ # Look for external node definitions.
+ def find(request)
+ output = super or return nil
+
+ # Translate the output to ruby.
+ result = translate(request.key, output)
+
+ create_node(request.key, result)
+ end
+
+ private
+
+ # Turn our outputted objects into a Puppet::Node instance.
+ def create_node(name, result)
+ node = Puppet::Node.new(name)
+ set = false
+ [:parameters, :classes, :environment].each do |param|
+ if value = result[param]
+ node.send(param.to_s + "=", value)
+ set = true
+ end
end
- # Look for external node definitions.
- def find(request)
- output = super or return nil
+ node.fact_merge
+ node
+ end
- # Translate the output to ruby.
- result = translate(request.key, output)
-
- create_node(request.key, result)
- end
-
- private
-
- # Turn our outputted objects into a Puppet::Node instance.
- def create_node(name, result)
- node = Puppet::Node.new(name)
- set = false
- [:parameters, :classes, :environment].each do |param|
- if value = result[param]
- node.send(param.to_s + "=", value)
- set = true
- end
- end
-
- node.fact_merge
- node
- end
-
- # Translate the yaml string into Ruby objects.
- def translate(name, output)
- YAML.load(output).inject({}) { |hash, data| hash[symbolize(data[0])] = data[1]; hash }
- rescue => detail
- raise Puppet::Error, "Could not load external node results for #{name}: #{detail}"
- end
+ # Translate the yaml string into Ruby objects.
+ def translate(name, output)
+ YAML.load(output).inject({}) { |hash, data| hash[symbolize(data[0])] = data[1]; hash }
+ rescue => detail
+ raise Puppet::Error, "Could not load external node results for #{name}: #{detail}"
+ end
end
diff --git a/lib/puppet/indirector/node/ldap.rb b/lib/puppet/indirector/node/ldap.rb
index 9e43262..b9fe355 100644
--- a/lib/puppet/indirector/node/ldap.rb
+++ b/lib/puppet/indirector/node/ldap.rb
@@ -2,299 +2,299 @@ require 'puppet/node'
require 'puppet/indirector/ldap'
class Puppet::Node::Ldap < Puppet::Indirector::Ldap
- desc "Search in LDAP for node configuration information. See
- the `LdapNodes`:trac: page for more information. This will first
- search for whatever the certificate name is, then (if that name
- contains a '.') for the short name, then 'default'."
-
- # The attributes that Puppet class information is stored in.
- def class_attributes
- # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
- x = Puppet[:ldapclassattrs].split(/\s*,\s*/)
+ desc "Search in LDAP for node configuration information. See
+ the `LdapNodes`:trac: page for more information. This will first
+ search for whatever the certificate name is, then (if that name
+ contains a '.') for the short name, then 'default'."
+
+ # The attributes that Puppet class information is stored in.
+ def class_attributes
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = Puppet[:ldapclassattrs].split(/\s*,\s*/)
+ end
+
+ # Separate this out so it's relatively atomic. It's tempting to call
+ # process instead of name2hash() here, but it ends up being
+ # difficult to test because all exceptions get caught by ldapsearch.
+ # LAK:NOTE Unfortunately, the ldap support is too stupid to throw anything
+ # but LDAP::ResultError, even on bad connections, so we are rough handed
+ # with our error handling.
+ def name2hash(name,name_env,node_type)
+ info = nil
+ ldapsearch(search_filter(name)) {
+ |entry| info = entry2hash(entry)
+ if info[:environment]
+ if name_env == info[:environment]
+ return info
+ else
+ info = nil
+ end
+ else
+ info_env = "production"
+ if name_env == info[:environment]
+ return info
+ else
+ info = nil
+ end
+ end
+ }
+ if node_type == 'parent'
+ raise Puppet::Error.new("Could not find node '#{name}' with environment '#{name_env}'")
end
- # Separate this out so it's relatively atomic. It's tempting to call
- # process instead of name2hash() here, but it ends up being
- # difficult to test because all exceptions get caught by ldapsearch.
- # LAK:NOTE Unfortunately, the ldap support is too stupid to throw anything
- # but LDAP::ResultError, even on bad connections, so we are rough handed
- # with our error handling.
- def name2hash(name,name_env,node_type)
- info = nil
- ldapsearch(search_filter(name)) {
- |entry| info = entry2hash(entry)
- if info[:environment]
- if name_env == info[:environment]
- return info
- else
- info = nil
- end
- else
- info_env = "production"
- if name_env == info[:environment]
- return info
- else
- info = nil
- end
- end
- }
- if node_type == 'parent'
- raise Puppet::Error.new("Could not find node '#{name}' with environment '#{name_env}'")
- end
-
- info = name2hash('default',name_env,'parent')
+ info = name2hash('default',name_env,'parent')
+ end
+
+ # Look for our node in ldap.
+ def find(request)
+ names = [request.key]
+ names << request.key.sub(/\..+/, '') if request.key.include?(".") # we assume it's an fqdn
+ names << "default"
+
+ node = nil
+ names.each do |name|
+ facts = Puppet::Node::Facts.find(name)
+ if facts.values["environment"]
+ name_env = facts.values["environment"]
+ else
+ name_env = "production"
+ end
+ info = name2hash(name,name_env,'child')
+ next if info == nil
+
+ if info
+ break if node = info2node(request.key, info)
+ end
end
- # Look for our node in ldap.
- def find(request)
- names = [request.key]
- names << request.key.sub(/\..+/, '') if request.key.include?(".") # we assume it's an fqdn
- names << "default"
-
- node = nil
- names.each do |name|
- facts = Puppet::Node::Facts.find(name)
- if facts.values["environment"]
- name_env = facts.values["environment"]
- else
- name_env = "production"
- end
- info = name2hash(name,name_env,'child')
- next if info == nil
-
- if info
- break if node = info2node(request.key, info)
- end
- end
-
- node
+ node
+ end
+
+ # Find more than one node. LAK:NOTE This is a bit of a clumsy API, because the 'search'
+ # method currently *requires* a key. It seems appropriate in some cases but not others,
+ # and I don't really know how to get rid of it as a requirement but allow it when desired.
+ def search(request)
+ if classes = request.options[:class]
+ classes = [classes] unless classes.is_a?(Array)
+ filter = "(&(objectclass=puppetClient)(puppetclass=" + classes.join(")(puppetclass=") + "))"
+ else
+ filter = "(objectclass=puppetClient)"
end
- # Find more than one node. LAK:NOTE This is a bit of a clumsy API, because the 'search'
- # method currently *requires* a key. It seems appropriate in some cases but not others,
- # and I don't really know how to get rid of it as a requirement but allow it when desired.
- def search(request)
- if classes = request.options[:class]
- classes = [classes] unless classes.is_a?(Array)
- filter = "(&(objectclass=puppetClient)(puppetclass=" + classes.join(")(puppetclass=") + "))"
- else
- filter = "(objectclass=puppetClient)"
- end
+ infos = []
+ ldapsearch(filter) { |entry| infos << entry2hash(entry, request.options[:fqdn]) }
- infos = []
- ldapsearch(filter) { |entry| infos << entry2hash(entry, request.options[:fqdn]) }
-
- return infos.collect do |info|
- info2node(info[:name], info)
- end
+ return infos.collect do |info|
+ info2node(info[:name], info)
end
-
- # The parent attribute, if we have one.
- def parent_attribute
- if pattr = Puppet[:ldapparentattr] and ! pattr.empty?
- pattr
- else
- nil
- end
+ end
+
+ # The parent attribute, if we have one.
+ def parent_attribute
+ if pattr = Puppet[:ldapparentattr] and ! pattr.empty?
+ pattr
+ else
+ nil
end
-
- # The attributes that Puppet will stack as array over the full
- # hierarchy.
- def stacked_attributes(dummy_argument=:work_arround_for_ruby_GC_bug)
- Puppet[:ldapstackedattrs].split(/\s*,\s*/)
+ end
+
+ # The attributes that Puppet will stack as array over the full
+ # hierarchy.
+ def stacked_attributes(dummy_argument=:work_arround_for_ruby_GC_bug)
+ Puppet[:ldapstackedattrs].split(/\s*,\s*/)
+ end
+
+ # Convert the found entry into a simple hash.
+ def entry2hash(entry, fqdn = false)
+ result = {}
+
+ cn = entry.dn[ /cn\s*=\s*([^,\s]+)/i,1]
+ dcs = entry.dn.scan(/dc\s*=\s*([^,\s]+)/i)
+ result[:name] = fqdn ? ([cn]+dcs).join('.') : cn
+ result[:parent] = get_parent_from_entry(entry) if parent_attribute
+ result[:classes] = get_classes_from_entry(entry)
+ result[:stacked] = get_stacked_values_from_entry(entry)
+ result[:parameters] = get_parameters_from_entry(entry)
+
+ result[:environment] = result[:parameters]["environment"] if result[:parameters]["environment"]
+
+ result[:stacked_parameters] = {}
+
+ if result[:stacked]
+ result[:stacked].each do |value|
+ param = value.split('=', 2)
+ result[:stacked_parameters][param[0]] = param[1]
+ end
end
- # Convert the found entry into a simple hash.
- def entry2hash(entry, fqdn = false)
- result = {}
-
- cn = entry.dn[ /cn\s*=\s*([^,\s]+)/i,1]
- dcs = entry.dn.scan(/dc\s*=\s*([^,\s]+)/i)
- result[:name] = fqdn ? ([cn]+dcs).join('.') : cn
- result[:parent] = get_parent_from_entry(entry) if parent_attribute
- result[:classes] = get_classes_from_entry(entry)
- result[:stacked] = get_stacked_values_from_entry(entry)
- result[:parameters] = get_parameters_from_entry(entry)
+ if result[:stacked_parameters]
+ result[:stacked_parameters].each do |param, value|
+ result[:parameters][param] = value unless result[:parameters].include?(param)
+ end
+ end
- result[:environment] = result[:parameters]["environment"] if result[:parameters]["environment"]
+ result[:parameters] = convert_parameters(result[:parameters])
- result[:stacked_parameters] = {}
+ result
+ end
- if result[:stacked]
- result[:stacked].each do |value|
- param = value.split('=', 2)
- result[:stacked_parameters][param[0]] = param[1]
- end
- end
+ # Default to all attributes.
+ def search_attributes
+ ldapattrs = Puppet[:ldapattrs]
- if result[:stacked_parameters]
- result[:stacked_parameters].each do |param, value|
- result[:parameters][param] = value unless result[:parameters].include?(param)
- end
- end
+ # results in everything getting returned
+ return nil if ldapattrs == "all"
- result[:parameters] = convert_parameters(result[:parameters])
+ search_attrs = class_attributes + ldapattrs.split(/\s*,\s*/)
- result
+ if pattr = parent_attribute
+ search_attrs << pattr
end
- # Default to all attributes.
- def search_attributes
- ldapattrs = Puppet[:ldapattrs]
-
- # results in everything getting returned
- return nil if ldapattrs == "all"
+ search_attrs
+ end
- search_attrs = class_attributes + ldapattrs.split(/\s*,\s*/)
+ # The ldap search filter to use.
+ def search_filter(name)
+ filter = Puppet[:ldapstring]
- if pattr = parent_attribute
- search_attrs << pattr
- end
-
- search_attrs
+ if filter.include? "%s"
+ # Don't replace the string in-line, since that would hard-code our node
+ # info.
+ filter = filter.gsub('%s', name)
end
-
- # The ldap search filter to use.
- def search_filter(name)
- filter = Puppet[:ldapstring]
-
- if filter.include? "%s"
- # Don't replace the string in-line, since that would hard-code our node
- # info.
- filter = filter.gsub('%s', name)
- end
- filter
+ filter
+ end
+
+ private
+
+ # Add our hash of ldap information to the node instance.
+ def add_to_node(node, information)
+ node.classes = information[:classes].uniq unless information[:classes].nil? or information[:classes].empty?
+ node.parameters = information[:parameters] unless information[:parameters].nil? or information[:parameters].empty?
+ node.environment = information[:environment] if information[:environment]
+ end
+
+ def convert_parameters(parameters)
+ result = {}
+ parameters.each do |param, value|
+ if value.is_a?(Array)
+ result[param] = value.collect { |v| convert(v) }
+ else
+ result[param] = convert(value)
+ end
end
+ result
+ end
+
+ # Convert any values if necessary.
+ def convert(value)
+ case value
+ when Integer, Fixnum, Bignum; value
+ when "true"; true
+ when "false"; false
+ else
+ value
+ end
+ end
- private
+ # Find information for our parent and merge it into the current info.
+ def find_and_merge_parent(parent, information)
- # Add our hash of ldap information to the node instance.
- def add_to_node(node, information)
- node.classes = information[:classes].uniq unless information[:classes].nil? or information[:classes].empty?
- node.parameters = information[:parameters] unless information[:parameters].nil? or information[:parameters].empty?
- node.environment = information[:environment] if information[:environment]
+ if information[:environment]
+ name_env = information[:environment]
+ else
+ name_env = 'production'
end
- def convert_parameters(parameters)
- result = {}
- parameters.each do |param, value|
- if value.is_a?(Array)
- result[param] = value.collect { |v| convert(v) }
- else
- result[param] = convert(value)
- end
- end
- result
+ parent_info = name2hash(parent,name_env,'parent')
+ if parent_info
+ information[:classes] += parent_info[:classes]
+ parent_info[:parameters].each do |param, value|
+ # Specifically test for whether it's set, so false values are handled
+ # correctly.
+ information[:parameters][param] = value unless information[:parameters].include?(param)
end
- # Convert any values if necessary.
- def convert(value)
- case value
- when Integer, Fixnum, Bignum; value
- when "true"; true
- when "false"; false
- else
- value
- end
+ information[:environment] ||= parent_info[:environment]
+ parent_info[:parent]
+ else
+ raise Puppet::Error.new("Could not find parent node '#{parent}'")
+ nil
end
- # Find information for our parent and merge it into the current info.
- def find_and_merge_parent(parent, information)
+ end
- if information[:environment]
- name_env = information[:environment]
- else
- name_env = 'production'
- end
-
- parent_info = name2hash(parent,name_env,'parent')
- if parent_info
- information[:classes] += parent_info[:classes]
- parent_info[:parameters].each do |param, value|
- # Specifically test for whether it's set, so false values are handled
- # correctly.
- information[:parameters][param] = value unless information[:parameters].include?(param)
- end
-
- information[:environment] ||= parent_info[:environment]
- parent_info[:parent]
- else
- raise Puppet::Error.new("Could not find parent node '#{parent}'")
- nil
- end
+ # Take a name and a hash, and return a node instance.
+ def info2node(name, info)
+ merge_parent(info) if info[:parent]
- end
+ node = Puppet::Node.new(name)
- # Take a name and a hash, and return a node instance.
- def info2node(name, info)
- merge_parent(info) if info[:parent]
+ add_to_node(node, info)
- node = Puppet::Node.new(name)
+ node.fact_merge
- add_to_node(node, info)
+ node
+ end
- node.fact_merge
+ def merge_parent(info)
+ parent_info = nil
+ parent = info[:parent]
- node
+ # Preload the parent array with the node name.
+ parents = [info[:name]]
+ while parent
+ raise ArgumentError, "Found loop in LDAP node parents; #{parent} appears twice" if parents.include?(parent)
+ parents << parent
+ parent = find_and_merge_parent(parent, info)
end
- def merge_parent(info)
- parent_info = nil
- parent = info[:parent]
-
- # Preload the parent array with the node name.
- parents = [info[:name]]
- while parent
- raise ArgumentError, "Found loop in LDAP node parents; #{parent} appears twice" if parents.include?(parent)
- parents << parent
- parent = find_and_merge_parent(parent, info)
- end
-
- info
- end
+ info
+ end
- def get_classes_from_entry(entry)
- result = class_attributes.inject([]) do |array, attr|
- if values = entry.vals(attr)
- values.each do |v| array << v end
- end
- array
- end
- result.uniq
+ def get_classes_from_entry(entry)
+ result = class_attributes.inject([]) do |array, attr|
+ if values = entry.vals(attr)
+ values.each do |v| array << v end
+ end
+ array
end
-
- def get_parameters_from_entry(entry)
- stacked_params = stacked_attributes
- entry.to_hash.inject({}) do |hash, ary|
- unless stacked_params.include?(ary[0]) # don't add our stacked parameters to the main param list
- if ary[1].length == 1
- hash[ary[0]] = ary[1].shift
- else
- hash[ary[0]] = ary[1]
- end
- end
- hash
+ result.uniq
+ end
+
+ def get_parameters_from_entry(entry)
+ stacked_params = stacked_attributes
+ entry.to_hash.inject({}) do |hash, ary|
+ unless stacked_params.include?(ary[0]) # don't add our stacked parameters to the main param list
+ if ary[1].length == 1
+ hash[ary[0]] = ary[1].shift
+ else
+ hash[ary[0]] = ary[1]
end
+ end
+ hash
end
+ end
- def get_parent_from_entry(entry)
- pattr = parent_attribute
+ def get_parent_from_entry(entry)
+ pattr = parent_attribute
- return nil unless values = entry.vals(pattr)
+ return nil unless values = entry.vals(pattr)
- if values.length > 1
- raise Puppet::Error,
- "Node entry #{entry.dn} specifies more than one parent: #{values.inspect}"
- end
- return(values.empty? ? nil : values.shift)
+ if values.length > 1
+ raise Puppet::Error,
+ "Node entry #{entry.dn} specifies more than one parent: #{values.inspect}"
end
-
- def get_stacked_values_from_entry(entry)
- stacked_attributes.inject([]) do |result, attr|
- if values = entry.vals(attr)
- result += values
- end
- result
- end
+ return(values.empty? ? nil : values.shift)
+ end
+
+ def get_stacked_values_from_entry(entry)
+ stacked_attributes.inject([]) do |result, attr|
+ if values = entry.vals(attr)
+ result += values
+ end
+ result
end
+ end
end
diff --git a/lib/puppet/indirector/node/memory.rb b/lib/puppet/indirector/node/memory.rb
index de0ed8a..ce4a52a 100644
--- a/lib/puppet/indirector/node/memory.rb
+++ b/lib/puppet/indirector/node/memory.rb
@@ -2,9 +2,9 @@ require 'puppet/node'
require 'puppet/indirector/memory'
class Puppet::Node::Memory < Puppet::Indirector::Memory
- desc "Keep track of nodes in memory but nowhere else. This is used for
- one-time compiles, such as what the stand-alone ``puppet`` does.
- To use this terminus, you must load it with the data you want it
- to contain; it is only useful for developers and should generally not
- be chosen by a normal user."
+ desc "Keep track of nodes in memory but nowhere else. This is used for
+ one-time compiles, such as what the stand-alone ``puppet`` does.
+ To use this terminus, you must load it with the data you want it
+ to contain; it is only useful for developers and should generally not
+ be chosen by a normal user."
end
diff --git a/lib/puppet/indirector/node/plain.rb b/lib/puppet/indirector/node/plain.rb
index 37ceb06..d648cce 100644
--- a/lib/puppet/indirector/node/plain.rb
+++ b/lib/puppet/indirector/node/plain.rb
@@ -2,18 +2,18 @@ require 'puppet/node'
require 'puppet/indirector/plain'
class Puppet::Node::Plain < Puppet::Indirector::Plain
- desc "Always return an empty node object. Assumes you keep track of nodes
- in flat file manifests. You should use it when you don't have some other,
- functional source you want to use, as the compiler will not work without a
- valid node terminus.
+ desc "Always return an empty node object. Assumes you keep track of nodes
+ in flat file manifests. You should use it when you don't have some other,
+ functional source you want to use, as the compiler will not work without a
+ valid node terminus.
- Note that class is responsible for merging the node's facts into the
- node instance before it is returned."
+ Note that class is responsible for merging the node's facts into the
+ node instance before it is returned."
- # Just return an empty node.
- def find(request)
- node = super
- node.fact_merge
- node
- end
+ # Just return an empty node.
+ def find(request)
+ node = super
+ node.fact_merge
+ node
+ end
end
diff --git a/lib/puppet/indirector/node/rest.rb b/lib/puppet/indirector/node/rest.rb
index d8b75f6..6aa8025 100644
--- a/lib/puppet/indirector/node/rest.rb
+++ b/lib/puppet/indirector/node/rest.rb
@@ -2,6 +2,6 @@ require 'puppet/node'
require 'puppet/indirector/rest'
class Puppet::Node::Rest < Puppet::Indirector::REST
- desc "This will eventually be a REST-based mechanism for finding nodes. It is currently non-functional."
- # TODO/FIXME
+ desc "This will eventually be a REST-based mechanism for finding nodes. It is currently non-functional."
+ # TODO/FIXME
end
diff --git a/lib/puppet/indirector/node/yaml.rb b/lib/puppet/indirector/node/yaml.rb
index f287347..5a316b6 100644
--- a/lib/puppet/indirector/node/yaml.rb
+++ b/lib/puppet/indirector/node/yaml.rb
@@ -2,6 +2,6 @@ require 'puppet/node'
require 'puppet/indirector/yaml'
class Puppet::Node::Yaml < Puppet::Indirector::Yaml
- desc "Store node information as flat files, serialized using YAML,
- or deserialize stored YAML nodes."
+ desc "Store node information as flat files, serialized using YAML,
+ or deserialize stored YAML nodes."
end
diff --git a/lib/puppet/indirector/plain.rb b/lib/puppet/indirector/plain.rb
index 2caa094..e11fc68 100644
--- a/lib/puppet/indirector/plain.rb
+++ b/lib/puppet/indirector/plain.rb
@@ -2,8 +2,8 @@ require 'puppet/indirector/terminus'
# An empty terminus type, meant to just return empty objects.
class Puppet::Indirector::Plain < Puppet::Indirector::Terminus
- # Just return nothing.
- def find(request)
- indirection.model.new(request.key)
- end
+ # Just return nothing.
+ def find(request)
+ indirection.model.new(request.key)
+ end
end
diff --git a/lib/puppet/indirector/queue.rb b/lib/puppet/indirector/queue.rb
index b831cd6..fd089f4 100644
--- a/lib/puppet/indirector/queue.rb
+++ b/lib/puppet/indirector/queue.rb
@@ -19,63 +19,63 @@ require 'puppet/util'
# client library to handle queue creation as necessary (for a number of popular queuing solutions, queue
# creation is automatic and not a concern).
class Puppet::Indirector::Queue < Puppet::Indirector::Terminus
- extend ::Puppet::Util::Queue
- include Puppet::Util
+ extend ::Puppet::Util::Queue
+ include Puppet::Util
- def initialize(*args)
- super
- raise ArgumentError, "Queueing requires pson support" unless Puppet.features.pson?
- end
+ def initialize(*args)
+ super
+ raise ArgumentError, "Queueing requires pson support" unless Puppet.features.pson?
+ end
- # Queue has no idiomatic "find"
- def find(request)
- nil
- end
+ # Queue has no idiomatic "find"
+ def find(request)
+ nil
+ end
- # Place the request on the queue
- def save(request)
- result = nil
- benchmark :info, "Queued #{indirection.name} for #{request.key}" do
- result = client.send_message(queue, request.instance.render(:pson))
- end
- result
- rescue => detail
- raise Puppet::Error, "Could not write #{request.key} to queue: #{detail}\nInstance::#{request.instance}\n client : #{client}"
- end
+ # Place the request on the queue
+ def save(request)
+ result = nil
+ benchmark :info, "Queued #{indirection.name} for #{request.key}" do
+ result = client.send_message(queue, request.instance.render(:pson))
+ end
+ result
+ rescue => detail
+ raise Puppet::Error, "Could not write #{request.key} to queue: #{detail}\nInstance::#{request.instance}\n client : #{client}"
+ end
- def self.queue
- indirection_name
- end
+ def self.queue
+ indirection_name
+ end
- def queue
- self.class.queue
- end
+ def queue
+ self.class.queue
+ end
- # Returns the singleton queue client object.
- def client
- self.class.client
- end
+ # Returns the singleton queue client object.
+ def client
+ self.class.client
+ end
- # converts the _message_ from deserialized format to an actual model instance.
- def self.intern(message)
- result = nil
- benchmark :info, "Loaded queued #{indirection.name}" do
- result = model.convert_from(:pson, message)
- end
- result
+ # converts the _message_ from deserialized format to an actual model instance.
+ def self.intern(message)
+ result = nil
+ benchmark :info, "Loaded queued #{indirection.name}" do
+ result = model.convert_from(:pson, message)
end
+ result
+ end
- # Provides queue subscription functionality; for a given indirection, use this method on the terminus
- # to subscribe to the indirection-specific queue. Your _block_ will be executed per new indirection
- # model received from the queue, with _obj_ being the model instance.
- def self.subscribe
- client.subscribe(queue) do |msg|
- begin
- yield(self.intern(msg))
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Error occured with subscription to queue #{queue} for indirection #{indirection_name}: #{detail}"
- end
- end
+ # Provides queue subscription functionality; for a given indirection, use this method on the terminus
+ # to subscribe to the indirection-specific queue. Your _block_ will be executed per new indirection
+ # model received from the queue, with _obj_ being the model instance.
+ def self.subscribe
+ client.subscribe(queue) do |msg|
+ begin
+ yield(self.intern(msg))
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Error occured with subscription to queue #{queue} for indirection #{indirection_name}: #{detail}"
+ end
end
+ end
end
diff --git a/lib/puppet/indirector/report/processor.rb b/lib/puppet/indirector/report/processor.rb
index 2f8e9f3..88fe4b4 100644
--- a/lib/puppet/indirector/report/processor.rb
+++ b/lib/puppet/indirector/report/processor.rb
@@ -3,46 +3,46 @@ require 'puppet/indirector/code'
require 'puppet/reports'
class Puppet::Transaction::Report::Processor < Puppet::Indirector::Code
- desc "Puppet's report processor. Processes the report with each of
- the report types listed in the 'reports' setting."
+ desc "Puppet's report processor. Processes the report with each of
+ the report types listed in the 'reports' setting."
- def initialize
- Puppet.settings.use(:main, :reporting, :metrics)
- end
+ def initialize
+ Puppet.settings.use(:main, :reporting, :metrics)
+ end
- def save(request)
- process(request.instance)
- end
+ def save(request)
+ process(request.instance)
+ end
- private
+ private
- # Process the report with each of the configured report types.
- # LAK:NOTE This isn't necessarily the best design, but it's backward
- # compatible and that's good enough for now.
- def process(report)
- return if Puppet[:reports] == "none"
+ # Process the report with each of the configured report types.
+ # LAK:NOTE This isn't necessarily the best design, but it's backward
+ # compatible and that's good enough for now.
+ def process(report)
+ return if Puppet[:reports] == "none"
- reports.each do |name|
- if mod = Puppet::Reports.report(name)
- # We have to use a dup because we're including a module in the
- # report.
- newrep = report.dup
- begin
- newrep.extend(mod)
- newrep.process
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Report #{name} failed: #{detail}"
- end
- else
- Puppet.warning "No report named '#{name}'"
- end
+ reports.each do |name|
+ if mod = Puppet::Reports.report(name)
+ # We have to use a dup because we're including a module in the
+ # report.
+ newrep = report.dup
+ begin
+ newrep.extend(mod)
+ newrep.process
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Report #{name} failed: #{detail}"
end
+ else
+ Puppet.warning "No report named '#{name}'"
+ end
end
+ end
- # Handle the parsing of the reports attribute.
- def reports
- # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
- x = Puppet[:reports].gsub(/(^\s+)|(\s+$)/, '').split(/\s*,\s*/)
- end
+ # Handle the parsing of the reports attribute.
+ def reports
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = Puppet[:reports].gsub(/(^\s+)|(\s+$)/, '').split(/\s*,\s*/)
+ end
end
diff --git a/lib/puppet/indirector/report/rest.rb b/lib/puppet/indirector/report/rest.rb
index f92d1ed..601da9e 100644
--- a/lib/puppet/indirector/report/rest.rb
+++ b/lib/puppet/indirector/report/rest.rb
@@ -1,7 +1,7 @@
require 'puppet/indirector/rest'
class Puppet::Transaction::Report::Rest < Puppet::Indirector::REST
- desc "Get server report over HTTP via REST."
- use_server_setting(:report_server)
- use_port_setting(:report_port)
+ desc "Get server report over HTTP via REST."
+ use_server_setting(:report_server)
+ use_port_setting(:report_port)
end
diff --git a/lib/puppet/indirector/request.rb b/lib/puppet/indirector/request.rb
index 759b442..fd8d654 100644
--- a/lib/puppet/indirector/request.rb
+++ b/lib/puppet/indirector/request.rb
@@ -6,194 +6,194 @@ require 'puppet/indirector'
# Indirection call, and as a a result also handles REST calls. It's somewhat
# analogous to an HTTP Request object, except tuned for our Indirector.
class Puppet::Indirector::Request
- attr_accessor :key, :method, :options, :instance, :node, :ip, :authenticated, :ignore_cache, :ignore_terminus
+ attr_accessor :key, :method, :options, :instance, :node, :ip, :authenticated, :ignore_cache, :ignore_terminus
- attr_accessor :server, :port, :uri, :protocol
+ attr_accessor :server, :port, :uri, :protocol
- attr_reader :indirection_name
+ attr_reader :indirection_name
- OPTION_ATTRIBUTES = [:ip, :node, :authenticated, :ignore_terminus, :ignore_cache, :instance, :environment]
+ OPTION_ATTRIBUTES = [:ip, :node, :authenticated, :ignore_terminus, :ignore_cache, :instance, :environment]
- # Is this an authenticated request?
- def authenticated?
- # Double negative, so we just get true or false
- ! ! authenticated
- end
-
- def environment
- @environment ||= Puppet::Node::Environment.new
- end
+ # Is this an authenticated request?
+ def authenticated?
+ # Double negative, so we just get true or false
+ ! ! authenticated
+ end
- def environment=(env)
- @environment = if env.is_a?(Puppet::Node::Environment)
- env
- else
- Puppet::Node::Environment.new(env)
- end
- end
+ def environment
+ @environment ||= Puppet::Node::Environment.new
+ end
+
+ def environment=(env)
+ @environment = if env.is_a?(Puppet::Node::Environment)
+ env
+ else
+ Puppet::Node::Environment.new(env)
+ end
+ end
+
+ def escaped_key
+ URI.escape(key)
+ end
+
+ # LAK:NOTE This is a messy interface to the cache, and it's only
+ # used by the Configurer class. I decided it was better to implement
+ # it now and refactor later, when we have a better design, than
+ # to spend another month coming up with a design now that might
+ # not be any better.
+ def ignore_cache?
+ ignore_cache
+ end
+
+ def ignore_terminus?
+ ignore_terminus
+ end
+
+ def initialize(indirection_name, method, key_or_instance, options_or_instance = {})
+ if options_or_instance.is_a? Hash
+ options = options_or_instance
+ @instance = nil
+ else
+ options = {}
+ @instance = options_or_instance
+ end
+
+ self.indirection_name = indirection_name
+ self.method = method
+
+ set_attributes(options)
+
+ @options = options.inject({}) { |hash, ary| hash[ary[0].to_sym] = ary[1]; hash }
+
+ if key_or_instance.is_a?(String) || key_or_instance.is_a?(Symbol)
+ key = key_or_instance
+ else
+ @instance ||= key_or_instance
+ end
+
+ if key
+ # If the request key is a URI, then we need to treat it specially,
+ # because it rewrites the key. We could otherwise strip server/port/etc
+ # info out in the REST class, but it seemed bad design for the REST
+ # class to rewrite the key.
+ if key.to_s =~ /^\w+:\/\// # it's a URI
+ set_uri_key(key)
+ else
+ @key = key
+ end
+ end
+
+ @key = @instance.name if ! @key and @instance
+ end
+
+ # Look up the indirection based on the name provided.
+ def indirection
+ Puppet::Indirector::Indirection.instance(indirection_name)
+ end
- def escaped_key
- URI.escape(key)
- end
+ def indirection_name=(name)
+ @indirection_name = name.to_sym
+ end
- # LAK:NOTE This is a messy interface to the cache, and it's only
- # used by the Configurer class. I decided it was better to implement
- # it now and refactor later, when we have a better design, than
- # to spend another month coming up with a design now that might
- # not be any better.
- def ignore_cache?
- ignore_cache
- end
- def ignore_terminus?
- ignore_terminus
- end
-
- def initialize(indirection_name, method, key_or_instance, options_or_instance = {})
- if options_or_instance.is_a? Hash
- options = options_or_instance
- @instance = nil
- else
- options = {}
- @instance = options_or_instance
- end
-
- self.indirection_name = indirection_name
- self.method = method
-
- set_attributes(options)
-
- @options = options.inject({}) { |hash, ary| hash[ary[0].to_sym] = ary[1]; hash }
-
- if key_or_instance.is_a?(String) || key_or_instance.is_a?(Symbol)
- key = key_or_instance
- else
- @instance ||= key_or_instance
- end
-
- if key
- # If the request key is a URI, then we need to treat it specially,
- # because it rewrites the key. We could otherwise strip server/port/etc
- # info out in the REST class, but it seemed bad design for the REST
- # class to rewrite the key.
- if key.to_s =~ /^\w+:\/\// # it's a URI
- set_uri_key(key)
- else
- @key = key
- end
- end
-
- @key = @instance.name if ! @key and @instance
- end
-
- # Look up the indirection based on the name provided.
- def indirection
- Puppet::Indirector::Indirection.instance(indirection_name)
- end
+ def model
+ raise ArgumentError, "Could not find indirection '#{indirection_name}'" unless i = indirection
+ i.model
+ end
- def indirection_name=(name)
- @indirection_name = name.to_sym
+ # Should we allow use of the cached object?
+ def use_cache?
+ if defined?(@use_cache)
+ ! ! use_cache
+ else
+ true
end
+ end
+ # Are we trying to interact with multiple resources, or just one?
+ def plural?
+ method == :search
+ end
+
+ # Create the query string, if options are present.
+ def query_string
+ return "" unless options and ! options.empty?
+ "?" + options.collect do |key, value|
+ case value
+ when nil; next
+ when true, false; value = value.to_s
+ when Fixnum, Bignum, Float; value = value # nothing
+ when String; value = CGI.escape(value)
+ when Symbol; value = CGI.escape(value.to_s)
+ when Array; value = CGI.escape(YAML.dump(value))
+ else
+ raise ArgumentError, "HTTP REST queries cannot handle values of type '#{value.class}'"
+ end
- def model
- raise ArgumentError, "Could not find indirection '#{indirection_name}'" unless i = indirection
- i.model
+ "#{key}=#{value}"
+ end.join("&")
+ end
+
+ def to_hash
+ result = options.dup
+
+ OPTION_ATTRIBUTES.each do |attribute|
+ if value = send(attribute)
+ result[attribute] = value
+ end
end
+ result
+ end
- # Should we allow use of the cached object?
- def use_cache?
- if defined?(@use_cache)
- ! ! use_cache
- else
- true
- end
- end
-
- # Are we trying to interact with multiple resources, or just one?
- def plural?
- method == :search
- end
-
- # Create the query string, if options are present.
- def query_string
- return "" unless options and ! options.empty?
- "?" + options.collect do |key, value|
- case value
- when nil; next
- when true, false; value = value.to_s
- when Fixnum, Bignum, Float; value = value # nothing
- when String; value = CGI.escape(value)
- when Symbol; value = CGI.escape(value.to_s)
- when Array; value = CGI.escape(YAML.dump(value))
- else
- raise ArgumentError, "HTTP REST queries cannot handle values of type '#{value.class}'"
- end
-
- "#{key}=#{value}"
- end.join("&")
- end
-
- def to_hash
- result = options.dup
-
- OPTION_ATTRIBUTES.each do |attribute|
- if value = send(attribute)
- result[attribute] = value
- end
- end
- result
- end
-
- def to_s
- return(uri ? uri : "/#{indirection_name}/#{key}")
- end
+ def to_s
+ return(uri ? uri : "/#{indirection_name}/#{key}")
+ end
- private
+ private
- def set_attributes(options)
- OPTION_ATTRIBUTES.each do |attribute|
- if options.include?(attribute)
- send(attribute.to_s + "=", options[attribute])
- options.delete(attribute)
- end
- end
+ def set_attributes(options)
+ OPTION_ATTRIBUTES.each do |attribute|
+ if options.include?(attribute)
+ send(attribute.to_s + "=", options[attribute])
+ options.delete(attribute)
+ end
end
+ end
- # Parse the key as a URI, setting attributes appropriately.
- def set_uri_key(key)
- @uri = key
- begin
- uri = URI.parse(URI.escape(key))
- rescue => detail
- raise ArgumentError, "Could not understand URL #{key}: #{detail}"
- end
-
- # Just short-circuit these to full paths
- if uri.scheme == "file"
- @key = URI.unescape(uri.path)
- return
- end
-
- @server = uri.host if uri.host
-
- # If the URI class can look up the scheme, it will provide a port,
- # otherwise it will default to '0'.
- if uri.port.to_i == 0 and uri.scheme == "puppet"
- @port = Puppet.settings[:masterport].to_i
- else
- @port = uri.port.to_i
- end
-
- @protocol = uri.scheme
-
- if uri.scheme == 'puppet'
- @key = URI.unescape(uri.path.sub(/^\//, ''))
- return
- end
-
- env, indirector, @key = URI.unescape(uri.path.sub(/^\//, '')).split('/',3)
- @key ||= ''
- self.environment = env unless env == ''
+ # Parse the key as a URI, setting attributes appropriately.
+ def set_uri_key(key)
+ @uri = key
+ begin
+ uri = URI.parse(URI.escape(key))
+ rescue => detail
+ raise ArgumentError, "Could not understand URL #{key}: #{detail}"
+ end
+
+ # Just short-circuit these to full paths
+ if uri.scheme == "file"
+ @key = URI.unescape(uri.path)
+ return
+ end
+
+ @server = uri.host if uri.host
+
+ # If the URI class can look up the scheme, it will provide a port,
+ # otherwise it will default to '0'.
+ if uri.port.to_i == 0 and uri.scheme == "puppet"
+ @port = Puppet.settings[:masterport].to_i
+ else
+ @port = uri.port.to_i
+ end
+
+ @protocol = uri.scheme
+
+ if uri.scheme == 'puppet'
+ @key = URI.unescape(uri.path.sub(/^\//, ''))
+ return
end
+
+ env, indirector, @key = URI.unescape(uri.path.sub(/^\//, '')).split('/',3)
+ @key ||= ''
+ self.environment = env unless env == ''
+ end
end
diff --git a/lib/puppet/indirector/resource/ral.rb b/lib/puppet/indirector/resource/ral.rb
index 7a97fcc..1c2ab14 100644
--- a/lib/puppet/indirector/resource/ral.rb
+++ b/lib/puppet/indirector/resource/ral.rb
@@ -1,48 +1,48 @@
class Puppet::Resource::Ral < Puppet::Indirector::Code
- def find( request )
- # find by name
- res = type(request).instances.find { |o| o.name == resource_name(request) }
- res ||= type(request).new(:name => resource_name(request), :audit => type(request).properties.collect { |s| s.name })
-
- res.to_resource
+ def find( request )
+ # find by name
+ res = type(request).instances.find { |o| o.name == resource_name(request) }
+ res ||= type(request).new(:name => resource_name(request), :audit => type(request).properties.collect { |s| s.name })
+
+ res.to_resource
+ end
+
+ def search( request )
+ conditions = request.options.dup
+ conditions[:name] = resource_name(request) if resource_name(request)
+
+ type(request).instances.map do |res|
+ res.to_resource
+ end.find_all do |res|
+ conditions.all? {|property, value| res.to_resource[property].to_s == value.to_s}
+ end.sort do |a,b|
+ a.title <=> b.title
end
+ end
- def search( request )
- conditions = request.options.dup
- conditions[:name] = resource_name(request) if resource_name(request)
-
- type(request).instances.map do |res|
- res.to_resource
- end.find_all do |res|
- conditions.all? {|property, value| res.to_resource[property].to_s == value.to_s}
- end.sort do |a,b|
- a.title <=> b.title
- end
- end
+ def save( request )
+ # In RAL-land, to "save" means to actually try to change machine state
+ res = request.instance
+ ral_res = res.to_ral
- def save( request )
- # In RAL-land, to "save" means to actually try to change machine state
- res = request.instance
- ral_res = res.to_ral
+ catalog = Puppet::Resource::Catalog.new
+ catalog.add_resource ral_res
+ catalog.apply
- catalog = Puppet::Resource::Catalog.new
- catalog.add_resource ral_res
- catalog.apply
+ ral_res.to_resource
+ end
- ral_res.to_resource
- end
+ private
- private
+ def type_name( request )
+ request.key.split('/')[0]
+ end
- def type_name( request )
- request.key.split('/')[0]
- end
+ def resource_name( request )
+ request.key.split('/')[1]
+ end
- def resource_name( request )
- request.key.split('/')[1]
- end
-
- def type( request )
- Puppet::Type.type(type_name(request)) or raise Puppet::Error, "Could not find type #{type}"
- end
+ def type( request )
+ Puppet::Type.type(type_name(request)) or raise Puppet::Error, "Could not find type #{type}"
+ end
end
diff --git a/lib/puppet/indirector/resource_type/parser.rb b/lib/puppet/indirector/resource_type/parser.rb
index 81ec1bf..8b1bed0 100644
--- a/lib/puppet/indirector/resource_type/parser.rb
+++ b/lib/puppet/indirector/resource_type/parser.rb
@@ -3,25 +3,25 @@ require 'puppet/indirector/code'
require 'puppet/indirector/resource_type'
class Puppet::Indirector::ResourceType::Parser < Puppet::Indirector::Code
- desc "Return the data-form of a resource type."
+ desc "Return the data-form of a resource type."
- def find(request)
- krt = request.environment.known_resource_types
+ def find(request)
+ krt = request.environment.known_resource_types
- # This is a bit ugly.
- [:hostclass, :definition, :node].each do |type|
- if r = krt.send(type, request.key)
- return r
- end
- end
- nil
+ # This is a bit ugly.
+ [:hostclass, :definition, :node].each do |type|
+ if r = krt.send(type, request.key)
+ return r
+ end
end
+ nil
+ end
- def search(request)
- raise ArgumentError, "Only '*' is acceptable as a search request" unless request.key == "*"
- krt = request.environment.known_resource_types
- result = [krt.hostclasses.values, krt.definitions.values, krt.nodes.values].flatten
- return nil if result.empty?
- result
- end
+ def search(request)
+ raise ArgumentError, "Only '*' is acceptable as a search request" unless request.key == "*"
+ krt = request.environment.known_resource_types
+ result = [krt.hostclasses.values, krt.definitions.values, krt.nodes.values].flatten
+ return nil if result.empty?
+ result
+ end
end
diff --git a/lib/puppet/indirector/resource_type/rest.rb b/lib/puppet/indirector/resource_type/rest.rb
index 66d3320..f372ecc 100644
--- a/lib/puppet/indirector/resource_type/rest.rb
+++ b/lib/puppet/indirector/resource_type/rest.rb
@@ -3,5 +3,5 @@ require 'puppet/indirector/rest'
require 'puppet/indirector/resource_type'
class Puppet::Indirector::ResourceType::Rest < Puppet::Indirector::REST
- desc "Retrieve resource types via a REST HTTP interface."
+ desc "Retrieve resource types via a REST HTTP interface."
end
diff --git a/lib/puppet/indirector/rest.rb b/lib/puppet/indirector/rest.rb
index 127eb71..eb41ff3 100644
--- a/lib/puppet/indirector/rest.rb
+++ b/lib/puppet/indirector/rest.rb
@@ -7,92 +7,92 @@ require 'puppet/network/http/compression'
# Access objects via REST
class Puppet::Indirector::REST < Puppet::Indirector::Terminus
- include Puppet::Network::HTTP::API::V1
- include Puppet::Network::HTTP::Compression.module
-
- class << self
- attr_reader :server_setting, :port_setting
- end
-
- # Specify the setting that we should use to get the server name.
- def self.use_server_setting(setting)
- @server_setting = setting
+ include Puppet::Network::HTTP::API::V1
+ include Puppet::Network::HTTP::Compression.module
+
+ class << self
+ attr_reader :server_setting, :port_setting
+ end
+
+ # Specify the setting that we should use to get the server name.
+ def self.use_server_setting(setting)
+ @server_setting = setting
+ end
+
+ def self.server
+ Puppet.settings[server_setting || :server]
+ end
+
+ # Specify the setting that we should use to get the port.
+ def self.use_port_setting(setting)
+ @port_setting = setting
+ end
+
+ def self.port
+ Puppet.settings[port_setting || :masterport].to_i
+ end
+
+ # Figure out the content type, turn that into a format, and use the format
+ # to extract the body of the response.
+ def deserialize(response, multiple = false)
+ case response.code
+ when "404"
+ return nil
+ when /^2/
+ raise "No content type in http response; cannot parse" unless response['content-type']
+
+ content_type = response['content-type'].gsub(/\s*;.*$/,'') # strip any appended charset
+
+ body = uncompress_body(response)
+
+ # Convert the response to a deserialized object.
+ if multiple
+ model.convert_from_multiple(content_type, body)
+ else
+ model.convert_from(content_type, body)
+ end
+ else
+ # Raise the http error if we didn't get a 'success' of some kind.
+ message = "Error #{response.code} on SERVER: #{(response.body||'').empty? ? response.message : uncompress_body(response)}"
+ raise Net::HTTPError.new(message, response)
end
-
- def self.server
- Puppet.settings[server_setting || :server]
+ end
+
+ # Provide appropriate headers.
+ def headers
+ add_accept_encoding({"Accept" => model.supported_formats.join(", ")})
+ end
+
+ def network(request)
+ Puppet::Network::HttpPool.http_instance(request.server || self.class.server, request.port || self.class.port)
+ end
+
+ def find(request)
+ return nil unless result = deserialize(network(request).get(indirection2uri(request), headers))
+ result.name = request.key if result.respond_to?(:name=)
+ result
+ end
+
+ def search(request)
+ unless result = deserialize(network(request).get(indirection2uri(request), headers), true)
+ return []
end
+ result
+ end
- # Specify the setting that we should use to get the port.
- def self.use_port_setting(setting)
- @port_setting = setting
- end
+ def destroy(request)
+ raise ArgumentError, "DELETE does not accept options" unless request.options.empty?
+ deserialize network(request).delete(indirection2uri(request), headers)
+ end
- def self.port
- Puppet.settings[port_setting || :masterport].to_i
- end
+ def save(request)
+ raise ArgumentError, "PUT does not accept options" unless request.options.empty?
+ deserialize network(request).put(indirection2uri(request), request.instance.render, headers.merge({ "Content-Type" => request.instance.mime }))
+ end
- # Figure out the content type, turn that into a format, and use the format
- # to extract the body of the response.
- def deserialize(response, multiple = false)
- case response.code
- when "404"
- return nil
- when /^2/
- raise "No content type in http response; cannot parse" unless response['content-type']
-
- content_type = response['content-type'].gsub(/\s*;.*$/,'') # strip any appended charset
-
- body = uncompress_body(response)
-
- # Convert the response to a deserialized object.
- if multiple
- model.convert_from_multiple(content_type, body)
- else
- model.convert_from(content_type, body)
- end
- else
- # Raise the http error if we didn't get a 'success' of some kind.
- message = "Error #{response.code} on SERVER: #{(response.body||'').empty? ? response.message : uncompress_body(response)}"
- raise Net::HTTPError.new(message, response)
- end
- end
-
- # Provide appropriate headers.
- def headers
- add_accept_encoding({"Accept" => model.supported_formats.join(", ")})
- end
-
- def network(request)
- Puppet::Network::HttpPool.http_instance(request.server || self.class.server, request.port || self.class.port)
- end
+ private
- def find(request)
- return nil unless result = deserialize(network(request).get(indirection2uri(request), headers))
- result.name = request.key if result.respond_to?(:name=)
- result
- end
-
- def search(request)
- unless result = deserialize(network(request).get(indirection2uri(request), headers), true)
- return []
- end
- result
- end
-
- def destroy(request)
- raise ArgumentError, "DELETE does not accept options" unless request.options.empty?
- deserialize network(request).delete(indirection2uri(request), headers)
- end
-
- def save(request)
- raise ArgumentError, "PUT does not accept options" unless request.options.empty?
- deserialize network(request).put(indirection2uri(request), request.instance.render, headers.merge({ "Content-Type" => request.instance.mime }))
- end
-
- private
-
- def environment
- Puppet::Node::Environment.new
- end
+ def environment
+ Puppet::Node::Environment.new
+ end
end
diff --git a/lib/puppet/indirector/run/local.rb b/lib/puppet/indirector/run/local.rb
index 5e8f349..8cf65d1 100644
--- a/lib/puppet/indirector/run/local.rb
+++ b/lib/puppet/indirector/run/local.rb
@@ -2,7 +2,7 @@ require 'puppet/run'
require 'puppet/indirector/code'
class Puppet::Run::Local < Puppet::Indirector::Code
- def save( request )
- request.instance.run
- end
+ def save( request )
+ request.instance.run
+ end
end
diff --git a/lib/puppet/indirector/run/rest.rb b/lib/puppet/indirector/run/rest.rb
index 7cf6411..cbd3481 100644
--- a/lib/puppet/indirector/run/rest.rb
+++ b/lib/puppet/indirector/run/rest.rb
@@ -2,5 +2,5 @@ require 'puppet/run'
require 'puppet/indirector/rest'
class Puppet::Run::Rest < Puppet::Indirector::REST
- desc "Trigger Agent runs via REST."
+ desc "Trigger Agent runs via REST."
end
diff --git a/lib/puppet/indirector/ssl_file.rb b/lib/puppet/indirector/ssl_file.rb
index 3aeff3a..531180f 100644
--- a/lib/puppet/indirector/ssl_file.rb
+++ b/lib/puppet/indirector/ssl_file.rb
@@ -1,171 +1,171 @@
require 'puppet/ssl'
class Puppet::Indirector::SslFile < Puppet::Indirector::Terminus
- # Specify the directory in which multiple files are stored.
- def self.store_in(setting)
- @directory_setting = setting
- end
-
- # Specify a single file location for storing just one file.
- # This is used for things like the CRL.
- def self.store_at(setting)
- @file_setting = setting
- end
-
- # Specify where a specific ca file should be stored.
- def self.store_ca_at(setting)
- @ca_setting = setting
- end
-
- class << self
- attr_reader :directory_setting, :file_setting, :ca_setting
- end
-
- # The full path to where we should store our files.
- def self.collection_directory
- return nil unless directory_setting
- Puppet.settings[directory_setting]
- end
-
- # The full path to an individual file we would be managing.
- def self.file_location
- return nil unless file_setting
- Puppet.settings[file_setting]
- end
-
- # The full path to a ca file we would be managing.
- def self.ca_location
- return nil unless ca_setting
- Puppet.settings[ca_setting]
- end
-
- # We assume that all files named 'ca' are pointing to individual ca files,
- # rather than normal host files. It's a bit hackish, but all the other
- # solutions seemed even more hackish.
- def ca?(name)
- name == Puppet::SSL::Host.ca_name
- end
-
- def initialize
- Puppet.settings.use(:main, :ssl)
-
- (collection_directory || file_location) or raise Puppet::DevError, "No file or directory setting provided; terminus #{self.class.name} cannot function"
- end
-
- # Use a setting to determine our path.
- def path(name)
- if ca?(name) and ca_location
- ca_location
- elsif collection_directory
- File.join(collection_directory, name.to_s + ".pem")
- else
- file_location
- end
- end
-
- # Remove our file.
- def destroy(request)
- path = path(request.key)
- return false unless FileTest.exist?(path)
-
- Puppet.notice "Removing file #{model} #{request.key} at '#{path}'"
- begin
- File.unlink(path)
- rescue => detail
- raise Puppet::Error, "Could not remove #{request.key}: #{detail}"
- end
- end
-
- # Find the file on disk, returning an instance of the model.
- def find(request)
- path = path(request.key)
-
- return nil unless FileTest.exist?(path) or rename_files_with_uppercase(path)
-
- result = model.new(request.key)
- result.read(path)
- result
- end
-
- # Save our file to disk.
- def save(request)
- path = path(request.key)
- dir = File.dirname(path)
-
- raise Puppet::Error.new("Cannot save #{request.key}; parent directory #{dir} does not exist") unless FileTest.directory?(dir)
- raise Puppet::Error.new("Cannot save #{request.key}; parent directory #{dir} is not writable") unless FileTest.writable?(dir)
-
- write(request.key, path) { |f| f.print request.instance.to_s }
- end
-
- # Search for more than one file. At this point, it just returns
- # an instance for every file in the directory.
- def search(request)
- dir = collection_directory
- Dir.entries(dir).reject { |file| file !~ /\.pem$/ }.collect do |file|
- name = file.sub(/\.pem$/, '')
- result = model.new(name)
- result.read(File.join(dir, file))
- result
- end
- end
-
- private
-
- # Demeterish pointers to class info.
- def collection_directory
- self.class.collection_directory
- end
-
- def file_location
- self.class.file_location
- end
-
- def ca_location
- self.class.ca_location
- end
-
- # A hack method to deal with files that exist with a different case.
- # Just renames it; doesn't read it in or anything.
- # LAK:NOTE This is a copy of the method in sslcertificates/support.rb,
- # which we'll be EOL'ing at some point. This method was added at 20080702
- # and should be removed at some point.
- def rename_files_with_uppercase(file)
- dir, short = File.split(file)
- return nil unless FileTest.exist?(dir)
-
- raise ArgumentError, "Tried to fix SSL files to a file containing uppercase" unless short.downcase == short
- real_file = Dir.entries(dir).reject { |f| f =~ /^\./ }.find do |other|
- other.downcase == short
- end
-
- return nil unless real_file
-
- full_file = File.join(dir, real_file)
-
- Puppet.notice "Fixing case in #{full_file}; renaming to #{file}"
- File.rename(full_file, file)
-
- true
- end
-
- # Yield a filehandle set up appropriately, either with our settings doing
- # the work or opening a filehandle manually.
- def write(name, path)
- if ca?(name) and ca_location
- Puppet.settings.write(self.class.ca_setting) { |f| yield f }
- elsif file_location
- Puppet.settings.write(self.class.file_setting) { |f| yield f }
- elsif setting = self.class.directory_setting
- begin
- Puppet.settings.writesub(setting, path) { |f| yield f }
- rescue => detail
- raise Puppet::Error, "Could not write #{path} to #{setting}: #{detail}"
- end
- else
- raise Puppet::DevError, "You must provide a setting to determine where the files are stored"
- end
- end
+ # Specify the directory in which multiple files are stored.
+ def self.store_in(setting)
+ @directory_setting = setting
+ end
+
+ # Specify a single file location for storing just one file.
+ # This is used for things like the CRL.
+ def self.store_at(setting)
+ @file_setting = setting
+ end
+
+ # Specify where a specific ca file should be stored.
+ def self.store_ca_at(setting)
+ @ca_setting = setting
+ end
+
+ class << self
+ attr_reader :directory_setting, :file_setting, :ca_setting
+ end
+
+ # The full path to where we should store our files.
+ def self.collection_directory
+ return nil unless directory_setting
+ Puppet.settings[directory_setting]
+ end
+
+ # The full path to an individual file we would be managing.
+ def self.file_location
+ return nil unless file_setting
+ Puppet.settings[file_setting]
+ end
+
+ # The full path to a ca file we would be managing.
+ def self.ca_location
+ return nil unless ca_setting
+ Puppet.settings[ca_setting]
+ end
+
+ # We assume that all files named 'ca' are pointing to individual ca files,
+ # rather than normal host files. It's a bit hackish, but all the other
+ # solutions seemed even more hackish.
+ def ca?(name)
+ name == Puppet::SSL::Host.ca_name
+ end
+
+ def initialize
+ Puppet.settings.use(:main, :ssl)
+
+ (collection_directory || file_location) or raise Puppet::DevError, "No file or directory setting provided; terminus #{self.class.name} cannot function"
+ end
+
+ # Use a setting to determine our path.
+ def path(name)
+ if ca?(name) and ca_location
+ ca_location
+ elsif collection_directory
+ File.join(collection_directory, name.to_s + ".pem")
+ else
+ file_location
+ end
+ end
+
+ # Remove our file.
+ def destroy(request)
+ path = path(request.key)
+ return false unless FileTest.exist?(path)
+
+ Puppet.notice "Removing file #{model} #{request.key} at '#{path}'"
+ begin
+ File.unlink(path)
+ rescue => detail
+ raise Puppet::Error, "Could not remove #{request.key}: #{detail}"
+ end
+ end
+
+ # Find the file on disk, returning an instance of the model.
+ def find(request)
+ path = path(request.key)
+
+ return nil unless FileTest.exist?(path) or rename_files_with_uppercase(path)
+
+ result = model.new(request.key)
+ result.read(path)
+ result
+ end
+
+ # Save our file to disk.
+ def save(request)
+ path = path(request.key)
+ dir = File.dirname(path)
+
+ raise Puppet::Error.new("Cannot save #{request.key}; parent directory #{dir} does not exist") unless FileTest.directory?(dir)
+ raise Puppet::Error.new("Cannot save #{request.key}; parent directory #{dir} is not writable") unless FileTest.writable?(dir)
+
+ write(request.key, path) { |f| f.print request.instance.to_s }
+ end
+
+ # Search for more than one file. At this point, it just returns
+ # an instance for every file in the directory.
+ def search(request)
+ dir = collection_directory
+ Dir.entries(dir).reject { |file| file !~ /\.pem$/ }.collect do |file|
+ name = file.sub(/\.pem$/, '')
+ result = model.new(name)
+ result.read(File.join(dir, file))
+ result
+ end
+ end
+
+ private
+
+ # Demeterish pointers to class info.
+ def collection_directory
+ self.class.collection_directory
+ end
+
+ def file_location
+ self.class.file_location
+ end
+
+ def ca_location
+ self.class.ca_location
+ end
+
+ # A hack method to deal with files that exist with a different case.
+ # Just renames it; doesn't read it in or anything.
+ # LAK:NOTE This is a copy of the method in sslcertificates/support.rb,
+ # which we'll be EOL'ing at some point. This method was added at 20080702
+ # and should be removed at some point.
+ def rename_files_with_uppercase(file)
+ dir, short = File.split(file)
+ return nil unless FileTest.exist?(dir)
+
+ raise ArgumentError, "Tried to fix SSL files to a file containing uppercase" unless short.downcase == short
+ real_file = Dir.entries(dir).reject { |f| f =~ /^\./ }.find do |other|
+ other.downcase == short
+ end
+
+ return nil unless real_file
+
+ full_file = File.join(dir, real_file)
+
+ Puppet.notice "Fixing case in #{full_file}; renaming to #{file}"
+ File.rename(full_file, file)
+
+ true
+ end
+
+ # Yield a filehandle set up appropriately, either with our settings doing
+ # the work or opening a filehandle manually.
+ def write(name, path)
+ if ca?(name) and ca_location
+ Puppet.settings.write(self.class.ca_setting) { |f| yield f }
+ elsif file_location
+ Puppet.settings.write(self.class.file_setting) { |f| yield f }
+ elsif setting = self.class.directory_setting
+ begin
+ Puppet.settings.writesub(setting, path) { |f| yield f }
+ rescue => detail
+ raise Puppet::Error, "Could not write #{path} to #{setting}: #{detail}"
+ end
+ else
+ raise Puppet::DevError, "You must provide a setting to determine where the files are stored"
+ end
+ end
end
# LAK:NOTE This has to be at the end, because classes like SSL::Key use this
diff --git a/lib/puppet/indirector/status/local.rb b/lib/puppet/indirector/status/local.rb
index f9a7fc5..9951f7e 100644
--- a/lib/puppet/indirector/status/local.rb
+++ b/lib/puppet/indirector/status/local.rb
@@ -1,7 +1,7 @@
require 'puppet/indirector/status'
class Puppet::Indirector::Status::Local < Puppet::Indirector::Code
- def find( *anything )
- model.new
- end
+ def find( *anything )
+ model.new
+ end
end
diff --git a/lib/puppet/indirector/terminus.rb b/lib/puppet/indirector/terminus.rb
index 546f835..4ebd0d0 100644
--- a/lib/puppet/indirector/terminus.rb
+++ b/lib/puppet/indirector/terminus.rb
@@ -4,145 +4,145 @@ require 'puppet/util/instance_loader'
# A simple class that can function as the base class for indirected types.
class Puppet::Indirector::Terminus
- require 'puppet/util/docs'
- extend Puppet::Util::Docs
-
- class << self
- include Puppet::Util::InstanceLoader
-
- attr_accessor :name, :terminus_type
- attr_reader :abstract_terminus, :indirection
-
- # Are we an abstract terminus type, rather than an instance with an
- # associated indirection?
- def abstract_terminus?
- abstract_terminus
- end
-
- # Convert a constant to a short name.
- def const2name(const)
- const.sub(/^[A-Z]/) { |i| i.downcase }.gsub(/[A-Z]/) { |i| "_#{i.downcase}" }.intern
- end
-
- # Look up the indirection if we were only provided a name.
- def indirection=(name)
- if name.is_a?(Puppet::Indirector::Indirection)
- @indirection = name
- elsif ind = Puppet::Indirector::Indirection.instance(name)
- @indirection = ind
- else
- raise ArgumentError, "Could not find indirection instance #{name} for #{self.name}"
- end
- end
-
- def indirection_name
- @indirection.name
- end
-
- # Register our subclass with the appropriate indirection.
- # This follows the convention that our terminus is named after the
- # indirection.
- def inherited(subclass)
- longname = subclass.to_s
- if longname =~ /#<Class/
- raise Puppet::DevError, "Terminus subclasses must have associated constants"
- end
- names = longname.split("::")
-
- # Convert everything to a lower-case symbol, converting camelcase to underscore word separation.
- name = names.pop.sub(/^[A-Z]/) { |i| i.downcase }.gsub(/[A-Z]/) { |i| "_#{i.downcase}" }.intern
-
- subclass.name = name
-
- # Short-circuit the abstract types, which are those that directly subclass
- # the Terminus class.
- if self == Puppet::Indirector::Terminus
- subclass.mark_as_abstract_terminus
- return
- end
-
- # Set the terminus type to be the name of the abstract terminus type.
- # Yay, class/instance confusion.
- subclass.terminus_type = self.name
-
- # Our subclass is specifically associated with an indirection.
- raise("Invalid name #{longname}") unless names.length > 0
- indirection_name = names.pop.sub(/^[A-Z]/) { |i| i.downcase }.gsub(/[A-Z]/) { |i| "_#{i.downcase}" }.intern
-
- if indirection_name == "" or indirection_name.nil?
- raise Puppet::DevError, "Could not discern indirection model from class constant"
- end
-
- # This will throw an exception if the indirection instance cannot be found.
- # Do this last, because it also registers the terminus type with the indirection,
- # which needs the above information.
- subclass.indirection = indirection_name
-
- # And add this instance to the instance hash.
- Puppet::Indirector::Terminus.register_terminus_class(subclass)
- end
-
- # Mark that this instance is abstract.
- def mark_as_abstract_terminus
- @abstract_terminus = true
- end
-
- def model
- indirection.model
- end
-
- # Convert a short name to a constant.
- def name2const(name)
- name.to_s.capitalize.sub(/_(.)/) { |i| $1.upcase }
- end
-
- # Register a class, probably autoloaded.
- def register_terminus_class(klass)
- setup_instance_loading klass.indirection_name
- instance_hash(klass.indirection_name)[klass.name] = klass
- end
-
- # Return a terminus by name, using the autoloader.
- def terminus_class(indirection_name, terminus_type)
- setup_instance_loading indirection_name
- loaded_instance(indirection_name, terminus_type)
- end
-
- # Return all terminus classes for a given indirection.
- def terminus_classes(indirection_name)
- setup_instance_loading indirection_name
-
- # Load them all.
- instance_loader(indirection_name).loadall
-
- # And return the list of names.
- loaded_instances(indirection_name)
- end
-
- private
-
- def setup_instance_loading(type)
- instance_load type, "puppet/indirector/#{type}" unless instance_loading?(type)
- end
+ require 'puppet/util/docs'
+ extend Puppet::Util::Docs
+
+ class << self
+ include Puppet::Util::InstanceLoader
+
+ attr_accessor :name, :terminus_type
+ attr_reader :abstract_terminus, :indirection
+
+ # Are we an abstract terminus type, rather than an instance with an
+ # associated indirection?
+ def abstract_terminus?
+ abstract_terminus
+ end
+
+ # Convert a constant to a short name.
+ def const2name(const)
+ const.sub(/^[A-Z]/) { |i| i.downcase }.gsub(/[A-Z]/) { |i| "_#{i.downcase}" }.intern
+ end
+
+ # Look up the indirection if we were only provided a name.
+ def indirection=(name)
+ if name.is_a?(Puppet::Indirector::Indirection)
+ @indirection = name
+ elsif ind = Puppet::Indirector::Indirection.instance(name)
+ @indirection = ind
+ else
+ raise ArgumentError, "Could not find indirection instance #{name} for #{self.name}"
+ end
+ end
+
+ def indirection_name
+ @indirection.name
end
- def indirection
- self.class.indirection
+ # Register our subclass with the appropriate indirection.
+ # This follows the convention that our terminus is named after the
+ # indirection.
+ def inherited(subclass)
+ longname = subclass.to_s
+ if longname =~ /#<Class/
+ raise Puppet::DevError, "Terminus subclasses must have associated constants"
+ end
+ names = longname.split("::")
+
+ # Convert everything to a lower-case symbol, converting camelcase to underscore word separation.
+ name = names.pop.sub(/^[A-Z]/) { |i| i.downcase }.gsub(/[A-Z]/) { |i| "_#{i.downcase}" }.intern
+
+ subclass.name = name
+
+ # Short-circuit the abstract types, which are those that directly subclass
+ # the Terminus class.
+ if self == Puppet::Indirector::Terminus
+ subclass.mark_as_abstract_terminus
+ return
+ end
+
+ # Set the terminus type to be the name of the abstract terminus type.
+ # Yay, class/instance confusion.
+ subclass.terminus_type = self.name
+
+ # Our subclass is specifically associated with an indirection.
+ raise("Invalid name #{longname}") unless names.length > 0
+ indirection_name = names.pop.sub(/^[A-Z]/) { |i| i.downcase }.gsub(/[A-Z]/) { |i| "_#{i.downcase}" }.intern
+
+ if indirection_name == "" or indirection_name.nil?
+ raise Puppet::DevError, "Could not discern indirection model from class constant"
+ end
+
+ # This will throw an exception if the indirection instance cannot be found.
+ # Do this last, because it also registers the terminus type with the indirection,
+ # which needs the above information.
+ subclass.indirection = indirection_name
+
+ # And add this instance to the instance hash.
+ Puppet::Indirector::Terminus.register_terminus_class(subclass)
end
- def initialize
- raise Puppet::DevError, "Cannot create instances of abstract terminus types" if self.class.abstract_terminus?
+ # Mark that this instance is abstract.
+ def mark_as_abstract_terminus
+ @abstract_terminus = true
end
def model
- self.class.model
+ indirection.model
end
- def name
- self.class.name
+ # Convert a short name to a constant.
+ def name2const(name)
+ name.to_s.capitalize.sub(/_(.)/) { |i| $1.upcase }
end
- def terminus_type
- self.class.terminus_type
+ # Register a class, probably autoloaded.
+ def register_terminus_class(klass)
+ setup_instance_loading klass.indirection_name
+ instance_hash(klass.indirection_name)[klass.name] = klass
end
+
+ # Return a terminus by name, using the autoloader.
+ def terminus_class(indirection_name, terminus_type)
+ setup_instance_loading indirection_name
+ loaded_instance(indirection_name, terminus_type)
+ end
+
+ # Return all terminus classes for a given indirection.
+ def terminus_classes(indirection_name)
+ setup_instance_loading indirection_name
+
+ # Load them all.
+ instance_loader(indirection_name).loadall
+
+ # And return the list of names.
+ loaded_instances(indirection_name)
+ end
+
+ private
+
+ def setup_instance_loading(type)
+ instance_load type, "puppet/indirector/#{type}" unless instance_loading?(type)
+ end
+ end
+
+ def indirection
+ self.class.indirection
+ end
+
+ def initialize
+ raise Puppet::DevError, "Cannot create instances of abstract terminus types" if self.class.abstract_terminus?
+ end
+
+ def model
+ self.class.model
+ end
+
+ def name
+ self.class.name
+ end
+
+ def terminus_type
+ self.class.terminus_type
+ end
end
diff --git a/lib/puppet/indirector/yaml.rb b/lib/puppet/indirector/yaml.rb
index 826a8ae..c7c053f 100644
--- a/lib/puppet/indirector/yaml.rb
+++ b/lib/puppet/indirector/yaml.rb
@@ -3,66 +3,66 @@ require 'puppet/util/file_locking'
# The base class for YAML indirection termini.
class Puppet::Indirector::Yaml < Puppet::Indirector::Terminus
- include Puppet::Util::FileLocking
+ include Puppet::Util::FileLocking
- # Read a given name's file in and convert it from YAML.
- def find(request)
- file = path(request.key)
- return nil unless FileTest.exist?(file)
+ # Read a given name's file in and convert it from YAML.
+ def find(request)
+ file = path(request.key)
+ return nil unless FileTest.exist?(file)
- yaml = nil
- begin
- readlock(file) { |fh| yaml = fh.read }
- rescue => detail
- raise Puppet::Error, "Could not read YAML data for #{indirection.name} #{request.key}: #{detail}"
- end
- begin
- return from_yaml(yaml)
- rescue => detail
- raise Puppet::Error, "Could not parse YAML data for #{indirection.name} #{request.key}: #{detail}"
- end
+ yaml = nil
+ begin
+ readlock(file) { |fh| yaml = fh.read }
+ rescue => detail
+ raise Puppet::Error, "Could not read YAML data for #{indirection.name} #{request.key}: #{detail}"
end
+ begin
+ return from_yaml(yaml)
+ rescue => detail
+ raise Puppet::Error, "Could not parse YAML data for #{indirection.name} #{request.key}: #{detail}"
+ end
+ end
- # Convert our object to YAML and store it to the disk.
- def save(request)
- raise ArgumentError.new("You can only save objects that respond to :name") unless request.instance.respond_to?(:name)
+ # Convert our object to YAML and store it to the disk.
+ def save(request)
+ raise ArgumentError.new("You can only save objects that respond to :name") unless request.instance.respond_to?(:name)
- file = path(request.key)
+ file = path(request.key)
- basedir = File.dirname(file)
+ basedir = File.dirname(file)
- # This is quite likely a bad idea, since we're not managing ownership or modes.
- Dir.mkdir(basedir) unless FileTest.exist?(basedir)
+ # This is quite likely a bad idea, since we're not managing ownership or modes.
+ Dir.mkdir(basedir) unless FileTest.exist?(basedir)
- begin
- writelock(file, 0660) { |f| f.print to_yaml(request.instance) }
- rescue TypeError => detail
- Puppet.err "Could not save #{self.name} #{request.key}: #{detail}"
- end
+ begin
+ writelock(file, 0660) { |f| f.print to_yaml(request.instance) }
+ rescue TypeError => detail
+ Puppet.err "Could not save #{self.name} #{request.key}: #{detail}"
end
+ end
- # Get the yaml directory
- def base
- Puppet.run_mode.master? ? Puppet[:yamldir] : Puppet[:clientyamldir]
- end
+ # Get the yaml directory
+ def base
+ Puppet.run_mode.master? ? Puppet[:yamldir] : Puppet[:clientyamldir]
+ end
- # Return the path to a given node's file.
- def path(name)
- File.join(base, self.class.indirection_name.to_s, name.to_s + ".yaml")
- end
+ # Return the path to a given node's file.
+ def path(name)
+ File.join(base, self.class.indirection_name.to_s, name.to_s + ".yaml")
+ end
- # Do a glob on the yaml directory, loading each file found
- def search(request)
- Dir.glob(File.join(base, self.class.indirection_name.to_s, request.key)).collect { |f| YAML.load_file(f) }
- end
+ # Do a glob on the yaml directory, loading each file found
+ def search(request)
+ Dir.glob(File.join(base, self.class.indirection_name.to_s, request.key)).collect { |f| YAML.load_file(f) }
+ end
- private
+ private
- def from_yaml(text)
- YAML.load(text)
- end
+ def from_yaml(text)
+ YAML.load(text)
+ end
- def to_yaml(object)
- YAML.dump(object)
- end
+ def to_yaml(object)
+ YAML.dump(object)
+ end
end
diff --git a/lib/puppet/metatype/manager.rb b/lib/puppet/metatype/manager.rb
index 51068f6..12cbf64 100644
--- a/lib/puppet/metatype/manager.rb
+++ b/lib/puppet/metatype/manager.rb
@@ -5,143 +5,143 @@ require 'puppet/util/classgen'
# Puppet::Type class, it's just split out here for clarity.
module Puppet::MetaType
module Manager
- include Puppet::Util::ClassGen
-
- # remove all type instances; this is mostly only useful for testing
- def allclear
- @types.each { |name, type|
- type.clear
- }
+ include Puppet::Util::ClassGen
+
+ # remove all type instances; this is mostly only useful for testing
+ def allclear
+ @types.each { |name, type|
+ type.clear
+ }
+ end
+
+ # iterate across all of the subclasses of Type
+ def eachtype
+ @types.each do |name, type|
+ # Only consider types that have names
+ #if ! type.parameters.empty? or ! type.validproperties.empty?
+ yield type
+ #end
end
-
- # iterate across all of the subclasses of Type
- def eachtype
- @types.each do |name, type|
- # Only consider types that have names
- #if ! type.parameters.empty? or ! type.validproperties.empty?
- yield type
- #end
- end
+ end
+
+ # Load all types. Only currently used for documentation.
+ def loadall
+ typeloader.loadall
+ end
+
+ # Define a new type.
+ def newtype(name, options = {}, &block)
+ # Handle backward compatibility
+ unless options.is_a?(Hash)
+ Puppet.warning "Puppet::Type.newtype(#{name}) now expects a hash as the second argument, not #{options.inspect}"
+ options = {:parent => options}
end
- # Load all types. Only currently used for documentation.
- def loadall
- typeloader.loadall
- end
+ # First make sure we don't have a method sitting around
+ name = symbolize(name)
+ newmethod = "new#{name.to_s}"
- # Define a new type.
- def newtype(name, options = {}, &block)
- # Handle backward compatibility
- unless options.is_a?(Hash)
- Puppet.warning "Puppet::Type.newtype(#{name}) now expects a hash as the second argument, not #{options.inspect}"
- options = {:parent => options}
- end
+ # Used for method manipulation.
+ selfobj = singleton_class
- # First make sure we don't have a method sitting around
- name = symbolize(name)
- newmethod = "new#{name.to_s}"
+ @types ||= {}
- # Used for method manipulation.
- selfobj = singleton_class
+ if @types.include?(name)
+ if self.respond_to?(newmethod)
+ # Remove the old newmethod
+ selfobj.send(:remove_method,newmethod)
+ end
+ end
- @types ||= {}
+ options = symbolize_options(options)
- if @types.include?(name)
- if self.respond_to?(newmethod)
- # Remove the old newmethod
- selfobj.send(:remove_method,newmethod)
- end
- end
+ if parent = options[:parent]
+ options.delete(:parent)
+ end
- options = symbolize_options(options)
+ # Then create the class.
- if parent = options[:parent]
- options.delete(:parent)
- end
+ klass = genclass(
+ name,
+ :parent => (parent || Puppet::Type),
+
+ :overwrite => true,
+ :hash => @types,
+ :attributes => options,
+ &block
+ )
+
+ # Now define a "new<type>" method for convenience.
+ if self.respond_to? newmethod
+ # Refuse to overwrite existing methods like 'newparam' or 'newtype'.
+ Puppet.warning "'new#{name.to_s}' method already exists; skipping"
+ else
+ selfobj.send(:define_method, newmethod) do |*args|
+ klass.new(*args)
+ end
+ end
- # Then create the class.
+ # If they've got all the necessary methods defined and they haven't
+ # already added the property, then do so now.
+ klass.ensurable if klass.ensurable? and ! klass.validproperty?(:ensure)
- klass = genclass(
- name,
- :parent => (parent || Puppet::Type),
-
- :overwrite => true,
- :hash => @types,
- :attributes => options,
- &block
- )
-
- # Now define a "new<type>" method for convenience.
- if self.respond_to? newmethod
- # Refuse to overwrite existing methods like 'newparam' or 'newtype'.
- Puppet.warning "'new#{name.to_s}' method already exists; skipping"
- else
- selfobj.send(:define_method, newmethod) do |*args|
- klass.new(*args)
- end
- end
-
- # If they've got all the necessary methods defined and they haven't
- # already added the property, then do so now.
- klass.ensurable if klass.ensurable? and ! klass.validproperty?(:ensure)
-
- # Now set up autoload any providers that might exist for this type.
-
- klass.providerloader = Puppet::Util::Autoload.new(
- klass,
+ # Now set up autoload any providers that might exist for this type.
+
+ klass.providerloader = Puppet::Util::Autoload.new(
+ klass,
- "puppet/provider/#{klass.name.to_s}"
- )
+ "puppet/provider/#{klass.name.to_s}"
+ )
- # We have to load everything so that we can figure out the default type.
- klass.providerloader.loadall
+ # We have to load everything so that we can figure out the default type.
+ klass.providerloader.loadall
- klass
- end
+ klass
+ end
- # Remove an existing defined type. Largely used for testing.
- def rmtype(name)
- # Then create the class.
+ # Remove an existing defined type. Largely used for testing.
+ def rmtype(name)
+ # Then create the class.
- klass = rmclass(
- name,
+ klass = rmclass(
+ name,
- :hash => @types
- )
+ :hash => @types
+ )
- singleton_class.send(:remove_method, "new#{name}") if respond_to?("new#{name}")
- end
+ singleton_class.send(:remove_method, "new#{name}") if respond_to?("new#{name}")
+ end
- # Return a Type instance by name.
- def type(name)
- @types ||= {}
+ # Return a Type instance by name.
+ def type(name)
+ @types ||= {}
- name = name.to_s.downcase.to_sym
+ name = name.to_s.downcase.to_sym
- if t = @types[name]
- return t
- else
- if typeloader.load(name)
- Puppet.warning "Loaded puppet/type/#{name} but no class was created" unless @types.include? name
- end
+ if t = @types[name]
+ return t
+ else
+ if typeloader.load(name)
+ Puppet.warning "Loaded puppet/type/#{name} but no class was created" unless @types.include? name
+ end
- return @types[name]
- end
+ return @types[name]
end
+ end
- # Create a loader for Puppet types.
- def typeloader
- unless defined?(@typeloader)
+ # Create a loader for Puppet types.
+ def typeloader
+ unless defined?(@typeloader)
- @typeloader = Puppet::Util::Autoload.new(
- self,
+ @typeloader = Puppet::Util::Autoload.new(
+ self,
- "puppet/type", :wrap => false
- )
- end
-
- @typeloader
+ "puppet/type", :wrap => false
+ )
end
+
+ @typeloader
+ end
end
end
diff --git a/lib/puppet/module.rb b/lib/puppet/module.rb
index b4184dd..8356144 100644
--- a/lib/puppet/module.rb
+++ b/lib/puppet/module.rb
@@ -2,203 +2,203 @@ require 'puppet/util/logging'
# Support for modules
class Puppet::Module
- class Error < Puppet::Error; end
- class MissingModule < Error; end
- class IncompatibleModule < Error; end
- class UnsupportedPlatform < Error; end
- class IncompatiblePlatform < Error; end
- class MissingMetadata < Error; end
- class InvalidName < Error; end
-
- include Puppet::Util::Logging
-
- TEMPLATES = "templates"
- FILES = "files"
- MANIFESTS = "manifests"
- PLUGINS = "plugins"
-
- FILETYPES = [MANIFESTS, FILES, TEMPLATES, PLUGINS]
-
- # Return an array of paths by splitting the +modulepath+ config
- # parameter. Only consider paths that are absolute and existing
- # directories
- def self.modulepath(environment = nil)
- Puppet::Node::Environment.new(environment).modulepath
- end
-
- # Find and return the +module+ that +path+ belongs to. If +path+ is
- # absolute, or if there is no module whose name is the first component
- # of +path+, return +nil+
- def self.find(modname, environment = nil)
- return nil unless modname
- Puppet::Node::Environment.new(environment).module(modname)
- end
-
- attr_reader :name, :environment
- attr_writer :environment
-
- attr_accessor :source, :author, :version, :license, :puppetversion, :summary, :description, :project_page
-
- def has_metadata?
- return false unless metadata_file
-
- FileTest.exist?(metadata_file)
- end
-
- def initialize(name, environment = nil)
- @name = name
-
- assert_validity
-
- if environment.is_a?(Puppet::Node::Environment)
- @environment = environment
- else
- @environment = Puppet::Node::Environment.new(environment)
- end
-
- load_metadata if has_metadata?
-
- validate_puppet_version
- validate_dependencies
- end
+ class Error < Puppet::Error; end
+ class MissingModule < Error; end
+ class IncompatibleModule < Error; end
+ class UnsupportedPlatform < Error; end
+ class IncompatiblePlatform < Error; end
+ class MissingMetadata < Error; end
+ class InvalidName < Error; end
+
+ include Puppet::Util::Logging
+
+ TEMPLATES = "templates"
+ FILES = "files"
+ MANIFESTS = "manifests"
+ PLUGINS = "plugins"
+
+ FILETYPES = [MANIFESTS, FILES, TEMPLATES, PLUGINS]
+
+ # Return an array of paths by splitting the +modulepath+ config
+ # parameter. Only consider paths that are absolute and existing
+ # directories
+ def self.modulepath(environment = nil)
+ Puppet::Node::Environment.new(environment).modulepath
+ end
+
+ # Find and return the +module+ that +path+ belongs to. If +path+ is
+ # absolute, or if there is no module whose name is the first component
+ # of +path+, return +nil+
+ def self.find(modname, environment = nil)
+ return nil unless modname
+ Puppet::Node::Environment.new(environment).module(modname)
+ end
+
+ attr_reader :name, :environment
+ attr_writer :environment
+
+ attr_accessor :source, :author, :version, :license, :puppetversion, :summary, :description, :project_page
+
+ def has_metadata?
+ return false unless metadata_file
+
+ FileTest.exist?(metadata_file)
+ end
+
+ def initialize(name, environment = nil)
+ @name = name
+
+ assert_validity
+
+ if environment.is_a?(Puppet::Node::Environment)
+ @environment = environment
+ else
+ @environment = Puppet::Node::Environment.new(environment)
+ end
+
+ load_metadata if has_metadata?
+
+ validate_puppet_version
+ validate_dependencies
+ end
+
+ FILETYPES.each do |type|
+ # A boolean method to let external callers determine if
+ # we have files of a given type.
+ define_method(type +'?') do
+ return false unless path
+ return false unless FileTest.exist?(subpath(type))
+ return true
+ end
+
+ # A method for returning a given file of a given type.
+ # e.g., file = mod.manifest("my/manifest.pp")
+ #
+ # If the file name is nil, then the base directory for the
+ # file type is passed; this is used for fileserving.
+ define_method(type.to_s.sub(/s$/, '')) do |file|
+ return nil unless path
+
+ # If 'file' is nil then they're asking for the base path.
+ # This is used for things like fileserving.
+ if file
+ full_path = File.join(subpath(type), file)
+ else
+ full_path = subpath(type)
+ end
+
+ return nil unless FileTest.exist?(full_path)
+ return full_path
+ end
+ end
+
+ def exist?
+ ! path.nil?
+ end
+
+ # Find the first 'files' directory. This is used by the XMLRPC fileserver.
+ def file_directory
+ subpath("files")
+ end
+
+ def license_file
+ return @license_file if defined?(@license_file)
+
+ return @license_file = nil unless path
+ @license_file = File.join(path, "License")
+ end
- FILETYPES.each do |type|
- # A boolean method to let external callers determine if
- # we have files of a given type.
- define_method(type +'?') do
- return false unless path
- return false unless FileTest.exist?(subpath(type))
- return true
+ def load_metadata
+ data = PSON.parse File.read(metadata_file)
+ [:source, :author, :version, :license, :puppetversion].each do |attr|
+ unless value = data[attr.to_s]
+ unless attr == :puppetversion
+ raise MissingMetadata, "No #{attr} module metadata provided for #{self.name}"
end
-
- # A method for returning a given file of a given type.
- # e.g., file = mod.manifest("my/manifest.pp")
- #
- # If the file name is nil, then the base directory for the
- # file type is passed; this is used for fileserving.
- define_method(type.to_s.sub(/s$/, '')) do |file|
- return nil unless path
-
- # If 'file' is nil then they're asking for the base path.
- # This is used for things like fileserving.
- if file
- full_path = File.join(subpath(type), file)
- else
- full_path = subpath(type)
- end
-
- return nil unless FileTest.exist?(full_path)
- return full_path
- end
- end
-
- def exist?
- ! path.nil?
- end
-
- # Find the first 'files' directory. This is used by the XMLRPC fileserver.
- def file_directory
- subpath("files")
- end
-
- def license_file
- return @license_file if defined?(@license_file)
-
- return @license_file = nil unless path
- @license_file = File.join(path, "License")
- end
-
- def load_metadata
- data = PSON.parse File.read(metadata_file)
- [:source, :author, :version, :license, :puppetversion].each do |attr|
- unless value = data[attr.to_s]
- unless attr == :puppetversion
- raise MissingMetadata, "No #{attr} module metadata provided for #{self.name}"
- end
- end
- send(attr.to_s + "=", value)
- end
- end
-
- # Return the list of manifests matching the given glob pattern,
- # defaulting to 'init.{pp,rb}' for empty modules.
- def match_manifests(rest)
- pat = File.join(path, MANIFESTS, rest || 'init')
- Dir.
- glob(pat + (File.extname(pat).empty? ? '.{pp,rb}' : '')).
- reject { |f| FileTest.directory?(f) }
- end
-
- def metadata_file
- return @metadata_file if defined?(@metadata_file)
-
- return @metadata_file = nil unless path
- @metadata_file = File.join(path, "metadata.json")
- end
-
- # Find this module in the modulepath.
- def path
- environment.modulepath.collect { |path| File.join(path, name) }.find { |d| FileTest.exist?(d) }
- end
-
- # Find all plugin directories. This is used by the Plugins fileserving mount.
- def plugin_directory
- subpath("plugins")
- end
-
- def requires(name, version = nil)
- @requires ||= []
- @requires << [name, version]
- end
-
- def supports(name, version = nil)
- @supports ||= []
- @supports << [name, version]
- end
-
- def to_s
- result = "Module #{name}"
- result += "(#{path})" if path
- result
- end
-
- def validate_dependencies
- return unless defined?(@requires)
-
- @requires.each do |name, version|
- unless mod = environment.module(name)
- raise MissingModule, "Missing module #{name} required by #{self.name}"
- end
-
- if version and mod.version != version
- raise IncompatibleModule, "Required module #{name} is version #{mod.version} but #{self.name} requires #{version}"
- end
- end
- end
-
- def validate_puppet_version
- return unless puppetversion and puppetversion != Puppet.version
- raise IncompatibleModule, "Module #{self.name} is only compatible with Puppet version #{puppetversion}, not #{Puppet.version}"
- end
-
- private
-
- def subpath(type)
- return File.join(path, type) unless type.to_s == "plugins"
-
- backward_compatible_plugins_dir
- end
-
- def backward_compatible_plugins_dir
- if dir = File.join(path, "plugins") and FileTest.exist?(dir)
- warning "using the deprecated 'plugins' directory for ruby extensions; please move to 'lib'"
- return dir
- else
- return File.join(path, "lib")
- end
- end
-
- def assert_validity
- raise InvalidName, "Invalid module name; module names must be alphanumeric (plus '-'), not '#{name}'" unless name =~ /^[-\w]+$/
- end
+ end
+ send(attr.to_s + "=", value)
+ end
+ end
+
+ # Return the list of manifests matching the given glob pattern,
+ # defaulting to 'init.{pp,rb}' for empty modules.
+ def match_manifests(rest)
+ pat = File.join(path, MANIFESTS, rest || 'init')
+ Dir.
+ glob(pat + (File.extname(pat).empty? ? '.{pp,rb}' : '')).
+ reject { |f| FileTest.directory?(f) }
+ end
+
+ def metadata_file
+ return @metadata_file if defined?(@metadata_file)
+
+ return @metadata_file = nil unless path
+ @metadata_file = File.join(path, "metadata.json")
+ end
+
+ # Find this module in the modulepath.
+ def path
+ environment.modulepath.collect { |path| File.join(path, name) }.find { |d| FileTest.exist?(d) }
+ end
+
+ # Find all plugin directories. This is used by the Plugins fileserving mount.
+ def plugin_directory
+ subpath("plugins")
+ end
+
+ def requires(name, version = nil)
+ @requires ||= []
+ @requires << [name, version]
+ end
+
+ def supports(name, version = nil)
+ @supports ||= []
+ @supports << [name, version]
+ end
+
+ def to_s
+ result = "Module #{name}"
+ result += "(#{path})" if path
+ result
+ end
+
+ def validate_dependencies
+ return unless defined?(@requires)
+
+ @requires.each do |name, version|
+ unless mod = environment.module(name)
+ raise MissingModule, "Missing module #{name} required by #{self.name}"
+ end
+
+ if version and mod.version != version
+ raise IncompatibleModule, "Required module #{name} is version #{mod.version} but #{self.name} requires #{version}"
+ end
+ end
+ end
+
+ def validate_puppet_version
+ return unless puppetversion and puppetversion != Puppet.version
+ raise IncompatibleModule, "Module #{self.name} is only compatible with Puppet version #{puppetversion}, not #{Puppet.version}"
+ end
+
+ private
+
+ def subpath(type)
+ return File.join(path, type) unless type.to_s == "plugins"
+
+ backward_compatible_plugins_dir
+ end
+
+ def backward_compatible_plugins_dir
+ if dir = File.join(path, "plugins") and FileTest.exist?(dir)
+ warning "using the deprecated 'plugins' directory for ruby extensions; please move to 'lib'"
+ return dir
+ else
+ return File.join(path, "lib")
+ end
+ end
+
+ def assert_validity
+ raise InvalidName, "Invalid module name; module names must be alphanumeric (plus '-'), not '#{name}'" unless name =~ /^[-\w]+$/
+ end
end
diff --git a/lib/puppet/network/authconfig.rb b/lib/puppet/network/authconfig.rb
index ba2caa4..4ba89fa 100644
--- a/lib/puppet/network/authconfig.rb
+++ b/lib/puppet/network/authconfig.rb
@@ -2,171 +2,171 @@ require 'puppet/util/loadedfile'
require 'puppet/network/rights'
module Puppet
- class ConfigurationError < Puppet::Error; end
- class Network::AuthConfig < Puppet::Util::LoadedFile
+ class ConfigurationError < Puppet::Error; end
+ class Network::AuthConfig < Puppet::Util::LoadedFile
- def self.main
- @main ||= self.new
- end
+ def self.main
+ @main ||= self.new
+ end
- # Just proxy the setting methods to our rights stuff
- [:allow, :deny].each do |method|
- define_method(method) do |*args|
- @rights.send(method, *args)
- end
- end
+ # Just proxy the setting methods to our rights stuff
+ [:allow, :deny].each do |method|
+ define_method(method) do |*args|
+ @rights.send(method, *args)
+ end
+ end
- # Here we add a little bit of semantics. They can set auth on a whole
- # namespace or on just a single method in the namespace.
- def allowed?(request)
- name = request.call.intern
- namespace = request.handler.intern
- method = request.method.intern
+ # Here we add a little bit of semantics. They can set auth on a whole
+ # namespace or on just a single method in the namespace.
+ def allowed?(request)
+ name = request.call.intern
+ namespace = request.handler.intern
+ method = request.method.intern
+
+ read
+
+ if @rights.include?(name)
+ return @rights[name].allowed?(request.name, request.ip)
+ elsif @rights.include?(namespace)
+ return @rights[namespace].allowed?(request.name, request.ip)
+ end
+ false
+ end
- read
+ # Does the file exist? Puppetmasterd does not require it, but
+ # puppet agent does.
+ def exists?
+ FileTest.exists?(@file)
+ end
- if @rights.include?(name)
- return @rights[name].allowed?(request.name, request.ip)
- elsif @rights.include?(namespace)
- return @rights[namespace].allowed?(request.name, request.ip)
- end
- false
- end
+ def initialize(file = nil, parsenow = true)
+ @file = file || Puppet[:authconfig]
- # Does the file exist? Puppetmasterd does not require it, but
- # puppet agent does.
- def exists?
- FileTest.exists?(@file)
- end
+ raise Puppet::DevError, "No authconfig file defined" unless @file
+ return unless self.exists?
+ super(@file)
+ @rights = Puppet::Network::Rights.new
+ @configstamp = @configstatted = nil
+ @configtimeout = 60
- def initialize(file = nil, parsenow = true)
- @file = file || Puppet[:authconfig]
+ read if parsenow
+ end
- raise Puppet::DevError, "No authconfig file defined" unless @file
- return unless self.exists?
- super(@file)
- @rights = Puppet::Network::Rights.new
- @configstamp = @configstatted = nil
- @configtimeout = 60
+ # Read the configuration file.
+ def read
+ return unless FileTest.exists?(@file)
- read if parsenow
- end
+ if @configstamp
+ if @configtimeout and @configstatted
+ if Time.now - @configstatted > @configtimeout
+ @configstatted = Time.now
+ tmp = File.stat(@file).ctime
- # Read the configuration file.
- def read
- return unless FileTest.exists?(@file)
-
- if @configstamp
- if @configtimeout and @configstatted
- if Time.now - @configstatted > @configtimeout
- @configstatted = Time.now
- tmp = File.stat(@file).ctime
-
- if tmp == @configstamp
- return
- else
- Puppet.notice "#{tmp} vs #{@configstamp}"
- end
- else
- return
- end
- else
- Puppet.notice "#{@configtimeout} and #{@configstatted}"
- end
+ if tmp == @configstamp
+ return
+ else
+ Puppet.notice "#{tmp} vs #{@configstamp}"
end
-
- parse
-
- @configstamp = File.stat(@file).ctime
- @configstatted = Time.now
+ else
+ return
+ end
+ else
+ Puppet.notice "#{@configtimeout} and #{@configstatted}"
end
+ end
- private
-
- def parse
- newrights = Puppet::Network::Rights.new
- begin
- File.open(@file) { |f|
- right = nil
- count = 1
- f.each { |line|
- case line
- when /^\s*#/ # skip comments
- count += 1
- next
- when /^\s*$/ # skip blank lines
- count += 1
- next
- when /^(?:(\[[\w.]+\])|(path)\s+((?:~\s+)?[^ ]+))\s*$/ # "namespace" or "namespace.method" or "path /path" or "path ~ regex"
- name = $1
- name = $3 if $2 == "path"
- name.chomp!
- right = newrights.newright(name, count, @file)
- when /^\s*(allow|deny|method|environment|auth(?:enticated)?)\s+(.+)$/
- parse_right_directive(right, $1, $2, count)
- else
- raise ConfigurationError, "Invalid line #{count}: #{line}"
- end
- count += 1
- }
- }
- rescue Errno::EACCES => detail
- Puppet.err "Configuration error: Cannot read #{@file}; cannot serve"
- #raise Puppet::Error, "Cannot read #{@config}"
- rescue Errno::ENOENT => detail
- Puppet.err "Configuration error: '#{@file}' does not exit; cannot serve"
- #raise Puppet::Error, "#{@config} does not exit"
- #rescue FileServerError => detail
- # Puppet.err "FileServer error: #{detail}"
- end
+ parse
- # Verify each of the rights are valid.
- # We let the check raise an error, so that it can raise an error
- # pointing to the specific problem.
- newrights.each { |name, right|
- right.valid?
- }
- @rights = newrights
- end
+ @configstamp = File.stat(@file).ctime
+ @configstatted = Time.now
+ end
- def parse_right_directive(right, var, value, count)
- case var
- when "allow"
- modify_right(right, :allow, value, "allowing %s access", count)
- when "deny"
- modify_right(right, :deny, value, "denying %s access", count)
- when "method"
- unless right.acl_type == :regex
- raise ConfigurationError, "'method' directive not allowed in namespace ACL at line #{count} of #{@config}"
- end
- modify_right(right, :restrict_method, value, "allowing 'method' %s", count)
- when "environment"
- unless right.acl_type == :regex
- raise ConfigurationError, "'environment' directive not allowed in namespace ACL at line #{count} of #{@config}"
- end
- modify_right(right, :restrict_environment, value, "adding environment %s", count)
- when /auth(?:enticated)?/
- unless right.acl_type == :regex
- raise ConfigurationError, "'authenticated' directive not allowed in namespace ACL at line #{count} of #{@config}"
- end
- modify_right(right, :restrict_authenticated, value, "adding authentication %s", count)
+ private
+
+ def parse
+ newrights = Puppet::Network::Rights.new
+ begin
+ File.open(@file) { |f|
+ right = nil
+ count = 1
+ f.each { |line|
+ case line
+ when /^\s*#/ # skip comments
+ count += 1
+ next
+ when /^\s*$/ # skip blank lines
+ count += 1
+ next
+ when /^(?:(\[[\w.]+\])|(path)\s+((?:~\s+)?[^ ]+))\s*$/ # "namespace" or "namespace.method" or "path /path" or "path ~ regex"
+ name = $1
+ name = $3 if $2 == "path"
+ name.chomp!
+ right = newrights.newright(name, count, @file)
+ when /^\s*(allow|deny|method|environment|auth(?:enticated)?)\s+(.+)$/
+ parse_right_directive(right, $1, $2, count)
else
- raise ConfigurationError,
- "Invalid argument '#{var}' at line #{count}"
+ raise ConfigurationError, "Invalid line #{count}: #{line}"
end
- end
+ count += 1
+ }
+ }
+ rescue Errno::EACCES => detail
+ Puppet.err "Configuration error: Cannot read #{@file}; cannot serve"
+ #raise Puppet::Error, "Cannot read #{@config}"
+ rescue Errno::ENOENT => detail
+ Puppet.err "Configuration error: '#{@file}' does not exit; cannot serve"
+ #raise Puppet::Error, "#{@config} does not exit"
+ #rescue FileServerError => detail
+ # Puppet.err "FileServer error: #{detail}"
+ end
+
+ # Verify each of the rights are valid.
+ # We let the check raise an error, so that it can raise an error
+ # pointing to the specific problem.
+ newrights.each { |name, right|
+ right.valid?
+ }
+ @rights = newrights
+ end
- def modify_right(right, method, value, msg, count)
- value.split(/\s*,\s*/).each do |val|
- begin
- right.info msg % val
- right.send(method, val)
- rescue AuthStoreError => detail
- raise ConfigurationError, "#{detail} at line #{count} of #{@file}"
- end
- end
+ def parse_right_directive(right, var, value, count)
+ case var
+ when "allow"
+ modify_right(right, :allow, value, "allowing %s access", count)
+ when "deny"
+ modify_right(right, :deny, value, "denying %s access", count)
+ when "method"
+ unless right.acl_type == :regex
+ raise ConfigurationError, "'method' directive not allowed in namespace ACL at line #{count} of #{@config}"
+ end
+ modify_right(right, :restrict_method, value, "allowing 'method' %s", count)
+ when "environment"
+ unless right.acl_type == :regex
+ raise ConfigurationError, "'environment' directive not allowed in namespace ACL at line #{count} of #{@config}"
+ end
+ modify_right(right, :restrict_environment, value, "adding environment %s", count)
+ when /auth(?:enticated)?/
+ unless right.acl_type == :regex
+ raise ConfigurationError, "'authenticated' directive not allowed in namespace ACL at line #{count} of #{@config}"
end
+ modify_right(right, :restrict_authenticated, value, "adding authentication %s", count)
+ else
+ raise ConfigurationError,
+ "Invalid argument '#{var}' at line #{count}"
+ end
+ end
+ def modify_right(right, method, value, msg, count)
+ value.split(/\s*,\s*/).each do |val|
+ begin
+ right.info msg % val
+ right.send(method, val)
+ rescue AuthStoreError => detail
+ raise ConfigurationError, "#{detail} at line #{count} of #{@file}"
+ end
+ end
end
+
+ end
end
diff --git a/lib/puppet/network/authorization.rb b/lib/puppet/network/authorization.rb
index 12459a5..b9cab21 100644
--- a/lib/puppet/network/authorization.rb
+++ b/lib/puppet/network/authorization.rb
@@ -2,75 +2,75 @@ require 'puppet/network/client_request'
require 'puppet/network/authconfig'
module Puppet::Network
- # Most of our subclassing is just so that we can get
- # access to information from the request object, like
- # the client name and IP address.
- class InvalidClientRequest < Puppet::Error; end
- module Authorization
- # Create our config object if necessary. This works even if
- # there's no configuration file.
- def authconfig
- @authconfig ||= Puppet::Network::AuthConfig.main
+ # Most of our subclassing is just so that we can get
+ # access to information from the request object, like
+ # the client name and IP address.
+ class InvalidClientRequest < Puppet::Error; end
+ module Authorization
+ # Create our config object if necessary. This works even if
+ # there's no configuration file.
+ def authconfig
+ @authconfig ||= Puppet::Network::AuthConfig.main
- @authconfig
- end
+ @authconfig
+ end
- # Verify that our client has access. We allow untrusted access to
- # puppetca methods but no others.
- def authorized?(request)
- msg = "#{request.authenticated? ? "authenticated" : "unauthenticated"} client #{request} access to #{request.call}"
+ # Verify that our client has access. We allow untrusted access to
+ # puppetca methods but no others.
+ def authorized?(request)
+ msg = "#{request.authenticated? ? "authenticated" : "unauthenticated"} client #{request} access to #{request.call}"
- if request.authenticated?
- if authconfig.exists?
- if authconfig.allowed?(request)
- Puppet.debug "Allowing #{msg}"
- return true
- else
- Puppet.notice "Denying #{msg}"
- return false
- end
- else
- if Puppet.run_mode.master?
- Puppet.debug "Allowing #{msg}"
- return true
- else
- Puppet.notice "Denying #{msg}"
- return false
- end
- end
- else
- if request.handler == "puppetca"
- Puppet.notice "Allowing #{msg}"
- else
- Puppet.notice "Denying #{msg}"
- return false
- end
- end
+ if request.authenticated?
+ if authconfig.exists?
+ if authconfig.allowed?(request)
+ Puppet.debug "Allowing #{msg}"
+ return true
+ else
+ Puppet.notice "Denying #{msg}"
+ return false
+ end
+ else
+ if Puppet.run_mode.master?
+ Puppet.debug "Allowing #{msg}"
+ return true
+ else
+ Puppet.notice "Denying #{msg}"
+ return false
+ end
end
-
- # Is this functionality available?
- def available?(request)
- if handler_loaded?(request.handler)
- return true
- else
- Puppet.warning "Client #{request} requested unavailable functionality #{request.handler}"
- return false
- end
+ else
+ if request.handler == "puppetca"
+ Puppet.notice "Allowing #{msg}"
+ else
+ Puppet.notice "Denying #{msg}"
+ return false
end
+ end
+ end
- # Make sure that this method is available and authorized.
- def verify(request)
- unless available?(request)
- raise InvalidClientRequest.new(
- "Functionality #{request.handler} not available"
- )
- end
- unless authorized?(request)
- raise InvalidClientRequest.new(
- "Host #{request} not authorized to call #{request.call}"
- )
- end
- end
+ # Is this functionality available?
+ def available?(request)
+ if handler_loaded?(request.handler)
+ return true
+ else
+ Puppet.warning "Client #{request} requested unavailable functionality #{request.handler}"
+ return false
+ end
+ end
+
+ # Make sure that this method is available and authorized.
+ def verify(request)
+ unless available?(request)
+ raise InvalidClientRequest.new(
+ "Functionality #{request.handler} not available"
+ )
+ end
+ unless authorized?(request)
+ raise InvalidClientRequest.new(
+ "Host #{request} not authorized to call #{request.call}"
+ )
+ end
end
+ end
end
diff --git a/lib/puppet/network/authstore.rb b/lib/puppet/network/authstore.rb
index 720145e..4ddd14f 100755
--- a/lib/puppet/network/authstore.rb
+++ b/lib/puppet/network/authstore.rb
@@ -5,246 +5,246 @@ require 'ipaddr'
require 'puppet/util/logging'
module Puppet
- class AuthStoreError < Puppet::Error; end
- class AuthorizationError < Puppet::Error; end
-
- class Network::AuthStore
- include Puppet::Util::Logging
-
- # Mark a given pattern as allowed.
- def allow(pattern)
- # a simple way to allow anyone at all to connect
- if pattern == "*"
- @globalallow = true
- else
- store(:allow, pattern)
- end
-
- nil
- end
+ class AuthStoreError < Puppet::Error; end
+ class AuthorizationError < Puppet::Error; end
+
+ class Network::AuthStore
+ include Puppet::Util::Logging
+
+ # Mark a given pattern as allowed.
+ def allow(pattern)
+ # a simple way to allow anyone at all to connect
+ if pattern == "*"
+ @globalallow = true
+ else
+ store(:allow, pattern)
+ end
+
+ nil
+ end
- # Is a given combination of name and ip address allowed? If either input
- # is non-nil, then both inputs must be provided. If neither input
- # is provided, then the authstore is considered local and defaults to "true".
- def allowed?(name, ip)
- if name or ip
- # This is probably unnecessary, and can cause some weirdnesses in
- # cases where we're operating over localhost but don't have a real
- # IP defined.
- raise Puppet::DevError, "Name and IP must be passed to 'allowed?'" unless name and ip
- # else, we're networked and such
- else
- # we're local
- return true
- end
-
- # yay insecure overrides
- return true if globalallow?
-
- if decl = declarations.find { |d| d.match?(name, ip) }
- return decl.result
- end
-
- info "defaulting to no access for #{name}"
- false
- end
+ # Is a given combination of name and ip address allowed? If either input
+ # is non-nil, then both inputs must be provided. If neither input
+ # is provided, then the authstore is considered local and defaults to "true".
+ def allowed?(name, ip)
+ if name or ip
+ # This is probably unnecessary, and can cause some weirdnesses in
+ # cases where we're operating over localhost but don't have a real
+ # IP defined.
+ raise Puppet::DevError, "Name and IP must be passed to 'allowed?'" unless name and ip
+ # else, we're networked and such
+ else
+ # we're local
+ return true
+ end
+
+ # yay insecure overrides
+ return true if globalallow?
+
+ if decl = declarations.find { |d| d.match?(name, ip) }
+ return decl.result
+ end
+
+ info "defaulting to no access for #{name}"
+ false
+ end
- # Deny a given pattern.
- def deny(pattern)
- store(:deny, pattern)
- end
+ # Deny a given pattern.
+ def deny(pattern)
+ store(:deny, pattern)
+ end
- # Is global allow enabled?
- def globalallow?
- @globalallow
- end
+ # Is global allow enabled?
+ def globalallow?
+ @globalallow
+ end
- # does this auth store has any rules?
- def empty?
- @globalallow.nil? && @declarations.size == 0
- end
+ # does this auth store has any rules?
+ def empty?
+ @globalallow.nil? && @declarations.size == 0
+ end
- def initialize
- @globalallow = nil
- @declarations = []
- end
+ def initialize
+ @globalallow = nil
+ @declarations = []
+ end
- def to_s
- "authstore"
- end
+ def to_s
+ "authstore"
+ end
- def interpolate(match)
- Thread.current[:declarations] = @declarations.collect { |ace| ace.interpolate(match) }.sort
- end
+ def interpolate(match)
+ Thread.current[:declarations] = @declarations.collect { |ace| ace.interpolate(match) }.sort
+ end
- def reset_interpolation
- Thread.current[:declarations] = nil
- end
+ def reset_interpolation
+ Thread.current[:declarations] = nil
+ end
- private
+ private
- # returns our ACEs list, but if we have a modification of it
- # in our current thread, let's return it
- # this is used if we want to override the this purely immutable list
- # by a modified version in a multithread safe way.
- def declarations
- Thread.current[:declarations] || @declarations
- end
+ # returns our ACEs list, but if we have a modification of it
+ # in our current thread, let's return it
+ # this is used if we want to override the this purely immutable list
+ # by a modified version in a multithread safe way.
+ def declarations
+ Thread.current[:declarations] || @declarations
+ end
- # Store the results of a pattern into our hash. Basically just
- # converts the pattern and sticks it into the hash.
- def store(type, pattern)
- @declarations << Declaration.new(type, pattern)
- @declarations.sort!
+ # Store the results of a pattern into our hash. Basically just
+ # converts the pattern and sticks it into the hash.
+ def store(type, pattern)
+ @declarations << Declaration.new(type, pattern)
+ @declarations.sort!
- nil
- end
+ nil
+ end
- # A single declaration. Stores the info for a given declaration,
- # provides the methods for determining whether a declaration matches,
- # and handles sorting the declarations appropriately.
- class Declaration
- include Puppet::Util
- include Comparable
-
- # The type of declaration: either :allow or :deny
- attr_reader :type
-
- # The name: :ip or :domain
- attr_accessor :name
-
- # The pattern we're matching against. Can be an IPAddr instance,
- # or an array of strings, resulting from reversing a hostname
- # or domain name.
- attr_reader :pattern
-
- # The length. Only used for iprange and domain.
- attr_accessor :length
-
- # Sort the declarations most specific first.
- def <=>(other)
- compare(exact?, other.exact?) ||
- compare(ip?, other.ip?) ||
- ((length != other.length) && (other.length <=> length)) ||
- compare(deny?, other.deny?) ||
- ( ip? ? pattern.to_s <=> other.pattern.to_s : pattern <=> other.pattern)
- end
-
- def deny?
- type == :deny
- end
-
- def exact?
- @exact == :exact
- end
-
- def initialize(type, pattern)
- self.type = type
- self.pattern = pattern
- end
-
- # Are we an IP type?
- def ip?
- name == :ip
- end
-
- # Does this declaration match the name/ip combo?
- def match?(name, ip)
- ip? ? pattern.include?(IPAddr.new(ip)) : matchname?(name)
- end
-
- # Set the pattern appropriately. Also sets the name and length.
- def pattern=(pattern)
- parse(pattern)
- @orig = pattern
- end
-
- # Mapping a type of statement into a return value.
- def result
- type == :allow
- end
-
- def to_s
- "#{type}: #{pattern}"
- end
-
- # Set the declaration type. Either :allow or :deny.
- def type=(type)
- type = symbolize(type)
- raise ArgumentError, "Invalid declaration type #{type}" unless [:allow, :deny].include?(type)
- @type = type
- end
-
- # interpolate a pattern to replace any
- # backreferences by the given match
- # for instance if our pattern is $1.reductivelabs.com
- # and we're called with a MatchData whose capture 1 is puppet
- # we'll return a pattern of puppet.reductivelabs.com
- def interpolate(match)
- clone = dup
- clone.pattern = clone.pattern.reverse.collect do |p|
- p.gsub(/\$(\d)/) { |m| match[$1.to_i] }
- end.join(".")
- clone
- end
-
- private
-
- # Returns nil if both values are true or both are false, returns
- # -1 if the first is true, and 1 if the second is true. Used
- # in the <=> operator.
- def compare(me, them)
- (me and them) ? nil : me ? -1 : them ? 1 : nil
- end
-
- # Does the name match our pattern?
- def matchname?(name)
- name = munge_name(name)
- (pattern == name) or (not exact? and pattern.zip(name).all? { |p,n| p == n })
- end
-
- # Convert the name to a common pattern.
- def munge_name(name)
- # LAK:NOTE http://snurl.com/21zf8 [groups_google_com]
- # Change to name.downcase.split(".",-1).reverse for FQDN support
- name.downcase.split(".").reverse
- end
-
- # Parse our input pattern and figure out what kind of allowal
- # statement it is. The output of this is used for later matching.
- Octet = '(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])'
- IPv4 = "#{Octet}\.#{Octet}\.#{Octet}\.#{Octet}"
- IPv6_full = "_:_:_:_:_:_:_:_|_:_:_:_:_:_::_?|_:_:_:_:_::((_:)?_)?|_:_:_:_::((_:){0,2}_)?|_:_:_::((_:){0,3}_)?|_:_::((_:){0,4}_)?|_::((_:){0,5}_)?|::((_:){0,6}_)?"
- IPv6_partial = "_:_:_:_:_:_:|_:_:_:_::(_:)?|_:_::(_:){0,2}|_::(_:){0,3}"
- # It should be:
- # IP = "#{IPv4}|#{IPv6_full}|(#{IPv6_partial}#{IPv4})".gsub(/_/,'([0-9a-fA-F]{1,4})').gsub(/\(/,'(?:')
- # but ruby's ipaddr lib doesn't support the hybrid format
- IP = "#{IPv4}|#{IPv6_full}".gsub(/_/,'([0-9a-fA-F]{1,4})').gsub(/\(/,'(?:')
- def parse(value)
- @name, at exact, at length, at pattern = *case value
- when /^(?:#{IP})\/(\d+)$/ # 12.34.56.78/24, a001:b002::efff/120, c444:1000:2000::9:192.168.0.1/112
- [:ip,:inexact,$1.to_i,IPAddr.new(value)]
- when /^(#{IP})$/ # 10.20.30.40,
- [:ip,:exact,nil,IPAddr.new(value)]
- when /^(#{Octet}\.){1,3}\*$/ # an ip address with a '*' at the end
- segments = value.split(".")[0..-2]
- bits = 8*segments.length
- [:ip,:inexact,bits,IPAddr.new((segments+[0,0,0])[0,4].join(".") + "/#{bits}")]
- when /^(\w[-\w]*\.)+[-\w]+$/ # a full hostname
- # Change to /^(\w[-\w]*\.)+[-\w]+\.?$/ for FQDN support
- [:domain,:exact,nil,munge_name(value)]
- when /^\*(\.(\w[-\w]*)){1,}$/ # *.domain.com
- host_sans_star = munge_name(value)[0..-2]
- [:domain,:inexact,host_sans_star.length,host_sans_star]
- when /\$\d+/ # a backreference pattern ala $1.reductivelabs.com or 192.168.0.$1 or $1.$2
- [:dynamic,:exact,nil,munge_name(value)]
- when /^\w[-.@\w]*$/ # ? Just like a host name but allow '@'s and ending '.'s
- [:opaque,:exact,nil,[value]]
- else
- raise AuthStoreError, "Invalid pattern #{value}"
- end
- end
+ # A single declaration. Stores the info for a given declaration,
+ # provides the methods for determining whether a declaration matches,
+ # and handles sorting the declarations appropriately.
+ class Declaration
+ include Puppet::Util
+ include Comparable
+
+ # The type of declaration: either :allow or :deny
+ attr_reader :type
+
+ # The name: :ip or :domain
+ attr_accessor :name
+
+ # The pattern we're matching against. Can be an IPAddr instance,
+ # or an array of strings, resulting from reversing a hostname
+ # or domain name.
+ attr_reader :pattern
+
+ # The length. Only used for iprange and domain.
+ attr_accessor :length
+
+ # Sort the declarations most specific first.
+ def <=>(other)
+ compare(exact?, other.exact?) ||
+ compare(ip?, other.ip?) ||
+ ((length != other.length) && (other.length <=> length)) ||
+ compare(deny?, other.deny?) ||
+ ( ip? ? pattern.to_s <=> other.pattern.to_s : pattern <=> other.pattern)
+ end
+
+ def deny?
+ type == :deny
+ end
+
+ def exact?
+ @exact == :exact
+ end
+
+ def initialize(type, pattern)
+ self.type = type
+ self.pattern = pattern
+ end
+
+ # Are we an IP type?
+ def ip?
+ name == :ip
+ end
+
+ # Does this declaration match the name/ip combo?
+ def match?(name, ip)
+ ip? ? pattern.include?(IPAddr.new(ip)) : matchname?(name)
+ end
+
+ # Set the pattern appropriately. Also sets the name and length.
+ def pattern=(pattern)
+ parse(pattern)
+ @orig = pattern
+ end
+
+ # Mapping a type of statement into a return value.
+ def result
+ type == :allow
+ end
+
+ def to_s
+ "#{type}: #{pattern}"
+ end
+
+ # Set the declaration type. Either :allow or :deny.
+ def type=(type)
+ type = symbolize(type)
+ raise ArgumentError, "Invalid declaration type #{type}" unless [:allow, :deny].include?(type)
+ @type = type
+ end
+
+ # interpolate a pattern to replace any
+ # backreferences by the given match
+ # for instance if our pattern is $1.reductivelabs.com
+ # and we're called with a MatchData whose capture 1 is puppet
+ # we'll return a pattern of puppet.reductivelabs.com
+ def interpolate(match)
+ clone = dup
+ clone.pattern = clone.pattern.reverse.collect do |p|
+ p.gsub(/\$(\d)/) { |m| match[$1.to_i] }
+ end.join(".")
+ clone
+ end
+
+ private
+
+ # Returns nil if both values are true or both are false, returns
+ # -1 if the first is true, and 1 if the second is true. Used
+ # in the <=> operator.
+ def compare(me, them)
+ (me and them) ? nil : me ? -1 : them ? 1 : nil
+ end
+
+ # Does the name match our pattern?
+ def matchname?(name)
+ name = munge_name(name)
+ (pattern == name) or (not exact? and pattern.zip(name).all? { |p,n| p == n })
+ end
+
+ # Convert the name to a common pattern.
+ def munge_name(name)
+ # LAK:NOTE http://snurl.com/21zf8 [groups_google_com]
+ # Change to name.downcase.split(".",-1).reverse for FQDN support
+ name.downcase.split(".").reverse
+ end
+
+ # Parse our input pattern and figure out what kind of allowal
+ # statement it is. The output of this is used for later matching.
+ Octet = '(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])'
+ IPv4 = "#{Octet}\.#{Octet}\.#{Octet}\.#{Octet}"
+ IPv6_full = "_:_:_:_:_:_:_:_|_:_:_:_:_:_::_?|_:_:_:_:_::((_:)?_)?|_:_:_:_::((_:){0,2}_)?|_:_:_::((_:){0,3}_)?|_:_::((_:){0,4}_)?|_::((_:){0,5}_)?|::((_:){0,6}_)?"
+ IPv6_partial = "_:_:_:_:_:_:|_:_:_:_::(_:)?|_:_::(_:){0,2}|_::(_:){0,3}"
+ # It should be:
+ # IP = "#{IPv4}|#{IPv6_full}|(#{IPv6_partial}#{IPv4})".gsub(/_/,'([0-9a-fA-F]{1,4})').gsub(/\(/,'(?:')
+ # but ruby's ipaddr lib doesn't support the hybrid format
+ IP = "#{IPv4}|#{IPv6_full}".gsub(/_/,'([0-9a-fA-F]{1,4})').gsub(/\(/,'(?:')
+ def parse(value)
+ @name, at exact, at length, at pattern = *case value
+ when /^(?:#{IP})\/(\d+)$/ # 12.34.56.78/24, a001:b002::efff/120, c444:1000:2000::9:192.168.0.1/112
+ [:ip,:inexact,$1.to_i,IPAddr.new(value)]
+ when /^(#{IP})$/ # 10.20.30.40,
+ [:ip,:exact,nil,IPAddr.new(value)]
+ when /^(#{Octet}\.){1,3}\*$/ # an ip address with a '*' at the end
+ segments = value.split(".")[0..-2]
+ bits = 8*segments.length
+ [:ip,:inexact,bits,IPAddr.new((segments+[0,0,0])[0,4].join(".") + "/#{bits}")]
+ when /^(\w[-\w]*\.)+[-\w]+$/ # a full hostname
+ # Change to /^(\w[-\w]*\.)+[-\w]+\.?$/ for FQDN support
+ [:domain,:exact,nil,munge_name(value)]
+ when /^\*(\.(\w[-\w]*)){1,}$/ # *.domain.com
+ host_sans_star = munge_name(value)[0..-2]
+ [:domain,:inexact,host_sans_star.length,host_sans_star]
+ when /\$\d+/ # a backreference pattern ala $1.reductivelabs.com or 192.168.0.$1 or $1.$2
+ [:dynamic,:exact,nil,munge_name(value)]
+ when /^\w[-.@\w]*$/ # ? Just like a host name but allow '@'s and ending '.'s
+ [:opaque,:exact,nil,[value]]
+ else
+ raise AuthStoreError, "Invalid pattern #{value}"
end
+ end
end
+ end
end
diff --git a/lib/puppet/network/client.rb b/lib/puppet/network/client.rb
index e406ae8..cd88b9d 100644
--- a/lib/puppet/network/client.rb
+++ b/lib/puppet/network/client.rb
@@ -13,167 +13,167 @@ require 'net/http'
# Some versions of ruby don't have this method defined, which basically causes
# us to never use ssl. Yay.
class Net::HTTP
- def use_ssl?
- if defined?(@use_ssl)
- @use_ssl
- else
- false
- end
+ def use_ssl?
+ if defined?(@use_ssl)
+ @use_ssl
+ else
+ false
end
+ end
- # JJM: This is a "backport" of sorts to older ruby versions which
- # do not have this accessor. See #896 for more information.
- attr_accessor :enable_post_connection_check unless Net::HTTP.instance_methods.include? "enable_post_connection_check"
+ # JJM: This is a "backport" of sorts to older ruby versions which
+ # do not have this accessor. See #896 for more information.
+ attr_accessor :enable_post_connection_check unless Net::HTTP.instance_methods.include? "enable_post_connection_check"
end
# The base class for all of the clients. Many clients just directly
# call methods, but some of them need to do some extra work or
# provide a different interface.
class Puppet::Network::Client
- Client = self
- include Puppet::Util
- extend Puppet::Util::SubclassLoader
- include Puppet::Util::MethodHelper
-
- # This handles reading in the key and such-like.
- include Puppet::SSLCertificates::Support
-
- attr_accessor :schedule, :lastrun, :local, :stopping
-
- attr_reader :driver
-
- # Set up subclass loading
- handle_subclasses :client, "puppet/network/client"
-
- # Determine what clients look for when being passed an object for local
- # client/server stuff. E.g., you could call Client::CA.new(:CA => ca).
- def self.drivername
- @drivername ||= self.name
+ Client = self
+ include Puppet::Util
+ extend Puppet::Util::SubclassLoader
+ include Puppet::Util::MethodHelper
+
+ # This handles reading in the key and such-like.
+ include Puppet::SSLCertificates::Support
+
+ attr_accessor :schedule, :lastrun, :local, :stopping
+
+ attr_reader :driver
+
+ # Set up subclass loading
+ handle_subclasses :client, "puppet/network/client"
+
+ # Determine what clients look for when being passed an object for local
+ # client/server stuff. E.g., you could call Client::CA.new(:CA => ca).
+ def self.drivername
+ @drivername ||= self.name
+ end
+
+ # Figure out the handler for our client.
+ def self.handler
+ @handler ||= Puppet::Network::Handler.handler(self.name)
+ end
+
+ # The class that handles xmlrpc interaction for us.
+ def self.xmlrpc_client
+ @xmlrpc_client ||= Puppet::Network::XMLRPCClient.handler_class(self.handler)
+ end
+
+ # Create our client.
+ def initialize(hash)
+ # to whom do we connect?
+ @server = nil
+
+ if hash.include?(:Cache)
+ @cache = hash[:Cache]
+ else
+ @cache = true
end
- # Figure out the handler for our client.
- def self.handler
- @handler ||= Puppet::Network::Handler.handler(self.name)
+ driverparam = self.class.drivername
+ if hash.include?(:Server)
+ args = {:Server => hash[:Server]}
+ @server = hash[:Server]
+ args[:Port] = hash[:Port] || Puppet[:masterport]
+
+ @driver = self.class.xmlrpc_client.new(args)
+
+ self.read_cert
+
+ # We have to start the HTTP connection manually before we start
+ # sending it requests or keep-alive won't work. Note that with #1010,
+ # we don't currently actually want keep-alive.
+ @driver.start if @driver.respond_to? :start and Puppet::Network::HttpPool.keep_alive?
+
+ @local = false
+ elsif hash.include?(driverparam)
+ @driver = hash[driverparam]
+ if @driver == true
+ @driver = self.class.handler.new
+ end
+ @local = true
+ else
+ raise Puppet::Network::ClientError, "#{self.class} must be passed a Server or #{driverparam}"
end
-
- # The class that handles xmlrpc interaction for us.
- def self.xmlrpc_client
- @xmlrpc_client ||= Puppet::Network::XMLRPCClient.handler_class(self.handler)
+ end
+
+ # Are we a local client?
+ def local?
+ if @local
+ true
+ else
+ false
end
-
- # Create our client.
- def initialize(hash)
- # to whom do we connect?
- @server = nil
-
- if hash.include?(:Cache)
- @cache = hash[:Cache]
- else
- @cache = true
- end
-
- driverparam = self.class.drivername
- if hash.include?(:Server)
- args = {:Server => hash[:Server]}
- @server = hash[:Server]
- args[:Port] = hash[:Port] || Puppet[:masterport]
-
- @driver = self.class.xmlrpc_client.new(args)
-
- self.read_cert
-
- # We have to start the HTTP connection manually before we start
- # sending it requests or keep-alive won't work. Note that with #1010,
- # we don't currently actually want keep-alive.
- @driver.start if @driver.respond_to? :start and Puppet::Network::HttpPool.keep_alive?
-
- @local = false
- elsif hash.include?(driverparam)
- @driver = hash[driverparam]
- if @driver == true
- @driver = self.class.handler.new
- end
- @local = true
- else
- raise Puppet::Network::ClientError, "#{self.class} must be passed a Server or #{driverparam}"
- end
+ end
+
+ # Make sure we set the driver up when we read the cert in.
+ def recycle_connection
+ @driver.recycle_connection if @driver.respond_to?(:recycle_connection)
+ end
+
+ # A wrapper method to run and then store the last run time
+ def runnow
+ if self.stopping
+ Puppet.notice "In shutdown progress; skipping run"
+ return
end
-
- # Are we a local client?
- def local?
- if @local
- true
- else
- false
- end
+ begin
+ self.run
+ self.lastrun = Time.now.to_i
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Could not run #{self.class}: #{detail}"
end
+ end
- # Make sure we set the driver up when we read the cert in.
- def recycle_connection
- @driver.recycle_connection if @driver.respond_to?(:recycle_connection)
- end
+ def run
+ raise Puppet::DevError, "Client type #{self.class} did not override run"
+ end
- # A wrapper method to run and then store the last run time
- def runnow
- if self.stopping
- Puppet.notice "In shutdown progress; skipping run"
- return
- end
- begin
- self.run
- self.lastrun = Time.now.to_i
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Could not run #{self.class}: #{detail}"
- end
+ def scheduled?
+ if sched = self.schedule
+ return sched.match?(self.lastrun)
+ else
+ return true
end
-
- def run
- raise Puppet::DevError, "Client type #{self.class} did not override run"
+ end
+
+ def shutdown
+ if self.stopping
+ Puppet.notice "Already in shutdown"
+ else
+ self.stopping = true
+ Puppet::Util::Storage.store if self.respond_to? :running? and self.running?
+ rmpidfile
end
+ end
- def scheduled?
- if sched = self.schedule
- return sched.match?(self.lastrun)
- else
- return true
- end
- end
+ # Start listening for events. We're pretty much just listening for
+ # timer events here.
+ def start
+ # Create our timer. Puppet will handle observing it and such.
- def shutdown
- if self.stopping
- Puppet.notice "Already in shutdown"
- else
- self.stopping = true
- Puppet::Util::Storage.store if self.respond_to? :running? and self.running?
- rmpidfile
- end
- end
-
- # Start listening for events. We're pretty much just listening for
- # timer events here.
- def start
- # Create our timer. Puppet will handle observing it and such.
-
- timer = Puppet.newtimer(
+ timer = Puppet.newtimer(
- :interval => Puppet[:runinterval],
- :tolerance => 1,
+ :interval => Puppet[:runinterval],
+ :tolerance => 1,
- :start? => true
- ) do
- begin
- self.runnow if self.scheduled?
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Could not run client; got otherwise uncaught exception: #{detail}"
- end
- end
-
- # Run once before we start following the timer
- self.runnow
+ :start? => true
+ ) do
+ begin
+ self.runnow if self.scheduled?
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Could not run client; got otherwise uncaught exception: #{detail}"
+ end
end
- require 'puppet/network/client/proxy'
+ # Run once before we start following the timer
+ self.runnow
+ end
+
+ require 'puppet/network/client/proxy'
end
diff --git a/lib/puppet/network/client/ca.rb b/lib/puppet/network/client/ca.rb
index ca5c7d5..4c0177d 100644
--- a/lib/puppet/network/client/ca.rb
+++ b/lib/puppet/network/client/ca.rb
@@ -2,55 +2,55 @@ require 'puppet/network/client'
# Request a certificate from the remote system.
class Puppet::Network::Client::CA < Puppet::Network::Client
- class InvalidCertificate < Puppet::Error; end
-
- def initialize(options = {})
- options = symbolize_options(options)
- unless options.include?(:Server) or options.include?(:CA)
- options[:Server] = Puppet[:ca_server]
- options[:Port] = Puppet[:ca_port]
- end
- super(options)
+ class InvalidCertificate < Puppet::Error; end
+
+ def initialize(options = {})
+ options = symbolize_options(options)
+ unless options.include?(:Server) or options.include?(:CA)
+ options[:Server] = Puppet[:ca_server]
+ options[:Port] = Puppet[:ca_port]
+ end
+ super(options)
+ end
+
+ # This client is really only able to request certificates for the
+ # current host. It uses the Puppet.settings settings to figure everything out.
+ def request_cert
+ Puppet.settings.use(:main, :ssl)
+
+ if cert = read_cert
+ return cert
+ end
+
+ begin
+ cert, cacert = @driver.getcert(csr.to_pem)
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ raise Puppet::Error.new("Certificate retrieval failed: #{detail}")
end
- # This client is really only able to request certificates for the
- # current host. It uses the Puppet.settings settings to figure everything out.
- def request_cert
- Puppet.settings.use(:main, :ssl)
-
- if cert = read_cert
- return cert
- end
-
- begin
- cert, cacert = @driver.getcert(csr.to_pem)
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- raise Puppet::Error.new("Certificate retrieval failed: #{detail}")
- end
-
- if cert.nil? or cert == ""
- return nil
- end
-
- begin
- @cert = OpenSSL::X509::Certificate.new(cert)
- @cacert = OpenSSL::X509::Certificate.new(cacert)
- rescue => detail
- raise InvalidCertificate.new(
- "Invalid certificate: #{detail}"
- )
- end
-
- unless @cert.check_private_key(key)
- raise InvalidCertificate, "Certificate does not match private key. Try 'puppetca --clean #{Puppet[:certname]}' on the server."
- end
-
- # Only write the cert out if it passes validating.
- Puppet.settings.write(:hostcert) do |f| f.print cert end
- Puppet.settings.write(:localcacert) do |f| f.print cacert end
-
- @cert
+ if cert.nil? or cert == ""
+ return nil
end
+
+ begin
+ @cert = OpenSSL::X509::Certificate.new(cert)
+ @cacert = OpenSSL::X509::Certificate.new(cacert)
+ rescue => detail
+ raise InvalidCertificate.new(
+ "Invalid certificate: #{detail}"
+ )
+ end
+
+ unless @cert.check_private_key(key)
+ raise InvalidCertificate, "Certificate does not match private key. Try 'puppetca --clean #{Puppet[:certname]}' on the server."
+ end
+
+ # Only write the cert out if it passes validating.
+ Puppet.settings.write(:hostcert) do |f| f.print cert end
+ Puppet.settings.write(:localcacert) do |f| f.print cacert end
+
+ @cert
+ end
end
diff --git a/lib/puppet/network/client/file.rb b/lib/puppet/network/client/file.rb
index 6dd2ada..caafb75 100644
--- a/lib/puppet/network/client/file.rb
+++ b/lib/puppet/network/client/file.rb
@@ -1,6 +1,6 @@
class Puppet::Network::Client::File < Puppet::Network::Client::ProxyClient
- @handler = Puppet::Network::Handler.handler(:fileserver)
- @drivername = :FileServer
- self.mkmethods
+ @handler = Puppet::Network::Handler.handler(:fileserver)
+ @drivername = :FileServer
+ self.mkmethods
end
diff --git a/lib/puppet/network/client/proxy.rb b/lib/puppet/network/client/proxy.rb
index d3fc9d1..1d565a8 100644
--- a/lib/puppet/network/client/proxy.rb
+++ b/lib/puppet/network/client/proxy.rb
@@ -2,26 +2,26 @@
# is basically just a proxy class -- it calls its methods on the driver
# and that's about it
class Puppet::Network::Client::ProxyClient < Puppet::Network::Client
- def self.mkmethods
- interface = self.handler.interface
- namespace = interface.prefix
+ def self.mkmethods
+ interface = self.handler.interface
+ namespace = interface.prefix
- interface.methods.each { |ary|
- method = ary[0]
- Puppet.debug "#{self}: defining #{namespace}.#{method}"
- define_method(method) { |*args|
- begin
- @driver.send(method, *args)
- rescue XMLRPC::FaultException => detail
- #Puppet.err "Could not call %s.%s: %s" %
- # [namespace, method, detail.faultString]
- #raise NetworkClientError,
- # "XMLRPC Error: #{detail.faultString}"
- raise NetworkClientError, detail.faultString
- end
- }
- }
- end
+ interface.methods.each { |ary|
+ method = ary[0]
+ Puppet.debug "#{self}: defining #{namespace}.#{method}"
+ define_method(method) { |*args|
+ begin
+ @driver.send(method, *args)
+ rescue XMLRPC::FaultException => detail
+ #Puppet.err "Could not call %s.%s: %s" %
+ # [namespace, method, detail.faultString]
+ #raise NetworkClientError,
+ # "XMLRPC Error: #{detail.faultString}"
+ raise NetworkClientError, detail.faultString
+ end
+ }
+ }
+ end
end
diff --git a/lib/puppet/network/client/report.rb b/lib/puppet/network/client/report.rb
index f4a9cda..c9afaf9 100644
--- a/lib/puppet/network/client/report.rb
+++ b/lib/puppet/network/client/report.rb
@@ -1,26 +1,26 @@
class Puppet::Network::Client::Report < Puppet::Network::Client
- @handler = Puppet::Network::Handler.handler(:report)
+ @handler = Puppet::Network::Handler.handler(:report)
- def initialize(hash = {})
- hash[:Report] = self.class.handler.new if hash.include?(:Report)
+ def initialize(hash = {})
+ hash[:Report] = self.class.handler.new if hash.include?(:Report)
- super(hash)
- end
-
- # Send our report. We get the transaction report and convert it to YAML
- # as appropriate.
- def report(transreport)
- report = YAML.dump(transreport)
+ super(hash)
+ end
- report = CGI.escape(report) unless self.local
+ # Send our report. We get the transaction report and convert it to YAML
+ # as appropriate.
+ def report(transreport)
+ report = YAML.dump(transreport)
- # Now send the report
- file = nil
- benchmark(:info, "Sent transaction report") do
- file = @driver.report(report)
- end
+ report = CGI.escape(report) unless self.local
- file
+ # Now send the report
+ file = nil
+ benchmark(:info, "Sent transaction report") do
+ file = @driver.report(report)
end
+
+ file
+ end
end
diff --git a/lib/puppet/network/client/runner.rb b/lib/puppet/network/client/runner.rb
index 68005c9..a4596a7 100644
--- a/lib/puppet/network/client/runner.rb
+++ b/lib/puppet/network/client/runner.rb
@@ -1,10 +1,10 @@
class Puppet::Network::Client::Runner < Puppet::Network::Client::ProxyClient
- self.mkmethods
+ self.mkmethods
- def initialize(hash = {})
- hash[:Runner] = self.class.handler.new if hash.include?(:Runner)
+ def initialize(hash = {})
+ hash[:Runner] = self.class.handler.new if hash.include?(:Runner)
- super(hash)
- end
+ super(hash)
+ end
end
diff --git a/lib/puppet/network/client/status.rb b/lib/puppet/network/client/status.rb
index 9dc22b6..c24c7e3 100644
--- a/lib/puppet/network/client/status.rb
+++ b/lib/puppet/network/client/status.rb
@@ -1,4 +1,4 @@
class Puppet::Network::Client::Status < Puppet::Network::Client::ProxyClient
- self.mkmethods
+ self.mkmethods
end
diff --git a/lib/puppet/network/client_request.rb b/lib/puppet/network/client_request.rb
index f914bad..e3df471 100644
--- a/lib/puppet/network/client_request.rb
+++ b/lib/puppet/network/client_request.rb
@@ -1,29 +1,29 @@
module Puppet::Network # :nodoc:
- # A struct-like class for passing around a client request. It's mostly
- # just used for validation and authorization.
- class ClientRequest
- attr_accessor :name, :ip, :authenticated, :handler, :method
+ # A struct-like class for passing around a client request. It's mostly
+ # just used for validation and authorization.
+ class ClientRequest
+ attr_accessor :name, :ip, :authenticated, :handler, :method
- def authenticated?
- self.authenticated
- end
+ def authenticated?
+ self.authenticated
+ end
- # A common way of talking about the full call. Individual servers
- # are responsible for setting the values correctly, but this common
- # format makes it possible to check rights.
- def call
- raise ArgumentError, "Request is not set up; cannot build call" unless handler and method
+ # A common way of talking about the full call. Individual servers
+ # are responsible for setting the values correctly, but this common
+ # format makes it possible to check rights.
+ def call
+ raise ArgumentError, "Request is not set up; cannot build call" unless handler and method
- [handler, method].join(".")
- end
+ [handler, method].join(".")
+ end
- def initialize(name, ip, authenticated)
- @name, @ip, @authenticated = name, ip, authenticated
- end
+ def initialize(name, ip, authenticated)
+ @name, @ip, @authenticated = name, ip, authenticated
+ end
- def to_s
- "#{self.name}(#{self.ip})"
- end
+ def to_s
+ "#{self.name}(#{self.ip})"
end
+ end
end
diff --git a/lib/puppet/network/format.rb b/lib/puppet/network/format.rb
index 2b5b892..9cd6cf0 100644
--- a/lib/puppet/network/format.rb
+++ b/lib/puppet/network/format.rb
@@ -4,108 +4,108 @@ require 'puppet/provider/confiner'
# A simple class for modeling encoding formats for moving
# instances around the network.
class Puppet::Network::Format
- include Puppet::Provider::Confiner
-
- attr_reader :name, :mime
- attr_accessor :intern_method, :render_method, :intern_multiple_method, :render_multiple_method, :weight, :required_methods, :extension
-
- def init_attribute(name, default)
- if value = @options[name]
- @options.delete(name)
- else
- value = default
- end
- self.send(name.to_s + "=", value)
- end
-
- def initialize(name, options = {}, &block)
- @name = name.to_s.downcase.intern
+ include Puppet::Provider::Confiner
- @options = options
+ attr_reader :name, :mime
+ attr_accessor :intern_method, :render_method, :intern_multiple_method, :render_multiple_method, :weight, :required_methods, :extension
- # This must be done early the values can be used to set required_methods
- define_method_names
+ def init_attribute(name, default)
+ if value = @options[name]
+ @options.delete(name)
+ else
+ value = default
+ end
+ self.send(name.to_s + "=", value)
+ end
- method_list = {
- :intern_method => "from_#{name}",
- :intern_multiple_method => "from_multiple_#{name}",
- :render_multiple_method => "to_multiple_#{name}",
- :render_method => "to_#{name}"
- }
+ def initialize(name, options = {}, &block)
+ @name = name.to_s.downcase.intern
- init_attribute(:mime, "text/#{name}")
- init_attribute(:weight, 5)
- init_attribute(:required_methods, method_list.keys)
- init_attribute(:extension, name.to_s)
+ @options = options
- method_list.each do |method, value|
- init_attribute(method, value)
- end
+ # This must be done early the values can be used to set required_methods
+ define_method_names
- raise ArgumentError, "Unsupported option(s) #{@options.keys}" unless @options.empty?
+ method_list = {
+ :intern_method => "from_#{name}",
+ :intern_multiple_method => "from_multiple_#{name}",
+ :render_multiple_method => "to_multiple_#{name}",
+ :render_method => "to_#{name}"
+ }
- @options = nil
+ init_attribute(:mime, "text/#{name}")
+ init_attribute(:weight, 5)
+ init_attribute(:required_methods, method_list.keys)
+ init_attribute(:extension, name.to_s)
- instance_eval(&block) if block_given?
+ method_list.each do |method, value|
+ init_attribute(method, value)
end
- def intern(klass, text)
- return klass.send(intern_method, text) if klass.respond_to?(intern_method)
- raise NotImplementedError, "#{klass} does not respond to #{intern_method}; can not intern instances from #{mime}"
- end
+ raise ArgumentError, "Unsupported option(s) #{@options.keys}" unless @options.empty?
- def intern_multiple(klass, text)
- return klass.send(intern_multiple_method, text) if klass.respond_to?(intern_multiple_method)
- raise NotImplementedError, "#{klass} does not respond to #{intern_multiple_method}; can not intern multiple instances from #{mime}"
- end
+ @options = nil
- def mime=(mime)
- @mime = mime.to_s.downcase
- end
+ instance_eval(&block) if block_given?
+ end
- def render(instance)
- return instance.send(render_method) if instance.respond_to?(render_method)
- raise NotImplementedError, "#{instance.class} does not respond to #{render_method}; can not render instances to #{mime}"
- end
+ def intern(klass, text)
+ return klass.send(intern_method, text) if klass.respond_to?(intern_method)
+ raise NotImplementedError, "#{klass} does not respond to #{intern_method}; can not intern instances from #{mime}"
+ end
- def render_multiple(instances)
- # This method implicitly assumes that all instances are of the same type.
- return instances[0].class.send(render_multiple_method, instances) if instances[0].class.respond_to?(render_multiple_method)
- raise NotImplementedError, "#{instances[0].class} does not respond to #{render_multiple_method}; can not intern multiple instances to #{mime}"
- end
+ def intern_multiple(klass, text)
+ return klass.send(intern_multiple_method, text) if klass.respond_to?(intern_multiple_method)
+ raise NotImplementedError, "#{klass} does not respond to #{intern_multiple_method}; can not intern multiple instances from #{mime}"
+ end
- def required_methods_present?(klass)
- [:intern_method, :intern_multiple_method, :render_multiple_method].each do |name|
- return false unless required_method_present?(name, klass, :class)
- end
+ def mime=(mime)
+ @mime = mime.to_s.downcase
+ end
- return false unless required_method_present?(:render_method, klass, :instance)
+ def render(instance)
+ return instance.send(render_method) if instance.respond_to?(render_method)
+ raise NotImplementedError, "#{instance.class} does not respond to #{render_method}; can not render instances to #{mime}"
+ end
- true
- end
+ def render_multiple(instances)
+ # This method implicitly assumes that all instances are of the same type.
+ return instances[0].class.send(render_multiple_method, instances) if instances[0].class.respond_to?(render_multiple_method)
+ raise NotImplementedError, "#{instances[0].class} does not respond to #{render_multiple_method}; can not intern multiple instances to #{mime}"
+ end
- def supported?(klass)
- suitable? and required_methods_present?(klass)
+ def required_methods_present?(klass)
+ [:intern_method, :intern_multiple_method, :render_multiple_method].each do |name|
+ return false unless required_method_present?(name, klass, :class)
end
- def to_s
- "Puppet::Network::Format[#{name}]"
- end
+ return false unless required_method_present?(:render_method, klass, :instance)
- private
+ true
+ end
- def define_method_names
- @intern_method = "from_#{name}"
- @render_method = "to_#{name}"
- @intern_multiple_method = "from_multiple_#{name}"
- @render_multiple_method = "to_multiple_#{name}"
- end
+ def supported?(klass)
+ suitable? and required_methods_present?(klass)
+ end
- def required_method_present?(name, klass, type)
- return true unless required_methods.include?(name)
+ def to_s
+ "Puppet::Network::Format[#{name}]"
+ end
- method = send(name)
+ private
- return(type == :class ? klass.respond_to?(method) : klass.instance_methods.include?(method))
- end
+ def define_method_names
+ @intern_method = "from_#{name}"
+ @render_method = "to_#{name}"
+ @intern_multiple_method = "from_multiple_#{name}"
+ @render_multiple_method = "to_multiple_#{name}"
+ end
+
+ def required_method_present?(name, klass, type)
+ return true unless required_methods.include?(name)
+
+ method = send(name)
+
+ return(type == :class ? klass.respond_to?(method) : klass.instance_methods.include?(method))
+ end
end
diff --git a/lib/puppet/network/format_handler.rb b/lib/puppet/network/format_handler.rb
index b5817d5..d378ad6 100644
--- a/lib/puppet/network/format_handler.rb
+++ b/lib/puppet/network/format_handler.rb
@@ -3,173 +3,173 @@ require 'puppet/network'
require 'puppet/network/format'
module Puppet::Network::FormatHandler
- class FormatError < Puppet::Error; end
+ class FormatError < Puppet::Error; end
+
+ class FormatProtector
+ attr_reader :format
+
+ def protect(method, args)
+ Puppet::Network::FormatHandler.format(format).send(method, *args)
+ rescue => details
+ direction = method.to_s.include?("intern") ? "from" : "to"
+ error = FormatError.new("Could not #{method} #{direction} #{format}: #{details}")
+ error.set_backtrace(details.backtrace)
+ raise error
+ end
- class FormatProtector
- attr_reader :format
+ def initialize(format)
+ @format = format
+ end
- def protect(method, args)
- Puppet::Network::FormatHandler.format(format).send(method, *args)
- rescue => details
- direction = method.to_s.include?("intern") ? "from" : "to"
- error = FormatError.new("Could not #{method} #{direction} #{format}: #{details}")
- error.set_backtrace(details.backtrace)
- raise error
- end
+ [:intern, :intern_multiple, :render, :render_multiple, :mime].each do |method|
+ define_method(method) do |*args|
+ protect(method, args)
+ end
+ end
+ end
- def initialize(format)
- @format = format
- end
+ @formats = {}
+ def self.create(*args, &block)
+ instance = Puppet::Network::Format.new(*args)
+ instance.instance_eval(&block) if block_given?
- [:intern, :intern_multiple, :render, :render_multiple, :mime].each do |method|
- define_method(method) do |*args|
- protect(method, args)
- end
- end
- end
+ @formats[instance.name] = instance
+ instance
+ end
- @formats = {}
- def self.create(*args, &block)
- instance = Puppet::Network::Format.new(*args)
- instance.instance_eval(&block) if block_given?
+ def self.extended(klass)
+ klass.extend(ClassMethods)
- @formats[instance.name] = instance
- instance
- end
+ # LAK:NOTE This won't work in 1.9 ('send' won't be able to send
+ # private methods, but I don't know how else to do it.
+ klass.send(:include, InstanceMethods)
+ end
- def self.extended(klass)
- klass.extend(ClassMethods)
+ def self.format(name)
+ @formats[name.to_s.downcase.intern]
+ end
- # LAK:NOTE This won't work in 1.9 ('send' won't be able to send
- # private methods, but I don't know how else to do it.
- klass.send(:include, InstanceMethods)
+ def self.format_by_extension(ext)
+ @formats.each do |name, format|
+ return format if format.extension == ext
end
-
- def self.format(name)
- @formats[name.to_s.downcase.intern]
+ nil
+ end
+
+ # Provide a list of all formats.
+ def self.formats
+ @formats.keys
+ end
+
+ # Return a format capable of handling the provided mime type.
+ def self.mime(mimetype)
+ mimetype = mimetype.to_s.downcase
+ @formats.values.find { |format| format.mime == mimetype }
+ end
+
+ # Use a delegator to make sure any exceptions generated by our formats are
+ # handled intelligently.
+ def self.protected_format(name)
+ name = format_to_canonical_name(name)
+ @format_protectors ||= {}
+ @format_protectors[name] ||= FormatProtector.new(name)
+ @format_protectors[name]
+ end
+
+ # Return a format name given:
+ # * a format name
+ # * a mime-type
+ # * a format instance
+ def self.format_to_canonical_name(format)
+ case format
+ when Puppet::Network::Format
+ out = format
+ when %r{\w+/\w+}
+ out = mime(format)
+ else
+ out = format(format)
end
+ raise ArgumentError, "No format match the given format name or mime-type (#{format})" if out.nil?
+ out.name
+ end
- def self.format_by_extension(ext)
- @formats.each do |name, format|
- return format if format.extension == ext
- end
- nil
+ module ClassMethods
+ def format_handler
+ Puppet::Network::FormatHandler
end
- # Provide a list of all formats.
- def self.formats
- @formats.keys
+ def convert_from(format, data)
+ format_handler.protected_format(format).intern(self, data)
end
- # Return a format capable of handling the provided mime type.
- def self.mime(mimetype)
- mimetype = mimetype.to_s.downcase
- @formats.values.find { |format| format.mime == mimetype }
+ def convert_from_multiple(format, data)
+ format_handler.protected_format(format).intern_multiple(self, data)
end
- # Use a delegator to make sure any exceptions generated by our formats are
- # handled intelligently.
- def self.protected_format(name)
- name = format_to_canonical_name(name)
- @format_protectors ||= {}
- @format_protectors[name] ||= FormatProtector.new(name)
- @format_protectors[name]
+ def render_multiple(format, instances)
+ format_handler.protected_format(format).render_multiple(instances)
end
- # Return a format name given:
- # * a format name
- # * a mime-type
- # * a format instance
- def self.format_to_canonical_name(format)
- case format
- when Puppet::Network::Format
- out = format
- when %r{\w+/\w+}
- out = mime(format)
- else
- out = format(format)
- end
- raise ArgumentError, "No format match the given format name or mime-type (#{format})" if out.nil?
- out.name
+ def default_format
+ supported_formats[0]
end
- module ClassMethods
- def format_handler
- Puppet::Network::FormatHandler
- end
-
- def convert_from(format, data)
- format_handler.protected_format(format).intern(self, data)
- end
+ def support_format?(name)
+ Puppet::Network::FormatHandler.format(name).supported?(self)
+ end
- def convert_from_multiple(format, data)
- format_handler.protected_format(format).intern_multiple(self, data)
- end
+ def supported_formats
+ result = format_handler.formats.collect { |f| format_handler.format(f) }.find_all { |f| f.supported?(self) }.collect { |f| f.name }.sort do |a, b|
+ # It's an inverse sort -- higher weight formats go first.
+ format_handler.format(b).weight <=> format_handler.format(a).weight
+ end
- def render_multiple(format, instances)
- format_handler.protected_format(format).render_multiple(instances)
- end
+ result = put_preferred_format_first(result)
- def default_format
- supported_formats[0]
- end
+ Puppet.debug "#{friendly_name} supports formats: #{result.map{ |f| f.to_s }.sort.join(' ')}; using #{result.first}"
- def support_format?(name)
- Puppet::Network::FormatHandler.format(name).supported?(self)
- end
+ result
+ end
- def supported_formats
- result = format_handler.formats.collect { |f| format_handler.format(f) }.find_all { |f| f.supported?(self) }.collect { |f| f.name }.sort do |a, b|
- # It's an inverse sort -- higher weight formats go first.
- format_handler.format(b).weight <=> format_handler.format(a).weight
- end
+ private
- result = put_preferred_format_first(result)
+ def friendly_name
+ if self.respond_to? :indirection
+ indirection.name
+ else
+ self
+ end
+ end
- Puppet.debug "#{friendly_name} supports formats: #{result.map{ |f| f.to_s }.sort.join(' ')}; using #{result.first}"
+ def put_preferred_format_first(list)
+ preferred_format = Puppet.settings[:preferred_serialization_format].to_sym
+ if list.include?(preferred_format)
+ list.delete(preferred_format)
+ list.unshift(preferred_format)
+ else
+ Puppet.debug "Value of 'preferred_serialization_format' (#{preferred_format}) is invalid for #{friendly_name}, using default (#{list.first})"
+ end
+ list
+ end
+ end
- result
- end
+ module InstanceMethods
+ def render(format = nil)
+ format ||= self.class.default_format
- private
+ Puppet::Network::FormatHandler.protected_format(format).render(self)
+ end
- def friendly_name
- if self.respond_to? :indirection
- indirection.name
- else
- self
- end
- end
+ def mime(format = nil)
+ format ||= self.class.default_format
- def put_preferred_format_first(list)
- preferred_format = Puppet.settings[:preferred_serialization_format].to_sym
- if list.include?(preferred_format)
- list.delete(preferred_format)
- list.unshift(preferred_format)
- else
- Puppet.debug "Value of 'preferred_serialization_format' (#{preferred_format}) is invalid for #{friendly_name}, using default (#{list.first})"
- end
- list
- end
+ Puppet::Network::FormatHandler.protected_format(format).mime
end
- module InstanceMethods
- def render(format = nil)
- format ||= self.class.default_format
-
- Puppet::Network::FormatHandler.protected_format(format).render(self)
- end
-
- def mime(format = nil)
- format ||= self.class.default_format
-
- Puppet::Network::FormatHandler.protected_format(format).mime
- end
-
- def support_format?(name)
- self.class.support_format?(name)
- end
+ def support_format?(name)
+ self.class.support_format?(name)
end
+ end
end
require 'puppet/network/formats'
diff --git a/lib/puppet/network/formats.rb b/lib/puppet/network/formats.rb
index 2d519ae..8a61ee6 100644
--- a/lib/puppet/network/formats.rb
+++ b/lib/puppet/network/formats.rb
@@ -1,161 +1,161 @@
require 'puppet/network/format_handler'
Puppet::Network::FormatHandler.create(:yaml, :mime => "text/yaml") do
- # Yaml doesn't need the class name; it's serialized.
- def intern(klass, text)
- YAML.load(text)
- end
-
- # Yaml doesn't need the class name; it's serialized.
- def intern_multiple(klass, text)
- YAML.load(text)
- end
-
- def render(instance)
- instance.to_yaml
- end
-
- # Yaml monkey-patches Array, so this works.
- def render_multiple(instances)
- instances.to_yaml
- end
-
- # Unlike core's yaml, ZAML should support 1.8.1 just fine
- def supported?(klass)
- true
- end
+ # Yaml doesn't need the class name; it's serialized.
+ def intern(klass, text)
+ YAML.load(text)
+ end
+
+ # Yaml doesn't need the class name; it's serialized.
+ def intern_multiple(klass, text)
+ YAML.load(text)
+ end
+
+ def render(instance)
+ instance.to_yaml
+ end
+
+ # Yaml monkey-patches Array, so this works.
+ def render_multiple(instances)
+ instances.to_yaml
+ end
+
+ # Unlike core's yaml, ZAML should support 1.8.1 just fine
+ def supported?(klass)
+ true
+ end
end
# This is a "special" format which is used for the moment only when sending facts
# as REST GET parameters (see Puppet::Configurer::FactHandler).
# This format combines a yaml serialization, then zlib compression and base64 encoding.
Puppet::Network::FormatHandler.create(:b64_zlib_yaml, :mime => "text/b64_zlib_yaml") do
- require 'base64'
+ require 'base64'
- def use_zlib?
- Puppet.features.zlib? && Puppet[:zlib]
- end
+ def use_zlib?
+ Puppet.features.zlib? && Puppet[:zlib]
+ end
- def requiring_zlib
- if use_zlib?
- yield
- else
- raise Puppet::Error, "the zlib library is not installed or is disabled."
- end
+ def requiring_zlib
+ if use_zlib?
+ yield
+ else
+ raise Puppet::Error, "the zlib library is not installed or is disabled."
end
+ end
- def intern(klass, text)
- decode(text)
- end
+ def intern(klass, text)
+ decode(text)
+ end
- def intern_multiple(klass, text)
- decode(text)
- end
+ def intern_multiple(klass, text)
+ decode(text)
+ end
- def render(instance)
- encode(instance.to_yaml)
- end
+ def render(instance)
+ encode(instance.to_yaml)
+ end
- def render_multiple(instances)
- encode(instances.to_yaml)
- end
+ def render_multiple(instances)
+ encode(instances.to_yaml)
+ end
- def supported?(klass)
- true
- end
+ def supported?(klass)
+ true
+ end
- def encode(text)
- requiring_zlib do
- Base64.encode64(Zlib::Deflate.deflate(text, Zlib::BEST_COMPRESSION))
- end
+ def encode(text)
+ requiring_zlib do
+ Base64.encode64(Zlib::Deflate.deflate(text, Zlib::BEST_COMPRESSION))
end
+ end
- def decode(yaml)
- requiring_zlib do
- YAML.load(Zlib::Inflate.inflate(Base64.decode64(yaml)))
- end
+ def decode(yaml)
+ requiring_zlib do
+ YAML.load(Zlib::Inflate.inflate(Base64.decode64(yaml)))
end
+ end
end
Puppet::Network::FormatHandler.create(:marshal, :mime => "text/marshal") do
- # Marshal doesn't need the class name; it's serialized.
- def intern(klass, text)
- Marshal.load(text)
- end
-
- # Marshal doesn't need the class name; it's serialized.
- def intern_multiple(klass, text)
- Marshal.load(text)
- end
-
- def render(instance)
- Marshal.dump(instance)
- end
-
- # Marshal monkey-patches Array, so this works.
- def render_multiple(instances)
- Marshal.dump(instances)
- end
-
- # Everything's supported
- def supported?(klass)
- true
- end
+ # Marshal doesn't need the class name; it's serialized.
+ def intern(klass, text)
+ Marshal.load(text)
+ end
+
+ # Marshal doesn't need the class name; it's serialized.
+ def intern_multiple(klass, text)
+ Marshal.load(text)
+ end
+
+ def render(instance)
+ Marshal.dump(instance)
+ end
+
+ # Marshal monkey-patches Array, so this works.
+ def render_multiple(instances)
+ Marshal.dump(instances)
+ end
+
+ # Everything's supported
+ def supported?(klass)
+ true
+ end
end
Puppet::Network::FormatHandler.create(:s, :mime => "text/plain", :extension => "txt")
# A very low-weight format so it'll never get chosen automatically.
Puppet::Network::FormatHandler.create(:raw, :mime => "application/x-raw", :weight => 1) do
- def intern_multiple(klass, text)
- raise NotImplementedError
- end
-
- def render_multiple(instances)
- raise NotImplementedError
- end
-
- # LAK:NOTE The format system isn't currently flexible enough to handle
- # what I need to support raw formats just for individual instances (rather
- # than both individual and collections), but we don't yet have enough data
- # to make a "correct" design.
- # So, we hack it so it works for singular but fail if someone tries it
- # on plurals.
- def supported?(klass)
- true
- end
+ def intern_multiple(klass, text)
+ raise NotImplementedError
+ end
+
+ def render_multiple(instances)
+ raise NotImplementedError
+ end
+
+ # LAK:NOTE The format system isn't currently flexible enough to handle
+ # what I need to support raw formats just for individual instances (rather
+ # than both individual and collections), but we don't yet have enough data
+ # to make a "correct" design.
+ # So, we hack it so it works for singular but fail if someone tries it
+ # on plurals.
+ def supported?(klass)
+ true
+ end
end
Puppet::Network::FormatHandler.create(:pson, :mime => "text/pson", :weight => 10, :required_methods => [:render_method, :intern_method]) do
- confine :true => Puppet.features.pson?
-
- def intern(klass, text)
- data_to_instance(klass, PSON.parse(text))
- end
-
- def intern_multiple(klass, text)
- PSON.parse(text).collect do |data|
- data_to_instance(klass, data)
- end
- end
-
- # PSON monkey-patches Array, so this works.
- def render_multiple(instances)
- instances.to_pson
- end
-
- # If they pass class information, we want to ignore it. By default,
- # we'll include class information but we won't rely on it - we don't
- # want class names to be required because we then can't change our
- # internal class names, which is bad.
- def data_to_instance(klass, data)
- if data.is_a?(Hash) and d = data['data']
- data = d
- end
- return data if data.is_a?(klass)
- klass.from_pson(data)
- end
+ confine :true => Puppet.features.pson?
+
+ def intern(klass, text)
+ data_to_instance(klass, PSON.parse(text))
+ end
+
+ def intern_multiple(klass, text)
+ PSON.parse(text).collect do |data|
+ data_to_instance(klass, data)
+ end
+ end
+
+ # PSON monkey-patches Array, so this works.
+ def render_multiple(instances)
+ instances.to_pson
+ end
+
+ # If they pass class information, we want to ignore it. By default,
+ # we'll include class information but we won't rely on it - we don't
+ # want class names to be required because we then can't change our
+ # internal class names, which is bad.
+ def data_to_instance(klass, data)
+ if data.is_a?(Hash) and d = data['data']
+ data = d
+ end
+ return data if data.is_a?(klass)
+ klass.from_pson(data)
+ end
end
# This is really only ever going to be used for Catalogs.
diff --git a/lib/puppet/network/handler.rb b/lib/puppet/network/handler.rb
index 4b741eb..3cad387 100644
--- a/lib/puppet/network/handler.rb
+++ b/lib/puppet/network/handler.rb
@@ -2,49 +2,49 @@ require 'puppet/util/docs'
require 'puppet/util/subclass_loader'
module Puppet::Network
- # The base class for the different handlers. The handlers are each responsible
- # for separate xmlrpc namespaces.
- class Handler
- extend Puppet::Util::Docs
-
- # This is so that the handlers can subclass just 'Handler', rather
- # then having to specify the full class path.
- Handler = self
- attr_accessor :server, :local
-
- extend Puppet::Util::SubclassLoader
- extend Puppet::Util
-
- handle_subclasses :handler, "puppet/network/handler"
-
- # Return the xmlrpc interface.
- def self.interface
- if defined?(@interface)
- return @interface
- else
- raise Puppet::DevError, "Handler #{self} has no defined interface"
- end
- end
-
- # Set/Determine whether we're a client- or server-side handler.
- def self.side(side = nil)
- if side
- side = side.intern if side.is_a?(String)
- raise ArgumentError, "Invalid side registration '#{side}' for #{self.name}" unless [:client, :server].include?(side)
- @side = side
- else
- @side ||= :server
- return @side
- end
- end
-
- # Create an empty init method with the same signature.
- def initialize(hash = {})
- end
-
- def local?
- self.local
- end
+ # The base class for the different handlers. The handlers are each responsible
+ # for separate xmlrpc namespaces.
+ class Handler
+ extend Puppet::Util::Docs
+
+ # This is so that the handlers can subclass just 'Handler', rather
+ # then having to specify the full class path.
+ Handler = self
+ attr_accessor :server, :local
+
+ extend Puppet::Util::SubclassLoader
+ extend Puppet::Util
+
+ handle_subclasses :handler, "puppet/network/handler"
+
+ # Return the xmlrpc interface.
+ def self.interface
+ if defined?(@interface)
+ return @interface
+ else
+ raise Puppet::DevError, "Handler #{self} has no defined interface"
+ end
end
+
+ # Set/Determine whether we're a client- or server-side handler.
+ def self.side(side = nil)
+ if side
+ side = side.intern if side.is_a?(String)
+ raise ArgumentError, "Invalid side registration '#{side}' for #{self.name}" unless [:client, :server].include?(side)
+ @side = side
+ else
+ @side ||= :server
+ return @side
+ end
+ end
+
+ # Create an empty init method with the same signature.
+ def initialize(hash = {})
+ end
+
+ def local?
+ self.local
+ end
+ end
end
diff --git a/lib/puppet/network/handler/ca.rb b/lib/puppet/network/handler/ca.rb
index 101cf6f..ebb6fc4 100644
--- a/lib/puppet/network/handler/ca.rb
+++ b/lib/puppet/network/handler/ca.rb
@@ -7,145 +7,145 @@ require 'xmlrpc/server'
# http://segment7.net/projects/ruby/QuickCert/
class Puppet::Network::Handler
- class CA < Handler
- attr_reader :ca
-
- desc "Provides an interface for signing CSRs. Accepts a CSR and returns
- the CA certificate and the signed certificate, or returns nil if
- the cert is not signed."
+ class CA < Handler
+ attr_reader :ca
+
+ desc "Provides an interface for signing CSRs. Accepts a CSR and returns
+ the CA certificate and the signed certificate, or returns nil if
+ the cert is not signed."
+
+ @interface = XMLRPC::Service::Interface.new("puppetca") { |iface|
+ iface.add_method("array getcert(csr)")
+ }
+
+ def autosign
+ if defined?(@autosign)
+ @autosign
+ else
+ Puppet[:autosign]
+ end
+ end
- @interface = XMLRPC::Service::Interface.new("puppetca") { |iface|
- iface.add_method("array getcert(csr)")
+ # FIXME autosign? should probably accept both hostnames and IP addresses
+ def autosign?(hostname)
+ # simple values are easy
+ if autosign == true or autosign == false
+ return autosign
+ end
+
+ # we only otherwise know how to handle files
+ unless autosign =~ /^\//
+ raise Puppet::Error, "Invalid autosign value #{autosign.inspect}"
+ end
+
+ unless FileTest.exists?(autosign)
+ unless defined?(@@warnedonautosign)
+ @@warnedonautosign = true
+ Puppet.info "Autosign is enabled but #{autosign} is missing"
+ end
+ return false
+ end
+ auth = Puppet::Network::AuthStore.new
+ File.open(autosign) { |f|
+ f.each { |line|
+ next if line =~ /^\s*#/
+ next if line =~ /^\s*$/
+ auth.allow(line.chomp)
}
+ }
- def autosign
- if defined?(@autosign)
- @autosign
- else
- Puppet[:autosign]
- end
- end
+ # for now, just cheat and pass a fake IP address to allowed?
+ auth.allowed?(hostname, "127.1.1.1")
+ end
- # FIXME autosign? should probably accept both hostnames and IP addresses
- def autosign?(hostname)
- # simple values are easy
- if autosign == true or autosign == false
- return autosign
- end
-
- # we only otherwise know how to handle files
- unless autosign =~ /^\//
- raise Puppet::Error, "Invalid autosign value #{autosign.inspect}"
- end
-
- unless FileTest.exists?(autosign)
- unless defined?(@@warnedonautosign)
- @@warnedonautosign = true
- Puppet.info "Autosign is enabled but #{autosign} is missing"
- end
- return false
- end
- auth = Puppet::Network::AuthStore.new
- File.open(autosign) { |f|
- f.each { |line|
- next if line =~ /^\s*#/
- next if line =~ /^\s*$/
- auth.allow(line.chomp)
- }
- }
-
- # for now, just cheat and pass a fake IP address to allowed?
- auth.allowed?(hostname, "127.1.1.1")
- end
+ def initialize(hash = {})
+ Puppet.settings.use(:main, :ssl, :ca)
+ @autosign = hash[:autosign] if hash.include? :autosign
- def initialize(hash = {})
- Puppet.settings.use(:main, :ssl, :ca)
- @autosign = hash[:autosign] if hash.include? :autosign
+ @ca = Puppet::SSLCertificates::CA.new(hash)
+ end
- @ca = Puppet::SSLCertificates::CA.new(hash)
- end
+ # our client sends us a csr, and we either store it for later signing,
+ # or we sign it right away
+ def getcert(csrtext, client = nil, clientip = nil)
+ csr = OpenSSL::X509::Request.new(csrtext)
+
+ # Use the hostname from the CSR, not from the network.
+ subject = csr.subject
+
+ nameary = subject.to_a.find { |ary|
+ ary[0] == "CN"
+ }
- # our client sends us a csr, and we either store it for later signing,
- # or we sign it right away
- def getcert(csrtext, client = nil, clientip = nil)
- csr = OpenSSL::X509::Request.new(csrtext)
-
- # Use the hostname from the CSR, not from the network.
- subject = csr.subject
-
- nameary = subject.to_a.find { |ary|
- ary[0] == "CN"
- }
-
- if nameary.nil?
- Puppet.err(
- "Invalid certificate request: could not retrieve server name"
- )
- return "invalid"
- end
-
- hostname = nameary[1]
-
- unless @ca
- Puppet.notice "Host #{hostname} asked for signing from non-CA master"
- return ""
- end
-
- # We used to save the public key, but it's basically unnecessary
- # and it mucks with the permissions requirements.
- # save_pk(hostname, csr.public_key)
-
- certfile = File.join(Puppet[:certdir], [hostname, "pem"].join("."))
-
- # first check to see if we already have a signed cert for the host
- cert, cacert = ca.getclientcert(hostname)
- if cert and cacert
- Puppet.info "Retrieving existing certificate for #{hostname}"
- unless csr.public_key.to_s == cert.public_key.to_s
- raise Puppet::Error, "Certificate request does not match existing certificate; run 'puppetca --clean #{hostname}'."
- end
- return [cert.to_pem, cacert.to_pem]
- elsif @ca
- if self.autosign?(hostname) or client.nil?
- Puppet.info "Signing certificate for CA server" if client.nil?
- # okay, we don't have a signed cert
- # if we're a CA and autosign is turned on, then go ahead and sign
- # the csr and return the results
- Puppet.info "Signing certificate for #{hostname}"
- cert, cacert = @ca.sign(csr)
- #Puppet.info "Cert: #{cert.class}; Cacert: #{cacert.class}"
- return [cert.to_pem, cacert.to_pem]
- else # just write out the csr for later signing
- if @ca.getclientcsr(hostname)
- Puppet.info "Not replacing existing request from #{hostname}"
- else
- Puppet.notice "Host #{hostname} has a waiting certificate request"
- @ca.storeclientcsr(csr)
- end
- return ["", ""]
- end
- else
- raise "huh?"
- end
+ if nameary.nil?
+ Puppet.err(
+ "Invalid certificate request: could not retrieve server name"
+ )
+ return "invalid"
+ end
+
+ hostname = nameary[1]
+
+ unless @ca
+ Puppet.notice "Host #{hostname} asked for signing from non-CA master"
+ return ""
+ end
+
+ # We used to save the public key, but it's basically unnecessary
+ # and it mucks with the permissions requirements.
+ # save_pk(hostname, csr.public_key)
+
+ certfile = File.join(Puppet[:certdir], [hostname, "pem"].join("."))
+
+ # first check to see if we already have a signed cert for the host
+ cert, cacert = ca.getclientcert(hostname)
+ if cert and cacert
+ Puppet.info "Retrieving existing certificate for #{hostname}"
+ unless csr.public_key.to_s == cert.public_key.to_s
+ raise Puppet::Error, "Certificate request does not match existing certificate; run 'puppetca --clean #{hostname}'."
end
+ return [cert.to_pem, cacert.to_pem]
+ elsif @ca
+ if self.autosign?(hostname) or client.nil?
+ Puppet.info "Signing certificate for CA server" if client.nil?
+ # okay, we don't have a signed cert
+ # if we're a CA and autosign is turned on, then go ahead and sign
+ # the csr and return the results
+ Puppet.info "Signing certificate for #{hostname}"
+ cert, cacert = @ca.sign(csr)
+ #Puppet.info "Cert: #{cert.class}; Cacert: #{cacert.class}"
+ return [cert.to_pem, cacert.to_pem]
+ else # just write out the csr for later signing
+ if @ca.getclientcsr(hostname)
+ Puppet.info "Not replacing existing request from #{hostname}"
+ else
+ Puppet.notice "Host #{hostname} has a waiting certificate request"
+ @ca.storeclientcsr(csr)
+ end
+ return ["", ""]
+ end
+ else
+ raise "huh?"
+ end
+ end
+
+ private
- private
-
- # Save the public key.
- def save_pk(hostname, public_key)
- pkeyfile = File.join(Puppet[:publickeydir], [hostname, "pem"].join('.'))
-
- if FileTest.exists?(pkeyfile)
- currentkey = File.open(pkeyfile) { |k| k.read }
- unless currentkey == public_key.to_s
- raise Puppet::Error, "public keys for #{hostname} differ"
- end
- else
- File.open(pkeyfile, "w", 0644) { |f|
- f.print public_key.to_s
- }
- end
+ # Save the public key.
+ def save_pk(hostname, public_key)
+ pkeyfile = File.join(Puppet[:publickeydir], [hostname, "pem"].join('.'))
+
+ if FileTest.exists?(pkeyfile)
+ currentkey = File.open(pkeyfile) { |k| k.read }
+ unless currentkey == public_key.to_s
+ raise Puppet::Error, "public keys for #{hostname} differ"
end
+ else
+ File.open(pkeyfile, "w", 0644) { |f|
+ f.print public_key.to_s
+ }
+ end
end
+ end
end
diff --git a/lib/puppet/network/handler/filebucket.rb b/lib/puppet/network/handler/filebucket.rb
index c0693ad..6aaa2df 100755
--- a/lib/puppet/network/handler/filebucket.rb
+++ b/lib/puppet/network/handler/filebucket.rb
@@ -3,49 +3,49 @@ require 'digest/md5'
require 'puppet/external/base64'
class Puppet::Network::Handler # :nodoc:
- # Accept files and store them by md5 sum, returning the md5 sum back
- # to the client. Alternatively, accept an md5 sum and return the
- # associated content.
- class FileBucket < Handler
- desc "The interface to Puppet's FileBucket system. Can be used to store
- files in and retrieve files from a filebucket."
-
- @interface = XMLRPC::Service::Interface.new("puppetbucket") { |iface|
- iface.add_method("string addfile(string, string)")
- iface.add_method("string getfile(string)")
- }
-
- Puppet::Util.logmethods(self, true)
- attr_reader :name, :path
-
- def initialize(hash)
- @path = hash[:Path] || Puppet[:bucketdir]
- @name = "Filebucket[#{@path}]"
- end
-
- # Accept a file from a client and store it by md5 sum, returning
- # the sum.
- def addfile(contents, path, client = nil, clientip = nil)
- contents = Base64.decode64(contents) if client
- bucket = Puppet::FileBucket::File.new(contents)
- bucket.save
- end
-
- # Return the contents associated with a given md5 sum.
- def getfile(md5, client = nil, clientip = nil)
- bucket = Puppet::FileBucket::File.find("md5:#{md5}")
- contents = bucket.contents
-
- if client
- return Base64.encode64(contents)
- else
- return contents
- end
- end
-
- def to_s
- self.name
- end
+ # Accept files and store them by md5 sum, returning the md5 sum back
+ # to the client. Alternatively, accept an md5 sum and return the
+ # associated content.
+ class FileBucket < Handler
+ desc "The interface to Puppet's FileBucket system. Can be used to store
+ files in and retrieve files from a filebucket."
+
+ @interface = XMLRPC::Service::Interface.new("puppetbucket") { |iface|
+ iface.add_method("string addfile(string, string)")
+ iface.add_method("string getfile(string)")
+ }
+
+ Puppet::Util.logmethods(self, true)
+ attr_reader :name, :path
+
+ def initialize(hash)
+ @path = hash[:Path] || Puppet[:bucketdir]
+ @name = "Filebucket[#{@path}]"
end
+
+ # Accept a file from a client and store it by md5 sum, returning
+ # the sum.
+ def addfile(contents, path, client = nil, clientip = nil)
+ contents = Base64.decode64(contents) if client
+ bucket = Puppet::FileBucket::File.new(contents)
+ bucket.save
+ end
+
+ # Return the contents associated with a given md5 sum.
+ def getfile(md5, client = nil, clientip = nil)
+ bucket = Puppet::FileBucket::File.find("md5:#{md5}")
+ contents = bucket.contents
+
+ if client
+ return Base64.encode64(contents)
+ else
+ return contents
+ end
+ end
+
+ def to_s
+ self.name
+ end
+ end
end
diff --git a/lib/puppet/network/handler/fileserver.rb b/lib/puppet/network/handler/fileserver.rb
index 0a50820..27b913a 100755
--- a/lib/puppet/network/handler/fileserver.rb
+++ b/lib/puppet/network/handler/fileserver.rb
@@ -9,717 +9,717 @@ require 'puppet/file_serving'
require 'puppet/file_serving/metadata'
class Puppet::Network::Handler
- AuthStoreError = Puppet::AuthStoreError
- class FileServerError < Puppet::Error; end
- class FileServer < Handler
- desc "The interface to Puppet's fileserving abilities."
+ AuthStoreError = Puppet::AuthStoreError
+ class FileServerError < Puppet::Error; end
+ class FileServer < Handler
+ desc "The interface to Puppet's fileserving abilities."
- attr_accessor :local
+ attr_accessor :local
- CHECKPARAMS = [:mode, :type, :owner, :group, :checksum]
+ CHECKPARAMS = [:mode, :type, :owner, :group, :checksum]
- # Special filserver module for puppet's module system
- MODULES = "modules"
- PLUGINS = "plugins"
+ # Special filserver module for puppet's module system
+ MODULES = "modules"
+ PLUGINS = "plugins"
- @interface = XMLRPC::Service::Interface.new("fileserver") { |iface|
- iface.add_method("string describe(string, string)")
- iface.add_method("string list(string, string, boolean, array)")
- iface.add_method("string retrieve(string, string)")
- }
+ @interface = XMLRPC::Service::Interface.new("fileserver") { |iface|
+ iface.add_method("string describe(string, string)")
+ iface.add_method("string list(string, string, boolean, array)")
+ iface.add_method("string retrieve(string, string)")
+ }
- def self.params
- CHECKPARAMS.dup
- end
+ def self.params
+ CHECKPARAMS.dup
+ end
- # If the configuration file exists, then create (if necessary) a LoadedFile
- # object to manage it; else, return nil.
- def configuration
- # Short-circuit the default case.
- return @configuration if defined?(@configuration)
+ # If the configuration file exists, then create (if necessary) a LoadedFile
+ # object to manage it; else, return nil.
+ def configuration
+ # Short-circuit the default case.
+ return @configuration if defined?(@configuration)
- config_path = @passed_configuration_path || Puppet[:fileserverconfig]
- return nil unless FileTest.exist?(config_path)
+ config_path = @passed_configuration_path || Puppet[:fileserverconfig]
+ return nil unless FileTest.exist?(config_path)
- # The file exists but we don't have a LoadedFile instance for it.
- @configuration = Puppet::Util::LoadedFile.new(config_path)
- end
+ # The file exists but we don't have a LoadedFile instance for it.
+ @configuration = Puppet::Util::LoadedFile.new(config_path)
+ end
- # Create our default mounts for modules and plugins. This is duplicated code,
- # but I'm not really worried about that.
- def create_default_mounts
- @mounts = {}
- Puppet.debug "No file server configuration file; autocreating #{MODULES} mount with default permissions"
- mount = Mount.new(MODULES)
- mount.allow("*")
- @mounts[MODULES] = mount
-
- Puppet.debug "No file server configuration file; autocreating #{PLUGINS} mount with default permissions"
- mount = PluginMount.new(PLUGINS)
- mount.allow("*")
- @mounts[PLUGINS] = mount
- end
+ # Create our default mounts for modules and plugins. This is duplicated code,
+ # but I'm not really worried about that.
+ def create_default_mounts
+ @mounts = {}
+ Puppet.debug "No file server configuration file; autocreating #{MODULES} mount with default permissions"
+ mount = Mount.new(MODULES)
+ mount.allow("*")
+ @mounts[MODULES] = mount
+
+ Puppet.debug "No file server configuration file; autocreating #{PLUGINS} mount with default permissions"
+ mount = PluginMount.new(PLUGINS)
+ mount.allow("*")
+ @mounts[PLUGINS] = mount
+ end
- # Describe a given file. This returns all of the manageable aspects
- # of that file.
- def describe(url, links = :follow, client = nil, clientip = nil)
- links = links.intern if links.is_a? String
+ # Describe a given file. This returns all of the manageable aspects
+ # of that file.
+ def describe(url, links = :follow, client = nil, clientip = nil)
+ links = links.intern if links.is_a? String
- mount, path = convert(url, client, clientip)
+ mount, path = convert(url, client, clientip)
- mount.debug("Describing #{url} for #{client}") if client
+ mount.debug("Describing #{url} for #{client}") if client
- # use the mount to resolve the path for us.
- return "" unless full_path = mount.file_path(path, client)
+ # use the mount to resolve the path for us.
+ return "" unless full_path = mount.file_path(path, client)
- metadata = Puppet::FileServing::Metadata.new(url, :path => full_path, :links => links)
+ metadata = Puppet::FileServing::Metadata.new(url, :path => full_path, :links => links)
- return "" unless metadata.exist?
+ return "" unless metadata.exist?
- begin
- metadata.collect
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err detail
- return ""
- end
+ begin
+ metadata.collect
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err detail
+ return ""
+ end
- metadata.attributes_with_tabs
- end
+ metadata.attributes_with_tabs
+ end
- # Create a new fileserving module.
- def initialize(hash = {})
- @mounts = {}
- @files = {}
+ # Create a new fileserving module.
+ def initialize(hash = {})
+ @mounts = {}
+ @files = {}
- @local = hash[:Local]
+ @local = hash[:Local]
- @noreadconfig = true if hash[:Config] == false
+ @noreadconfig = true if hash[:Config] == false
- @passed_configuration_path = hash[:Config]
+ @passed_configuration_path = hash[:Config]
- if hash.include?(:Mount)
- @passedconfig = true
- raise Puppet::DevError, "Invalid mount hash #{hash[:Mount].inspect}" unless hash[:Mount].is_a?(Hash)
+ if hash.include?(:Mount)
+ @passedconfig = true
+ raise Puppet::DevError, "Invalid mount hash #{hash[:Mount].inspect}" unless hash[:Mount].is_a?(Hash)
- hash[:Mount].each { |dir, name|
- self.mount(dir, name) if FileTest.exists?(dir)
- }
- self.mount(nil, MODULES)
- self.mount(nil, PLUGINS)
- else
- @passedconfig = false
- if configuration
- readconfig(false) # don't check the file the first time.
- else
- create_default_mounts
- end
- end
+ hash[:Mount].each { |dir, name|
+ self.mount(dir, name) if FileTest.exists?(dir)
+ }
+ self.mount(nil, MODULES)
+ self.mount(nil, PLUGINS)
+ else
+ @passedconfig = false
+ if configuration
+ readconfig(false) # don't check the file the first time.
+ else
+ create_default_mounts
end
+ end
+ end
- # List a specific directory's contents.
- def list(url, links = :ignore, recurse = false, ignore = false, client = nil, clientip = nil)
- mount, path = convert(url, client, clientip)
-
- mount.debug "Listing #{url} for #{client}" if client
+ # List a specific directory's contents.
+ def list(url, links = :ignore, recurse = false, ignore = false, client = nil, clientip = nil)
+ mount, path = convert(url, client, clientip)
- return "" unless mount.path_exists?(path, client)
+ mount.debug "Listing #{url} for #{client}" if client
- desc = mount.list(path, recurse, ignore, client)
+ return "" unless mount.path_exists?(path, client)
- if desc.length == 0
- mount.notice "Got no information on //#{mount}/#{path}"
- return ""
- end
-
- desc.collect { |sub| sub.join("\t") }.join("\n")
- end
+ desc = mount.list(path, recurse, ignore, client)
- def local?
- self.local
- end
+ if desc.length == 0
+ mount.notice "Got no information on //#{mount}/#{path}"
+ return ""
+ end
- # Is a given mount available?
- def mounted?(name)
- @mounts.include?(name)
- end
+ desc.collect { |sub| sub.join("\t") }.join("\n")
+ end
- # Mount a new directory with a name.
- def mount(path, name)
- if @mounts.include?(name)
- if @mounts[name] != path
- raise FileServerError, "#{@mounts[name].path} is already mounted at #{name}"
- else
- # it's already mounted; no problem
- return
- end
- end
+ def local?
+ self.local
+ end
- # Let the mounts do their own error-checking.
- @mounts[name] = Mount.new(name, path)
- @mounts[name].info "Mounted #{path}"
+ # Is a given mount available?
+ def mounted?(name)
+ @mounts.include?(name)
+ end
- @mounts[name]
+ # Mount a new directory with a name.
+ def mount(path, name)
+ if @mounts.include?(name)
+ if @mounts[name] != path
+ raise FileServerError, "#{@mounts[name].path} is already mounted at #{name}"
+ else
+ # it's already mounted; no problem
+ return
end
+ end
- # Retrieve a file from the local disk and pass it to the remote
- # client.
- def retrieve(url, links = :ignore, client = nil, clientip = nil)
- links = links.intern if links.is_a? String
-
- mount, path = convert(url, client, clientip)
+ # Let the mounts do their own error-checking.
+ @mounts[name] = Mount.new(name, path)
+ @mounts[name].info "Mounted #{path}"
- mount.info "Sending #{url} to #{client}" if client
-
- unless mount.path_exists?(path, client)
- mount.debug "#{mount} reported that #{path} does not exist"
- return ""
- end
-
- links = links.intern if links.is_a? String
+ @mounts[name]
+ end
- if links == :ignore and FileTest.symlink?(path)
- mount.debug "I think that #{path} is a symlink and we're ignoring them"
- return ""
- end
+ # Retrieve a file from the local disk and pass it to the remote
+ # client.
+ def retrieve(url, links = :ignore, client = nil, clientip = nil)
+ links = links.intern if links.is_a? String
- str = mount.read_file(path, client)
+ mount, path = convert(url, client, clientip)
- if @local
- return str
- else
- return CGI.escape(str)
- end
- end
+ mount.info "Sending #{url} to #{client}" if client
- def umount(name)
- @mounts.delete(name) if @mounts.include? name
- end
+ unless mount.path_exists?(path, client)
+ mount.debug "#{mount} reported that #{path} does not exist"
+ return ""
+ end
- private
+ links = links.intern if links.is_a? String
- def authcheck(file, mount, client, clientip)
- # If we're local, don't bother passing in information.
- if local?
- client = nil
- clientip = nil
- end
- unless mount.allowed?(client, clientip)
- mount.warning "#{client} cannot access #{file}"
- raise Puppet::AuthorizationError, "Cannot access #{mount}"
- end
- end
+ if links == :ignore and FileTest.symlink?(path)
+ mount.debug "I think that #{path} is a symlink and we're ignoring them"
+ return ""
+ end
- # Take a URL and some client info and return a mount and relative
- # path pair.
- #
- def convert(url, client, clientip)
- readconfig
+ str = mount.read_file(path, client)
- url = URI.unescape(url)
+ if @local
+ return str
+ else
+ return CGI.escape(str)
+ end
+ end
- mount, stub = splitpath(url, client)
+ def umount(name)
+ @mounts.delete(name) if @mounts.include? name
+ end
- authcheck(url, mount, client, clientip)
+ private
+
+ def authcheck(file, mount, client, clientip)
+ # If we're local, don't bother passing in information.
+ if local?
+ client = nil
+ clientip = nil
+ end
+ unless mount.allowed?(client, clientip)
+ mount.warning "#{client} cannot access #{file}"
+ raise Puppet::AuthorizationError, "Cannot access #{mount}"
+ end
+ end
- return mount, stub
- end
+ # Take a URL and some client info and return a mount and relative
+ # path pair.
+ #
+ def convert(url, client, clientip)
+ readconfig
- # Return the mount for the Puppet modules; allows file copying from
- # the modules.
- def modules_mount(module_name, client)
- # Find our environment, if we have one.
- unless hostname = (client || Facter.value("hostname"))
- raise ArgumentError, "Could not find hostname"
- end
- env = (node = Puppet::Node.find(hostname)) ? node.environment : nil
+ url = URI.unescape(url)
- # And use the environment to look up the module.
- (mod = Puppet::Node::Environment.new(env).module(module_name) and mod.files?) ? @mounts[MODULES].copy(mod.name, mod.file_directory) : nil
- end
+ mount, stub = splitpath(url, client)
- # Read the configuration file.
- def readconfig(check = true)
- return if @noreadconfig
-
- return unless configuration
-
- return if check and ! @configuration.changed?
-
- newmounts = {}
- begin
- File.open(@configuration.file) { |f|
- mount = nil
- count = 1
- f.each { |line|
- case line
- when /^\s*#/; next # skip comments
- when /^\s*$/; next # skip blank lines
- when /\[([-\w]+)\]/
- name = $1
- raise FileServerError, "#{newmounts[name]} is already mounted as #{name} in #{@configuration.file}" if newmounts.include?(name)
- mount = Mount.new(name)
- newmounts[name] = mount
- when /^\s*(\w+)\s+(.+)$/
- var = $1
- value = $2
- case var
- when "path"
- if mount.name == MODULES
- Puppet.warning "The '#{mount.name}' module can not have a path. Ignoring attempt to set it"
- else
- begin
- mount.path = value
- rescue FileServerError => detail
- Puppet.err "Removing mount #{mount.name}: #{detail}"
- newmounts.delete(mount.name)
- end
- end
- when "allow"
- value.split(/\s*,\s*/).each { |val|
- begin
- mount.info "allowing #{val} access"
- mount.allow(val)
- rescue AuthStoreError => detail
- puts detail.backtrace if Puppet[:trace]
-
- raise FileServerError.new(
- detail.to_s,
-
- count, @configuration.file)
- end
- }
- when "deny"
- value.split(/\s*,\s*/).each { |val|
- begin
- mount.info "denying #{val} access"
- mount.deny(val)
- rescue AuthStoreError => detail
-
- raise FileServerError.new(
- detail.to_s,
-
- count, @configuration.file)
- end
- }
- else
- raise FileServerError.new("Invalid argument '#{var}'", count, @configuration.file)
- end
- else
- raise FileServerError.new("Invalid line '#{line.chomp}'", count, @configuration.file)
- end
- count += 1
- }
- }
- rescue Errno::EACCES => detail
- Puppet.err "FileServer error: Cannot read #{@configuration}; cannot serve"
- #raise Puppet::Error, "Cannot read #{@configuration}"
- rescue Errno::ENOENT => detail
- Puppet.err "FileServer error: '#{@configuration}' does not exist; cannot serve"
- end
+ authcheck(url, mount, client, clientip)
- unless newmounts[MODULES]
- Puppet.debug "No #{MODULES} mount given; autocreating with default permissions"
- mount = Mount.new(MODULES)
- mount.allow("*")
- newmounts[MODULES] = mount
- end
-
- unless newmounts[PLUGINS]
- Puppet.debug "No #{PLUGINS} mount given; autocreating with default permissions"
- mount = PluginMount.new(PLUGINS)
- mount.allow("*")
- newmounts[PLUGINS] = mount
- end
-
- unless newmounts[PLUGINS].valid?
- Puppet.debug "No path given for #{PLUGINS} mount; creating a special PluginMount"
- # We end up here if the user has specified access rules for
- # the plugins mount, without specifying a path (which means
- # they want to have the default behaviour for the mount, but
- # special access control). So we need to move all the
- # user-specified access controls into the new PluginMount
- # object...
- mount = PluginMount.new(PLUGINS)
- # Yes, you're allowed to hate me for this.
-
- mount.instance_variable_set(
- :@declarations,
-
- newmounts[PLUGINS].instance_variable_get(:@declarations)
- )
- newmounts[PLUGINS] = mount
- end
+ return mount, stub
+ end
- # Verify each of the mounts are valid.
- # We let the check raise an error, so that it can raise an error
- # pointing to the specific problem.
- newmounts.each { |name, mount|
- raise FileServerError, "Invalid mount #{name}" unless mount.valid?
- }
- @mounts = newmounts
- end
+ # Return the mount for the Puppet modules; allows file copying from
+ # the modules.
+ def modules_mount(module_name, client)
+ # Find our environment, if we have one.
+ unless hostname = (client || Facter.value("hostname"))
+ raise ArgumentError, "Could not find hostname"
+ end
+ env = (node = Puppet::Node.find(hostname)) ? node.environment : nil
+
+ # And use the environment to look up the module.
+ (mod = Puppet::Node::Environment.new(env).module(module_name) and mod.files?) ? @mounts[MODULES].copy(mod.name, mod.file_directory) : nil
+ end
- # Split the path into the separate mount point and path.
- def splitpath(dir, client)
- # the dir is based on one of the mounts
- # so first retrieve the mount path
- mount = nil
- path = nil
- if dir =~ %r{/([-\w]+)}
- # Strip off the mount name.
- mount_name, path = dir.sub(%r{^/}, '').split(File::Separator, 2)
-
- unless mount = modules_mount(mount_name, client)
- unless mount = @mounts[mount_name]
- raise FileServerError, "Fileserver module '#{mount_name}' not mounted"
- end
+ # Read the configuration file.
+ def readconfig(check = true)
+ return if @noreadconfig
+
+ return unless configuration
+
+ return if check and ! @configuration.changed?
+
+ newmounts = {}
+ begin
+ File.open(@configuration.file) { |f|
+ mount = nil
+ count = 1
+ f.each { |line|
+ case line
+ when /^\s*#/; next # skip comments
+ when /^\s*$/; next # skip blank lines
+ when /\[([-\w]+)\]/
+ name = $1
+ raise FileServerError, "#{newmounts[name]} is already mounted as #{name} in #{@configuration.file}" if newmounts.include?(name)
+ mount = Mount.new(name)
+ newmounts[name] = mount
+ when /^\s*(\w+)\s+(.+)$/
+ var = $1
+ value = $2
+ case var
+ when "path"
+ if mount.name == MODULES
+ Puppet.warning "The '#{mount.name}' module can not have a path. Ignoring attempt to set it"
+ else
+ begin
+ mount.path = value
+ rescue FileServerError => detail
+ Puppet.err "Removing mount #{mount.name}: #{detail}"
+ newmounts.delete(mount.name)
+ end
end
+ when "allow"
+ value.split(/\s*,\s*/).each { |val|
+ begin
+ mount.info "allowing #{val} access"
+ mount.allow(val)
+ rescue AuthStoreError => detail
+ puts detail.backtrace if Puppet[:trace]
+
+ raise FileServerError.new(
+ detail.to_s,
+
+ count, @configuration.file)
+ end
+ }
+ when "deny"
+ value.split(/\s*,\s*/).each { |val|
+ begin
+ mount.info "denying #{val} access"
+ mount.deny(val)
+ rescue AuthStoreError => detail
+
+ raise FileServerError.new(
+ detail.to_s,
+
+ count, @configuration.file)
+ end
+ }
+ else
+ raise FileServerError.new("Invalid argument '#{var}'", count, @configuration.file)
+ end
else
- raise FileServerError, "Fileserver error: Invalid path '#{dir}'"
- end
-
- if path.nil? or path == ''
- path = '/'
- elsif path
- # Remove any double slashes that might have occurred
- path = URI.unescape(path.gsub(/\/\//, "/"))
+ raise FileServerError.new("Invalid line '#{line.chomp}'", count, @configuration.file)
end
+ count += 1
+ }
+ }
+ rescue Errno::EACCES => detail
+ Puppet.err "FileServer error: Cannot read #{@configuration}; cannot serve"
+ #raise Puppet::Error, "Cannot read #{@configuration}"
+ rescue Errno::ENOENT => detail
+ Puppet.err "FileServer error: '#{@configuration}' does not exist; cannot serve"
+ end
+
+ unless newmounts[MODULES]
+ Puppet.debug "No #{MODULES} mount given; autocreating with default permissions"
+ mount = Mount.new(MODULES)
+ mount.allow("*")
+ newmounts[MODULES] = mount
+ end
+
+ unless newmounts[PLUGINS]
+ Puppet.debug "No #{PLUGINS} mount given; autocreating with default permissions"
+ mount = PluginMount.new(PLUGINS)
+ mount.allow("*")
+ newmounts[PLUGINS] = mount
+ end
+
+ unless newmounts[PLUGINS].valid?
+ Puppet.debug "No path given for #{PLUGINS} mount; creating a special PluginMount"
+ # We end up here if the user has specified access rules for
+ # the plugins mount, without specifying a path (which means
+ # they want to have the default behaviour for the mount, but
+ # special access control). So we need to move all the
+ # user-specified access controls into the new PluginMount
+ # object...
+ mount = PluginMount.new(PLUGINS)
+ # Yes, you're allowed to hate me for this.
+
+ mount.instance_variable_set(
+ :@declarations,
+
+ newmounts[PLUGINS].instance_variable_get(:@declarations)
+ )
+ newmounts[PLUGINS] = mount
+ end
+
+ # Verify each of the mounts are valid.
+ # We let the check raise an error, so that it can raise an error
+ # pointing to the specific problem.
+ newmounts.each { |name, mount|
+ raise FileServerError, "Invalid mount #{name}" unless mount.valid?
+ }
+ @mounts = newmounts
+ end
- return mount, path
- end
-
- def to_s
- "fileserver"
+ # Split the path into the separate mount point and path.
+ def splitpath(dir, client)
+ # the dir is based on one of the mounts
+ # so first retrieve the mount path
+ mount = nil
+ path = nil
+ if dir =~ %r{/([-\w]+)}
+ # Strip off the mount name.
+ mount_name, path = dir.sub(%r{^/}, '').split(File::Separator, 2)
+
+ unless mount = modules_mount(mount_name, client)
+ unless mount = @mounts[mount_name]
+ raise FileServerError, "Fileserver module '#{mount_name}' not mounted"
+ end
end
+ else
+ raise FileServerError, "Fileserver error: Invalid path '#{dir}'"
+ end
+
+ if path.nil? or path == ''
+ path = '/'
+ elsif path
+ # Remove any double slashes that might have occurred
+ path = URI.unescape(path.gsub(/\/\//, "/"))
+ end
+
+ return mount, path
+ end
- # A simple class for wrapping mount points. Instances of this class
- # don't know about the enclosing object; they're mainly just used for
- # authorization.
- class Mount < Puppet::Network::AuthStore
- attr_reader :name
-
- @@syncs = {}
-
- @@files = {}
-
- Puppet::Util.logmethods(self, true)
-
- # Create a map for a specific client.
- def clientmap(client)
- {
- "h" => client.sub(/\..*$/, ""),
- "H" => client,
- "d" => client.sub(/[^.]+\./, "") # domain name
- }
- end
-
- # Replace % patterns as appropriate.
- def expand(path, client = nil)
- # This map should probably be moved into a method.
- map = nil
-
- if client
- map = clientmap(client)
- else
- Puppet.notice "No client; expanding '#{path}' with local host"
- # Else, use the local information
- map = localmap
- end
- path.gsub(/%(.)/) do |v|
- key = $1
- if key == "%"
- "%"
- else
- map[key] || v
- end
- end
- end
-
- # Do we have any patterns in our path, yo?
- def expandable?
- if defined?(@expandable)
- @expandable
- else
- false
- end
- end
-
- # Return a fully qualified path, given a short path and
- # possibly a client name.
- def file_path(relative_path, node = nil)
- full_path = path(node)
-
- unless full_path
- p self
- raise ArgumentError.new("Mounts without paths are not usable") unless full_path
- end
-
- # If there's no relative path name, then we're serving the mount itself.
- return full_path unless relative_path and relative_path != "/"
-
- File.join(full_path, relative_path)
- end
-
- # Create out object. It must have a name.
- def initialize(name, path = nil)
- unless name =~ %r{^[-\w]+$}
- raise FileServerError, "Invalid name format '#{name}'"
- end
- @name = name
-
- if path
- self.path = path
- else
- @path = nil
- end
-
- @files = {}
-
- super()
- end
-
- def fileobj(path, links, client)
- obj = nil
- if obj = @files[file_path(path, client)]
- # This can only happen in local fileserving, but it's an
- # important one. It'd be nice if we didn't just set
- # the check params every time, but I'm not sure it's worth
- # the effort.
- obj[:audit] = CHECKPARAMS
- else
-
- obj = Puppet::Type.type(:file).new(
-
- :name => file_path(path, client),
-
- :audit => CHECKPARAMS
- )
- @files[file_path(path, client)] = obj
- end
-
- if links == :manage
- links = :follow
- end
+ def to_s
+ "fileserver"
+ end
- # This, ah, might be completely redundant
- obj[:links] = links unless obj[:links] == links
+ # A simple class for wrapping mount points. Instances of this class
+ # don't know about the enclosing object; they're mainly just used for
+ # authorization.
+ class Mount < Puppet::Network::AuthStore
+ attr_reader :name
- obj
- end
+ @@syncs = {}
- # Read the contents of the file at the relative path given.
- def read_file(relpath, client)
- File.read(file_path(relpath, client))
- end
+ @@files = {}
- # Cache this manufactured map, since if it's used it's likely
- # to get used a lot.
- def localmap
- unless defined?(@@localmap)
- @@localmap = {
- "h" => Facter.value("hostname"),
- "H" => [Facter.value("hostname"),
- Facter.value("domain")].join("."),
- "d" => Facter.value("domain")
- }
- end
- @@localmap
- end
-
- # Return the path as appropriate, expanding as necessary.
- def path(client = nil)
- if expandable?
- return expand(@path, client)
- else
- return @path
- end
- end
+ Puppet::Util.logmethods(self, true)
- # Set the path.
- def path=(path)
- # FIXME: For now, just don't validate paths with replacement
- # patterns in them.
- if path =~ /%./
- # Mark that we're expandable.
- @expandable = true
- else
- raise FileServerError, "#{path} does not exist" unless FileTest.exists?(path)
- raise FileServerError, "#{path} is not a directory" unless FileTest.directory?(path)
- raise FileServerError, "#{path} is not readable" unless FileTest.readable?(path)
- @expandable = false
- end
- @path = path
- end
-
- # Verify that the path given exists within this mount's subtree.
- #
- def path_exists?(relpath, client = nil)
- File.exists?(file_path(relpath, client))
- end
+ # Create a map for a specific client.
+ def clientmap(client)
+ {
+ "h" => client.sub(/\..*$/, ""),
+ "H" => client,
+ "d" => client.sub(/[^.]+\./, "") # domain name
+ }
+ end
+
+ # Replace % patterns as appropriate.
+ def expand(path, client = nil)
+ # This map should probably be moved into a method.
+ map = nil
+
+ if client
+ map = clientmap(client)
+ else
+ Puppet.notice "No client; expanding '#{path}' with local host"
+ # Else, use the local information
+ map = localmap
+ end
+ path.gsub(/%(.)/) do |v|
+ key = $1
+ if key == "%"
+ "%"
+ else
+ map[key] || v
+ end
+ end
+ end
+
+ # Do we have any patterns in our path, yo?
+ def expandable?
+ if defined?(@expandable)
+ @expandable
+ else
+ false
+ end
+ end
- # Return the current values for the object.
- def properties(obj)
- obj.retrieve.inject({}) { |props, ary| props[ary[0].name] = ary[1]; props }
- end
+ # Return a fully qualified path, given a short path and
+ # possibly a client name.
+ def file_path(relative_path, node = nil)
+ full_path = path(node)
- # Retrieve a specific directory relative to a mount point.
- # If they pass in a client, then expand as necessary.
- def subdir(dir = nil, client = nil)
- basedir = self.path(client)
+ unless full_path
+ p self
+ raise ArgumentError.new("Mounts without paths are not usable") unless full_path
+ end
- dirname = if dir
- File.join(basedir, *dir.split("/"))
- else
- basedir
- end
+ # If there's no relative path name, then we're serving the mount itself.
+ return full_path unless relative_path and relative_path != "/"
- dirname
- end
+ File.join(full_path, relative_path)
+ end
- def sync(path)
- @@syncs[path] ||= Sync.new
- @@syncs[path]
- end
+ # Create out object. It must have a name.
+ def initialize(name, path = nil)
+ unless name =~ %r{^[-\w]+$}
+ raise FileServerError, "Invalid name format '#{name}'"
+ end
+ @name = name
- def to_s
- "mount[#{@name}]"
- end
+ if path
+ self.path = path
+ else
+ @path = nil
+ end
- # Verify our configuration is valid. This should really check to
- # make sure at least someone will be allowed, but, eh.
- def valid?
- if name == MODULES
- return @path.nil?
- else
- return ! @path.nil?
- end
- end
+ @files = {}
- # Return a new mount with the same properties as +self+, except
- # with a different name and path.
- def copy(name, path)
- result = self.clone
- result.path = path
- result.instance_variable_set(:@name, name)
- result
- end
+ super()
+ end
- # List the contents of the relative path +relpath+ of this mount.
- #
- # +recurse+ is the number of levels to recurse into the tree,
- # or false to provide no recursion or true if you just want to
- # go for broke.
- #
- # +ignore+ is an array of filenames to ignore when traversing
- # the list.
- #
- # The return value of this method is a complex nest of arrays,
- # which describes a directory tree. Each file or directory is
- # represented by an array, where the first element is the path
- # of the file (relative to the root of the mount), and the
- # second element is the type. A directory is represented by an
- # array as well, where the first element is a "directory" array,
- # while the remaining elements are other file or directory
- # arrays. Confusing? Hell yes. As an added bonus, all names
- # must start with a slash, because... well, I'm fairly certain
- # a complete explanation would involve the words "crack pipe"
- # and "bad batch".
- #
- def list(relpath, recurse, ignore, client = nil)
- abspath = file_path(relpath, client)
- if FileTest.exists?(abspath)
- if FileTest.directory?(abspath) and recurse
- return reclist(abspath, recurse, ignore)
- else
- return [["/", File.stat(abspath).ftype]]
- end
- end
- nil
- end
+ def fileobj(path, links, client)
+ obj = nil
+ if obj = @files[file_path(path, client)]
+ # This can only happen in local fileserving, but it's an
+ # important one. It'd be nice if we didn't just set
+ # the check params every time, but I'm not sure it's worth
+ # the effort.
+ obj[:audit] = CHECKPARAMS
+ else
- def reclist(abspath, recurse, ignore)
- require 'puppet/file_serving'
- require 'puppet/file_serving/fileset'
- if recurse.is_a?(Fixnum)
- args = { :recurse => true, :recurselimit => recurse, :links => :follow }
- else
- args = { :recurse => recurse, :links => :follow }
- end
- args[:ignore] = ignore if ignore
- fs = Puppet::FileServing::Fileset.new(abspath, args)
- ary = fs.files.collect do |file|
- if file == "."
- file = "/"
- else
- file = File.join("/", file )
- end
- stat = fs.stat(File.join(abspath, file))
- next if stat.nil?
- [ file, stat.ftype ]
- end
+ obj = Puppet::Type.type(:file).new(
- ary.compact
- end
+ :name => file_path(path, client),
+ :audit => CHECKPARAMS
+ )
+ @files[file_path(path, client)] = obj
end
- # A special mount class specifically for the plugins mount -- just
- # has some magic to effectively do a union mount of the 'plugins'
- # directory of all modules.
- #
- class PluginMount < Mount
- def path(client)
- ''
- end
-
- def mod_path_exists?(mod, relpath, client = nil)
- ! mod.plugin(relpath).nil?
- end
+ if links == :manage
+ links = :follow
+ end
- def path_exists?(relpath, client = nil)
- !valid_modules(client).find { |mod| mod.plugin(relpath) }.nil?
- end
+ # This, ah, might be completely redundant
+ obj[:links] = links unless obj[:links] == links
+
+ obj
+ end
+
+ # Read the contents of the file at the relative path given.
+ def read_file(relpath, client)
+ File.read(file_path(relpath, client))
+ end
+
+ # Cache this manufactured map, since if it's used it's likely
+ # to get used a lot.
+ def localmap
+ unless defined?(@@localmap)
+ @@localmap = {
+ "h" => Facter.value("hostname"),
+ "H" => [Facter.value("hostname"),
+ Facter.value("domain")].join("."),
+ "d" => Facter.value("domain")
+ }
+ end
+ @@localmap
+ end
+
+ # Return the path as appropriate, expanding as necessary.
+ def path(client = nil)
+ if expandable?
+ return expand(@path, client)
+ else
+ return @path
+ end
+ end
+
+ # Set the path.
+ def path=(path)
+ # FIXME: For now, just don't validate paths with replacement
+ # patterns in them.
+ if path =~ /%./
+ # Mark that we're expandable.
+ @expandable = true
+ else
+ raise FileServerError, "#{path} does not exist" unless FileTest.exists?(path)
+ raise FileServerError, "#{path} is not a directory" unless FileTest.directory?(path)
+ raise FileServerError, "#{path} is not readable" unless FileTest.readable?(path)
+ @expandable = false
+ end
+ @path = path
+ end
+
+ # Verify that the path given exists within this mount's subtree.
+ #
+ def path_exists?(relpath, client = nil)
+ File.exists?(file_path(relpath, client))
+ end
+
+ # Return the current values for the object.
+ def properties(obj)
+ obj.retrieve.inject({}) { |props, ary| props[ary[0].name] = ary[1]; props }
+ end
+
+ # Retrieve a specific directory relative to a mount point.
+ # If they pass in a client, then expand as necessary.
+ def subdir(dir = nil, client = nil)
+ basedir = self.path(client)
+
+ dirname = if dir
+ File.join(basedir, *dir.split("/"))
+ else
+ basedir
+ end
- def valid?
- true
- end
+ dirname
+ end
+
+ def sync(path)
+ @@syncs[path] ||= Sync.new
+ @@syncs[path]
+ end
+
+ def to_s
+ "mount[#{@name}]"
+ end
+
+ # Verify our configuration is valid. This should really check to
+ # make sure at least someone will be allowed, but, eh.
+ def valid?
+ if name == MODULES
+ return @path.nil?
+ else
+ return ! @path.nil?
+ end
+ end
+
+ # Return a new mount with the same properties as +self+, except
+ # with a different name and path.
+ def copy(name, path)
+ result = self.clone
+ result.path = path
+ result.instance_variable_set(:@name, name)
+ result
+ end
+
+ # List the contents of the relative path +relpath+ of this mount.
+ #
+ # +recurse+ is the number of levels to recurse into the tree,
+ # or false to provide no recursion or true if you just want to
+ # go for broke.
+ #
+ # +ignore+ is an array of filenames to ignore when traversing
+ # the list.
+ #
+ # The return value of this method is a complex nest of arrays,
+ # which describes a directory tree. Each file or directory is
+ # represented by an array, where the first element is the path
+ # of the file (relative to the root of the mount), and the
+ # second element is the type. A directory is represented by an
+ # array as well, where the first element is a "directory" array,
+ # while the remaining elements are other file or directory
+ # arrays. Confusing? Hell yes. As an added bonus, all names
+ # must start with a slash, because... well, I'm fairly certain
+ # a complete explanation would involve the words "crack pipe"
+ # and "bad batch".
+ #
+ def list(relpath, recurse, ignore, client = nil)
+ abspath = file_path(relpath, client)
+ if FileTest.exists?(abspath)
+ if FileTest.directory?(abspath) and recurse
+ return reclist(abspath, recurse, ignore)
+ else
+ return [["/", File.stat(abspath).ftype]]
+ end
+ end
+ nil
+ end
+
+ def reclist(abspath, recurse, ignore)
+ require 'puppet/file_serving'
+ require 'puppet/file_serving/fileset'
+ if recurse.is_a?(Fixnum)
+ args = { :recurse => true, :recurselimit => recurse, :links => :follow }
+ else
+ args = { :recurse => recurse, :links => :follow }
+ end
+ args[:ignore] = ignore if ignore
+ fs = Puppet::FileServing::Fileset.new(abspath, args)
+ ary = fs.files.collect do |file|
+ if file == "."
+ file = "/"
+ else
+ file = File.join("/", file )
+ end
+ stat = fs.stat(File.join(abspath, file))
+ next if stat.nil?
+ [ file, stat.ftype ]
+ end
- def mod_file_path(mod, relpath, client = nil)
- File.join(mod, PLUGINS, relpath)
- end
+ ary.compact
+ end
- def file_path(relpath, client = nil)
- return nil unless mod = valid_modules(client).find { |m| m.plugin(relpath) }
- mod.plugin(relpath)
- end
+ end
- # create a list of files by merging all modules
- def list(relpath, recurse, ignore, client = nil)
- result = []
- valid_modules(client).each do |mod|
- if modpath = mod.plugin(relpath)
- if FileTest.directory?(modpath) and recurse
- ary = reclist(modpath, recurse, ignore)
- ary ||= []
- result += ary
- else
- result += [["/", File.stat(modpath).ftype]]
- end
- end
- end
- result
+ # A special mount class specifically for the plugins mount -- just
+ # has some magic to effectively do a union mount of the 'plugins'
+ # directory of all modules.
+ #
+ class PluginMount < Mount
+ def path(client)
+ ''
+ end
+
+ def mod_path_exists?(mod, relpath, client = nil)
+ ! mod.plugin(relpath).nil?
+ end
+
+ def path_exists?(relpath, client = nil)
+ !valid_modules(client).find { |mod| mod.plugin(relpath) }.nil?
+ end
+
+ def valid?
+ true
+ end
+
+ def mod_file_path(mod, relpath, client = nil)
+ File.join(mod, PLUGINS, relpath)
+ end
+
+ def file_path(relpath, client = nil)
+ return nil unless mod = valid_modules(client).find { |m| m.plugin(relpath) }
+ mod.plugin(relpath)
+ end
+
+ # create a list of files by merging all modules
+ def list(relpath, recurse, ignore, client = nil)
+ result = []
+ valid_modules(client).each do |mod|
+ if modpath = mod.plugin(relpath)
+ if FileTest.directory?(modpath) and recurse
+ ary = reclist(modpath, recurse, ignore)
+ ary ||= []
+ result += ary
+ else
+ result += [["/", File.stat(modpath).ftype]]
end
+ end
+ end
+ result
+ end
- private
- def valid_modules(client)
- Puppet::Node::Environment.new.modules.find_all { |mod| mod.exist? }
- end
+ private
+ def valid_modules(client)
+ Puppet::Node::Environment.new.modules.find_all { |mod| mod.exist? }
+ end
- def add_to_filetree(f, filetree)
- first, rest = f.split(File::SEPARATOR, 2)
- end
- end
+ def add_to_filetree(f, filetree)
+ first, rest = f.split(File::SEPARATOR, 2)
+ end
end
+ end
end
diff --git a/lib/puppet/network/handler/master.rb b/lib/puppet/network/handler/master.rb
index 6696df4..c21aafa 100644
--- a/lib/puppet/network/handler/master.rb
+++ b/lib/puppet/network/handler/master.rb
@@ -5,85 +5,85 @@ require 'xmlrpc/server'
require 'yaml'
class Puppet::Network::Handler
- class MasterError < Puppet::Error; end
- class Master < Handler
- desc "Puppet's configuration interface. Used for all interactions related to
- generating client configurations."
+ class MasterError < Puppet::Error; end
+ class Master < Handler
+ desc "Puppet's configuration interface. Used for all interactions related to
+ generating client configurations."
- include Puppet::Util
+ include Puppet::Util
- attr_accessor :ast
- attr_reader :ca
+ attr_accessor :ast
+ attr_reader :ca
- @interface = XMLRPC::Service::Interface.new("puppetmaster") { |iface|
- iface.add_method("string getconfig(string)")
- iface.add_method("int freshness()")
- }
+ @interface = XMLRPC::Service::Interface.new("puppetmaster") { |iface|
+ iface.add_method("string getconfig(string)")
+ iface.add_method("int freshness()")
+ }
- # Tell a client whether there's a fresh config for it
- def freshness(client = nil, clientip = nil)
- # Always force a recompile. Newer clients shouldn't do this (as of April 2008).
- Time.now.to_i
- end
+ # Tell a client whether there's a fresh config for it
+ def freshness(client = nil, clientip = nil)
+ # Always force a recompile. Newer clients shouldn't do this (as of April 2008).
+ Time.now.to_i
+ end
- def initialize(hash = {})
- args = {}
+ def initialize(hash = {})
+ args = {}
- @local = hash[:Local]
+ @local = hash[:Local]
- args[:Local] = true
+ args[:Local] = true
- @ca = (hash.include?(:CA) and hash[:CA]) ? Puppet::SSLCertificates::CA.new : nil
+ @ca = (hash.include?(:CA) and hash[:CA]) ? Puppet::SSLCertificates::CA.new : nil
- # This is only used by the cfengine module, or if --loadclasses was
- # specified in +puppet+.
- args[:Classes] = hash[:Classes] if hash.include?(:Classes)
- end
+ # This is only used by the cfengine module, or if --loadclasses was
+ # specified in +puppet+.
+ args[:Classes] = hash[:Classes] if hash.include?(:Classes)
+ end
- # Call our various handlers; this handler is getting deprecated.
- def getconfig(facts, format = "marshal", client = nil, clientip = nil)
- facts = decode_facts(facts)
+ # Call our various handlers; this handler is getting deprecated.
+ def getconfig(facts, format = "marshal", client = nil, clientip = nil)
+ facts = decode_facts(facts)
- client ||= facts["hostname"]
+ client ||= facts["hostname"]
- # Pass the facts to the fact handler
- Puppet::Node::Facts.new(client, facts).save unless local?
+ # Pass the facts to the fact handler
+ Puppet::Node::Facts.new(client, facts).save unless local?
- catalog = Puppet::Resource::Catalog.find(client)
+ catalog = Puppet::Resource::Catalog.find(client)
- case format
- when "yaml"
- return CGI.escape(catalog.extract.to_yaml)
- when "marshal"
- return CGI.escape(Marshal.dump(catalog.extract))
- else
- raise "Invalid markup format '#{format}'"
- end
- end
+ case format
+ when "yaml"
+ return CGI.escape(catalog.extract.to_yaml)
+ when "marshal"
+ return CGI.escape(Marshal.dump(catalog.extract))
+ else
+ raise "Invalid markup format '#{format}'"
+ end
+ end
- #
- def decode_facts(facts)
- if @local
- # we don't need to do anything, since we should already
- # have raw objects
- Puppet.debug "Our client is local"
- else
- Puppet.debug "Our client is remote"
-
- begin
- facts = YAML.load(CGI.unescape(facts))
- rescue => detail
- raise XMLRPC::FaultException.new(
- 1, "Could not rebuild facts"
- )
- end
- end
-
- facts
+ #
+ def decode_facts(facts)
+ if @local
+ # we don't need to do anything, since we should already
+ # have raw objects
+ Puppet.debug "Our client is local"
+ else
+ Puppet.debug "Our client is remote"
+
+ begin
+ facts = YAML.load(CGI.unescape(facts))
+ rescue => detail
+ raise XMLRPC::FaultException.new(
+ 1, "Could not rebuild facts"
+ )
end
+ end
- # Translate our configuration appropriately for sending back to a client.
- def translate(config)
- end
+ facts
+ end
+
+ # Translate our configuration appropriately for sending back to a client.
+ def translate(config)
end
+ end
end
diff --git a/lib/puppet/network/handler/report.rb b/lib/puppet/network/handler/report.rb
index d935d38..cdd6c8b 100755
--- a/lib/puppet/network/handler/report.rb
+++ b/lib/puppet/network/handler/report.rb
@@ -3,78 +3,78 @@ require 'puppet/reports'
# A simple server for triggering a new run on a Puppet client.
class Puppet::Network::Handler
- class Report < Handler
- desc "Accepts a Puppet transaction report and processes it."
+ class Report < Handler
+ desc "Accepts a Puppet transaction report and processes it."
- @interface = XMLRPC::Service::Interface.new("puppetreports") { |iface|
- iface.add_method("string report(array)")
- }
+ @interface = XMLRPC::Service::Interface.new("puppetreports") { |iface|
+ iface.add_method("string report(array)")
+ }
- # Add a new report type.
- def self.newreport(name, options = {}, &block)
- Puppet.warning "The interface for registering report types has changed; use Puppet::Reports.register_report for report type #{name}"
- Puppet::Reports.register_report(name, options, &block)
- end
+ # Add a new report type.
+ def self.newreport(name, options = {}, &block)
+ Puppet.warning "The interface for registering report types has changed; use Puppet::Reports.register_report for report type #{name}"
+ Puppet::Reports.register_report(name, options, &block)
+ end
- def initialize(*args)
- super
- Puppet.settings.use(:main, :reporting, :metrics)
- end
+ def initialize(*args)
+ super
+ Puppet.settings.use(:main, :reporting, :metrics)
+ end
- # Accept a report from a client.
- def report(report, client = nil, clientip = nil)
- # Unescape the report
- report = CGI.unescape(report) unless @local
+ # Accept a report from a client.
+ def report(report, client = nil, clientip = nil)
+ # Unescape the report
+ report = CGI.unescape(report) unless @local
- Puppet.info "Processing reports #{reports().join(", ")} for #{client}"
- begin
- process(report)
- rescue => detail
- Puppet.err "Could not process report for #{client}: #{detail}"
- puts detail.backtrace if Puppet[:trace]
- end
- end
+ Puppet.info "Processing reports #{reports().join(", ")} for #{client}"
+ begin
+ process(report)
+ rescue => detail
+ Puppet.err "Could not process report for #{client}: #{detail}"
+ puts detail.backtrace if Puppet[:trace]
+ end
+ end
- private
+ private
- # Process the report using all of the existing hooks.
- def process(yaml)
- return if Puppet[:reports] == "none"
+ # Process the report using all of the existing hooks.
+ def process(yaml)
+ return if Puppet[:reports] == "none"
- # First convert the report to real objects
- begin
- report = YAML.load(yaml)
- rescue => detail
- Puppet.warning "Could not load report: #{detail}"
- return
- end
+ # First convert the report to real objects
+ begin
+ report = YAML.load(yaml)
+ rescue => detail
+ Puppet.warning "Could not load report: #{detail}"
+ return
+ end
- # Used for those reports that accept yaml
- client = report.host
+ # Used for those reports that accept yaml
+ client = report.host
- reports.each do |name|
- if mod = Puppet::Reports.report(name)
- # We have to use a dup because we're including a module in the
- # report.
- newrep = report.dup
- begin
- newrep.extend(mod)
- newrep.process
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Report #{name} failed: #{detail}"
- end
- else
- Puppet.warning "No report named '#{name}'"
- end
- end
+ reports.each do |name|
+ if mod = Puppet::Reports.report(name)
+ # We have to use a dup because we're including a module in the
+ # report.
+ newrep = report.dup
+ begin
+ newrep.extend(mod)
+ newrep.process
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Report #{name} failed: #{detail}"
+ end
+ else
+ Puppet.warning "No report named '#{name}'"
end
+ end
+ end
- # Handle the parsing of the reports attribute.
- def reports
- # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
- x = Puppet[:reports].gsub(/(^\s+)|(\s+$)/, '').split(/\s*,\s*/)
- end
+ # Handle the parsing of the reports attribute.
+ def reports
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = Puppet[:reports].gsub(/(^\s+)|(\s+$)/, '').split(/\s*,\s*/)
end
+ end
end
diff --git a/lib/puppet/network/handler/runner.rb b/lib/puppet/network/handler/runner.rb
index bc1a07a..b02d3a5 100755
--- a/lib/puppet/network/handler/runner.rb
+++ b/lib/puppet/network/handler/runner.rb
@@ -1,31 +1,31 @@
require 'puppet/run'
class Puppet::Network::Handler
- class MissingMasterError < RuntimeError; end # Cannot find the master client
- # A simple server for triggering a new run on a Puppet client.
- class Runner < Handler
- desc "An interface for triggering client configuration runs."
+ class MissingMasterError < RuntimeError; end # Cannot find the master client
+ # A simple server for triggering a new run on a Puppet client.
+ class Runner < Handler
+ desc "An interface for triggering client configuration runs."
- @interface = XMLRPC::Service::Interface.new("puppetrunner") { |iface|
- iface.add_method("string run(string, string)")
- }
+ @interface = XMLRPC::Service::Interface.new("puppetrunner") { |iface|
+ iface.add_method("string run(string, string)")
+ }
- side :client
+ side :client
- # Run the client configuration right now, optionally specifying
- # tags and whether to ignore schedules
- def run(tags = nil, ignoreschedules = false, fg = true, client = nil, clientip = nil)
- options = {}
- options[:tags] = tags if tags
- options[:ignoreschedules] = ignoreschedules if ignoreschedules
- options[:background] = !fg
+ # Run the client configuration right now, optionally specifying
+ # tags and whether to ignore schedules
+ def run(tags = nil, ignoreschedules = false, fg = true, client = nil, clientip = nil)
+ options = {}
+ options[:tags] = tags if tags
+ options[:ignoreschedules] = ignoreschedules if ignoreschedules
+ options[:background] = !fg
- runner = Puppet::Run.new(options)
+ runner = Puppet::Run.new(options)
- runner.run
+ runner.run
- runner.status
- end
+ runner.status
end
+ end
end
diff --git a/lib/puppet/network/handler/status.rb b/lib/puppet/network/handler/status.rb
index fe6c23d..ec6a402 100644
--- a/lib/puppet/network/handler/status.rb
+++ b/lib/puppet/network/handler/status.rb
@@ -1,16 +1,16 @@
class Puppet::Network::Handler
- class Status < Handler
- desc "A simple interface for testing Puppet connectivity."
+ class Status < Handler
+ desc "A simple interface for testing Puppet connectivity."
- side :client
+ side :client
- @interface = XMLRPC::Service::Interface.new("status") { |iface|
- iface.add_method("int status()")
- }
+ @interface = XMLRPC::Service::Interface.new("status") { |iface|
+ iface.add_method("int status()")
+ }
- def status(client = nil, clientip = nil)
- 1
- end
+ def status(client = nil, clientip = nil)
+ 1
end
+ end
end
diff --git a/lib/puppet/network/http.rb b/lib/puppet/network/http.rb
index ee6b704..512055b 100644
--- a/lib/puppet/network/http.rb
+++ b/lib/puppet/network/http.rb
@@ -1,15 +1,15 @@
module Puppet::Network::HTTP
- def self.server_class_by_type(kind)
- case kind.to_sym
- when :webrick
- require 'puppet/network/http/webrick'
- return Puppet::Network::HTTP::WEBrick
- when :mongrel
- raise ArgumentError, "Mongrel is not installed on this platform" unless Puppet.features.mongrel?
- require 'puppet/network/http/mongrel'
- return Puppet::Network::HTTP::Mongrel
- else
- raise ArgumentError, "Unknown HTTP server name [#{kind}]"
- end
+ def self.server_class_by_type(kind)
+ case kind.to_sym
+ when :webrick
+ require 'puppet/network/http/webrick'
+ return Puppet::Network::HTTP::WEBrick
+ when :mongrel
+ raise ArgumentError, "Mongrel is not installed on this platform" unless Puppet.features.mongrel?
+ require 'puppet/network/http/mongrel'
+ return Puppet::Network::HTTP::Mongrel
+ else
+ raise ArgumentError, "Unknown HTTP server name [#{kind}]"
end
+ end
end
diff --git a/lib/puppet/network/http/api/v1.rb b/lib/puppet/network/http/api/v1.rb
index 5773285..dd4612a 100644
--- a/lib/puppet/network/http/api/v1.rb
+++ b/lib/puppet/network/http/api/v1.rb
@@ -1,70 +1,70 @@
require 'puppet/network/http/api'
module Puppet::Network::HTTP::API::V1
- # How we map http methods and the indirection name in the URI
- # to an indirection method.
- METHOD_MAP = {
- "GET" => {
- :plural => :search,
- :singular => :find
- },
- "PUT" => {
- :singular => :save
- },
- "DELETE" => {
- :singular => :destroy
- }
+ # How we map http methods and the indirection name in the URI
+ # to an indirection method.
+ METHOD_MAP = {
+ "GET" => {
+ :plural => :search,
+ :singular => :find
+ },
+ "PUT" => {
+ :singular => :save
+ },
+ "DELETE" => {
+ :singular => :destroy
}
+ }
- def uri2indirection(http_method, uri, params)
- environment, indirection, key = uri.split("/", 4)[1..-1] # the first field is always nil because of the leading slash
+ def uri2indirection(http_method, uri, params)
+ environment, indirection, key = uri.split("/", 4)[1..-1] # the first field is always nil because of the leading slash
- raise ArgumentError, "The environment must be purely alphanumeric, not '#{environment}'" unless environment =~ /^\w+$/
- raise ArgumentError, "The indirection name must be purely alphanumeric, not '#{indirection}'" unless indirection =~ /^\w+$/
+ raise ArgumentError, "The environment must be purely alphanumeric, not '#{environment}'" unless environment =~ /^\w+$/
+ raise ArgumentError, "The indirection name must be purely alphanumeric, not '#{indirection}'" unless indirection =~ /^\w+$/
- method = indirection_method(http_method, indirection)
+ method = indirection_method(http_method, indirection)
- params[:environment] = environment
+ params[:environment] = environment
- raise ArgumentError, "No request key specified in #{uri}" if key == "" or key.nil?
+ raise ArgumentError, "No request key specified in #{uri}" if key == "" or key.nil?
- key = URI.unescape(key)
+ key = URI.unescape(key)
- Puppet::Indirector::Request.new(indirection, method, key, params)
- end
-
- def indirection2uri(request)
- indirection = request.method == :search ? pluralize(request.indirection_name.to_s) : request.indirection_name.to_s
- "/#{request.environment.to_s}/#{indirection}/#{request.escaped_key}#{request.query_string}"
- end
+ Puppet::Indirector::Request.new(indirection, method, key, params)
+ end
- def indirection_method(http_method, indirection)
- raise ArgumentError, "No support for http method #{http_method}" unless METHOD_MAP[http_method]
+ def indirection2uri(request)
+ indirection = request.method == :search ? pluralize(request.indirection_name.to_s) : request.indirection_name.to_s
+ "/#{request.environment.to_s}/#{indirection}/#{request.escaped_key}#{request.query_string}"
+ end
- unless method = METHOD_MAP[http_method][plurality(indirection)]
- raise ArgumentError, "No support for plural #{http_method} operations"
- end
+ def indirection_method(http_method, indirection)
+ raise ArgumentError, "No support for http method #{http_method}" unless METHOD_MAP[http_method]
- method
+ unless method = METHOD_MAP[http_method][plurality(indirection)]
+ raise ArgumentError, "No support for plural #{http_method} operations"
end
- def pluralize(indirection)
- return(indirection == "status" ? "statuses" : indirection + "s")
- end
+ method
+ end
- def plurality(indirection)
- # NOTE This specific hook for facts is ridiculous, but it's a *many*-line
- # fix to not need this, and our goal is to move away from the complication
- # that leads to the fix being too long.
- return :singular if indirection == "facts"
+ def pluralize(indirection)
+ return(indirection == "status" ? "statuses" : indirection + "s")
+ end
- # "status" really is singular
- return :singular if indirection == "status"
+ def plurality(indirection)
+ # NOTE This specific hook for facts is ridiculous, but it's a *many*-line
+ # fix to not need this, and our goal is to move away from the complication
+ # that leads to the fix being too long.
+ return :singular if indirection == "facts"
- result = (indirection =~ /s$/) ? :plural : :singular
+ # "status" really is singular
+ return :singular if indirection == "status"
- indirection.sub!(/s$/, '') if result
+ result = (indirection =~ /s$/) ? :plural : :singular
- result
- end
+ indirection.sub!(/s$/, '') if result
+
+ result
+ end
end
diff --git a/lib/puppet/network/http/compression.rb b/lib/puppet/network/http/compression.rb
index bb06a57..d9b56f1 100644
--- a/lib/puppet/network/http/compression.rb
+++ b/lib/puppet/network/http/compression.rb
@@ -2,110 +2,110 @@ require 'puppet/network/http'
module Puppet::Network::HTTP::Compression
- # this module function allows to use the right underlying
- # methods depending on zlib presence
- def module
- return(Puppet.features.zlib? ? Active : None)
+ # this module function allows to use the right underlying
+ # methods depending on zlib presence
+ def module
+ return(Puppet.features.zlib? ? Active : None)
+ end
+ module_function :module
+
+ module Active
+ require 'zlib'
+ require 'stringio'
+
+ # return an uncompressed body if the response has been
+ # compressed
+ def uncompress_body(response)
+ case response['content-encoding']
+ when 'gzip'
+ return Zlib::GzipReader.new(StringIO.new(response.body)).read
+ when 'deflate'
+ return Zlib::Inflate.new.inflate(response.body)
+ when nil, 'identity'
+ return response.body
+ else
+ raise Net::HTTPError.new("Unknown content encoding - #{response['content-encoding']}", response)
+ end
end
- module_function :module
-
- module Active
- require 'zlib'
- require 'stringio'
-
- # return an uncompressed body if the response has been
- # compressed
- def uncompress_body(response)
- case response['content-encoding']
- when 'gzip'
- return Zlib::GzipReader.new(StringIO.new(response.body)).read
- when 'deflate'
- return Zlib::Inflate.new.inflate(response.body)
- when nil, 'identity'
- return response.body
- else
- raise Net::HTTPError.new("Unknown content encoding - #{response['content-encoding']}", response)
- end
- end
-
- def uncompress(response)
- raise Net::HTTPError.new("No block passed") unless block_given?
-
- case response['content-encoding']
- when 'gzip','deflate'
- uncompressor = ZlibAdapter.new
- when nil, 'identity'
- uncompressor = IdentityAdapter.new
- else
- raise Net::HTTPError.new("Unknown content encoding - #{response['content-encoding']}", response)
- end
-
- yield uncompressor
-
- uncompressor.close
- end
-
- def add_accept_encoding(headers={})
- headers['accept-encoding'] = 'gzip; q=1.0, deflate; q=1.0; identity' if Puppet.settings[:http_compression]
- headers
- end
-
- # This adapters knows how to uncompress both 'zlib' stream (the deflate algorithm from Content-Encoding)
- # and GZip streams.
- class ZlibAdapter
- def initialize
- # Create an inflater that knows to parse GZip streams and zlib streams.
- # This uses a property of the C Zlib library, documented as follow:
- # windowBits can also be greater than 15 for optional gzip decoding. Add
- # 32 to windowBits to enable zlib and gzip decoding with automatic header
- # detection, or add 16 to decode only the gzip format (the zlib format will
- # return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is
- # a crc32 instead of an adler32.
- @uncompressor = Zlib::Inflate.new(15 + 32)
- @first = true
- end
-
- def uncompress(chunk)
- out = @uncompressor.inflate(chunk)
- @first = false
- return out
- rescue Zlib::DataError => z
- # it can happen that we receive a raw deflate stream
- # which might make our inflate throw a data error.
- # in this case, we try with a verbatim (no header)
- # deflater.
- @uncompressor = Zlib::Inflate.new
- retry if @first
- raise
- end
-
- def close
- @uncompressor.finish
- @uncompressor.close
- end
- end
+
+ def uncompress(response)
+ raise Net::HTTPError.new("No block passed") unless block_given?
+
+ case response['content-encoding']
+ when 'gzip','deflate'
+ uncompressor = ZlibAdapter.new
+ when nil, 'identity'
+ uncompressor = IdentityAdapter.new
+ else
+ raise Net::HTTPError.new("Unknown content encoding - #{response['content-encoding']}", response)
+ end
+
+ yield uncompressor
+
+ uncompressor.close
end
- module None
- def uncompress_body(response)
- response.body
- end
+ def add_accept_encoding(headers={})
+ headers['accept-encoding'] = 'gzip; q=1.0, deflate; q=1.0; identity' if Puppet.settings[:http_compression]
+ headers
+ end
- def add_accept_encoding(headers)
- headers
- end
+ # This adapters knows how to uncompress both 'zlib' stream (the deflate algorithm from Content-Encoding)
+ # and GZip streams.
+ class ZlibAdapter
+ def initialize
+ # Create an inflater that knows to parse GZip streams and zlib streams.
+ # This uses a property of the C Zlib library, documented as follow:
+ # windowBits can also be greater than 15 for optional gzip decoding. Add
+ # 32 to windowBits to enable zlib and gzip decoding with automatic header
+ # detection, or add 16 to decode only the gzip format (the zlib format will
+ # return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is
+ # a crc32 instead of an adler32.
+ @uncompressor = Zlib::Inflate.new(15 + 32)
+ @first = true
+ end
+
+ def uncompress(chunk)
+ out = @uncompressor.inflate(chunk)
+ @first = false
+ return out
+ rescue Zlib::DataError => z
+ # it can happen that we receive a raw deflate stream
+ # which might make our inflate throw a data error.
+ # in this case, we try with a verbatim (no header)
+ # deflater.
+ @uncompressor = Zlib::Inflate.new
+ retry if @first
+ raise
+ end
+
+ def close
+ @uncompressor.finish
+ @uncompressor.close
+ end
+ end
+ end
- def uncompress(response)
- yield IdentityAdapter.new
- end
+ module None
+ def uncompress_body(response)
+ response.body
end
- class IdentityAdapter
- def uncompress(chunk)
- chunk
- end
+ def add_accept_encoding(headers)
+ headers
+ end
+
+ def uncompress(response)
+ yield IdentityAdapter.new
+ end
+ end
+
+ class IdentityAdapter
+ def uncompress(chunk)
+ chunk
+ end
- def close
- end
+ def close
end
+ end
end
diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb
index 9f46737..03d24b3 100644
--- a/lib/puppet/network/http/handler.rb
+++ b/lib/puppet/network/http/handler.rb
@@ -7,223 +7,223 @@ require 'puppet/network/rights'
require 'resolv'
module Puppet::Network::HTTP::Handler
- include Puppet::Network::HTTP::API::V1
- include Puppet::Network::RestAuthorization
+ include Puppet::Network::HTTP::API::V1
+ include Puppet::Network::RestAuthorization
- attr_reader :server, :handler
+ attr_reader :server, :handler
- # Retrieve the accept header from the http request.
- def accept_header(request)
- raise NotImplementedError
- end
-
- # Retrieve the Content-Type header from the http request.
- def content_type_header(request)
- raise NotImplementedError
- end
-
- # Which format to use when serializing our response or interpreting the request.
- # IF the client provided a Content-Type use this, otherwise use the Accept header
- # and just pick the first value.
- def format_to_use(request)
- unless header = accept_header(request)
- raise ArgumentError, "An Accept header must be provided to pick the right format"
- end
-
- format = nil
- header.split(/,\s*/).each do |name|
- next unless format = Puppet::Network::FormatHandler.format(name)
- next unless format.suitable?
- return format
- end
-
- raise "No specified acceptable formats (#{header}) are functional on this machine"
- end
-
- def request_format(request)
- if header = content_type_header(request)
- header.gsub!(/\s*;.*$/,'') # strip any charset
- format = Puppet::Network::FormatHandler.mime(header)
- raise "Client sent a mime-type (#{header}) that doesn't correspond to a format we support" if format.nil?
- return format.name.to_s if format.suitable?
- end
-
- raise "No Content-Type header was received, it isn't possible to unserialize the request"
- end
-
- def format_to_mime(format)
- format.is_a?(Puppet::Network::Format) ? format.mime : format
- end
-
- def initialize_for_puppet(server)
- @server = server
- end
-
- # handle an HTTP request
- def process(request, response)
- indirection_request = uri2indirection(http_method(request), path(request), params(request))
-
- check_authorization(indirection_request)
-
- send("do_#{indirection_request.method}", indirection_request, request, response)
- rescue SystemExit,NoMemoryError
- raise
- rescue Exception => e
- return do_exception(response, e)
- end
-
- # Set the response up, with the body and status.
- def set_response(response, body, status = 200)
- raise NotImplementedError
- end
-
- # Set the specified format as the content type of the response.
- def set_content_type(response, format)
- raise NotImplementedError
- end
+ # Retrieve the accept header from the http request.
+ def accept_header(request)
+ raise NotImplementedError
+ end
- def do_exception(response, exception, status=400)
- if exception.is_a?(Puppet::Network::AuthorizationError)
- # make sure we return the correct status code
- # for authorization issues
- status = 403 if status == 400
- end
- if exception.is_a?(Exception)
- puts exception.backtrace if Puppet[:trace]
- Puppet.err(exception)
- end
- set_content_type(response, "text/plain")
- set_response(response, exception.to_s, status)
- end
-
- # Execute our find.
- def do_find(indirection_request, request, response)
- unless result = indirection_request.model.find(indirection_request.key, indirection_request.to_hash)
- Puppet.info("Could not find #{indirection_request.indirection_name} for '#{indirection_request.key}'")
- return do_exception(response, "Could not find #{indirection_request.indirection_name} #{indirection_request.key}", 404)
- end
-
- # The encoding of the result must include the format to use,
- # and it needs to be used for both the rendering and as
- # the content type.
- format = format_to_use(request)
- set_content_type(response, format)
-
- set_response(response, result.render(format))
- end
+ # Retrieve the Content-Type header from the http request.
+ def content_type_header(request)
+ raise NotImplementedError
+ end
- # Execute our search.
- def do_search(indirection_request, request, response)
- result = indirection_request.model.search(indirection_request.key, indirection_request.to_hash)
-
- if result.nil? or (result.is_a?(Array) and result.empty?)
- return do_exception(response, "Could not find instances in #{indirection_request.indirection_name} with '#{indirection_request.to_hash.inspect}'", 404)
- end
-
- format = format_to_use(request)
- set_content_type(response, format)
-
- set_response(response, indirection_request.model.render_multiple(format, result))
+ # Which format to use when serializing our response or interpreting the request.
+ # IF the client provided a Content-Type use this, otherwise use the Accept header
+ # and just pick the first value.
+ def format_to_use(request)
+ unless header = accept_header(request)
+ raise ArgumentError, "An Accept header must be provided to pick the right format"
end
- # Execute our destroy.
- def do_destroy(indirection_request, request, response)
- result = indirection_request.model.destroy(indirection_request.key, indirection_request.to_hash)
-
- return_yaml_response(response, result)
+ format = nil
+ header.split(/,\s*/).each do |name|
+ next unless format = Puppet::Network::FormatHandler.format(name)
+ next unless format.suitable?
+ return format
end
- # Execute our save.
- def do_save(indirection_request, request, response)
- data = body(request).to_s
- raise ArgumentError, "No data to save" if !data or data.empty?
-
- format = request_format(request)
- obj = indirection_request.model.convert_from(format, data)
- result = save_object(indirection_request, obj)
- return_yaml_response(response, result)
- end
+ raise "No specified acceptable formats (#{header}) are functional on this machine"
+ end
- # resolve node name from peer's ip address
- # this is used when the request is unauthenticated
- def resolve_node(result)
- begin
- return Resolv.getname(result[:ip])
- rescue => detail
- Puppet.err "Could not resolve #{result[:ip]}: #{detail}"
- end
- result[:ip]
+ def request_format(request)
+ if header = content_type_header(request)
+ header.gsub!(/\s*;.*$/,'') # strip any charset
+ format = Puppet::Network::FormatHandler.mime(header)
+ raise "Client sent a mime-type (#{header}) that doesn't correspond to a format we support" if format.nil?
+ return format.name.to_s if format.suitable?
end
- private
+ raise "No Content-Type header was received, it isn't possible to unserialize the request"
+ end
+
+ def format_to_mime(format)
+ format.is_a?(Puppet::Network::Format) ? format.mime : format
+ end
- def return_yaml_response(response, body)
- set_content_type(response, Puppet::Network::FormatHandler.format("yaml"))
- set_response(response, body.to_yaml)
- end
+ def initialize_for_puppet(server)
+ @server = server
+ end
- # LAK:NOTE This has to be here for testing; it's a stub-point so
- # we keep infinite recursion from happening.
- def save_object(ind_request, object)
- object.save(ind_request.key)
- end
+ # handle an HTTP request
+ def process(request, response)
+ indirection_request = uri2indirection(http_method(request), path(request), params(request))
- def get?(request)
- http_method(request) == 'GET'
- end
+ check_authorization(indirection_request)
- def put?(request)
- http_method(request) == 'PUT'
- end
+ send("do_#{indirection_request.method}", indirection_request, request, response)
+ rescue SystemExit,NoMemoryError
+ raise
+ rescue Exception => e
+ return do_exception(response, e)
+ end
- def delete?(request)
- http_method(request) == 'DELETE'
- end
+ # Set the response up, with the body and status.
+ def set_response(response, body, status = 200)
+ raise NotImplementedError
+ end
- # methods to be overridden by the including web server class
+ # Set the specified format as the content type of the response.
+ def set_content_type(response, format)
+ raise NotImplementedError
+ end
- def http_method(request)
- raise NotImplementedError
+ def do_exception(response, exception, status=400)
+ if exception.is_a?(Puppet::Network::AuthorizationError)
+ # make sure we return the correct status code
+ # for authorization issues
+ status = 403 if status == 400
end
-
- def path(request)
- raise NotImplementedError
+ if exception.is_a?(Exception)
+ puts exception.backtrace if Puppet[:trace]
+ Puppet.err(exception)
end
+ set_content_type(response, "text/plain")
+ set_response(response, exception.to_s, status)
+ end
- def request_key(request)
- raise NotImplementedError
+ # Execute our find.
+ def do_find(indirection_request, request, response)
+ unless result = indirection_request.model.find(indirection_request.key, indirection_request.to_hash)
+ Puppet.info("Could not find #{indirection_request.indirection_name} for '#{indirection_request.key}'")
+ return do_exception(response, "Could not find #{indirection_request.indirection_name} #{indirection_request.key}", 404)
end
- def body(request)
- raise NotImplementedError
- end
+ # The encoding of the result must include the format to use,
+ # and it needs to be used for both the rendering and as
+ # the content type.
+ format = format_to_use(request)
+ set_content_type(response, format)
- def params(request)
- raise NotImplementedError
- end
+ set_response(response, result.render(format))
+ end
- def decode_params(params)
- params.inject({}) do |result, ary|
- param, value = ary
- next result if param.nil? || param.empty?
-
- param = param.to_sym
-
- # These shouldn't be allowed to be set by clients
- # in the query string, for security reasons.
- next result if param == :node
- next result if param == :ip
- value = CGI.unescape(value)
- if value =~ /^---/
- value = YAML.load(value)
- else
- value = true if value == "true"
- value = false if value == "false"
- value = Integer(value) if value =~ /^\d+$/
- value = value.to_f if value =~ /^\d+\.\d+$/
- end
- result[param] = value
- result
- end
- end
+ # Execute our search.
+ def do_search(indirection_request, request, response)
+ result = indirection_request.model.search(indirection_request.key, indirection_request.to_hash)
+
+ if result.nil? or (result.is_a?(Array) and result.empty?)
+ return do_exception(response, "Could not find instances in #{indirection_request.indirection_name} with '#{indirection_request.to_hash.inspect}'", 404)
+ end
+
+ format = format_to_use(request)
+ set_content_type(response, format)
+
+ set_response(response, indirection_request.model.render_multiple(format, result))
+ end
+
+ # Execute our destroy.
+ def do_destroy(indirection_request, request, response)
+ result = indirection_request.model.destroy(indirection_request.key, indirection_request.to_hash)
+
+ return_yaml_response(response, result)
+ end
+
+ # Execute our save.
+ def do_save(indirection_request, request, response)
+ data = body(request).to_s
+ raise ArgumentError, "No data to save" if !data or data.empty?
+
+ format = request_format(request)
+ obj = indirection_request.model.convert_from(format, data)
+ result = save_object(indirection_request, obj)
+ return_yaml_response(response, result)
+ end
+
+ # resolve node name from peer's ip address
+ # this is used when the request is unauthenticated
+ def resolve_node(result)
+ begin
+ return Resolv.getname(result[:ip])
+ rescue => detail
+ Puppet.err "Could not resolve #{result[:ip]}: #{detail}"
+ end
+ result[:ip]
+ end
+
+ private
+
+ def return_yaml_response(response, body)
+ set_content_type(response, Puppet::Network::FormatHandler.format("yaml"))
+ set_response(response, body.to_yaml)
+ end
+
+ # LAK:NOTE This has to be here for testing; it's a stub-point so
+ # we keep infinite recursion from happening.
+ def save_object(ind_request, object)
+ object.save(ind_request.key)
+ end
+
+ def get?(request)
+ http_method(request) == 'GET'
+ end
+
+ def put?(request)
+ http_method(request) == 'PUT'
+ end
+
+ def delete?(request)
+ http_method(request) == 'DELETE'
+ end
+
+ # methods to be overridden by the including web server class
+
+ def http_method(request)
+ raise NotImplementedError
+ end
+
+ def path(request)
+ raise NotImplementedError
+ end
+
+ def request_key(request)
+ raise NotImplementedError
+ end
+
+ def body(request)
+ raise NotImplementedError
+ end
+
+ def params(request)
+ raise NotImplementedError
+ end
+
+ def decode_params(params)
+ params.inject({}) do |result, ary|
+ param, value = ary
+ next result if param.nil? || param.empty?
+
+ param = param.to_sym
+
+ # These shouldn't be allowed to be set by clients
+ # in the query string, for security reasons.
+ next result if param == :node
+ next result if param == :ip
+ value = CGI.unescape(value)
+ if value =~ /^---/
+ value = YAML.load(value)
+ else
+ value = true if value == "true"
+ value = false if value == "false"
+ value = Integer(value) if value =~ /^\d+$/
+ value = value.to_f if value =~ /^\d+\.\d+$/
+ end
+ result[param] = value
+ result
+ end
+ end
end
diff --git a/lib/puppet/network/http/mongrel.rb b/lib/puppet/network/http/mongrel.rb
index 88494ee..2a638b2 100644
--- a/lib/puppet/network/http/mongrel.rb
+++ b/lib/puppet/network/http/mongrel.rb
@@ -3,53 +3,53 @@ require 'mongrel' if Puppet.features.mongrel?
require 'puppet/network/http/mongrel/rest'
class Puppet::Network::HTTP::Mongrel
- def initialize(args = {})
- @listening = false
- end
-
- def listen(args = {})
- raise ArgumentError, ":protocols must be specified." if !args[:protocols] or args[:protocols].empty?
- raise ArgumentError, ":address must be specified." unless args[:address]
- raise ArgumentError, ":port must be specified." unless args[:port]
- raise "Mongrel server is already listening" if listening?
-
- @protocols = args[:protocols]
- @xmlrpc_handlers = args[:xmlrpc_handlers]
- @server = Mongrel::HttpServer.new(args[:address], args[:port])
- setup_handlers
-
- @listening = true
- @server.run
- end
-
- def unlisten
- raise "Mongrel server is not listening" unless listening?
- @server.stop
- @server = nil
- @listening = false
- end
-
- def listening?
- @listening
- end
-
- private
-
- def setup_handlers
- # Register our REST support at /
- klass = class_for_protocol(:rest)
- @server.register('/', klass.new(:server => @server))
-
- setup_xmlrpc_handlers if @protocols.include?(:xmlrpc) and ! @xmlrpc_handlers.empty?
- end
-
- # Use our existing code to provide the xmlrpc backward compatibility.
- def setup_xmlrpc_handlers
- @server.register('/RPC2', Puppet::Network::HTTPServer::Mongrel.new(@xmlrpc_handlers))
- end
-
- def class_for_protocol(protocol)
- return Puppet::Network::HTTP::MongrelREST if protocol.to_sym == :rest
- raise ArgumentError, "Unknown protocol [#{protocol}]."
- end
+ def initialize(args = {})
+ @listening = false
+ end
+
+ def listen(args = {})
+ raise ArgumentError, ":protocols must be specified." if !args[:protocols] or args[:protocols].empty?
+ raise ArgumentError, ":address must be specified." unless args[:address]
+ raise ArgumentError, ":port must be specified." unless args[:port]
+ raise "Mongrel server is already listening" if listening?
+
+ @protocols = args[:protocols]
+ @xmlrpc_handlers = args[:xmlrpc_handlers]
+ @server = Mongrel::HttpServer.new(args[:address], args[:port])
+ setup_handlers
+
+ @listening = true
+ @server.run
+ end
+
+ def unlisten
+ raise "Mongrel server is not listening" unless listening?
+ @server.stop
+ @server = nil
+ @listening = false
+ end
+
+ def listening?
+ @listening
+ end
+
+ private
+
+ def setup_handlers
+ # Register our REST support at /
+ klass = class_for_protocol(:rest)
+ @server.register('/', klass.new(:server => @server))
+
+ setup_xmlrpc_handlers if @protocols.include?(:xmlrpc) and ! @xmlrpc_handlers.empty?
+ end
+
+ # Use our existing code to provide the xmlrpc backward compatibility.
+ def setup_xmlrpc_handlers
+ @server.register('/RPC2', Puppet::Network::HTTPServer::Mongrel.new(@xmlrpc_handlers))
+ end
+
+ def class_for_protocol(protocol)
+ return Puppet::Network::HTTP::MongrelREST if protocol.to_sym == :rest
+ raise ArgumentError, "Unknown protocol [#{protocol}]."
+ end
end
diff --git a/lib/puppet/network/http/mongrel/rest.rb b/lib/puppet/network/http/mongrel/rest.rb
index 60367a1..7ef13f0 100644
--- a/lib/puppet/network/http/mongrel/rest.rb
+++ b/lib/puppet/network/http/mongrel/rest.rb
@@ -2,91 +2,91 @@ require 'puppet/network/http/handler'
class Puppet::Network::HTTP::MongrelREST < Mongrel::HttpHandler
- include Puppet::Network::HTTP::Handler
+ include Puppet::Network::HTTP::Handler
- ACCEPT_HEADER = "HTTP_ACCEPT".freeze # yay, zed's a crazy-man
+ ACCEPT_HEADER = "HTTP_ACCEPT".freeze # yay, zed's a crazy-man
- def initialize(args={})
- super()
- initialize_for_puppet(args)
- end
+ def initialize(args={})
+ super()
+ initialize_for_puppet(args)
+ end
- def accept_header(request)
- request.params[ACCEPT_HEADER]
- end
+ def accept_header(request)
+ request.params[ACCEPT_HEADER]
+ end
- def content_type_header(request)
- request.params["HTTP_CONTENT_TYPE"]
- end
+ def content_type_header(request)
+ request.params["HTTP_CONTENT_TYPE"]
+ end
- # which HTTP verb was used in this request
- def http_method(request)
- request.params[Mongrel::Const::REQUEST_METHOD]
- end
+ # which HTTP verb was used in this request
+ def http_method(request)
+ request.params[Mongrel::Const::REQUEST_METHOD]
+ end
- # Return the query params for this request. We had to expose this method for
- # testing purposes.
- def params(request)
- params = Mongrel::HttpRequest.query_parse(request.params["QUERY_STRING"])
- params = decode_params(params)
- params.merge(client_info(request))
- end
+ # Return the query params for this request. We had to expose this method for
+ # testing purposes.
+ def params(request)
+ params = Mongrel::HttpRequest.query_parse(request.params["QUERY_STRING"])
+ params = decode_params(params)
+ params.merge(client_info(request))
+ end
- # what path was requested?
- def path(request)
- # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
- #x = '/' + request.params[Mongrel::Const::REQUEST_PATH]
- request.params[Mongrel::Const::REQUEST_PATH]
- end
+ # what path was requested?
+ def path(request)
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ #x = '/' + request.params[Mongrel::Const::REQUEST_PATH]
+ request.params[Mongrel::Const::REQUEST_PATH]
+ end
- # return the request body
- def body(request)
- request.body.read
- end
+ # return the request body
+ def body(request)
+ request.body.read
+ end
- def set_content_type(response, format)
- response.header['Content-Type'] = format_to_mime(format)
- end
+ def set_content_type(response, format)
+ response.header['Content-Type'] = format_to_mime(format)
+ end
- # produce the body of the response
- def set_response(response, result, status = 200)
- # Set the 'reason' (or 'message', as it's called in Webrick), when
- # we have a failure, unless we're on a version of mongrel that doesn't
- # support this.
- if status < 300
- unless result.is_a?(File)
- response.start(status) { |head, body| body.write(result) }
- else
- response.start(status) { |head, body| }
- response.send_status(result.stat.size)
- response.send_header
- response.send_file(result.path)
- end
- else
- begin
- response.start(status,false,result) { |head, body| body.write(result) }
- rescue ArgumentError
- response.start(status) { |head, body| body.write(result) }
- end
- end
+ # produce the body of the response
+ def set_response(response, result, status = 200)
+ # Set the 'reason' (or 'message', as it's called in Webrick), when
+ # we have a failure, unless we're on a version of mongrel that doesn't
+ # support this.
+ if status < 300
+ unless result.is_a?(File)
+ response.start(status) { |head, body| body.write(result) }
+ else
+ response.start(status) { |head, body| }
+ response.send_status(result.stat.size)
+ response.send_header
+ response.send_file(result.path)
+ end
+ else
+ begin
+ response.start(status,false,result) { |head, body| body.write(result) }
+ rescue ArgumentError
+ response.start(status) { |head, body| body.write(result) }
+ end
end
+ end
- def client_info(request)
- result = {}
- params = request.params
- result[:ip] = params["HTTP_X_FORWARDED_FOR"] ? params["HTTP_X_FORWARDED_FOR"].split(',').last.strip : params["REMOTE_ADDR"]
+ def client_info(request)
+ result = {}
+ params = request.params
+ result[:ip] = params["HTTP_X_FORWARDED_FOR"] ? params["HTTP_X_FORWARDED_FOR"].split(',').last.strip : params["REMOTE_ADDR"]
- # JJM #906 The following dn.match regular expression is forgiving
- # enough to match the two Distinguished Name string contents
- # coming from Apache, Pound or other reverse SSL proxies.
- if dn = params[Puppet[:ssl_client_header]] and dn_matchdata = dn.match(/^.*?CN\s*=\s*(.*)/)
- result[:node] = dn_matchdata[1].to_str
- result[:authenticated] = (params[Puppet[:ssl_client_verify_header]] == 'SUCCESS')
- else
- result[:node] = resolve_node(result)
- result[:authenticated] = false
- end
-
- result
+ # JJM #906 The following dn.match regular expression is forgiving
+ # enough to match the two Distinguished Name string contents
+ # coming from Apache, Pound or other reverse SSL proxies.
+ if dn = params[Puppet[:ssl_client_header]] and dn_matchdata = dn.match(/^.*?CN\s*=\s*(.*)/)
+ result[:node] = dn_matchdata[1].to_str
+ result[:authenticated] = (params[Puppet[:ssl_client_verify_header]] == 'SUCCESS')
+ else
+ result[:node] = resolve_node(result)
+ result[:authenticated] = false
end
+
+ result
+ end
end
diff --git a/lib/puppet/network/http/rack.rb b/lib/puppet/network/http/rack.rb
index b7da1fc..c18a075 100644
--- a/lib/puppet/network/http/rack.rb
+++ b/lib/puppet/network/http/rack.rb
@@ -6,57 +6,57 @@ require 'puppet/network/http/rack/xmlrpc'
# An rack application, for running the Puppet HTTP Server.
class Puppet::Network::HTTP::Rack
- def initialize(args)
- raise ArgumentError, ":protocols must be specified." if !args[:protocols] or args[:protocols].empty?
- protocols = args[:protocols]
+ def initialize(args)
+ raise ArgumentError, ":protocols must be specified." if !args[:protocols] or args[:protocols].empty?
+ protocols = args[:protocols]
- # Always prepare a REST handler
- @rest_http_handler = Puppet::Network::HTTP::RackREST.new
- protocols.delete :rest
+ # Always prepare a REST handler
+ @rest_http_handler = Puppet::Network::HTTP::RackREST.new
+ protocols.delete :rest
- # Prepare the XMLRPC handler, for backward compatibility (if requested)
- @xmlrpc_path = '/RPC2'
- if args[:protocols].include?(:xmlrpc)
- raise ArgumentError, "XMLRPC was requested, but no handlers were given" if !args.include?(:xmlrpc_handlers)
+ # Prepare the XMLRPC handler, for backward compatibility (if requested)
+ @xmlrpc_path = '/RPC2'
+ if args[:protocols].include?(:xmlrpc)
+ raise ArgumentError, "XMLRPC was requested, but no handlers were given" if !args.include?(:xmlrpc_handlers)
- @xmlrpc_http_handler = Puppet::Network::HTTP::RackXMLRPC.new(args[:xmlrpc_handlers])
- protocols.delete :xmlrpc
- end
+ @xmlrpc_http_handler = Puppet::Network::HTTP::RackXMLRPC.new(args[:xmlrpc_handlers])
+ protocols.delete :xmlrpc
+ end
- raise ArgumentError, "there were unknown :protocols specified." if !protocols.empty?
+ raise ArgumentError, "there were unknown :protocols specified." if !protocols.empty?
+ end
+
+ # The real rack application (which needs to respond to call).
+ # The work we need to do, roughly is:
+ # * Read request (from env) and prepare a response
+ # * Route the request to the correct handler
+ # * Return the response (in rack-format) to our caller.
+ def call(env)
+ request = Rack::Request.new(env)
+ response = Rack::Response.new
+ Puppet.debug 'Handling request: %s %s' % [request.request_method, request.fullpath]
+
+ # if we shall serve XMLRPC, have /RPC2 go to the xmlrpc handler
+ if @xmlrpc_http_handler and @xmlrpc_path == request.path_info[0, @xmlrpc_path.size]
+ handler = @xmlrpc_http_handler
+ else
+ # everything else is handled by the new REST handler
+ handler = @rest_http_handler
end
- # The real rack application (which needs to respond to call).
- # The work we need to do, roughly is:
- # * Read request (from env) and prepare a response
- # * Route the request to the correct handler
- # * Return the response (in rack-format) to our caller.
- def call(env)
- request = Rack::Request.new(env)
- response = Rack::Response.new
- Puppet.debug 'Handling request: %s %s' % [request.request_method, request.fullpath]
-
- # if we shall serve XMLRPC, have /RPC2 go to the xmlrpc handler
- if @xmlrpc_http_handler and @xmlrpc_path == request.path_info[0, @xmlrpc_path.size]
- handler = @xmlrpc_http_handler
- else
- # everything else is handled by the new REST handler
- handler = @rest_http_handler
- end
-
- begin
- handler.process(request, response)
- rescue => detail
- # Send a Status 500 Error on unhandled exceptions.
- response.status = 500
- response['Content-Type'] = 'text/plain'
- response.write 'Internal Server Error: "%s"' % detail.message
- # log what happened
- Puppet.err "Puppet Server (Rack): Internal Server Error: Unhandled Exception: \"%s\"" % detail.message
- Puppet.err "Backtrace:"
- detail.backtrace.each { |line| Puppet.err " > #{line}" }
- end
- response.finish
+ begin
+ handler.process(request, response)
+ rescue => detail
+ # Send a Status 500 Error on unhandled exceptions.
+ response.status = 500
+ response['Content-Type'] = 'text/plain'
+ response.write 'Internal Server Error: "%s"' % detail.message
+ # log what happened
+ Puppet.err "Puppet Server (Rack): Internal Server Error: Unhandled Exception: \"%s\"" % detail.message
+ Puppet.err "Backtrace:"
+ detail.backtrace.each { |line| Puppet.err " > #{line}" }
end
+ response.finish
+ end
end
diff --git a/lib/puppet/network/http/rack/httphandler.rb b/lib/puppet/network/http/rack/httphandler.rb
index fed06f8..c540623 100644
--- a/lib/puppet/network/http/rack/httphandler.rb
+++ b/lib/puppet/network/http/rack/httphandler.rb
@@ -3,14 +3,14 @@ require 'puppet/ssl/certificate'
class Puppet::Network::HTTP::RackHttpHandler
- def initialize
- end
+ def initialize
+ end
- # do something useful with request (a Rack::Request) and use
- # response to fill your Rack::Response
- def process(request, response)
- raise NotImplementedError, "Your RackHttpHandler subclass is supposed to override service(request)"
- end
+ # do something useful with request (a Rack::Request) and use
+ # response to fill your Rack::Response
+ def process(request, response)
+ raise NotImplementedError, "Your RackHttpHandler subclass is supposed to override service(request)"
+ end
end
diff --git a/lib/puppet/network/http/rack/rest.rb b/lib/puppet/network/http/rack/rest.rb
index 5245275..e5f50c4 100644
--- a/lib/puppet/network/http/rack/rest.rb
+++ b/lib/puppet/network/http/rack/rest.rb
@@ -3,100 +3,100 @@ require 'puppet/network/http/rack/httphandler'
class Puppet::Network::HTTP::RackREST < Puppet::Network::HTTP::RackHttpHandler
- include Puppet::Network::HTTP::Handler
+ include Puppet::Network::HTTP::Handler
- HEADER_ACCEPT = 'HTTP_ACCEPT'.freeze
- ContentType = 'Content-Type'.freeze
+ HEADER_ACCEPT = 'HTTP_ACCEPT'.freeze
+ ContentType = 'Content-Type'.freeze
- CHUNK_SIZE = 8192
+ CHUNK_SIZE = 8192
- class RackFile
- def initialize(file)
- @file = file
- end
-
- def each
- while chunk = @file.read(CHUNK_SIZE)
- yield chunk
- end
- end
-
- def close
- @file.close
- end
- end
-
- def initialize(args={})
- super()
- initialize_for_puppet(args)
+ class RackFile
+ def initialize(file)
+ @file = file
end
- def set_content_type(response, format)
- response[ContentType] = format_to_mime(format)
+ def each
+ while chunk = @file.read(CHUNK_SIZE)
+ yield chunk
+ end
end
- # produce the body of the response
- def set_response(response, result, status = 200)
- response.status = status
- unless result.is_a?(File)
- response.write result
- else
- response["Content-Length"] = result.stat.size
- response.body = RackFile.new(result)
- end
+ def close
+ @file.close
end
-
- # Retrieve the accept header from the http request.
- def accept_header(request)
- request.env[HEADER_ACCEPT]
- end
-
- # Retrieve the accept header from the http request.
- def content_type_header(request)
- request.content_type
+ end
+
+ def initialize(args={})
+ super()
+ initialize_for_puppet(args)
+ end
+
+ def set_content_type(response, format)
+ response[ContentType] = format_to_mime(format)
+ end
+
+ # produce the body of the response
+ def set_response(response, result, status = 200)
+ response.status = status
+ unless result.is_a?(File)
+ response.write result
+ else
+ response["Content-Length"] = result.stat.size
+ response.body = RackFile.new(result)
end
-
- # Return which HTTP verb was used in this request.
- def http_method(request)
- request.request_method
+ end
+
+ # Retrieve the accept header from the http request.
+ def accept_header(request)
+ request.env[HEADER_ACCEPT]
+ end
+
+ # Retrieve the accept header from the http request.
+ def content_type_header(request)
+ request.content_type
+ end
+
+ # Return which HTTP verb was used in this request.
+ def http_method(request)
+ request.request_method
+ end
+
+ # Return the query params for this request.
+ def params(request)
+ result = decode_params(request.params)
+ result.merge(extract_client_info(request))
+ end
+
+ # what path was requested? (this is, without any query parameters)
+ def path(request)
+ request.path
+ end
+
+ # return the request body
+ # request.body has some limitiations, so we need to concat it back
+ # into a regular string, which is something puppet can use.
+ def body(request)
+ body = ''
+ request.body.each { |part| body += part }
+ body
+ end
+
+ def extract_client_info(request)
+ result = {}
+ result[:ip] = request.ip
+
+ # if we find SSL info in the headers, use them to get a hostname.
+ # try this with :ssl_client_header, which defaults should work for
+ # Apache with StdEnvVars.
+ if dn = request.env[Puppet[:ssl_client_header]] and dn_matchdata = dn.match(/^.*?CN\s*=\s*(.*)/)
+ result[:node] = dn_matchdata[1].to_str
+ result[:authenticated] = (request.env[Puppet[:ssl_client_verify_header]] == 'SUCCESS')
+ else
+ result[:node] = resolve_node(result)
+ result[:authenticated] = false
end
- # Return the query params for this request.
- def params(request)
- result = decode_params(request.params)
- result.merge(extract_client_info(request))
- end
-
- # what path was requested? (this is, without any query parameters)
- def path(request)
- request.path
- end
-
- # return the request body
- # request.body has some limitiations, so we need to concat it back
- # into a regular string, which is something puppet can use.
- def body(request)
- body = ''
- request.body.each { |part| body += part }
- body
- end
-
- def extract_client_info(request)
- result = {}
- result[:ip] = request.ip
-
- # if we find SSL info in the headers, use them to get a hostname.
- # try this with :ssl_client_header, which defaults should work for
- # Apache with StdEnvVars.
- if dn = request.env[Puppet[:ssl_client_header]] and dn_matchdata = dn.match(/^.*?CN\s*=\s*(.*)/)
- result[:node] = dn_matchdata[1].to_str
- result[:authenticated] = (request.env[Puppet[:ssl_client_verify_header]] == 'SUCCESS')
- else
- result[:node] = resolve_node(result)
- result[:authenticated] = false
- end
-
- result
- end
+ result
+ end
end
diff --git a/lib/puppet/network/http/rack/xmlrpc.rb b/lib/puppet/network/http/rack/xmlrpc.rb
index c3209a6..f753427 100644
--- a/lib/puppet/network/http/rack/xmlrpc.rb
+++ b/lib/puppet/network/http/rack/xmlrpc.rb
@@ -3,63 +3,63 @@ require 'puppet/network/xmlrpc/server'
require 'resolv'
class Puppet::Network::HTTP::RackXMLRPC < Puppet::Network::HTTP::RackHttpHandler
- def initialize(handlers)
- @xmlrpc_server = Puppet::Network::XMLRPCServer.new
- handlers.each do |name|
- Puppet.debug " -> register xmlrpc namespace #{name}"
- unless handler = Puppet::Network::Handler.handler(name)
- raise ArgumentError, "Invalid XMLRPC handler #{name}"
- end
- @xmlrpc_server.add_handler(handler.interface, handler.new({}))
- end
- super()
+ def initialize(handlers)
+ @xmlrpc_server = Puppet::Network::XMLRPCServer.new
+ handlers.each do |name|
+ Puppet.debug " -> register xmlrpc namespace #{name}"
+ unless handler = Puppet::Network::Handler.handler(name)
+ raise ArgumentError, "Invalid XMLRPC handler #{name}"
+ end
+ @xmlrpc_server.add_handler(handler.interface, handler.new({}))
end
+ super()
+ end
- def process(request, response)
- # errors are sent as text/plain
- response['Content-Type'] = 'text/plain'
- if not request.post?
- response.status = 405
- response.write 'Method Not Allowed'
- return
- end
- if request.media_type != "text/xml"
- response.status = 400
- response.write 'Bad Request'
- return
- end
+ def process(request, response)
+ # errors are sent as text/plain
+ response['Content-Type'] = 'text/plain'
+ if not request.post?
+ response.status = 405
+ response.write 'Method Not Allowed'
+ return
+ end
+ if request.media_type != "text/xml"
+ response.status = 400
+ response.write 'Bad Request'
+ return
+ end
- # get auth/certificate data
- client_request = build_client_request(request)
+ # get auth/certificate data
+ client_request = build_client_request(request)
- response_body = @xmlrpc_server.process(request.body.read, client_request)
+ response_body = @xmlrpc_server.process(request.body.read, client_request)
- response.status = 200
- response['Content-Type'] = 'text/xml; charset=utf-8'
- response.write response_body
- end
+ response.status = 200
+ response['Content-Type'] = 'text/xml; charset=utf-8'
+ response.write response_body
+ end
- def build_client_request(request)
- ip = request.ip
+ def build_client_request(request)
+ ip = request.ip
- # if we find SSL info in the headers, use them to get a hostname.
- # try this with :ssl_client_header, which defaults should work for
- # Apache with StdEnvVars.
- if dn = request.env[Puppet[:ssl_client_header]] and dn_matchdata = dn.match(/^.*?CN\s*=\s*(.*)/)
- node = dn_matchdata[1].to_str
- authenticated = (request.env[Puppet[:ssl_client_verify_header]] == 'SUCCESS')
- else
- begin
- node = Resolv.getname(ip)
- rescue => detail
- Puppet.err "Could not resolve #{ip}: #{detail}"
- node = "unknown"
- end
- authenticated = false
- end
-
- Puppet::Network::ClientRequest.new(node, ip, authenticated)
+ # if we find SSL info in the headers, use them to get a hostname.
+ # try this with :ssl_client_header, which defaults should work for
+ # Apache with StdEnvVars.
+ if dn = request.env[Puppet[:ssl_client_header]] and dn_matchdata = dn.match(/^.*?CN\s*=\s*(.*)/)
+ node = dn_matchdata[1].to_str
+ authenticated = (request.env[Puppet[:ssl_client_verify_header]] == 'SUCCESS')
+ else
+ begin
+ node = Resolv.getname(ip)
+ rescue => detail
+ Puppet.err "Could not resolve #{ip}: #{detail}"
+ node = "unknown"
+ end
+ authenticated = false
end
+ Puppet::Network::ClientRequest.new(node, ip, authenticated)
+ end
+
end
diff --git a/lib/puppet/network/http/webrick.rb b/lib/puppet/network/http/webrick.rb
index 66932ad..8ed0b28 100644
--- a/lib/puppet/network/http/webrick.rb
+++ b/lib/puppet/network/http/webrick.rb
@@ -8,132 +8,132 @@ require 'puppet/ssl/certificate'
require 'puppet/ssl/certificate_revocation_list'
class Puppet::Network::HTTP::WEBrick
- def initialize(args = {})
- @listening = false
- @mutex = Mutex.new
+ def initialize(args = {})
+ @listening = false
+ @mutex = Mutex.new
+ end
+
+ def self.class_for_protocol(protocol)
+ return Puppet::Network::HTTP::WEBrickREST if protocol.to_sym == :rest
+ raise "Unknown protocol [#{protocol}]."
+ end
+
+ def listen(args = {})
+ raise ArgumentError, ":protocols must be specified." if !args[:protocols] or args[:protocols].empty?
+ raise ArgumentError, ":address must be specified." unless args[:address]
+ raise ArgumentError, ":port must be specified." unless args[:port]
+
+ @protocols = args[:protocols]
+ @xmlrpc_handlers = args[:xmlrpc_handlers]
+
+ arguments = {:BindAddress => args[:address], :Port => args[:port]}
+ arguments.merge!(setup_logger)
+ arguments.merge!(setup_ssl)
+
+ @server = WEBrick::HTTPServer.new(arguments)
+ @server.listeners.each { |l| l.start_immediately = false }
+
+ setup_handlers
+
+ @mutex.synchronize do
+ raise "WEBrick server is already listening" if @listening
+ @listening = true
+ @thread = Thread.new {
+ @server.start { |sock|
+ raise "Client disconnected before connection could be established" unless IO.select([sock],nil,nil,0.1)
+ sock.accept
+ @server.run(sock)
+ }
+ }
+ sleep 0.1 until @server.status == :Running
end
-
- def self.class_for_protocol(protocol)
- return Puppet::Network::HTTP::WEBrickREST if protocol.to_sym == :rest
- raise "Unknown protocol [#{protocol}]."
+ end
+
+ def unlisten
+ @mutex.synchronize do
+ raise "WEBrick server is not listening" unless @listening
+ @server.shutdown
+ @thread.join
+ @server = nil
+ @listening = false
end
+ end
- def listen(args = {})
- raise ArgumentError, ":protocols must be specified." if !args[:protocols] or args[:protocols].empty?
- raise ArgumentError, ":address must be specified." unless args[:address]
- raise ArgumentError, ":port must be specified." unless args[:port]
-
- @protocols = args[:protocols]
- @xmlrpc_handlers = args[:xmlrpc_handlers]
-
- arguments = {:BindAddress => args[:address], :Port => args[:port]}
- arguments.merge!(setup_logger)
- arguments.merge!(setup_ssl)
-
- @server = WEBrick::HTTPServer.new(arguments)
- @server.listeners.each { |l| l.start_immediately = false }
-
- setup_handlers
-
- @mutex.synchronize do
- raise "WEBrick server is already listening" if @listening
- @listening = true
- @thread = Thread.new {
- @server.start { |sock|
- raise "Client disconnected before connection could be established" unless IO.select([sock],nil,nil,0.1)
- sock.accept
- @server.run(sock)
- }
- }
- sleep 0.1 until @server.status == :Running
- end
+ def listening?
+ @mutex.synchronize do
+ @listening
end
+ end
- def unlisten
- @mutex.synchronize do
- raise "WEBrick server is not listening" unless @listening
- @server.shutdown
- @thread.join
- @server = nil
- @listening = false
- end
- end
+ # Configure our http log file.
+ def setup_logger
+ # Make sure the settings are all ready for us.
+ Puppet.settings.use(:main, :ssl, Puppet[:name])
- def listening?
- @mutex.synchronize do
- @listening
- end
+ if Puppet.run_mode.master?
+ file = Puppet[:masterhttplog]
+ else
+ file = Puppet[:httplog]
end
- # Configure our http log file.
- def setup_logger
- # Make sure the settings are all ready for us.
- Puppet.settings.use(:main, :ssl, Puppet[:name])
-
- if Puppet.run_mode.master?
- file = Puppet[:masterhttplog]
- else
- file = Puppet[:httplog]
- end
-
- # open the log manually to prevent file descriptor leak
- file_io = ::File.open(file, "a+")
- file_io.sync
- file_io.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
-
- args = [file_io]
- args << WEBrick::Log::DEBUG if Puppet::Util::Log.level == :debug
-
- logger = WEBrick::Log.new(*args)
- return :Logger => logger, :AccessLog => [
- [logger, WEBrick::AccessLog::COMMON_LOG_FORMAT ],
- [logger, WEBrick::AccessLog::REFERER_LOG_FORMAT ]
- ]
- end
+ # open the log manually to prevent file descriptor leak
+ file_io = ::File.open(file, "a+")
+ file_io.sync
+ file_io.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
- # Add all of the ssl cert information.
- def setup_ssl
- results = {}
+ args = [file_io]
+ args << WEBrick::Log::DEBUG if Puppet::Util::Log.level == :debug
- # Get the cached copy. We know it's been generated, too.
- host = Puppet::SSL::Host.localhost
+ logger = WEBrick::Log.new(*args)
+ return :Logger => logger, :AccessLog => [
+ [logger, WEBrick::AccessLog::COMMON_LOG_FORMAT ],
+ [logger, WEBrick::AccessLog::REFERER_LOG_FORMAT ]
+ ]
+ end
- raise Puppet::Error, "Could not retrieve certificate for #{host.name} and not running on a valid certificate authority" unless host.certificate
+ # Add all of the ssl cert information.
+ def setup_ssl
+ results = {}
- results[:SSLPrivateKey] = host.key.content
- results[:SSLCertificate] = host.certificate.content
- results[:SSLStartImmediately] = true
- results[:SSLEnable] = true
+ # Get the cached copy. We know it's been generated, too.
+ host = Puppet::SSL::Host.localhost
- raise Puppet::Error, "Could not find CA certificate" unless Puppet::SSL::Certificate.find(Puppet::SSL::CA_NAME)
+ raise Puppet::Error, "Could not retrieve certificate for #{host.name} and not running on a valid certificate authority" unless host.certificate
- results[:SSLCACertificateFile] = Puppet[:localcacert]
- results[:SSLVerifyClient] = OpenSSL::SSL::VERIFY_PEER
+ results[:SSLPrivateKey] = host.key.content
+ results[:SSLCertificate] = host.certificate.content
+ results[:SSLStartImmediately] = true
+ results[:SSLEnable] = true
- results[:SSLCertificateStore] = host.ssl_store
+ raise Puppet::Error, "Could not find CA certificate" unless Puppet::SSL::Certificate.find(Puppet::SSL::CA_NAME)
- results
- end
+ results[:SSLCACertificateFile] = Puppet[:localcacert]
+ results[:SSLVerifyClient] = OpenSSL::SSL::VERIFY_PEER
- private
+ results[:SSLCertificateStore] = host.ssl_store
- def setup_handlers
- # Set up the new-style protocols.
- klass = self.class.class_for_protocol(:rest)
- @server.mount('/', klass, :this_value_is_apparently_necessary_but_unused)
+ results
+ end
- # And then set up xmlrpc, if configured.
- @server.mount("/RPC2", xmlrpc_servlet) if @protocols.include?(:xmlrpc) and ! @xmlrpc_handlers.empty?
- end
+ private
- # Create our xmlrpc servlet, which provides backward compatibility.
- def xmlrpc_servlet
- handlers = @xmlrpc_handlers.collect { |handler|
- unless hclass = Puppet::Network::Handler.handler(handler)
- raise "Invalid xmlrpc handler #{handler}"
- end
- hclass.new({})
- }
- Puppet::Network::XMLRPC::WEBrickServlet.new handlers
- end
+ def setup_handlers
+ # Set up the new-style protocols.
+ klass = self.class.class_for_protocol(:rest)
+ @server.mount('/', klass, :this_value_is_apparently_necessary_but_unused)
+
+ # And then set up xmlrpc, if configured.
+ @server.mount("/RPC2", xmlrpc_servlet) if @protocols.include?(:xmlrpc) and ! @xmlrpc_handlers.empty?
+ end
+
+ # Create our xmlrpc servlet, which provides backward compatibility.
+ def xmlrpc_servlet
+ handlers = @xmlrpc_handlers.collect { |handler|
+ unless hclass = Puppet::Network::Handler.handler(handler)
+ raise "Invalid xmlrpc handler #{handler}"
+ end
+ hclass.new({})
+ }
+ Puppet::Network::XMLRPC::WEBrickServlet.new handlers
+ end
end
diff --git a/lib/puppet/network/http/webrick/rest.rb b/lib/puppet/network/http/webrick/rest.rb
index 7526099..91008aa 100644
--- a/lib/puppet/network/http/webrick/rest.rb
+++ b/lib/puppet/network/http/webrick/rest.rb
@@ -3,78 +3,78 @@ require 'resolv'
class Puppet::Network::HTTP::WEBrickREST < WEBrick::HTTPServlet::AbstractServlet
- include Puppet::Network::HTTP::Handler
+ include Puppet::Network::HTTP::Handler
- def initialize(server, handler)
- raise ArgumentError, "server is required" unless server
- super(server)
- initialize_for_puppet(:server => server, :handler => handler)
- end
+ def initialize(server, handler)
+ raise ArgumentError, "server is required" unless server
+ super(server)
+ initialize_for_puppet(:server => server, :handler => handler)
+ end
- # Retrieve the request parameters, including authentication information.
- def params(request)
- result = request.query
- result = decode_params(result)
- result.merge(client_information(request))
- end
+ # Retrieve the request parameters, including authentication information.
+ def params(request)
+ result = request.query
+ result = decode_params(result)
+ result.merge(client_information(request))
+ end
- # WEBrick uses a service method to respond to requests. Simply delegate to the handler response method.
- def service(request, response)
- process(request, response)
- end
+ # WEBrick uses a service method to respond to requests. Simply delegate to the handler response method.
+ def service(request, response)
+ process(request, response)
+ end
- def accept_header(request)
- request["accept"]
- end
+ def accept_header(request)
+ request["accept"]
+ end
- def content_type_header(request)
- request["content-type"]
- end
+ def content_type_header(request)
+ request["content-type"]
+ end
- def http_method(request)
- request.request_method
- end
+ def http_method(request)
+ request.request_method
+ end
- def path(request)
- request.path
- end
+ def path(request)
+ request.path
+ end
- def body(request)
- request.body
- end
+ def body(request)
+ request.body
+ end
- # Set the specified format as the content type of the response.
- def set_content_type(response, format)
- response["content-type"] = format_to_mime(format)
- end
+ # Set the specified format as the content type of the response.
+ def set_content_type(response, format)
+ response["content-type"] = format_to_mime(format)
+ end
- def set_response(response, result, status = 200)
- response.status = status
- if status >= 200 and status != 304
- response.body = result
- response["content-length"] = result.stat.size if result.is_a?(File)
- end
- response.reason_phrase = result if status < 200 or status >= 300
+ def set_response(response, result, status = 200)
+ response.status = status
+ if status >= 200 and status != 304
+ response.body = result
+ response["content-length"] = result.stat.size if result.is_a?(File)
end
+ response.reason_phrase = result if status < 200 or status >= 300
+ end
- # Retrieve node/cert/ip information from the request object.
- def client_information(request)
- result = {}
- if peer = request.peeraddr and ip = peer[3]
- result[:ip] = ip
- end
-
- # If they have a certificate (which will almost always be true)
- # then we get the hostname from the cert, instead of via IP
- # info
- result[:authenticated] = false
- if cert = request.client_cert and nameary = cert.subject.to_a.find { |ary| ary[0] == "CN" }
- result[:node] = nameary[1]
- result[:authenticated] = true
- else
- result[:node] = resolve_node(result)
- end
+ # Retrieve node/cert/ip information from the request object.
+ def client_information(request)
+ result = {}
+ if peer = request.peeraddr and ip = peer[3]
+ result[:ip] = ip
+ end
- result
+ # If they have a certificate (which will almost always be true)
+ # then we get the hostname from the cert, instead of via IP
+ # info
+ result[:authenticated] = false
+ if cert = request.client_cert and nameary = cert.subject.to_a.find { |ary| ary[0] == "CN" }
+ result[:node] = nameary[1]
+ result[:authenticated] = true
+ else
+ result[:node] = resolve_node(result)
end
+
+ result
+ end
end
diff --git a/lib/puppet/network/http_pool.rb b/lib/puppet/network/http_pool.rb
index b4f40c6..a3b0555 100644
--- a/lib/puppet/network/http_pool.rb
+++ b/lib/puppet/network/http_pool.rb
@@ -6,111 +6,111 @@ module Puppet::Network; end
# Manage Net::HTTP instances for keep-alive.
module Puppet::Network::HttpPool
- class << self
- include Puppet::Util::Cacher
+ class << self
+ include Puppet::Util::Cacher
- private
+ private
- cached_attr(:http_cache) { Hash.new }
- end
+ cached_attr(:http_cache) { Hash.new }
+ end
- # Use the global localhost instance.
- def self.ssl_host
- Puppet::SSL::Host.localhost
- end
+ # Use the global localhost instance.
+ def self.ssl_host
+ Puppet::SSL::Host.localhost
+ end
- # 2008/03/23
- # LAK:WARNING: Enabling this has a high propability of
- # causing corrupt files and who knows what else. See #1010.
- HTTP_KEEP_ALIVE = false
+ # 2008/03/23
+ # LAK:WARNING: Enabling this has a high propability of
+ # causing corrupt files and who knows what else. See #1010.
+ HTTP_KEEP_ALIVE = false
- def self.keep_alive?
- HTTP_KEEP_ALIVE
- end
+ def self.keep_alive?
+ HTTP_KEEP_ALIVE
+ end
- # Clear our http cache, closing all connections.
- def self.clear_http_instances
- http_cache.each do |name, connection|
- connection.finish if connection.started?
- end
- Puppet::Util::Cacher.expire
+ # Clear our http cache, closing all connections.
+ def self.clear_http_instances
+ http_cache.each do |name, connection|
+ connection.finish if connection.started?
end
-
- # Make sure we set the driver up when we read the cert in.
- def self.read_cert
- if val = super # This calls read_cert from the Puppet::SSLCertificates::Support module.
- # Clear out all of our connections, since they previously had no cert and now they
- # should have them.
- clear_http_instances
- return val
- else
- return false
- end
+ Puppet::Util::Cacher.expire
+ end
+
+ # Make sure we set the driver up when we read the cert in.
+ def self.read_cert
+ if val = super # This calls read_cert from the Puppet::SSLCertificates::Support module.
+ # Clear out all of our connections, since they previously had no cert and now they
+ # should have them.
+ clear_http_instances
+ return val
+ else
+ return false
end
-
- # Use cert information from a Puppet client to set up the http object.
- def self.cert_setup(http)
- # Just no-op if we don't have certs.
- return false unless FileTest.exist?(Puppet[:hostcert]) and FileTest.exist?(Puppet[:localcacert])
-
- http.cert_store = ssl_host.ssl_store
- http.ca_file = Puppet[:localcacert]
- http.cert = ssl_host.certificate.content
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
- http.key = ssl_host.key.content
- http.verify_callback = self.method(:ssl_verify_callback).to_proc if Puppet[:debug]
+ end
+
+ # Use cert information from a Puppet client to set up the http object.
+ def self.cert_setup(http)
+ # Just no-op if we don't have certs.
+ return false unless FileTest.exist?(Puppet[:hostcert]) and FileTest.exist?(Puppet[:localcacert])
+
+ http.cert_store = ssl_host.ssl_store
+ http.ca_file = Puppet[:localcacert]
+ http.cert = ssl_host.certificate.content
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
+ http.key = ssl_host.key.content
+ http.verify_callback = self.method(:ssl_verify_callback).to_proc if Puppet[:debug]
+ end
+
+ def self.ssl_verify_callback(peer_ok, x509_store_ctx)
+ if not peer_ok
+ Puppet.debug "OpenSSL: Error(#{x509_store_ctx.error}): #{x509_store_ctx.error_string}"
+ Puppet.debug "OpenSSL: Cert: #{x509_store_ctx.current_cert.issuer}"
+ Puppet.debug "OpenSSL: Current CRL: #{x509_store_ctx.current_crl}"
+ Puppet.debug "OpenSSL: Chain:"
+ x509_store_ctx.chain.each_index { |i| Puppet.debug "OpenSSL: \t#{i} #{x509_store_ctx.chain[i].issuer}" }
end
-
- def self.ssl_verify_callback(peer_ok, x509_store_ctx)
- if not peer_ok
- Puppet.debug "OpenSSL: Error(#{x509_store_ctx.error}): #{x509_store_ctx.error_string}"
- Puppet.debug "OpenSSL: Cert: #{x509_store_ctx.current_cert.issuer}"
- Puppet.debug "OpenSSL: Current CRL: #{x509_store_ctx.current_crl}"
- Puppet.debug "OpenSSL: Chain:"
- x509_store_ctx.chain.each_index { |i| Puppet.debug "OpenSSL: \t#{i} #{x509_store_ctx.chain[i].issuer}" }
- end
- peer_ok
+ peer_ok
+ end
+
+ # Retrieve a cached http instance if caching is enabled, else return
+ # a new one.
+ def self.http_instance(host, port, reset = false)
+ # We overwrite the uninitialized @http here with a cached one.
+ key = "#{host}:#{port}"
+
+ # Return our cached instance if we've got a cache, as long as we're not
+ # resetting the instance.
+ if keep_alive?
+ return http_cache[key] if ! reset and http_cache[key]
+
+ # Clean up old connections if we have them.
+ if http = http_cache[key]
+ http_cache.delete(key)
+ http.finish if http.started?
+ end
end
- # Retrieve a cached http instance if caching is enabled, else return
- # a new one.
- def self.http_instance(host, port, reset = false)
- # We overwrite the uninitialized @http here with a cached one.
- key = "#{host}:#{port}"
-
- # Return our cached instance if we've got a cache, as long as we're not
- # resetting the instance.
- if keep_alive?
- return http_cache[key] if ! reset and http_cache[key]
-
- # Clean up old connections if we have them.
- if http = http_cache[key]
- http_cache.delete(key)
- http.finish if http.started?
- end
- end
-
- args = [host, port]
- if Puppet[:http_proxy_host] == "none"
- args << nil << nil
- else
- args << Puppet[:http_proxy_host] << Puppet[:http_proxy_port]
- end
- http = Net::HTTP.new(*args)
-
- # Pop open the http client a little; older versions of Net::HTTP(s) didn't
- # give us a reader for ca_file... Grr...
- class << http; attr_accessor :ca_file; end
-
- http.use_ssl = true
- # Use configured timeout (#1176)
- http.read_timeout = Puppet[:configtimeout]
- http.open_timeout = Puppet[:configtimeout]
-
- cert_setup(http)
-
- http_cache[key] = http if keep_alive?
-
- http
+ args = [host, port]
+ if Puppet[:http_proxy_host] == "none"
+ args << nil << nil
+ else
+ args << Puppet[:http_proxy_host] << Puppet[:http_proxy_port]
end
+ http = Net::HTTP.new(*args)
+
+ # Pop open the http client a little; older versions of Net::HTTP(s) didn't
+ # give us a reader for ca_file... Grr...
+ class << http; attr_accessor :ca_file; end
+
+ http.use_ssl = true
+ # Use configured timeout (#1176)
+ http.read_timeout = Puppet[:configtimeout]
+ http.open_timeout = Puppet[:configtimeout]
+
+ cert_setup(http)
+
+ http_cache[key] = http if keep_alive?
+
+ http
+ end
end
diff --git a/lib/puppet/network/http_server/mongrel.rb b/lib/puppet/network/http_server/mongrel.rb
index 0f81bf2..9bd949a 100644
--- a/lib/puppet/network/http_server/mongrel.rb
+++ b/lib/puppet/network/http_server/mongrel.rb
@@ -49,102 +49,102 @@ require 'resolv'
# handler.xmlrpc_server.add_handler("my.add") { |a, b| a.to_i + b.to_i }
# </pre>
module Puppet::Network
- class HTTPServer::Mongrel < ::Mongrel::HttpHandler
- attr_reader :xmlrpc_server
-
- def initialize(handlers)
- if Puppet[:debug]
- $mongrel_debug_client = true
- Puppet.debug 'Mongrel client debugging enabled. [$mongrel_debug_client = true].'
- end
- # Create a new instance of BasicServer. We are supposed to subclass it
- # but that does not make sense since we would not introduce any new
- # behaviour and we have to subclass Mongrel::HttpHandler so our handler
- # works for Mongrel.
- @xmlrpc_server = Puppet::Network::XMLRPCServer.new
- handlers.each do |name|
- unless handler = Puppet::Network::Handler.handler(name)
- raise ArgumentError, "Invalid handler #{name}"
- end
- @xmlrpc_server.add_handler(handler.interface, handler.new({}))
- end
+ class HTTPServer::Mongrel < ::Mongrel::HttpHandler
+ attr_reader :xmlrpc_server
+
+ def initialize(handlers)
+ if Puppet[:debug]
+ $mongrel_debug_client = true
+ Puppet.debug 'Mongrel client debugging enabled. [$mongrel_debug_client = true].'
+ end
+ # Create a new instance of BasicServer. We are supposed to subclass it
+ # but that does not make sense since we would not introduce any new
+ # behaviour and we have to subclass Mongrel::HttpHandler so our handler
+ # works for Mongrel.
+ @xmlrpc_server = Puppet::Network::XMLRPCServer.new
+ handlers.each do |name|
+ unless handler = Puppet::Network::Handler.handler(name)
+ raise ArgumentError, "Invalid handler #{name}"
end
+ @xmlrpc_server.add_handler(handler.interface, handler.new({}))
+ end
+ end
- # This method produces the same results as XMLRPC::CGIServer.serve
- # from Ruby's stdlib XMLRPC implementation.
- def process(request, response)
- # Make sure this has been a POST as required for XMLRPC.
- request_method = request.params[Mongrel::Const::REQUEST_METHOD] || Mongrel::Const::GET
- if request_method != "POST"
- response.start(405) { |head, out| out.write("Method Not Allowed") }
- return
- end
-
- # Make sure the user has sent text/xml data.
- request_mime = request.params["CONTENT_TYPE"] || "text/plain"
- if parse_content_type(request_mime).first != "text/xml"
- response.start(400) { |head, out| out.write("Bad Request") }
- return
- end
-
- # Make sure there is data in the body at all.
- length = request.params[Mongrel::Const::CONTENT_LENGTH].to_i
- if length <= 0
- response.start(411) { |head, out| out.write("Length Required") }
- return
- end
-
- # Check the body to be valid.
- if request.body.nil? or request.body.size != length
- response.start(400) { |head, out| out.write("Bad Request") }
- return
- end
-
- info = client_info(request)
-
- # All checks above passed through
- response.start(200) do |head, out|
- head["Content-Type"] = "text/xml; charset=utf-8"
- begin
- out.write(@xmlrpc_server.process(request.body, info))
- rescue => detail
- puts detail.backtrace
- raise
- end
- end
+ # This method produces the same results as XMLRPC::CGIServer.serve
+ # from Ruby's stdlib XMLRPC implementation.
+ def process(request, response)
+ # Make sure this has been a POST as required for XMLRPC.
+ request_method = request.params[Mongrel::Const::REQUEST_METHOD] || Mongrel::Const::GET
+ if request_method != "POST"
+ response.start(405) { |head, out| out.write("Method Not Allowed") }
+ return
+ end
+
+ # Make sure the user has sent text/xml data.
+ request_mime = request.params["CONTENT_TYPE"] || "text/plain"
+ if parse_content_type(request_mime).first != "text/xml"
+ response.start(400) { |head, out| out.write("Bad Request") }
+ return
+ end
+
+ # Make sure there is data in the body at all.
+ length = request.params[Mongrel::Const::CONTENT_LENGTH].to_i
+ if length <= 0
+ response.start(411) { |head, out| out.write("Length Required") }
+ return
+ end
+
+ # Check the body to be valid.
+ if request.body.nil? or request.body.size != length
+ response.start(400) { |head, out| out.write("Bad Request") }
+ return
+ end
+
+ info = client_info(request)
+
+ # All checks above passed through
+ response.start(200) do |head, out|
+ head["Content-Type"] = "text/xml; charset=utf-8"
+ begin
+ out.write(@xmlrpc_server.process(request.body, info))
+ rescue => detail
+ puts detail.backtrace
+ raise
end
+ end
+ end
- private
-
- def client_info(request)
- params = request.params
- ip = params["HTTP_X_FORWARDED_FOR"] ? params["HTTP_X_FORWARDED_FOR"].split(',').last.strip : params["REMOTE_ADDR"]
- # JJM #906 The following dn.match regular expression is forgiving
- # enough to match the two Distinguished Name string contents
- # coming from Apache, Pound or other reverse SSL proxies.
- if dn = params[Puppet[:ssl_client_header]] and dn_matchdata = dn.match(/^.*?CN\s*=\s*(.*)/)
- client = dn_matchdata[1].to_str
- valid = (params[Puppet[:ssl_client_verify_header]] == 'SUCCESS')
- else
- begin
- client = Resolv.getname(ip)
- rescue => detail
- Puppet.err "Could not resolve #{ip}: #{detail}"
- client = "unknown"
- end
- valid = false
- end
-
- info = Puppet::Network::ClientRequest.new(client, ip, valid)
-
- info
+ private
+
+ def client_info(request)
+ params = request.params
+ ip = params["HTTP_X_FORWARDED_FOR"] ? params["HTTP_X_FORWARDED_FOR"].split(',').last.strip : params["REMOTE_ADDR"]
+ # JJM #906 The following dn.match regular expression is forgiving
+ # enough to match the two Distinguished Name string contents
+ # coming from Apache, Pound or other reverse SSL proxies.
+ if dn = params[Puppet[:ssl_client_header]] and dn_matchdata = dn.match(/^.*?CN\s*=\s*(.*)/)
+ client = dn_matchdata[1].to_str
+ valid = (params[Puppet[:ssl_client_verify_header]] == 'SUCCESS')
+ else
+ begin
+ client = Resolv.getname(ip)
+ rescue => detail
+ Puppet.err "Could not resolve #{ip}: #{detail}"
+ client = "unknown"
end
+ valid = false
+ end
- # Taken from XMLRPC::ParseContentType
- def parse_content_type(str)
- a, *b = str.split(";")
- return a.strip, *b
- end
+ info = Puppet::Network::ClientRequest.new(client, ip, valid)
+
+ info
+ end
+
+ # Taken from XMLRPC::ParseContentType
+ def parse_content_type(str)
+ a, *b = str.split(";")
+ return a.strip, *b
end
+ end
end
diff --git a/lib/puppet/network/http_server/webrick.rb b/lib/puppet/network/http_server/webrick.rb
index e622b71..1f4b3b0 100644
--- a/lib/puppet/network/http_server/webrick.rb
+++ b/lib/puppet/network/http_server/webrick.rb
@@ -10,146 +10,146 @@ require 'puppet/network/client'
require 'puppet/network/handler'
module Puppet
- class ServerError < RuntimeError; end
- module Network
- # The old-school, pure ruby webrick server, which is the default serving
- # mechanism.
- class HTTPServer::WEBrick < WEBrick::HTTPServer
- include Puppet::SSLCertificates::Support
-
- # Read the CA cert and CRL and populate an OpenSSL::X509::Store
- # with them, with flags appropriate for checking client
- # certificates for revocation
- def x509store
- unless File.exist?(Puppet[:cacrl])
- # No CRL, no store needed
- return nil
- end
- crl = OpenSSL::X509::CRL.new(File.read(Puppet[:cacrl]))
- store = OpenSSL::X509::Store.new
- store.purpose = OpenSSL::X509::PURPOSE_ANY
- store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK if Puppet.settings[:certificate_revocation]
- raise Puppet::Error, "Could not find CA certificate" unless self.ca_cert
-
- store.add_file(Puppet[:localcacert])
- store.add_crl(crl)
- store
- end
-
- # Set up the http log.
- def httplog
- args = []
-
- # yuck; separate http logs
- file = nil
- Puppet.settings.use(:main, :ssl, Puppet[:name])
- if Puppet.run_mode.master?
- file = Puppet[:masterhttplog]
- else
- file = Puppet[:httplog]
- end
-
- # open the log manually to prevent file descriptor leak
- file_io = open(file, "a+")
- file_io.sync
- file_io.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
-
- args << file_io
- args << WEBrick::Log::DEBUG if Puppet[:debug]
-
- log = WEBrick::Log.new(*args)
-
-
- log
- end
-
- # Create our server, yo.
- def initialize(hash = {})
- Puppet.info "Starting server for Puppet version #{Puppet.version}"
-
- if handlers = hash[:Handlers]
- handler_instances = setup_handlers(handlers)
- else
- raise ServerError, "A server must have handlers"
- end
-
- unless self.read_cert
- if ca = handler_instances.find { |handler| handler.is_a?(Puppet::Network::Handler.ca) }
- request_cert(ca)
- else
- raise Puppet::Error, "No certificate and no CA; cannot get cert"
- end
- end
-
- setup_webrick(hash)
-
- begin
- super(hash)
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- raise Puppet::Error, "Could not start WEBrick: #{detail}"
- end
-
- # make sure children don't inherit the sockets
- listeners.each { |sock|
- sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
- }
-
- Puppet.info "Listening on port #{hash[:Port]}"
-
- # this creates a new servlet for every connection,
- # but all servlets have the same list of handlers
- # thus, the servlets can have their own state -- passing
- # around the requests and such -- but the handlers
- # have a global state
-
- # mount has to be called after the server is initialized
- servlet = Puppet::Network::XMLRPC::WEBrickServlet.new( handler_instances)
- self.mount("/RPC2", servlet)
- end
-
- # Create a ca client to set up our cert for us.
- def request_cert(ca)
- client = Puppet::Network::Client.ca.new(:CA => ca)
- raise Puppet::Error, "Could get certificate" unless client.request_cert
- end
-
- # Create all of our handler instances.
- def setup_handlers(handlers)
- raise ServerError, "Handlers must have arguments" unless handlers.is_a?(Hash)
-
- handlers.collect { |handler, args|
- hclass = nil
- unless hclass = Puppet::Network::Handler.handler(handler)
- raise ServerError, "Invalid handler #{handler}"
- end
- hclass.new(args)
- }
- end
-
- # Handle all of the many webrick arguments.
- def setup_webrick(hash)
- hash[:Port] ||= Puppet[:masterport]
- hash[:Logger] ||= self.httplog
- hash[:AccessLog] ||= [
- [ self.httplog, WEBrick::AccessLog::COMMON_LOG_FORMAT ],
- [ self.httplog, WEBrick::AccessLog::REFERER_LOG_FORMAT ]
- ]
-
- hash[:SSLCertificateStore] = x509store
- hash[:SSLCertificate] = self.cert
- hash[:SSLPrivateKey] = self.key
- hash[:SSLStartImmediately] = true
- hash[:SSLEnable] = true
- hash[:SSLCACertificateFile] = Puppet[:localcacert]
- hash[:SSLVerifyClient] = OpenSSL::SSL::VERIFY_PEER
- hash[:SSLCertName] = nil
-
- if addr = Puppet[:bindaddress] and addr != ""
- hash[:BindAddress] = addr
- end
- end
+ class ServerError < RuntimeError; end
+ module Network
+ # The old-school, pure ruby webrick server, which is the default serving
+ # mechanism.
+ class HTTPServer::WEBrick < WEBrick::HTTPServer
+ include Puppet::SSLCertificates::Support
+
+ # Read the CA cert and CRL and populate an OpenSSL::X509::Store
+ # with them, with flags appropriate for checking client
+ # certificates for revocation
+ def x509store
+ unless File.exist?(Puppet[:cacrl])
+ # No CRL, no store needed
+ return nil
end
+ crl = OpenSSL::X509::CRL.new(File.read(Puppet[:cacrl]))
+ store = OpenSSL::X509::Store.new
+ store.purpose = OpenSSL::X509::PURPOSE_ANY
+ store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK if Puppet.settings[:certificate_revocation]
+ raise Puppet::Error, "Could not find CA certificate" unless self.ca_cert
+
+ store.add_file(Puppet[:localcacert])
+ store.add_crl(crl)
+ store
+ end
+
+ # Set up the http log.
+ def httplog
+ args = []
+
+ # yuck; separate http logs
+ file = nil
+ Puppet.settings.use(:main, :ssl, Puppet[:name])
+ if Puppet.run_mode.master?
+ file = Puppet[:masterhttplog]
+ else
+ file = Puppet[:httplog]
+ end
+
+ # open the log manually to prevent file descriptor leak
+ file_io = open(file, "a+")
+ file_io.sync
+ file_io.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
+
+ args << file_io
+ args << WEBrick::Log::DEBUG if Puppet[:debug]
+
+ log = WEBrick::Log.new(*args)
+
+
+ log
+ end
+
+ # Create our server, yo.
+ def initialize(hash = {})
+ Puppet.info "Starting server for Puppet version #{Puppet.version}"
+
+ if handlers = hash[:Handlers]
+ handler_instances = setup_handlers(handlers)
+ else
+ raise ServerError, "A server must have handlers"
+ end
+
+ unless self.read_cert
+ if ca = handler_instances.find { |handler| handler.is_a?(Puppet::Network::Handler.ca) }
+ request_cert(ca)
+ else
+ raise Puppet::Error, "No certificate and no CA; cannot get cert"
+ end
+ end
+
+ setup_webrick(hash)
+
+ begin
+ super(hash)
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ raise Puppet::Error, "Could not start WEBrick: #{detail}"
+ end
+
+ # make sure children don't inherit the sockets
+ listeners.each { |sock|
+ sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
+ }
+
+ Puppet.info "Listening on port #{hash[:Port]}"
+
+ # this creates a new servlet for every connection,
+ # but all servlets have the same list of handlers
+ # thus, the servlets can have their own state -- passing
+ # around the requests and such -- but the handlers
+ # have a global state
+
+ # mount has to be called after the server is initialized
+ servlet = Puppet::Network::XMLRPC::WEBrickServlet.new( handler_instances)
+ self.mount("/RPC2", servlet)
+ end
+
+ # Create a ca client to set up our cert for us.
+ def request_cert(ca)
+ client = Puppet::Network::Client.ca.new(:CA => ca)
+ raise Puppet::Error, "Could get certificate" unless client.request_cert
+ end
+
+ # Create all of our handler instances.
+ def setup_handlers(handlers)
+ raise ServerError, "Handlers must have arguments" unless handlers.is_a?(Hash)
+
+ handlers.collect { |handler, args|
+ hclass = nil
+ unless hclass = Puppet::Network::Handler.handler(handler)
+ raise ServerError, "Invalid handler #{handler}"
+ end
+ hclass.new(args)
+ }
+ end
+
+ # Handle all of the many webrick arguments.
+ def setup_webrick(hash)
+ hash[:Port] ||= Puppet[:masterport]
+ hash[:Logger] ||= self.httplog
+ hash[:AccessLog] ||= [
+ [ self.httplog, WEBrick::AccessLog::COMMON_LOG_FORMAT ],
+ [ self.httplog, WEBrick::AccessLog::REFERER_LOG_FORMAT ]
+ ]
+
+ hash[:SSLCertificateStore] = x509store
+ hash[:SSLCertificate] = self.cert
+ hash[:SSLPrivateKey] = self.key
+ hash[:SSLStartImmediately] = true
+ hash[:SSLEnable] = true
+ hash[:SSLCACertificateFile] = Puppet[:localcacert]
+ hash[:SSLVerifyClient] = OpenSSL::SSL::VERIFY_PEER
+ hash[:SSLCertName] = nil
+
+ if addr = Puppet[:bindaddress] and addr != ""
+ hash[:BindAddress] = addr
+ end
+ end
end
+ end
end
diff --git a/lib/puppet/network/rest_authconfig.rb b/lib/puppet/network/rest_authconfig.rb
index d233c87..38a8f9a 100644
--- a/lib/puppet/network/rest_authconfig.rb
+++ b/lib/puppet/network/rest_authconfig.rb
@@ -1,94 +1,94 @@
require 'puppet/network/authconfig'
module Puppet
- class Network::RestAuthConfig < Network::AuthConfig
+ class Network::RestAuthConfig < Network::AuthConfig
- attr_accessor :rights
+ attr_accessor :rights
- DEFAULT_ACL = [
- { :acl => "~ ^\/catalog\/([^\/]+)$", :method => :find, :allow => '$1', :authenticated => true },
- # this one will allow all file access, and thus delegate
- # to fileserver.conf
- { :acl => "/file" },
- { :acl => "/certificate_revocation_list/ca", :method => :find, :authenticated => true },
- { :acl => "/report", :method => :save, :authenticated => true },
- { :acl => "/certificate/ca", :method => :find, :authenticated => false },
- { :acl => "/certificate/", :method => :find, :authenticated => false },
- { :acl => "/certificate_request", :method => [:find, :save], :authenticated => false },
- { :acl => "/status", :method => [:find], :authenticated => true },
- { :acl => "/resource", :method => [:find, :save, :search], :authenticated => true },
- ]
+ DEFAULT_ACL = [
+ { :acl => "~ ^\/catalog\/([^\/]+)$", :method => :find, :allow => '$1', :authenticated => true },
+ # this one will allow all file access, and thus delegate
+ # to fileserver.conf
+ { :acl => "/file" },
+ { :acl => "/certificate_revocation_list/ca", :method => :find, :authenticated => true },
+ { :acl => "/report", :method => :save, :authenticated => true },
+ { :acl => "/certificate/ca", :method => :find, :authenticated => false },
+ { :acl => "/certificate/", :method => :find, :authenticated => false },
+ { :acl => "/certificate_request", :method => [:find, :save], :authenticated => false },
+ { :acl => "/status", :method => [:find], :authenticated => true },
+ { :acl => "/resource", :method => [:find, :save, :search], :authenticated => true },
+ ]
- def self.main
- add_acl = @main.nil?
- super
- @main.insert_default_acl if add_acl and !@main.exists?
- @main
- end
+ def self.main
+ add_acl = @main.nil?
+ super
+ @main.insert_default_acl if add_acl and !@main.exists?
+ @main
+ end
- # check wether this request is allowed in our ACL
- # raise an Puppet::Network::AuthorizedError if the request
- # is denied.
- def allowed?(request)
- read
+ # check wether this request is allowed in our ACL
+ # raise an Puppet::Network::AuthorizedError if the request
+ # is denied.
+ def allowed?(request)
+ read
- # we're splitting the request in part because
- # fail_on_deny could as well be called in the XMLRPC context
- # with a ClientRequest.
+ # we're splitting the request in part because
+ # fail_on_deny could as well be called in the XMLRPC context
+ # with a ClientRequest.
- @rights.fail_on_deny(
- build_uri(request),
+ @rights.fail_on_deny(
+ build_uri(request),
- :node => request.node,
- :ip => request.ip,
- :method => request.method,
- :environment => request.environment,
- :authenticated => request.authenticated)
- end
+ :node => request.node,
+ :ip => request.ip,
+ :method => request.method,
+ :environment => request.environment,
+ :authenticated => request.authenticated)
+ end
- def initialize(file = nil, parsenow = true)
- super(file || Puppet[:rest_authconfig], parsenow)
+ def initialize(file = nil, parsenow = true)
+ super(file || Puppet[:rest_authconfig], parsenow)
- # if we didn't read a file (ie it doesn't exist)
- # make sure we can create some default rights
- @rights ||= Puppet::Network::Rights.new
- end
+ # if we didn't read a file (ie it doesn't exist)
+ # make sure we can create some default rights
+ @rights ||= Puppet::Network::Rights.new
+ end
- def parse
- super()
- insert_default_acl
- end
+ def parse
+ super()
+ insert_default_acl
+ end
- # force regular ACLs to be present
- def insert_default_acl
- DEFAULT_ACL.each do |acl|
- unless rights[acl[:acl]]
- Puppet.info "Inserting default '#{acl[:acl]}'(#{acl[:authenticated] ? "auth" : "non-auth"}) acl because #{( !exists? ? "#{Puppet[:rest_authconfig]} doesn't exist" : "none where found in '#{@file}'")}"
- mk_acl(acl)
- end
- end
- # queue an empty (ie deny all) right for every other path
- # actually this is not strictly necessary as the rights system
- # denies not explicitely allowed paths
- unless rights["/"]
- rights.newright("/")
- rights.restrict_authenticated("/", :any)
- end
+ # force regular ACLs to be present
+ def insert_default_acl
+ DEFAULT_ACL.each do |acl|
+ unless rights[acl[:acl]]
+ Puppet.info "Inserting default '#{acl[:acl]}'(#{acl[:authenticated] ? "auth" : "non-auth"}) acl because #{( !exists? ? "#{Puppet[:rest_authconfig]} doesn't exist" : "none where found in '#{@file}'")}"
+ mk_acl(acl)
end
+ end
+ # queue an empty (ie deny all) right for every other path
+ # actually this is not strictly necessary as the rights system
+ # denies not explicitely allowed paths
+ unless rights["/"]
+ rights.newright("/")
+ rights.restrict_authenticated("/", :any)
+ end
+ end
- def mk_acl(acl)
- @rights.newright(acl[:acl])
- @rights.allow(acl[:acl], acl[:allow] || "*")
+ def mk_acl(acl)
+ @rights.newright(acl[:acl])
+ @rights.allow(acl[:acl], acl[:allow] || "*")
- if method = acl[:method]
- method = [method] unless method.is_a?(Array)
- method.each { |m| @rights.restrict_method(acl[:acl], m) }
- end
- @rights.restrict_authenticated(acl[:acl], acl[:authenticated]) unless acl[:authenticated].nil?
- end
+ if method = acl[:method]
+ method = [method] unless method.is_a?(Array)
+ method.each { |m| @rights.restrict_method(acl[:acl], m) }
+ end
+ @rights.restrict_authenticated(acl[:acl], acl[:authenticated]) unless acl[:authenticated].nil?
+ end
- def build_uri(request)
- "/#{request.indirection_name}/#{request.key}"
- end
+ def build_uri(request)
+ "/#{request.indirection_name}/#{request.key}"
end
+ end
end
diff --git a/lib/puppet/network/rest_authorization.rb b/lib/puppet/network/rest_authorization.rb
index d9a8370..e052245 100644
--- a/lib/puppet/network/rest_authorization.rb
+++ b/lib/puppet/network/rest_authorization.rb
@@ -3,21 +3,21 @@ require 'puppet/network/rest_authconfig'
module Puppet::Network
- module RestAuthorization
+ module RestAuthorization
- # Create our config object if necessary. If there's no configuration file
- # we install our defaults
- def authconfig
- @authconfig ||= Puppet::Network::RestAuthConfig.main
+ # Create our config object if necessary. If there's no configuration file
+ # we install our defaults
+ def authconfig
+ @authconfig ||= Puppet::Network::RestAuthConfig.main
- @authconfig
- end
+ @authconfig
+ end
- # Verify that our client has access.
- def check_authorization(request)
- authconfig.allowed?(request)
- end
+ # Verify that our client has access.
+ def check_authorization(request)
+ authconfig.allowed?(request)
end
+ end
end
diff --git a/lib/puppet/network/rights.rb b/lib/puppet/network/rights.rb
index a57260a..e3cd317 100755
--- a/lib/puppet/network/rights.rb
+++ b/lib/puppet/network/rights.rb
@@ -12,256 +12,256 @@ class AuthorizationError < Puppet::Error; end
# * path based rights (which are matched on a longest prefix basis)
class Rights
- # We basically just proxy directly to our rights. Each Right stores
- # its own auth abilities.
- [:allow, :deny, :restrict_method, :restrict_environment, :restrict_authenticated].each do |method|
- define_method(method) do |name, *args|
- if obj = self[name]
- obj.send(method, *args)
- else
- raise ArgumentError, "Unknown right '#{name}'"
- end
- end
+ # We basically just proxy directly to our rights. Each Right stores
+ # its own auth abilities.
+ [:allow, :deny, :restrict_method, :restrict_environment, :restrict_authenticated].each do |method|
+ define_method(method) do |name, *args|
+ if obj = self[name]
+ obj.send(method, *args)
+ else
+ raise ArgumentError, "Unknown right '#{name}'"
+ end
end
-
- # Check that name is allowed or not
- def allowed?(name, *args)
- begin
- fail_on_deny(name, :node => args[0], :ip => args[1])
- rescue AuthorizationError
- return false
- rescue ArgumentError
- # the namespace contract says we should raise this error
- # if we didn't find the right acl
- raise
- end
- true
+ end
+
+ # Check that name is allowed or not
+ def allowed?(name, *args)
+ begin
+ fail_on_deny(name, :node => args[0], :ip => args[1])
+ rescue AuthorizationError
+ return false
+ rescue ArgumentError
+ # the namespace contract says we should raise this error
+ # if we didn't find the right acl
+ raise
end
-
- def fail_on_deny(name, args = {})
- res = :nomatch
- right = @rights.find do |acl|
- found = false
- # an acl can return :dunno, which means "I'm not qualified to answer your question,
- # please ask someone else". This is used when for instance an acl matches, but not for the
- # current rest method, where we might think some other acl might be more specific.
- if match = acl.match?(name)
- args[:match] = match
- if (res = acl.allowed?(args[:node], args[:ip], args)) != :dunno
- # return early if we're allowed
- return if res
- # we matched, select this acl
- found = true
- end
- end
- found
- end
-
- # if we end here, then that means we either didn't match
- # or failed, in any case will throw an error to the outside world
- if name =~ /^\// or right
- # we're a patch ACL, let's fail
- msg = "#{(args[:node].nil? ? args[:ip] : "#{args[:node]}(#{args[:ip]})")} access to #{name} [#{args[:method]}]"
-
- msg += " authenticated " if args[:authenticated]
-
- error = AuthorizationError.new("Forbidden request: #{msg}")
- if right
- error.file = right.file
- error.line = right.line
- end
- Puppet.warning("Denying access: #{error}")
- else
- # there were no rights allowing/denying name
- # if name is not a path, let's throw
- error = ArgumentError.new "Unknown namespace right '#{name}'"
+ true
+ end
+
+ def fail_on_deny(name, args = {})
+ res = :nomatch
+ right = @rights.find do |acl|
+ found = false
+ # an acl can return :dunno, which means "I'm not qualified to answer your question,
+ # please ask someone else". This is used when for instance an acl matches, but not for the
+ # current rest method, where we might think some other acl might be more specific.
+ if match = acl.match?(name)
+ args[:match] = match
+ if (res = acl.allowed?(args[:node], args[:ip], args)) != :dunno
+ # return early if we're allowed
+ return if res
+ # we matched, select this acl
+ found = true
end
- raise error
+ end
+ found
end
- def initialize
- @rights = []
+ # if we end here, then that means we either didn't match
+ # or failed, in any case will throw an error to the outside world
+ if name =~ /^\// or right
+ # we're a patch ACL, let's fail
+ msg = "#{(args[:node].nil? ? args[:ip] : "#{args[:node]}(#{args[:ip]})")} access to #{name} [#{args[:method]}]"
+
+ msg += " authenticated " if args[:authenticated]
+
+ error = AuthorizationError.new("Forbidden request: #{msg}")
+ if right
+ error.file = right.file
+ error.line = right.line
+ end
+ Puppet.warning("Denying access: #{error}")
+ else
+ # there were no rights allowing/denying name
+ # if name is not a path, let's throw
+ error = ArgumentError.new "Unknown namespace right '#{name}'"
end
+ raise error
+ end
- def [](name)
- @rights.find { |acl| acl == name }
- end
+ def initialize
+ @rights = []
+ end
- def include?(name)
- @rights.include?(name)
- end
+ def [](name)
+ @rights.find { |acl| acl == name }
+ end
- def each
- @rights.each { |r| yield r.name,r }
- end
+ def include?(name)
+ @rights.include?(name)
+ end
- # Define a new right to which access can be provided.
- def newright(name, line=nil, file=nil)
- add_right( Right.new(name, line, file) )
- end
+ def each
+ @rights.each { |r| yield r.name,r }
+ end
- private
+ # Define a new right to which access can be provided.
+ def newright(name, line=nil, file=nil)
+ add_right( Right.new(name, line, file) )
+ end
- def add_right(right)
- if right.acl_type == :name and include?(right.key)
- raise ArgumentError, "Right '%s' already exists"
- end
- @rights << right
- sort_rights
- right
- end
+ private
- def sort_rights
- @rights.sort!
+ def add_right(right)
+ if right.acl_type == :name and include?(right.key)
+ raise ArgumentError, "Right '%s' already exists"
end
-
- # Retrieve a right by name.
- def right(name)
- self[name]
+ @rights << right
+ sort_rights
+ right
+ end
+
+ def sort_rights
+ @rights.sort!
+ end
+
+ # Retrieve a right by name.
+ def right(name)
+ self[name]
+ end
+
+ # A right.
+ class Right < Puppet::Network::AuthStore
+ include Puppet::FileCollection::Lookup
+
+ attr_accessor :name, :key, :acl_type
+ attr_accessor :methods, :environment, :authentication
+
+ ALL = [:save, :destroy, :find, :search]
+
+ Puppet::Util.logmethods(self, true)
+
+ def initialize(name, line, file)
+ @methods = []
+ @environment = []
+ @authentication = true # defaults to authenticated
+ @name = name
+ @line = line || 0
+ @file = file
+
+ case name
+ when Symbol
+ @acl_type = :name
+ @key = name
+ when /^\[(.+)\]$/
+ @acl_type = :name
+ @key = $1.intern if name.is_a?(String)
+ when /^\//
+ @acl_type = :regex
+ @key = Regexp.new("^" + Regexp.escape(name))
+ @methods = ALL
+ when /^~/ # this is a regex
+ @acl_type = :regex
+ @name = name.gsub(/^~\s+/,'')
+ @key = Regexp.new(@name)
+ @methods = ALL
+ else
+ raise ArgumentError, "Unknown right type '#{name}'"
+ end
+ super()
end
- # A right.
- class Right < Puppet::Network::AuthStore
- include Puppet::FileCollection::Lookup
-
- attr_accessor :name, :key, :acl_type
- attr_accessor :methods, :environment, :authentication
-
- ALL = [:save, :destroy, :find, :search]
-
- Puppet::Util.logmethods(self, true)
-
- def initialize(name, line, file)
- @methods = []
- @environment = []
- @authentication = true # defaults to authenticated
- @name = name
- @line = line || 0
- @file = file
-
- case name
- when Symbol
- @acl_type = :name
- @key = name
- when /^\[(.+)\]$/
- @acl_type = :name
- @key = $1.intern if name.is_a?(String)
- when /^\//
- @acl_type = :regex
- @key = Regexp.new("^" + Regexp.escape(name))
- @methods = ALL
- when /^~/ # this is a regex
- @acl_type = :regex
- @name = name.gsub(/^~\s+/,'')
- @key = Regexp.new(@name)
- @methods = ALL
- else
- raise ArgumentError, "Unknown right type '#{name}'"
- end
- super()
- end
-
- def to_s
- "access[#{@name}]"
- end
-
- # There's no real check to do at this point
- def valid?
- true
- end
+ def to_s
+ "access[#{@name}]"
+ end
- def regex?
- acl_type == :regex
- end
+ # There's no real check to do at this point
+ def valid?
+ true
+ end
- # does this right is allowed for this triplet?
- # if this right is too restrictive (ie we don't match this access method)
- # then return :dunno so that upper layers have a chance to try another right
- # tailored to the given method
- def allowed?(name, ip, args = {})
- return :dunno if acl_type == :regex and not @methods.include?(args[:method])
- return :dunno if acl_type == :regex and @environment.size > 0 and not @environment.include?(args[:environment])
- return :dunno if acl_type == :regex and not @authentication.nil? and args[:authenticated] != @authentication
-
- begin
- # make sure any capture are replaced if needed
- interpolate(args[:match]) if acl_type == :regex and args[:match]
- res = super(name,ip)
- ensure
- reset_interpolation if acl_type == :regex
- end
- res
- end
+ def regex?
+ acl_type == :regex
+ end
- # restrict this right to some method only
- def restrict_method(m)
- m = m.intern if m.is_a?(String)
+ # does this right is allowed for this triplet?
+ # if this right is too restrictive (ie we don't match this access method)
+ # then return :dunno so that upper layers have a chance to try another right
+ # tailored to the given method
+ def allowed?(name, ip, args = {})
+ return :dunno if acl_type == :regex and not @methods.include?(args[:method])
+ return :dunno if acl_type == :regex and @environment.size > 0 and not @environment.include?(args[:environment])
+ return :dunno if acl_type == :regex and not @authentication.nil? and args[:authenticated] != @authentication
+
+ begin
+ # make sure any capture are replaced if needed
+ interpolate(args[:match]) if acl_type == :regex and args[:match]
+ res = super(name,ip)
+ ensure
+ reset_interpolation if acl_type == :regex
+ end
+ res
+ end
- raise ArgumentError, "'#{m}' is not an allowed value for method directive" unless ALL.include?(m)
+ # restrict this right to some method only
+ def restrict_method(m)
+ m = m.intern if m.is_a?(String)
- # if we were allowing all methods, then starts from scratch
- if @methods === ALL
- @methods = []
- end
+ raise ArgumentError, "'#{m}' is not an allowed value for method directive" unless ALL.include?(m)
- raise ArgumentError, "'#{m}' is already in the '#{name}' ACL" if @methods.include?(m)
+ # if we were allowing all methods, then starts from scratch
+ if @methods === ALL
+ @methods = []
+ end
- @methods << m
- end
+ raise ArgumentError, "'#{m}' is already in the '#{name}' ACL" if @methods.include?(m)
- def restrict_environment(env)
- env = Puppet::Node::Environment.new(env)
- raise ArgumentError, "'#{env}' is already in the '#{name}' ACL" if @environment.include?(env)
+ @methods << m
+ end
- @environment << env
- end
+ def restrict_environment(env)
+ env = Puppet::Node::Environment.new(env)
+ raise ArgumentError, "'#{env}' is already in the '#{name}' ACL" if @environment.include?(env)
- def restrict_authenticated(authentication)
- case authentication
- when "yes", "on", "true", true
- authentication = true
- when "no", "off", "false", false
- authentication = false
- when "all","any", :all, :any
- authentication = nil
- else
- raise ArgumentError, "'#{name}' incorrect authenticated value: #{authentication}"
- end
- @authentication = authentication
- end
+ @environment << env
+ end
- def match?(key)
- # if we are a namespace compare directly
- return self.key == namespace_to_key(key) if acl_type == :name
+ def restrict_authenticated(authentication)
+ case authentication
+ when "yes", "on", "true", true
+ authentication = true
+ when "no", "off", "false", false
+ authentication = false
+ when "all","any", :all, :any
+ authentication = nil
+ else
+ raise ArgumentError, "'#{name}' incorrect authenticated value: #{authentication}"
+ end
+ @authentication = authentication
+ end
- # otherwise match with the regex
- self.key.match(key)
- end
+ def match?(key)
+ # if we are a namespace compare directly
+ return self.key == namespace_to_key(key) if acl_type == :name
- def namespace_to_key(key)
- key = key.intern if key.is_a?(String)
- key
- end
+ # otherwise match with the regex
+ self.key.match(key)
+ end
- # this is where all the magic happens.
- # we're sorting the rights array with this scheme:
- # * namespace rights are all in front
- # * regex path rights are then all queued in file order
- def <=>(rhs)
- # move namespace rights at front
- return self.acl_type == :name ? -1 : 1 if self.acl_type != rhs.acl_type
-
- # sort by creation order (ie first match appearing in the file will win)
- # that is don't sort, in which case the sort algorithm will order in the
- # natural array order (ie the creation order)
- 0
- end
+ def namespace_to_key(key)
+ key = key.intern if key.is_a?(String)
+ key
+ end
- def ==(name)
- return(acl_type == :name ? self.key == namespace_to_key(name) : self.name == name.gsub(/^~\s+/,''))
- end
+ # this is where all the magic happens.
+ # we're sorting the rights array with this scheme:
+ # * namespace rights are all in front
+ # * regex path rights are then all queued in file order
+ def <=>(rhs)
+ # move namespace rights at front
+ return self.acl_type == :name ? -1 : 1 if self.acl_type != rhs.acl_type
+
+ # sort by creation order (ie first match appearing in the file will win)
+ # that is don't sort, in which case the sort algorithm will order in the
+ # natural array order (ie the creation order)
+ 0
+ end
+ def ==(name)
+ return(acl_type == :name ? self.key == namespace_to_key(name) : self.name == name.gsub(/^~\s+/,''))
end
+ end
+
end
end
diff --git a/lib/puppet/network/server.rb b/lib/puppet/network/server.rb
index e4945be..d424b9c 100644
--- a/lib/puppet/network/server.rb
+++ b/lib/puppet/network/server.rb
@@ -2,164 +2,164 @@ require 'puppet/network/http'
require 'puppet/util/pidlock'
class Puppet::Network::Server
- attr_reader :server_type, :protocols, :address, :port
-
- # Put the daemon into the background.
- def daemonize
- if pid = fork
- Process.detach(pid)
- exit(0)
- end
-
- # Get rid of console logging
- Puppet::Util::Log.close(:console)
-
- Process.setsid
- Dir.chdir("/")
- begin
- $stdin.reopen "/dev/null"
- $stdout.reopen "/dev/null", "a"
- $stderr.reopen $stdout
- Puppet::Util::Log.reopen
- rescue => detail
- Puppet::Util.secure_open("/tmp/daemonout", "w") { |f|
- f.puts "Could not start #{Puppet[:name]}: #{detail}"
- }
- raise "Could not start #{Puppet[:name]}: #{detail}"
- end
+ attr_reader :server_type, :protocols, :address, :port
+
+ # Put the daemon into the background.
+ def daemonize
+ if pid = fork
+ Process.detach(pid)
+ exit(0)
+ end
+
+ # Get rid of console logging
+ Puppet::Util::Log.close(:console)
+
+ Process.setsid
+ Dir.chdir("/")
+ begin
+ $stdin.reopen "/dev/null"
+ $stdout.reopen "/dev/null", "a"
+ $stderr.reopen $stdout
+ Puppet::Util::Log.reopen
+ rescue => detail
+ Puppet::Util.secure_open("/tmp/daemonout", "w") { |f|
+ f.puts "Could not start #{Puppet[:name]}: #{detail}"
+ }
+ raise "Could not start #{Puppet[:name]}: #{detail}"
end
+ end
- # Create a pidfile for our daemon, so we can be stopped and others
- # don't try to start.
- def create_pidfile
- Puppet::Util.sync(Puppet[:name]).synchronize(Sync::EX) do
- raise "Could not create PID file: #{pidfile}" unless Puppet::Util::Pidlock.new(pidfile).lock
- end
- end
-
- # Remove the pid file for our daemon.
- def remove_pidfile
- Puppet::Util.sync(Puppet[:name]).synchronize(Sync::EX) do
- locker = Puppet::Util::Pidlock.new(pidfile)
- locker.unlock or Puppet.err "Could not remove PID file #{pidfile}" if locker.locked?
- end
- end
+ # Create a pidfile for our daemon, so we can be stopped and others
+ # don't try to start.
+ def create_pidfile
+ Puppet::Util.sync(Puppet[:name]).synchronize(Sync::EX) do
+ raise "Could not create PID file: #{pidfile}" unless Puppet::Util::Pidlock.new(pidfile).lock
+ end
+ end
- # Provide the path to our pidfile.
- def pidfile
- Puppet[:pidfile]
- end
+ # Remove the pid file for our daemon.
+ def remove_pidfile
+ Puppet::Util.sync(Puppet[:name]).synchronize(Sync::EX) do
+ locker = Puppet::Util::Pidlock.new(pidfile)
+ locker.unlock or Puppet.err "Could not remove PID file #{pidfile}" if locker.locked?
+ end
+ end
+
+ # Provide the path to our pidfile.
+ def pidfile
+ Puppet[:pidfile]
+ end
+
+ def initialize(args = {})
+ valid_args = [:handlers, :xmlrpc_handlers, :port]
+ bad_args = args.keys.find_all { |p| ! valid_args.include?(p) }.collect { |p| p.to_s }.join(",")
+ raise ArgumentError, "Invalid argument(s) #{bad_args}" unless bad_args == ""
+ @server_type = Puppet[:servertype] or raise "No servertype configuration found." # e.g., WEBrick, Mongrel, etc.
+ http_server_class || raise(ArgumentError, "Could not determine HTTP Server class for server type [#{@server_type}]")
- def initialize(args = {})
- valid_args = [:handlers, :xmlrpc_handlers, :port]
- bad_args = args.keys.find_all { |p| ! valid_args.include?(p) }.collect { |p| p.to_s }.join(",")
- raise ArgumentError, "Invalid argument(s) #{bad_args}" unless bad_args == ""
- @server_type = Puppet[:servertype] or raise "No servertype configuration found." # e.g., WEBrick, Mongrel, etc.
- http_server_class || raise(ArgumentError, "Could not determine HTTP Server class for server type [#{@server_type}]")
-
- @port = args[:port] || Puppet[:masterport] || raise(ArgumentError, "Must specify :port or configure Puppet :masterport")
- @address = determine_bind_address
-
- @protocols = [ :rest, :xmlrpc ]
- @listening = false
- @routes = {}
- @xmlrpc_routes = {}
- self.register(args[:handlers]) if args[:handlers]
- self.register_xmlrpc(args[:xmlrpc_handlers]) if args[:xmlrpc_handlers]
-
- # Make sure we have all of the directories we need to function.
- Puppet.settings.use(:main, :ssl, Puppet[:name])
- end
+ @port = args[:port] || Puppet[:masterport] || raise(ArgumentError, "Must specify :port or configure Puppet :masterport")
+ @address = determine_bind_address
+
+ @protocols = [ :rest, :xmlrpc ]
+ @listening = false
+ @routes = {}
+ @xmlrpc_routes = {}
+ self.register(args[:handlers]) if args[:handlers]
+ self.register_xmlrpc(args[:xmlrpc_handlers]) if args[:xmlrpc_handlers]
+
+ # Make sure we have all of the directories we need to function.
+ Puppet.settings.use(:main, :ssl, Puppet[:name])
+ end
+
+ # Register handlers for REST networking, based on the Indirector.
+ def register(*indirections)
+ raise ArgumentError, "Indirection names are required." if indirections.empty?
+ indirections.flatten.each do |name|
+ Puppet::Indirector::Indirection.model(name) || raise(ArgumentError, "Cannot locate indirection '#{name}'.")
+ @routes[name.to_sym] = true
+ end
+ end
+
+ # Unregister Indirector handlers.
+ def unregister(*indirections)
+ raise "Cannot unregister indirections while server is listening." if listening?
+ indirections = @routes.keys if indirections.empty?
+
+ indirections.flatten.each do |i|
+ raise(ArgumentError, "Indirection [#{i}] is unknown.") unless @routes[i.to_sym]
+ end
+
+ indirections.flatten.each do |i|
+ @routes.delete(i.to_sym)
+ end
+ end
+
+ # Register xmlrpc handlers for backward compatibility.
+ def register_xmlrpc(*namespaces)
+ raise ArgumentError, "XMLRPC namespaces are required." if namespaces.empty?
+ namespaces.flatten.each do |name|
+ Puppet::Network::Handler.handler(name) || raise(ArgumentError, "Cannot locate XMLRPC handler for namespace '#{name}'.")
+ @xmlrpc_routes[name.to_sym] = true
+ end
+ end
+
+ # Unregister xmlrpc handlers.
+ def unregister_xmlrpc(*namespaces)
+ raise "Cannot unregister xmlrpc handlers while server is listening." if listening?
+ namespaces = @xmlrpc_routes.keys if namespaces.empty?
+
+ namespaces.flatten.each do |i|
+ raise(ArgumentError, "XMLRPC handler '#{i}' is unknown.") unless @xmlrpc_routes[i.to_sym]
+ end
+
+ namespaces.flatten.each do |i|
+ @xmlrpc_routes.delete(i.to_sym)
+ end
+ end
+
+ def listening?
+ @listening
+ end
+
+ def listen
+ raise "Cannot listen -- already listening." if listening?
+ @listening = true
+ http_server.listen(:address => address, :port => port, :handlers => @routes.keys, :xmlrpc_handlers => @xmlrpc_routes.keys, :protocols => protocols)
+ end
- # Register handlers for REST networking, based on the Indirector.
- def register(*indirections)
- raise ArgumentError, "Indirection names are required." if indirections.empty?
- indirections.flatten.each do |name|
- Puppet::Indirector::Indirection.model(name) || raise(ArgumentError, "Cannot locate indirection '#{name}'.")
- @routes[name.to_sym] = true
- end
- end
+ def unlisten
+ raise "Cannot unlisten -- not currently listening." unless listening?
+ http_server.unlisten
+ @listening = false
+ end
- # Unregister Indirector handlers.
- def unregister(*indirections)
- raise "Cannot unregister indirections while server is listening." if listening?
- indirections = @routes.keys if indirections.empty?
+ def http_server_class
+ http_server_class_by_type(@server_type)
+ end
- indirections.flatten.each do |i|
- raise(ArgumentError, "Indirection [#{i}] is unknown.") unless @routes[i.to_sym]
- end
+ def start
+ create_pidfile
+ listen
+ end
- indirections.flatten.each do |i|
- @routes.delete(i.to_sym)
- end
- end
+ def stop
+ unlisten
+ remove_pidfile
+ end
+
+ private
- # Register xmlrpc handlers for backward compatibility.
- def register_xmlrpc(*namespaces)
- raise ArgumentError, "XMLRPC namespaces are required." if namespaces.empty?
- namespaces.flatten.each do |name|
- Puppet::Network::Handler.handler(name) || raise(ArgumentError, "Cannot locate XMLRPC handler for namespace '#{name}'.")
- @xmlrpc_routes[name.to_sym] = true
- end
- end
+ def http_server
+ @http_server ||= http_server_class.new
+ end
- # Unregister xmlrpc handlers.
- def unregister_xmlrpc(*namespaces)
- raise "Cannot unregister xmlrpc handlers while server is listening." if listening?
- namespaces = @xmlrpc_routes.keys if namespaces.empty?
-
- namespaces.flatten.each do |i|
- raise(ArgumentError, "XMLRPC handler '#{i}' is unknown.") unless @xmlrpc_routes[i.to_sym]
- end
-
- namespaces.flatten.each do |i|
- @xmlrpc_routes.delete(i.to_sym)
- end
- end
-
- def listening?
- @listening
- end
-
- def listen
- raise "Cannot listen -- already listening." if listening?
- @listening = true
- http_server.listen(:address => address, :port => port, :handlers => @routes.keys, :xmlrpc_handlers => @xmlrpc_routes.keys, :protocols => protocols)
- end
+ def http_server_class_by_type(kind)
+ Puppet::Network::HTTP.server_class_by_type(kind)
+ end
- def unlisten
- raise "Cannot unlisten -- not currently listening." unless listening?
- http_server.unlisten
- @listening = false
- end
-
- def http_server_class
- http_server_class_by_type(@server_type)
- end
-
- def start
- create_pidfile
- listen
- end
-
- def stop
- unlisten
- remove_pidfile
- end
-
- private
-
- def http_server
- @http_server ||= http_server_class.new
- end
-
- def http_server_class_by_type(kind)
- Puppet::Network::HTTP.server_class_by_type(kind)
- end
-
- def determine_bind_address
- tmp = Puppet[:bindaddress]
- return tmp if tmp != ""
- server_type.to_s == "webrick" ? "0.0.0.0" : "127.0.0.1"
- end
+ def determine_bind_address
+ tmp = Puppet[:bindaddress]
+ return tmp if tmp != ""
+ server_type.to_s == "webrick" ? "0.0.0.0" : "127.0.0.1"
+ end
end
diff --git a/lib/puppet/network/xmlrpc/client.rb b/lib/puppet/network/xmlrpc/client.rb
index 3afd1dc..ca6ac60 100644
--- a/lib/puppet/network/xmlrpc/client.rb
+++ b/lib/puppet/network/xmlrpc/client.rb
@@ -8,204 +8,204 @@ require 'net/https'
require 'yaml'
module Puppet::Network
- class ClientError < Puppet::Error; end
- class XMLRPCClientError < Puppet::Error; end
- class XMLRPCClient < ::XMLRPC::Client
-
- attr_accessor :puppet_server, :puppet_port
- @clients = {}
-
- class << self
- include Puppet::Util
- include Puppet::Util::ClassGen
- end
-
- # Create a netclient for each handler
- def self.mkclient(handler)
- interface = handler.interface
- namespace = interface.prefix
-
- # Create a subclass for every client type. This is
- # so that all of the methods are on their own class,
- # so that their namespaces can define the same methods if
- # they want.
- constant = handler.name.to_s.capitalize
- name = namespace.downcase
- newclient = genclass(name, :hash => @clients, :constant => constant)
-
- interface.methods.each { |ary|
- method = ary[0]
- newclient.send(:define_method,method) { |*args|
- make_rpc_call(namespace, method, *args)
- }
- }
-
- newclient
- end
-
- def self.handler_class(handler)
- @clients[handler] || self.mkclient(handler)
- end
-
- class ErrorHandler
- def initialize(&block)
- singleton_class.define_method(:execute, &block)
- end
- end
-
- # Use a class variable so all subclasses have access to it.
- @@error_handlers = {}
-
- def self.error_handler(exception)
- if handler = @@error_handlers[exception.class]
- return handler
- else
- return @@error_handlers[:default]
- end
- end
-
- def self.handle_error(*exceptions, &block)
- handler = ErrorHandler.new(&block)
-
- exceptions.each do |exception|
- @@error_handlers[exception] = handler
- end
- end
-
- handle_error(OpenSSL::SSL::SSLError) do |client, detail, namespace, method|
- if detail.message =~ /bad write retry/
- Puppet.warning "Transient SSL write error; restarting connection and retrying"
- client.recycle_connection
- return :retry
- end
- ["certificate verify failed", "hostname was not match", "hostname not match"].each do |str|
- Puppet.warning "Certificate validation failed; consider using the certname configuration option" if detail.message.include?(str)
- end
- raise XMLRPCClientError, "Certificates were not trusted: #{detail}"
- end
-
- handle_error(:default) do |client, detail, namespace, method|
- if detail.message.to_s =~ /^Wrong size\. Was \d+, should be \d+$/
- Puppet.warning "XMLRPC returned wrong size. Retrying."
- return :retry
- end
- Puppet.err "Could not call #{namespace}.#{method}: #{detail.inspect}"
- error = XMLRPCClientError.new(detail.to_s)
- error.set_backtrace detail.backtrace
- raise error
- end
-
- handle_error(OpenSSL::SSL::SSLError) do |client, detail, namespace, method|
- if detail.message =~ /bad write retry/
- Puppet.warning "Transient SSL write error; restarting connection and retrying"
- client.recycle_connection
- return :retry
- end
- ["certificate verify failed", "hostname was not match", "hostname not match"].each do |str|
- Puppet.warning "Certificate validation failed; consider using the certname configuration option" if detail.message.include?(str)
- end
- raise XMLRPCClientError, "Certificates were not trusted: #{detail}"
- end
-
- handle_error(::XMLRPC::FaultException) do |client, detail, namespace, method|
- raise XMLRPCClientError, detail.faultString
- end
-
- handle_error(Errno::ECONNREFUSED) do |client, detail, namespace, method|
- msg = "Could not connect to #{client.host} on port #{client.port}"
- raise XMLRPCClientError, msg
- end
-
- handle_error(SocketError) do |client, detail, namespace, method|
- Puppet.err "Could not find server #{@host}: #{detail}"
- error = XMLRPCClientError.new("Could not find server #{client.host}")
- error.set_backtrace detail.backtrace
- raise error
- end
-
- handle_error(Errno::EPIPE, EOFError) do |client, detail, namespace, method|
- Puppet.info "Other end went away; restarting connection and retrying"
- client.recycle_connection
- return :retry
- end
-
- handle_error(Timeout::Error) do |client, detail, namespace, method|
- Puppet.err "Connection timeout calling #{namespace}.#{method}: #{detail}"
- error = XMLRPCClientError.new("Connection Timeout")
- error.set_backtrace(detail.backtrace)
- raise error
- end
-
- def make_rpc_call(namespace, method, *args)
- Puppet.debug "Calling #{namespace}.#{method}"
- begin
- call("#{namespace}.#{method}",*args)
- rescue SystemExit,NoMemoryError
- raise
- rescue Exception => detail
- retry if self.class.error_handler(detail).execute(self, detail, namespace, method) == :retry
- end
- ensure
- http.finish if http.started?
- end
-
- def http
- @http ||= Puppet::Network::HttpPool.http_instance(host, port, true)
- end
-
- attr_reader :host, :port
-
- def initialize(hash = {})
- hash[:Path] ||= "/RPC2"
- hash[:Server] ||= Puppet[:server]
- hash[:Port] ||= Puppet[:masterport]
- hash[:HTTPProxyHost] ||= Puppet[:http_proxy_host]
- hash[:HTTPProxyPort] ||= Puppet[:http_proxy_port]
-
- if "none" == hash[:HTTPProxyHost]
- hash[:HTTPProxyHost] = nil
- hash[:HTTPProxyPort] = nil
- end
-
-
- super(
+ class ClientError < Puppet::Error; end
+ class XMLRPCClientError < Puppet::Error; end
+ class XMLRPCClient < ::XMLRPC::Client
+
+ attr_accessor :puppet_server, :puppet_port
+ @clients = {}
+
+ class << self
+ include Puppet::Util
+ include Puppet::Util::ClassGen
+ end
+
+ # Create a netclient for each handler
+ def self.mkclient(handler)
+ interface = handler.interface
+ namespace = interface.prefix
+
+ # Create a subclass for every client type. This is
+ # so that all of the methods are on their own class,
+ # so that their namespaces can define the same methods if
+ # they want.
+ constant = handler.name.to_s.capitalize
+ name = namespace.downcase
+ newclient = genclass(name, :hash => @clients, :constant => constant)
+
+ interface.methods.each { |ary|
+ method = ary[0]
+ newclient.send(:define_method,method) { |*args|
+ make_rpc_call(namespace, method, *args)
+ }
+ }
+
+ newclient
+ end
+
+ def self.handler_class(handler)
+ @clients[handler] || self.mkclient(handler)
+ end
+
+ class ErrorHandler
+ def initialize(&block)
+ singleton_class.define_method(:execute, &block)
+ end
+ end
+
+ # Use a class variable so all subclasses have access to it.
+ @@error_handlers = {}
+
+ def self.error_handler(exception)
+ if handler = @@error_handlers[exception.class]
+ return handler
+ else
+ return @@error_handlers[:default]
+ end
+ end
+
+ def self.handle_error(*exceptions, &block)
+ handler = ErrorHandler.new(&block)
+
+ exceptions.each do |exception|
+ @@error_handlers[exception] = handler
+ end
+ end
+
+ handle_error(OpenSSL::SSL::SSLError) do |client, detail, namespace, method|
+ if detail.message =~ /bad write retry/
+ Puppet.warning "Transient SSL write error; restarting connection and retrying"
+ client.recycle_connection
+ return :retry
+ end
+ ["certificate verify failed", "hostname was not match", "hostname not match"].each do |str|
+ Puppet.warning "Certificate validation failed; consider using the certname configuration option" if detail.message.include?(str)
+ end
+ raise XMLRPCClientError, "Certificates were not trusted: #{detail}"
+ end
+
+ handle_error(:default) do |client, detail, namespace, method|
+ if detail.message.to_s =~ /^Wrong size\. Was \d+, should be \d+$/
+ Puppet.warning "XMLRPC returned wrong size. Retrying."
+ return :retry
+ end
+ Puppet.err "Could not call #{namespace}.#{method}: #{detail.inspect}"
+ error = XMLRPCClientError.new(detail.to_s)
+ error.set_backtrace detail.backtrace
+ raise error
+ end
+
+ handle_error(OpenSSL::SSL::SSLError) do |client, detail, namespace, method|
+ if detail.message =~ /bad write retry/
+ Puppet.warning "Transient SSL write error; restarting connection and retrying"
+ client.recycle_connection
+ return :retry
+ end
+ ["certificate verify failed", "hostname was not match", "hostname not match"].each do |str|
+ Puppet.warning "Certificate validation failed; consider using the certname configuration option" if detail.message.include?(str)
+ end
+ raise XMLRPCClientError, "Certificates were not trusted: #{detail}"
+ end
+
+ handle_error(::XMLRPC::FaultException) do |client, detail, namespace, method|
+ raise XMLRPCClientError, detail.faultString
+ end
+
+ handle_error(Errno::ECONNREFUSED) do |client, detail, namespace, method|
+ msg = "Could not connect to #{client.host} on port #{client.port}"
+ raise XMLRPCClientError, msg
+ end
+
+ handle_error(SocketError) do |client, detail, namespace, method|
+ Puppet.err "Could not find server #{@host}: #{detail}"
+ error = XMLRPCClientError.new("Could not find server #{client.host}")
+ error.set_backtrace detail.backtrace
+ raise error
+ end
+
+ handle_error(Errno::EPIPE, EOFError) do |client, detail, namespace, method|
+ Puppet.info "Other end went away; restarting connection and retrying"
+ client.recycle_connection
+ return :retry
+ end
+
+ handle_error(Timeout::Error) do |client, detail, namespace, method|
+ Puppet.err "Connection timeout calling #{namespace}.#{method}: #{detail}"
+ error = XMLRPCClientError.new("Connection Timeout")
+ error.set_backtrace(detail.backtrace)
+ raise error
+ end
+
+ def make_rpc_call(namespace, method, *args)
+ Puppet.debug "Calling #{namespace}.#{method}"
+ begin
+ call("#{namespace}.#{method}",*args)
+ rescue SystemExit,NoMemoryError
+ raise
+ rescue Exception => detail
+ retry if self.class.error_handler(detail).execute(self, detail, namespace, method) == :retry
+ end
+ ensure
+ http.finish if http.started?
+ end
+
+ def http
+ @http ||= Puppet::Network::HttpPool.http_instance(host, port, true)
+ end
+
+ attr_reader :host, :port
+
+ def initialize(hash = {})
+ hash[:Path] ||= "/RPC2"
+ hash[:Server] ||= Puppet[:server]
+ hash[:Port] ||= Puppet[:masterport]
+ hash[:HTTPProxyHost] ||= Puppet[:http_proxy_host]
+ hash[:HTTPProxyPort] ||= Puppet[:http_proxy_port]
+
+ if "none" == hash[:HTTPProxyHost]
+ hash[:HTTPProxyHost] = nil
+ hash[:HTTPProxyPort] = nil
+ end
+
+
+ super(
- hash[:Server],
- hash[:Path],
- hash[:Port],
- hash[:HTTPProxyHost],
- hash[:HTTPProxyPort],
+ hash[:Server],
+ hash[:Path],
+ hash[:Port],
+ hash[:HTTPProxyHost],
+ hash[:HTTPProxyPort],
- nil, # user
- nil, # password
- true, # use_ssl
- Puppet[:configtimeout] # use configured timeout (#1176)
- )
- @http = Puppet::Network::HttpPool.http_instance(@host, @port)
- end
-
- # Get rid of our existing connection, replacing it with a new one.
- # This should only happen if we lose our connection somehow (e.g., an EPIPE)
- # or we've just downloaded certs and we need to create new http instances
- # with the certs added.
- def recycle_connection
- http.finish if http.started?
- @http = nil
- self.http # force a new one
- end
-
- def start
- @http.start unless @http.started?
- rescue => detail
- Puppet.err "Could not connect to server: #{detail}"
- end
-
- def local
- false
- end
-
- def local?
- false
- end
+ nil, # user
+ nil, # password
+ true, # use_ssl
+ Puppet[:configtimeout] # use configured timeout (#1176)
+ )
+ @http = Puppet::Network::HttpPool.http_instance(@host, @port)
+ end
+
+ # Get rid of our existing connection, replacing it with a new one.
+ # This should only happen if we lose our connection somehow (e.g., an EPIPE)
+ # or we've just downloaded certs and we need to create new http instances
+ # with the certs added.
+ def recycle_connection
+ http.finish if http.started?
+ @http = nil
+ self.http # force a new one
+ end
+
+ def start
+ @http.start unless @http.started?
+ rescue => detail
+ Puppet.err "Could not connect to server: #{detail}"
+ end
+
+ def local
+ false
+ end
+
+ def local?
+ false
end
+ end
end
diff --git a/lib/puppet/network/xmlrpc/processor.rb b/lib/puppet/network/xmlrpc/processor.rb
index 9d3904f..dea8a02 100644
--- a/lib/puppet/network/xmlrpc/processor.rb
+++ b/lib/puppet/network/xmlrpc/processor.rb
@@ -3,84 +3,84 @@ require 'xmlrpc/server'
# Just silly.
class ::XMLRPC::FaultException
- def to_s
- self.message
- end
+ def to_s
+ self.message
+ end
end
module Puppet::Network
- # Most of our subclassing is just so that we can get
- # access to information from the request object, like
- # the client name and IP address.
- module XMLRPCProcessor
- include Puppet::Network::Authorization
+ # Most of our subclassing is just so that we can get
+ # access to information from the request object, like
+ # the client name and IP address.
+ module XMLRPCProcessor
+ include Puppet::Network::Authorization
- ERR_UNAUTHORIZED = 30
+ ERR_UNAUTHORIZED = 30
- def add_handler(interface, handler)
- @loadedhandlers << interface.prefix
- super(interface, handler)
- end
+ def add_handler(interface, handler)
+ @loadedhandlers << interface.prefix
+ super(interface, handler)
+ end
- def handler_loaded?(handler)
- @loadedhandlers.include?(handler.to_s)
- end
+ def handler_loaded?(handler)
+ @loadedhandlers.include?(handler.to_s)
+ end
- # Convert our data and client request into xmlrpc calls, and verify
- # they're authorized and such-like. This method differs from the
- # default in that it expects a ClientRequest object in addition to the
- # data.
- def process(data, request)
- call, params = parser.parseMethodCall(data)
- params << request.name << request.ip
- handler, method = call.split(".")
- request.handler = handler
- request.method = method
- begin
- verify(request)
- rescue InvalidClientRequest => detail
- raise ::XMLRPC::FaultException.new(ERR_UNAUTHORIZED, detail.to_s)
- end
- handle(request.call, *params)
- end
+ # Convert our data and client request into xmlrpc calls, and verify
+ # they're authorized and such-like. This method differs from the
+ # default in that it expects a ClientRequest object in addition to the
+ # data.
+ def process(data, request)
+ call, params = parser.parseMethodCall(data)
+ params << request.name << request.ip
+ handler, method = call.split(".")
+ request.handler = handler
+ request.method = method
+ begin
+ verify(request)
+ rescue InvalidClientRequest => detail
+ raise ::XMLRPC::FaultException.new(ERR_UNAUTHORIZED, detail.to_s)
+ end
+ handle(request.call, *params)
+ end
- private
+ private
- # Provide error handling for method calls.
- def protect_service(obj, *args)
- begin
- obj.call(*args)
- rescue ::XMLRPC::FaultException
- raise
- rescue Puppet::AuthorizationError => detail
- Puppet.err "Permission denied: #{detail}"
- raise ::XMLRPC::FaultException.new(
- 1, detail.to_s
- )
- rescue Puppet::Error => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err detail.to_s
- error = ::XMLRPC::FaultException.new(
- 1, detail.to_s
- )
- error.set_backtrace detail.backtrace
- raise error
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Could not call: #{detail}"
- error = ::XMLRPC::FaultException.new(1, detail.to_s)
- error.set_backtrace detail.backtrace
- raise error
- end
- end
+ # Provide error handling for method calls.
+ def protect_service(obj, *args)
+ begin
+ obj.call(*args)
+ rescue ::XMLRPC::FaultException
+ raise
+ rescue Puppet::AuthorizationError => detail
+ Puppet.err "Permission denied: #{detail}"
+ raise ::XMLRPC::FaultException.new(
+ 1, detail.to_s
+ )
+ rescue Puppet::Error => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err detail.to_s
+ error = ::XMLRPC::FaultException.new(
+ 1, detail.to_s
+ )
+ error.set_backtrace detail.backtrace
+ raise error
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Could not call: #{detail}"
+ error = ::XMLRPC::FaultException.new(1, detail.to_s)
+ error.set_backtrace detail.backtrace
+ raise error
+ end
+ end
- # Set up our service hook and init our handler list.
- def setup_processor
- @loadedhandlers = []
- self.set_service_hook do |obj, *args|
- protect_service(obj, *args)
- end
- end
+ # Set up our service hook and init our handler list.
+ def setup_processor
+ @loadedhandlers = []
+ self.set_service_hook do |obj, *args|
+ protect_service(obj, *args)
+ end
end
+ end
end
diff --git a/lib/puppet/network/xmlrpc/server.rb b/lib/puppet/network/xmlrpc/server.rb
index 8fdf02b..e548817 100644
--- a/lib/puppet/network/xmlrpc/server.rb
+++ b/lib/puppet/network/xmlrpc/server.rb
@@ -3,17 +3,17 @@ require 'puppet/network/authorization'
require 'puppet/network/xmlrpc/processor'
module Puppet::Network
- # Most of our subclassing is just so that we can get
- # access to information from the request object, like
- # the client name and IP address.
- class XMLRPCServer < ::XMLRPC::BasicServer
- include Puppet::Util
- include Puppet::Network::XMLRPCProcessor
+ # Most of our subclassing is just so that we can get
+ # access to information from the request object, like
+ # the client name and IP address.
+ class XMLRPCServer < ::XMLRPC::BasicServer
+ include Puppet::Util
+ include Puppet::Network::XMLRPCProcessor
- def initialize
- super()
- setup_processor
- end
+ def initialize
+ super()
+ setup_processor
end
+ end
end
diff --git a/lib/puppet/network/xmlrpc/webrick_servlet.rb b/lib/puppet/network/xmlrpc/webrick_servlet.rb
index 035448a..c538cf7 100644
--- a/lib/puppet/network/xmlrpc/webrick_servlet.rb
+++ b/lib/puppet/network/xmlrpc/webrick_servlet.rb
@@ -3,112 +3,112 @@ require 'puppet/network/authorization'
require 'puppet/network/xmlrpc/processor'
module Puppet::Network::XMLRPC
- class ServletError < RuntimeError; end
- class WEBrickServlet < ::XMLRPC::WEBrickServlet
- include Puppet::Network::XMLRPCProcessor
-
- # This is a hackish way to avoid an auth message every time we have a
- # normal operation
- def self.log(msg)
- @logs ||= {}
- if @logs.include?(msg)
- @logs[msg] += 1
- else
- Puppet.info msg
- @logs[msg] = 1
- end
- end
+ class ServletError < RuntimeError; end
+ class WEBrickServlet < ::XMLRPC::WEBrickServlet
+ include Puppet::Network::XMLRPCProcessor
+
+ # This is a hackish way to avoid an auth message every time we have a
+ # normal operation
+ def self.log(msg)
+ @logs ||= {}
+ if @logs.include?(msg)
+ @logs[msg] += 1
+ else
+ Puppet.info msg
+ @logs[msg] = 1
+ end
+ end
- # Accept a list of handlers and register them all.
- def initialize(handlers)
- # the servlet base class does not consume any arguments
- # and its BasicServer base class only accepts a 'class_delim'
- # option which won't change in Puppet at all
- # thus, we don't need to pass any args to our base class,
- # and we can consume them all ourselves
- super()
-
- setup_processor
-
- # Set up each of the passed handlers.
- handlers.each do |handler|
- add_handler(handler.class.interface, handler)
- end
- end
+ # Accept a list of handlers and register them all.
+ def initialize(handlers)
+ # the servlet base class does not consume any arguments
+ # and its BasicServer base class only accepts a 'class_delim'
+ # option which won't change in Puppet at all
+ # thus, we don't need to pass any args to our base class,
+ # and we can consume them all ourselves
+ super()
+
+ setup_processor
+
+ # Set up each of the passed handlers.
+ handlers.each do |handler|
+ add_handler(handler.class.interface, handler)
+ end
+ end
- # Handle the actual request. We can't use the super() method, because
- # we need to pass a ClientRequest object to process so we can do
- # authorization. It's the only way to stay thread-safe.
- def service(request, response)
- if @valid_ip
- raise WEBrick::HTTPStatus::Forbidden unless @valid_ip.any? { |ip| request.peeraddr[3] =~ ip }
- end
+ # Handle the actual request. We can't use the super() method, because
+ # we need to pass a ClientRequest object to process so we can do
+ # authorization. It's the only way to stay thread-safe.
+ def service(request, response)
+ if @valid_ip
+ raise WEBrick::HTTPStatus::Forbidden unless @valid_ip.any? { |ip| request.peeraddr[3] =~ ip }
+ end
- if request.request_method != "POST"
- raise WEBrick::HTTPStatus::MethodNotAllowed,
- "unsupported method `#{request.request_method}'."
- end
+ if request.request_method != "POST"
+ raise WEBrick::HTTPStatus::MethodNotAllowed,
+ "unsupported method `#{request.request_method}'."
+ end
- raise WEBrick::HTTPStatus::BadRequest if parse_content_type(request['Content-type']).first != "text/xml"
+ raise WEBrick::HTTPStatus::BadRequest if parse_content_type(request['Content-type']).first != "text/xml"
- length = (request['Content-length'] || 0).to_i
+ length = (request['Content-length'] || 0).to_i
- raise WEBrick::HTTPStatus::LengthRequired unless length > 0
+ raise WEBrick::HTTPStatus::LengthRequired unless length > 0
- data = request.body
+ data = request.body
- raise WEBrick::HTTPStatus::BadRequest if data.nil? or data.size != length
+ raise WEBrick::HTTPStatus::BadRequest if data.nil? or data.size != length
- resp = process(data, client_request(request))
- raise WEBrick::HTTPStatus::InternalServerError if resp.nil? or resp.size <= 0
+ resp = process(data, client_request(request))
+ raise WEBrick::HTTPStatus::InternalServerError if resp.nil? or resp.size <= 0
- response.status = 200
- response['Content-Length'] = resp.size
- response['Content-Type'] = "text/xml; charset=utf-8"
- response.body = resp
- end
+ response.status = 200
+ response['Content-Length'] = resp.size
+ response['Content-Type'] = "text/xml; charset=utf-8"
+ response.body = resp
+ end
- private
+ private
- # Generate a ClientRequest object for later validation.
- def client_request(request)
- if peer = request.peeraddr
- client = peer[2]
- clientip = peer[3]
- else
+ # Generate a ClientRequest object for later validation.
+ def client_request(request)
+ if peer = request.peeraddr
+ client = peer[2]
+ clientip = peer[3]
+ else
- raise ::XMLRPC::FaultException.new(
+ raise ::XMLRPC::FaultException.new(
- ERR_UNCAUGHT_EXCEPTION,
+ ERR_UNCAUGHT_EXCEPTION,
- "Could not retrieve client information"
- )
- end
-
- # If they have a certificate (which will almost always be true)
- # then we get the hostname from the cert, instead of via IP
- # info
- valid = false
- if cert = request.client_cert
- nameary = cert.subject.to_a.find { |ary|
- ary[0] == "CN"
- }
-
- if nameary.nil?
- Puppet.warning "Could not retrieve server name from cert"
- else
- unless client == nameary[1]
- Puppet.debug "Overriding #{client} with cert name #{nameary[1]}"
- client = nameary[1]
- end
- valid = true
- end
- end
-
- info = Puppet::Network::ClientRequest.new(client, clientip, valid)
-
- info
+ "Could not retrieve client information"
+ )
+ end
+
+ # If they have a certificate (which will almost always be true)
+ # then we get the hostname from the cert, instead of via IP
+ # info
+ valid = false
+ if cert = request.client_cert
+ nameary = cert.subject.to_a.find { |ary|
+ ary[0] == "CN"
+ }
+
+ if nameary.nil?
+ Puppet.warning "Could not retrieve server name from cert"
+ else
+ unless client == nameary[1]
+ Puppet.debug "Overriding #{client} with cert name #{nameary[1]}"
+ client = nameary[1]
+ end
+ valid = true
end
+ end
+
+ info = Puppet::Network::ClientRequest.new(client, clientip, valid)
+
+ info
end
+ end
end
diff --git a/lib/puppet/node.rb b/lib/puppet/node.rb
index 81d88d0..1fc6154 100644
--- a/lib/puppet/node.rb
+++ b/lib/puppet/node.rb
@@ -2,118 +2,118 @@ require 'puppet/indirector'
# A class for managing nodes, including their facts and environment.
class Puppet::Node
- require 'puppet/node/facts'
- require 'puppet/node/environment'
+ require 'puppet/node/facts'
+ require 'puppet/node/environment'
- # Set up indirection, so that nodes can be looked for in
- # the node sources.
- extend Puppet::Indirector
+ # Set up indirection, so that nodes can be looked for in
+ # the node sources.
+ extend Puppet::Indirector
- # Adds the environment getter and setter, with some instance/string conversion
- include Puppet::Node::Environment::Helper
+ # Adds the environment getter and setter, with some instance/string conversion
+ include Puppet::Node::Environment::Helper
- # Use the node source as the indirection terminus.
- indirects :node, :terminus_setting => :node_terminus, :doc => "Where to find node information.
- A node is composed of its name, its facts, and its environment."
+ # Use the node source as the indirection terminus.
+ indirects :node, :terminus_setting => :node_terminus, :doc => "Where to find node information.
+ A node is composed of its name, its facts, and its environment."
- attr_accessor :name, :classes, :source, :ipaddress
- attr_reader :time, :parameters
+ attr_accessor :name, :classes, :source, :ipaddress
+ attr_reader :time, :parameters
- def environment
- return super if @environment
+ def environment
+ return super if @environment
- if env = parameters["environment"]
- self.environment = env
- return super
- end
+ if env = parameters["environment"]
+ self.environment = env
+ return super
+ end
- # Else, return the default
- Puppet::Node::Environment.new
+ # Else, return the default
+ Puppet::Node::Environment.new
+ end
+
+ def initialize(name, options = {})
+ raise ArgumentError, "Node names cannot be nil" unless name
+ @name = name
+
+ if classes = options[:classes]
+ if classes.is_a?(String)
+ @classes = [classes]
+ else
+ @classes = classes
+ end
+ else
+ @classes = []
end
- def initialize(name, options = {})
- raise ArgumentError, "Node names cannot be nil" unless name
- @name = name
+ @parameters = options[:parameters] || {}
- if classes = options[:classes]
- if classes.is_a?(String)
- @classes = [classes]
- else
- @classes = classes
- end
- else
- @classes = []
- end
+ if env = options[:environment]
+ self.environment = env
+ end
- @parameters = options[:parameters] || {}
+ @time = Time.now
+ end
+
+ # Merge the node facts with parameters from the node source.
+ def fact_merge
+ if facts = Puppet::Node::Facts.find(name)
+ merge(facts.values)
+ end
+ rescue => detail
+ error = Puppet::Error.new("Could not retrieve facts for #{name}: #{detail}")
+ error.set_backtrace(detail.backtrace)
+ raise error
+ end
+
+ # Merge any random parameters into our parameter list.
+ def merge(params)
+ params.each do |name, value|
+ @parameters[name] = value unless @parameters.include?(name)
+ end
- if env = options[:environment]
- self.environment = env
- end
+ @parameters["environment"] ||= self.environment.name.to_s if self.environment
+ end
- @time = Time.now
- end
+ # Calculate the list of names we might use for looking
+ # up our node. This is only used for AST nodes.
+ def names
+ return [name] if Puppet.settings[:strict_hostname_checking]
- # Merge the node facts with parameters from the node source.
- def fact_merge
- if facts = Puppet::Node::Facts.find(name)
- merge(facts.values)
- end
- rescue => detail
- error = Puppet::Error.new("Could not retrieve facts for #{name}: #{detail}")
- error.set_backtrace(detail.backtrace)
- raise error
- end
+ names = []
- # Merge any random parameters into our parameter list.
- def merge(params)
- params.each do |name, value|
- @parameters[name] = value unless @parameters.include?(name)
- end
+ names += split_name(name) if name.include?(".")
- @parameters["environment"] ||= self.environment.name.to_s if self.environment
+ # First, get the fqdn
+ unless fqdn = parameters["fqdn"]
+ if parameters["hostname"] and parameters["domain"]
+ fqdn = parameters["hostname"] + "." + parameters["domain"]
+ else
+ Puppet.warning "Host is missing hostname and/or domain: #{name}"
+ end
end
- # Calculate the list of names we might use for looking
- # up our node. This is only used for AST nodes.
- def names
- return [name] if Puppet.settings[:strict_hostname_checking]
-
- names = []
-
- names += split_name(name) if name.include?(".")
-
- # First, get the fqdn
- unless fqdn = parameters["fqdn"]
- if parameters["hostname"] and parameters["domain"]
- fqdn = parameters["hostname"] + "." + parameters["domain"]
- else
- Puppet.warning "Host is missing hostname and/or domain: #{name}"
- end
- end
-
- # Now that we (might) have the fqdn, add each piece to the name
- # list to search, in order of longest to shortest.
- names += split_name(fqdn) if fqdn
-
- # And make sure the node name is first, since that's the most
- # likely usage.
- # The name is usually the Certificate CN, but it can be
- # set to the 'facter' hostname instead.
- if Puppet[:node_name] == 'cert'
- names.unshift name
- else
- names.unshift parameters["hostname"]
- end
- names.uniq
+ # Now that we (might) have the fqdn, add each piece to the name
+ # list to search, in order of longest to shortest.
+ names += split_name(fqdn) if fqdn
+
+ # And make sure the node name is first, since that's the most
+ # likely usage.
+ # The name is usually the Certificate CN, but it can be
+ # set to the 'facter' hostname instead.
+ if Puppet[:node_name] == 'cert'
+ names.unshift name
+ else
+ names.unshift parameters["hostname"]
end
-
- def split_name(name)
- list = name.split(".")
- tmp = []
- list.each_with_index do |short, i|
- tmp << list[0..i].join(".")
- end
- tmp.reverse
+ names.uniq
+ end
+
+ def split_name(name)
+ list = name.split(".")
+ tmp = []
+ list.each_with_index do |short, i|
+ tmp << list[0..i].join(".")
end
+ tmp.reverse
+ end
end
diff --git a/lib/puppet/node/environment.rb b/lib/puppet/node/environment.rb
index 4f3ef2d..44c7640 100644
--- a/lib/puppet/node/environment.rb
+++ b/lib/puppet/node/environment.rb
@@ -7,124 +7,124 @@ end
# Model the environment that a node can operate in. This class just
# provides a simple wrapper for the functionality around environments.
class Puppet::Node::Environment
- module Helper
- def environment
- Puppet::Node::Environment.new(@environment)
- end
-
- def environment=(env)
- if env.is_a?(String) or env.is_a?(Symbol)
- @environment = env
- else
- @environment = env.name
- end
- end
+ module Helper
+ def environment
+ Puppet::Node::Environment.new(@environment)
end
- include Puppet::Util::Cacher
-
- @seen = {}
+ def environment=(env)
+ if env.is_a?(String) or env.is_a?(Symbol)
+ @environment = env
+ else
+ @environment = env.name
+ end
+ end
+ end
- # Return an existing environment instance, or create a new one.
- def self.new(name = nil)
- return name if name.is_a?(self)
- name ||= Puppet.settings.value(:environment)
+ include Puppet::Util::Cacher
- raise ArgumentError, "Environment name must be specified" unless name
+ @seen = {}
- symbol = name.to_sym
+ # Return an existing environment instance, or create a new one.
+ def self.new(name = nil)
+ return name if name.is_a?(self)
+ name ||= Puppet.settings.value(:environment)
- return @seen[symbol] if @seen[symbol]
+ raise ArgumentError, "Environment name must be specified" unless name
- obj = self.allocate
- obj.send :initialize, symbol
- @seen[symbol] = obj
- end
-
- def self.current
- Thread.current[:environment] || root
- end
-
- def self.current=(env)
- Thread.current[:environment] = new(env)
- end
-
- def self.root
- @root
- end
+ symbol = name.to_sym
- # This is only used for testing.
- def self.clear
- @seen.clear
- end
+ return @seen[symbol] if @seen[symbol]
- attr_reader :name
+ obj = self.allocate
+ obj.send :initialize, symbol
+ @seen[symbol] = obj
+ end
- # Return an environment-specific setting.
- def [](param)
- Puppet.settings.value(param, self.name)
- end
+ def self.current
+ Thread.current[:environment] || root
+ end
- def initialize(name)
- @name = name
- end
+ def self.current=(env)
+ Thread.current[:environment] = new(env)
+ end
- def known_resource_types
- if @known_resource_types.nil? or @known_resource_types.stale?
- @known_resource_types = Puppet::Resource::TypeCollection.new(self)
- @known_resource_types.perform_initial_import
- end
- @known_resource_types
- end
+ def self.root
+ @root
+ end
- def module(name)
- mod = Puppet::Module.new(name, self)
- return nil unless mod.exist?
- mod
- end
+ # This is only used for testing.
+ def self.clear
+ @seen.clear
+ end
- # Cache the modulepath, so that we aren't searching through
- # all known directories all the time.
- cached_attr(:modulepath, :ttl => Puppet[:filetimeout]) do
- dirs = self[:modulepath].split(File::PATH_SEPARATOR)
- dirs = ENV["PUPPETLIB"].split(File::PATH_SEPARATOR) + dirs if ENV["PUPPETLIB"]
- validate_dirs(dirs)
- end
+ attr_reader :name
- # Return all modules from this environment.
- # Cache the list, because it can be expensive to create.
- cached_attr(:modules, :ttl => Puppet[:filetimeout]) do
- module_names = modulepath.collect { |path| Dir.entries(path) }.flatten.uniq
- module_names.collect do |path|
- begin
- Puppet::Module.new(path, self)
- rescue Puppet::Module::Error => e
- nil
- end
- end.compact
- end
+ # Return an environment-specific setting.
+ def [](param)
+ Puppet.settings.value(param, self.name)
+ end
- # Cache the manifestdir, so that we aren't searching through
- # all known directories all the time.
- cached_attr(:manifestdir, :ttl => Puppet[:filetimeout]) do
- validate_dirs(self[:manifestdir].split(File::PATH_SEPARATOR))
- end
+ def initialize(name)
+ @name = name
+ end
- def to_s
- name.to_s
+ def known_resource_types
+ if @known_resource_types.nil? or @known_resource_types.stale?
+ @known_resource_types = Puppet::Resource::TypeCollection.new(self)
+ @known_resource_types.perform_initial_import
end
-
- def validate_dirs(dirs)
- dirs.collect do |dir|
- if dir !~ /^#{File::SEPARATOR}/
- File.join(Dir.getwd, dir)
- else
- dir
- end
- end.find_all do |p|
- p =~ /^#{File::SEPARATOR}/ && FileTest.directory?(p)
- end
+ @known_resource_types
+ end
+
+ def module(name)
+ mod = Puppet::Module.new(name, self)
+ return nil unless mod.exist?
+ mod
+ end
+
+ # Cache the modulepath, so that we aren't searching through
+ # all known directories all the time.
+ cached_attr(:modulepath, :ttl => Puppet[:filetimeout]) do
+ dirs = self[:modulepath].split(File::PATH_SEPARATOR)
+ dirs = ENV["PUPPETLIB"].split(File::PATH_SEPARATOR) + dirs if ENV["PUPPETLIB"]
+ validate_dirs(dirs)
+ end
+
+ # Return all modules from this environment.
+ # Cache the list, because it can be expensive to create.
+ cached_attr(:modules, :ttl => Puppet[:filetimeout]) do
+ module_names = modulepath.collect { |path| Dir.entries(path) }.flatten.uniq
+ module_names.collect do |path|
+ begin
+ Puppet::Module.new(path, self)
+ rescue Puppet::Module::Error => e
+ nil
+ end
+ end.compact
+ end
+
+ # Cache the manifestdir, so that we aren't searching through
+ # all known directories all the time.
+ cached_attr(:manifestdir, :ttl => Puppet[:filetimeout]) do
+ validate_dirs(self[:manifestdir].split(File::PATH_SEPARATOR))
+ end
+
+ def to_s
+ name.to_s
+ end
+
+ def validate_dirs(dirs)
+ dirs.collect do |dir|
+ if dir !~ /^#{File::SEPARATOR}/
+ File.join(Dir.getwd, dir)
+ else
+ dir
+ end
+ end.find_all do |p|
+ p =~ /^#{File::SEPARATOR}/ && FileTest.directory?(p)
end
+ end
- @root = new(:'*root*')
+ @root = new(:'*root*')
end
diff --git a/lib/puppet/node/facts.rb b/lib/puppet/node/facts.rb
index 0b9fc58..b77ad22 100755
--- a/lib/puppet/node/facts.rb
+++ b/lib/puppet/node/facts.rb
@@ -4,67 +4,67 @@ require 'puppet/indirector'
# Manage a given node's facts. This either accepts facts and stores them, or
# returns facts for a given node.
class Puppet::Node::Facts
- # Set up indirection, so that nodes can be looked for in
- # the node sources.
- extend Puppet::Indirector
+ # Set up indirection, so that nodes can be looked for in
+ # the node sources.
+ extend Puppet::Indirector
- # We want to expire any cached nodes if the facts are saved.
- module NodeExpirer
- def save(key, instance)
- Puppet::Node.expire(instance.name)
- super
- end
+ # We want to expire any cached nodes if the facts are saved.
+ module NodeExpirer
+ def save(key, instance)
+ Puppet::Node.expire(instance.name)
+ super
end
+ end
- indirects :facts, :terminus_setting => :facts_terminus, :extend => NodeExpirer
+ indirects :facts, :terminus_setting => :facts_terminus, :extend => NodeExpirer
- attr_accessor :name, :values
+ attr_accessor :name, :values
- def add_local_facts
- values["clientcert"] = Puppet.settings[:certname]
- values["clientversion"] = Puppet.version.to_s
- values["environment"] ||= Puppet.settings[:environment]
- end
+ def add_local_facts
+ values["clientcert"] = Puppet.settings[:certname]
+ values["clientversion"] = Puppet.version.to_s
+ values["environment"] ||= Puppet.settings[:environment]
+ end
- def initialize(name, values = {})
- @name = name
- @values = values
+ def initialize(name, values = {})
+ @name = name
+ @values = values
- add_internal
- end
+ add_internal
+ end
- def downcase_if_necessary
- return unless Puppet.settings[:downcasefacts]
+ def downcase_if_necessary
+ return unless Puppet.settings[:downcasefacts]
- Puppet.warning "DEPRECATION NOTICE: Fact downcasing is deprecated; please disable (20080122)"
- values.each do |fact, value|
- values[fact] = value.downcase if value.is_a?(String)
- end
+ Puppet.warning "DEPRECATION NOTICE: Fact downcasing is deprecated; please disable (20080122)"
+ values.each do |fact, value|
+ values[fact] = value.downcase if value.is_a?(String)
end
+ end
- # Convert all fact values into strings.
- def stringify
- values.each do |fact, value|
- values[fact] = value.to_s
- end
+ # Convert all fact values into strings.
+ def stringify
+ values.each do |fact, value|
+ values[fact] = value.to_s
end
+ end
- def ==(other)
- return false unless self.name == other.name
- strip_internal == other.send(:strip_internal)
- end
+ def ==(other)
+ return false unless self.name == other.name
+ strip_internal == other.send(:strip_internal)
+ end
- private
+ private
- # Add internal data to the facts for storage.
- def add_internal
- self.values[:_timestamp] = Time.now
- end
+ # Add internal data to the facts for storage.
+ def add_internal
+ self.values[:_timestamp] = Time.now
+ end
- # Strip out that internal data.
- def strip_internal
- newvals = values.dup
- newvals.find_all { |name, value| name.to_s =~ /^_/ }.each { |name, value| newvals.delete(name) }
- newvals
- end
+ # Strip out that internal data.
+ def strip_internal
+ newvals = values.dup
+ newvals.find_all { |name, value| name.to_s =~ /^_/ }.each { |name, value| newvals.delete(name) }
+ newvals
+ end
end
diff --git a/lib/puppet/parameter.rb b/lib/puppet/parameter.rb
index be44b3e..ff7cab2 100644
--- a/lib/puppet/parameter.rb
+++ b/lib/puppet/parameter.rb
@@ -5,298 +5,298 @@ require 'puppet/util/docs'
require 'puppet/util/cacher'
class Puppet::Parameter
- include Puppet::Util
- include Puppet::Util::Errors
- include Puppet::Util::LogPaths
- include Puppet::Util::Logging
- include Puppet::Util::MethodHelper
- include Puppet::Util::Cacher
-
- require 'puppet/parameter/value_collection'
-
- class << self
- include Puppet::Util
- include Puppet::Util::Docs
- attr_reader :validater, :munger, :name, :default, :required_features, :value_collection
- attr_accessor :metaparam
-
- # Define the default value for a given parameter or parameter. This
- # means that 'nil' is an invalid default value. This defines
- # the 'default' instance method.
- def defaultto(value = nil, &block)
- if block
- define_method(:default, &block)
- else
- if value.nil?
- raise Puppet::DevError,
- "Either a default value or block must be provided"
- end
- define_method(:default) do value end
- end
- end
-
- # Return a documentation string. If there are valid values,
- # then tack them onto the string.
- def doc
- @doc ||= ""
-
- unless defined?(@addeddocvals)
- @doc += value_collection.doc
+ include Puppet::Util
+ include Puppet::Util::Errors
+ include Puppet::Util::LogPaths
+ include Puppet::Util::Logging
+ include Puppet::Util::MethodHelper
+ include Puppet::Util::Cacher
- if f = self.required_features
- @doc += " Requires features #{f.flatten.collect { |f| f.to_s }.join(" ")}."
- end
- @addeddocvals = true
- end
+ require 'puppet/parameter/value_collection'
- @doc
- end
-
- def nodefault
- undef_method :default if public_method_defined? :default
- end
-
- # Store documentation for this parameter.
- def desc(str)
- @doc = str
- end
-
- def initvars
- @value_collection = ValueCollection.new
- end
-
- # This is how we munge the value. Basically, this is our
- # opportunity to convert the value from one form into another.
- def munge(&block)
- # I need to wrap the unsafe version in begin/rescue parameterments,
- # but if I directly call the block then it gets bound to the
- # class's context, not the instance's, thus the two methods,
- # instead of just one.
- define_method(:unsafe_munge, &block)
- end
-
- # Does the parameter supports reverse munge?
- # This will be called when something wants to access the parameter
- # in a canonical form different to what the storage form is.
- def unmunge(&block)
- define_method(:unmunge, &block)
- end
-
- # Mark whether we're the namevar.
- def isnamevar
- @isnamevar = true
- @required = true
- end
-
- # Is this parameter the namevar? Defaults to false.
- def isnamevar?
- @isnamevar
- end
-
- # This parameter is required.
- def isrequired
- @required = true
- end
-
- # Specify features that are required for this parameter to work.
- def required_features=(*args)
- @required_features = args.flatten.collect { |a| a.to_s.downcase.intern }
+ class << self
+ include Puppet::Util
+ include Puppet::Util::Docs
+ attr_reader :validater, :munger, :name, :default, :required_features, :value_collection
+ attr_accessor :metaparam
+
+ # Define the default value for a given parameter or parameter. This
+ # means that 'nil' is an invalid default value. This defines
+ # the 'default' instance method.
+ def defaultto(value = nil, &block)
+ if block
+ define_method(:default, &block)
+ else
+ if value.nil?
+ raise Puppet::DevError,
+ "Either a default value or block must be provided"
end
+ define_method(:default) do value end
+ end
+ end
- # Is this parameter required? Defaults to false.
- def required?
- @required
- end
+ # Return a documentation string. If there are valid values,
+ # then tack them onto the string.
+ def doc
+ @doc ||= ""
- # Verify that we got a good value
- def validate(&block)
- define_method(:unsafe_validate, &block)
- end
+ unless defined?(@addeddocvals)
+ @doc += value_collection.doc
- # Define a new value for our parameter.
- def newvalues(*names)
- @value_collection.newvalues(*names)
+ if f = self.required_features
+ @doc += " Requires features #{f.flatten.collect { |f| f.to_s }.join(" ")}."
end
+ @addeddocvals = true
+ end
- def aliasvalue(name, other)
- @value_collection.aliasvalue(name, other)
- end
+ @doc
end
- # Just a simple method to proxy instance methods to class methods
- def self.proxymethods(*values)
- values.each { |val|
- define_method(val) do
- self.class.send(val)
- end
- }
+ def nodefault
+ undef_method :default if public_method_defined? :default
end
- # And then define one of these proxies for each method in our
- # ParamHandler class.
- proxymethods("required?", "isnamevar?")
-
- attr_accessor :resource
- # LAK 2007-05-09: Keep the @parent around for backward compatibility.
- attr_accessor :parent
-
- [:line, :file, :version].each do |param|
- define_method(param) do
- resource.send(param)
- end
+ # Store documentation for this parameter.
+ def desc(str)
+ @doc = str
end
- def devfail(msg)
- self.fail(Puppet::DevError, msg)
+ def initvars
+ @value_collection = ValueCollection.new
end
- def expirer
- resource.catalog
+ # This is how we munge the value. Basically, this is our
+ # opportunity to convert the value from one form into another.
+ def munge(&block)
+ # I need to wrap the unsafe version in begin/rescue parameterments,
+ # but if I directly call the block then it gets bound to the
+ # class's context, not the instance's, thus the two methods,
+ # instead of just one.
+ define_method(:unsafe_munge, &block)
end
- def fail(*args)
- type = nil
- if args[0].is_a?(Class)
- type = args.shift
- else
- type = Puppet::Error
- end
-
- error = type.new(args.join(" "))
-
- error.line = @resource.line if @resource and @resource.line
-
- error.file = @resource.file if @resource and @resource.file
-
- raise error
+ # Does the parameter supports reverse munge?
+ # This will be called when something wants to access the parameter
+ # in a canonical form different to what the storage form is.
+ def unmunge(&block)
+ define_method(:unmunge, &block)
end
- # Basic parameter initialization.
- def initialize(options = {})
- options = symbolize_options(options)
- if resource = options[:resource]
- self.resource = resource
- options.delete(:resource)
- else
- raise Puppet::DevError, "No resource set for #{self.class.name}"
- end
-
- set_options(options)
+ # Mark whether we're the namevar.
+ def isnamevar
+ @isnamevar = true
+ @required = true
end
- def log(msg)
- send_log(resource[:loglevel], msg)
+ # Is this parameter the namevar? Defaults to false.
+ def isnamevar?
+ @isnamevar
end
- # Is this parameter a metaparam?
- def metaparam?
- self.class.metaparam
+ # This parameter is required.
+ def isrequired
+ @required = true
end
- # each parameter class must define the name method, and parameter
- # instances do not change that name this implicitly means that a given
- # object can only have one parameter instance of a given parameter
- # class
- def name
- self.class.name
+ # Specify features that are required for this parameter to work.
+ def required_features=(*args)
+ @required_features = args.flatten.collect { |a| a.to_s.downcase.intern }
end
- # for testing whether we should actually do anything
- def noop
- @noop ||= false
- tmp = @noop || self.resource.noop || Puppet[:noop] || false
- #debug "noop is #{tmp}"
- tmp
+ # Is this parameter required? Defaults to false.
+ def required?
+ @required
end
- # return the full path to us, for logging and rollback; not currently
- # used
- def pathbuilder
- if @resource
- return [@resource.pathbuilder, self.name]
- else
- return [self.name]
- end
+ # Verify that we got a good value
+ def validate(&block)
+ define_method(:unsafe_validate, &block)
end
- # If the specified value is allowed, then munge appropriately.
- # If the developer uses a 'munge' hook, this method will get overridden.
- def unsafe_munge(value)
- self.class.value_collection.munge(value)
+ # Define a new value for our parameter.
+ def newvalues(*names)
+ @value_collection.newvalues(*names)
end
- # no unmunge by default
- def unmunge(value)
- value
+ def aliasvalue(name, other)
+ @value_collection.aliasvalue(name, other)
end
-
- # A wrapper around our munging that makes sure we raise useful exceptions.
- def munge(value)
- begin
- ret = unsafe_munge(value)
- rescue Puppet::Error => detail
- Puppet.debug "Reraising #{detail}"
- raise
- rescue => detail
- raise Puppet::DevError, "Munging failed for value #{value.inspect} in class #{self.name}: #{detail}", detail.backtrace
- end
- ret
+ end
+
+ # Just a simple method to proxy instance methods to class methods
+ def self.proxymethods(*values)
+ values.each { |val|
+ define_method(val) do
+ self.class.send(val)
+ end
+ }
+ end
+
+ # And then define one of these proxies for each method in our
+ # ParamHandler class.
+ proxymethods("required?", "isnamevar?")
+
+ attr_accessor :resource
+ # LAK 2007-05-09: Keep the @parent around for backward compatibility.
+ attr_accessor :parent
+
+ [:line, :file, :version].each do |param|
+ define_method(param) do
+ resource.send(param)
end
-
- # Verify that the passed value is valid.
- # If the developer uses a 'validate' hook, this method will get overridden.
- def unsafe_validate(value)
- self.class.value_collection.validate(value)
+ end
+
+ def devfail(msg)
+ self.fail(Puppet::DevError, msg)
+ end
+
+ def expirer
+ resource.catalog
+ end
+
+ def fail(*args)
+ type = nil
+ if args[0].is_a?(Class)
+ type = args.shift
+ else
+ type = Puppet::Error
end
- # A protected validation method that only ever raises useful exceptions.
- def validate(value)
- begin
- unsafe_validate(value)
- rescue ArgumentError => detail
- fail detail.to_s
- rescue Puppet::Error, TypeError
- raise
- rescue => detail
- raise Puppet::DevError, "Validate method failed for class #{self.name}: #{detail}", detail.backtrace
- end
- end
+ error = type.new(args.join(" "))
- def remove
- @resource = nil
- end
+ error.line = @resource.line if @resource and @resource.line
- def value
- unmunge(@value) unless @value.nil?
- end
+ error.file = @resource.file if @resource and @resource.file
- # Store the value provided. All of the checking should possibly be
- # late-binding (e.g., users might not exist when the value is assigned
- # but might when it is asked for).
- def value=(value)
- validate(value)
+ raise error
+ end
- @value = munge(value)
+ # Basic parameter initialization.
+ def initialize(options = {})
+ options = symbolize_options(options)
+ if resource = options[:resource]
+ self.resource = resource
+ options.delete(:resource)
+ else
+ raise Puppet::DevError, "No resource set for #{self.class.name}"
end
- # Retrieve the resource's provider. Some types don't have providers, in which
- # case we return the resource object itself.
- def provider
- @resource.provider
+ set_options(options)
+ end
+
+ def log(msg)
+ send_log(resource[:loglevel], msg)
+ end
+
+ # Is this parameter a metaparam?
+ def metaparam?
+ self.class.metaparam
+ end
+
+ # each parameter class must define the name method, and parameter
+ # instances do not change that name this implicitly means that a given
+ # object can only have one parameter instance of a given parameter
+ # class
+ def name
+ self.class.name
+ end
+
+ # for testing whether we should actually do anything
+ def noop
+ @noop ||= false
+ tmp = @noop || self.resource.noop || Puppet[:noop] || false
+ #debug "noop is #{tmp}"
+ tmp
+ end
+
+ # return the full path to us, for logging and rollback; not currently
+ # used
+ def pathbuilder
+ if @resource
+ return [@resource.pathbuilder, self.name]
+ else
+ return [self.name]
end
-
- # The properties need to return tags so that logs correctly collect them.
- def tags
- unless defined?(@tags)
- @tags = []
- # This might not be true in testing
- @tags = @resource.tags if @resource.respond_to? :tags
- @tags << self.name.to_s
- end
- @tags
+ end
+
+ # If the specified value is allowed, then munge appropriately.
+ # If the developer uses a 'munge' hook, this method will get overridden.
+ def unsafe_munge(value)
+ self.class.value_collection.munge(value)
+ end
+
+ # no unmunge by default
+ def unmunge(value)
+ value
+ end
+
+ # A wrapper around our munging that makes sure we raise useful exceptions.
+ def munge(value)
+ begin
+ ret = unsafe_munge(value)
+ rescue Puppet::Error => detail
+ Puppet.debug "Reraising #{detail}"
+ raise
+ rescue => detail
+ raise Puppet::DevError, "Munging failed for value #{value.inspect} in class #{self.name}: #{detail}", detail.backtrace
end
-
- def to_s
- name.to_s
+ ret
+ end
+
+ # Verify that the passed value is valid.
+ # If the developer uses a 'validate' hook, this method will get overridden.
+ def unsafe_validate(value)
+ self.class.value_collection.validate(value)
+ end
+
+ # A protected validation method that only ever raises useful exceptions.
+ def validate(value)
+ begin
+ unsafe_validate(value)
+ rescue ArgumentError => detail
+ fail detail.to_s
+ rescue Puppet::Error, TypeError
+ raise
+ rescue => detail
+ raise Puppet::DevError, "Validate method failed for class #{self.name}: #{detail}", detail.backtrace
+ end
+ end
+
+ def remove
+ @resource = nil
+ end
+
+ def value
+ unmunge(@value) unless @value.nil?
+ end
+
+ # Store the value provided. All of the checking should possibly be
+ # late-binding (e.g., users might not exist when the value is assigned
+ # but might when it is asked for).
+ def value=(value)
+ validate(value)
+
+ @value = munge(value)
+ end
+
+ # Retrieve the resource's provider. Some types don't have providers, in which
+ # case we return the resource object itself.
+ def provider
+ @resource.provider
+ end
+
+ # The properties need to return tags so that logs correctly collect them.
+ def tags
+ unless defined?(@tags)
+ @tags = []
+ # This might not be true in testing
+ @tags = @resource.tags if @resource.respond_to? :tags
+ @tags << self.name.to_s
end
+ @tags
+ end
+
+ def to_s
+ name.to_s
+ end
end
diff --git a/lib/puppet/parameter/value.rb b/lib/puppet/parameter/value.rb
index 3482c2c..d9bfbaf 100644
--- a/lib/puppet/parameter/value.rb
+++ b/lib/puppet/parameter/value.rb
@@ -2,62 +2,62 @@ require 'puppet/parameter/value_collection'
# An individual Value class.
class Puppet::Parameter::Value
- attr_reader :name, :options, :event
- attr_accessor :block, :call, :method, :required_features
-
- # Add an alias for this value.
- def alias(name)
- @aliases << convert(name)
- end
-
- # Return all aliases.
- def aliases
- @aliases.dup
- end
-
- # Store the event that our value generates, if it does so.
- def event=(value)
- @event = convert(value)
+ attr_reader :name, :options, :event
+ attr_accessor :block, :call, :method, :required_features
+
+ # Add an alias for this value.
+ def alias(name)
+ @aliases << convert(name)
+ end
+
+ # Return all aliases.
+ def aliases
+ @aliases.dup
+ end
+
+ # Store the event that our value generates, if it does so.
+ def event=(value)
+ @event = convert(value)
+ end
+
+ def initialize(name)
+ if name.is_a?(Regexp)
+ @name = name
+ else
+ # Convert to a string and then a symbol, so things like true/false
+ # still show up as symbols.
+ @name = convert(name)
end
- def initialize(name)
- if name.is_a?(Regexp)
- @name = name
- else
- # Convert to a string and then a symbol, so things like true/false
- # still show up as symbols.
- @name = convert(name)
- end
+ @aliases = []
- @aliases = []
+ @call = :instead
+ end
- @call = :instead
+ # Does a provided value match our value?
+ def match?(value)
+ if regex?
+ return true if name =~ value.to_s
+ else
+ return(name == convert(value) ? true : @aliases.include?(convert(value)))
end
-
- # Does a provided value match our value?
- def match?(value)
- if regex?
- return true if name =~ value.to_s
- else
- return(name == convert(value) ? true : @aliases.include?(convert(value)))
- end
- end
-
- # Is our value a regex?
- def regex?
- @name.is_a?(Regexp)
- end
-
- private
-
- # A standard way of converting all of our values, so we're always
- # comparing apples to apples.
- def convert(value)
- if value == ''
- # We can't intern an empty string, yay.
- value
- else
- value.to_s.to_sym
- end
+ end
+
+ # Is our value a regex?
+ def regex?
+ @name.is_a?(Regexp)
+ end
+
+ private
+
+ # A standard way of converting all of our values, so we're always
+ # comparing apples to apples.
+ def convert(value)
+ if value == ''
+ # We can't intern an empty string, yay.
+ value
+ else
+ value.to_s.to_sym
end
+ end
end
diff --git a/lib/puppet/parameter/value_collection.rb b/lib/puppet/parameter/value_collection.rb
index eabeb30..a9fd202 100644
--- a/lib/puppet/parameter/value_collection.rb
+++ b/lib/puppet/parameter/value_collection.rb
@@ -4,140 +4,140 @@ require 'puppet/parameter/value'
# what values are allowed in a given parameter.
class Puppet::Parameter::ValueCollection
- def aliasvalue(name, other)
- other = other.to_sym
- unless value = match?(other)
- raise Puppet::DevError, "Cannot alias nonexistent value #{other}"
- end
-
- value.alias(name)
+ def aliasvalue(name, other)
+ other = other.to_sym
+ unless value = match?(other)
+ raise Puppet::DevError, "Cannot alias nonexistent value #{other}"
end
- # Return a doc string for all of the values in this parameter/property.
- def doc
- unless defined?(@doc)
- @doc = ""
- unless values.empty?
- @doc += " Valid values are "
- @doc += @strings.collect do |value|
- if aliases = value.aliases and ! aliases.empty?
- "``#{value.name}`` (also called ``#{aliases.join(", ")}``)"
- else
- "``#{value.name}``"
- end
- end.join(", ") + "."
- end
-
- @doc += " Values can match ``" + regexes.join("``, ``") + "``." unless regexes.empty?
- end
-
- @doc
+ value.alias(name)
+ end
+
+ # Return a doc string for all of the values in this parameter/property.
+ def doc
+ unless defined?(@doc)
+ @doc = ""
+ unless values.empty?
+ @doc += " Valid values are "
+ @doc += @strings.collect do |value|
+ if aliases = value.aliases and ! aliases.empty?
+ "``#{value.name}`` (also called ``#{aliases.join(", ")}``)"
+ else
+ "``#{value.name}``"
+ end
+ end.join(", ") + "."
+ end
+
+ @doc += " Values can match ``" + regexes.join("``, ``") + "``." unless regexes.empty?
end
- # Does this collection contain any value definitions?
- def empty?
- @values.empty?
+ @doc
+ end
+
+ # Does this collection contain any value definitions?
+ def empty?
+ @values.empty?
+ end
+
+ def initialize
+ # We often look values up by name, so a hash makes more sense.
+ @values = {}
+
+ # However, we want to retain the ability to match values in order,
+ # but we always prefer directly equality (i.e., strings) over regex matches.
+ @regexes = []
+ @strings = []
+ end
+
+ # Can we match a given value?
+ def match?(test_value)
+ # First look for normal values
+ if value = @strings.find { |v| v.match?(test_value) }
+ return value
end
- def initialize
- # We often look values up by name, so a hash makes more sense.
- @values = {}
-
- # However, we want to retain the ability to match values in order,
- # but we always prefer directly equality (i.e., strings) over regex matches.
- @regexes = []
- @strings = []
+ # Then look for a regex match
+ @regexes.find { |v| v.match?(test_value) }
+ end
+
+ # If the specified value is allowed, then munge appropriately.
+ def munge(value)
+ return value if empty?
+
+ if instance = match?(value)
+ if instance.regex?
+ return value
+ else
+ return instance.name
+ end
+ else
+ return value
end
-
- # Can we match a given value?
- def match?(test_value)
- # First look for normal values
- if value = @strings.find { |v| v.match?(test_value) }
- return value
- end
-
- # Then look for a regex match
- @regexes.find { |v| v.match?(test_value) }
+ end
+
+ # Define a new valid value for a property. You must provide the value itself,
+ # usually as a symbol, or a regex to match the value.
+ #
+ # The first argument to the method is either the value itself or a regex.
+ # The second argument is an option hash; valid options are:
+ # * <tt>:event</tt>: The event that should be returned when this value is set.
+ # * <tt>:call</tt>: When to call any associated block. The default value
+ # is ``instead``, which means to call the value instead of calling the
+ # provider. You can also specify ``before`` or ``after``, which will
+ # call both the block and the provider, according to the order you specify
+ # (the ``first`` refers to when the block is called, not the provider).
+ def newvalue(name, options = {}, &block)
+ value = Puppet::Parameter::Value.new(name)
+ @values[value.name] = value
+ if value.regex?
+ @regexes << value
+ else
+ @strings << value
end
- # If the specified value is allowed, then munge appropriately.
- def munge(value)
- return value if empty?
-
- if instance = match?(value)
- if instance.regex?
- return value
- else
- return instance.name
- end
- else
- return value
- end
+ options.each { |opt, arg| value.send(opt.to_s + "=", arg) }
+ if block_given?
+ value.block = block
+ else
+ value.call = options[:call] || :none
end
- # Define a new valid value for a property. You must provide the value itself,
- # usually as a symbol, or a regex to match the value.
- #
- # The first argument to the method is either the value itself or a regex.
- # The second argument is an option hash; valid options are:
- # * <tt>:event</tt>: The event that should be returned when this value is set.
- # * <tt>:call</tt>: When to call any associated block. The default value
- # is ``instead``, which means to call the value instead of calling the
- # provider. You can also specify ``before`` or ``after``, which will
- # call both the block and the provider, according to the order you specify
- # (the ``first`` refers to when the block is called, not the provider).
- def newvalue(name, options = {}, &block)
- value = Puppet::Parameter::Value.new(name)
- @values[value.name] = value
- if value.regex?
- @regexes << value
- else
- @strings << value
- end
-
- options.each { |opt, arg| value.send(opt.to_s + "=", arg) }
- if block_given?
- value.block = block
- else
- value.call = options[:call] || :none
- end
-
- value.method ||= "set_#{value.name}" if block_given? and ! value.regex?
-
- value
- end
+ value.method ||= "set_#{value.name}" if block_given? and ! value.regex?
- # Define one or more new values for our parameter.
- def newvalues(*names)
- names.each { |name| newvalue(name) }
- end
+ value
+ end
- def regexes
- @regexes.collect { |r| r.name.inspect }
- end
+ # Define one or more new values for our parameter.
+ def newvalues(*names)
+ names.each { |name| newvalue(name) }
+ end
- # Verify that the passed value is valid.
- def validate(value)
- return if empty?
+ def regexes
+ @regexes.collect { |r| r.name.inspect }
+ end
- unless @values.detect { |name, v| v.match?(value) }
- str = "Invalid value #{value.inspect}. "
+ # Verify that the passed value is valid.
+ def validate(value)
+ return if empty?
- str += "Valid values are #{values.join(", ")}. " unless values.empty?
+ unless @values.detect { |name, v| v.match?(value) }
+ str = "Invalid value #{value.inspect}. "
- str += "Valid values match #{regexes.join(", ")}." unless regexes.empty?
+ str += "Valid values are #{values.join(", ")}. " unless values.empty?
- raise ArgumentError, str
- end
- end
+ str += "Valid values match #{regexes.join(", ")}." unless regexes.empty?
- # Return a single value instance.
- def value(name)
- @values[name]
+ raise ArgumentError, str
end
+ end
- # Return the list of valid values.
- def values
- @strings.collect { |s| s.name }
- end
+ # Return a single value instance.
+ def value(name)
+ @values[name]
+ end
+
+ # Return the list of valid values.
+ def values
+ @strings.collect { |s| s.name }
+ end
end
diff --git a/lib/puppet/parser/ast.rb b/lib/puppet/parser/ast.rb
index dffc30a..2773a24 100644
--- a/lib/puppet/parser/ast.rb
+++ b/lib/puppet/parser/ast.rb
@@ -8,85 +8,85 @@ require 'puppet/file_collection/lookup'
# Handles things like file name, line #, and also does the initialization
# for all of the parameters of all of the child objects.
class Puppet::Parser::AST
- # Do this so I don't have to type the full path in all of the subclasses
- AST = Puppet::Parser::AST
+ # Do this so I don't have to type the full path in all of the subclasses
+ AST = Puppet::Parser::AST
- include Puppet::FileCollection::Lookup
+ include Puppet::FileCollection::Lookup
- include Puppet::Util::Errors
- include Puppet::Util::MethodHelper
- include Puppet::Util::Docs
+ include Puppet::Util::Errors
+ include Puppet::Util::MethodHelper
+ include Puppet::Util::Docs
- attr_accessor :parent, :scope
+ attr_accessor :parent, :scope
- # don't fetch lexer comment by default
- def use_docs
- self.class.use_docs
- end
+ # don't fetch lexer comment by default
+ def use_docs
+ self.class.use_docs
+ end
- # allow our subclass to specify they want documentation
- class << self
- attr_accessor :use_docs
- def associates_doc
- self.use_docs = true
- end
+ # allow our subclass to specify they want documentation
+ class << self
+ attr_accessor :use_docs
+ def associates_doc
+ self.use_docs = true
end
+ end
- # Does this ast object set something? If so, it gets evaluated first.
- def self.settor?
- if defined?(@settor)
- @settor
- else
- false
- end
+ # Does this ast object set something? If so, it gets evaluated first.
+ def self.settor?
+ if defined?(@settor)
+ @settor
+ else
+ false
end
+ end
- # Evaluate the current object. Just a stub method, since the subclass
- # should override this method.
- # of the contained children and evaluates them in turn, returning a
- # list of all of the collected values, rejecting nil values
- def evaluate(*options)
- raise Puppet::DevError, "Did not override #evaluate in #{self.class}"
- end
+ # Evaluate the current object. Just a stub method, since the subclass
+ # should override this method.
+ # of the contained children and evaluates them in turn, returning a
+ # list of all of the collected values, rejecting nil values
+ def evaluate(*options)
+ raise Puppet::DevError, "Did not override #evaluate in #{self.class}"
+ end
- # Throw a parse error.
- def parsefail(message)
- self.fail(Puppet::ParseError, message)
- end
+ # Throw a parse error.
+ def parsefail(message)
+ self.fail(Puppet::ParseError, message)
+ end
- # Wrap a statemp in a reusable way so we always throw a parse error.
- def parsewrap
- exceptwrap :type => Puppet::ParseError do
- yield
- end
+ # Wrap a statemp in a reusable way so we always throw a parse error.
+ def parsewrap
+ exceptwrap :type => Puppet::ParseError do
+ yield
end
+ end
- # The version of the evaluate method that should be called, because it
- # correctly handles errors. It is critical to use this method because
- # it can enable you to catch the error where it happens, rather than
- # much higher up the stack.
- def safeevaluate(*options)
- # We duplicate code here, rather than using exceptwrap, because this
- # is called so many times during parsing.
- begin
- return self.evaluate(*options)
- rescue Puppet::Error => detail
- raise adderrorcontext(detail)
- rescue => detail
- error = Puppet::Error.new(detail.to_s)
- # We can't use self.fail here because it always expects strings,
- # not exceptions.
- raise adderrorcontext(error, detail)
- end
+ # The version of the evaluate method that should be called, because it
+ # correctly handles errors. It is critical to use this method because
+ # it can enable you to catch the error where it happens, rather than
+ # much higher up the stack.
+ def safeevaluate(*options)
+ # We duplicate code here, rather than using exceptwrap, because this
+ # is called so many times during parsing.
+ begin
+ return self.evaluate(*options)
+ rescue Puppet::Error => detail
+ raise adderrorcontext(detail)
+ rescue => detail
+ error = Puppet::Error.new(detail.to_s)
+ # We can't use self.fail here because it always expects strings,
+ # not exceptions.
+ raise adderrorcontext(error, detail)
end
+ end
- # Initialize the object. Requires a hash as the argument, and
- # takes each of the parameters of the hash and calls the settor
- # method for them. This is probably pretty inefficient and should
- # likely be changed at some point.
- def initialize(args)
- set_options(args)
- end
+ # Initialize the object. Requires a hash as the argument, and
+ # takes each of the parameters of the hash and calls the settor
+ # method for them. This is probably pretty inefficient and should
+ # likely be changed at some point.
+ def initialize(args)
+ set_options(args)
+ end
end
# And include all of the AST subclasses.
diff --git a/lib/puppet/parser/ast/arithmetic_operator.rb b/lib/puppet/parser/ast/arithmetic_operator.rb
index 6b9a601..33352d7 100644
--- a/lib/puppet/parser/ast/arithmetic_operator.rb
+++ b/lib/puppet/parser/ast/arithmetic_operator.rb
@@ -2,38 +2,38 @@ require 'puppet'
require 'puppet/parser/ast/branch'
class Puppet::Parser::AST
- class ArithmeticOperator < AST::Branch
+ class ArithmeticOperator < AST::Branch
- attr_accessor :operator, :lval, :rval
+ attr_accessor :operator, :lval, :rval
- # Iterate across all of our children.
- def each
- [@lval, at rval, at operator].each { |child| yield child }
- end
+ # Iterate across all of our children.
+ def each
+ [@lval, at rval, at operator].each { |child| yield child }
+ end
- # Returns a boolean which is the result of the boolean operation
- # of lval and rval operands
- def evaluate(scope)
- # evaluate the operands, should return a boolean value
- lval = @lval.safeevaluate(scope)
- lval = Puppet::Parser::Scope.number?(lval)
- if lval == nil
- raise ArgumentError, "left operand of #{@operator} is not a number"
- end
- rval = @rval.safeevaluate(scope)
- rval = Puppet::Parser::Scope.number?(rval)
- if rval == nil
- raise ArgumentError, "right operand of #{@operator} is not a number"
- end
+ # Returns a boolean which is the result of the boolean operation
+ # of lval and rval operands
+ def evaluate(scope)
+ # evaluate the operands, should return a boolean value
+ lval = @lval.safeevaluate(scope)
+ lval = Puppet::Parser::Scope.number?(lval)
+ if lval == nil
+ raise ArgumentError, "left operand of #{@operator} is not a number"
+ end
+ rval = @rval.safeevaluate(scope)
+ rval = Puppet::Parser::Scope.number?(rval)
+ if rval == nil
+ raise ArgumentError, "right operand of #{@operator} is not a number"
+ end
- # compute result
- lval.send(@operator, rval)
- end
+ # compute result
+ lval.send(@operator, rval)
+ end
- def initialize(hash)
- super
+ def initialize(hash)
+ super
- raise ArgumentError, "Invalid arithmetic operator #{@operator}" unless %w{+ - * / << >>}.include?(@operator)
- end
+ raise ArgumentError, "Invalid arithmetic operator #{@operator}" unless %w{+ - * / << >>}.include?(@operator)
end
+ end
end
diff --git a/lib/puppet/parser/ast/astarray.rb b/lib/puppet/parser/ast/astarray.rb
index f0a0c56..529998e 100644
--- a/lib/puppet/parser/ast/astarray.rb
+++ b/lib/puppet/parser/ast/astarray.rb
@@ -1,61 +1,61 @@
require 'puppet/parser/ast/branch'
class Puppet::Parser::AST
- # The basic container class. This object behaves almost identically
- # to a normal array except at initialization time. Note that its name
- # is 'AST::ASTArray', rather than plain 'AST::Array'; I had too many
- # bugs when it was just 'AST::Array', because things like
- # 'object.is_a?(Array)' never behaved as I expected.
- class ASTArray < Branch
- include Enumerable
-
- # Return a child by index. Probably never used.
- def [](index)
- @children[index]
- end
+ # The basic container class. This object behaves almost identically
+ # to a normal array except at initialization time. Note that its name
+ # is 'AST::ASTArray', rather than plain 'AST::Array'; I had too many
+ # bugs when it was just 'AST::Array', because things like
+ # 'object.is_a?(Array)' never behaved as I expected.
+ class ASTArray < Branch
+ include Enumerable
+
+ # Return a child by index. Probably never used.
+ def [](index)
+ @children[index]
+ end
- # Evaluate our children.
- def evaluate(scope)
- # Make a new array, so we don't have to deal with the details of
- # flattening and such
- items = []
-
- # First clean out any AST::ASTArrays
- @children.each { |child|
- if child.instance_of?(AST::ASTArray)
- child.each do |ac|
- items << ac
- end
- else
- items << child
- end
- }
-
- rets = items.flatten.collect { |child|
- child.safeevaluate(scope)
- }
- rets.reject { |o| o.nil? }
+ # Evaluate our children.
+ def evaluate(scope)
+ # Make a new array, so we don't have to deal with the details of
+ # flattening and such
+ items = []
+
+ # First clean out any AST::ASTArrays
+ @children.each { |child|
+ if child.instance_of?(AST::ASTArray)
+ child.each do |ac|
+ items << ac
+ end
+ else
+ items << child
end
+ }
- def push(*ary)
- ary.each { |child|
- #Puppet.debug "adding %s(%s) of type %s to %s" %
- # [child, child.object_id, child.class.to_s.sub(/.+::/,''),
- # self.object_id]
- @children.push(child)
- }
+ rets = items.flatten.collect { |child|
+ child.safeevaluate(scope)
+ }
+ rets.reject { |o| o.nil? }
+ end
- self
- end
+ def push(*ary)
+ ary.each { |child|
+ #Puppet.debug "adding %s(%s) of type %s to %s" %
+ # [child, child.object_id, child.class.to_s.sub(/.+::/,''),
+ # self.object_id]
+ @children.push(child)
+ }
- def to_s
- "[" + @children.collect { |c| c.to_s }.join(', ') + "]"
- end
+ self
+ end
+
+ def to_s
+ "[" + @children.collect { |c| c.to_s }.join(', ') + "]"
end
+ end
- # A simple container class, containing the parameters for an object.
- # Used for abstracting the grammar declarations. Basically unnecessary
- # except that I kept finding bugs because I had too many arrays that
- # meant completely different things.
- class ResourceInstance < ASTArray; end
+ # A simple container class, containing the parameters for an object.
+ # Used for abstracting the grammar declarations. Basically unnecessary
+ # except that I kept finding bugs because I had too many arrays that
+ # meant completely different things.
+ class ResourceInstance < ASTArray; end
end
diff --git a/lib/puppet/parser/ast/asthash.rb b/lib/puppet/parser/ast/asthash.rb
index d16b745..ae81d35 100644
--- a/lib/puppet/parser/ast/asthash.rb
+++ b/lib/puppet/parser/ast/asthash.rb
@@ -1,37 +1,37 @@
require 'puppet/parser/ast/leaf'
class Puppet::Parser::AST
- class ASTHash < Leaf
- include Enumerable
+ class ASTHash < Leaf
+ include Enumerable
- # Evaluate our children.
- def evaluate(scope)
- items = {}
+ # Evaluate our children.
+ def evaluate(scope)
+ items = {}
- @value.each_pair do |k,v|
- key = k.respond_to?(:safeevaluate) ? k.safeevaluate(scope) : k
- items.merge!({ key => v.safeevaluate(scope) })
- end
+ @value.each_pair do |k,v|
+ key = k.respond_to?(:safeevaluate) ? k.safeevaluate(scope) : k
+ items.merge!({ key => v.safeevaluate(scope) })
+ end
- items
- end
+ items
+ end
- def merge(hash)
- case hash
- when ASTHash
- @value = @value.merge(hash.value)
- when Hash
- @value = @value.merge(hash)
- end
- end
+ def merge(hash)
+ case hash
+ when ASTHash
+ @value = @value.merge(hash.value)
+ when Hash
+ @value = @value.merge(hash)
+ end
+ end
- def to_s
- "{" + @value.collect { |v| v.collect { |a| a.to_s }.join(' => ') }.join(', ') + "}"
- end
+ def to_s
+ "{" + @value.collect { |v| v.collect { |a| a.to_s }.join(' => ') }.join(', ') + "}"
+ end
- def initialize(args)
- super(args)
- @value ||= {}
- end
+ def initialize(args)
+ super(args)
+ @value ||= {}
end
+ end
end
diff --git a/lib/puppet/parser/ast/boolean_operator.rb b/lib/puppet/parser/ast/boolean_operator.rb
index 0f7e21d..8481e4f 100644
--- a/lib/puppet/parser/ast/boolean_operator.rb
+++ b/lib/puppet/parser/ast/boolean_operator.rb
@@ -2,45 +2,45 @@ require 'puppet'
require 'puppet/parser/ast/branch'
class Puppet::Parser::AST
- class BooleanOperator < AST::Branch
+ class BooleanOperator < AST::Branch
- attr_accessor :operator, :lval, :rval
+ attr_accessor :operator, :lval, :rval
- # Iterate across all of our children.
- def each
- [@lval, at rval, at operator].each { |child| yield child }
- end
+ # Iterate across all of our children.
+ def each
+ [@lval, at rval, at operator].each { |child| yield child }
+ end
- # Returns a boolean which is the result of the boolean operation
- # of lval and rval operands
- def evaluate(scope)
- # evaluate the first operand, should return a boolean value
- lval = @lval.safeevaluate(scope)
+ # Returns a boolean which is the result of the boolean operation
+ # of lval and rval operands
+ def evaluate(scope)
+ # evaluate the first operand, should return a boolean value
+ lval = @lval.safeevaluate(scope)
- # return result
- # lazy evaluate right operand
- case @operator
- when "and"
- if Puppet::Parser::Scope.true?(lval)
- rval = @rval.safeevaluate(scope)
- Puppet::Parser::Scope.true?(rval)
- else # false and false == false
- false
- end
- when "or"
- if Puppet::Parser::Scope.true?(lval)
- true
- else
- rval = @rval.safeevaluate(scope)
- Puppet::Parser::Scope.true?(rval)
- end
- end
+ # return result
+ # lazy evaluate right operand
+ case @operator
+ when "and"
+ if Puppet::Parser::Scope.true?(lval)
+ rval = @rval.safeevaluate(scope)
+ Puppet::Parser::Scope.true?(rval)
+ else # false and false == false
+ false
+ end
+ when "or"
+ if Puppet::Parser::Scope.true?(lval)
+ true
+ else
+ rval = @rval.safeevaluate(scope)
+ Puppet::Parser::Scope.true?(rval)
end
+ end
+ end
- def initialize(hash)
- super
+ def initialize(hash)
+ super
- raise ArgumentError, "Invalid boolean operator #{@operator}" unless %w{and or}.include?(@operator)
- end
+ raise ArgumentError, "Invalid boolean operator #{@operator}" unless %w{and or}.include?(@operator)
end
+ end
end
diff --git a/lib/puppet/parser/ast/branch.rb b/lib/puppet/parser/ast/branch.rb
index 96d065e..73a2f67 100644
--- a/lib/puppet/parser/ast/branch.rb
+++ b/lib/puppet/parser/ast/branch.rb
@@ -1,37 +1,37 @@
class Puppet::Parser::AST
- # The parent class of all AST objects that contain other AST objects.
- # Everything but the really simple objects descend from this. It is
- # important to note that Branch objects contain other AST objects only --
- # if you want to contain values, use a descendent of the AST::Leaf class.
- class Branch < AST
- include Enumerable
- attr_accessor :pin, :children
+ # The parent class of all AST objects that contain other AST objects.
+ # Everything but the really simple objects descend from this. It is
+ # important to note that Branch objects contain other AST objects only --
+ # if you want to contain values, use a descendent of the AST::Leaf class.
+ class Branch < AST
+ include Enumerable
+ attr_accessor :pin, :children
- # Yield each contained AST node in turn. Used mostly by 'evaluate'.
- # This definition means that I don't have to override 'evaluate'
- # every time, but each child of Branch will likely need to override
- # this method.
- def each
- @children.each { |child|
- yield child
- }
- end
+ # Yield each contained AST node in turn. Used mostly by 'evaluate'.
+ # This definition means that I don't have to override 'evaluate'
+ # every time, but each child of Branch will likely need to override
+ # this method.
+ def each
+ @children.each { |child|
+ yield child
+ }
+ end
- # Initialize our object. Largely relies on the method from the base
- # class, but also does some verification.
- def initialize(arghash)
- super(arghash)
+ # Initialize our object. Largely relies on the method from the base
+ # class, but also does some verification.
+ def initialize(arghash)
+ super(arghash)
- # Create the hash, if it was not set at initialization time.
- @children ||= []
+ # Create the hash, if it was not set at initialization time.
+ @children ||= []
- # Verify that we only got valid AST nodes.
- @children.each { |child|
- unless child.is_a?(AST)
- raise Puppet::DevError,
- "child #{child} is a #{child.class} instead of ast"
- end
- }
+ # Verify that we only got valid AST nodes.
+ @children.each { |child|
+ unless child.is_a?(AST)
+ raise Puppet::DevError,
+ "child #{child} is a #{child.class} instead of ast"
end
+ }
end
+ end
end
diff --git a/lib/puppet/parser/ast/caseopt.rb b/lib/puppet/parser/ast/caseopt.rb
index 6cf36f9..4e296e8 100644
--- a/lib/puppet/parser/ast/caseopt.rb
+++ b/lib/puppet/parser/ast/caseopt.rb
@@ -1,64 +1,64 @@
require 'puppet/parser/ast/branch'
class Puppet::Parser::AST
- # Each individual option in a case statement.
- class CaseOpt < AST::Branch
- attr_accessor :value, :statements
+ # Each individual option in a case statement.
+ class CaseOpt < AST::Branch
+ attr_accessor :value, :statements
- # CaseOpt is a bit special -- we just want the value first,
- # so that CaseStatement can compare, and then it will selectively
- # decide whether to fully evaluate this option
+ # CaseOpt is a bit special -- we just want the value first,
+ # so that CaseStatement can compare, and then it will selectively
+ # decide whether to fully evaluate this option
- def each
- [@value, at statements].each { |child| yield child }
- end
+ def each
+ [@value, at statements].each { |child| yield child }
+ end
- # Are we the default option?
- def default?
- # Cache the @default value.
- return @default if defined?(@default)
+ # Are we the default option?
+ def default?
+ # Cache the @default value.
+ return @default if defined?(@default)
- if @value.is_a?(AST::ASTArray)
- @value.each { |subval|
- if subval.is_a?(AST::Default)
- @default = true
- break
- end
- }
- else
- @default = true if @value.is_a?(AST::Default)
- end
+ if @value.is_a?(AST::ASTArray)
+ @value.each { |subval|
+ if subval.is_a?(AST::Default)
+ @default = true
+ break
+ end
+ }
+ else
+ @default = true if @value.is_a?(AST::Default)
+ end
- @default ||= false
+ @default ||= false
- @default
- end
+ @default
+ end
- # You can specify a list of values; return each in turn.
- def eachvalue(scope)
- if @value.is_a?(AST::ASTArray)
- @value.each { |subval|
- yield subval.safeevaluate(scope)
- }
- else
- yield @value.safeevaluate(scope)
- end
- end
+ # You can specify a list of values; return each in turn.
+ def eachvalue(scope)
+ if @value.is_a?(AST::ASTArray)
+ @value.each { |subval|
+ yield subval.safeevaluate(scope)
+ }
+ else
+ yield @value.safeevaluate(scope)
+ end
+ end
- def eachopt
- if @value.is_a?(AST::ASTArray)
- @value.each { |subval|
- yield subval
- }
- else
- yield @value
- end
- end
+ def eachopt
+ if @value.is_a?(AST::ASTArray)
+ @value.each { |subval|
+ yield subval
+ }
+ else
+ yield @value
+ end
+ end
- # Evaluate the actual statements; this only gets called if
- # our option matched.
- def evaluate(scope)
- @statements.safeevaluate(scope)
- end
+ # Evaluate the actual statements; this only gets called if
+ # our option matched.
+ def evaluate(scope)
+ @statements.safeevaluate(scope)
end
+ end
end
diff --git a/lib/puppet/parser/ast/casestatement.rb b/lib/puppet/parser/ast/casestatement.rb
index 0cddef0..8370d11 100644
--- a/lib/puppet/parser/ast/casestatement.rb
+++ b/lib/puppet/parser/ast/casestatement.rb
@@ -1,44 +1,44 @@
require 'puppet/parser/ast/branch'
class Puppet::Parser::AST
- # The basic logical structure in Puppet. Supports a list of
- # tests and statement arrays.
- class CaseStatement < AST::Branch
- attr_accessor :test, :options, :default
+ # The basic logical structure in Puppet. Supports a list of
+ # tests and statement arrays.
+ class CaseStatement < AST::Branch
+ attr_accessor :test, :options, :default
- associates_doc
+ associates_doc
- # Short-curcuit evaluation. Return the value of the statements for
- # the first option that matches.
- def evaluate(scope)
- level = scope.ephemeral_level
+ # Short-curcuit evaluation. Return the value of the statements for
+ # the first option that matches.
+ def evaluate(scope)
+ level = scope.ephemeral_level
- value = @test.safeevaluate(scope)
+ value = @test.safeevaluate(scope)
- retvalue = nil
- found = false
+ retvalue = nil
+ found = false
- # Iterate across the options looking for a match.
- default = nil
- @options.each do |option|
- option.eachopt do |opt|
- return option.safeevaluate(scope) if opt.evaluate_match(value, scope)
- end
+ # Iterate across the options looking for a match.
+ default = nil
+ @options.each do |option|
+ option.eachopt do |opt|
+ return option.safeevaluate(scope) if opt.evaluate_match(value, scope)
+ end
- default = option if option.default?
- end
+ default = option if option.default?
+ end
- # Unless we found something, look for the default.
- return default.safeevaluate(scope) if default
+ # Unless we found something, look for the default.
+ return default.safeevaluate(scope) if default
- Puppet.debug "No true answers and no default"
- return nil
- ensure
- scope.unset_ephemeral_var(level)
- end
+ Puppet.debug "No true answers and no default"
+ return nil
+ ensure
+ scope.unset_ephemeral_var(level)
+ end
- def each
- [@test, at options].each { |child| yield child }
- end
+ def each
+ [@test, at options].each { |child| yield child }
end
+ end
end
diff --git a/lib/puppet/parser/ast/collection.rb b/lib/puppet/parser/ast/collection.rb
index 44f3b33..09d5b4e 100644
--- a/lib/puppet/parser/ast/collection.rb
+++ b/lib/puppet/parser/ast/collection.rb
@@ -6,60 +6,60 @@ require 'puppet/parser/collector'
# them to the current host, yo.
class Puppet::Parser::AST
class Collection < AST::Branch
- attr_accessor :type, :query, :form
- attr_reader :override
+ attr_accessor :type, :query, :form
+ attr_reader :override
- associates_doc
+ associates_doc
- # We return an object that does a late-binding evaluation.
- def evaluate(scope)
- if self.query
- str, code = self.query.safeevaluate scope
- else
- str = code = nil
- end
+ # We return an object that does a late-binding evaluation.
+ def evaluate(scope)
+ if self.query
+ str, code = self.query.safeevaluate scope
+ else
+ str = code = nil
+ end
- newcoll = Puppet::Parser::Collector.new(scope, @type, str, code, self.form)
+ newcoll = Puppet::Parser::Collector.new(scope, @type, str, code, self.form)
- scope.compiler.add_collection(newcoll)
+ scope.compiler.add_collection(newcoll)
- # overrides if any
- # Evaluate all of the specified params.
- if @override
- params = @override.collect do |param|
- param.safeevaluate(scope)
- end
+ # overrides if any
+ # Evaluate all of the specified params.
+ if @override
+ params = @override.collect do |param|
+ param.safeevaluate(scope)
+ end
- newcoll.add_override(
+ newcoll.add_override(
- :parameters => params,
- :file => @file,
- :line => @line,
- :source => scope.source,
+ :parameters => params,
+ :file => @file,
+ :line => @line,
+ :source => scope.source,
- :scope => scope
- )
- end
-
- newcoll
+ :scope => scope
+ )
end
- # Handle our parameter ourselves
- def override=(override)
- if override.is_a?(AST::ASTArray)
- @override = override
- else
+ newcoll
+ end
+
+ # Handle our parameter ourselves
+ def override=(override)
+ if override.is_a?(AST::ASTArray)
+ @override = override
+ else
- @override = AST::ASTArray.new(
+ @override = AST::ASTArray.new(
- :line => override.line,
- :file => override.file,
+ :line => override.line,
+ :file => override.file,
- :children => [override]
- )
- end
+ :children => [override]
+ )
end
+ end
end
end
diff --git a/lib/puppet/parser/ast/collexpr.rb b/lib/puppet/parser/ast/collexpr.rb
index f71b53d..f912b4b 100644
--- a/lib/puppet/parser/ast/collexpr.rb
+++ b/lib/puppet/parser/ast/collexpr.rb
@@ -6,81 +6,81 @@ require 'puppet/parser/collector'
# them to the current host, yo.
class Puppet::Parser::AST
class CollExpr < AST::Branch
- attr_accessor :test1, :test2, :oper, :form, :type, :parens
+ attr_accessor :test1, :test2, :oper, :form, :type, :parens
- # We return an object that does a late-binding evaluation.
- def evaluate(scope)
- # Make sure our contained expressions have all the info they need.
- [@test1, @test2].each do |t|
- if t.is_a?(self.class)
- t.form ||= self.form
- t.type ||= self.type
- end
- end
-
- # The code is only used for virtual lookups
- str1, code1 = @test1.safeevaluate scope
- str2, code2 = @test2.safeevaluate scope
-
- # First build up the virtual code.
- # If we're a conjunction operator, then we're calling code. I did
- # some speed comparisons, and it's at least twice as fast doing these
- # case statements as doing an eval here.
- code = proc do |resource|
- case @oper
- when "and"; code1.call(resource) and code2.call(resource)
- when "or"; code1.call(resource) or code2.call(resource)
- when "=="
- if str1 == "tag"
- resource.tagged?(str2)
- else
- if resource[str1].is_a?(Array)
- resource[str1].include?(str2)
- else
- resource[str1] == str2
- end
- end
- when "!="; resource[str1] != str2
- end
- end
-
- # Now build up the rails conditions code
- if self.parens and self.form == :exported
- Puppet.warning "Parentheses are ignored in Rails searches"
- end
+ # We return an object that does a late-binding evaluation.
+ def evaluate(scope)
+ # Make sure our contained expressions have all the info they need.
+ [@test1, @test2].each do |t|
+ if t.is_a?(self.class)
+ t.form ||= self.form
+ t.type ||= self.type
+ end
+ end
- case @oper
- when "and", "or"
- if form == :exported
- raise Puppet::ParseError, "Puppet does not currently support collecting exported resources with more than one condition"
- end
- oper = @oper.upcase
- when "=="; oper = "="
- else
- oper = @oper
- end
+ # The code is only used for virtual lookups
+ str1, code1 = @test1.safeevaluate scope
+ str2, code2 = @test2.safeevaluate scope
- if oper == "=" or oper == "!="
- # Add the rails association info where necessary
- case str1
- when "title"
- str = "title #{oper} '#{str2}'"
- when "tag"
- str = "puppet_tags.name #{oper} '#{str2}'"
- else
- str = "param_values.value #{oper} '#{str2}' and param_names.name = '#{str1}'"
- end
+ # First build up the virtual code.
+ # If we're a conjunction operator, then we're calling code. I did
+ # some speed comparisons, and it's at least twice as fast doing these
+ # case statements as doing an eval here.
+ code = proc do |resource|
+ case @oper
+ when "and"; code1.call(resource) and code2.call(resource)
+ when "or"; code1.call(resource) or code2.call(resource)
+ when "=="
+ if str1 == "tag"
+ resource.tagged?(str2)
else
- str = "(#{str1}) #{oper} (#{str2})"
+ if resource[str1].is_a?(Array)
+ resource[str1].include?(str2)
+ else
+ resource[str1] == str2
+ end
end
+ when "!="; resource[str1] != str2
+ end
+ end
- return str, code
+ # Now build up the rails conditions code
+ if self.parens and self.form == :exported
+ Puppet.warning "Parentheses are ignored in Rails searches"
end
- def initialize(hash = {})
- super
+ case @oper
+ when "and", "or"
+ if form == :exported
+ raise Puppet::ParseError, "Puppet does not currently support collecting exported resources with more than one condition"
+ end
+ oper = @oper.upcase
+ when "=="; oper = "="
+ else
+ oper = @oper
+ end
- raise ArgumentError, "Invalid operator #{@oper}" unless %w{== != and or}.include?(@oper)
+ if oper == "=" or oper == "!="
+ # Add the rails association info where necessary
+ case str1
+ when "title"
+ str = "title #{oper} '#{str2}'"
+ when "tag"
+ str = "puppet_tags.name #{oper} '#{str2}'"
+ else
+ str = "param_values.value #{oper} '#{str2}' and param_names.name = '#{str1}'"
+ end
+ else
+ str = "(#{str1}) #{oper} (#{str2})"
end
+
+ return str, code
+ end
+
+ def initialize(hash = {})
+ super
+
+ raise ArgumentError, "Invalid operator #{@oper}" unless %w{== != and or}.include?(@oper)
+ end
end
end
diff --git a/lib/puppet/parser/ast/comparison_operator.rb b/lib/puppet/parser/ast/comparison_operator.rb
index e8b21d4..c8694bb 100644
--- a/lib/puppet/parser/ast/comparison_operator.rb
+++ b/lib/puppet/parser/ast/comparison_operator.rb
@@ -2,38 +2,38 @@ require 'puppet'
require 'puppet/parser/ast/branch'
class Puppet::Parser::AST
- class ComparisonOperator < AST::Branch
-
- attr_accessor :operator, :lval, :rval
-
- # Iterate across all of our children.
- def each
- [@lval, at rval, at operator].each { |child| yield child }
- end
-
- # Returns a boolean which is the result of the boolean operation
- # of lval and rval operands
- def evaluate(scope)
- # evaluate the operands, should return a boolean value
- lval = @lval.safeevaluate(scope)
- rval = @rval.safeevaluate(scope)
-
- # convert to number if operands are number
- lval = Puppet::Parser::Scope.number?(lval) || lval
- rval = Puppet::Parser::Scope.number?(rval) || rval
-
- # return result
- unless @operator == '!='
- lval.send(@operator,rval)
- else
- lval != rval
- end
- end
-
- def initialize(hash)
- super
-
- raise ArgumentError, "Invalid comparison operator #{@operator}" unless %w{== != < > <= >=}.include?(@operator)
- end
+ class ComparisonOperator < AST::Branch
+
+ attr_accessor :operator, :lval, :rval
+
+ # Iterate across all of our children.
+ def each
+ [@lval, at rval, at operator].each { |child| yield child }
+ end
+
+ # Returns a boolean which is the result of the boolean operation
+ # of lval and rval operands
+ def evaluate(scope)
+ # evaluate the operands, should return a boolean value
+ lval = @lval.safeevaluate(scope)
+ rval = @rval.safeevaluate(scope)
+
+ # convert to number if operands are number
+ lval = Puppet::Parser::Scope.number?(lval) || lval
+ rval = Puppet::Parser::Scope.number?(rval) || rval
+
+ # return result
+ unless @operator == '!='
+ lval.send(@operator,rval)
+ else
+ lval != rval
+ end
+ end
+
+ def initialize(hash)
+ super
+
+ raise ArgumentError, "Invalid comparison operator #{@operator}" unless %w{== != < > <= >=}.include?(@operator)
end
+ end
end
diff --git a/lib/puppet/parser/ast/else.rb b/lib/puppet/parser/ast/else.rb
index 2da9191..1721491 100644
--- a/lib/puppet/parser/ast/else.rb
+++ b/lib/puppet/parser/ast/else.rb
@@ -1,22 +1,22 @@
require 'puppet/parser/ast/branch'
class Puppet::Parser::AST
- # A separate ElseIf statement; can function as an 'else' if there's no
- # test.
- class Else < AST::Branch
+ # A separate ElseIf statement; can function as an 'else' if there's no
+ # test.
+ class Else < AST::Branch
- associates_doc
+ associates_doc
- attr_accessor :statements
+ attr_accessor :statements
- def each
- yield @statements
- end
+ def each
+ yield @statements
+ end
- # Evaluate the actual statements; this only gets called if
- # our test was true matched.
- def evaluate(scope)
- @statements.safeevaluate(scope)
- end
+ # Evaluate the actual statements; this only gets called if
+ # our test was true matched.
+ def evaluate(scope)
+ @statements.safeevaluate(scope)
end
+ end
end
diff --git a/lib/puppet/parser/ast/function.rb b/lib/puppet/parser/ast/function.rb
index 6f6c869..602016c 100644
--- a/lib/puppet/parser/ast/function.rb
+++ b/lib/puppet/parser/ast/function.rb
@@ -1,51 +1,51 @@
require 'puppet/parser/ast/branch'
class Puppet::Parser::AST
- # An AST object to call a function.
- class Function < AST::Branch
+ # An AST object to call a function.
+ class Function < AST::Branch
- associates_doc
+ associates_doc
- attr_accessor :name, :arguments
+ attr_accessor :name, :arguments
- @settor = true
+ @settor = true
- def evaluate(scope)
+ def evaluate(scope)
- # Make sure it's a defined function
- raise Puppet::ParseError, "Unknown function #{@name}" unless Puppet::Parser::Functions.function(@name)
+ # Make sure it's a defined function
+ raise Puppet::ParseError, "Unknown function #{@name}" unless Puppet::Parser::Functions.function(@name)
- # Now check that it's been used correctly
- case @ftype
- when :rvalue
- raise Puppet::ParseError, "Function '#{@name}' does not return a value" unless Puppet::Parser::Functions.rvalue?(@name)
- when :statement
- if Puppet::Parser::Functions.rvalue?(@name)
- raise Puppet::ParseError,
- "Function '#{@name}' must be the value of a statement"
- end
- else
- raise Puppet::DevError, "Invalid function type #{@ftype.inspect}"
- end
+ # Now check that it's been used correctly
+ case @ftype
+ when :rvalue
+ raise Puppet::ParseError, "Function '#{@name}' does not return a value" unless Puppet::Parser::Functions.rvalue?(@name)
+ when :statement
+ if Puppet::Parser::Functions.rvalue?(@name)
+ raise Puppet::ParseError,
+ "Function '#{@name}' must be the value of a statement"
+ end
+ else
+ raise Puppet::DevError, "Invalid function type #{@ftype.inspect}"
+ end
- # We don't need to evaluate the name, because it's plaintext
- args = @arguments.safeevaluate(scope)
+ # We don't need to evaluate the name, because it's plaintext
+ args = @arguments.safeevaluate(scope)
- scope.send("function_#{@name}", args)
- end
+ scope.send("function_#{@name}", args)
+ end
- def initialize(hash)
- @ftype = hash[:ftype] || :rvalue
- hash.delete(:ftype) if hash.include? :ftype
+ def initialize(hash)
+ @ftype = hash[:ftype] || :rvalue
+ hash.delete(:ftype) if hash.include? :ftype
- super(hash)
+ super(hash)
- # Lastly, check the parity
- end
+ # Lastly, check the parity
+ end
- def to_s
- args = arguments.is_a?(ASTArray) ? arguments.to_s.gsub(/\[(.*)\]/,'\1') : arguments
- "#{name}(#{args})"
- end
+ def to_s
+ args = arguments.is_a?(ASTArray) ? arguments.to_s.gsub(/\[(.*)\]/,'\1') : arguments
+ "#{name}(#{args})"
end
+ end
end
diff --git a/lib/puppet/parser/ast/ifstatement.rb b/lib/puppet/parser/ast/ifstatement.rb
index cbb61bf..7fd8a57 100644
--- a/lib/puppet/parser/ast/ifstatement.rb
+++ b/lib/puppet/parser/ast/ifstatement.rb
@@ -1,34 +1,34 @@
require 'puppet/parser/ast/branch'
class Puppet::Parser::AST
- # A basic 'if/elsif/else' statement.
- class IfStatement < AST::Branch
+ # A basic 'if/elsif/else' statement.
+ class IfStatement < AST::Branch
- associates_doc
+ associates_doc
- attr_accessor :test, :else, :statements
+ attr_accessor :test, :else, :statements
- def each
- [@test, at else, at statements].each { |child| yield child }
- end
+ def each
+ [@test, at else, at statements].each { |child| yield child }
+ end
- # Short-curcuit evaluation. If we're true, evaluate our statements,
- # else if there's an 'else' setting, evaluate it.
- # the first option that matches.
- def evaluate(scope)
- level = scope.ephemeral_level
- value = @test.safeevaluate(scope)
+ # Short-curcuit evaluation. If we're true, evaluate our statements,
+ # else if there's an 'else' setting, evaluate it.
+ # the first option that matches.
+ def evaluate(scope)
+ level = scope.ephemeral_level
+ value = @test.safeevaluate(scope)
- # let's emulate a new scope for each branches
- begin
- if Puppet::Parser::Scope.true?(value)
- return @statements.safeevaluate(scope)
- else
- return defined?(@else) ? @else.safeevaluate(scope) : nil
- end
- ensure
- scope.unset_ephemeral_var(level)
- end
+ # let's emulate a new scope for each branches
+ begin
+ if Puppet::Parser::Scope.true?(value)
+ return @statements.safeevaluate(scope)
+ else
+ return defined?(@else) ? @else.safeevaluate(scope) : nil
end
+ ensure
+ scope.unset_ephemeral_var(level)
+ end
end
+ end
end
diff --git a/lib/puppet/parser/ast/in_operator.rb b/lib/puppet/parser/ast/in_operator.rb
index 1b17b10..2a163e7 100644
--- a/lib/puppet/parser/ast/in_operator.rb
+++ b/lib/puppet/parser/ast/in_operator.rb
@@ -2,23 +2,23 @@ require 'puppet'
require 'puppet/parser/ast/branch'
class Puppet::Parser::AST
- class InOperator < AST::Branch
+ class InOperator < AST::Branch
- attr_accessor :lval, :rval
+ attr_accessor :lval, :rval
- # Returns a boolean which is the result of the 'in' operation
- # of lval and rval operands
- def evaluate(scope)
+ # Returns a boolean which is the result of the 'in' operation
+ # of lval and rval operands
+ def evaluate(scope)
- # evaluate the operands, should return a boolean value
- lval = @lval.safeevaluate(scope)
- raise ArgumentError, "'#{lval}' from left operand of 'in' expression is not a string" unless lval.is_a?(::String)
+ # evaluate the operands, should return a boolean value
+ lval = @lval.safeevaluate(scope)
+ raise ArgumentError, "'#{lval}' from left operand of 'in' expression is not a string" unless lval.is_a?(::String)
- rval = @rval.safeevaluate(scope)
- unless rval.respond_to?(:include?)
- raise ArgumentError, "'#{rval}' from right operand of 'in' expression is not of a supported type (string, array or hash)"
- end
- rval.include?(lval)
- end
+ rval = @rval.safeevaluate(scope)
+ unless rval.respond_to?(:include?)
+ raise ArgumentError, "'#{rval}' from right operand of 'in' expression is not of a supported type (string, array or hash)"
+ end
+ rval.include?(lval)
end
+ end
end
diff --git a/lib/puppet/parser/ast/leaf.rb b/lib/puppet/parser/ast/leaf.rb
index a62edc6..3b9163d 100644
--- a/lib/puppet/parser/ast/leaf.rb
+++ b/lib/puppet/parser/ast/leaf.rb
@@ -1,224 +1,224 @@
class Puppet::Parser::AST
- # The base class for all of the leaves of the parse trees. These
- # basically just have types and values. Both of these parameters
- # are simple values, not AST objects.
- class Leaf < AST
- attr_accessor :value, :type
-
- # Return our value.
- def evaluate(scope)
- @value
- end
-
- # evaluate ourselves, and match
- def evaluate_match(value, scope)
- obj = self.safeevaluate(scope)
+ # The base class for all of the leaves of the parse trees. These
+ # basically just have types and values. Both of these parameters
+ # are simple values, not AST objects.
+ class Leaf < AST
+ attr_accessor :value, :type
+
+ # Return our value.
+ def evaluate(scope)
+ @value
+ end
- obj = obj.downcase if obj.respond_to?(:downcase)
- value = value.downcase if value.respond_to?(:downcase)
+ # evaluate ourselves, and match
+ def evaluate_match(value, scope)
+ obj = self.safeevaluate(scope)
- # "" == undef for case/selector/if
- obj == value or (obj == "" and value == :undef)
- end
+ obj = obj.downcase if obj.respond_to?(:downcase)
+ value = value.downcase if value.respond_to?(:downcase)
- def match(value)
- @value == value
- end
+ # "" == undef for case/selector/if
+ obj == value or (obj == "" and value == :undef)
+ end
- def to_s
- @value.to_s unless @value.nil?
- end
+ def match(value)
+ @value == value
end
- # The boolean class. True or false. Converts the string it receives
- # to a Ruby boolean.
- class Boolean < AST::Leaf
+ def to_s
+ @value.to_s unless @value.nil?
+ end
+ end
- # Use the parent method, but then convert to a real boolean.
- def initialize(hash)
- super
+ # The boolean class. True or false. Converts the string it receives
+ # to a Ruby boolean.
+ class Boolean < AST::Leaf
- unless @value == true or @value == false
- raise Puppet::DevError,
- "'#{@value}' is not a boolean"
- end
- @value
- end
+ # Use the parent method, but then convert to a real boolean.
+ def initialize(hash)
+ super
- def to_s
- @value ? "true" : "false"
- end
+ unless @value == true or @value == false
+ raise Puppet::DevError,
+ "'#{@value}' is not a boolean"
+ end
+ @value
end
- # The base string class.
- class String < AST::Leaf
- def evaluate(scope)
- @value
- end
+ def to_s
+ @value ? "true" : "false"
+ end
+ end
- def to_s
- "\"#{@value}\""
- end
+ # The base string class.
+ class String < AST::Leaf
+ def evaluate(scope)
+ @value
end
- # An uninterpreted string.
- class FlatString < AST::Leaf
- def evaluate(scope)
- @value
- end
+ def to_s
+ "\"#{@value}\""
+ end
+ end
- def to_s
- "\"#{@value}\""
- end
+ # An uninterpreted string.
+ class FlatString < AST::Leaf
+ def evaluate(scope)
+ @value
end
- class Concat < AST::Leaf
- def evaluate(scope)
- @value.collect { |x| x.evaluate(scope) }.join
- end
+ def to_s
+ "\"#{@value}\""
+ end
+ end
- def to_s
- "concat(#{@value.join(',')})"
- end
+ class Concat < AST::Leaf
+ def evaluate(scope)
+ @value.collect { |x| x.evaluate(scope) }.join
end
- # The 'default' option on case statements and selectors.
- class Default < AST::Leaf; end
+ def to_s
+ "concat(#{@value.join(',')})"
+ end
+ end
- # Capitalized words; used mostly for type-defaults, but also
- # get returned by the lexer any other time an unquoted capitalized
- # word is found.
- class Type < AST::Leaf; end
+ # The 'default' option on case statements and selectors.
+ class Default < AST::Leaf; end
- # Lower-case words.
- class Name < AST::Leaf; end
+ # Capitalized words; used mostly for type-defaults, but also
+ # get returned by the lexer any other time an unquoted capitalized
+ # word is found.
+ class Type < AST::Leaf; end
- # double-colon separated class names
- class ClassName < AST::Leaf; end
+ # Lower-case words.
+ class Name < AST::Leaf; end
- # undef values; equiv to nil
- class Undef < AST::Leaf; end
+ # double-colon separated class names
+ class ClassName < AST::Leaf; end
- # Host names, either fully qualified or just the short name, or even a regex
- class HostName < AST::Leaf
- def initialize(hash)
- super
+ # undef values; equiv to nil
+ class Undef < AST::Leaf; end
- # Note that this is an AST::Regex, not a Regexp
- @value = @value.to_s.downcase unless @value.is_a?(Regex)
- if @value =~ /[^-\w.]/
- raise Puppet::DevError,
- "'#{@value}' is not a valid hostname"
- end
- end
+ # Host names, either fully qualified or just the short name, or even a regex
+ class HostName < AST::Leaf
+ def initialize(hash)
+ super
- # implementing eql? and hash so that when an HostName is stored
- # in a hash it has the same hashing properties as the underlying value
- def eql?(value)
- value = value.value if value.is_a?(HostName)
- @value.eql?(value)
- end
+ # Note that this is an AST::Regex, not a Regexp
+ @value = @value.to_s.downcase unless @value.is_a?(Regex)
+ if @value =~ /[^-\w.]/
+ raise Puppet::DevError,
+ "'#{@value}' is not a valid hostname"
+ end
+ end
- def hash
- @value.hash
- end
+ # implementing eql? and hash so that when an HostName is stored
+ # in a hash it has the same hashing properties as the underlying value
+ def eql?(value)
+ value = value.value if value.is_a?(HostName)
+ @value.eql?(value)
+ end
- def to_s
- @value.to_s
- end
+ def hash
+ @value.hash
end
- # A simple variable. This object is only used during interpolation;
- # the VarDef class is used for assignment.
- class Variable < Name
- # Looks up the value of the object in the scope tree (does
- # not include syntactical constructs, like '$' and '{}').
- def evaluate(scope)
- parsewrap do
- if (var = scope.lookupvar(@value, false)) == :undefined
- var = :undef
- end
- var
- end
- end
+ def to_s
+ @value.to_s
+ end
+ end
+
+ # A simple variable. This object is only used during interpolation;
+ # the VarDef class is used for assignment.
+ class Variable < Name
+ # Looks up the value of the object in the scope tree (does
+ # not include syntactical constructs, like '$' and '{}').
+ def evaluate(scope)
+ parsewrap do
+ if (var = scope.lookupvar(@value, false)) == :undefined
+ var = :undef
+ end
+ var
+ end
+ end
- def to_s
- "\$#{value}"
- end
+ def to_s
+ "\$#{value}"
end
+ end
- class HashOrArrayAccess < AST::Leaf
- attr_accessor :variable, :key
+ class HashOrArrayAccess < AST::Leaf
+ attr_accessor :variable, :key
- def evaluate_container(scope)
- container = variable.respond_to?(:evaluate) ? variable.safeevaluate(scope) : variable
- (container.is_a?(Hash) or container.is_a?(Array)) ? container : scope.lookupvar(container)
- end
+ def evaluate_container(scope)
+ container = variable.respond_to?(:evaluate) ? variable.safeevaluate(scope) : variable
+ (container.is_a?(Hash) or container.is_a?(Array)) ? container : scope.lookupvar(container)
+ end
- def evaluate_key(scope)
- key.respond_to?(:evaluate) ? key.safeevaluate(scope) : key
- end
+ def evaluate_key(scope)
+ key.respond_to?(:evaluate) ? key.safeevaluate(scope) : key
+ end
- def evaluate(scope)
- object = evaluate_container(scope)
+ def evaluate(scope)
+ object = evaluate_container(scope)
- raise Puppet::ParseError, "#{variable} is not an hash or array when accessing it with #{accesskey}" unless object.is_a?(Hash) or object.is_a?(Array)
+ raise Puppet::ParseError, "#{variable} is not an hash or array when accessing it with #{accesskey}" unless object.is_a?(Hash) or object.is_a?(Array)
- object[evaluate_key(scope)]
- end
+ object[evaluate_key(scope)]
+ end
- # Assign value to this hashkey or array index
- def assign(scope, value)
- object = evaluate_container(scope)
- accesskey = evaluate_key(scope)
+ # Assign value to this hashkey or array index
+ def assign(scope, value)
+ object = evaluate_container(scope)
+ accesskey = evaluate_key(scope)
- if object.is_a?(Hash) and object.include?(accesskey)
- raise Puppet::ParseError, "Assigning to the hash '#{variable}' with an existing key '#{accesskey}' is forbidden"
- end
+ if object.is_a?(Hash) and object.include?(accesskey)
+ raise Puppet::ParseError, "Assigning to the hash '#{variable}' with an existing key '#{accesskey}' is forbidden"
+ end
- # assign to hash or array
- object[accesskey] = value
- end
+ # assign to hash or array
+ object[accesskey] = value
+ end
- def to_s
- "\$#{variable.to_s}[#{key.to_s}]"
- end
+ def to_s
+ "\$#{variable.to_s}[#{key.to_s}]"
end
+ end
- class Regex < AST::Leaf
- def initialize(hash)
- super
- @value = Regexp.new(@value) unless @value.is_a?(Regexp)
- end
+ class Regex < AST::Leaf
+ def initialize(hash)
+ super
+ @value = Regexp.new(@value) unless @value.is_a?(Regexp)
+ end
- # we're returning self here to wrap the regexp and to be used in places
- # where a string would have been used, without modifying any client code.
- # For instance, in many places we have the following code snippet:
- # val = @val.safeevaluate(@scope)
- # if val.match(otherval)
- # ...
- # end
- # this way, we don't have to modify this test specifically for handling
- # regexes.
- def evaluate(scope)
- self
- end
+ # we're returning self here to wrap the regexp and to be used in places
+ # where a string would have been used, without modifying any client code.
+ # For instance, in many places we have the following code snippet:
+ # val = @val.safeevaluate(@scope)
+ # if val.match(otherval)
+ # ...
+ # end
+ # this way, we don't have to modify this test specifically for handling
+ # regexes.
+ def evaluate(scope)
+ self
+ end
- def evaluate_match(value, scope, options = {})
- value = value.is_a?(String) ? value : value.to_s
+ def evaluate_match(value, scope, options = {})
+ value = value.is_a?(String) ? value : value.to_s
- if matched = @value.match(value)
- scope.ephemeral_from(matched, options[:file], options[:line])
- end
- matched
- end
+ if matched = @value.match(value)
+ scope.ephemeral_from(matched, options[:file], options[:line])
+ end
+ matched
+ end
- def match(value)
- @value.match(value)
- end
+ def match(value)
+ @value.match(value)
+ end
- def to_s
- "/#{@value.source}/"
- end
+ def to_s
+ "/#{@value.source}/"
end
+ end
end
diff --git a/lib/puppet/parser/ast/match_operator.rb b/lib/puppet/parser/ast/match_operator.rb
index 2ab2bef..6207a8c 100644
--- a/lib/puppet/parser/ast/match_operator.rb
+++ b/lib/puppet/parser/ast/match_operator.rb
@@ -2,27 +2,27 @@ require 'puppet'
require 'puppet/parser/ast/branch'
class Puppet::Parser::AST
- class MatchOperator < AST::Branch
+ class MatchOperator < AST::Branch
- attr_accessor :lval, :rval, :operator
+ attr_accessor :lval, :rval, :operator
- # Iterate across all of our children.
- def each
- [@lval, at rval].each { |child| yield child }
- end
+ # Iterate across all of our children.
+ def each
+ [@lval, at rval].each { |child| yield child }
+ end
- # Returns a boolean which is the result of the boolean operation
- # of lval and rval operands
- def evaluate(scope)
- lval = @lval.safeevaluate(scope)
+ # Returns a boolean which is the result of the boolean operation
+ # of lval and rval operands
+ def evaluate(scope)
+ lval = @lval.safeevaluate(scope)
- return(rval.evaluate_match(lval, scope) ? @operator == "=~" : @operator == "!~")
- end
+ return(rval.evaluate_match(lval, scope) ? @operator == "=~" : @operator == "!~")
+ end
- def initialize(hash)
- super
+ def initialize(hash)
+ super
- raise ArgumentError, "Invalid regexp operator #{@operator}" unless %w{!~ =~}.include?(@operator)
- end
+ raise ArgumentError, "Invalid regexp operator #{@operator}" unless %w{!~ =~}.include?(@operator)
end
+ end
end
diff --git a/lib/puppet/parser/ast/minus.rb b/lib/puppet/parser/ast/minus.rb
index 40f6433..d7a362a 100644
--- a/lib/puppet/parser/ast/minus.rb
+++ b/lib/puppet/parser/ast/minus.rb
@@ -4,20 +4,20 @@ require 'puppet/parser/ast/branch'
# An object that returns a boolean which is the boolean not
# of the given value.
class Puppet::Parser::AST
- class Minus < AST::Branch
- attr_accessor :value
+ class Minus < AST::Branch
+ attr_accessor :value
- def each
- yield @value
- end
+ def each
+ yield @value
+ end
- def evaluate(scope)
- val = @value.safeevaluate(scope)
- val = Puppet::Parser::Scope.number?(val)
- if val == nil
- raise ArgumentError, "minus operand #{val} is not a number"
- end
- -val
- end
+ def evaluate(scope)
+ val = @value.safeevaluate(scope)
+ val = Puppet::Parser::Scope.number?(val)
+ if val == nil
+ raise ArgumentError, "minus operand #{val} is not a number"
+ end
+ -val
end
+ end
end
diff --git a/lib/puppet/parser/ast/nop.rb b/lib/puppet/parser/ast/nop.rb
index ea52320..bf35c6a 100644
--- a/lib/puppet/parser/ast/nop.rb
+++ b/lib/puppet/parser/ast/nop.rb
@@ -1,11 +1,11 @@
require 'puppet/parser/ast/branch'
class Puppet::Parser::AST
- # This class is a no-op, it doesn't produce anything
- # when evaluated, hence it's name :-)
- class Nop < AST::Leaf
- def evaluate(scope)
- # nothing to do
- end
+ # This class is a no-op, it doesn't produce anything
+ # when evaluated, hence it's name :-)
+ class Nop < AST::Leaf
+ def evaluate(scope)
+ # nothing to do
end
+ end
end
diff --git a/lib/puppet/parser/ast/not.rb b/lib/puppet/parser/ast/not.rb
index 24d5e83..30fa6d5 100644
--- a/lib/puppet/parser/ast/not.rb
+++ b/lib/puppet/parser/ast/not.rb
@@ -4,16 +4,16 @@ require 'puppet/parser/ast/branch'
# An object that returns a boolean which is the boolean not
# of the given value.
class Puppet::Parser::AST
- class Not < AST::Branch
- attr_accessor :value
+ class Not < AST::Branch
+ attr_accessor :value
- def each
- yield @value
- end
+ def each
+ yield @value
+ end
- def evaluate(scope)
- val = @value.safeevaluate(scope)
- ! Puppet::Parser::Scope.true?(val)
- end
+ def evaluate(scope)
+ val = @value.safeevaluate(scope)
+ ! Puppet::Parser::Scope.true?(val)
end
+ end
end
diff --git a/lib/puppet/parser/ast/relationship.rb b/lib/puppet/parser/ast/relationship.rb
index 9f9f6fc..a7134a0 100644
--- a/lib/puppet/parser/ast/relationship.rb
+++ b/lib/puppet/parser/ast/relationship.rb
@@ -3,58 +3,58 @@ require 'puppet/parser/ast/branch'
require 'puppet/parser/relationship'
class Puppet::Parser::AST::Relationship < Puppet::Parser::AST::Branch
- RELATIONSHIP_TYPES = %w{-> <- ~> <~}
+ RELATIONSHIP_TYPES = %w{-> <- ~> <~}
- attr_accessor :left, :right, :arrow, :type
+ attr_accessor :left, :right, :arrow, :type
- def actual_left
- chained? ? left.right : left
- end
+ def actual_left
+ chained? ? left.right : left
+ end
- # Evaluate our object, but just return a simple array of the type
- # and name.
- def evaluate(scope)
- if chained?
- real_left = left.safeevaluate(scope)
- left_dep = left_dep.shift if left_dep.is_a?(Array)
- else
- real_left = left.safeevaluate(scope)
- end
- real_right = right.safeevaluate(scope)
-
- source, target = sides2edge(real_left, real_right)
- result = Puppet::Parser::Relationship.new(source, target, type)
- scope.compiler.add_relationship(result)
- real_right
+ # Evaluate our object, but just return a simple array of the type
+ # and name.
+ def evaluate(scope)
+ if chained?
+ real_left = left.safeevaluate(scope)
+ left_dep = left_dep.shift if left_dep.is_a?(Array)
+ else
+ real_left = left.safeevaluate(scope)
end
+ real_right = right.safeevaluate(scope)
- def initialize(left, right, arrow, args = {})
- super(args)
- unless RELATIONSHIP_TYPES.include?(arrow)
- raise ArgumentError, "Invalid relationship type #{arrow.inspect}; valid types are #{RELATIONSHIP_TYPES.collect { |r| r.to_s }.join(", ")}"
- end
- @left, @right, @arrow = left, right, arrow
- end
+ source, target = sides2edge(real_left, real_right)
+ result = Puppet::Parser::Relationship.new(source, target, type)
+ scope.compiler.add_relationship(result)
+ real_right
+ end
- def type
- subscription? ? :subscription : :relationship
+ def initialize(left, right, arrow, args = {})
+ super(args)
+ unless RELATIONSHIP_TYPES.include?(arrow)
+ raise ArgumentError, "Invalid relationship type #{arrow.inspect}; valid types are #{RELATIONSHIP_TYPES.collect { |r| r.to_s }.join(", ")}"
end
+ @left, @right, @arrow = left, right, arrow
+ end
- def sides2edge(left, right)
- out_edge? ? [left, right] : [right, left]
- end
+ def type
+ subscription? ? :subscription : :relationship
+ end
- private
+ def sides2edge(left, right)
+ out_edge? ? [left, right] : [right, left]
+ end
- def chained?
- left.is_a?(self.class)
- end
+ private
- def out_edge?
- ["->", "~>"].include?(arrow)
- end
+ def chained?
+ left.is_a?(self.class)
+ end
- def subscription?
- ["~>", "<~"].include?(arrow)
- end
+ def out_edge?
+ ["->", "~>"].include?(arrow)
+ end
+
+ def subscription?
+ ["~>", "<~"].include?(arrow)
+ end
end
diff --git a/lib/puppet/parser/ast/resource.rb b/lib/puppet/parser/ast/resource.rb
index 01b9370..1b063c9 100644
--- a/lib/puppet/parser/ast/resource.rb
+++ b/lib/puppet/parser/ast/resource.rb
@@ -5,73 +5,73 @@ require 'puppet/parser/ast/resource_reference'
class Puppet::Parser::AST
class Resource < AST::ResourceReference
- associates_doc
+ associates_doc
- attr_accessor :title, :type, :exported, :virtual
- attr_reader :parameters
+ attr_accessor :title, :type, :exported, :virtual
+ attr_reader :parameters
- # Does not actually return an object; instead sets an object
- # in the current scope.
- def evaluate(scope)
- # Evaluate all of the specified params.
- paramobjects = parameters.collect { |param|
- param.safeevaluate(scope)
- }
+ # Does not actually return an object; instead sets an object
+ # in the current scope.
+ def evaluate(scope)
+ # Evaluate all of the specified params.
+ paramobjects = parameters.collect { |param|
+ param.safeevaluate(scope)
+ }
- resource_titles = @title.safeevaluate(scope)
+ resource_titles = @title.safeevaluate(scope)
- # it's easier to always use an array, even for only one name
- resource_titles = [resource_titles] unless resource_titles.is_a?(Array)
+ # it's easier to always use an array, even for only one name
+ resource_titles = [resource_titles] unless resource_titles.is_a?(Array)
- # We want virtual to be true if exported is true. We can't
- # just set :virtual => self.virtual in the initialization,
- # because sometimes the :virtual attribute is set *after*
- # :exported, in which case it clobbers :exported if :exported
- # is true. Argh, this was a very tough one to track down.
- virt = self.virtual || self.exported
+ # We want virtual to be true if exported is true. We can't
+ # just set :virtual => self.virtual in the initialization,
+ # because sometimes the :virtual attribute is set *after*
+ # :exported, in which case it clobbers :exported if :exported
+ # is true. Argh, this was a very tough one to track down.
+ virt = self.virtual || self.exported
- # This is where our implicit iteration takes place; if someone
- # passed an array as the name, then we act just like the called us
- # many times.
- resource_titles.flatten.collect { |resource_title|
- exceptwrap :type => Puppet::ParseError do
+ # This is where our implicit iteration takes place; if someone
+ # passed an array as the name, then we act just like the called us
+ # many times.
+ resource_titles.flatten.collect { |resource_title|
+ exceptwrap :type => Puppet::ParseError do
- resource = Puppet::Parser::Resource.new(
- type, resource_title,
- :parameters => paramobjects,
- :file => self.file,
- :line => self.line,
- :exported => self.exported,
- :virtual => virt,
- :source => scope.source,
- :scope => scope,
+ resource = Puppet::Parser::Resource.new(
+ type, resource_title,
+ :parameters => paramobjects,
+ :file => self.file,
+ :line => self.line,
+ :exported => self.exported,
+ :virtual => virt,
+ :source => scope.source,
+ :scope => scope,
- :strict => true
- )
+ :strict => true
+ )
- # And then store the resource in the compiler.
- # At some point, we need to switch all of this to return
- # resources instead of storing them like this.
- scope.compiler.add_resource(scope, resource)
- resource
- end
- }.reject { |resource| resource.nil? }
- end
+ # And then store the resource in the compiler.
+ # At some point, we need to switch all of this to return
+ # resources instead of storing them like this.
+ scope.compiler.add_resource(scope, resource)
+ resource
+ end
+ }.reject { |resource| resource.nil? }
+ end
- # Set the parameters for our object.
- def parameters=(params)
- if params.is_a?(AST::ASTArray)
- @parameters = params
- else
+ # Set the parameters for our object.
+ def parameters=(params)
+ if params.is_a?(AST::ASTArray)
+ @parameters = params
+ else
- @parameters = AST::ASTArray.new(
+ @parameters = AST::ASTArray.new(
- :line => params.line,
- :file => params.file,
+ :line => params.line,
+ :file => params.file,
- :children => [params]
- )
- end
+ :children => [params]
+ )
end
+ end
end
end
diff --git a/lib/puppet/parser/ast/resource_defaults.rb b/lib/puppet/parser/ast/resource_defaults.rb
index aec86d0..812b979 100644
--- a/lib/puppet/parser/ast/resource_defaults.rb
+++ b/lib/puppet/parser/ast/resource_defaults.rb
@@ -1,24 +1,24 @@
require 'puppet/parser/ast/branch'
class Puppet::Parser::AST
- # A statement syntactically similar to an ResourceDef, but uses a
- # capitalized object type and cannot have a name.
- class ResourceDefaults < AST::Branch
- attr_accessor :type, :parameters
+ # A statement syntactically similar to an ResourceDef, but uses a
+ # capitalized object type and cannot have a name.
+ class ResourceDefaults < AST::Branch
+ attr_accessor :type, :parameters
- associates_doc
+ associates_doc
- # As opposed to ResourceDef, this stores each default for the given
- # object type.
- def evaluate(scope)
- # Use a resource reference to canonize the type
- ref = Puppet::Resource.new(@type, "whatever")
- type = ref.type
- params = @parameters.safeevaluate(scope)
+ # As opposed to ResourceDef, this stores each default for the given
+ # object type.
+ def evaluate(scope)
+ # Use a resource reference to canonize the type
+ ref = Puppet::Resource.new(@type, "whatever")
+ type = ref.type
+ params = @parameters.safeevaluate(scope)
- parsewrap do
- scope.setdefaults(type, params)
- end
- end
+ parsewrap do
+ scope.setdefaults(type, params)
+ end
end
+ end
end
diff --git a/lib/puppet/parser/ast/resource_override.rb b/lib/puppet/parser/ast/resource_override.rb
index 7f7047d..e0be889 100644
--- a/lib/puppet/parser/ast/resource_override.rb
+++ b/lib/puppet/parser/ast/resource_override.rb
@@ -1,68 +1,68 @@
require 'puppet/parser/ast/resource'
class Puppet::Parser::AST
- # Set a parameter on a resource specification created somewhere else in the
- # configuration. The object is responsible for verifying that this is allowed.
- class ResourceOverride < Resource
+ # Set a parameter on a resource specification created somewhere else in the
+ # configuration. The object is responsible for verifying that this is allowed.
+ class ResourceOverride < Resource
- associates_doc
+ associates_doc
- attr_accessor :object
- attr_reader :parameters
+ attr_accessor :object
+ attr_reader :parameters
- # Iterate across all of our children.
- def each
- [@object, at parameters].flatten.each { |param|
- #Puppet.debug("yielding param #{param}")
- yield param
- }
- end
+ # Iterate across all of our children.
+ def each
+ [@object, at parameters].flatten.each { |param|
+ #Puppet.debug("yielding param #{param}")
+ yield param
+ }
+ end
- # Does not actually return an object; instead sets an object
- # in the current scope.
- def evaluate(scope)
- # Get our object reference.
- resource = @object.safeevaluate(scope)
+ # Does not actually return an object; instead sets an object
+ # in the current scope.
+ def evaluate(scope)
+ # Get our object reference.
+ resource = @object.safeevaluate(scope)
- hash = {}
+ hash = {}
- # Evaluate all of the specified params.
- params = @parameters.collect { |param|
- param.safeevaluate(scope)
- }
+ # Evaluate all of the specified params.
+ params = @parameters.collect { |param|
+ param.safeevaluate(scope)
+ }
- # Now we just create a normal resource, but we call a very different
- # method on the scope.
- resource = [resource] unless resource.is_a?(Array)
+ # Now we just create a normal resource, but we call a very different
+ # method on the scope.
+ resource = [resource] unless resource.is_a?(Array)
- resource = resource.collect do |r|
+ resource = resource.collect do |r|
- res = Puppet::Parser::Resource.new(
- r.type, r.title,
- :parameters => params,
- :file => file,
- :line => line,
- :source => scope.source,
+ res = Puppet::Parser::Resource.new(
+ r.type, r.title,
+ :parameters => params,
+ :file => file,
+ :line => line,
+ :source => scope.source,
- :scope => scope
- )
+ :scope => scope
+ )
- # Now we tell the scope that it's an override, and it behaves as
- # necessary.
- scope.compiler.add_override(res)
+ # Now we tell the scope that it's an override, and it behaves as
+ # necessary.
+ scope.compiler.add_override(res)
- res
- end
- # decapsulate array in case of only one item
- return(resource.length == 1 ? resource.pop : resource)
- end
+ res
+ end
+ # decapsulate array in case of only one item
+ return(resource.length == 1 ? resource.pop : resource)
+ end
- # Create our ResourceDef. Handles type checking for us.
- def initialize(hash)
- @checked = false
- super
+ # Create our ResourceDef. Handles type checking for us.
+ def initialize(hash)
+ @checked = false
+ super
- #self.typecheck(@type.value)
- end
+ #self.typecheck(@type.value)
end
+ end
end
diff --git a/lib/puppet/parser/ast/resource_reference.rb b/lib/puppet/parser/ast/resource_reference.rb
index 37e82d5..5d83343 100644
--- a/lib/puppet/parser/ast/resource_reference.rb
+++ b/lib/puppet/parser/ast/resource_reference.rb
@@ -2,20 +2,20 @@ require 'puppet/parser/ast'
require 'puppet/parser/ast/branch'
class Puppet::Parser::AST::ResourceReference < Puppet::Parser::AST::Branch
- attr_accessor :title, :type
+ attr_accessor :title, :type
- # Evaluate our object, but just return a simple array of the type
- # and name.
- def evaluate(scope)
- titles = Array(title.safeevaluate(scope)).collect { |t| Puppet::Resource.new(type, t, :namespaces => scope.namespaces) }
- return(titles.length == 1 ? titles.pop : titles)
- end
+ # Evaluate our object, but just return a simple array of the type
+ # and name.
+ def evaluate(scope)
+ titles = Array(title.safeevaluate(scope)).collect { |t| Puppet::Resource.new(type, t, :namespaces => scope.namespaces) }
+ return(titles.length == 1 ? titles.pop : titles)
+ end
- def to_s
- if title.is_a?(Puppet::Parser::AST::ASTArray)
- "#{type.to_s.capitalize}#{title}"
- else
- "#{type.to_s.capitalize}[#{title}]"
- end
+ def to_s
+ if title.is_a?(Puppet::Parser::AST::ASTArray)
+ "#{type.to_s.capitalize}#{title}"
+ else
+ "#{type.to_s.capitalize}[#{title}]"
end
+ end
end
diff --git a/lib/puppet/parser/ast/resourceparam.rb b/lib/puppet/parser/ast/resourceparam.rb
index bf0a225..4073a19 100644
--- a/lib/puppet/parser/ast/resourceparam.rb
+++ b/lib/puppet/parser/ast/resourceparam.rb
@@ -1,29 +1,29 @@
require 'puppet/parser/ast/branch'
class Puppet::Parser::AST
- # The AST object for the parameters inside ResourceDefs and Selectors.
- class ResourceParam < AST::Branch
- attr_accessor :value, :param, :add
+ # The AST object for the parameters inside ResourceDefs and Selectors.
+ class ResourceParam < AST::Branch
+ attr_accessor :value, :param, :add
- def each
- [@param, at value].each { |child| yield child }
- end
+ def each
+ [@param, at value].each { |child| yield child }
+ end
- # Return the parameter and the value.
- def evaluate(scope)
+ # Return the parameter and the value.
+ def evaluate(scope)
- return Puppet::Parser::Resource::Param.new(
+ return Puppet::Parser::Resource::Param.new(
- :name => @param,
- :value => @value.safeevaluate(scope),
+ :name => @param,
+ :value => @value.safeevaluate(scope),
- :source => scope.source, :line => self.line, :file => self.file,
- :add => self.add
- )
- end
+ :source => scope.source, :line => self.line, :file => self.file,
+ :add => self.add
+ )
+ end
- def to_s
- "#{@param} => #{@value.to_s}"
- end
+ def to_s
+ "#{@param} => #{@value.to_s}"
end
+ end
end
diff --git a/lib/puppet/parser/ast/selector.rb b/lib/puppet/parser/ast/selector.rb
index cf6b8ac..d6a4ea4 100644
--- a/lib/puppet/parser/ast/selector.rb
+++ b/lib/puppet/parser/ast/selector.rb
@@ -1,44 +1,44 @@
require 'puppet/parser/ast/branch'
class Puppet::Parser::AST
- # The inline conditional operator. Unlike CaseStatement, which executes
- # code, we just return a value.
- class Selector < AST::Branch
- attr_accessor :param, :values
+ # The inline conditional operator. Unlike CaseStatement, which executes
+ # code, we just return a value.
+ class Selector < AST::Branch
+ attr_accessor :param, :values
- def each
- [@param, at values].each { |child| yield child }
- end
+ def each
+ [@param, at values].each { |child| yield child }
+ end
- # Find the value that corresponds with the test.
- def evaluate(scope)
- level = scope.ephemeral_level
- # Get our parameter.
- paramvalue = @param.safeevaluate(scope)
+ # Find the value that corresponds with the test.
+ def evaluate(scope)
+ level = scope.ephemeral_level
+ # Get our parameter.
+ paramvalue = @param.safeevaluate(scope)
- default = nil
+ default = nil
- @values = [@values] unless @values.instance_of? AST::ASTArray or @values.instance_of? Array
+ @values = [@values] unless @values.instance_of? AST::ASTArray or @values.instance_of? Array
- # Then look for a match in the options.
- @values.each do |obj|
- # short circuit asap if we have a match
- return obj.value.safeevaluate(scope) if obj.param.evaluate_match(paramvalue, scope)
+ # Then look for a match in the options.
+ @values.each do |obj|
+ # short circuit asap if we have a match
+ return obj.value.safeevaluate(scope) if obj.param.evaluate_match(paramvalue, scope)
- # Store the default, in case it's necessary.
- default = obj if obj.param.is_a?(Default)
- end
+ # Store the default, in case it's necessary.
+ default = obj if obj.param.is_a?(Default)
+ end
- # Unless we found something, look for the default.
- return default.value.safeevaluate(scope) if default
+ # Unless we found something, look for the default.
+ return default.value.safeevaluate(scope) if default
- self.fail Puppet::ParseError, "No matching value for selector param '#{paramvalue}'"
- ensure
- scope.unset_ephemeral_var(level)
- end
+ self.fail Puppet::ParseError, "No matching value for selector param '#{paramvalue}'"
+ ensure
+ scope.unset_ephemeral_var(level)
+ end
- def to_s
- param.to_s + " ? { " + values.collect { |v| v.to_s }.join(', ') + " }"
- end
+ def to_s
+ param.to_s + " ? { " + values.collect { |v| v.to_s }.join(', ') + " }"
end
+ end
end
diff --git a/lib/puppet/parser/ast/tag.rb b/lib/puppet/parser/ast/tag.rb
index 2909504..6f906a1 100644
--- a/lib/puppet/parser/ast/tag.rb
+++ b/lib/puppet/parser/ast/tag.rb
@@ -1,24 +1,24 @@
require 'puppet/parser/ast/branch'
class Puppet::Parser::AST
- # The code associated with a class. This is different from components
- # in that each class is a singleton -- only one will exist for a given
- # node.
- class Tag < AST::Branch
- @name = :class
- attr_accessor :type
+ # The code associated with a class. This is different from components
+ # in that each class is a singleton -- only one will exist for a given
+ # node.
+ class Tag < AST::Branch
+ @name = :class
+ attr_accessor :type
- def evaluate(scope)
- types = @type.safeevaluate(scope)
+ def evaluate(scope)
+ types = @type.safeevaluate(scope)
- types = [types] unless types.is_a? Array
+ types = [types] unless types.is_a? Array
- types.each do |type|
- # Now set our class. We don't have to worry about checking
- # whether we've been evaluated because we're not evaluating
- # any code.
- scope.setclass(self.object_id, type)
- end
- end
+ types.each do |type|
+ # Now set our class. We don't have to worry about checking
+ # whether we've been evaluated because we're not evaluating
+ # any code.
+ scope.setclass(self.object_id, type)
+ end
end
+ end
end
diff --git a/lib/puppet/parser/ast/vardef.rb b/lib/puppet/parser/ast/vardef.rb
index f103d49..6de1860 100644
--- a/lib/puppet/parser/ast/vardef.rb
+++ b/lib/puppet/parser/ast/vardef.rb
@@ -1,33 +1,33 @@
require 'puppet/parser/ast/branch'
class Puppet::Parser::AST
- # Define a variable. Stores the value in the current scope.
- class VarDef < AST::Branch
+ # Define a variable. Stores the value in the current scope.
+ class VarDef < AST::Branch
- associates_doc
+ associates_doc
- attr_accessor :name, :value, :append
+ attr_accessor :name, :value, :append
- @settor = true
+ @settor = true
- # Look up our name and value, and store them appropriately. The
- # lexer strips off the syntax stuff like '$'.
- def evaluate(scope)
- value = @value.safeevaluate(scope)
- if name.is_a?(HashOrArrayAccess)
- name.assign(scope, value)
- else
- name = @name.safeevaluate(scope)
+ # Look up our name and value, and store them appropriately. The
+ # lexer strips off the syntax stuff like '$'.
+ def evaluate(scope)
+ value = @value.safeevaluate(scope)
+ if name.is_a?(HashOrArrayAccess)
+ name.assign(scope, value)
+ else
+ name = @name.safeevaluate(scope)
- parsewrap do
- scope.setvar(name,value, :file => @file, :line => @line, :append => @append)
- end
- end
+ parsewrap do
+ scope.setvar(name,value, :file => @file, :line => @line, :append => @append)
end
+ end
+ end
- def each
- [@name, at value].each { |child| yield child }
- end
+ def each
+ [@name, at value].each { |child| yield child }
end
+ end
end
diff --git a/lib/puppet/parser/collector.rb b/lib/puppet/parser/collector.rb
index c03add3..de60cb1 100644
--- a/lib/puppet/parser/collector.rb
+++ b/lib/puppet/parser/collector.rb
@@ -1,223 +1,223 @@
# An object that collects stored objects from the central cache and returns
# them to the current host, yo.
class Puppet::Parser::Collector
- attr_accessor :type, :scope, :vquery, :equery, :form, :resources, :overrides, :collected
-
- # Call the collection method, mark all of the returned objects as non-virtual,
- # optionally applying parameter overrides. The collector can also delete himself
- # from the compiler if there is no more resources to collect (valid only for resource fixed-set collector
- # which get their resources from +collect_resources+ and not from the catalog)
- def evaluate
- # Shortcut if we're not using storeconfigs and they're trying to collect
- # exported resources.
- if form == :exported and Puppet[:storeconfigs] != true
- Puppet.warning "Not collecting exported resources without storeconfigs"
- return false
- end
+ attr_accessor :type, :scope, :vquery, :equery, :form, :resources, :overrides, :collected
+
+ # Call the collection method, mark all of the returned objects as non-virtual,
+ # optionally applying parameter overrides. The collector can also delete himself
+ # from the compiler if there is no more resources to collect (valid only for resource fixed-set collector
+ # which get their resources from +collect_resources+ and not from the catalog)
+ def evaluate
+ # Shortcut if we're not using storeconfigs and they're trying to collect
+ # exported resources.
+ if form == :exported and Puppet[:storeconfigs] != true
+ Puppet.warning "Not collecting exported resources without storeconfigs"
+ return false
+ end
- if self.resources
- unless objects = collect_resources and ! objects.empty?
- return false
- end
- else
- method = "collect_#{@form.to_s}"
- objects = send(method).each do |obj|
- obj.virtual = false
- end
- return false if objects.empty?
- end
+ if self.resources
+ unless objects = collect_resources and ! objects.empty?
+ return false
+ end
+ else
+ method = "collect_#{@form.to_s}"
+ objects = send(method).each do |obj|
+ obj.virtual = false
+ end
+ return false if objects.empty?
+ end
- # we have an override for the collected resources
- if @overrides and !objects.empty?
-
- # force the resource to be always child of any other resource
- overrides[:source].meta_def(:child_of?) do
- true
- end
-
- # tell the compiler we have some override for him unless we already
- # overrided those resources
- objects.each do |res|
- unless @collected.include?(res.ref)
-
- newres = Puppet::Parser::Resource.new(
- res.type, res.title,
- :parameters => overrides[:parameters],
- :file => overrides[:file],
- :line => overrides[:line],
- :source => overrides[:source],
+ # we have an override for the collected resources
+ if @overrides and !objects.empty?
+
+ # force the resource to be always child of any other resource
+ overrides[:source].meta_def(:child_of?) do
+ true
+ end
+
+ # tell the compiler we have some override for him unless we already
+ # overrided those resources
+ objects.each do |res|
+ unless @collected.include?(res.ref)
+
+ newres = Puppet::Parser::Resource.new(
+ res.type, res.title,
+ :parameters => overrides[:parameters],
+ :file => overrides[:file],
+ :line => overrides[:line],
+ :source => overrides[:source],
- :scope => overrides[:scope]
- )
+ :scope => overrides[:scope]
+ )
- scope.compiler.add_override(newres)
- end
- end
+ scope.compiler.add_override(newres)
end
+ end
+ end
- # filter out object that already have been collected by ourself
- objects.reject! { |o| @collected.include?(o.ref) }
+ # filter out object that already have been collected by ourself
+ objects.reject! { |o| @collected.include?(o.ref) }
- return false if objects.empty?
+ return false if objects.empty?
- # keep an eye on the resources we have collected
- objects.inject(@collected) { |c,o| c[o.ref]=o; c }
+ # keep an eye on the resources we have collected
+ objects.inject(@collected) { |c,o| c[o.ref]=o; c }
- # return our newly collected resources
- objects
- end
+ # return our newly collected resources
+ objects
+ end
- def initialize(scope, type, equery, vquery, form)
- @scope = scope
+ def initialize(scope, type, equery, vquery, form)
+ @scope = scope
- # initialisation
- @collected = {}
+ # initialisation
+ @collected = {}
- # Canonize the type
- @type = Puppet::Resource.new(type, "whatever").type
- @equery = equery
- @vquery = vquery
+ # Canonize the type
+ @type = Puppet::Resource.new(type, "whatever").type
+ @equery = equery
+ @vquery = vquery
- raise(ArgumentError, "Invalid query form #{form}") unless [:exported, :virtual].include?(form)
- @form = form
- end
+ raise(ArgumentError, "Invalid query form #{form}") unless [:exported, :virtual].include?(form)
+ @form = form
+ end
- # add a resource override to the soon to be exported/realized resources
- def add_override(hash)
- raise ArgumentError, "Exported resource try to override without parameters" unless hash[:parameters]
+ # add a resource override to the soon to be exported/realized resources
+ def add_override(hash)
+ raise ArgumentError, "Exported resource try to override without parameters" unless hash[:parameters]
- # schedule an override for an upcoming collection
- @overrides = hash
- end
-
- private
-
- # Create our active record query.
- def build_active_record_query
- Puppet::Rails.init unless ActiveRecord::Base.connected?
-
- raise Puppet::DevError, "Cannot collect resources for a nil host" unless @scope.host
- host = Puppet::Rails::Host.find_by_name(@scope.host)
-
- search = "(exported=? AND restype=?)"
- values = [true, @type]
-
- search += " AND (#{@equery})" if @equery
-
- # note:
- # we're not eagerly including any relations here because
- # it can creates so much objects we'll throw out later.
- # We used to eagerly include param_names/values but the way
- # the search filter is built ruined those efforts and we
- # were eagerly loading only the searched parameter and not
- # the other ones.
- query = {}
- case search
- when /puppet_tags/
- query = {:joins => {:resource_tags => :puppet_tag}}
- when /param_name/
- query = {:joins => {:param_values => :param_name}}
- end
+ # schedule an override for an upcoming collection
+ @overrides = hash
+ end
- # We're going to collect objects from rails, but we don't want any
- # objects from this host.
- search = ("host_id != ? AND #{search}") and values.unshift(host.id) if host
+ private
- query[:conditions] = [search, *values]
+ # Create our active record query.
+ def build_active_record_query
+ Puppet::Rails.init unless ActiveRecord::Base.connected?
- query
- end
+ raise Puppet::DevError, "Cannot collect resources for a nil host" unless @scope.host
+ host = Puppet::Rails::Host.find_by_name(@scope.host)
- # Collect exported objects.
- def collect_exported
- # First get everything from the export table. Just reuse our
- # collect_virtual method but tell it to use 'exported? for the test.
- resources = collect_virtual(true).reject { |r| ! r.virtual? }
-
- count = resources.length
-
- query = build_active_record_query
-
- # Now look them up in the rails db. When we support attribute comparison
- # and such, we'll need to vary the conditions, but this works with no
- # attributes, anyway.
- time = Puppet::Util.thinmark do
- Puppet::Rails::Resource.find(:all, query).each do |obj|
- if resource = exported_resource(obj)
- count += 1
- resources << resource
- end
- end
- end
+ search = "(exported=? AND restype=?)"
+ values = [true, @type]
- scope.debug("Collected %s %s resource%s in %.2f seconds" % [count, @type, count == 1 ? "" : "s", time])
+ search += " AND (#{@equery})" if @equery
- resources
+ # note:
+ # we're not eagerly including any relations here because
+ # it can creates so much objects we'll throw out later.
+ # We used to eagerly include param_names/values but the way
+ # the search filter is built ruined those efforts and we
+ # were eagerly loading only the searched parameter and not
+ # the other ones.
+ query = {}
+ case search
+ when /puppet_tags/
+ query = {:joins => {:resource_tags => :puppet_tag}}
+ when /param_name/
+ query = {:joins => {:param_values => :param_name}}
end
- def collect_resources
- @resources = [@resources] unless @resources.is_a?(Array)
- method = "collect_#{form.to_s}_resources"
- send(method)
- end
+ # We're going to collect objects from rails, but we don't want any
+ # objects from this host.
+ search = ("host_id != ? AND #{search}") and values.unshift(host.id) if host
- def collect_exported_resources
- raise Puppet::ParseError, "realize() is not yet implemented for exported resources"
- end
+ query[:conditions] = [search, *values]
- # Collect resources directly; this is the result of using 'realize',
- # which specifies resources, rather than using a normal collection.
- def collect_virtual_resources
- return [] unless defined?(@resources) and ! @resources.empty?
- result = @resources.dup.collect do |ref|
- if res = @scope.findresource(ref.to_s)
- @resources.delete(ref)
- res
- end
- end.reject { |r| r.nil? }.each do |res|
- res.virtual = false
- end
+ query
+ end
- # If there are no more resources to find, delete this from the list
- # of collections.
- @scope.compiler.delete_collection(self) if @resources.empty?
+ # Collect exported objects.
+ def collect_exported
+ # First get everything from the export table. Just reuse our
+ # collect_virtual method but tell it to use 'exported? for the test.
+ resources = collect_virtual(true).reject { |r| ! r.virtual? }
- result
- end
+ count = resources.length
- # Collect just virtual objects, from our local compiler.
- def collect_virtual(exported = false)
- scope.compiler.resources.find_all do |resource|
- resource.type == @type and (exported ? resource.exported? : true) and match?(resource)
+ query = build_active_record_query
+
+ # Now look them up in the rails db. When we support attribute comparison
+ # and such, we'll need to vary the conditions, but this works with no
+ # attributes, anyway.
+ time = Puppet::Util.thinmark do
+ Puppet::Rails::Resource.find(:all, query).each do |obj|
+ if resource = exported_resource(obj)
+ count += 1
+ resources << resource
end
+ end
end
- # Seek a specific exported resource.
- def exported_resource(obj)
- if existing = @scope.findresource(obj.restype, obj.title)
- # Next see if we've already collected this resource
- return nil if existing.rails_id == obj.id
+ scope.debug("Collected %s %s resource%s in %.2f seconds" % [count, @type, count == 1 ? "" : "s", time])
+
+ resources
+ end
+
+ def collect_resources
+ @resources = [@resources] unless @resources.is_a?(Array)
+ method = "collect_#{form.to_s}_resources"
+ send(method)
+ end
+
+ def collect_exported_resources
+ raise Puppet::ParseError, "realize() is not yet implemented for exported resources"
+ end
+
+ # Collect resources directly; this is the result of using 'realize',
+ # which specifies resources, rather than using a normal collection.
+ def collect_virtual_resources
+ return [] unless defined?(@resources) and ! @resources.empty?
+ result = @resources.dup.collect do |ref|
+ if res = @scope.findresource(ref.to_s)
+ @resources.delete(ref)
+ res
+ end
+ end.reject { |r| r.nil? }.each do |res|
+ res.virtual = false
+ end
- # This is the one we've already collected
- raise Puppet::ParseError, "Exported resource #{obj.ref} cannot override local resource"
- end
+ # If there are no more resources to find, delete this from the list
+ # of collections.
+ @scope.compiler.delete_collection(self) if @resources.empty?
- resource = obj.to_resource(self.scope)
+ result
+ end
- resource.exported = false
+ # Collect just virtual objects, from our local compiler.
+ def collect_virtual(exported = false)
+ scope.compiler.resources.find_all do |resource|
+ resource.type == @type and (exported ? resource.exported? : true) and match?(resource)
+ end
+ end
- scope.compiler.add_resource(scope, resource)
+ # Seek a specific exported resource.
+ def exported_resource(obj)
+ if existing = @scope.findresource(obj.restype, obj.title)
+ # Next see if we've already collected this resource
+ return nil if existing.rails_id == obj.id
- resource
+ # This is the one we've already collected
+ raise Puppet::ParseError, "Exported resource #{obj.ref} cannot override local resource"
end
- # Does the resource match our tests? We don't yet support tests,
- # so it's always true at the moment.
- def match?(resource)
- if self.vquery
- return self.vquery.call(resource)
- else
- return true
- end
+ resource = obj.to_resource(self.scope)
+
+ resource.exported = false
+
+ scope.compiler.add_resource(scope, resource)
+
+ resource
+ end
+
+ # Does the resource match our tests? We don't yet support tests,
+ # so it's always true at the moment.
+ def match?(resource)
+ if self.vquery
+ return self.vquery.call(resource)
+ else
+ return true
end
+ end
end
diff --git a/lib/puppet/parser/compiler.rb b/lib/puppet/parser/compiler.rb
index 17b05ba..8598072 100644
--- a/lib/puppet/parser/compiler.rb
+++ b/lib/puppet/parser/compiler.rb
@@ -10,484 +10,484 @@ require 'puppet/resource/type_collection_helper'
# Maintain a graph of scopes, along with a bunch of data
# about the individual catalog we're compiling.
class Puppet::Parser::Compiler
- include Puppet::Util
- include Puppet::Util::Errors
- include Puppet::Resource::TypeCollectionHelper
-
- def self.compile(node)
- new(node).compile.to_resource
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- raise Puppet::Error, "#{detail} on node #{node.name}"
- end
-
- attr_reader :node, :facts, :collections, :catalog, :node_scope, :resources, :relationships
+ include Puppet::Util
+ include Puppet::Util::Errors
+ include Puppet::Resource::TypeCollectionHelper
- # Add a collection to the global list.
- def add_collection(coll)
- @collections << coll
- end
-
- def add_relationship(dep)
- @relationships << dep
- end
+ def self.compile(node)
+ new(node).compile.to_resource
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ raise Puppet::Error, "#{detail} on node #{node.name}"
+ end
- # Store a resource override.
- def add_override(override)
- # If possible, merge the override in immediately.
- if resource = @catalog.resource(override.ref)
- resource.merge(override)
- else
- # Otherwise, store the override for later; these
- # get evaluated in Resource#finish.
- @resource_overrides[override.ref] << override
- end
- end
+ attr_reader :node, :facts, :collections, :catalog, :node_scope, :resources, :relationships
- # Store a resource in our resource table.
- def add_resource(scope, resource)
- @resources << resource
+ # Add a collection to the global list.
+ def add_collection(coll)
+ @collections << coll
+ end
- # Note that this will fail if the resource is not unique.
- @catalog.add_resource(resource)
+ def add_relationship(dep)
+ @relationships << dep
+ end
- set_container_resource(scope, resource)
+ # Store a resource override.
+ def add_override(override)
+ # If possible, merge the override in immediately.
+ if resource = @catalog.resource(override.ref)
+ resource.merge(override)
+ else
+ # Otherwise, store the override for later; these
+ # get evaluated in Resource#finish.
+ @resource_overrides[override.ref] << override
end
+ end
- # Add our container edge. If we're a class, then we get treated specially - we can
- # control the stage that the class is applied in. Otherwise, we just
- # get added to our parent container.
- def set_container_resource(scope, resource)
- return if resource.type.to_s.downcase == "stage"
-
- if resource.type.to_s.downcase != "class"
- raise ArgumentError, "Only classes can set 'stage'; normal resources like #{resource} cannot change run stage" if resource[:stage]
- return @catalog.add_edge(scope.resource, resource)
- end
-
- unless stage = @catalog.resource(:stage, resource[:stage] || :main)
- raise ArgumentError, "Could not find stage #{resource[:stage] || :main} specified by #{resource}"
- end
+ # Store a resource in our resource table.
+ def add_resource(scope, resource)
+ @resources << resource
- @catalog.add_edge(stage, resource)
- end
+ # Note that this will fail if the resource is not unique.
+ @catalog.add_resource(resource)
- private :set_container_resource
+ set_container_resource(scope, resource)
+ end
- # Do we use nodes found in the code, vs. the external node sources?
- def ast_nodes?
- known_resource_types.nodes?
- end
+ # Add our container edge. If we're a class, then we get treated specially - we can
+ # control the stage that the class is applied in. Otherwise, we just
+ # get added to our parent container.
+ def set_container_resource(scope, resource)
+ return if resource.type.to_s.downcase == "stage"
- # Store the fact that we've evaluated a class
- def add_class(name)
- @catalog.add_class(name) unless name == ""
+ if resource.type.to_s.downcase != "class"
+ raise ArgumentError, "Only classes can set 'stage'; normal resources like #{resource} cannot change run stage" if resource[:stage]
+ return @catalog.add_edge(scope.resource, resource)
end
-
- # Return a list of all of the defined classes.
- def classlist
- @catalog.classes
+ unless stage = @catalog.resource(:stage, resource[:stage] || :main)
+ raise ArgumentError, "Could not find stage #{resource[:stage] || :main} specified by #{resource}"
end
- # Compiler our catalog. This mostly revolves around finding and evaluating classes.
- # This is the main entry into our catalog.
- def compile
- # Set the client's parameters into the top scope.
- set_node_parameters
- create_settings_scope
+ @catalog.add_edge(stage, resource)
+ end
- evaluate_main
+ private :set_container_resource
+
+ # Do we use nodes found in the code, vs. the external node sources?
+ def ast_nodes?
+ known_resource_types.nodes?
+ end
- evaluate_ast_node
+ # Store the fact that we've evaluated a class
+ def add_class(name)
+ @catalog.add_class(name) unless name == ""
+ end
- evaluate_node_classes
- evaluate_generators
+ # Return a list of all of the defined classes.
+ def classlist
+ @catalog.classes
+ end
+
+ # Compiler our catalog. This mostly revolves around finding and evaluating classes.
+ # This is the main entry into our catalog.
+ def compile
+ # Set the client's parameters into the top scope.
+ set_node_parameters
+ create_settings_scope
+
+ evaluate_main
+
+ evaluate_ast_node
+
+ evaluate_node_classes
+
+ evaluate_generators
+
+ finish
+
+ fail_on_unevaluated
+
+ @catalog
+ end
+
+ # LAK:FIXME There are no tests for this.
+ def delete_collection(coll)
+ @collections.delete(coll) if @collections.include?(coll)
+ end
- finish
-
- fail_on_unevaluated
-
- @catalog
+ # Return the node's environment.
+ def environment
+ unless defined?(@environment)
+ @environment = (node.environment and node.environment != "") ? node.environment : nil
end
+ Puppet::Node::Environment.current = @environment
+ @environment
+ end
- # LAK:FIXME There are no tests for this.
- def delete_collection(coll)
- @collections.delete(coll) if @collections.include?(coll)
- end
+ # Evaluate all of the classes specified by the node.
+ def evaluate_node_classes
+ evaluate_classes(@node.classes, topscope)
+ end
- # Return the node's environment.
- def environment
- unless defined?(@environment)
- @environment = (node.environment and node.environment != "") ? node.environment : nil
- end
- Puppet::Node::Environment.current = @environment
- @environment
- end
+ # Evaluate each specified class in turn. If there are any classes we can't
+ # find, just tag the catalog and move on. This method really just
+ # creates resource objects that point back to the classes, and then the
+ # resources are themselves evaluated later in the process.
+ def evaluate_classes(classes, scope, lazy_evaluate = true)
+ raise Puppet::DevError, "No source for scope passed to evaluate_classes" unless scope.source
+ found = []
+ classes.each do |name|
+ # If we can find the class, then make a resource that will evaluate it.
+ if klass = scope.find_hostclass(name)
+ found << name and next if scope.class_scope(klass)
- # Evaluate all of the classes specified by the node.
- def evaluate_node_classes
- evaluate_classes(@node.classes, topscope)
- end
-
- # Evaluate each specified class in turn. If there are any classes we can't
- # find, just tag the catalog and move on. This method really just
- # creates resource objects that point back to the classes, and then the
- # resources are themselves evaluated later in the process.
- def evaluate_classes(classes, scope, lazy_evaluate = true)
- raise Puppet::DevError, "No source for scope passed to evaluate_classes" unless scope.source
- found = []
- classes.each do |name|
- # If we can find the class, then make a resource that will evaluate it.
- if klass = scope.find_hostclass(name)
- found << name and next if scope.class_scope(klass)
-
- resource = klass.mk_plain_resource(scope)
-
- # If they've disabled lazy evaluation (which the :include function does),
- # then evaluate our resource immediately.
- resource.evaluate unless lazy_evaluate
- found << name
- else
- Puppet.info "Could not find class #{name} for #{node.name}"
- @catalog.tag(name)
- end
- end
- found
- end
-
- def evaluate_relationships
- @relationships.each { |rel| rel.evaluate(catalog) }
- end
+ resource = klass.mk_plain_resource(scope)
- # Return a resource by either its ref or its type and title.
- def findresource(*args)
- @catalog.resource(*args)
+ # If they've disabled lazy evaluation (which the :include function does),
+ # then evaluate our resource immediately.
+ resource.evaluate unless lazy_evaluate
+ found << name
+ else
+ Puppet.info "Could not find class #{name} for #{node.name}"
+ @catalog.tag(name)
+ end
end
-
- def initialize(node, options = {})
- @node = node
-
- options.each do |param, value|
- begin
- send(param.to_s + "=", value)
- rescue NoMethodError
- raise ArgumentError, "Compiler objects do not accept #{param}"
- end
+ found
+ end
+
+ def evaluate_relationships
+ @relationships.each { |rel| rel.evaluate(catalog) }
+ end
+
+ # Return a resource by either its ref or its type and title.
+ def findresource(*args)
+ @catalog.resource(*args)
+ end
+
+ def initialize(node, options = {})
+ @node = node
+
+ options.each do |param, value|
+ begin
+ send(param.to_s + "=", value)
+ rescue NoMethodError
+ raise ArgumentError, "Compiler objects do not accept #{param}"
+ end
+ end
+
+ initvars
+ end
+
+ # Create a new scope, with either a specified parent scope or
+ # using the top scope.
+ def newscope(parent, options = {})
+ parent ||= topscope
+ options[:compiler] = self
+ scope = Puppet::Parser::Scope.new(options)
+ scope.parent = parent
+ scope
+ end
+
+ # Return any overrides for the given resource.
+ def resource_overrides(resource)
+ @resource_overrides[resource.ref]
+ end
+
+ # The top scope is usually the top-level scope, but if we're using AST nodes,
+ # then it is instead the node's scope.
+ def topscope
+ node_scope || @topscope
+ end
+
+ private
+
+ # If ast nodes are enabled, then see if we can find and evaluate one.
+ def evaluate_ast_node
+ return unless ast_nodes?
+
+ # Now see if we can find the node.
+ astnode = nil
+ @node.names.each do |name|
+ break if astnode = known_resource_types.node(name.to_s.downcase)
+ end
+
+ unless (astnode ||= known_resource_types.node("default"))
+ raise Puppet::ParseError, "Could not find default node or by name with '#{node.names.join(", ")}'"
+ end
+
+ # Create a resource to model this node, and then add it to the list
+ # of resources.
+ resource = astnode.mk_plain_resource(topscope)
+
+ resource.evaluate
+
+ # Now set the node scope appropriately, so that :topscope can
+ # behave differently.
+ @node_scope = topscope.class_scope(astnode)
+ end
+
+ # Evaluate our collections and return true if anything returned an object.
+ # The 'true' is used to continue a loop, so it's important.
+ def evaluate_collections
+ return false if @collections.empty?
+
+ found_something = false
+ exceptwrap do
+ # We have to iterate over a dup of the array because
+ # collections can delete themselves from the list, which
+ # changes its length and causes some collections to get missed.
+ @collections.dup.each do |collection|
+ found_something = true if collection.evaluate
+ end
+ end
+
+ found_something
+ end
+
+ # Make sure all of our resources have been evaluated into native resources.
+ # We return true if any resources have, so that we know to continue the
+ # evaluate_generators loop.
+ def evaluate_definitions
+ exceptwrap do
+ if ary = unevaluated_resources
+ evaluated = false
+ ary.each do |resource|
+ if not resource.virtual?
+ resource.evaluate
+ evaluated = true
+ end
end
-
- initvars
- end
-
- # Create a new scope, with either a specified parent scope or
- # using the top scope.
- def newscope(parent, options = {})
- parent ||= topscope
- options[:compiler] = self
- scope = Puppet::Parser::Scope.new(options)
- scope.parent = parent
- scope
- end
-
- # Return any overrides for the given resource.
- def resource_overrides(resource)
- @resource_overrides[resource.ref]
- end
-
- # The top scope is usually the top-level scope, but if we're using AST nodes,
- # then it is instead the node's scope.
- def topscope
- node_scope || @topscope
- end
-
- private
-
- # If ast nodes are enabled, then see if we can find and evaluate one.
- def evaluate_ast_node
- return unless ast_nodes?
-
- # Now see if we can find the node.
- astnode = nil
- @node.names.each do |name|
- break if astnode = known_resource_types.node(name.to_s.downcase)
- end
-
- unless (astnode ||= known_resource_types.node("default"))
- raise Puppet::ParseError, "Could not find default node or by name with '#{node.names.join(", ")}'"
+ # If we evaluated, let the loop know.
+ return evaluated
+ else
+ return false
+ end
+ end
+ end
+
+ # Iterate over collections and resources until we're sure that the whole
+ # compile is evaluated. This is necessary because both collections
+ # and defined resources can generate new resources, which themselves could
+ # be defined resources.
+ def evaluate_generators
+ count = 0
+ loop do
+ done = true
+
+ # Call collections first, then definitions.
+ done = false if evaluate_collections
+ done = false if evaluate_definitions
+ break if done
+
+ count += 1
+
+ if count > 1000
+ raise Puppet::ParseError, "Somehow looped more than 1000 times while evaluating host catalog"
+ end
+ end
+ end
+
+ # Find and evaluate our main object, if possible.
+ def evaluate_main
+ @main = known_resource_types.find_hostclass([""], "") || known_resource_types.add(Puppet::Resource::Type.new(:hostclass, ""))
+ @topscope.source = @main
+ @main_resource = Puppet::Parser::Resource.new("class", :main, :scope => @topscope, :source => @main)
+ @topscope.resource = @main_resource
+
+ @resources << @main_resource
+ @catalog.add_resource(@main_resource)
+
+ set_container_resource(@topscope, @main_resource)
+
+ @main_resource.evaluate
+ end
+
+ # Make sure the entire catalog is evaluated.
+ def fail_on_unevaluated
+ fail_on_unevaluated_overrides
+ fail_on_unevaluated_resource_collections
+ end
+
+ # If there are any resource overrides remaining, then we could
+ # not find the resource they were supposed to override, so we
+ # want to throw an exception.
+ def fail_on_unevaluated_overrides
+ remaining = []
+ @resource_overrides.each do |name, overrides|
+ remaining += overrides
+ end
+
+ unless remaining.empty?
+ fail Puppet::ParseError,
+ "Could not find resource(s) %s for overriding" % remaining.collect { |o|
+ o.ref
+ }.join(", ")
+ end
+ end
+
+ # Make sure we don't have any remaining collections that specifically
+ # look for resources, because we want to consider those to be
+ # parse errors.
+ def fail_on_unevaluated_resource_collections
+ remaining = []
+ @collections.each do |coll|
+ # We're only interested in the 'resource' collections,
+ # which result from direct calls of 'realize'. Anything
+ # else is allowed not to return resources.
+ # Collect all of them, so we have a useful error.
+ if r = coll.resources
+ if r.is_a?(Array)
+ remaining += r
+ else
+ remaining << r
end
-
- # Create a resource to model this node, and then add it to the list
- # of resources.
- resource = astnode.mk_plain_resource(topscope)
-
- resource.evaluate
-
- # Now set the node scope appropriately, so that :topscope can
- # behave differently.
- @node_scope = topscope.class_scope(astnode)
+ end
end
- # Evaluate our collections and return true if anything returned an object.
- # The 'true' is used to continue a loop, so it's important.
- def evaluate_collections
- return false if @collections.empty?
-
- found_something = false
- exceptwrap do
- # We have to iterate over a dup of the array because
- # collections can delete themselves from the list, which
- # changes its length and causes some collections to get missed.
- @collections.dup.each do |collection|
- found_something = true if collection.evaluate
- end
- end
+ raise Puppet::ParseError, "Failed to realize virtual resources #{remaining.join(', ')}" unless remaining.empty?
+ end
- found_something
- end
+ # Make sure all of our resources and such have done any last work
+ # necessary.
+ def finish
+ evaluate_relationships
- # Make sure all of our resources have been evaluated into native resources.
- # We return true if any resources have, so that we know to continue the
- # evaluate_generators loop.
- def evaluate_definitions
- exceptwrap do
- if ary = unevaluated_resources
- evaluated = false
- ary.each do |resource|
- if not resource.virtual?
- resource.evaluate
- evaluated = true
- end
- end
- # If we evaluated, let the loop know.
- return evaluated
- else
- return false
- end
+ resources.each do |resource|
+ # Add in any resource overrides.
+ if overrides = resource_overrides(resource)
+ overrides.each do |over|
+ resource.merge(over)
end
- end
- # Iterate over collections and resources until we're sure that the whole
- # compile is evaluated. This is necessary because both collections
- # and defined resources can generate new resources, which themselves could
- # be defined resources.
- def evaluate_generators
- count = 0
- loop do
- done = true
-
- # Call collections first, then definitions.
- done = false if evaluate_collections
- done = false if evaluate_definitions
- break if done
-
- count += 1
-
- if count > 1000
- raise Puppet::ParseError, "Somehow looped more than 1000 times while evaluating host catalog"
- end
- end
- end
-
- # Find and evaluate our main object, if possible.
- def evaluate_main
- @main = known_resource_types.find_hostclass([""], "") || known_resource_types.add(Puppet::Resource::Type.new(:hostclass, ""))
- @topscope.source = @main
- @main_resource = Puppet::Parser::Resource.new("class", :main, :scope => @topscope, :source => @main)
- @topscope.resource = @main_resource
-
- @resources << @main_resource
- @catalog.add_resource(@main_resource)
+ # Remove the overrides, so that the configuration knows there
+ # are none left.
+ overrides.clear
+ end
- set_container_resource(@topscope, @main_resource)
-
- @main_resource.evaluate
+ resource.finish if resource.respond_to?(:finish)
end
- # Make sure the entire catalog is evaluated.
- def fail_on_unevaluated
- fail_on_unevaluated_overrides
- fail_on_unevaluated_resource_collections
- end
+ add_resource_metaparams
+ end
- # If there are any resource overrides remaining, then we could
- # not find the resource they were supposed to override, so we
- # want to throw an exception.
- def fail_on_unevaluated_overrides
- remaining = []
- @resource_overrides.each do |name, overrides|
- remaining += overrides
- end
-
- unless remaining.empty?
- fail Puppet::ParseError,
- "Could not find resource(s) %s for overriding" % remaining.collect { |o|
- o.ref
- }.join(", ")
- end
+ def add_resource_metaparams
+ unless main = catalog.resource(:class, :main)
+ raise "Couldn't find main"
end
- # Make sure we don't have any remaining collections that specifically
- # look for resources, because we want to consider those to be
- # parse errors.
- def fail_on_unevaluated_resource_collections
- remaining = []
- @collections.each do |coll|
- # We're only interested in the 'resource' collections,
- # which result from direct calls of 'realize'. Anything
- # else is allowed not to return resources.
- # Collect all of them, so we have a useful error.
- if r = coll.resources
- if r.is_a?(Array)
- remaining += r
- else
- remaining << r
- end
- end
- end
-
- raise Puppet::ParseError, "Failed to realize virtual resources #{remaining.join(', ')}" unless remaining.empty?
+ names = []
+ Puppet::Type.eachmetaparam do |name|
+ next if Puppet::Parser::Resource.relationship_parameter?(name)
+ names << name
end
- # Make sure all of our resources and such have done any last work
- # necessary.
- def finish
- evaluate_relationships
-
- resources.each do |resource|
- # Add in any resource overrides.
- if overrides = resource_overrides(resource)
- overrides.each do |over|
- resource.merge(over)
- end
-
- # Remove the overrides, so that the configuration knows there
- # are none left.
- overrides.clear
- end
-
- resource.finish if resource.respond_to?(:finish)
+ data = {}
+ catalog.walk(main, :out) do |source, target|
+ if source_data = data[source] || metaparams_as_data(source, names)
+ # only store anything in the data hash if we've actually got
+ # data
+ data[source] ||= source_data
+ source_data.each do |param, value|
+ target[param] = value if target[param].nil?
end
+ data[target] = source_data.merge(metaparams_as_data(target, names))
+ end
- add_resource_metaparams
+ target.tag(*(source.tags))
end
+ end
- def add_resource_metaparams
- unless main = catalog.resource(:class, :main)
- raise "Couldn't find main"
- end
-
- names = []
- Puppet::Type.eachmetaparam do |name|
- next if Puppet::Parser::Resource.relationship_parameter?(name)
- names << name
- end
-
- data = {}
- catalog.walk(main, :out) do |source, target|
- if source_data = data[source] || metaparams_as_data(source, names)
- # only store anything in the data hash if we've actually got
- # data
- data[source] ||= source_data
- source_data.each do |param, value|
- target[param] = value if target[param].nil?
- end
- data[target] = source_data.merge(metaparams_as_data(target, names))
- end
-
- target.tag(*(source.tags))
- end
+ def metaparams_as_data(resource, params)
+ data = nil
+ params.each do |param|
+ unless resource[param].nil?
+ # Because we could be creating a hash for every resource,
+ # and we actually probably don't often have any data here at all,
+ # we're optimizing a bit by only creating a hash if there's
+ # any data to put in it.
+ data ||= {}
+ data[param] = resource[param]
+ end
end
+ data
+ end
- def metaparams_as_data(resource, params)
- data = nil
- params.each do |param|
- unless resource[param].nil?
- # Because we could be creating a hash for every resource,
- # and we actually probably don't often have any data here at all,
- # we're optimizing a bit by only creating a hash if there's
- # any data to put in it.
- data ||= {}
- data[param] = resource[param]
- end
- end
- data
- end
+ # Set up all of our internal variables.
+ def initvars
+ # The list of objects that will available for export.
+ @exported_resources = {}
- # Set up all of our internal variables.
- def initvars
- # The list of objects that will available for export.
- @exported_resources = {}
+ # The list of overrides. This is used to cache overrides on objects
+ # that don't exist yet. We store an array of each override.
+ @resource_overrides = Hash.new do |overs, ref|
+ overs[ref] = []
+ end
- # The list of overrides. This is used to cache overrides on objects
- # that don't exist yet. We store an array of each override.
- @resource_overrides = Hash.new do |overs, ref|
- overs[ref] = []
- end
+ # The list of collections that have been created. This is a global list,
+ # but they each refer back to the scope that created them.
+ @collections = []
- # The list of collections that have been created. This is a global list,
- # but they each refer back to the scope that created them.
- @collections = []
+ # The list of relationships to evaluate.
+ @relationships = []
- # The list of relationships to evaluate.
- @relationships = []
+ # For maintaining the relationship between scopes and their resources.
+ @catalog = Puppet::Resource::Catalog.new(@node.name)
+ @catalog.version = known_resource_types.version
- # For maintaining the relationship between scopes and their resources.
- @catalog = Puppet::Resource::Catalog.new(@node.name)
- @catalog.version = known_resource_types.version
+ # Create our initial scope and a resource that will evaluate main.
+ @topscope = Puppet::Parser::Scope.new(:compiler => self)
- # Create our initial scope and a resource that will evaluate main.
- @topscope = Puppet::Parser::Scope.new(:compiler => self)
+ @main_stage_resource = Puppet::Parser::Resource.new("stage", :main, :scope => @topscope)
+ @catalog.add_resource(@main_stage_resource)
- @main_stage_resource = Puppet::Parser::Resource.new("stage", :main, :scope => @topscope)
- @catalog.add_resource(@main_stage_resource)
+ # local resource array to maintain resource ordering
+ @resources = []
- # local resource array to maintain resource ordering
- @resources = []
+ # Make sure any external node classes are in our class list
+ @catalog.add_class(*@node.classes)
+ end
- # Make sure any external node classes are in our class list
- @catalog.add_class(*@node.classes)
+ # Set the node's parameters into the top-scope as variables.
+ def set_node_parameters
+ node.parameters.each do |param, value|
+ @topscope.setvar(param, value)
end
- # Set the node's parameters into the top-scope as variables.
- def set_node_parameters
- node.parameters.each do |param, value|
- @topscope.setvar(param, value)
- end
+ # These might be nil.
+ catalog.client_version = node.parameters["clientversion"]
+ catalog.server_version = node.parameters["serverversion"]
+ end
- # These might be nil.
- catalog.client_version = node.parameters["clientversion"]
- catalog.server_version = node.parameters["serverversion"]
+ def create_settings_scope
+ unless settings_type = environment.known_resource_types.hostclass("settings")
+ settings_type = Puppet::Resource::Type.new :hostclass, "settings"
+ environment.known_resource_types.add(settings_type)
end
- def create_settings_scope
- unless settings_type = environment.known_resource_types.hostclass("settings")
- settings_type = Puppet::Resource::Type.new :hostclass, "settings"
- environment.known_resource_types.add(settings_type)
- end
+ settings_resource = Puppet::Parser::Resource.new("class", "settings", :scope => @topscope)
+ settings_type.evaluate_code(settings_resource)
- settings_resource = Puppet::Parser::Resource.new("class", "settings", :scope => @topscope)
- settings_type.evaluate_code(settings_resource)
+ @catalog.add_resource(settings_resource)
- @catalog.add_resource(settings_resource)
+ scope = @topscope.class_scope(settings_type)
- scope = @topscope.class_scope(settings_type)
-
- Puppet.settings.each do |name, setting|
- next if name.to_s == "name"
- scope.setvar name.to_s, environment[name]
- end
+ Puppet.settings.each do |name, setting|
+ next if name.to_s == "name"
+ scope.setvar name.to_s, environment[name]
end
+ end
- # Return an array of all of the unevaluated resources. These will be definitions,
- # which need to get evaluated into native resources.
- def unevaluated_resources
- ary = resources.reject { |resource| resource.builtin? or resource.evaluated? }
+ # Return an array of all of the unevaluated resources. These will be definitions,
+ # which need to get evaluated into native resources.
+ def unevaluated_resources
+ ary = resources.reject { |resource| resource.builtin? or resource.evaluated? }
- if ary.empty?
- return nil
- else
- return ary
- end
+ if ary.empty?
+ return nil
+ else
+ return ary
end
+ end
end
diff --git a/lib/puppet/parser/files.rb b/lib/puppet/parser/files.rb
index 875a878..7497434 100644
--- a/lib/puppet/parser/files.rb
+++ b/lib/puppet/parser/files.rb
@@ -6,83 +6,83 @@ require 'puppet/parser/parser'
# doesn't really belong in the Puppet::Module class,
# but it doesn't really belong anywhere else, either.
module Puppet::Parser::Files
- module_function
+ module_function
- # Return a list of manifests (as absolute filenames) that match +pat+
- # with the current directory set to +cwd+. If the first component of
- # +pat+ does not contain any wildcards and is an existing module, return
- # a list of manifests in that module matching the rest of +pat+
- # Otherwise, try to find manifests matching +pat+ relative to +cwd+
- def find_manifests(start, options = {})
- cwd = options[:cwd] || Dir.getwd
- module_name, pattern = split_file_path(start)
- begin
- if mod = Puppet::Module.find(module_name, options[:environment])
- return [mod.name, mod.match_manifests(pattern)]
- end
- rescue Puppet::Module::InvalidName
- # Than that would be a "no."
- end
- abspat = File::expand_path(start, cwd)
- [nil, Dir.glob(abspat + (File.extname(abspat).empty? ? '{,.pp,.rb}' : '' )).reject { |f| FileTest.directory?(f) }]
+ # Return a list of manifests (as absolute filenames) that match +pat+
+ # with the current directory set to +cwd+. If the first component of
+ # +pat+ does not contain any wildcards and is an existing module, return
+ # a list of manifests in that module matching the rest of +pat+
+ # Otherwise, try to find manifests matching +pat+ relative to +cwd+
+ def find_manifests(start, options = {})
+ cwd = options[:cwd] || Dir.getwd
+ module_name, pattern = split_file_path(start)
+ begin
+ if mod = Puppet::Module.find(module_name, options[:environment])
+ return [mod.name, mod.match_manifests(pattern)]
+ end
+ rescue Puppet::Module::InvalidName
+ # Than that would be a "no."
end
+ abspat = File::expand_path(start, cwd)
+ [nil, Dir.glob(abspat + (File.extname(abspat).empty? ? '{,.pp,.rb}' : '' )).reject { |f| FileTest.directory?(f) }]
+ end
- # Find the concrete file denoted by +file+. If +file+ is absolute,
- # return it directly. Otherwise try to find it as a template in a
- # module. If that fails, return it relative to the +templatedir+ config
- # param.
- # In all cases, an absolute path is returned, which does not
- # necessarily refer to an existing file
- def find_template(template, environment = nil)
- if template == File.expand_path(template)
- return template
- end
-
- if template_paths = templatepath(environment)
- # If we can find the template in :templatedir, we return that.
- template_paths.collect { |path|
- File::join(path, template)
- }.each do |f|
- return f if FileTest.exist?(f)
- end
- end
+ # Find the concrete file denoted by +file+. If +file+ is absolute,
+ # return it directly. Otherwise try to find it as a template in a
+ # module. If that fails, return it relative to the +templatedir+ config
+ # param.
+ # In all cases, an absolute path is returned, which does not
+ # necessarily refer to an existing file
+ def find_template(template, environment = nil)
+ if template == File.expand_path(template)
+ return template
+ end
- # check in the default template dir, if there is one
- if td_file = find_template_in_module(template, environment)
- return td_file
- end
+ if template_paths = templatepath(environment)
+ # If we can find the template in :templatedir, we return that.
+ template_paths.collect { |path|
+ File::join(path, template)
+ }.each do |f|
+ return f if FileTest.exist?(f)
+ end
+ end
- nil
+ # check in the default template dir, if there is one
+ if td_file = find_template_in_module(template, environment)
+ return td_file
end
- def find_template_in_module(template, environment = nil)
- path, file = split_file_path(template)
+ nil
+ end
- # Because templates don't have an assumed template name, like manifests do,
- # we treat templates with no name as being templates in the main template
- # directory.
- return nil unless file
+ def find_template_in_module(template, environment = nil)
+ path, file = split_file_path(template)
- if mod = Puppet::Module.find(path, environment) and t = mod.template(file)
- return t
- end
- nil
- end
+ # Because templates don't have an assumed template name, like manifests do,
+ # we treat templates with no name as being templates in the main template
+ # directory.
+ return nil unless file
- # Return an array of paths by splitting the +templatedir+ config
- # parameter.
- def templatepath(environment = nil)
- dirs = Puppet.settings.value(:templatedir, environment).split(File::PATH_SEPARATOR)
- dirs.select do |p|
- File::directory?(p)
- end
+ if mod = Puppet::Module.find(path, environment) and t = mod.template(file)
+ return t
end
+ nil
+ end
- # Split the path into the module and the rest of the path, or return
- # nil if the path is empty or absolute (starts with a /).
- # This method can return nil & anyone calling it needs to handle that.
- def split_file_path(path)
- path.split(File::SEPARATOR, 2) unless path == "" or path == File.expand_path(path)
+ # Return an array of paths by splitting the +templatedir+ config
+ # parameter.
+ def templatepath(environment = nil)
+ dirs = Puppet.settings.value(:templatedir, environment).split(File::PATH_SEPARATOR)
+ dirs.select do |p|
+ File::directory?(p)
end
+ end
+
+ # Split the path into the module and the rest of the path, or return
+ # nil if the path is empty or absolute (starts with a /).
+ # This method can return nil & anyone calling it needs to handle that.
+ def split_file_path(path)
+ path.split(File::SEPARATOR, 2) unless path == "" or path == File.expand_path(path)
+ end
end
diff --git a/lib/puppet/parser/functions.rb b/lib/puppet/parser/functions.rb
index 3e56f2a..c238da5 100644
--- a/lib/puppet/parser/functions.rb
+++ b/lib/puppet/parser/functions.rb
@@ -7,116 +7,116 @@ require 'monitor'
# class.
module Puppet::Parser::Functions
- (@functions = Hash.new { |h,k| h[k] = {} }).extend(MonitorMixin)
- (@modules = {} ).extend(MonitorMixin)
+ (@functions = Hash.new { |h,k| h[k] = {} }).extend(MonitorMixin)
+ (@modules = {} ).extend(MonitorMixin)
- class << self
- include Puppet::Util
- end
+ class << self
+ include Puppet::Util
+ end
- def self.autoloader
- unless defined?(@autoloader)
+ def self.autoloader
+ unless defined?(@autoloader)
- @autoloader = Puppet::Util::Autoload.new(
- self,
- "puppet/parser/functions",
+ @autoloader = Puppet::Util::Autoload.new(
+ self,
+ "puppet/parser/functions",
- :wrap => false
- )
- end
-
- @autoloader
+ :wrap => false
+ )
end
- Environment = Puppet::Node::Environment
+ @autoloader
+ end
- def self.environment_module(env = nil)
- @modules.synchronize {
- @modules[ env || Environment.current || Environment.root ] ||= Module.new
- }
- end
+ Environment = Puppet::Node::Environment
- # Create a new function type.
- def self.newfunction(name, options = {}, &block)
- name = symbolize(name)
+ def self.environment_module(env = nil)
+ @modules.synchronize {
+ @modules[ env || Environment.current || Environment.root ] ||= Module.new
+ }
+ end
- raise Puppet::DevError, "Function #{name} already defined" if functions.include?(name)
+ # Create a new function type.
+ def self.newfunction(name, options = {}, &block)
+ name = symbolize(name)
- ftype = options[:type] || :statement
+ raise Puppet::DevError, "Function #{name} already defined" if functions.include?(name)
- unless ftype == :statement or ftype == :rvalue
- raise Puppet::DevError, "Invalid statement type #{ftype.inspect}"
- end
+ ftype = options[:type] || :statement
- fname = "function_#{name}"
- environment_module.send(:define_method, fname, &block)
-
- # Someday we'll support specifying an arity, but for now, nope
- #functions[name] = {:arity => arity, :type => ftype}
- functions[name] = {:type => ftype, :name => fname}
- functions[name][:doc] = options[:doc] if options[:doc]
+ unless ftype == :statement or ftype == :rvalue
+ raise Puppet::DevError, "Invalid statement type #{ftype.inspect}"
end
- # Remove a function added by newfunction
- def self.rmfunction(name)
- name = symbolize(name)
+ fname = "function_#{name}"
+ environment_module.send(:define_method, fname, &block)
- raise Puppet::DevError, "Function #{name} is not defined" unless functions.include? name
+ # Someday we'll support specifying an arity, but for now, nope
+ #functions[name] = {:arity => arity, :type => ftype}
+ functions[name] = {:type => ftype, :name => fname}
+ functions[name][:doc] = options[:doc] if options[:doc]
+ end
- functions.delete name
+ # Remove a function added by newfunction
+ def self.rmfunction(name)
+ name = symbolize(name)
- fname = "function_#{name}"
- environment_module.send(:remove_method, fname)
- end
+ raise Puppet::DevError, "Function #{name} is not defined" unless functions.include? name
- # Determine if a given name is a function
- def self.function(name)
- name = symbolize(name)
+ functions.delete name
- unless functions.include?(name) or functions(Puppet::Node::Environment.root).include?(name)
- autoloader.load(name,Environment.current || Environment.root)
- end
+ fname = "function_#{name}"
+ environment_module.send(:remove_method, fname)
+ end
- ( functions(Environment.root)[name] || functions[name] || {:name => false} )[:name]
+ # Determine if a given name is a function
+ def self.function(name)
+ name = symbolize(name)
+
+ unless functions.include?(name) or functions(Puppet::Node::Environment.root).include?(name)
+ autoloader.load(name,Environment.current || Environment.root)
end
- def self.functiondocs
- autoloader.loadall
+ ( functions(Environment.root)[name] || functions[name] || {:name => false} )[:name]
+ end
- ret = ""
+ def self.functiondocs
+ autoloader.loadall
- functions.sort { |a,b| a[0].to_s <=> b[0].to_s }.each do |name, hash|
- #ret += "#{name}\n#{hash[:type]}\n"
- ret += "#{name}\n#{"-" * name.to_s.length}\n"
- if hash[:doc]
- ret += Puppet::Util::Docs.scrub(hash[:doc])
- else
- ret += "Undocumented.\n"
- end
+ ret = ""
- ret += "\n\n- **Type**: #{hash[:type]}\n\n"
- end
+ functions.sort { |a,b| a[0].to_s <=> b[0].to_s }.each do |name, hash|
+ #ret += "#{name}\n#{hash[:type]}\n"
+ ret += "#{name}\n#{"-" * name.to_s.length}\n"
+ if hash[:doc]
+ ret += Puppet::Util::Docs.scrub(hash[:doc])
+ else
+ ret += "Undocumented.\n"
+ end
- ret
+ ret += "\n\n- **Type**: #{hash[:type]}\n\n"
end
- def self.functions(env = nil)
- @functions.synchronize {
- @functions[ env || Environment.current || Environment.root ]
- }
- end
+ ret
+ end
- # Determine if a given function returns a value or not.
- def self.rvalue?(name)
- (functions[symbolize(name)] || {})[:type] == :rvalue
- end
+ def self.functions(env = nil)
+ @functions.synchronize {
+ @functions[ env || Environment.current || Environment.root ]
+ }
+ end
+
+ # Determine if a given function returns a value or not.
+ def self.rvalue?(name)
+ (functions[symbolize(name)] || {})[:type] == :rvalue
+ end
- # Runs a newfunction to create a function for each of the log levels
+ # Runs a newfunction to create a function for each of the log levels
- Puppet::Util::Log.levels.each do |level|
- newfunction(level, :doc => "Log a message on the server at level #{level.to_s}.") do |vals|
- send(level, vals.join(" "))
- end
+ Puppet::Util::Log.levels.each do |level|
+ newfunction(level, :doc => "Log a message on the server at level #{level.to_s}.") do |vals|
+ send(level, vals.join(" "))
end
+ end
end
diff --git a/lib/puppet/parser/functions/defined.rb b/lib/puppet/parser/functions/defined.rb
index 4d1d8c6..2930a65 100644
--- a/lib/puppet/parser/functions/defined.rb
+++ b/lib/puppet/parser/functions/defined.rb
@@ -1,27 +1,27 @@
# Test whether a given class or definition is defined
Puppet::Parser::Functions::newfunction(:defined, :type => :rvalue, :doc => "Determine whether a given
- type is defined, either as a native type or a defined type, or whether a class is defined.
- This is useful for checking whether a class is defined and only including it if it is.
- This function can also test whether a resource has been defined, using resource references
- (e.g., ``if defined(File['/tmp/myfile']) { ... }``). This function is unfortunately
- dependent on the parse order of the configuration when testing whether a resource is defined.") do |vals|
- result = false
- vals = [vals] unless vals.is_a?(Array)
- vals.each do |val|
- case val
- when String
- if Puppet::Type.type(val) or find_definition(val) or find_hostclass(val)
- result = true
- break
- end
- when Puppet::Resource
- if findresource(val.to_s)
- result = true
- break
- end
- else
- raise ArgumentError, "Invalid argument of type '#{val.class}' to 'defined'"
- end
+ type is defined, either as a native type or a defined type, or whether a class is defined.
+ This is useful for checking whether a class is defined and only including it if it is.
+ This function can also test whether a resource has been defined, using resource references
+ (e.g., ``if defined(File['/tmp/myfile']) { ... }``). This function is unfortunately
+ dependent on the parse order of the configuration when testing whether a resource is defined.") do |vals|
+ result = false
+ vals = [vals] unless vals.is_a?(Array)
+ vals.each do |val|
+ case val
+ when String
+ if Puppet::Type.type(val) or find_definition(val) or find_hostclass(val)
+ result = true
+ break
end
- result
+ when Puppet::Resource
+ if findresource(val.to_s)
+ result = true
+ break
+ end
+ else
+ raise ArgumentError, "Invalid argument of type '#{val.class}' to 'defined'"
+ end
+ end
+ result
end
diff --git a/lib/puppet/parser/functions/fail.rb b/lib/puppet/parser/functions/fail.rb
index 35b20ee..5bef6c7 100644
--- a/lib/puppet/parser/functions/fail.rb
+++ b/lib/puppet/parser/functions/fail.rb
@@ -1,4 +1,4 @@
Puppet::Parser::Functions::newfunction(:fail, :doc => "Fail with a parse error.") do |vals|
- vals = vals.collect { |s| s.to_s }.join(" ") if vals.is_a? Array
- raise Puppet::ParseError, vals.to_s
+ vals = vals.collect { |s| s.to_s }.join(" ") if vals.is_a? Array
+ raise Puppet::ParseError, vals.to_s
end
diff --git a/lib/puppet/parser/functions/file.rb b/lib/puppet/parser/functions/file.rb
index d13b01e..9631112 100644
--- a/lib/puppet/parser/functions/file.rb
+++ b/lib/puppet/parser/functions/file.rb
@@ -1,23 +1,23 @@
# Returns the contents of a file
- Puppet::Parser::Functions::newfunction(
- :file, :type => :rvalue,
+ Puppet::Parser::Functions::newfunction(
+ :file, :type => :rvalue,
- :doc => "Return the contents of a file. Multiple files
- can be passed, and the first file that exists will be read in.") do |vals|
- ret = nil
- vals.each do |file|
- unless file =~ /^#{File::SEPARATOR}/
- raise Puppet::ParseError, "Files must be fully qualified"
- end
- if FileTest.exists?(file)
- ret = File.read(file)
- break
- end
- end
- if ret
- ret
- else
- raise Puppet::ParseError, "Could not find any files from #{vals.join(", ")}"
- end
+ :doc => "Return the contents of a file. Multiple files
+ can be passed, and the first file that exists will be read in.") do |vals|
+ ret = nil
+ vals.each do |file|
+ unless file =~ /^#{File::SEPARATOR}/
+ raise Puppet::ParseError, "Files must be fully qualified"
+ end
+ if FileTest.exists?(file)
+ ret = File.read(file)
+ break
+ end
+ end
+ if ret
+ ret
+ else
+ raise Puppet::ParseError, "Could not find any files from #{vals.join(", ")}"
+ end
end
diff --git a/lib/puppet/parser/functions/fqdn_rand.rb b/lib/puppet/parser/functions/fqdn_rand.rb
index 27af2d7..3e7018a 100644
--- a/lib/puppet/parser/functions/fqdn_rand.rb
+++ b/lib/puppet/parser/functions/fqdn_rand.rb
@@ -1,9 +1,9 @@
Puppet::Parser::Functions::newfunction(:fqdn_rand, :type => :rvalue, :doc =>
- "Generates random numbers based on the node's fqdn. The first argument
- sets the range. Additional (optional) arguments may be used to further
- distinguish the seed.") do |args|
- require 'md5'
- max = args.shift
- srand MD5.new([lookupvar('fqdn'),args].join(':')).to_s.hex
- rand(max).to_s
+ "Generates random numbers based on the node's fqdn. The first argument
+ sets the range. Additional (optional) arguments may be used to further
+ distinguish the seed.") do |args|
+ require 'md5'
+ max = args.shift
+ srand MD5.new([lookupvar('fqdn'),args].join(':')).to_s.hex
+ rand(max).to_s
end
diff --git a/lib/puppet/parser/functions/generate.rb b/lib/puppet/parser/functions/generate.rb
index 8430f03..91f7b22 100644
--- a/lib/puppet/parser/functions/generate.rb
+++ b/lib/puppet/parser/functions/generate.rb
@@ -1,31 +1,31 @@
# Runs an external command and returns the results
Puppet::Parser::Functions::newfunction(:generate, :type => :rvalue,
- :doc => "Calls an external command on the Puppet master and returns
- the results of the command. Any arguments are passed to the external command as
- arguments. If the generator does not exit with return code of 0,
- the generator is considered to have failed and a parse error is
- thrown. Generators can only have file separators, alphanumerics, dashes,
- and periods in them. This function will attempt to protect you from
- malicious generator calls (e.g., those with '..' in them), but it can
- never be entirely safe. No subshell is used to execute
- generators, so all shell metacharacters are passed directly to
- the generator.") do |args|
+ :doc => "Calls an external command on the Puppet master and returns
+ the results of the command. Any arguments are passed to the external command as
+ arguments. If the generator does not exit with return code of 0,
+ the generator is considered to have failed and a parse error is
+ thrown. Generators can only have file separators, alphanumerics, dashes,
+ and periods in them. This function will attempt to protect you from
+ malicious generator calls (e.g., those with '..' in them), but it can
+ never be entirely safe. No subshell is used to execute
+ generators, so all shell metacharacters are passed directly to
+ the generator.") do |args|
- raise Puppet::ParseError, "Generators must be fully qualified" unless args[0] =~ /^#{File::SEPARATOR}/
+ raise Puppet::ParseError, "Generators must be fully qualified" unless args[0] =~ /^#{File::SEPARATOR}/
- unless args[0] =~ /^[-#{File::SEPARATOR}\w.]+$/
- raise Puppet::ParseError,
- "Generators can only contain alphanumerics, file separators, and dashes"
- end
+ unless args[0] =~ /^[-#{File::SEPARATOR}\w.]+$/
+ raise Puppet::ParseError,
+ "Generators can only contain alphanumerics, file separators, and dashes"
+ end
- if args[0] =~ /\.\./
- raise Puppet::ParseError,
- "Can not use generators with '..' in them."
- end
+ if args[0] =~ /\.\./
+ raise Puppet::ParseError,
+ "Can not use generators with '..' in them."
+ end
- begin
- Dir.chdir(File.dirname(args[0])) { Puppet::Util.execute(args) }
- rescue Puppet::ExecutionFailure => detail
- raise Puppet::ParseError, "Failed to execute generator #{args[0]}: #{detail}"
- end
+ begin
+ Dir.chdir(File.dirname(args[0])) { Puppet::Util.execute(args) }
+ rescue Puppet::ExecutionFailure => detail
+ raise Puppet::ParseError, "Failed to execute generator #{args[0]}: #{detail}"
+ end
end
diff --git a/lib/puppet/parser/functions/include.rb b/lib/puppet/parser/functions/include.rb
index d1bafa5..1e12a6a 100644
--- a/lib/puppet/parser/functions/include.rb
+++ b/lib/puppet/parser/functions/include.rb
@@ -1,24 +1,24 @@
# Include the specified classes
Puppet::Parser::Functions::newfunction(:include, :doc => "Evaluate one or more classes.") do |vals|
- vals = [vals] unless vals.is_a?(Array)
+ vals = [vals] unless vals.is_a?(Array)
- # The 'false' disables lazy evaluation.
- klasses = compiler.evaluate_classes(vals, self, false)
+ # The 'false' disables lazy evaluation.
+ klasses = compiler.evaluate_classes(vals, self, false)
- missing = vals.find_all do |klass|
- ! klasses.include?(klass)
- end
+ missing = vals.find_all do |klass|
+ ! klasses.include?(klass)
+ end
- unless missing.empty?
- # Throw an error if we didn't evaluate all of the classes.
- str = "Could not find class"
- str += "es" if missing.length > 1
+ unless missing.empty?
+ # Throw an error if we didn't evaluate all of the classes.
+ str = "Could not find class"
+ str += "es" if missing.length > 1
- str += " " + missing.join(", ")
+ str += " " + missing.join(", ")
- if n = namespaces and ! n.empty? and n != [""]
- str += " in namespaces #{@namespaces.join(", ")}"
- end
- self.fail Puppet::ParseError, str
- end
+ if n = namespaces and ! n.empty? and n != [""]
+ str += " in namespaces #{@namespaces.join(", ")}"
+ end
+ self.fail Puppet::ParseError, str
+ end
end
diff --git a/lib/puppet/parser/functions/inline_template.rb b/lib/puppet/parser/functions/inline_template.rb
index 6c0485d..11d980f 100644
--- a/lib/puppet/parser/functions/inline_template.rb
+++ b/lib/puppet/parser/functions/inline_template.rb
@@ -1,20 +1,20 @@
Puppet::Parser::Functions::newfunction(:inline_template, :type => :rvalue, :doc =>
- "Evaluate a template string and return its value. See `the templating docs
- </trac/puppet/wiki/PuppetTemplating>`_ for more information. Note that
- if multiple template strings are specified, their output is all concatenated
- and returned as the output of the function.") do |vals|
- require 'erb'
+ "Evaluate a template string and return its value. See `the templating docs
+ </trac/puppet/wiki/PuppetTemplating>`_ for more information. Note that
+ if multiple template strings are specified, their output is all concatenated
+ and returned as the output of the function.") do |vals|
+ require 'erb'
- vals.collect do |string|
- # Use a wrapper, so the template can't get access to the full
- # Scope object.
+ vals.collect do |string|
+ # Use a wrapper, so the template can't get access to the full
+ # Scope object.
- wrapper = Puppet::Parser::TemplateWrapper.new(self)
- begin
- wrapper.result(string)
- rescue => detail
- raise Puppet::ParseError,
- "Failed to parse inline template: #{detail}"
- end
- end.join("")
+ wrapper = Puppet::Parser::TemplateWrapper.new(self)
+ begin
+ wrapper.result(string)
+ rescue => detail
+ raise Puppet::ParseError,
+ "Failed to parse inline template: #{detail}"
+ end
+ end.join("")
end
diff --git a/lib/puppet/parser/functions/realize.rb b/lib/puppet/parser/functions/realize.rb
index 6aff19d..4247b8a 100644
--- a/lib/puppet/parser/functions/realize.rb
+++ b/lib/puppet/parser/functions/realize.rb
@@ -2,13 +2,13 @@
# be a good bit faster.
Puppet::Parser::Functions::newfunction(:realize, :doc => "Make a virtual object real. This is useful
- when you want to know the name of the virtual object and don't want to
- bother with a full collection. It is slightly faster than a collection,
- and, of course, is a bit shorter. You must pass the object using a
- reference; e.g.: ``realize User[luke]``." ) do |vals|
- coll = Puppet::Parser::Collector.new(self, :nomatter, nil, nil, :virtual)
- vals = [vals] unless vals.is_a?(Array)
- coll.resources = vals.flatten
+ when you want to know the name of the virtual object and don't want to
+ bother with a full collection. It is slightly faster than a collection,
+ and, of course, is a bit shorter. You must pass the object using a
+ reference; e.g.: ``realize User[luke]``." ) do |vals|
+ coll = Puppet::Parser::Collector.new(self, :nomatter, nil, nil, :virtual)
+ vals = [vals] unless vals.is_a?(Array)
+ coll.resources = vals.flatten
- compiler.add_collection(coll)
+ compiler.add_collection(coll)
end
diff --git a/lib/puppet/parser/functions/regsubst.rb b/lib/puppet/parser/functions/regsubst.rb
index c47c165..c0aeef2 100644
--- a/lib/puppet/parser/functions/regsubst.rb
+++ b/lib/puppet/parser/functions/regsubst.rb
@@ -1,10 +1,10 @@
module Puppet::Parser::Functions
- newfunction(
- :regsubst, :type => :rvalue,
+ newfunction(
+ :regsubst, :type => :rvalue,
- :doc => "
- Perform regexp replacement on a string or array of strings.
+ :doc => "
+ Perform regexp replacement on a string or array of strings.
- **Parameters** (in order):
@@ -16,85 +16,85 @@ module Puppet::Parser::Functions
:flags: Optional. String of single letter flags for how the regexp is interpreted:
- - **E** Extended regexps
- - **I** Ignore case in regexps
- - **M** Multiline regexps
- - **G** Global replacement; all occurrences of the regexp in each target string will be replaced. Without this, only the first occurrence will be replaced.
+ - **E** Extended regexps
+ - **I** Ignore case in regexps
+ - **M** Multiline regexps
+ - **G** Global replacement; all occurrences of the regexp in each target string will be replaced. Without this, only the first occurrence will be replaced.
:lang: Optional. How to handle multibyte characters. A single-character string with the following values:
- - **N** None
- - **E** EUC
- - **S** SJIS
- - **U** UTF-8
+ - **N** None
+ - **E** EUC
+ - **S** SJIS
+ - **U** UTF-8
- **Examples**
Get the third octet from the node's IP address::
- $i3 = regsubst($ipaddress,'^([0-9]+)[.]([0-9]+)[.]([0-9]+)[.]([0-9]+)$','\\3')
+ $i3 = regsubst($ipaddress,'^([0-9]+)[.]([0-9]+)[.]([0-9]+)[.]([0-9]+)$','\\3')
Put angle brackets around each octet in the node's IP address::
- $x = regsubst($ipaddress, '([0-9]+)', '<\\1>', 'G')
+ $x = regsubst($ipaddress, '([0-9]+)', '<\\1>', 'G')
") \
- do |args|
- unless args.length.between?(3, 5)
-
- raise(
- Puppet::ParseError,
-
- "regsubst(): got #{args.length} arguments, expected 3 to 5")
- end
- target, regexp, replacement, flags, lang = args
- reflags = 0
- operation = :sub
- if flags == nil
- flags = []
- elsif flags.respond_to?(:split)
- flags = flags.split('')
- else
-
- raise(
- Puppet::ParseError,
-
- "regsubst(): bad flags parameter #{flags.class}:`#{flags}'")
- end
- flags.each do |f|
- case f
- when 'G' then operation = :gsub
- when 'E' then reflags |= Regexp::EXTENDED
- when 'I' then reflags |= Regexp::IGNORECASE
- when 'M' then reflags |= Regexp::MULTILINE
- else raise(Puppet::ParseError, "regsubst(): bad flag `#{f}'")
- end
- end
- begin
- re = Regexp.compile(regexp, reflags, lang)
- rescue RegexpError, TypeError
-
- raise(
- Puppet::ParseError,
-
- "regsubst(): Bad regular expression `#{regexp}'")
- end
- if target.respond_to?(operation)
- # String parameter -> string result
- result = target.send(operation, re, replacement)
- elsif target.respond_to?(:collect) and
- target.respond_to?(:all?) and
- target.all? { |e| e.respond_to?(operation) }
- # Array parameter -> array result
- result = target.collect { |e|
- e.send(operation, re, replacement)
- }
- else
-
- raise(
- Puppet::ParseError,
-
- "regsubst(): bad target #{target.class}:`#{target}'")
- end
- return result
+ do |args|
+ unless args.length.between?(3, 5)
+
+ raise(
+ Puppet::ParseError,
+
+ "regsubst(): got #{args.length} arguments, expected 3 to 5")
+ end
+ target, regexp, replacement, flags, lang = args
+ reflags = 0
+ operation = :sub
+ if flags == nil
+ flags = []
+ elsif flags.respond_to?(:split)
+ flags = flags.split('')
+ else
+
+ raise(
+ Puppet::ParseError,
+
+ "regsubst(): bad flags parameter #{flags.class}:`#{flags}'")
+ end
+ flags.each do |f|
+ case f
+ when 'G' then operation = :gsub
+ when 'E' then reflags |= Regexp::EXTENDED
+ when 'I' then reflags |= Regexp::IGNORECASE
+ when 'M' then reflags |= Regexp::MULTILINE
+ else raise(Puppet::ParseError, "regsubst(): bad flag `#{f}'")
+ end
+ end
+ begin
+ re = Regexp.compile(regexp, reflags, lang)
+ rescue RegexpError, TypeError
+
+ raise(
+ Puppet::ParseError,
+
+ "regsubst(): Bad regular expression `#{regexp}'")
+ end
+ if target.respond_to?(operation)
+ # String parameter -> string result
+ result = target.send(operation, re, replacement)
+ elsif target.respond_to?(:collect) and
+ target.respond_to?(:all?) and
+ target.all? { |e| e.respond_to?(operation) }
+ # Array parameter -> array result
+ result = target.collect { |e|
+ e.send(operation, re, replacement)
+ }
+ else
+
+ raise(
+ Puppet::ParseError,
+
+ "regsubst(): bad target #{target.class}:`#{target}'")
end
+ return result
+ end
end
diff --git a/lib/puppet/parser/functions/require.rb b/lib/puppet/parser/functions/require.rb
index c5c4c85..3f98c95 100644
--- a/lib/puppet/parser/functions/require.rb
+++ b/lib/puppet/parser/functions/require.rb
@@ -1,9 +1,9 @@
# Requires the specified classes
- Puppet::Parser::Functions::newfunction(
- :require,
+ Puppet::Parser::Functions::newfunction(
+ :require,
- :doc =>"Evaluate one or more classes, adding the required class as a dependency.
+ :doc =>"Evaluate one or more classes, adding the required class as a dependency.
The relationship metaparameters work well for specifying relationships
between individual resources, but they can be clumsy for specifying
@@ -12,47 +12,47 @@ relationships between classes. This function is a superset of the
class depends on the required class.
Warning: using require in place of include can lead to unwanted dependency cycles.
- For instance the following manifest, with 'require' instead of 'include'
- would produce a nasty dependence cycle, because notify imposes a before
- between File[/foo] and Service[foo]::
+ For instance the following manifest, with 'require' instead of 'include'
+ would produce a nasty dependence cycle, because notify imposes a before
+ between File[/foo] and Service[foo]::
- class myservice {
- service { foo: ensure => running }
- }
+ class myservice {
+ service { foo: ensure => running }
+ }
- class otherstuff {
- include myservice
- file { '/foo': notify => Service[foo] }
- }
+ class otherstuff {
+ include myservice
+ file { '/foo': notify => Service[foo] }
+ }
Note that this function only works with clients 0.25 and later, and it will
fail if used with earlier clients.
") do |vals|
- # Verify that the 'include' function is loaded
- method = Puppet::Parser::Functions.function(:include)
-
- send(method, vals)
- if resource.metaparam_compatibility_mode?
- warning "The 'require' function is only compatible with clients at 0.25 and above; including class but not adding dependency"
- else
- vals = [vals] unless vals.is_a?(Array)
-
- vals.each do |klass|
- # lookup the class in the scopes
- if classobj = find_hostclass(klass)
- klass = classobj.name
- else
- raise Puppet::ParseError, "Could not find class #{klass}"
- end
-
- # This is a bit hackish, in some ways, but it's the only way
- # to configure a dependency that will make it to the client.
- # The 'obvious' way is just to add an edge in the catalog,
- # but that is considered a containment edge, not a dependency
- # edge, so it usually gets lost on the client.
- ref = Puppet::Resource.new(:class, klass)
- resource.set_parameter(:require, [resource[:require]].flatten.compact << ref)
- end
+ # Verify that the 'include' function is loaded
+ method = Puppet::Parser::Functions.function(:include)
+
+ send(method, vals)
+ if resource.metaparam_compatibility_mode?
+ warning "The 'require' function is only compatible with clients at 0.25 and above; including class but not adding dependency"
+ else
+ vals = [vals] unless vals.is_a?(Array)
+
+ vals.each do |klass|
+ # lookup the class in the scopes
+ if classobj = find_hostclass(klass)
+ klass = classobj.name
+ else
+ raise Puppet::ParseError, "Could not find class #{klass}"
+ end
+
+ # This is a bit hackish, in some ways, but it's the only way
+ # to configure a dependency that will make it to the client.
+ # The 'obvious' way is just to add an edge in the catalog,
+ # but that is considered a containment edge, not a dependency
+ # edge, so it usually gets lost on the client.
+ ref = Puppet::Resource.new(:class, klass)
+ resource.set_parameter(:require, [resource[:require]].flatten.compact << ref)
end
+ end
end
diff --git a/lib/puppet/parser/functions/search.rb b/lib/puppet/parser/functions/search.rb
index 87dd02d..8a9c7c8 100644
--- a/lib/puppet/parser/functions/search.rb
+++ b/lib/puppet/parser/functions/search.rb
@@ -1,7 +1,7 @@
Puppet::Parser::Functions::newfunction(:search, :doc => "Add another namespace for this class to search.
- This allows you to create classes with sets of definitions and add
- those classes to another class's search path.") do |vals|
- vals.each do |val|
- add_namespace(val)
- end
+ This allows you to create classes with sets of definitions and add
+ those classes to another class's search path.") do |vals|
+ vals.each do |val|
+ add_namespace(val)
+ end
end
diff --git a/lib/puppet/parser/functions/sha1.rb b/lib/puppet/parser/functions/sha1.rb
index 432825e..10cc55c 100644
--- a/lib/puppet/parser/functions/sha1.rb
+++ b/lib/puppet/parser/functions/sha1.rb
@@ -1,5 +1,5 @@
Puppet::Parser::Functions::newfunction(:sha1, :type => :rvalue, :doc => "Returns a SHA1 hash value from a provided string.") do |args|
- require 'sha1'
+ require 'sha1'
- Digest::SHA1.hexdigest(args[0])
+ Digest::SHA1.hexdigest(args[0])
end
diff --git a/lib/puppet/parser/functions/shellquote.rb b/lib/puppet/parser/functions/shellquote.rb
index 888b976..3ddb988 100644
--- a/lib/puppet/parser/functions/shellquote.rb
+++ b/lib/puppet/parser/functions/shellquote.rb
@@ -1,39 +1,39 @@
module Puppet::Parser::Functions
- Safe = 'a-zA-Z0-9@%_+=:,./-' # Safe unquoted
- Dangerous = '!"`$\\' # Unsafe inside double quotes
+ Safe = 'a-zA-Z0-9@%_+=:,./-' # Safe unquoted
+ Dangerous = '!"`$\\' # Unsafe inside double quotes
- newfunction(:shellquote, :type => :rvalue, :doc => "\
- Quote and concatenate arguments for use in Bourne shell.
+ newfunction(:shellquote, :type => :rvalue, :doc => "\
+ Quote and concatenate arguments for use in Bourne shell.
- Each argument is quoted separately, and then all are concatenated
- with spaces. If an argument is an array, the elements of that
- array is interpolated within the rest of the arguments; this makes
- it possible to have an array of arguments and pass that array to
- shellquote instead of having to specify each argument
- individually in the call.
- ") \
- do |args|
+ Each argument is quoted separately, and then all are concatenated
+ with spaces. If an argument is an array, the elements of that
+ array is interpolated within the rest of the arguments; this makes
+ it possible to have an array of arguments and pass that array to
+ shellquote instead of having to specify each argument
+ individually in the call.
+ ") \
+ do |args|
- result = []
- args.flatten.each do |word|
- if word.length != 0 and word.count(Safe) == word.length
- result << word
- elsif word.count(Dangerous) == 0
- result << ('"' + word + '"')
- elsif word.count("'") == 0
- result << ("'" + word + "'")
- else
- r = '"'
- word.each_byte do |c|
- r += "\\" if Dangerous.include?(c)
- r += c.chr
- end
- r += '"'
- result << r
- end
+ result = []
+ args.flatten.each do |word|
+ if word.length != 0 and word.count(Safe) == word.length
+ result << word
+ elsif word.count(Dangerous) == 0
+ result << ('"' + word + '"')
+ elsif word.count("'") == 0
+ result << ("'" + word + "'")
+ else
+ r = '"'
+ word.each_byte do |c|
+ r += "\\" if Dangerous.include?(c)
+ r += c.chr
end
-
- return result.join(" ")
+ r += '"'
+ result << r
+ end
end
+
+ return result.join(" ")
+ end
end
diff --git a/lib/puppet/parser/functions/split.rb b/lib/puppet/parser/functions/split.rb
index 09caa18..5d0a9da 100644
--- a/lib/puppet/parser/functions/split.rb
+++ b/lib/puppet/parser/functions/split.rb
@@ -1,17 +1,17 @@
module Puppet::Parser::Functions
- newfunction(
- :split, :type => :rvalue,
+ newfunction(
+ :split, :type => :rvalue,
- :doc => "\
+ :doc => "\
Split a string variable into an array using the specified split regexp.
- Usage::
+ Usage::
- $string = 'v1.v2:v3.v4'
- $array_var1 = split($string, ':')
- $array_var2 = split($string, '[.]')
- $array_var3 = split($string, '[.:]')
+ $string = 'v1.v2:v3.v4'
+ $array_var1 = split($string, ':')
+ $array_var2 = split($string, '[.]')
+ $array_var3 = split($string, '[.:]')
$array_var1 now holds the result ['v1.v2', 'v3.v4'],
while $array_var2 holds ['v1', 'v2:v3', 'v4'], and
@@ -22,8 +22,8 @@ a regexp meta-character (.), and that needs protection. A simple
way to do that for a single character is to enclose it in square
brackets.") do |args|
- raise Puppet::ParseError, ("split(): wrong number of arguments (#{args.length}; must be 2)") if args.length != 2
+ raise Puppet::ParseError, ("split(): wrong number of arguments (#{args.length}; must be 2)") if args.length != 2
- return args[0].split(Regexp.compile(args[1]))
- end
+ return args[0].split(Regexp.compile(args[1]))
+ end
end
diff --git a/lib/puppet/parser/functions/sprintf.rb b/lib/puppet/parser/functions/sprintf.rb
index af0a721..5ada0fe 100644
--- a/lib/puppet/parser/functions/sprintf.rb
+++ b/lib/puppet/parser/functions/sprintf.rb
@@ -1,13 +1,13 @@
module Puppet::Parser::Functions
- newfunction(
- :sprintf, :type => :rvalue,
+ newfunction(
+ :sprintf, :type => :rvalue,
- :doc => "Perform printf-style formatting of text.
+ :doc => "Perform printf-style formatting of text.
- The first parameter is format string describing how the rest of the parameters should be formatted. See the documentation for the ``Kernel::sprintf`` function in Ruby for all the details.") do |args|
- raise Puppet::ParseError, 'sprintf() needs at least one argument' if args.length < 1
- fmt = args.shift
- return sprintf(fmt, *args)
- end
+ The first parameter is format string describing how the rest of the parameters should be formatted. See the documentation for the ``Kernel::sprintf`` function in Ruby for all the details.") do |args|
+ raise Puppet::ParseError, 'sprintf() needs at least one argument' if args.length < 1
+ fmt = args.shift
+ return sprintf(fmt, *args)
+ end
end
diff --git a/lib/puppet/parser/functions/tag.rb b/lib/puppet/parser/functions/tag.rb
index 3e487fe..84df175 100644
--- a/lib/puppet/parser/functions/tag.rb
+++ b/lib/puppet/parser/functions/tag.rb
@@ -1,6 +1,6 @@
# Tag the current scope with each passed name
Puppet::Parser::Functions::newfunction(:tag, :doc => "Add the specified tags to the containing class
- or definition. All contained objects will then acquire that tag, also.
- ") do |vals|
- self.resource.tag(*vals)
+ or definition. All contained objects will then acquire that tag, also.
+ ") do |vals|
+ self.resource.tag(*vals)
end
diff --git a/lib/puppet/parser/functions/tagged.rb b/lib/puppet/parser/functions/tagged.rb
index fccb132..aaa2adf 100644
--- a/lib/puppet/parser/functions/tagged.rb
+++ b/lib/puppet/parser/functions/tagged.rb
@@ -1,18 +1,18 @@
# Test whether a given tag is set. This functions as a big OR -- if any of the specified tags are unset, we return false.
Puppet::Parser::Functions::newfunction(:tagged, :type => :rvalue, :doc => "A boolean function that
- tells you whether the current container is tagged with the specified tags.
- The tags are ANDed, so that all of the specified tags must be included for
- the function to return true.") do |vals|
- configtags = compiler.catalog.tags
- resourcetags = resource.tags
+ tells you whether the current container is tagged with the specified tags.
+ The tags are ANDed, so that all of the specified tags must be included for
+ the function to return true.") do |vals|
+ configtags = compiler.catalog.tags
+ resourcetags = resource.tags
- retval = true
- vals.each do |val|
- unless configtags.include?(val) or resourcetags.include?(val)
- retval = false
- break
- end
- end
+ retval = true
+ vals.each do |val|
+ unless configtags.include?(val) or resourcetags.include?(val)
+ retval = false
+ break
+ end
+ end
- return retval
+ return retval
end
diff --git a/lib/puppet/parser/functions/template.rb b/lib/puppet/parser/functions/template.rb
index 6c4873e..f51bcc1 100644
--- a/lib/puppet/parser/functions/template.rb
+++ b/lib/puppet/parser/functions/template.rb
@@ -1,22 +1,22 @@
Puppet::Parser::Functions::newfunction(:template, :type => :rvalue, :doc =>
- "Evaluate a template and return its value. See `the templating docs
- <http://docs.puppetlabs.com/guides/templating.html>`_ for more information.
- Note that if multiple templates are specified, their output is all
- concatenated and returned as the output of the function.") do |vals|
- require 'erb'
+ "Evaluate a template and return its value. See `the templating docs
+ <http://docs.puppetlabs.com/guides/templating.html>`_ for more information.
+ Note that if multiple templates are specified, their output is all
+ concatenated and returned as the output of the function.") do |vals|
+ require 'erb'
- vals.collect do |file|
- # Use a wrapper, so the template can't get access to the full
- # Scope object.
- debug "Retrieving template #{file}"
+ vals.collect do |file|
+ # Use a wrapper, so the template can't get access to the full
+ # Scope object.
+ debug "Retrieving template #{file}"
- wrapper = Puppet::Parser::TemplateWrapper.new(self)
- wrapper.file = file
- begin
- wrapper.result
- rescue => detail
- raise Puppet::ParseError,
- "Failed to parse template #{file}: #{detail}"
- end
- end.join("")
+ wrapper = Puppet::Parser::TemplateWrapper.new(self)
+ wrapper.file = file
+ begin
+ wrapper.result
+ rescue => detail
+ raise Puppet::ParseError,
+ "Failed to parse template #{file}: #{detail}"
+ end
+ end.join("")
end
diff --git a/lib/puppet/parser/functions/versioncmp.rb b/lib/puppet/parser/functions/versioncmp.rb
index b8d39af..b384065 100644
--- a/lib/puppet/parser/functions/versioncmp.rb
+++ b/lib/puppet/parser/functions/versioncmp.rb
@@ -1,34 +1,34 @@
require 'puppet/util/package'
- Puppet::Parser::Functions::newfunction(
- :versioncmp, :type => :rvalue,
+ Puppet::Parser::Functions::newfunction(
+ :versioncmp, :type => :rvalue,
- :doc => "Compares two versions
+ :doc => "Compares two versions
Prototype::
- \$result = versioncmp(a, b)
+ \$result = versioncmp(a, b)
- where a and b are arbitrary version strings
+ where a and b are arbitrary version strings
This functions returns a number::
- * > 0 if version a is greater than version b
- * == 0 if both version are equals
- * < 0 if version a is less than version b
+ * > 0 if version a is greater than version b
+ * == 0 if both version are equals
+ * < 0 if version a is less than version b
Example::
- if versioncmp('2.6-1', '2.4.5') > 0 {
- notice('2.6-1 is > than 2.4.5')
- }
+ if versioncmp('2.6-1', '2.4.5') > 0 {
+ notice('2.6-1 is > than 2.4.5')
+ }
") do |args|
- unless args.length == 2
- raise Puppet::ParseError, "versioncmp should have 2 arguments"
- end
+ unless args.length == 2
+ raise Puppet::ParseError, "versioncmp should have 2 arguments"
+ end
- return Puppet::Util::Package.versioncmp(args[0], args[1])
+ return Puppet::Util::Package.versioncmp(args[0], args[1])
end
diff --git a/lib/puppet/parser/grammar.ra b/lib/puppet/parser/grammar.ra
index 9fa8f50..7a316d4 100644
--- a/lib/puppet/parser/grammar.ra
+++ b/lib/puppet/parser/grammar.ra
@@ -15,73 +15,73 @@ token MATCH NOMATCH REGEX IN_EDGE OUT_EDGE IN_EDGE_SUB OUT_EDGE_SUB
token IN
prechigh
- right NOT
- nonassoc UMINUS
- left IN MATCH NOMATCH
- left TIMES DIV
- left MINUS PLUS
- left LSHIFT RSHIFT
- left NOTEQUAL ISEQUAL
- left GREATEREQUAL GREATERTHAN LESSTHAN LESSEQUAL
- left AND
- left OR
+ right NOT
+ nonassoc UMINUS
+ left IN MATCH NOMATCH
+ left TIMES DIV
+ left MINUS PLUS
+ left LSHIFT RSHIFT
+ left NOTEQUAL ISEQUAL
+ left GREATEREQUAL GREATERTHAN LESSTHAN LESSEQUAL
+ left AND
+ left OR
preclow
rule
program: statements {
- if val[0]
- # Make sure we always return an array.
- if val[0].is_a?(AST::ASTArray)
- if val[0].children.empty?
- result = nil
- else
- result = val[0]
- end
- else
- result = aryfy(val[0])
- end
- else
+ if val[0]
+ # Make sure we always return an array.
+ if val[0].is_a?(AST::ASTArray)
+ if val[0].children.empty?
result = nil
+ else
+ result = val[0]
+ end
+ else
+ result = aryfy(val[0])
end
+ else
+ result = nil
+ end
}
- | nil
+ | nil
statements: statement
- | statements statement {
- if val[0] and val[1]
- if val[0].instance_of?(AST::ASTArray)
- val[0].push(val[1])
- result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0],val[1]]
- end
- elsif obj = (val[0] || val[1])
- result = obj
- else result = nil
+ | statements statement {
+ if val[0] and val[1]
+ if val[0].instance_of?(AST::ASTArray)
+ val[0].push(val[1])
+ result = val[0]
+ else
+ result = ast AST::ASTArray, :children => [val[0],val[1]]
end
+ elsif obj = (val[0] || val[1])
+ result = obj
+ else result = nil
+ end
}
# The main list of valid statements
statement: resource
- | virtualresource
- | collection
- | assignment
- | casestatement
- | ifstatement_begin
- | import
- | fstatement
- | definition
- | hostclass
- | nodedef
- | resourceoverride
- | append
- | relationship
+ | virtualresource
+ | collection
+ | assignment
+ | casestatement
+ | ifstatement_begin
+ | import
+ | fstatement
+ | definition
+ | hostclass
+ | nodedef
+ | resourceoverride
+ | append
+ | relationship
relationship: relationship_side edge relationship_side {
- result = AST::Relationship.new(val[0], val[2], val[1][:value], ast_context)
+ result = AST::Relationship.new(val[0], val[2], val[1][:value], ast_context)
}
- | relationship edge relationship_side {
- result = AST::Relationship.new(val[0], val[2], val[1][:value], ast_context)
+ | relationship edge relationship_side {
+ result = AST::Relationship.new(val[0], val[2], val[1][:value], ast_context)
}
relationship_side: resource | resourceref | collection
@@ -89,411 +89,411 @@ relationship_side: resource | resourceref | collection
edge: IN_EDGE | OUT_EDGE | IN_EDGE_SUB | OUT_EDGE_SUB
fstatement: NAME LPAREN funcvalues RPAREN {
- args = aryfy(val[2])
- result = ast AST::Function,
- :name => val[0][:value],
- :line => val[0][:line],
- :arguments => args,
- :ftype => :statement
+ args = aryfy(val[2])
+ result = ast AST::Function,
+ :name => val[0][:value],
+ :line => val[0][:line],
+ :arguments => args,
+ :ftype => :statement
}
| NAME LPAREN funcvalues COMMA RPAREN {
- args = aryfy(val[2])
- result = ast AST::Function,
- :name => val[0][:value],
- :line => val[0][:line],
- :arguments => args,
- :ftype => :statement
+ args = aryfy(val[2])
+ result = ast AST::Function,
+ :name => val[0][:value],
+ :line => val[0][:line],
+ :arguments => args,
+ :ftype => :statement
} | NAME LPAREN RPAREN {
+ result = ast AST::Function,
+ :name => val[0][:value],
+ :line => val[0][:line],
+ :arguments => AST::ASTArray.new({}),
+ :ftype => :statement
+}
+ | NAME funcvalues {
+ args = aryfy(val[1])
result = ast AST::Function,
- :name => val[0][:value],
- :line => val[0][:line],
- :arguments => AST::ASTArray.new({}),
- :ftype => :statement
-}
- | NAME funcvalues {
- args = aryfy(val[1])
- result = ast AST::Function,
- :name => val[0][:value],
- :line => val[0][:line],
- :arguments => args,
- :ftype => :statement
+ :name => val[0][:value],
+ :line => val[0][:line],
+ :arguments => args,
+ :ftype => :statement
}
funcvalues: namestring
- | resourceref
- | funcvalues COMMA namestring {
- result = aryfy(val[0], val[2])
- result.line = @lexer.line
- result.file = @lexer.file
-}
- | funcvalues COMMA resourceref {
- unless val[0].is_a?(AST::ASTArray)
- val[0] = aryfy(val[0])
- end
+ | resourceref
+ | funcvalues COMMA namestring {
+ result = aryfy(val[0], val[2])
+ result.line = @lexer.line
+ result.file = @lexer.file
+}
+ | funcvalues COMMA resourceref {
+ unless val[0].is_a?(AST::ASTArray)
+ val[0] = aryfy(val[0])
+ end
- val[0].push(val[2])
+ val[0].push(val[2])
- result = val[0]
+ result = val[0]
}
# This is *almost* an rvalue, but I couldn't get a full
# rvalue to work without scads of shift/reduce conflicts.
namestring: name
- | variable
- | type
- | boolean
- | funcrvalue
- | selector
- | quotedtext
- | hasharrayaccesses
- | CLASSNAME {
- result = ast AST::Name, :value => val[0][:value]
- }
+ | variable
+ | type
+ | boolean
+ | funcrvalue
+ | selector
+ | quotedtext
+ | hasharrayaccesses
+ | CLASSNAME {
+ result = ast AST::Name, :value => val[0][:value]
+ }
resource: classname LBRACE resourceinstances endsemi RBRACE {
- @lexer.commentpop
- array = val[2]
- array = [array] if array.instance_of?(AST::ResourceInstance)
- result = ast AST::ASTArray
-
- # this iterates across each specified resourceinstance
- array.each { |instance|
- raise Puppet::Dev, "Got something that isn't an instance" unless instance.instance_of?(AST::ResourceInstance)
- # now, i need to somehow differentiate between those things with
- # arrays in their names, and normal things
-
- result.push ast(
- AST::Resource,
- :type => val[0],
- :title => instance[0],
-
- :parameters => instance[1])
- }
+ @lexer.commentpop
+ array = val[2]
+ array = [array] if array.instance_of?(AST::ResourceInstance)
+ result = ast AST::ASTArray
+
+ # this iterates across each specified resourceinstance
+ array.each { |instance|
+ raise Puppet::Dev, "Got something that isn't an instance" unless instance.instance_of?(AST::ResourceInstance)
+ # now, i need to somehow differentiate between those things with
+ # arrays in their names, and normal things
+
+ result.push ast(
+ AST::Resource,
+ :type => val[0],
+ :title => instance[0],
+
+ :parameters => instance[1])
+ }
} | classname LBRACE params endcomma RBRACE {
- # This is a deprecated syntax.
- error "All resource specifications require names"
+ # This is a deprecated syntax.
+ error "All resource specifications require names"
} | classref LBRACE params endcomma RBRACE {
- # a defaults setting for a type
- @lexer.commentpop
- result = ast(AST::ResourceDefaults, :type => val[0], :parameters => val[2])
+ # a defaults setting for a type
+ @lexer.commentpop
+ result = ast(AST::ResourceDefaults, :type => val[0], :parameters => val[2])
}
# Override a value set elsewhere in the configuration.
resourceoverride: resourceref LBRACE anyparams endcomma RBRACE {
- @lexer.commentpop
- result = ast AST::ResourceOverride, :object => val[0], :parameters => val[2]
+ @lexer.commentpop
+ result = ast AST::ResourceOverride, :object => val[0], :parameters => val[2]
}
# Exported and virtual resources; these don't get sent to the client
# unless they get collected elsewhere in the db.
virtualresource: at resource {
- type = val[0]
+ type = val[0]
- if (type == :exported and ! Puppet[:storeconfigs]) and ! Puppet[:parseonly]
- Puppet.warning addcontext("You cannot collect without storeconfigs being set")
- end
+ if (type == :exported and ! Puppet[:storeconfigs]) and ! Puppet[:parseonly]
+ Puppet.warning addcontext("You cannot collect without storeconfigs being set")
+ end
- error "Defaults are not virtualizable" if val[1].is_a? AST::ResourceDefaults
+ error "Defaults are not virtualizable" if val[1].is_a? AST::ResourceDefaults
- method = type.to_s + "="
+ method = type.to_s + "="
- # Just mark our resources as exported and pass them through.
- if val[1].instance_of?(AST::ASTArray)
- val[1].each do |obj|
- obj.send(method, true)
- end
- else
- val[1].send(method, true)
+ # Just mark our resources as exported and pass them through.
+ if val[1].instance_of?(AST::ASTArray)
+ val[1].each do |obj|
+ obj.send(method, true)
end
+ else
+ val[1].send(method, true)
+ end
- result = val[1]
+ result = val[1]
}
at: AT { result = :virtual }
- | AT AT { result = :exported }
+ | AT AT { result = :exported }
# A collection statement. Currently supports no arguments at all, but eventually
# will, I assume.
collection: classref collectrhand LBRACE anyparams endcomma RBRACE {
- @lexer.commentpop
- Puppet.warning addcontext("Collection names must now be capitalized") if val[0] =~ /^[a-z]/
- type = val[0].downcase
- args = {:type => type}
-
- if val[1].is_a?(AST::CollExpr)
- args[:query] = val[1]
- args[:query].type = type
- args[:form] = args[:query].form
- else
- args[:form] = val[1]
- end
- if args[:form] == :exported and ! Puppet[:storeconfigs] and ! Puppet[:parseonly]
- Puppet.warning addcontext("You cannot collect exported resources without storeconfigs being set; the collection will be ignored")
- end
- args[:override] = val[3]
- result = ast AST::Collection, args
-}
- | classref collectrhand {
- if val[0] =~ /^[a-z]/
- Puppet.warning addcontext("Collection names must now be capitalized")
- end
- type = val[0].downcase
- args = {:type => type }
-
- if val[1].is_a?(AST::CollExpr)
- args[:query] = val[1]
- args[:query].type = type
- args[:form] = args[:query].form
- else
- args[:form] = val[1]
- end
- if args[:form] == :exported and ! Puppet[:storeconfigs] and ! Puppet[:parseonly]
- Puppet.warning addcontext("You cannot collect exported resources without storeconfigs being set; the collection will be ignored")
- end
- result = ast AST::Collection, args
+ @lexer.commentpop
+ Puppet.warning addcontext("Collection names must now be capitalized") if val[0] =~ /^[a-z]/
+ type = val[0].downcase
+ args = {:type => type}
+
+ if val[1].is_a?(AST::CollExpr)
+ args[:query] = val[1]
+ args[:query].type = type
+ args[:form] = args[:query].form
+ else
+ args[:form] = val[1]
+ end
+ if args[:form] == :exported and ! Puppet[:storeconfigs] and ! Puppet[:parseonly]
+ Puppet.warning addcontext("You cannot collect exported resources without storeconfigs being set; the collection will be ignored")
+ end
+ args[:override] = val[3]
+ result = ast AST::Collection, args
+}
+ | classref collectrhand {
+ if val[0] =~ /^[a-z]/
+ Puppet.warning addcontext("Collection names must now be capitalized")
+ end
+ type = val[0].downcase
+ args = {:type => type }
+
+ if val[1].is_a?(AST::CollExpr)
+ args[:query] = val[1]
+ args[:query].type = type
+ args[:form] = args[:query].form
+ else
+ args[:form] = val[1]
+ end
+ if args[:form] == :exported and ! Puppet[:storeconfigs] and ! Puppet[:parseonly]
+ Puppet.warning addcontext("You cannot collect exported resources without storeconfigs being set; the collection will be ignored")
+ end
+ result = ast AST::Collection, args
}
collectrhand: LCOLLECT collstatements RCOLLECT {
- if val[1]
- result = val[1]
- result.form = :virtual
- else
- result = :virtual
- end
+ if val[1]
+ result = val[1]
+ result.form = :virtual
+ else
+ result = :virtual
+ end
}
- | LLCOLLECT collstatements RRCOLLECT {
- if val[1]
- result = val[1]
- result.form = :exported
- else
- result = :exported
- end
+ | LLCOLLECT collstatements RRCOLLECT {
+ if val[1]
+ result = val[1]
+ result.form = :exported
+ else
+ result = :exported
+ end
}
# A mini-language for handling collection comparisons. This is organized
# to avoid the need for precedence indications.
collstatements: nil
- | collstatement
- | collstatements colljoin collstatement {
- result = ast AST::CollExpr, :test1 => val[0], :oper => val[1], :test2 => val[2]
+ | collstatement
+ | collstatements colljoin collstatement {
+ result = ast AST::CollExpr, :test1 => val[0], :oper => val[1], :test2 => val[2]
}
collstatement: collexpr
- | LPAREN collstatements RPAREN {
- result = val[1]
- result.parens = true
+ | LPAREN collstatements RPAREN {
+ result = val[1]
+ result.parens = true
}
colljoin: AND { result=val[0][:value] }
- | OR { result=val[0][:value] }
+ | OR { result=val[0][:value] }
collexpr: colllval ISEQUAL simplervalue {
+ result = ast AST::CollExpr, :test1 => val[0], :oper => val[1][:value], :test2 => val[2]
+ #result = ast AST::CollExpr
+ #result.push *val
+}
+ | colllval NOTEQUAL simplervalue {
result = ast AST::CollExpr, :test1 => val[0], :oper => val[1][:value], :test2 => val[2]
#result = ast AST::CollExpr
#result.push *val
}
- | colllval NOTEQUAL simplervalue {
- result = ast AST::CollExpr, :test1 => val[0], :oper => val[1][:value], :test2 => val[2]
- #result = ast AST::CollExpr
- #result.push *val
-}
colllval: variable
- | name
+ | name
resourceinst: resourcename COLON params endcomma {
- result = ast AST::ResourceInstance, :children => [val[0],val[2]]
+ result = ast AST::ResourceInstance, :children => [val[0],val[2]]
}
resourceinstances: resourceinst
- | resourceinstances SEMIC resourceinst {
- if val[0].instance_of?(AST::ResourceInstance)
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- else
- val[0].push val[2]
- result = val[0]
- end
+ | resourceinstances SEMIC resourceinst {
+ if val[0].instance_of?(AST::ResourceInstance)
+ result = ast AST::ASTArray, :children => [val[0],val[2]]
+ else
+ val[0].push val[2]
+ result = val[0]
+ end
}
endsemi: # nothing
- | SEMIC
+ | SEMIC
undef: UNDEF {
- result = ast AST::Undef, :value => :undef
+ result = ast AST::Undef, :value => :undef
}
name: NAME {
- result = ast AST::Name, :value => val[0][:value], :line => val[0][:line]
+ result = ast AST::Name, :value => val[0][:value], :line => val[0][:line]
}
type: CLASSREF {
- result = ast AST::Type, :value => val[0][:value], :line => val[0][:line]
+ result = ast AST::Type, :value => val[0][:value], :line => val[0][:line]
}
resourcename: quotedtext
- | name
- | type
- | selector
- | variable
- | array
- | hasharrayaccesses
+ | name
+ | type
+ | selector
+ | variable
+ | array
+ | hasharrayaccesses
assignment: VARIABLE EQUALS expression {
- raise Puppet::ParseError, "Cannot assign to variables in other namespaces" if val[0][:value] =~ /::/
- # this is distinct from referencing a variable
- variable = ast AST::Name, :value => val[0][:value], :line => val[0][:line]
- result = ast AST::VarDef, :name => variable, :value => val[2], :line => val[0][:line]
+ raise Puppet::ParseError, "Cannot assign to variables in other namespaces" if val[0][:value] =~ /::/
+ # this is distinct from referencing a variable
+ variable = ast AST::Name, :value => val[0][:value], :line => val[0][:line]
+ result = ast AST::VarDef, :name => variable, :value => val[2], :line => val[0][:line]
}
- | hasharrayaccess EQUALS expression {
- result = ast AST::VarDef, :name => val[0], :value => val[2]
+ | hasharrayaccess EQUALS expression {
+ result = ast AST::VarDef, :name => val[0], :value => val[2]
}
append: VARIABLE APPENDS expression {
- variable = ast AST::Name, :value => val[0][:value], :line => val[0][:line]
- result = ast AST::VarDef, :name => variable, :value => val[2], :append => true, :line => val[0][:line]
+ variable = ast AST::Name, :value => val[0][:value], :line => val[0][:line]
+ result = ast AST::VarDef, :name => variable, :value => val[2], :append => true, :line => val[0][:line]
}
params: # nothing
{
- result = ast AST::ASTArray
+ result = ast AST::ASTArray
}
- | param { result = val[0] }
- | params COMMA param {
- if val[0].instance_of?(AST::ASTArray)
- val[0].push(val[2])
- result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- end
+ | param { result = val[0] }
+ | params COMMA param {
+ if val[0].instance_of?(AST::ASTArray)
+ val[0].push(val[2])
+ result = val[0]
+ else
+ result = ast AST::ASTArray, :children => [val[0],val[2]]
+ end
}
param: NAME FARROW rvalue {
- result = ast AST::ResourceParam, :param => val[0][:value], :line => val[0][:line], :value => val[2]
+ result = ast AST::ResourceParam, :param => val[0][:value], :line => val[0][:line], :value => val[2]
}
addparam: NAME PARROW rvalue {
- result = ast AST::ResourceParam, :param => val[0][:value], :line => val[0][:line], :value => val[2],
- :add => true
+ result = ast AST::ResourceParam, :param => val[0][:value], :line => val[0][:line], :value => val[2],
+ :add => true
}
anyparam: param
- | addparam
+ | addparam
anyparams: # nothing
{
- result = ast AST::ASTArray
+ result = ast AST::ASTArray
}
- | anyparam { result = val[0] }
- | anyparams COMMA anyparam {
- if val[0].instance_of?(AST::ASTArray)
- val[0].push(val[2])
- result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- end
+ | anyparam { result = val[0] }
+ | anyparams COMMA anyparam {
+ if val[0].instance_of?(AST::ASTArray)
+ val[0].push(val[2])
+ result = val[0]
+ else
+ result = ast AST::ASTArray, :children => [val[0],val[2]]
+ end
}
rvalues: rvalue
- | rvalues comma rvalue {
- if val[0].instance_of?(AST::ASTArray)
- result = val[0].push(val[2])
- else
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- end
+ | rvalues comma rvalue {
+ if val[0].instance_of?(AST::ASTArray)
+ result = val[0].push(val[2])
+ else
+ result = ast AST::ASTArray, :children => [val[0],val[2]]
+ end
}
simplervalue: quotedtext
- | name
- | type
- | boolean
- | selector
- | variable
+ | name
+ | type
+ | boolean
+ | selector
+ | variable
rvalue: quotedtext
- | name
- | type
- | boolean
- | selector
- | variable
- | array
- | hash
- | hasharrayaccesses
- | resourceref
- | funcrvalue
- | undef
+ | name
+ | type
+ | boolean
+ | selector
+ | variable
+ | array
+ | hash
+ | hasharrayaccesses
+ | resourceref
+ | funcrvalue
+ | undef
# We currently require arguments in these functions.
funcrvalue: NAME LPAREN funcvalues RPAREN {
- args = aryfy(val[2])
- result = ast AST::Function,
- :name => val[0][:value], :line => val[0][:line],
- :arguments => args,
- :ftype => :rvalue
+ args = aryfy(val[2])
+ result = ast AST::Function,
+ :name => val[0][:value], :line => val[0][:line],
+ :arguments => args,
+ :ftype => :rvalue
} | NAME LPAREN RPAREN {
- result = ast AST::Function,
- :name => val[0][:value], :line => val[0][:line],
- :arguments => AST::ASTArray.new({}),
- :ftype => :rvalue
+ result = ast AST::Function,
+ :name => val[0][:value], :line => val[0][:line],
+ :arguments => AST::ASTArray.new({}),
+ :ftype => :rvalue
}
quotedtext: STRING { result = ast AST::String, :value => val[0][:value], :line => val[0][:line] }
- | DQPRE dqrval { result = ast AST::Concat, :value => [ast(AST::String,val[0])]+val[1], :line => val[0][:line] }
+ | DQPRE dqrval { result = ast AST::Concat, :value => [ast(AST::String,val[0])]+val[1], :line => val[0][:line] }
dqrval: expression dqtail { result = [val[0]] + val[1] }
dqtail: DQPOST { result = [ast(AST::String,val[0])] }
- | DQMID dqrval { result = [ast(AST::String,val[0])] + val[1] }
+ | DQMID dqrval { result = [ast(AST::String,val[0])] + val[1] }
boolean: BOOLEAN {
- result = ast AST::Boolean, :value => val[0][:value], :line => val[0][:line]
+ result = ast AST::Boolean, :value => val[0][:value], :line => val[0][:line]
}
resourceref: NAME LBRACK rvalues RBRACK {
- Puppet.warning addcontext("Deprecation notice: Resource references should now be capitalized")
- result = ast AST::ResourceReference, :type => val[0][:value], :line => val[0][:line], :title => val[2]
+ Puppet.warning addcontext("Deprecation notice: Resource references should now be capitalized")
+ result = ast AST::ResourceReference, :type => val[0][:value], :line => val[0][:line], :title => val[2]
} | classref LBRACK rvalues RBRACK {
- result = ast AST::ResourceReference, :type => val[0], :title => val[2]
+ result = ast AST::ResourceReference, :type => val[0], :title => val[2]
}
ifstatement_begin: IF ifstatement {
- result = val[1]
+ result = val[1]
}
ifstatement: expression LBRACE statements RBRACE else {
- @lexer.commentpop
- args = {
- :test => val[0],
- :statements => val[2]
- }
+ @lexer.commentpop
+ args = {
+ :test => val[0],
+ :statements => val[2]
+ }
- args[:else] = val[4] if val[4]
+ args[:else] = val[4] if val[4]
- result = ast AST::IfStatement, args
+ result = ast AST::IfStatement, args
}
- | expression LBRACE RBRACE else {
- @lexer.commentpop
- args = {
- :test => val[0],
- :statements => ast(AST::Nop)
- }
+ | expression LBRACE RBRACE else {
+ @lexer.commentpop
+ args = {
+ :test => val[0],
+ :statements => ast(AST::Nop)
+ }
- args[:else] = val[3] if val[3]
+ args[:else] = val[3] if val[3]
- result = ast AST::IfStatement, args
+ result = ast AST::IfStatement, args
}
else: # nothing
- | ELSIF ifstatement {
- result = ast AST::Else, :statements => val[1]
+ | ELSIF ifstatement {
+ result = ast AST::Else, :statements => val[1]
}
- | ELSE LBRACE statements RBRACE {
- @lexer.commentpop
- result = ast AST::Else, :statements => val[2]
+ | ELSE LBRACE statements RBRACE {
+ @lexer.commentpop
+ result = ast AST::Else, :statements => val[2]
}
- | ELSE LBRACE RBRACE {
- @lexer.commentpop
- result = ast AST::Else, :statements => ast(AST::Nop)
+ | ELSE LBRACE RBRACE {
+ @lexer.commentpop
+ result = ast AST::Else, :statements => ast(AST::Nop)
}
# Unlike yacc/bison, it seems racc
@@ -509,343 +509,343 @@ else: # nothing
# per operator :-(
expression: rvalue
- | expression IN rvalue {
- result = ast AST::InOperator, :lval => val[0], :rval => val[2]
+ | expression IN rvalue {
+ result = ast AST::InOperator, :lval => val[0], :rval => val[2]
}
- | expression MATCH regex {
- result = ast AST::MatchOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
+ | expression MATCH regex {
+ result = ast AST::MatchOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
}
- | expression NOMATCH regex {
- result = ast AST::MatchOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
+ | expression NOMATCH regex {
+ result = ast AST::MatchOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
}
- | expression PLUS expression {
- result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
+ | expression PLUS expression {
+ result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
}
- | expression MINUS expression {
- result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
+ | expression MINUS expression {
+ result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
}
- | expression DIV expression {
- result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
+ | expression DIV expression {
+ result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
}
- | expression TIMES expression {
- result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
+ | expression TIMES expression {
+ result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
}
- | expression LSHIFT expression {
- result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
+ | expression LSHIFT expression {
+ result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
}
- | expression RSHIFT expression {
- result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
+ | expression RSHIFT expression {
+ result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
}
- | MINUS expression =UMINUS {
- result = ast AST::Minus, :value => val[1]
+ | MINUS expression =UMINUS {
+ result = ast AST::Minus, :value => val[1]
}
- | expression NOTEQUAL expression {
- result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
+ | expression NOTEQUAL expression {
+ result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
}
- | expression ISEQUAL expression {
- result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
+ | expression ISEQUAL expression {
+ result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
}
- | expression GREATERTHAN expression {
- result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
+ | expression GREATERTHAN expression {
+ result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
}
- | expression GREATEREQUAL expression {
- result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
+ | expression GREATEREQUAL expression {
+ result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
}
- | expression LESSTHAN expression {
- result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
+ | expression LESSTHAN expression {
+ result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
}
- | expression LESSEQUAL expression {
- result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
+ | expression LESSEQUAL expression {
+ result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
}
- | NOT expression {
- result = ast AST::Not, :value => val[1]
+ | NOT expression {
+ result = ast AST::Not, :value => val[1]
}
- | expression AND expression {
- result = ast AST::BooleanOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
+ | expression AND expression {
+ result = ast AST::BooleanOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
}
- | expression OR expression {
- result = ast AST::BooleanOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
+ | expression OR expression {
+ result = ast AST::BooleanOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
}
- | LPAREN expression RPAREN {
- result = val[1]
+ | LPAREN expression RPAREN {
+ result = val[1]
}
casestatement: CASE rvalue LBRACE caseopts RBRACE {
- @lexer.commentpop
- options = val[3]
- options = ast AST::ASTArray, :children => [val[3]] unless options.instance_of?(AST::ASTArray)
- result = ast AST::CaseStatement, :test => val[1], :options => options
+ @lexer.commentpop
+ options = val[3]
+ options = ast AST::ASTArray, :children => [val[3]] unless options.instance_of?(AST::ASTArray)
+ result = ast AST::CaseStatement, :test => val[1], :options => options
}
caseopts: caseopt
- | caseopts caseopt {
- if val[0].instance_of?(AST::ASTArray)
- val[0].push val[1]
- result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0], val[1]]
- end
+ | caseopts caseopt {
+ if val[0].instance_of?(AST::ASTArray)
+ val[0].push val[1]
+ result = val[0]
+ else
+ result = ast AST::ASTArray, :children => [val[0], val[1]]
+ end
}
caseopt: casevalues COLON LBRACE statements RBRACE {
- @lexer.commentpop
- result = ast AST::CaseOpt, :value => val[0], :statements => val[3]
+ @lexer.commentpop
+ result = ast AST::CaseOpt, :value => val[0], :statements => val[3]
} | casevalues COLON LBRACE RBRACE {
- @lexer.commentpop
+ @lexer.commentpop
- result = ast(
- AST::CaseOpt,
- :value => val[0],
+ result = ast(
+ AST::CaseOpt,
+ :value => val[0],
- :statements => ast(AST::ASTArray)
- )
+ :statements => ast(AST::ASTArray)
+ )
}
casevalues: selectlhand
- | casevalues COMMA selectlhand {
- if val[0].instance_of?(AST::ASTArray)
- val[0].push(val[2])
- result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- end
+ | casevalues COMMA selectlhand {
+ if val[0].instance_of?(AST::ASTArray)
+ val[0].push(val[2])
+ result = val[0]
+ else
+ result = ast AST::ASTArray, :children => [val[0],val[2]]
+ end
}
selector: selectlhand QMARK svalues {
- result = ast AST::Selector, :param => val[0], :values => val[2]
+ result = ast AST::Selector, :param => val[0], :values => val[2]
}
svalues: selectval
- | LBRACE sintvalues endcomma RBRACE {
- @lexer.commentpop
- result = val[1]
+ | LBRACE sintvalues endcomma RBRACE {
+ @lexer.commentpop
+ result = val[1]
}
sintvalues: selectval
- | sintvalues comma selectval {
- if val[0].instance_of?(AST::ASTArray)
- val[0].push(val[2])
- result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- end
+ | sintvalues comma selectval {
+ if val[0].instance_of?(AST::ASTArray)
+ val[0].push(val[2])
+ result = val[0]
+ else
+ result = ast AST::ASTArray, :children => [val[0],val[2]]
+ end
}
selectval: selectlhand FARROW rvalue {
- result = ast AST::ResourceParam, :param => val[0], :value => val[2]
+ result = ast AST::ResourceParam, :param => val[0], :value => val[2]
}
selectlhand: name
- | type
- | quotedtext
- | variable
- | funcrvalue
- | boolean
- | undef
- | DEFAULT {
- result = ast AST::Default, :value => val[0][:value], :line => val[0][:line]
+ | type
+ | quotedtext
+ | variable
+ | funcrvalue
+ | boolean
+ | undef
+ | DEFAULT {
+ result = ast AST::Default, :value => val[0][:value], :line => val[0][:line]
}
- | regex
+ | regex
# These are only used for importing, and we don't interpolate there.
string: STRING { result = [val[0][:value]] }
strings: string
- | strings COMMA string { result = val[0] += val[2] }
+ | strings COMMA string { result = val[0] += val[2] }
import: IMPORT strings {
- val[1].each do |file|
- import(file)
- end
+ val[1].each do |file|
+ import(file)
+ end
- result = AST::ASTArray.new(:children => [])
+ result = AST::ASTArray.new(:children => [])
}
# Disable definition inheritance for now. 8/27/06, luke
#definition: DEFINE NAME argumentlist parent LBRACE statements RBRACE {
definition: DEFINE classname argumentlist LBRACE statements RBRACE {
- @lexer.commentpop
- newdefine classname(val[1]), :arguments => val[2], :code => val[4], :line => val[0][:line]
- @lexer.indefine = false
- result = nil
+ @lexer.commentpop
+ newdefine classname(val[1]), :arguments => val[2], :code => val[4], :line => val[0][:line]
+ @lexer.indefine = false
+ result = nil
#} | DEFINE NAME argumentlist parent LBRACE RBRACE {
} | DEFINE classname argumentlist LBRACE RBRACE {
- @lexer.commentpop
- newdefine classname(val[1]), :arguments => val[2], :line => val[0][:line]
- @lexer.indefine = false
- result = nil
+ @lexer.commentpop
+ newdefine classname(val[1]), :arguments => val[2], :line => val[0][:line]
+ @lexer.indefine = false
+ result = nil
}
#hostclass: CLASS NAME argumentlist parent LBRACE statements RBRACE {
hostclass: CLASS classname argumentlist classparent LBRACE statements RBRACE {
- @lexer.commentpop
- # Our class gets defined in the parent namespace, not our own.
- @lexer.namepop
- newclass classname(val[1]), :arguments => val[2], :parent => val[3], :code => val[5], :line => val[0][:line]
- result = nil
+ @lexer.commentpop
+ # Our class gets defined in the parent namespace, not our own.
+ @lexer.namepop
+ newclass classname(val[1]), :arguments => val[2], :parent => val[3], :code => val[5], :line => val[0][:line]
+ result = nil
} | CLASS classname argumentlist classparent LBRACE RBRACE {
- @lexer.commentpop
- # Our class gets defined in the parent namespace, not our own.
- @lexer.namepop
- newclass classname(val[1]), :arguments => val[2], :parent => val[3], :line => val[0][:line]
- result = nil
+ @lexer.commentpop
+ # Our class gets defined in the parent namespace, not our own.
+ @lexer.namepop
+ newclass classname(val[1]), :arguments => val[2], :parent => val[3], :line => val[0][:line]
+ result = nil
}
nodedef: NODE hostnames nodeparent LBRACE statements RBRACE {
- @lexer.commentpop
- newnode val[1], :parent => val[2], :code => val[4], :line => val[0][:line]
- result = nil
+ @lexer.commentpop
+ newnode val[1], :parent => val[2], :code => val[4], :line => val[0][:line]
+ result = nil
} | NODE hostnames nodeparent LBRACE RBRACE {
- @lexer.commentpop
- newnode val[1], :parent => val[2], :line => val[0][:line]
- result = nil
+ @lexer.commentpop
+ newnode val[1], :parent => val[2], :line => val[0][:line]
+ result = nil
}
classref: CLASSREF { result = val[0][:value] }
classname: NAME { result = val[0][:value] }
- | CLASSNAME { result = val[0][:value] }
- | CLASS { result = "class" }
+ | CLASSNAME { result = val[0][:value] }
+ | CLASS { result = "class" }
# Multiple hostnames, as used for node names. These are all literal
# strings, not AST objects.
hostnames: nodename
- | hostnames COMMA nodename {
- result = val[0]
- result = [result] unless result.is_a?(Array)
- result << val[2]
+ | hostnames COMMA nodename {
+ result = val[0]
+ result = [result] unless result.is_a?(Array)
+ result << val[2]
}
nodename: hostname {
- result = ast AST::HostName, :value => val[0]
+ result = ast AST::HostName, :value => val[0]
}
hostname: NAME { result = val[0][:value] }
- | STRING { result = val[0][:value] }
- | DEFAULT { result = val[0][:value] }
- | regex
+ | STRING { result = val[0][:value] }
+ | DEFAULT { result = val[0][:value] }
+ | regex
nil: {
- result = nil
+ result = nil
}
nothing: {
- result = ast AST::ASTArray, :children => []
+ result = ast AST::ASTArray, :children => []
}
argumentlist: nil
- | LPAREN nothing RPAREN {
- result = nil
+ | LPAREN nothing RPAREN {
+ result = nil
}
- | LPAREN arguments RPAREN {
- result = val[1]
- result = [result] unless result[0].is_a?(Array)
+ | LPAREN arguments RPAREN {
+ result = val[1]
+ result = [result] unless result[0].is_a?(Array)
}
arguments: argument
- | arguments COMMA argument {
- result = val[0]
- result = [result] unless result[0].is_a?(Array)
- result << val[2]
+ | arguments COMMA argument {
+ result = val[0]
+ result = [result] unless result[0].is_a?(Array)
+ result << val[2]
}
argument: NAME EQUALS rvalue {
- Puppet.warning addcontext("Deprecation notice: must now include '$' in prototype")
- result = [val[0][:value], val[2]]
+ Puppet.warning addcontext("Deprecation notice: must now include '$' in prototype")
+ result = [val[0][:value], val[2]]
}
- | NAME {
- Puppet.warning addcontext("Deprecation notice: must now include '$' in prototype")
- result = [val[0][:value]]
+ | NAME {
+ Puppet.warning addcontext("Deprecation notice: must now include '$' in prototype")
+ result = [val[0][:value]]
} | VARIABLE EQUALS rvalue {
- result = [val[0][:value], val[2]]
+ result = [val[0][:value], val[2]]
} | VARIABLE {
- result = [val[0][:value]]
+ result = [val[0][:value]]
}
nodeparent: nil
- | INHERITS hostname {
- result = val[1]
+ | INHERITS hostname {
+ result = val[1]
}
classparent: nil
- | INHERITS classnameordefault {
- result = val[1]
+ | INHERITS classnameordefault {
+ result = val[1]
}
classnameordefault: classname | DEFAULT
variable: VARIABLE {
- result = ast AST::Variable, :value => val[0][:value], :line => val[0][:line]
+ result = ast AST::Variable, :value => val[0][:value], :line => val[0][:line]
}
array: LBRACK rvalues RBRACK {
- if val[1].instance_of?(AST::ASTArray)
- result = val[1]
- else
- result = ast AST::ASTArray, :children => [val[1]]
- end
+ if val[1].instance_of?(AST::ASTArray)
+ result = val[1]
+ else
+ result = ast AST::ASTArray, :children => [val[1]]
+ end
}
- | LBRACK rvalues COMMA RBRACK {
- if val[1].instance_of?(AST::ASTArray)
- result = val[1]
- else
- result = ast AST::ASTArray, :children => [val[1]]
- end
+ | LBRACK rvalues COMMA RBRACK {
+ if val[1].instance_of?(AST::ASTArray)
+ result = val[1]
+ else
+ result = ast AST::ASTArray, :children => [val[1]]
+ end
} | LBRACK RBRACK {
- result = ast AST::ASTArray
+ result = ast AST::ASTArray
}
comma: FARROW
- | COMMA
+ | COMMA
endcomma: # nothing
- | COMMA { result = nil }
+ | COMMA { result = nil }
regex: REGEX {
- result = ast AST::Regex, :value => val[0][:value]
+ result = ast AST::Regex, :value => val[0][:value]
}
hash: LBRACE hashpairs RBRACE {
- if val[1].instance_of?(AST::ASTHash)
- result = val[1]
- else
- result = ast AST::ASTHash, { :value => val[1] }
- end
+ if val[1].instance_of?(AST::ASTHash)
+ result = val[1]
+ else
+ result = ast AST::ASTHash, { :value => val[1] }
+ end
}
- | LBRACE hashpairs COMMA RBRACE {
- if val[1].instance_of?(AST::ASTHash)
- result = val[1]
- else
- result = ast AST::ASTHash, { :value => val[1] }
- end
+ | LBRACE hashpairs COMMA RBRACE {
+ if val[1].instance_of?(AST::ASTHash)
+ result = val[1]
+ else
+ result = ast AST::ASTHash, { :value => val[1] }
+ end
} | LBRACE RBRACE {
- result = ast AST::ASTHash
+ result = ast AST::ASTHash
}
hashpairs: hashpair
- | hashpairs COMMA hashpair {
- if val[0].instance_of?(AST::ASTHash)
- result = val[0].merge(val[2])
- else
- result = ast AST::ASTHash, :value => val[0]
- result.merge(val[2])
- end
+ | hashpairs COMMA hashpair {
+ if val[0].instance_of?(AST::ASTHash)
+ result = val[0].merge(val[2])
+ else
+ result = ast AST::ASTHash, :value => val[0]
+ result.merge(val[2])
+ end
}
hashpair: key FARROW rvalue {
- result = ast AST::ASTHash, { :value => { val[0] => val[2] } }
+ result = ast AST::ASTHash, { :value => { val[0] => val[2] } }
}
key: NAME { result = val[0][:value] }
- | quotedtext { result = val[0] }
+ | quotedtext { result = val[0] }
hasharrayaccess: VARIABLE LBRACK rvalue RBRACK {
- result = ast AST::HashOrArrayAccess, :variable => val[0][:value], :key => val[2]
+ result = ast AST::HashOrArrayAccess, :variable => val[0][:value], :key => val[2]
}
hasharrayaccesses: hasharrayaccess
- | hasharrayaccess LBRACK rvalue RBRACK {
- result = ast AST::HashOrArrayAccess, :variable => val[0], :key => val[2]
+ | hasharrayaccess LBRACK rvalue RBRACK {
+ result = ast AST::HashOrArrayAccess, :variable => val[0], :key => val[2]
}
end
@@ -856,9 +856,9 @@ require 'puppet/parser/lexer'
require 'puppet/parser/ast'
module Puppet
- class ParseError < Puppet::Error; end
- class ImportError < Racc::ParseError; end
- class AlreadyImportedError < ImportError; end
+ class ParseError < Puppet::Error; end
+ class ImportError < Racc::ParseError; end
+ class AlreadyImportedError < ImportError; end
end
---- inner ----
diff --git a/lib/puppet/parser/lexer.rb b/lib/puppet/parser/lexer.rb
index 0c95142..6a9f1cf 100644
--- a/lib/puppet/parser/lexer.rb
+++ b/lib/puppet/parser/lexer.rb
@@ -5,573 +5,573 @@ require 'puppet'
module Puppet
- class LexError < RuntimeError; end
+ class LexError < RuntimeError; end
end
module Puppet::Parser; end
class Puppet::Parser::Lexer
- attr_reader :last, :file, :lexing_context, :token_queue
+ attr_reader :last, :file, :lexing_context, :token_queue
- attr_accessor :line, :indefine
+ attr_accessor :line, :indefine
- def lex_error msg
- raise Puppet::LexError.new(msg)
- end
-
- class Token
- attr_accessor :regex, :name, :string, :skip, :incr_line, :skip_text, :accumulate
-
- def initialize(regex, name)
- if regex.is_a?(String)
- @name, @string = name, regex
- @regex = Regexp.new(Regexp.escape(@string))
- else
- @name, @regex = name, regex
- end
- end
-
- # MQR: Why not just alias?
- %w{skip accumulate}.each do |method|
- define_method(method+"?") do
- self.send(method)
- end
- end
-
- def to_s
- if self.string
- @string
- else
- @name.to_s
- end
- end
-
- def acceptable?(context={})
- # By default tokens are aceeptable in any context
- true
- end
- end
-
- # Maintain a list of tokens.
- class TokenList
- attr_reader :regex_tokens, :string_tokens
-
- def [](name)
- @tokens[name]
- end
-
- # Create a new token.
- def add_token(name, regex, options = {}, &block)
- token = Token.new(regex, name)
- raise(ArgumentError, "Token #{name} already exists") if @tokens.include?(name)
- @tokens[token.name] = token
- if token.string
- @string_tokens << token
- @tokens_by_string[token.string] = token
- else
- @regex_tokens << token
- end
-
- options.each do |name, option|
- token.send(name.to_s + "=", option)
- end
-
- token.meta_def(:convert, &block) if block_given?
-
- token
- end
-
- def initialize
- @tokens = {}
- @regex_tokens = []
- @string_tokens = []
- @tokens_by_string = {}
- end
-
- # Look up a token by its value, rather than name.
- def lookup(string)
- @tokens_by_string[string]
- end
-
- # Define more tokens.
- def add_tokens(hash)
- hash.each do |regex, name|
- add_token(name, regex)
- end
- end
-
- # Sort our tokens by length, so we know once we match, we're done.
- # This helps us avoid the O(n^2) nature of token matching.
- def sort_tokens
- @string_tokens.sort! { |a, b| b.string.length <=> a.string.length }
- end
- end
+ def lex_error msg
+ raise Puppet::LexError.new(msg)
+ end
- TOKENS = TokenList.new
-
- TOKENS.add_tokens(
-
- '[' => :LBRACK,
- ']' => :RBRACK,
- '{' => :LBRACE,
- '}' => :RBRACE,
- '(' => :LPAREN,
-
- ')' => :RPAREN,
- '=' => :EQUALS,
- '+=' => :APPENDS,
- '==' => :ISEQUAL,
- '>=' => :GREATEREQUAL,
- '>' => :GREATERTHAN,
- '<' => :LESSTHAN,
- '<=' => :LESSEQUAL,
- '!=' => :NOTEQUAL,
- '!' => :NOT,
- ',' => :COMMA,
- '.' => :DOT,
- ':' => :COLON,
- '@' => :AT,
- '<<|' => :LLCOLLECT,
- '->' => :IN_EDGE,
- '<-' => :OUT_EDGE,
- '~>' => :IN_EDGE_SUB,
- '<~' => :OUT_EDGE_SUB,
- '|>>' => :RRCOLLECT,
- '<|' => :LCOLLECT,
- '|>' => :RCOLLECT,
- ';' => :SEMIC,
- '?' => :QMARK,
- '\\' => :BACKSLASH,
- '=>' => :FARROW,
- '+>' => :PARROW,
- '+' => :PLUS,
- '-' => :MINUS,
- '/' => :DIV,
- '*' => :TIMES,
- '<<' => :LSHIFT,
- '>>' => :RSHIFT,
- '=~' => :MATCH,
- '!~' => :NOMATCH,
- %r{([a-z][-\w]*)?(::[a-z][-\w]*)+} => :CLASSNAME, # Require '::' in the class name, else we'd compete with NAME
- %r{((::){0,1}[A-Z][-\w]*)+} => :CLASSREF,
- "<string>" => :STRING,
- "<dqstring up to first interpolation>" => :DQPRE,
- "<dqstring between two interpolations>" => :DQMID,
- "<dqstring after final interpolation>" => :DQPOST,
- "<boolean>" => :BOOLEAN
- )
-
- TOKENS.add_token :NUMBER, %r{\b(?:0[xX][0-9A-Fa-f]+|0?\d+(?:\.\d+)?(?:[eE]-?\d+)?)\b} do |lexer, value|
- [TOKENS[:NAME], value]
- end
- #:stopdoc: # Issue #4161
- def (TOKENS[:NUMBER]).acceptable?(context={})
- ![:DQPRE,:DQMID].include? context[:after]
- end
- #:startdoc:
+ class Token
+ attr_accessor :regex, :name, :string, :skip, :incr_line, :skip_text, :accumulate
- TOKENS.add_token :NAME, %r{[a-z0-9][-\w]*} do |lexer, value|
- string_token = self
- # we're looking for keywords here
- if tmp = KEYWORDS.lookup(value)
- string_token = tmp
- if [:TRUE, :FALSE].include?(string_token.name)
- value = eval(value)
- string_token = TOKENS[:BOOLEAN]
- end
- end
- [string_token, value]
+ def initialize(regex, name)
+ if regex.is_a?(String)
+ @name, @string = name, regex
+ @regex = Regexp.new(Regexp.escape(@string))
+ else
+ @name, @regex = name, regex
+ end
end
- [:NAME,:CLASSNAME,:CLASSREF].each { |name_token|
- #:stopdoc: # Issue #4161
- def (TOKENS[name_token]).acceptable?(context={})
- ![:DQPRE,:DQMID].include? context[:after]
- end
- #:startdoc:
- }
- TOKENS.add_token :COMMENT, %r{#.*}, :accumulate => true, :skip => true do |lexer,value|
- value.sub!(/# ?/,'')
- [self, value]
+ # MQR: Why not just alias?
+ %w{skip accumulate}.each do |method|
+ define_method(method+"?") do
+ self.send(method)
+ end
end
- TOKENS.add_token :MLCOMMENT, %r{/\*(.*?)\*/}m, :accumulate => true, :skip => true do |lexer, value|
- lexer.line += value.count("\n")
- value.sub!(/^\/\* ?/,'')
- value.sub!(/ ?\*\/$/,'')
- [self,value]
+ def to_s
+ if self.string
+ @string
+ else
+ @name.to_s
+ end
end
- TOKENS.add_token :REGEX, %r{/[^/\n]*/} do |lexer, value|
- # Make sure we haven't matched an escaped /
- while value[-2..-2] == '\\'
- other = lexer.scan_until(%r{/})
- value += other
- end
- regex = value.sub(%r{\A/}, "").sub(%r{/\Z}, '').gsub("\\/", "/")
- [self, Regexp.new(regex)]
- end
-
- #:stopdoc: # Issue #4161
- def (TOKENS[:REGEX]).acceptable?(context={})
- [:NODE,:LBRACE,:RBRACE,:MATCH,:NOMATCH,:COMMA].include? context[:after]
+ def acceptable?(context={})
+ # By default tokens are aceeptable in any context
+ true
end
- #:startdoc:
+ end
- TOKENS.add_token :RETURN, "\n", :skip => true, :incr_line => true, :skip_text => true
+ # Maintain a list of tokens.
+ class TokenList
+ attr_reader :regex_tokens, :string_tokens
- TOKENS.add_token :SQUOTE, "'" do |lexer, value|
- [TOKENS[:STRING], lexer.slurpstring(value).first ]
+ def [](name)
+ @tokens[name]
end
- DQ_initial_token_types = {'$' => :DQPRE,'"' => :STRING}
- DQ_continuation_token_types = {'$' => :DQMID,'"' => :DQPOST}
+ # Create a new token.
+ def add_token(name, regex, options = {}, &block)
+ token = Token.new(regex, name)
+ raise(ArgumentError, "Token #{name} already exists") if @tokens.include?(name)
+ @tokens[token.name] = token
+ if token.string
+ @string_tokens << token
+ @tokens_by_string[token.string] = token
+ else
+ @regex_tokens << token
+ end
- TOKENS.add_token :DQUOTE, /"/ do |lexer, value|
- lexer.tokenize_interpolated_string(DQ_initial_token_types)
- end
+ options.each do |name, option|
+ token.send(name.to_s + "=", option)
+ end
- TOKENS.add_token :DQCONT, /\}/ do |lexer, value|
- lexer.tokenize_interpolated_string(DQ_continuation_token_types)
- end
- #:stopdoc: # Issue #4161
- def (TOKENS[:DQCONT]).acceptable?(context={})
- context[:string_interpolation_depth] > 0
- end
- #:startdoc:
+ token.meta_def(:convert, &block) if block_given?
- TOKENS.add_token :DOLLAR_VAR, %r{\$(\w*::)*\w+} do |lexer, value|
- [TOKENS[:VARIABLE],value[1..-1]]
+ token
end
- TOKENS.add_token :VARIABLE, %r{(\w*::)*\w+}
+ def initialize
+ @tokens = {}
+ @regex_tokens = []
+ @string_tokens = []
+ @tokens_by_string = {}
+ end
+
+ # Look up a token by its value, rather than name.
+ def lookup(string)
+ @tokens_by_string[string]
+ end
+
+ # Define more tokens.
+ def add_tokens(hash)
+ hash.each do |regex, name|
+ add_token(name, regex)
+ end
+ end
+
+ # Sort our tokens by length, so we know once we match, we're done.
+ # This helps us avoid the O(n^2) nature of token matching.
+ def sort_tokens
+ @string_tokens.sort! { |a, b| b.string.length <=> a.string.length }
+ end
+ end
+
+ TOKENS = TokenList.new
+
+ TOKENS.add_tokens(
+
+ '[' => :LBRACK,
+ ']' => :RBRACK,
+ '{' => :LBRACE,
+ '}' => :RBRACE,
+ '(' => :LPAREN,
+
+ ')' => :RPAREN,
+ '=' => :EQUALS,
+ '+=' => :APPENDS,
+ '==' => :ISEQUAL,
+ '>=' => :GREATEREQUAL,
+ '>' => :GREATERTHAN,
+ '<' => :LESSTHAN,
+ '<=' => :LESSEQUAL,
+ '!=' => :NOTEQUAL,
+ '!' => :NOT,
+ ',' => :COMMA,
+ '.' => :DOT,
+ ':' => :COLON,
+ '@' => :AT,
+ '<<|' => :LLCOLLECT,
+ '->' => :IN_EDGE,
+ '<-' => :OUT_EDGE,
+ '~>' => :IN_EDGE_SUB,
+ '<~' => :OUT_EDGE_SUB,
+ '|>>' => :RRCOLLECT,
+ '<|' => :LCOLLECT,
+ '|>' => :RCOLLECT,
+ ';' => :SEMIC,
+ '?' => :QMARK,
+ '\\' => :BACKSLASH,
+ '=>' => :FARROW,
+ '+>' => :PARROW,
+ '+' => :PLUS,
+ '-' => :MINUS,
+ '/' => :DIV,
+ '*' => :TIMES,
+ '<<' => :LSHIFT,
+ '>>' => :RSHIFT,
+ '=~' => :MATCH,
+ '!~' => :NOMATCH,
+ %r{([a-z][-\w]*)?(::[a-z][-\w]*)+} => :CLASSNAME, # Require '::' in the class name, else we'd compete with NAME
+ %r{((::){0,1}[A-Z][-\w]*)+} => :CLASSREF,
+ "<string>" => :STRING,
+ "<dqstring up to first interpolation>" => :DQPRE,
+ "<dqstring between two interpolations>" => :DQMID,
+ "<dqstring after final interpolation>" => :DQPOST,
+ "<boolean>" => :BOOLEAN
+ )
+
+ TOKENS.add_token :NUMBER, %r{\b(?:0[xX][0-9A-Fa-f]+|0?\d+(?:\.\d+)?(?:[eE]-?\d+)?)\b} do |lexer, value|
+ [TOKENS[:NAME], value]
+ end
+ #:stopdoc: # Issue #4161
+ def (TOKENS[:NUMBER]).acceptable?(context={})
+ ![:DQPRE,:DQMID].include? context[:after]
+ end
+ #:startdoc:
+
+ TOKENS.add_token :NAME, %r{[a-z0-9][-\w]*} do |lexer, value|
+ string_token = self
+ # we're looking for keywords here
+ if tmp = KEYWORDS.lookup(value)
+ string_token = tmp
+ if [:TRUE, :FALSE].include?(string_token.name)
+ value = eval(value)
+ string_token = TOKENS[:BOOLEAN]
+ end
+ end
+ [string_token, value]
+ end
+ [:NAME,:CLASSNAME,:CLASSREF].each { |name_token|
#:stopdoc: # Issue #4161
- def (TOKENS[:VARIABLE]).acceptable?(context={})
- [:DQPRE,:DQMID].include? context[:after]
+ def (TOKENS[name_token]).acceptable?(context={})
+ ![:DQPRE,:DQMID].include? context[:after]
end
#:startdoc:
-
-
- TOKENS.sort_tokens
-
- @@pairs = {
- "{" => "}",
- "(" => ")",
- "[" => "]",
- "<|" => "|>",
- "<<|" => "|>>"
+ }
+
+ TOKENS.add_token :COMMENT, %r{#.*}, :accumulate => true, :skip => true do |lexer,value|
+ value.sub!(/# ?/,'')
+ [self, value]
+ end
+
+ TOKENS.add_token :MLCOMMENT, %r{/\*(.*?)\*/}m, :accumulate => true, :skip => true do |lexer, value|
+ lexer.line += value.count("\n")
+ value.sub!(/^\/\* ?/,'')
+ value.sub!(/ ?\*\/$/,'')
+ [self,value]
+ end
+
+ TOKENS.add_token :REGEX, %r{/[^/\n]*/} do |lexer, value|
+ # Make sure we haven't matched an escaped /
+ while value[-2..-2] == '\\'
+ other = lexer.scan_until(%r{/})
+ value += other
+ end
+ regex = value.sub(%r{\A/}, "").sub(%r{/\Z}, '').gsub("\\/", "/")
+ [self, Regexp.new(regex)]
+ end
+
+ #:stopdoc: # Issue #4161
+ def (TOKENS[:REGEX]).acceptable?(context={})
+ [:NODE,:LBRACE,:RBRACE,:MATCH,:NOMATCH,:COMMA].include? context[:after]
+ end
+ #:startdoc:
+
+ TOKENS.add_token :RETURN, "\n", :skip => true, :incr_line => true, :skip_text => true
+
+ TOKENS.add_token :SQUOTE, "'" do |lexer, value|
+ [TOKENS[:STRING], lexer.slurpstring(value).first ]
+ end
+
+ DQ_initial_token_types = {'$' => :DQPRE,'"' => :STRING}
+ DQ_continuation_token_types = {'$' => :DQMID,'"' => :DQPOST}
+
+ TOKENS.add_token :DQUOTE, /"/ do |lexer, value|
+ lexer.tokenize_interpolated_string(DQ_initial_token_types)
+ end
+
+ TOKENS.add_token :DQCONT, /\}/ do |lexer, value|
+ lexer.tokenize_interpolated_string(DQ_continuation_token_types)
+ end
+ #:stopdoc: # Issue #4161
+ def (TOKENS[:DQCONT]).acceptable?(context={})
+ context[:string_interpolation_depth] > 0
+ end
+ #:startdoc:
+
+ TOKENS.add_token :DOLLAR_VAR, %r{\$(\w*::)*\w+} do |lexer, value|
+ [TOKENS[:VARIABLE],value[1..-1]]
+ end
+
+ TOKENS.add_token :VARIABLE, %r{(\w*::)*\w+}
+ #:stopdoc: # Issue #4161
+ def (TOKENS[:VARIABLE]).acceptable?(context={})
+ [:DQPRE,:DQMID].include? context[:after]
+ end
+ #:startdoc:
+
+
+ TOKENS.sort_tokens
+
+ @@pairs = {
+ "{" => "}",
+ "(" => ")",
+ "[" => "]",
+ "<|" => "|>",
+ "<<|" => "|>>"
+ }
+
+ KEYWORDS = TokenList.new
+
+
+ KEYWORDS.add_tokens(
+
+ "case" => :CASE,
+ "class" => :CLASS,
+ "default" => :DEFAULT,
+ "define" => :DEFINE,
+ "import" => :IMPORT,
+ "if" => :IF,
+ "elsif" => :ELSIF,
+ "else" => :ELSE,
+ "inherits" => :INHERITS,
+ "node" => :NODE,
+ "and" => :AND,
+ "or" => :OR,
+ "undef" => :UNDEF,
+ "false" => :FALSE,
+ "true" => :TRUE,
+
+ "in" => :IN
+ )
+
+ def clear
+ initvars
+ end
+
+ def expected
+ return nil if @expected.empty?
+ name = @expected[-1]
+ TOKENS.lookup(name) or lex_error "Could not find expected token #{name}"
+ end
+
+ # scan the whole file
+ # basically just used for testing
+ def fullscan
+ array = []
+
+ self.scan { |token, str|
+ # Ignore any definition nesting problems
+ @indefine = false
+ array.push([token,str])
}
-
- KEYWORDS = TokenList.new
-
-
- KEYWORDS.add_tokens(
-
- "case" => :CASE,
- "class" => :CLASS,
- "default" => :DEFAULT,
- "define" => :DEFINE,
- "import" => :IMPORT,
- "if" => :IF,
- "elsif" => :ELSIF,
- "else" => :ELSE,
- "inherits" => :INHERITS,
- "node" => :NODE,
- "and" => :AND,
- "or" => :OR,
- "undef" => :UNDEF,
- "false" => :FALSE,
- "true" => :TRUE,
-
- "in" => :IN
- )
-
- def clear
- initvars
- end
-
- def expected
- return nil if @expected.empty?
- name = @expected[-1]
- TOKENS.lookup(name) or lex_error "Could not find expected token #{name}"
- end
-
- # scan the whole file
- # basically just used for testing
- def fullscan
- array = []
-
- self.scan { |token, str|
- # Ignore any definition nesting problems
- @indefine = false
- array.push([token,str])
- }
- array
- end
-
- def file=(file)
- @file = file
- @line = 1
- @scanner = StringScanner.new(File.read(file))
- end
-
- def shift_token
- @token_queue.shift
- end
-
- def find_string_token
- # We know our longest string token is three chars, so try each size in turn
- # until we either match or run out of chars. This way our worst-case is three
- # tries, where it is otherwise the number of string token we have. Also,
- # the lookups are optimized hash lookups, instead of regex scans.
- #
- s = @scanner.peek(3)
- token = TOKENS.lookup(s[0,3]) || TOKENS.lookup(s[0,2]) || TOKENS.lookup(s[0,1])
- [ token, token && @scanner.scan(token.regex) ]
- end
-
- # Find the next token that matches a regex. We look for these first.
- def find_regex_token
- @regex += 1
- best_token = nil
- best_length = 0
-
- # I tried optimizing based on the first char, but it had
- # a slightly negative affect and was a good bit more complicated.
- TOKENS.regex_tokens.each do |token|
- if length = @scanner.match?(token.regex) and token.acceptable?(lexing_context)
- # We've found a longer match
- if length > best_length
- best_length = length
- best_token = token
- end
- end
+ array
+ end
+
+ def file=(file)
+ @file = file
+ @line = 1
+ @scanner = StringScanner.new(File.read(file))
+ end
+
+ def shift_token
+ @token_queue.shift
+ end
+
+ def find_string_token
+ # We know our longest string token is three chars, so try each size in turn
+ # until we either match or run out of chars. This way our worst-case is three
+ # tries, where it is otherwise the number of string token we have. Also,
+ # the lookups are optimized hash lookups, instead of regex scans.
+ #
+ s = @scanner.peek(3)
+ token = TOKENS.lookup(s[0,3]) || TOKENS.lookup(s[0,2]) || TOKENS.lookup(s[0,1])
+ [ token, token && @scanner.scan(token.regex) ]
+ end
+
+ # Find the next token that matches a regex. We look for these first.
+ def find_regex_token
+ @regex += 1
+ best_token = nil
+ best_length = 0
+
+ # I tried optimizing based on the first char, but it had
+ # a slightly negative affect and was a good bit more complicated.
+ TOKENS.regex_tokens.each do |token|
+ if length = @scanner.match?(token.regex) and token.acceptable?(lexing_context)
+ # We've found a longer match
+ if length > best_length
+ best_length = length
+ best_token = token
end
+ end
+ end
- return best_token, @scanner.scan(best_token.regex) if best_token
- end
-
- # Find the next token, returning the string and the token.
- def find_token
- @find += 1
- shift_token || find_regex_token || find_string_token
- end
+ return best_token, @scanner.scan(best_token.regex) if best_token
+ end
- def indefine?
- if defined?(@indefine)
- @indefine
- else
- false
- end
- end
+ # Find the next token, returning the string and the token.
+ def find_token
+ @find += 1
+ shift_token || find_regex_token || find_string_token
+ end
- def initialize
- @find = 0
- @regex = 0
- initvars
+ def indefine?
+ if defined?(@indefine)
+ @indefine
+ else
+ false
end
+ end
- def initvars
- @line = 1
- @previous_token = nil
- @scanner = nil
- @file = nil
- # AAARRGGGG! okay, regexes in ruby are bloody annoying
- # no one else has "\n" =~ /\s/
- @skip = %r{[ \t\r]+}
-
- @namestack = []
- @token_queue = []
- @indefine = false
- @expected = []
- @commentstack = [ ['', @line] ]
- @lexing_context = {
- :after => nil,
- :start_of_line => true,
- :string_interpolation_depth => 0
- }
- end
+ def initialize
+ @find = 0
+ @regex = 0
+ initvars
+ end
- # Make any necessary changes to the token and/or value.
- def munge_token(token, value)
- @line += 1 if token.incr_line
+ def initvars
+ @line = 1
+ @previous_token = nil
+ @scanner = nil
+ @file = nil
+ # AAARRGGGG! okay, regexes in ruby are bloody annoying
+ # no one else has "\n" =~ /\s/
+ @skip = %r{[ \t\r]+}
- skip if token.skip_text
+ @namestack = []
+ @token_queue = []
+ @indefine = false
+ @expected = []
+ @commentstack = [ ['', @line] ]
+ @lexing_context = {
+ :after => nil,
+ :start_of_line => true,
+ :string_interpolation_depth => 0
+ }
+ end
- return if token.skip and not token.accumulate?
+ # Make any necessary changes to the token and/or value.
+ def munge_token(token, value)
+ @line += 1 if token.incr_line
- token, value = token.convert(self, value) if token.respond_to?(:convert)
+ skip if token.skip_text
- return unless token
+ return if token.skip and not token.accumulate?
- if token.accumulate?
- comment = @commentstack.pop
- comment[0] << value + "\n"
- @commentstack.push(comment)
- end
+ token, value = token.convert(self, value) if token.respond_to?(:convert)
- return if token.skip
+ return unless token
- return token, { :value => value, :line => @line }
+ if token.accumulate?
+ comment = @commentstack.pop
+ comment[0] << value + "\n"
+ @commentstack.push(comment)
end
- # Go up one in the namespace.
- def namepop
- @namestack.pop
- end
+ return if token.skip
- # Collect the current namespace.
- def namespace
- @namestack.join("::")
- end
+ return token, { :value => value, :line => @line }
+ end
- # This value might have :: in it, but we don't care -- it'll be
- # handled normally when joining, and when popping we want to pop
- # this full value, however long the namespace is.
- def namestack(value)
- @namestack << value
- end
-
- def rest
- @scanner.rest
- end
-
- # this is the heart of the lexer
- def scan
- #Puppet.debug("entering scan")
- lex_error "Invalid or empty string" unless @scanner
-
- # Skip any initial whitespace.
- skip
+ # Go up one in the namespace.
+ def namepop
+ @namestack.pop
+ end
- until token_queue.empty? and @scanner.eos? do
- yielded = false
- matched_token, value = find_token
+ # Collect the current namespace.
+ def namespace
+ @namestack.join("::")
+ end
- # error out if we didn't match anything at all
- lex_error "Could not match #{@scanner.rest[/^(\S+|\s+|.*)/]}" unless matched_token
+ # This value might have :: in it, but we don't care -- it'll be
+ # handled normally when joining, and when popping we want to pop
+ # this full value, however long the namespace is.
+ def namestack(value)
+ @namestack << value
+ end
- newline = matched_token.name == :RETURN
+ def rest
+ @scanner.rest
+ end
- # this matches a blank line; eat the previously accumulated comments
- getcomment if lexing_context[:start_of_line] and newline
- lexing_context[:start_of_line] = newline
+ # this is the heart of the lexer
+ def scan
+ #Puppet.debug("entering scan")
+ lex_error "Invalid or empty string" unless @scanner
- final_token, token_value = munge_token(matched_token, value)
+ # Skip any initial whitespace.
+ skip
- unless final_token
- skip
- next
- end
+ until token_queue.empty? and @scanner.eos? do
+ yielded = false
+ matched_token, value = find_token
- lexing_context[:after] = final_token.name unless newline
- lexing_context[:string_interpolation_depth] += 1 if final_token.name == :DQPRE
- lexing_context[:string_interpolation_depth] -= 1 if final_token.name == :DQPOST
+ # error out if we didn't match anything at all
+ lex_error "Could not match #{@scanner.rest[/^(\S+|\s+|.*)/]}" unless matched_token
- value = token_value[:value]
+ newline = matched_token.name == :RETURN
+
+ # this matches a blank line; eat the previously accumulated comments
+ getcomment if lexing_context[:start_of_line] and newline
+ lexing_context[:start_of_line] = newline
- if match = @@pairs[value] and final_token.name != :DQUOTE and final_token.name != :SQUOTE
- @expected << match
- elsif exp = @expected[-1] and exp == value and final_token.name != :DQUOTE and final_token.name != :SQUOTE
- @expected.pop
- end
+ final_token, token_value = munge_token(matched_token, value)
- if final_token.name == :LBRACE
- commentpush
- end
-
- yield [final_token.name, token_value]
+ unless final_token
+ skip
+ next
+ end
- if @previous_token
- namestack(value) if @previous_token.name == :CLASS
+ lexing_context[:after] = final_token.name unless newline
+ lexing_context[:string_interpolation_depth] += 1 if final_token.name == :DQPRE
+ lexing_context[:string_interpolation_depth] -= 1 if final_token.name == :DQPOST
- if @previous_token.name == :DEFINE
- if indefine?
- msg = "Cannot nest definition #{value} inside #{@indefine}"
- self.indefine = false
- raise Puppet::ParseError, msg
- end
+ value = token_value[:value]
- @indefine = value
- end
- end
- @previous_token = final_token
- skip
- end
- @scanner = nil
+ if match = @@pairs[value] and final_token.name != :DQUOTE and final_token.name != :SQUOTE
+ @expected << match
+ elsif exp = @expected[-1] and exp == value and final_token.name != :DQUOTE and final_token.name != :SQUOTE
+ @expected.pop
+ end
- # This indicates that we're done parsing.
- yield [false,false]
- end
+ if final_token.name == :LBRACE
+ commentpush
+ end
- # Skip any skipchars in our remaining string.
- def skip
- @scanner.skip(@skip)
- end
+ yield [final_token.name, token_value]
- # Provide some limited access to the scanner, for those
- # tokens that need it.
- def scan_until(regex)
- @scanner.scan_until(regex)
- end
+ if @previous_token
+ namestack(value) if @previous_token.name == :CLASS
- # we've encountered the start of a string...
- # slurp in the rest of the string and return it
- Valid_escapes_in_strings = %w{ \\ $ ' " n t s }+["\n"]
- def slurpstring(terminators)
- # we search for the next quote that isn't preceded by a
- # backslash; the caret is there to match empty strings
- str = @scanner.scan_until(/([^\\]|^)[#{terminators}]/) or lex_error "Unclosed quote after '#{last}' in '#{rest}'"
- @line += str.count("\n") # literal carriage returns add to the line count.
- str.gsub!(/\\(.)/) {
- case ch=$1
- when 'n'; "\n"
- when 't'; "\t"
- when 's'; " "
- else
- if Valid_escapes_in_strings.include? ch and not (ch == '"' and terminators == "'")
- ch
- else
- Puppet.warning "Unrecognised escape sequence '\\#{ch}'#{file && " in file #{file}"}#{line && " at line #{line}"}"
- "\\#{ch}"
- end
- end
- }
- [ str[0..-2],str[-1,1] ]
- end
+ if @previous_token.name == :DEFINE
+ if indefine?
+ msg = "Cannot nest definition #{value} inside #{@indefine}"
+ self.indefine = false
+ raise Puppet::ParseError, msg
+ end
- def tokenize_interpolated_string(token_type)
- value,terminator = slurpstring('"$')
- token_queue << [TOKENS[token_type[terminator]],value]
- while terminator == '$' and not @scanner.scan(/\{/)
- token_queue << [TOKENS[:VARIABLE], at scanner.scan(%r{(\w*::)*\w+|[0-9]})]
- value,terminator = slurpstring('"$')
- token_queue << [TOKENS[DQ_continuation_token_types[terminator]],value]
+ @indefine = value
end
- token_queue.shift
- end
-
- # just parse a string, not a whole file
- def string=(string)
- @scanner = StringScanner.new(string)
- end
-
- # returns the content of the currently accumulated content cache
- def commentpop
- @commentstack.pop[0]
- end
-
- def getcomment(line = nil)
- comment = @commentstack.last
- if line.nil? or comment[1] <= line
- @commentstack.pop
- @commentstack.push(['', @line])
- return comment[0]
+ end
+ @previous_token = final_token
+ skip
+ end
+ @scanner = nil
+
+ # This indicates that we're done parsing.
+ yield [false,false]
+ end
+
+ # Skip any skipchars in our remaining string.
+ def skip
+ @scanner.skip(@skip)
+ end
+
+ # Provide some limited access to the scanner, for those
+ # tokens that need it.
+ def scan_until(regex)
+ @scanner.scan_until(regex)
+ end
+
+ # we've encountered the start of a string...
+ # slurp in the rest of the string and return it
+ Valid_escapes_in_strings = %w{ \\ $ ' " n t s }+["\n"]
+ def slurpstring(terminators)
+ # we search for the next quote that isn't preceded by a
+ # backslash; the caret is there to match empty strings
+ str = @scanner.scan_until(/([^\\]|^)[#{terminators}]/) or lex_error "Unclosed quote after '#{last}' in '#{rest}'"
+ @line += str.count("\n") # literal carriage returns add to the line count.
+ str.gsub!(/\\(.)/) {
+ case ch=$1
+ when 'n'; "\n"
+ when 't'; "\t"
+ when 's'; " "
+ else
+ if Valid_escapes_in_strings.include? ch and not (ch == '"' and terminators == "'")
+ ch
+ else
+ Puppet.warning "Unrecognised escape sequence '\\#{ch}'#{file && " in file #{file}"}#{line && " at line #{line}"}"
+ "\\#{ch}"
end
- ''
- end
-
- def commentpush
- @commentstack.push(['', @line])
- end
+ end
+ }
+ [ str[0..-2],str[-1,1] ]
+ end
+
+ def tokenize_interpolated_string(token_type)
+ value,terminator = slurpstring('"$')
+ token_queue << [TOKENS[token_type[terminator]],value]
+ while terminator == '$' and not @scanner.scan(/\{/)
+ token_queue << [TOKENS[:VARIABLE], at scanner.scan(%r{(\w*::)*\w+|[0-9]})]
+ value,terminator = slurpstring('"$')
+ token_queue << [TOKENS[DQ_continuation_token_types[terminator]],value]
+ end
+ token_queue.shift
+ end
+
+ # just parse a string, not a whole file
+ def string=(string)
+ @scanner = StringScanner.new(string)
+ end
+
+ # returns the content of the currently accumulated content cache
+ def commentpop
+ @commentstack.pop[0]
+ end
+
+ def getcomment(line = nil)
+ comment = @commentstack.last
+ if line.nil? or comment[1] <= line
+ @commentstack.pop
+ @commentstack.push(['', @line])
+ return comment[0]
+ end
+ ''
+ end
+
+ def commentpush
+ @commentstack.push(['', @line])
+ end
end
diff --git a/lib/puppet/parser/parser_support.rb b/lib/puppet/parser/parser_support.rb
index 8dd986b..4f3a4dd 100644
--- a/lib/puppet/parser/parser_support.rb
+++ b/lib/puppet/parser/parser_support.rb
@@ -1,235 +1,235 @@
# I pulled this into a separate file, because I got
# tired of rebuilding the parser.rb file all the time.
class Puppet::Parser::Parser
- require 'puppet/parser/functions'
- require 'puppet/parser/files'
- require 'puppet/resource/type_collection'
- require 'puppet/resource/type_collection_helper'
- require 'puppet/resource/type'
- require 'monitor'
+ require 'puppet/parser/functions'
+ require 'puppet/parser/files'
+ require 'puppet/resource/type_collection'
+ require 'puppet/resource/type_collection_helper'
+ require 'puppet/resource/type'
+ require 'monitor'
- AST = Puppet::Parser::AST
+ AST = Puppet::Parser::AST
- include Puppet::Resource::TypeCollectionHelper
+ include Puppet::Resource::TypeCollectionHelper
- attr_reader :version, :environment
- attr_accessor :files
+ attr_reader :version, :environment
+ attr_accessor :files
- attr_accessor :lexer
-
- # Add context to a message; useful for error messages and such.
- def addcontext(message, obj = nil)
- obj ||= @lexer
-
- message += " on line #{obj.line}"
- if file = obj.file
- message += " in file #{file}"
- end
-
- message
- end
-
- # Create an AST array out of all of the args
- def aryfy(*args)
- if args[0].instance_of?(AST::ASTArray)
- result = args.shift
- args.each { |arg|
- result.push arg
- }
- else
- result = ast AST::ASTArray, :children => args
- end
-
- result
- end
-
- # Create an AST object, and automatically add the file and line information if
- # available.
- def ast(klass, hash = {})
- klass.new ast_context(klass.use_docs).merge(hash)
- end
-
- def ast_context(include_docs = false)
- result = {
- :line => lexer.line,
- :file => lexer.file
- }
- result[:doc] = lexer.getcomment(result[:line]) if include_docs
- result
- end
-
- # The fully qualifed name, with the full namespace.
- def classname(name)
- [@lexer.namespace, name].join("::").sub(/^::/, '')
- end
-
- def clear
- initvars
- end
-
- # Raise a Parse error.
- def error(message)
- if brace = @lexer.expected
- message += "; expected '%s'"
- end
- except = Puppet::ParseError.new(message)
- except.line = @lexer.line
- except.file = @lexer.file if @lexer.file
-
- raise except
- end
-
- def file
- @lexer.file
- end
-
- def file=(file)
- unless FileTest.exist?(file)
- unless file =~ /\.pp$/
- file = file + ".pp"
- end
- raise Puppet::Error, "Could not find file #{file}" unless FileTest.exist?(file)
- end
- raise Puppet::AlreadyImportedError, "Import loop detected" if known_resource_types.watching_file?(file)
-
- watch_file(file)
- @lexer.file = file
- end
-
- [:hostclass, :definition, :node, :nodes?].each do |method|
- define_method(method) do |*args|
- known_resource_types.send(method, *args)
- end
- end
-
- def find_hostclass(namespace, name)
- known_resource_types.find_or_load(namespace, name, :hostclass)
- end
-
- def find_definition(namespace, name)
- known_resource_types.find_or_load(namespace, name, :definition)
- end
-
- def import(file)
- known_resource_types.loader.import(file, @lexer.file)
- end
-
- def initialize(env)
- # The environment is needed to know how to find the resource type collection.
- @environment = env.is_a?(String) ? Puppet::Node::Environment.new(env) : env
- initvars
- end
-
- # Initialize or reset all of our variables.
- def initvars
- @lexer = Puppet::Parser::Lexer.new
- end
-
- # Split an fq name into a namespace and name
- def namesplit(fullname)
- ary = fullname.split("::")
- n = ary.pop || ""
- ns = ary.join("::")
- return ns, n
- end
-
- # Create a new class, or merge with an existing class.
- def newclass(name, options = {})
- known_resource_types.add Puppet::Resource::Type.new(:hostclass, name, ast_context(true).merge(options))
- end
-
- # Create a new definition.
- def newdefine(name, options = {})
- known_resource_types.add Puppet::Resource::Type.new(:definition, name, ast_context(true).merge(options))
- end
-
- # Create a new node. Nodes are special, because they're stored in a global
- # table, not according to namespaces.
- def newnode(names, options = {})
- names = [names] unless names.instance_of?(Array)
- context = ast_context(true)
- names.collect do |name|
- known_resource_types.add(Puppet::Resource::Type.new(:node, name, context.merge(options)))
- end
- end
-
- def on_error(token,value,stack)
- if token == 0 # denotes end of file
- value = 'end of file'
- else
- value = "'#{value[:value]}'"
- end
- error = "Syntax error at #{value}"
-
- if brace = @lexer.expected
- error += "; expected '#{brace}'"
- end
-
- except = Puppet::ParseError.new(error)
- except.line = @lexer.line
- except.file = @lexer.file if @lexer.file
-
- raise except
- end
-
- # how should I do error handling here?
- def parse(string = nil)
- return parse_ruby_file if self.file =~ /\.rb$/
- self.string = string if string
- begin
- @yydebug = false
- main = yyparse(@lexer,:scan)
- rescue Racc::ParseError => except
- error = Puppet::ParseError.new(except)
- error.line = @lexer.line
- error.file = @lexer.file
- error.set_backtrace except.backtrace
- raise error
- rescue Puppet::ParseError => except
- except.line ||= @lexer.line
- except.file ||= @lexer.file
- raise except
- rescue Puppet::Error => except
- # and this is a framework error
- except.line ||= @lexer.line
- except.file ||= @lexer.file
- raise except
- rescue Puppet::DevError => except
- except.line ||= @lexer.line
- except.file ||= @lexer.file
- raise except
- rescue => except
- error = Puppet::DevError.new(except.message)
- error.line = @lexer.line
- error.file = @lexer.file
- error.set_backtrace except.backtrace
- raise error
- end
- if main
- # Store the results as the top-level class.
- newclass("", :code => main)
- end
- return known_resource_types
- ensure
- @lexer.clear
- end
-
- def parse_ruby_file
- require self.file
- end
-
- def string=(string)
- @lexer.string = string
- end
-
- def version
- known_resource_types.version
- end
-
- # Add a new file to be checked when we're checking to see if we should be
- # reparsed. This is basically only used by the TemplateWrapper to let the
- # parser know about templates that should be parsed.
- def watch_file(filename)
- known_resource_types.watch_file(filename)
- end
+ attr_accessor :lexer
+
+ # Add context to a message; useful for error messages and such.
+ def addcontext(message, obj = nil)
+ obj ||= @lexer
+
+ message += " on line #{obj.line}"
+ if file = obj.file
+ message += " in file #{file}"
+ end
+
+ message
+ end
+
+ # Create an AST array out of all of the args
+ def aryfy(*args)
+ if args[0].instance_of?(AST::ASTArray)
+ result = args.shift
+ args.each { |arg|
+ result.push arg
+ }
+ else
+ result = ast AST::ASTArray, :children => args
+ end
+
+ result
+ end
+
+ # Create an AST object, and automatically add the file and line information if
+ # available.
+ def ast(klass, hash = {})
+ klass.new ast_context(klass.use_docs).merge(hash)
+ end
+
+ def ast_context(include_docs = false)
+ result = {
+ :line => lexer.line,
+ :file => lexer.file
+ }
+ result[:doc] = lexer.getcomment(result[:line]) if include_docs
+ result
+ end
+
+ # The fully qualifed name, with the full namespace.
+ def classname(name)
+ [@lexer.namespace, name].join("::").sub(/^::/, '')
+ end
+
+ def clear
+ initvars
+ end
+
+ # Raise a Parse error.
+ def error(message)
+ if brace = @lexer.expected
+ message += "; expected '%s'"
+ end
+ except = Puppet::ParseError.new(message)
+ except.line = @lexer.line
+ except.file = @lexer.file if @lexer.file
+
+ raise except
+ end
+
+ def file
+ @lexer.file
+ end
+
+ def file=(file)
+ unless FileTest.exist?(file)
+ unless file =~ /\.pp$/
+ file = file + ".pp"
+ end
+ raise Puppet::Error, "Could not find file #{file}" unless FileTest.exist?(file)
+ end
+ raise Puppet::AlreadyImportedError, "Import loop detected" if known_resource_types.watching_file?(file)
+
+ watch_file(file)
+ @lexer.file = file
+ end
+
+ [:hostclass, :definition, :node, :nodes?].each do |method|
+ define_method(method) do |*args|
+ known_resource_types.send(method, *args)
+ end
+ end
+
+ def find_hostclass(namespace, name)
+ known_resource_types.find_or_load(namespace, name, :hostclass)
+ end
+
+ def find_definition(namespace, name)
+ known_resource_types.find_or_load(namespace, name, :definition)
+ end
+
+ def import(file)
+ known_resource_types.loader.import(file, @lexer.file)
+ end
+
+ def initialize(env)
+ # The environment is needed to know how to find the resource type collection.
+ @environment = env.is_a?(String) ? Puppet::Node::Environment.new(env) : env
+ initvars
+ end
+
+ # Initialize or reset all of our variables.
+ def initvars
+ @lexer = Puppet::Parser::Lexer.new
+ end
+
+ # Split an fq name into a namespace and name
+ def namesplit(fullname)
+ ary = fullname.split("::")
+ n = ary.pop || ""
+ ns = ary.join("::")
+ return ns, n
+ end
+
+ # Create a new class, or merge with an existing class.
+ def newclass(name, options = {})
+ known_resource_types.add Puppet::Resource::Type.new(:hostclass, name, ast_context(true).merge(options))
+ end
+
+ # Create a new definition.
+ def newdefine(name, options = {})
+ known_resource_types.add Puppet::Resource::Type.new(:definition, name, ast_context(true).merge(options))
+ end
+
+ # Create a new node. Nodes are special, because they're stored in a global
+ # table, not according to namespaces.
+ def newnode(names, options = {})
+ names = [names] unless names.instance_of?(Array)
+ context = ast_context(true)
+ names.collect do |name|
+ known_resource_types.add(Puppet::Resource::Type.new(:node, name, context.merge(options)))
+ end
+ end
+
+ def on_error(token,value,stack)
+ if token == 0 # denotes end of file
+ value = 'end of file'
+ else
+ value = "'#{value[:value]}'"
+ end
+ error = "Syntax error at #{value}"
+
+ if brace = @lexer.expected
+ error += "; expected '#{brace}'"
+ end
+
+ except = Puppet::ParseError.new(error)
+ except.line = @lexer.line
+ except.file = @lexer.file if @lexer.file
+
+ raise except
+ end
+
+ # how should I do error handling here?
+ def parse(string = nil)
+ return parse_ruby_file if self.file =~ /\.rb$/
+ self.string = string if string
+ begin
+ @yydebug = false
+ main = yyparse(@lexer,:scan)
+ rescue Racc::ParseError => except
+ error = Puppet::ParseError.new(except)
+ error.line = @lexer.line
+ error.file = @lexer.file
+ error.set_backtrace except.backtrace
+ raise error
+ rescue Puppet::ParseError => except
+ except.line ||= @lexer.line
+ except.file ||= @lexer.file
+ raise except
+ rescue Puppet::Error => except
+ # and this is a framework error
+ except.line ||= @lexer.line
+ except.file ||= @lexer.file
+ raise except
+ rescue Puppet::DevError => except
+ except.line ||= @lexer.line
+ except.file ||= @lexer.file
+ raise except
+ rescue => except
+ error = Puppet::DevError.new(except.message)
+ error.line = @lexer.line
+ error.file = @lexer.file
+ error.set_backtrace except.backtrace
+ raise error
+ end
+ if main
+ # Store the results as the top-level class.
+ newclass("", :code => main)
+ end
+ return known_resource_types
+ ensure
+ @lexer.clear
+ end
+
+ def parse_ruby_file
+ require self.file
+ end
+
+ def string=(string)
+ @lexer.string = string
+ end
+
+ def version
+ known_resource_types.version
+ end
+
+ # Add a new file to be checked when we're checking to see if we should be
+ # reparsed. This is basically only used by the TemplateWrapper to let the
+ # parser know about templates that should be parsed.
+ def watch_file(filename)
+ known_resource_types.watch_file(filename)
+ end
end
diff --git a/lib/puppet/parser/relationship.rb b/lib/puppet/parser/relationship.rb
index 1d1bad7..6190df5 100644
--- a/lib/puppet/parser/relationship.rb
+++ b/lib/puppet/parser/relationship.rb
@@ -1,43 +1,43 @@
class Puppet::Parser::Relationship
- attr_accessor :source, :target, :type
+ attr_accessor :source, :target, :type
- PARAM_MAP = {:relationship => :before, :subscription => :notify}
+ PARAM_MAP = {:relationship => :before, :subscription => :notify}
- def evaluate(catalog)
- if source.is_a?(Puppet::Parser::Collector)
- sources = source.collected.values
- else
- sources = [source]
- end
- if target.is_a?(Puppet::Parser::Collector)
- targets = target.collected.values
- else
- targets = [target]
- end
- sources.each do |s|
- targets.each do |t|
- mk_relationship(s, t, catalog)
- end
- end
+ def evaluate(catalog)
+ if source.is_a?(Puppet::Parser::Collector)
+ sources = source.collected.values
+ else
+ sources = [source]
end
-
- def initialize(source, target, type)
- @source, @target, @type = source, target, type
+ if target.is_a?(Puppet::Parser::Collector)
+ targets = target.collected.values
+ else
+ targets = [target]
end
-
- def param_name
- PARAM_MAP[type] || raise(ArgumentError, "Invalid relationship type #{type}")
+ sources.each do |s|
+ targets.each do |t|
+ mk_relationship(s, t, catalog)
+ end
end
+ end
+
+ def initialize(source, target, type)
+ @source, @target, @type = source, target, type
+ end
- def mk_relationship(source, target, catalog)
- unless source_resource = catalog.resource(source.to_s)
- raise ArgumentError, "Could not find resource '#{source}' for relationship on '#{target}'"
- end
- unless target_resource = catalog.resource(target.to_s)
- raise ArgumentError, "Could not find resource '#{target}' for relationship from '#{source}'"
- end
- Puppet.debug "Adding relationship from #{source.to_s} to #{target.to_s} with '#{param_name}'"
- source_resource[param_name] ||= []
- source_resource[param_name] << target.to_s
+ def param_name
+ PARAM_MAP[type] || raise(ArgumentError, "Invalid relationship type #{type}")
+ end
+
+ def mk_relationship(source, target, catalog)
+ unless source_resource = catalog.resource(source.to_s)
+ raise ArgumentError, "Could not find resource '#{source}' for relationship on '#{target}'"
+ end
+ unless target_resource = catalog.resource(target.to_s)
+ raise ArgumentError, "Could not find resource '#{target}' for relationship from '#{source}'"
end
+ Puppet.debug "Adding relationship from #{source.to_s} to #{target.to_s} with '#{param_name}'"
+ source_resource[param_name] ||= []
+ source_resource[param_name] << target.to_s
+ end
end
diff --git a/lib/puppet/parser/resource.rb b/lib/puppet/parser/resource.rb
index 2d31b40..3cccf4f 100644
--- a/lib/puppet/parser/resource.rb
+++ b/lib/puppet/parser/resource.rb
@@ -4,323 +4,323 @@ require 'puppet/resource'
# parent is that this class has rules on who can set
# parameters
class Puppet::Parser::Resource < Puppet::Resource
- require 'puppet/parser/resource/param'
- require 'puppet/util/tagging'
- require 'puppet/file_collection/lookup'
- require 'puppet/parser/yaml_trimmer'
- require 'puppet/resource/type_collection_helper'
-
- include Puppet::FileCollection::Lookup
- include Puppet::Resource::TypeCollectionHelper
-
- include Puppet::Util
- include Puppet::Util::MethodHelper
- include Puppet::Util::Errors
- include Puppet::Util::Logging
- include Puppet::Util::Tagging
- include Puppet::Parser::YamlTrimmer
-
- attr_accessor :source, :scope, :rails_id
- attr_accessor :virtual, :override, :translated, :catalog, :evaluated
-
- attr_reader :exported, :parameters
-
- # Determine whether the provided parameter name is a relationship parameter.
- def self.relationship_parameter?(name)
- @relationship_names ||= Puppet::Type.relationship_params.collect { |p| p.name }
- @relationship_names.include?(name)
+ require 'puppet/parser/resource/param'
+ require 'puppet/util/tagging'
+ require 'puppet/file_collection/lookup'
+ require 'puppet/parser/yaml_trimmer'
+ require 'puppet/resource/type_collection_helper'
+
+ include Puppet::FileCollection::Lookup
+ include Puppet::Resource::TypeCollectionHelper
+
+ include Puppet::Util
+ include Puppet::Util::MethodHelper
+ include Puppet::Util::Errors
+ include Puppet::Util::Logging
+ include Puppet::Util::Tagging
+ include Puppet::Parser::YamlTrimmer
+
+ attr_accessor :source, :scope, :rails_id
+ attr_accessor :virtual, :override, :translated, :catalog, :evaluated
+
+ attr_reader :exported, :parameters
+
+ # Determine whether the provided parameter name is a relationship parameter.
+ def self.relationship_parameter?(name)
+ @relationship_names ||= Puppet::Type.relationship_params.collect { |p| p.name }
+ @relationship_names.include?(name)
+ end
+
+ # Set up some boolean test methods
+ [:translated, :override, :evaluated].each do |method|
+ newmeth = (method.to_s + "?").intern
+ define_method(newmeth) do
+ self.send(method)
end
+ end
- # Set up some boolean test methods
- [:translated, :override, :evaluated].each do |method|
- newmeth = (method.to_s + "?").intern
- define_method(newmeth) do
- self.send(method)
- end
- end
-
- def [](param)
- param = symbolize(param)
- if param == :title
- return self.title
- end
- if @parameters.has_key?(param)
- @parameters[param].value
- else
- nil
- end
- end
-
- def []=(param, value)
- set_parameter(param, value)
+ def [](param)
+ param = symbolize(param)
+ if param == :title
+ return self.title
end
-
- def eachparam
- @parameters.each do |name, param|
- yield param
- end
+ if @parameters.has_key?(param)
+ @parameters[param].value
+ else
+ nil
end
+ end
- def environment
- scope.environment
- end
+ def []=(param, value)
+ set_parameter(param, value)
+ end
- # Retrieve the associated definition and evaluate it.
- def evaluate
- if klass = resource_type and ! builtin_type?
- finish
- return klass.evaluate_code(self)
- elsif builtin?
- devfail "Cannot evaluate a builtin type (#{type})"
- else
- self.fail "Cannot find definition #{type}"
- end
- ensure
- @evaluated = true
+ def eachparam
+ @parameters.each do |name, param|
+ yield param
end
-
- # Mark this resource as both exported and virtual,
- # or remove the exported mark.
- def exported=(value)
- if value
- @virtual = true
- @exported = value
- else
- @exported = value
- end
+ end
+
+ def environment
+ scope.environment
+ end
+
+ # Retrieve the associated definition and evaluate it.
+ def evaluate
+ if klass = resource_type and ! builtin_type?
+ finish
+ return klass.evaluate_code(self)
+ elsif builtin?
+ devfail "Cannot evaluate a builtin type (#{type})"
+ else
+ self.fail "Cannot find definition #{type}"
end
-
- # Do any finishing work on this object, called before evaluation or
- # before storage/translation.
- def finish
- return if finished?
- @finished = true
- add_defaults
- add_metaparams
- validate
+ ensure
+ @evaluated = true
+ end
+
+ # Mark this resource as both exported and virtual,
+ # or remove the exported mark.
+ def exported=(value)
+ if value
+ @virtual = true
+ @exported = value
+ else
+ @exported = value
end
-
- # Has this resource already been finished?
- def finished?
- @finished
+ end
+
+ # Do any finishing work on this object, called before evaluation or
+ # before storage/translation.
+ def finish
+ return if finished?
+ @finished = true
+ add_defaults
+ add_metaparams
+ validate
+ end
+
+ # Has this resource already been finished?
+ def finished?
+ @finished
+ end
+
+ def initialize(*args)
+ super
+
+ raise ArgumentError, "Resources require a scope" unless scope
+ @source ||= scope.source
+ end
+
+ # Is this resource modeling an isomorphic resource type?
+ def isomorphic?
+ if builtin_type?
+ return resource_type.isomorphic?
+ else
+ return true
end
-
- def initialize(*args)
- super
-
- raise ArgumentError, "Resources require a scope" unless scope
- @source ||= scope.source
+ end
+
+ # Merge an override resource in. This will throw exceptions if
+ # any overrides aren't allowed.
+ def merge(resource)
+ # Test the resource scope, to make sure the resource is even allowed
+ # to override.
+ unless self.source.object_id == resource.source.object_id || resource.source.child_of?(self.source)
+ raise Puppet::ParseError.new("Only subclasses can override parameters", resource.line, resource.file)
end
-
- # Is this resource modeling an isomorphic resource type?
- def isomorphic?
- if builtin_type?
- return resource_type.isomorphic?
- else
- return true
- end
+ # Some of these might fail, but they'll fail in the way we want.
+ resource.parameters.each do |name, param|
+ override_parameter(param)
end
-
- # Merge an override resource in. This will throw exceptions if
- # any overrides aren't allowed.
- def merge(resource)
- # Test the resource scope, to make sure the resource is even allowed
- # to override.
- unless self.source.object_id == resource.source.object_id || resource.source.child_of?(self.source)
- raise Puppet::ParseError.new("Only subclasses can override parameters", resource.line, resource.file)
- end
- # Some of these might fail, but they'll fail in the way we want.
- resource.parameters.each do |name, param|
- override_parameter(param)
- end
+ end
+
+ # Unless we're running >= 0.25, we're in compat mode.
+ def metaparam_compatibility_mode?
+ ! (catalog and ver = (catalog.client_version||'0.0.0').split(".") and (ver[0] > "0" or ver[1].to_i >= 25))
+ end
+
+ def name
+ self[:name] || self.title
+ end
+
+ def namespaces
+ scope.namespaces
+ end
+
+ # A temporary occasion, until I get paths in the scopes figured out.
+ def path
+ to_s
+ end
+
+ # Define a parameter in our resource.
+ # if we ever receive a parameter named 'tag', set
+ # the resource tags with its value.
+ def set_parameter(param, value = nil)
+ if ! value.nil?
+ param = Puppet::Parser::Resource::Param.new(
+ :name => param, :value => value, :source => self.source
+ )
+ elsif ! param.is_a?(Puppet::Parser::Resource::Param)
+ raise ArgumentError, "Must pass a parameter or all necessary values"
end
- # Unless we're running >= 0.25, we're in compat mode.
- def metaparam_compatibility_mode?
- ! (catalog and ver = (catalog.client_version||'0.0.0').split(".") and (ver[0] > "0" or ver[1].to_i >= 25))
- end
+ tag(*param.value) if param.name == :tag
- def name
- self[:name] || self.title
- end
+ # And store it in our parameter hash.
+ @parameters[param.name] = param
+ end
- def namespaces
- scope.namespaces
+ def to_hash
+ @parameters.inject({}) do |hash, ary|
+ param = ary[1]
+ # Skip "undef" values.
+ hash[param.name] = param.value if param.value != :undef
+ hash
end
-
- # A temporary occasion, until I get paths in the scopes figured out.
- def path
- to_s
- end
-
- # Define a parameter in our resource.
- # if we ever receive a parameter named 'tag', set
- # the resource tags with its value.
- def set_parameter(param, value = nil)
- if ! value.nil?
- param = Puppet::Parser::Resource::Param.new(
- :name => param, :value => value, :source => self.source
- )
- elsif ! param.is_a?(Puppet::Parser::Resource::Param)
- raise ArgumentError, "Must pass a parameter or all necessary values"
+ end
+
+
+ # Create a Puppet::Resource instance from this parser resource.
+ # We plan, at some point, on not needing to do this conversion, but
+ # it's sufficient for now.
+ def to_resource
+ result = Puppet::Resource.new(type, title)
+
+ to_hash.each do |p, v|
+ if v.is_a?(Puppet::Resource)
+ v = Puppet::Resource.new(v.type, v.title)
+ elsif v.is_a?(Array)
+ # flatten resource references arrays
+ v = v.flatten if v.flatten.find { |av| av.is_a?(Puppet::Resource) }
+ v = v.collect do |av|
+ av = Puppet::Resource.new(av.type, av.title) if av.is_a?(Puppet::Resource)
+ av
end
-
- tag(*param.value) if param.name == :tag
-
- # And store it in our parameter hash.
- @parameters[param.name] = param
+ end
+
+ # If the value is an array with only one value, then
+ # convert it to a single value. This is largely so that
+ # the database interaction doesn't have to worry about
+ # whether it returns an array or a string.
+ result[p] = if v.is_a?(Array) and v.length == 1
+ v[0]
+ else
+ v
+ end
end
- def to_hash
- @parameters.inject({}) do |hash, ary|
- param = ary[1]
- # Skip "undef" values.
- hash[param.name] = param.value if param.value != :undef
- hash
- end
- end
+ result.file = self.file
+ result.line = self.line
+ result.exported = self.exported
+ result.virtual = self.virtual
+ result.tag(*self.tags)
+ result
+ end
- # Create a Puppet::Resource instance from this parser resource.
- # We plan, at some point, on not needing to do this conversion, but
- # it's sufficient for now.
- def to_resource
- result = Puppet::Resource.new(type, title)
-
- to_hash.each do |p, v|
- if v.is_a?(Puppet::Resource)
- v = Puppet::Resource.new(v.type, v.title)
- elsif v.is_a?(Array)
- # flatten resource references arrays
- v = v.flatten if v.flatten.find { |av| av.is_a?(Puppet::Resource) }
- v = v.collect do |av|
- av = Puppet::Resource.new(av.type, av.title) if av.is_a?(Puppet::Resource)
- av
- end
- end
-
- # If the value is an array with only one value, then
- # convert it to a single value. This is largely so that
- # the database interaction doesn't have to worry about
- # whether it returns an array or a string.
- result[p] = if v.is_a?(Array) and v.length == 1
- v[0]
- else
- v
- end
- end
+ # Translate our object to a transportable object.
+ def to_trans
+ return nil if virtual?
- result.file = self.file
- result.line = self.line
- result.exported = self.exported
- result.virtual = self.virtual
- result.tag(*self.tags)
+ to_resource.to_trans
+ end
- result
- end
+ # Convert this resource to a RAL resource. We hackishly go via the
+ # transportable stuff.
+ def to_ral
+ to_resource.to_ral
+ end
- # Translate our object to a transportable object.
- def to_trans
- return nil if virtual?
+ private
- to_resource.to_trans
- end
+ # Add default values from our definition.
+ def add_defaults
+ scope.lookupdefaults(self.type).each do |name, param|
+ unless @parameters.include?(name)
+ self.debug "Adding default for #{name}"
- # Convert this resource to a RAL resource. We hackishly go via the
- # transportable stuff.
- def to_ral
- to_resource.to_ral
+ @parameters[name] = param.dup
+ end
end
+ end
- private
+ def add_backward_compatible_relationship_param(name)
+ # Skip metaparams for which we get no value.
+ return unless val = scope.lookupvar(name.to_s, false) and val != :undefined
- # Add default values from our definition.
- def add_defaults
- scope.lookupdefaults(self.type).each do |name, param|
- unless @parameters.include?(name)
- self.debug "Adding default for #{name}"
+ # The default case: just set the value
+ set_parameter(name, val) and return unless @parameters[name]
- @parameters[name] = param.dup
- end
- end
- end
+ # For relationship params, though, join the values (a la #446).
+ @parameters[name].value = [@parameters[name].value, val].flatten
+ end
- def add_backward_compatible_relationship_param(name)
- # Skip metaparams for which we get no value.
- return unless val = scope.lookupvar(name.to_s, false) and val != :undefined
+ # Add any metaparams defined in our scope. This actually adds any metaparams
+ # from any parent scope, and there's currently no way to turn that off.
+ def add_metaparams
+ compat_mode = metaparam_compatibility_mode?
- # The default case: just set the value
- set_parameter(name, val) and return unless @parameters[name]
-
- # For relationship params, though, join the values (a la #446).
- @parameters[name].value = [@parameters[name].value, val].flatten
+ Puppet::Type.eachmetaparam do |name|
+ next unless self.class.relationship_parameter?(name)
+ add_backward_compatible_relationship_param(name) if compat_mode
end
-
- # Add any metaparams defined in our scope. This actually adds any metaparams
- # from any parent scope, and there's currently no way to turn that off.
- def add_metaparams
- compat_mode = metaparam_compatibility_mode?
-
- Puppet::Type.eachmetaparam do |name|
- next unless self.class.relationship_parameter?(name)
- add_backward_compatible_relationship_param(name) if compat_mode
- end
+ end
+
+ # Accept a parameter from an override.
+ def override_parameter(param)
+ # This can happen if the override is defining a new parameter, rather
+ # than replacing an existing one.
+ (set_parameter(param) and return) unless current = @parameters[param.name]
+
+ # The parameter is already set. Fail if they're not allowed to override it.
+ unless param.source.child_of?(current.source)
+ puts caller if Puppet[:trace]
+ msg = "Parameter '#{param.name}' is already set on #{self}"
+ msg += " by #{current.source}" if current.source.to_s != ""
+ if current.file or current.line
+ fields = []
+ fields << current.file if current.file
+ fields << current.line.to_s if current.line
+ msg += " at #{fields.join(":")}"
+ end
+ msg += "; cannot redefine"
+ raise Puppet::ParseError.new(msg, param.line, param.file)
end
- # Accept a parameter from an override.
- def override_parameter(param)
- # This can happen if the override is defining a new parameter, rather
- # than replacing an existing one.
- (set_parameter(param) and return) unless current = @parameters[param.name]
-
- # The parameter is already set. Fail if they're not allowed to override it.
- unless param.source.child_of?(current.source)
- puts caller if Puppet[:trace]
- msg = "Parameter '#{param.name}' is already set on #{self}"
- msg += " by #{current.source}" if current.source.to_s != ""
- if current.file or current.line
- fields = []
- fields << current.file if current.file
- fields << current.line.to_s if current.line
- msg += " at #{fields.join(":")}"
- end
- msg += "; cannot redefine"
- raise Puppet::ParseError.new(msg, param.line, param.file)
- end
-
- # If we've gotten this far, we're allowed to override.
-
- # Merge with previous value, if the parameter was generated with the +>
- # syntax. It's important that we use a copy of the new param instance
- # here, not the old one, and not the original new one, so that the source
- # is registered correctly for later overrides but the values aren't
- # implcitly shared when multiple resources are overrriden at once (see
- # ticket #3556).
- if param.add
- param = param.dup
- param.value = [current.value, param.value].flatten
- end
-
- set_parameter(param)
+ # If we've gotten this far, we're allowed to override.
+
+ # Merge with previous value, if the parameter was generated with the +>
+ # syntax. It's important that we use a copy of the new param instance
+ # here, not the old one, and not the original new one, so that the source
+ # is registered correctly for later overrides but the values aren't
+ # implcitly shared when multiple resources are overrriden at once (see
+ # ticket #3556).
+ if param.add
+ param = param.dup
+ param.value = [current.value, param.value].flatten
end
- # Make sure the resource's parameters are all valid for the type.
- def validate
- @parameters.each do |name, param|
- validate_parameter(name)
- end
- rescue => detail
- fail Puppet::ParseError, detail.to_s
+ set_parameter(param)
+ end
+
+ # Make sure the resource's parameters are all valid for the type.
+ def validate
+ @parameters.each do |name, param|
+ validate_parameter(name)
end
+ rescue => detail
+ fail Puppet::ParseError, detail.to_s
+ end
- private
+ private
- def extract_parameters(params)
- params.each do |param|
- # Don't set the same parameter twice
- self.fail Puppet::ParseError, "Duplicate parameter '#{param.name}' for on #{self}" if @parameters[param.name]
+ def extract_parameters(params)
+ params.each do |param|
+ # Don't set the same parameter twice
+ self.fail Puppet::ParseError, "Duplicate parameter '#{param.name}' for on #{self}" if @parameters[param.name]
- set_parameter(param)
- end
+ set_parameter(param)
end
+ end
end
diff --git a/lib/puppet/parser/resource/param.rb b/lib/puppet/parser/resource/param.rb
index 7ca240d..af2d98f 100644
--- a/lib/puppet/parser/resource/param.rb
+++ b/lib/puppet/parser/resource/param.rb
@@ -3,25 +3,25 @@ require 'puppet/parser/yaml_trimmer'
# The parameters we stick in Resources.
class Puppet::Parser::Resource::Param
- attr_accessor :name, :value, :source, :add
- include Puppet::Util
- include Puppet::Util::Errors
- include Puppet::Util::MethodHelper
+ attr_accessor :name, :value, :source, :add
+ include Puppet::Util
+ include Puppet::Util::Errors
+ include Puppet::Util::MethodHelper
- include Puppet::FileCollection::Lookup
- include Puppet::Parser::YamlTrimmer
+ include Puppet::FileCollection::Lookup
+ include Puppet::Parser::YamlTrimmer
- def initialize(hash)
- set_options(hash)
- requiredopts(:name, :value, :source)
- @name = symbolize(@name)
- end
+ def initialize(hash)
+ set_options(hash)
+ requiredopts(:name, :value, :source)
+ @name = symbolize(@name)
+ end
- def line_to_i
- line ? Integer(line) : nil
- end
+ def line_to_i
+ line ? Integer(line) : nil
+ end
- def to_s
- "#{self.name} => #{self.value}"
- end
+ def to_s
+ "#{self.name} => #{self.value}"
+ end
end
diff --git a/lib/puppet/parser/scope.rb b/lib/puppet/parser/scope.rb
index 9b49ab6..ae0f9ea 100644
--- a/lib/puppet/parser/scope.rb
+++ b/lib/puppet/parser/scope.rb
@@ -9,475 +9,475 @@ require 'strscan'
require 'puppet/resource/type_collection_helper'
class Puppet::Parser::Scope
- include Puppet::Resource::TypeCollectionHelper
- require 'puppet/parser/resource'
-
- AST = Puppet::Parser::AST
-
- Puppet::Util.logmethods(self)
-
- include Enumerable
- include Puppet::Util::Errors
- attr_accessor :level, :source, :resource
- attr_accessor :base, :keyword
- attr_accessor :top, :translated, :compiler
- attr_accessor :parent
- attr_reader :namespaces
-
- # thin wrapper around an ephemeral
- # symbol table.
- # when a symbol
- class Ephemeral
- def initialize(parent=nil)
- @symbols = {}
- @parent = parent
+ include Puppet::Resource::TypeCollectionHelper
+ require 'puppet/parser/resource'
+
+ AST = Puppet::Parser::AST
+
+ Puppet::Util.logmethods(self)
+
+ include Enumerable
+ include Puppet::Util::Errors
+ attr_accessor :level, :source, :resource
+ attr_accessor :base, :keyword
+ attr_accessor :top, :translated, :compiler
+ attr_accessor :parent
+ attr_reader :namespaces
+
+ # thin wrapper around an ephemeral
+ # symbol table.
+ # when a symbol
+ class Ephemeral
+ def initialize(parent=nil)
+ @symbols = {}
+ @parent = parent
+ end
+
+ [:include?, :delete, :[]=].each do |m|
+ define_method(m) do |*args|
+ @symbols.send(m, *args)
+ end
+ end
+
+ def [](name)
+ unless @symbols.include?(name) or @parent.nil?
+ @parent[name]
+ else
+ @symbols[name]
+ end
+ end
+ end
+
+ # A demeterific shortcut to the catalog.
+ def catalog
+ compiler.catalog
+ end
+
+ def environment
+ compiler.environment
+ end
+
+ # Proxy accessors
+ def host
+ @compiler.node.name
+ end
+
+ # Is the value true? This allows us to control the definition of truth
+ # in one place.
+ def self.true?(value)
+ (value != false and value != "" and value != :undef)
+ end
+
+ # Is the value a number?, return the correct object or nil if not a number
+ def self.number?(value)
+ return nil unless value.is_a?(Fixnum) or value.is_a?(Bignum) or value.is_a?(Float) or value.is_a?(String)
+
+ if value.is_a?(String)
+ if value =~ /^-?\d+(:?\.\d+|(:?\.\d+)?e\d+)$/
+ return value.to_f
+ elsif value =~ /^0x[0-9a-f]+$/i
+ return value.to_i(16)
+ elsif value =~ /^0[0-7]+$/
+ return value.to_i(8)
+ elsif value =~ /^-?\d+$/
+ return value.to_i
+ else
+ return nil
+ end
+ end
+ # it is one of Fixnum,Bignum or Float
+ value
+ end
+
+ # Add to our list of namespaces.
+ def add_namespace(ns)
+ return false if @namespaces.include?(ns)
+ if @namespaces == [""]
+ @namespaces = [ns]
+ else
+ @namespaces << ns
+ end
+ end
+
+ # Remove this when rebasing
+ def environment
+ compiler.environment
+ end
+
+ # Are we the top scope?
+ def topscope?
+ @level == 1
+ end
+
+ def find_hostclass(name)
+ known_resource_types.find_hostclass(namespaces, name)
+ end
+
+ def find_definition(name)
+ known_resource_types.find_definition(namespaces, name)
+ end
+
+ def findresource(string, name = nil)
+ compiler.findresource(string, name)
+ end
+
+ # Initialize our new scope. Defaults to having no parent.
+ def initialize(hash = {})
+ if hash.include?(:namespace)
+ if n = hash[:namespace]
+ @namespaces = [n]
+ end
+ hash.delete(:namespace)
+ else
+ @namespaces = [""]
+ end
+ hash.each { |name, val|
+ method = name.to_s + "="
+ if self.respond_to? method
+ self.send(method, val)
+ else
+ raise Puppet::DevError, "Invalid scope argument #{name}"
+ end
+ }
+
+ extend_with_functions_module
+
+ @tags = []
+
+ # The symbol table for this scope. This is where we store variables.
+ @symtable = {}
+
+ # the ephemeral symbol tables
+ # those should not persist long, and are used for the moment only
+ # for $0..$xy capture variables of regexes
+ # this is actually implemented as a stack, with each ephemeral scope
+ # shadowing the previous one
+ @ephemeral = [ Ephemeral.new ]
+
+ # All of the defaults set for types. It's a hash of hashes,
+ # with the first key being the type, then the second key being
+ # the parameter.
+ @defaults = Hash.new { |dhash,type|
+ dhash[type] = {}
+ }
+
+ # The table for storing class singletons. This will only actually
+ # be used by top scopes and node scopes.
+ @class_scopes = {}
+ end
+
+ # Store the fact that we've evaluated a class, and store a reference to
+ # the scope in which it was evaluated, so that we can look it up later.
+ def class_set(name, scope)
+ return parent.class_set(name,scope) if parent
+ @class_scopes[name] = scope
+ end
+
+ # Return the scope associated with a class. This is just here so
+ # that subclasses can set their parent scopes to be the scope of
+ # their parent class, and it's also used when looking up qualified
+ # variables.
+ def class_scope(klass)
+ # They might pass in either the class or class name
+ k = klass.respond_to?(:name) ? klass.name : klass
+ @class_scopes[k] || (parent && parent.class_scope(k))
+ end
+
+ # Collect all of the defaults set at any higher scopes.
+ # This is a different type of lookup because it's additive --
+ # it collects all of the defaults, with defaults in closer scopes
+ # overriding those in later scopes.
+ def lookupdefaults(type)
+ values = {}
+
+ # first collect the values from the parents
+ unless parent.nil?
+ parent.lookupdefaults(type).each { |var,value|
+ values[var] = value
+ }
+ end
+
+ # then override them with any current values
+ # this should probably be done differently
+ if @defaults.include?(type)
+ @defaults[type].each { |var,value|
+ values[var] = value
+ }
+ end
+
+ #Puppet.debug "Got defaults for %s: %s" %
+ # [type,values.inspect]
+ values
+ end
+
+ # Look up a defined type.
+ def lookuptype(name)
+ find_definition(name) || find_hostclass(name)
+ end
+
+ def lookup_qualified_var(name, usestring)
+ parts = name.split(/::/)
+ shortname = parts.pop
+ klassname = parts.join("::")
+ klass = find_hostclass(klassname)
+ unless klass
+ warning "Could not look up qualified variable '#{name}'; class #{klassname} could not be found"
+ return usestring ? "" : :undefined
+ end
+ unless kscope = class_scope(klass)
+ warning "Could not look up qualified variable '#{name}'; class #{klassname} has not been evaluated"
+ return usestring ? "" : :undefined
+ end
+ kscope.lookupvar(shortname, usestring)
+ end
+
+ private :lookup_qualified_var
+
+ # Look up a variable. The simplest value search we do. Default to returning
+ # an empty string for missing values, but support returning a constant.
+ def lookupvar(name, usestring = true)
+ table = ephemeral?(name) ? @ephemeral.last : @symtable
+ # If the variable is qualified, then find the specified scope and look the variable up there instead.
+ if name =~ /::/
+ return lookup_qualified_var(name, usestring)
+ end
+ # We can't use "if table[name]" here because the value might be false
+ if ephemeral_include?(name) or table.include?(name)
+ if usestring and table[name] == :undef
+ return ""
+ else
+ return table[name]
+ end
+ elsif self.parent
+ return parent.lookupvar(name, usestring)
+ elsif usestring
+ return ""
+ else
+ return :undefined
+ end
+ end
+
+ # Return a hash containing our variables and their values, optionally (and
+ # by default) including the values defined in our parent. Local values
+ # shadow parent values.
+ def to_hash(recursive = true)
+ target = parent.to_hash(recursive) if recursive and parent
+ target ||= Hash.new
+ @symtable.keys.each { |name|
+ value = @symtable[name]
+ if value == :undef
+ target.delete(name)
+ else
+ target[name] = value
+ end
+ }
+ target
+ end
+
+ def namespaces
+ @namespaces.dup
+ end
+
+ # Create a new scope and set these options.
+ def newscope(options = {})
+ compiler.newscope(self, options)
+ end
+
+ def parent_module_name
+ return nil unless @parent
+ return nil unless @parent.source
+ @parent.source.module_name
+ end
+
+ # Return the list of scopes up to the top scope, ordered with our own first.
+ # This is used for looking up variables and defaults.
+ def scope_path
+ if parent
+ [self, parent.scope_path].flatten.compact
+ else
+ [self]
+ end
+ end
+
+ # Set defaults for a type. The typename should already be downcased,
+ # so that the syntax is isolated. We don't do any kind of type-checking
+ # here; instead we let the resource do it when the defaults are used.
+ def setdefaults(type, params)
+ table = @defaults[type]
+
+ # if we got a single param, it'll be in its own array
+ params = [params] unless params.is_a?(Array)
+
+ params.each { |param|
+ #Puppet.debug "Default for %s is %s => %s" %
+ # [type,ary[0].inspect,ary[1].inspect]
+ if table.include?(param.name)
+ raise Puppet::ParseError.new("Default already defined for #{type} { #{param.name} }; cannot redefine", param.line, param.file)
+ end
+ table[param.name] = param
+ }
+ end
+
+ # Set a variable in the current scope. This will override settings
+ # in scopes above, but will not allow variables in the current scope
+ # to be reassigned.
+ def setvar(name,value, options = {})
+ table = options[:ephemeral] ? @ephemeral.last : @symtable
+ #Puppet.debug "Setting %s to '%s' at level %s mode append %s" %
+ # [name.inspect,value,self.level, append]
+ if table.include?(name)
+ unless options[:append]
+ error = Puppet::ParseError.new("Cannot reassign variable #{name}")
+ else
+ error = Puppet::ParseError.new("Cannot append, variable #{name} is defined in this scope")
+ end
+ error.file = options[:file] if options[:file]
+ error.line = options[:line] if options[:line]
+ raise error
+ end
+
+ unless options[:append]
+ table[name] = value
+ else # append case
+ # lookup the value in the scope if it exists and insert the var
+ table[name] = lookupvar(name)
+ # concatenate if string, append if array, nothing for other types
+ case value
+ when Array
+ table[name] += value
+ when Hash
+ raise ArgumentError, "Trying to append to a hash with something which is not a hash is unsupported" unless value.is_a?(Hash)
+ table[name].merge!(value)
+ else
+ table[name] << value
+ end
+ end
+ end
+
+ # Return an interpolated string.
+ def strinterp(string, file = nil, line = nil)
+ # Most strings won't have variables in them.
+ ss = StringScanner.new(string)
+ out = ""
+ while not ss.eos?
+ if ss.scan(/^\$\{((\w*::)*\w+|[0-9]+)\}|^\$([0-9])|^\$((\w*::)*\w+)/)
+ # If it matches the backslash, then just retun the dollar sign.
+ if ss.matched == '\\$'
+ out << '$'
+ else # look the variable up
+ # make sure $0-$9 are lookupable only if ephemeral
+ var = ss[1] || ss[3] || ss[4]
+ if var and var =~ /^[0-9]+$/ and not ephemeral_include?(var)
+ next
+ end
+ out << lookupvar(var).to_s || ""
end
-
- [:include?, :delete, :[]=].each do |m|
- define_method(m) do |*args|
- @symbols.send(m, *args)
- end
- end
-
- def [](name)
- unless @symbols.include?(name) or @parent.nil?
- @parent[name]
- else
- @symbols[name]
- end
- end
- end
-
- # A demeterific shortcut to the catalog.
- def catalog
- compiler.catalog
- end
-
- def environment
- compiler.environment
- end
-
- # Proxy accessors
- def host
- @compiler.node.name
- end
-
- # Is the value true? This allows us to control the definition of truth
- # in one place.
- def self.true?(value)
- (value != false and value != "" and value != :undef)
- end
-
- # Is the value a number?, return the correct object or nil if not a number
- def self.number?(value)
- return nil unless value.is_a?(Fixnum) or value.is_a?(Bignum) or value.is_a?(Float) or value.is_a?(String)
-
- if value.is_a?(String)
- if value =~ /^-?\d+(:?\.\d+|(:?\.\d+)?e\d+)$/
- return value.to_f
- elsif value =~ /^0x[0-9a-f]+$/i
- return value.to_i(16)
- elsif value =~ /^0[0-7]+$/
- return value.to_i(8)
- elsif value =~ /^-?\d+$/
- return value.to_i
- else
- return nil
- end
- end
- # it is one of Fixnum,Bignum or Float
- value
- end
-
- # Add to our list of namespaces.
- def add_namespace(ns)
- return false if @namespaces.include?(ns)
- if @namespaces == [""]
- @namespaces = [ns]
+ elsif ss.scan(/^\\(.)/)
+ # Puppet.debug("Got escape: pos:%d; m:%s" % [ss.pos, ss.matched])
+ case ss[1]
+ when 'n'
+ out << "\n"
+ when 't'
+ out << "\t"
+ when 's'
+ out << " "
+ when '\\'
+ out << '\\'
+ when '$'
+ out << '$'
else
- @namespaces << ns
+ str = "Unrecognised escape sequence '#{ss.matched}'"
+ str += " in file #{file}" if file
+ str += " at line #{line}" if line
+ Puppet.warning str
+ out << ss.matched
end
- end
-
- # Remove this when rebasing
- def environment
- compiler.environment
- end
-
- # Are we the top scope?
- def topscope?
- @level == 1
- end
-
- def find_hostclass(name)
- known_resource_types.find_hostclass(namespaces, name)
- end
-
- def find_definition(name)
- known_resource_types.find_definition(namespaces, name)
- end
-
- def findresource(string, name = nil)
- compiler.findresource(string, name)
- end
-
- # Initialize our new scope. Defaults to having no parent.
- def initialize(hash = {})
- if hash.include?(:namespace)
- if n = hash[:namespace]
- @namespaces = [n]
- end
- hash.delete(:namespace)
- else
- @namespaces = [""]
+ elsif ss.scan(/^\$/)
+ out << '$'
+ elsif ss.scan(/^\\\n/) # an escaped carriage return
+ next
+ else
+ tmp = ss.scan(/[^\\$]+/)
+ # Puppet.debug("Got other: pos:%d; m:%s" % [ss.pos, tmp])
+ unless tmp
+ error = Puppet::ParseError.new("Could not parse string #{string.inspect}")
+ {:file= => file, :line= => line}.each do |m,v|
+ error.send(m, v) if v
+ end
+ raise error
end
- hash.each { |name, val|
- method = name.to_s + "="
- if self.respond_to? method
- self.send(method, val)
- else
- raise Puppet::DevError, "Invalid scope argument #{name}"
- end
- }
-
- extend_with_functions_module
-
- @tags = []
-
- # The symbol table for this scope. This is where we store variables.
- @symtable = {}
-
- # the ephemeral symbol tables
- # those should not persist long, and are used for the moment only
- # for $0..$xy capture variables of regexes
- # this is actually implemented as a stack, with each ephemeral scope
- # shadowing the previous one
- @ephemeral = [ Ephemeral.new ]
-
- # All of the defaults set for types. It's a hash of hashes,
- # with the first key being the type, then the second key being
- # the parameter.
- @defaults = Hash.new { |dhash,type|
- dhash[type] = {}
- }
-
- # The table for storing class singletons. This will only actually
- # be used by top scopes and node scopes.
- @class_scopes = {}
+ out << tmp
+ end
end
- # Store the fact that we've evaluated a class, and store a reference to
- # the scope in which it was evaluated, so that we can look it up later.
- def class_set(name, scope)
- return parent.class_set(name,scope) if parent
- @class_scopes[name] = scope
- end
+ out
+ end
- # Return the scope associated with a class. This is just here so
- # that subclasses can set their parent scopes to be the scope of
- # their parent class, and it's also used when looking up qualified
- # variables.
- def class_scope(klass)
- # They might pass in either the class or class name
- k = klass.respond_to?(:name) ? klass.name : klass
- @class_scopes[k] || (parent && parent.class_scope(k))
- end
+ # Return the tags associated with this scope. It's basically
+ # just our parents' tags, plus our type. We don't cache this value
+ # because our parent tags might change between calls.
+ def tags
+ resource.tags
+ end
- # Collect all of the defaults set at any higher scopes.
- # This is a different type of lookup because it's additive --
- # it collects all of the defaults, with defaults in closer scopes
- # overriding those in later scopes.
- def lookupdefaults(type)
- values = {}
-
- # first collect the values from the parents
- unless parent.nil?
- parent.lookupdefaults(type).each { |var,value|
- values[var] = value
- }
- end
+ # Used mainly for logging
+ def to_s
+ "Scope(#{@resource})"
+ end
- # then override them with any current values
- # this should probably be done differently
- if @defaults.include?(type)
- @defaults[type].each { |var,value|
- values[var] = value
- }
- end
+ # Undefine a variable; only used for testing.
+ def unsetvar(var)
+ table = ephemeral?(var) ? @ephemeral.last : @symtable
+ table.delete(var) if table.include?(var)
+ end
- #Puppet.debug "Got defaults for %s: %s" %
- # [type,values.inspect]
- values
+ # remove ephemeral scope up to level
+ def unset_ephemeral_var(level=:all)
+ if level == :all
+ @ephemeral = [ Ephemeral.new ]
+ else
+ (@ephemeral.size - level).times do
+ @ephemeral.pop
+ end
end
+ end
- # Look up a defined type.
- def lookuptype(name)
- find_definition(name) || find_hostclass(name)
+ # check if name exists in one of the ephemeral scope.
+ def ephemeral_include?(name)
+ @ephemeral.reverse.each do |eph|
+ return true if eph.include?(name)
end
+ false
+ end
- def lookup_qualified_var(name, usestring)
- parts = name.split(/::/)
- shortname = parts.pop
- klassname = parts.join("::")
- klass = find_hostclass(klassname)
- unless klass
- warning "Could not look up qualified variable '#{name}'; class #{klassname} could not be found"
- return usestring ? "" : :undefined
- end
- unless kscope = class_scope(klass)
- warning "Could not look up qualified variable '#{name}'; class #{klassname} has not been evaluated"
- return usestring ? "" : :undefined
- end
- kscope.lookupvar(shortname, usestring)
- end
+ # is name an ephemeral variable?
+ def ephemeral?(name)
+ name =~ /^\d+$/
+ end
- private :lookup_qualified_var
+ def ephemeral_level
+ @ephemeral.size
+ end
- # Look up a variable. The simplest value search we do. Default to returning
- # an empty string for missing values, but support returning a constant.
- def lookupvar(name, usestring = true)
- table = ephemeral?(name) ? @ephemeral.last : @symtable
- # If the variable is qualified, then find the specified scope and look the variable up there instead.
- if name =~ /::/
- return lookup_qualified_var(name, usestring)
- end
- # We can't use "if table[name]" here because the value might be false
- if ephemeral_include?(name) or table.include?(name)
- if usestring and table[name] == :undef
- return ""
- else
- return table[name]
- end
- elsif self.parent
- return parent.lookupvar(name, usestring)
- elsif usestring
- return ""
- else
- return :undefined
- end
- end
+ def new_ephemeral
+ @ephemeral.push(Ephemeral.new(@ephemeral.last))
+ end
- # Return a hash containing our variables and their values, optionally (and
- # by default) including the values defined in our parent. Local values
- # shadow parent values.
- def to_hash(recursive = true)
- target = parent.to_hash(recursive) if recursive and parent
- target ||= Hash.new
- @symtable.keys.each { |name|
- value = @symtable[name]
- if value == :undef
- target.delete(name)
- else
- target[name] = value
- end
- }
- target
- end
+ def ephemeral_from(match, file = nil, line = nil)
+ raise(ArgumentError,"Invalid regex match data") unless match.is_a?(MatchData)
- def namespaces
- @namespaces.dup
- end
+ new_ephemeral
- # Create a new scope and set these options.
- def newscope(options = {})
- compiler.newscope(self, options)
+ setvar("0", match[0], :file => file, :line => line, :ephemeral => true)
+ match.captures.each_with_index do |m,i|
+ setvar("#{i+1}", m, :file => file, :line => line, :ephemeral => true)
end
+ end
- def parent_module_name
- return nil unless @parent
- return nil unless @parent.source
- @parent.source.module_name
- end
-
- # Return the list of scopes up to the top scope, ordered with our own first.
- # This is used for looking up variables and defaults.
- def scope_path
- if parent
- [self, parent.scope_path].flatten.compact
- else
- [self]
- end
- end
-
- # Set defaults for a type. The typename should already be downcased,
- # so that the syntax is isolated. We don't do any kind of type-checking
- # here; instead we let the resource do it when the defaults are used.
- def setdefaults(type, params)
- table = @defaults[type]
-
- # if we got a single param, it'll be in its own array
- params = [params] unless params.is_a?(Array)
-
- params.each { |param|
- #Puppet.debug "Default for %s is %s => %s" %
- # [type,ary[0].inspect,ary[1].inspect]
- if table.include?(param.name)
- raise Puppet::ParseError.new("Default already defined for #{type} { #{param.name} }; cannot redefine", param.line, param.file)
- end
- table[param.name] = param
- }
- end
-
- # Set a variable in the current scope. This will override settings
- # in scopes above, but will not allow variables in the current scope
- # to be reassigned.
- def setvar(name,value, options = {})
- table = options[:ephemeral] ? @ephemeral.last : @symtable
- #Puppet.debug "Setting %s to '%s' at level %s mode append %s" %
- # [name.inspect,value,self.level, append]
- if table.include?(name)
- unless options[:append]
- error = Puppet::ParseError.new("Cannot reassign variable #{name}")
- else
- error = Puppet::ParseError.new("Cannot append, variable #{name} is defined in this scope")
- end
- error.file = options[:file] if options[:file]
- error.line = options[:line] if options[:line]
- raise error
- end
-
- unless options[:append]
- table[name] = value
- else # append case
- # lookup the value in the scope if it exists and insert the var
- table[name] = lookupvar(name)
- # concatenate if string, append if array, nothing for other types
- case value
- when Array
- table[name] += value
- when Hash
- raise ArgumentError, "Trying to append to a hash with something which is not a hash is unsupported" unless value.is_a?(Hash)
- table[name].merge!(value)
- else
- table[name] << value
- end
- end
- end
-
- # Return an interpolated string.
- def strinterp(string, file = nil, line = nil)
- # Most strings won't have variables in them.
- ss = StringScanner.new(string)
- out = ""
- while not ss.eos?
- if ss.scan(/^\$\{((\w*::)*\w+|[0-9]+)\}|^\$([0-9])|^\$((\w*::)*\w+)/)
- # If it matches the backslash, then just retun the dollar sign.
- if ss.matched == '\\$'
- out << '$'
- else # look the variable up
- # make sure $0-$9 are lookupable only if ephemeral
- var = ss[1] || ss[3] || ss[4]
- if var and var =~ /^[0-9]+$/ and not ephemeral_include?(var)
- next
- end
- out << lookupvar(var).to_s || ""
- end
- elsif ss.scan(/^\\(.)/)
- # Puppet.debug("Got escape: pos:%d; m:%s" % [ss.pos, ss.matched])
- case ss[1]
- when 'n'
- out << "\n"
- when 't'
- out << "\t"
- when 's'
- out << " "
- when '\\'
- out << '\\'
- when '$'
- out << '$'
- else
- str = "Unrecognised escape sequence '#{ss.matched}'"
- str += " in file #{file}" if file
- str += " at line #{line}" if line
- Puppet.warning str
- out << ss.matched
- end
- elsif ss.scan(/^\$/)
- out << '$'
- elsif ss.scan(/^\\\n/) # an escaped carriage return
- next
- else
- tmp = ss.scan(/[^\\$]+/)
- # Puppet.debug("Got other: pos:%d; m:%s" % [ss.pos, tmp])
- unless tmp
- error = Puppet::ParseError.new("Could not parse string #{string.inspect}")
- {:file= => file, :line= => line}.each do |m,v|
- error.send(m, v) if v
- end
- raise error
- end
- out << tmp
- end
- end
-
- out
- end
-
- # Return the tags associated with this scope. It's basically
- # just our parents' tags, plus our type. We don't cache this value
- # because our parent tags might change between calls.
- def tags
- resource.tags
- end
-
- # Used mainly for logging
- def to_s
- "Scope(#{@resource})"
- end
-
- # Undefine a variable; only used for testing.
- def unsetvar(var)
- table = ephemeral?(var) ? @ephemeral.last : @symtable
- table.delete(var) if table.include?(var)
- end
-
- # remove ephemeral scope up to level
- def unset_ephemeral_var(level=:all)
- if level == :all
- @ephemeral = [ Ephemeral.new ]
- else
- (@ephemeral.size - level).times do
- @ephemeral.pop
- end
- end
- end
+ private
- # check if name exists in one of the ephemeral scope.
- def ephemeral_include?(name)
- @ephemeral.reverse.each do |eph|
- return true if eph.include?(name)
- end
- false
- end
-
- # is name an ephemeral variable?
- def ephemeral?(name)
- name =~ /^\d+$/
- end
-
- def ephemeral_level
- @ephemeral.size
- end
-
- def new_ephemeral
- @ephemeral.push(Ephemeral.new(@ephemeral.last))
- end
-
- def ephemeral_from(match, file = nil, line = nil)
- raise(ArgumentError,"Invalid regex match data") unless match.is_a?(MatchData)
-
- new_ephemeral
-
- setvar("0", match[0], :file => file, :line => line, :ephemeral => true)
- match.captures.each_with_index do |m,i|
- setvar("#{i+1}", m, :file => file, :line => line, :ephemeral => true)
- end
- end
-
- private
-
- def extend_with_functions_module
- extend Puppet::Parser::Functions.environment_module(Puppet::Node::Environment.root)
- extend Puppet::Parser::Functions.environment_module(compiler ? environment : nil)
- end
+ def extend_with_functions_module
+ extend Puppet::Parser::Functions.environment_module(Puppet::Node::Environment.root)
+ extend Puppet::Parser::Functions.environment_module(compiler ? environment : nil)
+ end
end
diff --git a/lib/puppet/parser/templatewrapper.rb b/lib/puppet/parser/templatewrapper.rb
index 6966387..73a4ad8 100644
--- a/lib/puppet/parser/templatewrapper.rb
+++ b/lib/puppet/parser/templatewrapper.rb
@@ -3,112 +3,112 @@
require 'puppet/parser/files'
class Puppet::Parser::TemplateWrapper
- attr_writer :scope
- attr_reader :file
- attr_accessor :string
- include Puppet::Util
- Puppet::Util.logmethods(self)
-
- def initialize(scope)
- @__scope__ = scope
+ attr_writer :scope
+ attr_reader :file
+ attr_accessor :string
+ include Puppet::Util
+ Puppet::Util.logmethods(self)
+
+ def initialize(scope)
+ @__scope__ = scope
+ end
+
+ def scope
+ @__scope__
+ end
+
+ # Should return true if a variable is defined, false if it is not
+ def has_variable?(name)
+ if scope.lookupvar(name.to_s, false) != :undefined
+ true
+ else
+ false
end
-
- def scope
- @__scope__
+ end
+
+ # Allow templates to access the defined classes
+ def classes
+ scope.catalog.classes
+ end
+
+ # Allow templates to access the tags defined in the current scope
+ def tags
+ scope.tags
+ end
+
+ # Allow templates to access the all the defined tags
+ def all_tags
+ scope.catalog.tags
+ end
+
+ # Ruby treats variables like methods, so we used to expose variables
+ # within scope to the ERB code via method_missing. As per RedMine #1427,
+ # though, this means that conflicts between methods in our inheritance
+ # tree (Kernel#fork) and variable names (fork => "yes/no") could arise.
+ #
+ # Worse, /new/ conflicts could pop up when a new kernel or object method
+ # was added to Ruby, causing templates to suddenly fail mysteriously when
+ # Ruby was upgraded.
+ #
+ # To ensure that legacy templates using unqualified names work we retain
+ # the missing_method definition here until we declare the syntax finally
+ # dead.
+ def method_missing(name, *args)
+ # We have to tell lookupvar to return :undefined to us when
+ # appropriate; otherwise it converts to "".
+ value = scope.lookupvar(name.to_s, false)
+ if value != :undefined
+ return value
+ else
+ # Just throw an error immediately, instead of searching for
+ # other missingmethod things or whatever.
+ raise Puppet::ParseError, "Could not find value for '#{name}'"
end
+ end
- # Should return true if a variable is defined, false if it is not
- def has_variable?(name)
- if scope.lookupvar(name.to_s, false) != :undefined
- true
- else
- false
- end
+ def file=(filename)
+ unless @file = Puppet::Parser::Files.find_template(filename, scope.compiler.environment.to_s)
+ raise Puppet::ParseError, "Could not find template '#{filename}'"
end
- # Allow templates to access the defined classes
- def classes
- scope.catalog.classes
- end
+ # We'll only ever not have a parser in testing, but, eh.
+ scope.known_resource_types.watch_file(file)
- # Allow templates to access the tags defined in the current scope
- def tags
- scope.tags
- end
+ @string = File.read(file)
+ end
- # Allow templates to access the all the defined tags
- def all_tags
- scope.catalog.tags
+ def result(string = nil)
+ if string
+ self.string = string
+ template_source = "inline template"
+ else
+ template_source = file
end
- # Ruby treats variables like methods, so we used to expose variables
- # within scope to the ERB code via method_missing. As per RedMine #1427,
- # though, this means that conflicts between methods in our inheritance
- # tree (Kernel#fork) and variable names (fork => "yes/no") could arise.
- #
- # Worse, /new/ conflicts could pop up when a new kernel or object method
- # was added to Ruby, causing templates to suddenly fail mysteriously when
- # Ruby was upgraded.
- #
- # To ensure that legacy templates using unqualified names work we retain
- # the missing_method definition here until we declare the syntax finally
- # dead.
- def method_missing(name, *args)
- # We have to tell lookupvar to return :undefined to us when
- # appropriate; otherwise it converts to "".
- value = scope.lookupvar(name.to_s, false)
- if value != :undefined
- return value
+ # Expose all the variables in our scope as instance variables of the
+ # current object, making it possible to access them without conflict
+ # to the regular methods.
+ benchmark(:debug, "Bound template variables for #{template_source}") do
+ scope.to_hash.each { |name, value|
+ if name.kind_of?(String)
+ realname = name.gsub(/[^\w]/, "_")
else
- # Just throw an error immediately, instead of searching for
- # other missingmethod things or whatever.
- raise Puppet::ParseError, "Could not find value for '#{name}'"
+ realname = name
end
+ instance_variable_set("@#{realname}", value)
+ }
end
- def file=(filename)
- unless @file = Puppet::Parser::Files.find_template(filename, scope.compiler.environment.to_s)
- raise Puppet::ParseError, "Could not find template '#{filename}'"
- end
-
- # We'll only ever not have a parser in testing, but, eh.
- scope.known_resource_types.watch_file(file)
-
- @string = File.read(file)
+ result = nil
+ benchmark(:debug, "Interpolated template #{template_source}") do
+ template = ERB.new(self.string, 0, "-")
+ result = template.result(binding)
end
- def result(string = nil)
- if string
- self.string = string
- template_source = "inline template"
- else
- template_source = file
- end
-
- # Expose all the variables in our scope as instance variables of the
- # current object, making it possible to access them without conflict
- # to the regular methods.
- benchmark(:debug, "Bound template variables for #{template_source}") do
- scope.to_hash.each { |name, value|
- if name.kind_of?(String)
- realname = name.gsub(/[^\w]/, "_")
- else
- realname = name
- end
- instance_variable_set("@#{realname}", value)
- }
- end
-
- result = nil
- benchmark(:debug, "Interpolated template #{template_source}") do
- template = ERB.new(self.string, 0, "-")
- result = template.result(binding)
- end
-
- result
- end
+ result
+ end
- def to_s
- "template[#{(file ? file : "inline")}]"
- end
+ def to_s
+ "template[#{(file ? file : "inline")}]"
+ end
end
diff --git a/lib/puppet/parser/type_loader.rb b/lib/puppet/parser/type_loader.rb
index 37fa03f..e56ab94 100644
--- a/lib/puppet/parser/type_loader.rb
+++ b/lib/puppet/parser/type_loader.rb
@@ -1,146 +1,146 @@
require 'puppet/node/environment'
class Puppet::Parser::TypeLoader
- include Puppet::Node::Environment::Helper
-
- class Helper < Hash
- include MonitorMixin
- def done_with(item)
- synchronize do
- delete(item)[:busy].signal if self.has_key?(item) and self[item][:loader] == Thread.current
- end
- end
- def owner_of(item)
- synchronize do
- if !self.has_key? item
- self[item] = { :loader => Thread.current, :busy => self.new_cond}
- :nobody
- elsif self[item][:loader] == Thread.current
- :this_thread
- else
- flag = self[item][:busy]
- flag.wait
- flag.signal
- :another_thread
- end
- end
- end
+ include Puppet::Node::Environment::Helper
+
+ class Helper < Hash
+ include MonitorMixin
+ def done_with(item)
+ synchronize do
+ delete(item)[:busy].signal if self.has_key?(item) and self[item][:loader] == Thread.current
+ end
end
-
- # Import our files.
- def import(file, current_file = nil)
- return if Puppet[:ignoreimport]
-
- # use a path relative to the file doing the importing
- if current_file
- dir = current_file.sub(%r{[^/]+$},'').sub(/\/$/, '')
+ def owner_of(item)
+ synchronize do
+ if !self.has_key? item
+ self[item] = { :loader => Thread.current, :busy => self.new_cond}
+ :nobody
+ elsif self[item][:loader] == Thread.current
+ :this_thread
else
- dir = "."
- end
- if dir == ""
- dir = "."
- end
-
- pat = file
- modname, files = Puppet::Parser::Files.find_manifests(pat, :cwd => dir, :environment => environment)
- if files.size == 0
- raise Puppet::ImportError.new("No file(s) found for import of '#{pat}'")
- end
-
- files.each do |file|
- unless file =~ /^#{File::SEPARATOR}/
- file = File.join(dir, file)
- end
- @imported[file] = true
- parse_file(file)
+ flag = self[item][:busy]
+ flag.wait
+ flag.signal
+ :another_thread
end
-
- modname
+ end
end
+ end
- def imported?(file)
- @imported.has_key?(file)
- end
+ # Import our files.
+ def import(file, current_file = nil)
+ return if Puppet[:ignoreimport]
- def known_resource_types
- environment.known_resource_types
+ # use a path relative to the file doing the importing
+ if current_file
+ dir = current_file.sub(%r{[^/]+$},'').sub(/\/$/, '')
+ else
+ dir = "."
end
-
- def initialize(env)
- self.environment = env
- @loaded = []
- @loading = Helper.new
-
- @imported = {}
+ if dir == ""
+ dir = "."
end
- def load_until(namespaces, name)
- return nil if name == "" # special-case main.
- name2files(namespaces, name).each do |filename|
- modname = nil
- import_if_possible(filename) do
- modname = import(filename)
- @loaded << filename
- end
- if result = yield(filename)
- Puppet.info "Automatically imported #{name} from #{filename}"
- result.module_name = modname if modname and result.respond_to?(:module_name=)
- return result
- end
- end
- nil
+ pat = file
+ modname, files = Puppet::Parser::Files.find_manifests(pat, :cwd => dir, :environment => environment)
+ if files.size == 0
+ raise Puppet::ImportError.new("No file(s) found for import of '#{pat}'")
end
- def loaded?(name)
- @loaded.include?(name)
+ files.each do |file|
+ unless file =~ /^#{File::SEPARATOR}/
+ file = File.join(dir, file)
+ end
+ @imported[file] = true
+ parse_file(file)
end
- def name2files(namespaces, name)
- return [name.sub(/^::/, '').gsub("::", File::SEPARATOR)] if name =~ /^::/
+ modname
+ end
+
+ def imported?(file)
+ @imported.has_key?(file)
+ end
+
+ def known_resource_types
+ environment.known_resource_types
+ end
+
+ def initialize(env)
+ self.environment = env
+ @loaded = []
+ @loading = Helper.new
+
+ @imported = {}
+ end
+
+ def load_until(namespaces, name)
+ return nil if name == "" # special-case main.
+ name2files(namespaces, name).each do |filename|
+ modname = nil
+ import_if_possible(filename) do
+ modname = import(filename)
+ @loaded << filename
+ end
+ if result = yield(filename)
+ Puppet.info "Automatically imported #{name} from #{filename}"
+ result.module_name = modname if modname and result.respond_to?(:module_name=)
+ return result
+ end
+ end
+ nil
+ end
- result = namespaces.inject([]) do |names_to_try, namespace|
- fullname = (namespace + "::#{name}").sub(/^::/, '')
+ def loaded?(name)
+ @loaded.include?(name)
+ end
- # Try to load the module init file if we're a qualified name
- names_to_try << fullname.split("::")[0] if fullname.include?("::")
+ def name2files(namespaces, name)
+ return [name.sub(/^::/, '').gsub("::", File::SEPARATOR)] if name =~ /^::/
- # Then the fully qualified name
- names_to_try << fullname
- end
+ result = namespaces.inject([]) do |names_to_try, namespace|
+ fullname = (namespace + "::#{name}").sub(/^::/, '')
- # Otherwise try to load the bare name on its own. This
- # is appropriate if the class we're looking for is in a
- # module that's different from our namespace.
- result << name
- result.uniq.collect { |f| f.gsub("::", File::SEPARATOR) }
- end
+ # Try to load the module init file if we're a qualified name
+ names_to_try << fullname.split("::")[0] if fullname.include?("::")
- def parse_file(file)
- Puppet.debug("importing '#{file}' in environment #{environment}")
- parser = Puppet::Parser::Parser.new(environment)
- parser.file = file
- parser.parse
+ # Then the fully qualified name
+ names_to_try << fullname
end
- private
-
- # Utility method factored out of load for handling thread-safety.
- # This isn't tested in the specs, because that's basically impossible.
- def import_if_possible(file)
- return if @loaded.include?(file)
- begin
- case @loading.owner_of(file)
- when :this_thread
- return
- when :another_thread
- return import_if_possible(file)
- when :nobody
- yield
- end
- rescue Puppet::ImportError => detail
- # We couldn't load the item
- ensure
- @loading.done_with(file)
- end
+ # Otherwise try to load the bare name on its own. This
+ # is appropriate if the class we're looking for is in a
+ # module that's different from our namespace.
+ result << name
+ result.uniq.collect { |f| f.gsub("::", File::SEPARATOR) }
+ end
+
+ def parse_file(file)
+ Puppet.debug("importing '#{file}' in environment #{environment}")
+ parser = Puppet::Parser::Parser.new(environment)
+ parser.file = file
+ parser.parse
+ end
+
+ private
+
+ # Utility method factored out of load for handling thread-safety.
+ # This isn't tested in the specs, because that's basically impossible.
+ def import_if_possible(file)
+ return if @loaded.include?(file)
+ begin
+ case @loading.owner_of(file)
+ when :this_thread
+ return
+ when :another_thread
+ return import_if_possible(file)
+ when :nobody
+ yield
+ end
+ rescue Puppet::ImportError => detail
+ # We couldn't load the item
+ ensure
+ @loading.done_with(file)
end
+ end
end
diff --git a/lib/puppet/parser/yaml_trimmer.rb b/lib/puppet/parser/yaml_trimmer.rb
index 131bafb..cf78709 100644
--- a/lib/puppet/parser/yaml_trimmer.rb
+++ b/lib/puppet/parser/yaml_trimmer.rb
@@ -1,9 +1,9 @@
module Puppet::Parser::YamlTrimmer
- REMOVE = %w{@scope @source}
+ REMOVE = %w{@scope @source}
- def to_yaml_properties
- r = instance_variables - REMOVE
- r -= skip_for_yaml if respond_to?(:skip_for_yaml)
- r
- end
+ def to_yaml_properties
+ r = instance_variables - REMOVE
+ r -= skip_for_yaml if respond_to?(:skip_for_yaml)
+ r
+ end
end
diff --git a/lib/puppet/property.rb b/lib/puppet/property.rb
index c7165fe..282a52c 100644
--- a/lib/puppet/property.rb
+++ b/lib/puppet/property.rb
@@ -5,320 +5,320 @@ require 'puppet'
require 'puppet/parameter'
class Puppet::Property < Puppet::Parameter
- require 'puppet/property/ensure'
-
- # Because 'should' uses an array, we have a special method for handling
- # it. We also want to keep copies of the original values, so that
- # they can be retrieved and compared later when merging.
- attr_reader :shouldorig
-
- attr_writer :noop
-
- class << self
- attr_accessor :unmanaged
- attr_reader :name
-
- # Return array matching info, defaulting to just matching
- # the first value.
- def array_matching
- @array_matching ||= :first
- end
-
- # Set whether properties should match all values or just the first one.
- def array_matching=(value)
- value = value.intern if value.is_a?(String)
- raise ArgumentError, "Supported values for Property#array_matching are 'first' and 'all'" unless [:first, :all].include?(value)
- @array_matching = value
- end
- end
-
- # Look up a value's name, so we can find options and such.
- def self.value_name(name)
- if value = value_collection.match?(name)
- value.name
- end
- end
-
- # Retrieve an option set when a value was defined.
- def self.value_option(name, option)
- if value = value_collection.value(name)
- value.send(option)
- end
- end
-
- # Define a new valid value for a property. You must provide the value itself,
- # usually as a symbol, or a regex to match the value.
- #
- # The first argument to the method is either the value itself or a regex.
- # The second argument is an option hash; valid options are:
- # * <tt>:method</tt>: The name of the method to define. Defaults to 'set_<value>'.
- # * <tt>:required_features</tt>: A list of features this value requires.
- # * <tt>:event</tt>: The event that should be returned when this value is set.
- # * <tt>:call</tt>: When to call any associated block. The default value
- # is ``instead``, which means to call the value instead of calling the
- # provider. You can also specify ``before`` or ``after``, which will
- # call both the block and the provider, according to the order you specify
- # (the ``first`` refers to when the block is called, not the provider).
- def self.newvalue(name, options = {}, &block)
- value = value_collection.newvalue(name, options, &block)
-
- define_method(value.method, &value.block) if value.method and value.block
- value
- end
-
- # Call the provider method.
- def call_provider(value)
- provider.send(self.class.name.to_s + "=", value)
- rescue NoMethodError
- self.fail "The #{provider.class.name} provider can not handle attribute #{self.class.name}"
- end
-
- # Call the dynamically-created method associated with our value, if
- # there is one.
- def call_valuemethod(name, value)
- if method = self.class.value_option(name, :method) and self.respond_to?(method)
- begin
- event = self.send(method)
- rescue Puppet::Error
- raise
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- error = Puppet::Error.new("Could not set '#{value} on #{self.class.name}: #{detail}", @resource.line, @resource.file)
- error.set_backtrace detail.backtrace
- raise error
- end
- elsif block = self.class.value_option(name, :block)
- # FIXME It'd be better here to define a method, so that
- # the blocks could return values.
- self.instance_eval(&block)
- else
- devfail "Could not find method for value '#{name}'"
- end
- end
-
- # How should a property change be printed as a string?
- def change_to_s(current_value, newvalue)
- begin
- if current_value == :absent
- return "defined '#{name}' as '#{should_to_s(newvalue)}'"
- elsif newvalue == :absent or newvalue == [:absent]
- return "undefined '#{name}' from '#{is_to_s(current_value)}'"
- else
- return "#{name} changed '#{is_to_s(current_value)}' to '#{should_to_s(newvalue)}'"
- end
- rescue Puppet::Error, Puppet::DevError
- raise
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- raise Puppet::DevError, "Could not convert change '#{name}' to string: #{detail}"
- end
- end
+ require 'puppet/property/ensure'
- # Figure out which event to return.
- def event_name
- value = self.should
+ # Because 'should' uses an array, we have a special method for handling
+ # it. We also want to keep copies of the original values, so that
+ # they can be retrieved and compared later when merging.
+ attr_reader :shouldorig
- event_name = self.class.value_option(value, :event) and return event_name
+ attr_writer :noop
- name == :ensure or return (name.to_s + "_changed").to_sym
+ class << self
+ attr_accessor :unmanaged
+ attr_reader :name
- return (resource.type.to_s + case value
- when :present; "_created"
- when :absent; "_removed"
- else
- "_changed"
- end).to_sym
+ # Return array matching info, defaulting to just matching
+ # the first value.
+ def array_matching
+ @array_matching ||= :first
end
- # Return a modified form of the resource event.
- def event
- resource.event :name => event_name, :desired_value => should, :property => self, :source_description => path
+ # Set whether properties should match all values or just the first one.
+ def array_matching=(value)
+ value = value.intern if value.is_a?(String)
+ raise ArgumentError, "Supported values for Property#array_matching are 'first' and 'all'" unless [:first, :all].include?(value)
+ @array_matching = value
end
+ end
- attr_reader :shadow
-
- # initialize our property
- def initialize(hash = {})
- super
-
- if ! self.metaparam? and klass = Puppet::Type.metaparamclass(self.class.name)
- setup_shadow(klass)
- end
+ # Look up a value's name, so we can find options and such.
+ def self.value_name(name)
+ if value = value_collection.match?(name)
+ value.name
end
+ end
- # Determine whether the property is in-sync or not. If @should is
- # not defined or is set to a non-true value, then we do not have
- # a valid value for it and thus consider the property to be in-sync
- # since we cannot fix it. Otherwise, we expect our should value
- # to be an array, and if @is matches any of those values, then
- # we consider it to be in-sync.
- def insync?(is)
- return true unless @should
-
- self.devfail "#{self.class.name}'s should is not array" unless @should.is_a?(Array)
-
- # an empty array is analogous to no should values
- return true if @should.empty?
-
- # Look for a matching value
- return (is == @should or is == @should.collect { |v| v.to_s }) if match_all?
-
- @should.each { |val| return true if is == val or is == val.to_s }
-
- # otherwise, return false
- false
+ # Retrieve an option set when a value was defined.
+ def self.value_option(name, option)
+ if value = value_collection.value(name)
+ value.send(option)
end
-
- # because the @should and @is vars might be in weird formats,
- # we need to set up a mechanism for pretty printing of the values
- # default to just the values, but this way individual properties can
- # override these methods
- def is_to_s(currentvalue)
- currentvalue
+ end
+
+ # Define a new valid value for a property. You must provide the value itself,
+ # usually as a symbol, or a regex to match the value.
+ #
+ # The first argument to the method is either the value itself or a regex.
+ # The second argument is an option hash; valid options are:
+ # * <tt>:method</tt>: The name of the method to define. Defaults to 'set_<value>'.
+ # * <tt>:required_features</tt>: A list of features this value requires.
+ # * <tt>:event</tt>: The event that should be returned when this value is set.
+ # * <tt>:call</tt>: When to call any associated block. The default value
+ # is ``instead``, which means to call the value instead of calling the
+ # provider. You can also specify ``before`` or ``after``, which will
+ # call both the block and the provider, according to the order you specify
+ # (the ``first`` refers to when the block is called, not the provider).
+ def self.newvalue(name, options = {}, &block)
+ value = value_collection.newvalue(name, options, &block)
+
+ define_method(value.method, &value.block) if value.method and value.block
+ value
+ end
+
+ # Call the provider method.
+ def call_provider(value)
+ provider.send(self.class.name.to_s + "=", value)
+ rescue NoMethodError
+ self.fail "The #{provider.class.name} provider can not handle attribute #{self.class.name}"
+ end
+
+ # Call the dynamically-created method associated with our value, if
+ # there is one.
+ def call_valuemethod(name, value)
+ if method = self.class.value_option(name, :method) and self.respond_to?(method)
+ begin
+ event = self.send(method)
+ rescue Puppet::Error
+ raise
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ error = Puppet::Error.new("Could not set '#{value} on #{self.class.name}: #{detail}", @resource.line, @resource.file)
+ error.set_backtrace detail.backtrace
+ raise error
+ end
+ elsif block = self.class.value_option(name, :block)
+ # FIXME It'd be better here to define a method, so that
+ # the blocks could return values.
+ self.instance_eval(&block)
+ else
+ devfail "Could not find method for value '#{name}'"
end
-
- # Send a log message.
- def log(msg)
-
- Puppet::Util::Log.create(
-
- :level => resource[:loglevel],
- :message => msg,
-
- :source => self
- )
+ end
+
+ # How should a property change be printed as a string?
+ def change_to_s(current_value, newvalue)
+ begin
+ if current_value == :absent
+ return "defined '#{name}' as '#{should_to_s(newvalue)}'"
+ elsif newvalue == :absent or newvalue == [:absent]
+ return "undefined '#{name}' from '#{is_to_s(current_value)}'"
+ else
+ return "#{name} changed '#{is_to_s(current_value)}' to '#{should_to_s(newvalue)}'"
+ end
+ rescue Puppet::Error, Puppet::DevError
+ raise
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ raise Puppet::DevError, "Could not convert change '#{name}' to string: #{detail}"
end
+ end
- # Should we match all values, or just the first?
- def match_all?
- self.class.array_matching == :all
- end
+ # Figure out which event to return.
+ def event_name
+ value = self.should
- # Execute our shadow's munge code, too, if we have one.
- def munge(value)
- self.shadow.munge(value) if self.shadow
+ event_name = self.class.value_option(value, :event) and return event_name
- super
- end
+ name == :ensure or return (name.to_s + "_changed").to_sym
- # each property class must define the name method, and property instances
- # do not change that name
- # this implicitly means that a given object can only have one property
- # instance of a given property class
- def name
- self.class.name
- end
+ return (resource.type.to_s + case value
+ when :present; "_created"
+ when :absent; "_removed"
+ else
+ "_changed"
+ end).to_sym
+ end
- # for testing whether we should actually do anything
- def noop
- # This is only here to make testing easier.
- if @resource.respond_to?(:noop?)
- @resource.noop?
- else
- if defined?(@noop)
- @noop
- else
- Puppet[:noop]
- end
- end
- end
+ # Return a modified form of the resource event.
+ def event
+ resource.event :name => event_name, :desired_value => should, :property => self, :source_description => path
+ end
- # By default, call the method associated with the property name on our
- # provider. In other words, if the property name is 'gid', we'll call
- # 'provider.gid' to retrieve the current value.
- def retrieve
- provider.send(self.class.name)
- end
+ attr_reader :shadow
- # Set our value, using the provider, an associated block, or both.
- def set(value)
- # Set a name for looking up associated options like the event.
- name = self.class.value_name(value)
-
- call = self.class.value_option(name, :call) || :none
-
- if call == :instead
- call_valuemethod(name, value)
- elsif call == :none
- # They haven't provided a block, and our parent does not have
- # a provider, so we have no idea how to handle this.
- self.fail "#{self.class.name} cannot handle values of type #{value.inspect}" unless @resource.provider
- call_provider(value)
- else
- # LAK:NOTE 20081031 This is a change in behaviour -- you could
- # previously specify :call => [;before|:after], which would call
- # the setter *in addition to* the block. I'm convinced this
- # was never used, and it makes things unecessarily complicated.
- # If you want to specify a block and still call the setter, then
- # do so in the block.
- devfail "Cannot use obsolete :call value '#{call}' for property '#{self.class.name}'"
- end
- end
+ # initialize our property
+ def initialize(hash = {})
+ super
- # If there's a shadowing metaparam, instantiate it now.
- # This allows us to create a property or parameter with the
- # same name as a metaparameter, and the metaparam will only be
- # stored as a shadow.
- def setup_shadow(klass)
- @shadow = klass.new(:resource => self.resource)
+ if ! self.metaparam? and klass = Puppet::Type.metaparamclass(self.class.name)
+ setup_shadow(klass)
end
+ end
- # Only return the first value
- def should
- return nil unless defined?(@should)
+ # Determine whether the property is in-sync or not. If @should is
+ # not defined or is set to a non-true value, then we do not have
+ # a valid value for it and thus consider the property to be in-sync
+ # since we cannot fix it. Otherwise, we expect our should value
+ # to be an array, and if @is matches any of those values, then
+ # we consider it to be in-sync.
+ def insync?(is)
+ return true unless @should
- self.devfail "should for #{self.class.name} on #{resource.name} is not an array" unless @should.is_a?(Array)
+ self.devfail "#{self.class.name}'s should is not array" unless @should.is_a?(Array)
- if match_all?
- return @should.collect { |val| self.unmunge(val) }
- else
- return self.unmunge(@should[0])
- end
- end
+ # an empty array is analogous to no should values
+ return true if @should.empty?
- # Set the should value.
- def should=(values)
- values = [values] unless values.is_a?(Array)
+ # Look for a matching value
+ return (is == @should or is == @should.collect { |v| v.to_s }) if match_all?
- @shouldorig = values
+ @should.each { |val| return true if is == val or is == val.to_s }
- values.each { |val| validate(val) }
- @should = values.collect { |val| self.munge(val) }
- end
+ # otherwise, return false
+ false
+ end
- def should_to_s(newvalue)
- [newvalue].flatten.join(" ")
- end
+ # because the @should and @is vars might be in weird formats,
+ # we need to set up a mechanism for pretty printing of the values
+ # default to just the values, but this way individual properties can
+ # override these methods
+ def is_to_s(currentvalue)
+ currentvalue
+ end
- def sync
- devfail "Got a nil value for should" unless should
- set(should)
- end
+ # Send a log message.
+ def log(msg)
- # Verify that the passed value is valid.
- # If the developer uses a 'validate' hook, this method will get overridden.
- def unsafe_validate(value)
- super
- validate_features_per_value(value)
+ Puppet::Util::Log.create(
+
+ :level => resource[:loglevel],
+ :message => msg,
+
+ :source => self
+ )
+ end
+
+ # Should we match all values, or just the first?
+ def match_all?
+ self.class.array_matching == :all
+ end
+
+ # Execute our shadow's munge code, too, if we have one.
+ def munge(value)
+ self.shadow.munge(value) if self.shadow
+
+ super
+ end
+
+ # each property class must define the name method, and property instances
+ # do not change that name
+ # this implicitly means that a given object can only have one property
+ # instance of a given property class
+ def name
+ self.class.name
+ end
+
+ # for testing whether we should actually do anything
+ def noop
+ # This is only here to make testing easier.
+ if @resource.respond_to?(:noop?)
+ @resource.noop?
+ else
+ if defined?(@noop)
+ @noop
+ else
+ Puppet[:noop]
+ end
end
-
- # Make sure that we've got all of the required features for a given value.
- def validate_features_per_value(value)
- if features = self.class.value_option(self.class.value_name(value), :required_features)
- features = Array(features)
- needed_features = features.collect { |f| f.to_s }.join(", ")
- raise ArgumentError, "Provider must have features '#{needed_features}' to set '#{self.class.name}' to '#{value}'" unless provider.satisfies?(features)
- end
+ end
+
+ # By default, call the method associated with the property name on our
+ # provider. In other words, if the property name is 'gid', we'll call
+ # 'provider.gid' to retrieve the current value.
+ def retrieve
+ provider.send(self.class.name)
+ end
+
+ # Set our value, using the provider, an associated block, or both.
+ def set(value)
+ # Set a name for looking up associated options like the event.
+ name = self.class.value_name(value)
+
+ call = self.class.value_option(name, :call) || :none
+
+ if call == :instead
+ call_valuemethod(name, value)
+ elsif call == :none
+ # They haven't provided a block, and our parent does not have
+ # a provider, so we have no idea how to handle this.
+ self.fail "#{self.class.name} cannot handle values of type #{value.inspect}" unless @resource.provider
+ call_provider(value)
+ else
+ # LAK:NOTE 20081031 This is a change in behaviour -- you could
+ # previously specify :call => [;before|:after], which would call
+ # the setter *in addition to* the block. I'm convinced this
+ # was never used, and it makes things unecessarily complicated.
+ # If you want to specify a block and still call the setter, then
+ # do so in the block.
+ devfail "Cannot use obsolete :call value '#{call}' for property '#{self.class.name}'"
end
-
- # Just return any should value we might have.
- def value
- self.should
+ end
+
+ # If there's a shadowing metaparam, instantiate it now.
+ # This allows us to create a property or parameter with the
+ # same name as a metaparameter, and the metaparam will only be
+ # stored as a shadow.
+ def setup_shadow(klass)
+ @shadow = klass.new(:resource => self.resource)
+ end
+
+ # Only return the first value
+ def should
+ return nil unless defined?(@should)
+
+ self.devfail "should for #{self.class.name} on #{resource.name} is not an array" unless @should.is_a?(Array)
+
+ if match_all?
+ return @should.collect { |val| self.unmunge(val) }
+ else
+ return self.unmunge(@should[0])
end
-
- # Match the Parameter interface, but we really just use 'should' internally.
- # Note that the should= method does all of the validation and such.
- def value=(value)
- self.should = value
+ end
+
+ # Set the should value.
+ def should=(values)
+ values = [values] unless values.is_a?(Array)
+
+ @shouldorig = values
+
+ values.each { |val| validate(val) }
+ @should = values.collect { |val| self.munge(val) }
+ end
+
+ def should_to_s(newvalue)
+ [newvalue].flatten.join(" ")
+ end
+
+ def sync
+ devfail "Got a nil value for should" unless should
+ set(should)
+ end
+
+ # Verify that the passed value is valid.
+ # If the developer uses a 'validate' hook, this method will get overridden.
+ def unsafe_validate(value)
+ super
+ validate_features_per_value(value)
+ end
+
+ # Make sure that we've got all of the required features for a given value.
+ def validate_features_per_value(value)
+ if features = self.class.value_option(self.class.value_name(value), :required_features)
+ features = Array(features)
+ needed_features = features.collect { |f| f.to_s }.join(", ")
+ raise ArgumentError, "Provider must have features '#{needed_features}' to set '#{self.class.name}' to '#{value}'" unless provider.satisfies?(features)
end
+ end
+
+ # Just return any should value we might have.
+ def value
+ self.should
+ end
+
+ # Match the Parameter interface, but we really just use 'should' internally.
+ # Note that the should= method does all of the validation and such.
+ def value=(value)
+ self.should = value
+ end
end
diff --git a/lib/puppet/property/ensure.rb b/lib/puppet/property/ensure.rb
index d6aa99e..8b97dde 100644
--- a/lib/puppet/property/ensure.rb
+++ b/lib/puppet/property/ensure.rb
@@ -3,90 +3,90 @@ require 'puppet/property'
# This property will get automatically added to any type that responds
# to the methods 'exists?', 'create', and 'destroy'.
class Puppet::Property::Ensure < Puppet::Property
- @name = :ensure
+ @name = :ensure
- def self.defaultvalues
- newvalue(:present) do
- if @resource.provider and @resource.provider.respond_to?(:create)
- @resource.provider.create
- else
- @resource.create
- end
- nil # return nil so the event is autogenerated
- end
-
- newvalue(:absent) do
- if @resource.provider and @resource.provider.respond_to?(:destroy)
- @resource.provider.destroy
- else
- @resource.destroy
- end
- nil # return nil so the event is autogenerated
- end
+ def self.defaultvalues
+ newvalue(:present) do
+ if @resource.provider and @resource.provider.respond_to?(:create)
+ @resource.provider.create
+ else
+ @resource.create
+ end
+ nil # return nil so the event is autogenerated
+ end
- defaultto do
- if @resource.managed?
- :present
- else
- nil
- end
- end
+ newvalue(:absent) do
+ if @resource.provider and @resource.provider.respond_to?(:destroy)
+ @resource.provider.destroy
+ else
+ @resource.destroy
+ end
+ nil # return nil so the event is autogenerated
+ end
- # This doc will probably get overridden
- @doc ||= "The basic property that the resource should be in."
+ defaultto do
+ if @resource.managed?
+ :present
+ else
+ nil
+ end
end
- def self.inherited(sub)
- # Add in the two properties that everyone will have.
- sub.class_eval do
- end
+ # This doc will probably get overridden
+ @doc ||= "The basic property that the resource should be in."
+ end
+
+ def self.inherited(sub)
+ # Add in the two properties that everyone will have.
+ sub.class_eval do
end
+ end
- def change_to_s(currentvalue, newvalue)
- begin
- if currentvalue == :absent or currentvalue.nil?
- return "created"
- elsif newvalue == :absent
- return "removed"
- else
- return "#{self.name} changed '#{self.is_to_s(currentvalue)}' to '#{self.should_to_s(newvalue)}'"
- end
- rescue Puppet::Error, Puppet::DevError
- raise
- rescue => detail
- raise Puppet::DevError, "Could not convert change #{self.name} to string: #{detail}"
- end
+ def change_to_s(currentvalue, newvalue)
+ begin
+ if currentvalue == :absent or currentvalue.nil?
+ return "created"
+ elsif newvalue == :absent
+ return "removed"
+ else
+ return "#{self.name} changed '#{self.is_to_s(currentvalue)}' to '#{self.should_to_s(newvalue)}'"
+ end
+ rescue Puppet::Error, Puppet::DevError
+ raise
+ rescue => detail
+ raise Puppet::DevError, "Could not convert change #{self.name} to string: #{detail}"
end
+ end
- def retrieve
- # XXX This is a problem -- whether the object exists or not often
- # depends on the results of other properties, yet we're the first property
- # to get checked, which means that those other properties do not have
- # @is values set. This seems to be the source of quite a few bugs,
- # although they're mostly logging bugs, not functional ones.
- if prov = @resource.provider and prov.respond_to?(:exists?)
- result = prov.exists?
- elsif @resource.respond_to?(:exists?)
- result = @resource.exists?
- else
- raise Puppet::DevError, "No ability to determine if #{@resource.class.name} exists"
- end
- if result
- return :present
- else
- return :absent
- end
+ def retrieve
+ # XXX This is a problem -- whether the object exists or not often
+ # depends on the results of other properties, yet we're the first property
+ # to get checked, which means that those other properties do not have
+ # @is values set. This seems to be the source of quite a few bugs,
+ # although they're mostly logging bugs, not functional ones.
+ if prov = @resource.provider and prov.respond_to?(:exists?)
+ result = prov.exists?
+ elsif @resource.respond_to?(:exists?)
+ result = @resource.exists?
+ else
+ raise Puppet::DevError, "No ability to determine if #{@resource.class.name} exists"
+ end
+ if result
+ return :present
+ else
+ return :absent
end
+ end
- # If they're talking about the thing at all, they generally want to
- # say it should exist.
- #defaultto :present
- defaultto do
- if @resource.managed?
- :present
- else
- nil
- end
+ # If they're talking about the thing at all, they generally want to
+ # say it should exist.
+ #defaultto :present
+ defaultto do
+ if @resource.managed?
+ :present
+ else
+ nil
end
+ end
end
diff --git a/lib/puppet/property/keyvalue.rb b/lib/puppet/property/keyvalue.rb
index 2ac87ac..0181708 100644
--- a/lib/puppet/property/keyvalue.rb
+++ b/lib/puppet/property/keyvalue.rb
@@ -9,80 +9,80 @@
require 'puppet/property'
module Puppet
- class Property
- class KeyValue < Property
-
- def hash_to_key_value_s(hash)
- hash.select { |k,v| true }.map { |pair| pair.join(separator) }.join(delimiter)
- end
-
- def should_to_s(should_value)
- hash_to_key_value_s(should_value)
- end
-
- def is_to_s(current_value)
- hash_to_key_value_s(current_value)
- end
-
- def membership
- :key_value_membership
- end
-
- def inclusive?
- @resource[membership] == :inclusive
- end
-
- def hashify(key_value_array)
- #turns string array into a hash
- key_value_array.inject({}) do |hash, key_value|
- tmp = key_value.split(separator)
- hash[tmp[0].intern] = tmp[1]
- hash
- end
- end
-
- def process_current_hash(current)
- return {} if current == :absent
-
- #inclusive means we are managing everything so if it isn't in should, its gone
- current.each_key { |key| current[key] = nil } if inclusive?
- current
- end
-
- def should
- return nil unless @should
-
- members = hashify(@should)
- current = process_current_hash(retrieve)
-
- #shared keys will get overwritten by members
- current.merge(members)
- end
-
- def separator
- "="
- end
-
- def delimiter
- ";"
- end
-
- def retrieve
- #ok, some 'convention' if the keyvalue property is named properties, provider should implement a properties method
- if key_hash = provider.send(name) and key_hash != :absent
- return key_hash
- else
- return :absent
- end
- end
-
- def insync?(is)
- return true unless @should
-
- return true unless is
-
- (is == self.should)
- end
+ class Property
+ class KeyValue < Property
+
+ def hash_to_key_value_s(hash)
+ hash.select { |k,v| true }.map { |pair| pair.join(separator) }.join(delimiter)
+ end
+
+ def should_to_s(should_value)
+ hash_to_key_value_s(should_value)
+ end
+
+ def is_to_s(current_value)
+ hash_to_key_value_s(current_value)
+ end
+
+ def membership
+ :key_value_membership
+ end
+
+ def inclusive?
+ @resource[membership] == :inclusive
+ end
+
+ def hashify(key_value_array)
+ #turns string array into a hash
+ key_value_array.inject({}) do |hash, key_value|
+ tmp = key_value.split(separator)
+ hash[tmp[0].intern] = tmp[1]
+ hash
end
+ end
+
+ def process_current_hash(current)
+ return {} if current == :absent
+
+ #inclusive means we are managing everything so if it isn't in should, its gone
+ current.each_key { |key| current[key] = nil } if inclusive?
+ current
+ end
+
+ def should
+ return nil unless @should
+
+ members = hashify(@should)
+ current = process_current_hash(retrieve)
+
+ #shared keys will get overwritten by members
+ current.merge(members)
+ end
+
+ def separator
+ "="
+ end
+
+ def delimiter
+ ";"
+ end
+
+ def retrieve
+ #ok, some 'convention' if the keyvalue property is named properties, provider should implement a properties method
+ if key_hash = provider.send(name) and key_hash != :absent
+ return key_hash
+ else
+ return :absent
+ end
+ end
+
+ def insync?(is)
+ return true unless @should
+
+ return true unless is
+
+ (is == self.should)
+ end
end
+ end
end
diff --git a/lib/puppet/property/list.rb b/lib/puppet/property/list.rb
index 0433a51..dcee85d 100644
--- a/lib/puppet/property/list.rb
+++ b/lib/puppet/property/list.rb
@@ -1,77 +1,77 @@
require 'puppet/property'
module Puppet
- class Property
- class List < Property
-
- def should_to_s(should_value)
- #just return the should value
- should_value
- end
-
- def is_to_s(currentvalue)
- if currentvalue == :absent
- return "absent"
- else
- return currentvalue.join(delimiter)
- end
- end
-
- def membership
- :membership
- end
-
- def add_should_with_current(should, current)
- should += current if current.is_a?(Array)
- should.uniq
- end
-
- def inclusive?
- @resource[membership] == :inclusive
- end
-
- #dearrayify was motivated because to simplify the implementation of the OrderedList property
- def dearrayify(array)
- array.sort.join(delimiter)
- end
-
- def should
- return nil unless @should
-
- members = @should
- #inclusive means we are managing everything so if it isn't in should, its gone
- members = add_should_with_current(members, retrieve) if ! inclusive?
-
- dearrayify(members)
- end
-
- def delimiter
- ","
- end
-
- def retrieve
- #ok, some 'convention' if the list property is named groups, provider should implement a groups method
- if tmp = provider.send(name) and tmp != :absent
- return tmp.split(delimiter)
- else
- return :absent
- end
- end
-
- def prepare_is_for_comparison(is)
- if is == :absent
- is = []
- end
- dearrayify(is)
- end
-
- def insync?(is)
- return true unless @should
-
- return true unless is
-
- (prepare_is_for_comparison(is) == self.should)
- end
+ class Property
+ class List < Property
+
+ def should_to_s(should_value)
+ #just return the should value
+ should_value
+ end
+
+ def is_to_s(currentvalue)
+ if currentvalue == :absent
+ return "absent"
+ else
+ return currentvalue.join(delimiter)
end
+ end
+
+ def membership
+ :membership
+ end
+
+ def add_should_with_current(should, current)
+ should += current if current.is_a?(Array)
+ should.uniq
+ end
+
+ def inclusive?
+ @resource[membership] == :inclusive
+ end
+
+ #dearrayify was motivated because to simplify the implementation of the OrderedList property
+ def dearrayify(array)
+ array.sort.join(delimiter)
+ end
+
+ def should
+ return nil unless @should
+
+ members = @should
+ #inclusive means we are managing everything so if it isn't in should, its gone
+ members = add_should_with_current(members, retrieve) if ! inclusive?
+
+ dearrayify(members)
+ end
+
+ def delimiter
+ ","
+ end
+
+ def retrieve
+ #ok, some 'convention' if the list property is named groups, provider should implement a groups method
+ if tmp = provider.send(name) and tmp != :absent
+ return tmp.split(delimiter)
+ else
+ return :absent
+ end
+ end
+
+ def prepare_is_for_comparison(is)
+ if is == :absent
+ is = []
+ end
+ dearrayify(is)
+ end
+
+ def insync?(is)
+ return true unless @should
+
+ return true unless is
+
+ (prepare_is_for_comparison(is) == self.should)
+ end
end
+ end
end
diff --git a/lib/puppet/property/ordered_list.rb b/lib/puppet/property/ordered_list.rb
index 816b16c..7408b30 100644
--- a/lib/puppet/property/ordered_list.rb
+++ b/lib/puppet/property/ordered_list.rb
@@ -1,22 +1,22 @@
require 'puppet/property/list'
module Puppet
- class Property
- class OrderedList < List
+ class Property
+ class OrderedList < List
- def add_should_with_current(should, current)
- if current.is_a?(Array)
- #tricky trick
- #Preserve all the current items in the list
- #but move them to the back of the line
- should = should + (current - should)
- end
- should
- end
-
- def dearrayify(array)
- array.join(delimiter)
- end
+ def add_should_with_current(should, current)
+ if current.is_a?(Array)
+ #tricky trick
+ #Preserve all the current items in the list
+ #but move them to the back of the line
+ should = should + (current - should)
end
+ should
+ end
+
+ def dearrayify(array)
+ array.join(delimiter)
+ end
end
+ end
end
diff --git a/lib/puppet/provider.rb b/lib/puppet/provider.rb
index 859a346..8f993db 100644
--- a/lib/puppet/provider.rb
+++ b/lib/puppet/provider.rb
@@ -1,195 +1,195 @@
# The container class for implementations.
class Puppet::Provider
- include Puppet::Util
- include Puppet::Util::Errors
- include Puppet::Util::Warnings
- extend Puppet::Util::Warnings
+ include Puppet::Util
+ include Puppet::Util::Errors
+ include Puppet::Util::Warnings
+ extend Puppet::Util::Warnings
- require 'puppet/provider/confiner'
+ require 'puppet/provider/confiner'
- extend Puppet::Provider::Confiner
+ extend Puppet::Provider::Confiner
- Puppet::Util.logmethods(self, true)
+ Puppet::Util.logmethods(self, true)
- class << self
- # Include the util module so we have access to things like 'binary'
- include Puppet::Util, Puppet::Util::Docs
- include Puppet::Util::Logging
- attr_accessor :name
+ class << self
+ # Include the util module so we have access to things like 'binary'
+ include Puppet::Util, Puppet::Util::Docs
+ include Puppet::Util::Logging
+ attr_accessor :name
- # The source parameter exists so that providers using the same
- # source can specify this, so reading doesn't attempt to read the
- # same package multiple times.
- attr_writer :source
-
- # LAK 2007-05-09: Keep the model stuff around for backward compatibility
- attr_reader :model
- attr_accessor :resource_type
- attr_writer :doc
- end
+ # The source parameter exists so that providers using the same
+ # source can specify this, so reading doesn't attempt to read the
+ # same package multiple times.
+ attr_writer :source
# LAK 2007-05-09: Keep the model stuff around for backward compatibility
attr_reader :model
- attr_accessor :resource
-
- def self.command(name)
- name = symbolize(name)
-
- if defined?(@commands) and command = @commands[name]
- # nothing
- elsif superclass.respond_to? :command and command = superclass.command(name)
- # nothing
- else
- raise Puppet::DevError, "No command #{name} defined for provider #{self.name}"
- end
-
- binary(command)
+ attr_accessor :resource_type
+ attr_writer :doc
+ end
+
+ # LAK 2007-05-09: Keep the model stuff around for backward compatibility
+ attr_reader :model
+ attr_accessor :resource
+
+ def self.command(name)
+ name = symbolize(name)
+
+ if defined?(@commands) and command = @commands[name]
+ # nothing
+ elsif superclass.respond_to? :command and command = superclass.command(name)
+ # nothing
+ else
+ raise Puppet::DevError, "No command #{name} defined for provider #{self.name}"
end
- # Define commands that are not optional.
- def self.commands(hash)
- optional_commands(hash) do |name, path|
- confine :exists => path, :for_binary => true
- end
- end
+ binary(command)
+ end
- # Is the provided feature a declared feature?
- def self.declared_feature?(name)
- defined?(@declared_features) and @declared_features.include?(name)
+ # Define commands that are not optional.
+ def self.commands(hash)
+ optional_commands(hash) do |name, path|
+ confine :exists => path, :for_binary => true
end
-
- # Does this implementation match all of the default requirements? If
- # defaults are empty, we return false.
- def self.default?
- return false if @defaults.empty?
- if @defaults.find do |fact, values|
- values = [values] unless values.is_a? Array
- if fval = Facter.value(fact).to_s and fval != ""
- fval = fval.to_s.downcase.intern
- else
- return false
- end
-
- # If any of the values match, we're a default.
- if values.find do |value| fval == value.to_s.downcase.intern end
- false
- else
- true
- end
- end
- return false
+ end
+
+ # Is the provided feature a declared feature?
+ def self.declared_feature?(name)
+ defined?(@declared_features) and @declared_features.include?(name)
+ end
+
+ # Does this implementation match all of the default requirements? If
+ # defaults are empty, we return false.
+ def self.default?
+ return false if @defaults.empty?
+ if @defaults.find do |fact, values|
+ values = [values] unless values.is_a? Array
+ if fval = Facter.value(fact).to_s and fval != ""
+ fval = fval.to_s.downcase.intern
else
- return true
+ return false
end
- end
- # Store how to determine defaults.
- def self.defaultfor(hash)
- hash.each do |d,v|
- @defaults[d] = v
+ # If any of the values match, we're a default.
+ if values.find do |value| fval == value.to_s.downcase.intern end
+ false
+ else
+ true
end
+ end
+ return false
+ else
+ return true
end
+ end
- def self.specificity
- (@defaults.length * 100) + ancestors.select { |a| a.is_a? Class }.length
+ # Store how to determine defaults.
+ def self.defaultfor(hash)
+ hash.each do |d,v|
+ @defaults[d] = v
end
-
- def self.initvars
- @defaults = {}
- @commands = {}
- end
-
- # The method for returning a list of provider instances. Note that it returns providers, preferably with values already
- # filled in, not resources.
- def self.instances
- raise Puppet::DevError, "Provider #{self.name} has not defined the 'instances' class method"
- end
-
- # Create the methods for a given command.
- def self.make_command_methods(name)
- # Now define a method for that command
- unless singleton_class.method_defined?(name)
- meta_def(name) do |*args|
- raise Puppet::Error, "Command #{name} is missing" unless command(name)
- if args.empty?
- cmd = [command(name)]
- else
- cmd = [command(name)] + args
- end
- # This might throw an ExecutionFailure, but the system above
- # will catch it, if so.
- return execute(cmd)
- end
-
- # And then define an instance method that just calls the class method.
- # We need both, so both instances and classes can easily run the commands.
- unless method_defined?(name)
- define_method(name) do |*args|
- self.class.send(name, *args)
- end
- end
+ end
+
+ def self.specificity
+ (@defaults.length * 100) + ancestors.select { |a| a.is_a? Class }.length
+ end
+
+ def self.initvars
+ @defaults = {}
+ @commands = {}
+ end
+
+ # The method for returning a list of provider instances. Note that it returns providers, preferably with values already
+ # filled in, not resources.
+ def self.instances
+ raise Puppet::DevError, "Provider #{self.name} has not defined the 'instances' class method"
+ end
+
+ # Create the methods for a given command.
+ def self.make_command_methods(name)
+ # Now define a method for that command
+ unless singleton_class.method_defined?(name)
+ meta_def(name) do |*args|
+ raise Puppet::Error, "Command #{name} is missing" unless command(name)
+ if args.empty?
+ cmd = [command(name)]
+ else
+ cmd = [command(name)] + args
end
- end
-
- # Create getter/setter methods for each property our resource type supports.
- # They all get stored in @property_hash. This method is useful
- # for those providers that use prefetch and flush.
- def self.mkmodelmethods
- warnonce "Provider.mkmodelmethods is deprecated; use Provider.mk_resource_methods"
- mk_resource_methods
- end
-
- # Create getter/setter methods for each property our resource type supports.
- # They all get stored in @property_hash. This method is useful
- # for those providers that use prefetch and flush.
- def self.mk_resource_methods
- [resource_type.validproperties, resource_type.parameters].flatten.each do |attr|
- attr = symbolize(attr)
- next if attr == :name
- define_method(attr) do
- @property_hash[attr] || :absent
- end
-
- define_method(attr.to_s + "=") do |val|
- @property_hash[attr] = val
- end
+ # This might throw an ExecutionFailure, but the system above
+ # will catch it, if so.
+ return execute(cmd)
+ end
+
+ # And then define an instance method that just calls the class method.
+ # We need both, so both instances and classes can easily run the commands.
+ unless method_defined?(name)
+ define_method(name) do |*args|
+ self.class.send(name, *args)
end
+ end
+ end
+ end
+
+ # Create getter/setter methods for each property our resource type supports.
+ # They all get stored in @property_hash. This method is useful
+ # for those providers that use prefetch and flush.
+ def self.mkmodelmethods
+ warnonce "Provider.mkmodelmethods is deprecated; use Provider.mk_resource_methods"
+ mk_resource_methods
+ end
+
+ # Create getter/setter methods for each property our resource type supports.
+ # They all get stored in @property_hash. This method is useful
+ # for those providers that use prefetch and flush.
+ def self.mk_resource_methods
+ [resource_type.validproperties, resource_type.parameters].flatten.each do |attr|
+ attr = symbolize(attr)
+ next if attr == :name
+ define_method(attr) do
+ @property_hash[attr] || :absent
+ end
+
+ define_method(attr.to_s + "=") do |val|
+ @property_hash[attr] = val
+ end
end
+ end
- self.initvars
+ self.initvars
- # Define one or more binaries we'll be using. If a block is passed, yield the name
- # and path to the block (really only used by 'commands').
- def self.optional_commands(hash)
- hash.each do |name, path|
- name = symbolize(name)
- @commands[name] = path
+ # Define one or more binaries we'll be using. If a block is passed, yield the name
+ # and path to the block (really only used by 'commands').
+ def self.optional_commands(hash)
+ hash.each do |name, path|
+ name = symbolize(name)
+ @commands[name] = path
- yield(name, path) if block_given?
+ yield(name, path) if block_given?
- # Now define the class and instance methods.
- make_command_methods(name)
- end
+ # Now define the class and instance methods.
+ make_command_methods(name)
end
-
- # Retrieve the data source. Defaults to the provider name.
- def self.source
- @source ||= self.name
+ end
+
+ # Retrieve the data source. Defaults to the provider name.
+ def self.source
+ @source ||= self.name
+ end
+
+ # Does this provider support the specified parameter?
+ def self.supports_parameter?(param)
+ if param.is_a?(Class)
+ klass = param
+ else
+ unless klass = resource_type.attrclass(param)
+ raise Puppet::DevError, "'#{param}' is not a valid parameter for #{resource_type.name}"
+ end
end
+ return true unless features = klass.required_features
- # Does this provider support the specified parameter?
- def self.supports_parameter?(param)
- if param.is_a?(Class)
- klass = param
- else
- unless klass = resource_type.attrclass(param)
- raise Puppet::DevError, "'#{param}' is not a valid parameter for #{resource_type.name}"
- end
- end
- return true unless features = klass.required_features
-
- !!satisfies?(*features)
- end
+ !!satisfies?(*features)
+ end
# def self.to_s
# unless defined?(@str)
@@ -202,80 +202,80 @@ class Puppet::Provider
# @str
# end
- dochook(:defaults) do
- if @defaults.length > 0
- return " Default for " + @defaults.collect do |f, v|
- "``#{f}`` == ``#{v}``"
- end.join(" and ") + "."
- end
+ dochook(:defaults) do
+ if @defaults.length > 0
+ return " Default for " + @defaults.collect do |f, v|
+ "``#{f}`` == ``#{v}``"
+ end.join(" and ") + "."
end
+ end
- dochook(:commands) do
- if @commands.length > 0
- return " Required binaries: " + @commands.collect do |n, c|
- "``#{c}``"
- end.join(", ") + "."
- end
+ dochook(:commands) do
+ if @commands.length > 0
+ return " Required binaries: " + @commands.collect do |n, c|
+ "``#{c}``"
+ end.join(", ") + "."
end
+ end
- dochook(:features) do
- if features.length > 0
- return " Supported features: " + features.collect do |f|
- "``#{f}``"
- end.join(", ") + "."
- end
+ dochook(:features) do
+ if features.length > 0
+ return " Supported features: " + features.collect do |f|
+ "``#{f}``"
+ end.join(", ") + "."
end
-
- # Remove the reference to the resource, so GC can clean up.
- def clear
- @resource = nil
- @model = nil
+ end
+
+ # Remove the reference to the resource, so GC can clean up.
+ def clear
+ @resource = nil
+ @model = nil
+ end
+
+ # Retrieve a named command.
+ def command(name)
+ self.class.command(name)
+ end
+
+ # Get a parameter value.
+ def get(param)
+ @property_hash[symbolize(param)] || :absent
+ end
+
+ def initialize(resource = nil)
+ if resource.is_a?(Hash)
+ # We don't use a duplicate here, because some providers (ParsedFile, at least)
+ # use the hash here for later events.
+ @property_hash = resource
+ elsif resource
+ @resource = resource
+ # LAK 2007-05-09: Keep the model stuff around for backward compatibility
+ @model = resource
+ @property_hash = {}
+ else
+ @property_hash = {}
end
-
- # Retrieve a named command.
- def command(name)
- self.class.command(name)
+ end
+
+ def name
+ if n = @property_hash[:name]
+ return n
+ elsif self.resource
+ resource.name
+ else
+ raise Puppet::DevError, "No resource and no name in property hash in #{self.class.name} instance"
end
+ end
- # Get a parameter value.
- def get(param)
- @property_hash[symbolize(param)] || :absent
+ # Set passed params as the current values.
+ def set(params)
+ params.each do |param, value|
+ @property_hash[symbolize(param)] = value
end
+ end
- def initialize(resource = nil)
- if resource.is_a?(Hash)
- # We don't use a duplicate here, because some providers (ParsedFile, at least)
- # use the hash here for later events.
- @property_hash = resource
- elsif resource
- @resource = resource
- # LAK 2007-05-09: Keep the model stuff around for backward compatibility
- @model = resource
- @property_hash = {}
- else
- @property_hash = {}
- end
- end
-
- def name
- if n = @property_hash[:name]
- return n
- elsif self.resource
- resource.name
- else
- raise Puppet::DevError, "No resource and no name in property hash in #{self.class.name} instance"
- end
- end
-
- # Set passed params as the current values.
- def set(params)
- params.each do |param, value|
- @property_hash[symbolize(param)] = value
- end
- end
-
- def to_s
- "#{@resource}(provider=#{self.class.name})"
- end
+ def to_s
+ "#{@resource}(provider=#{self.class.name})"
+ end
end
diff --git a/lib/puppet/provider/augeas/augeas.rb b/lib/puppet/provider/augeas/augeas.rb
index 4fff9e2..7dbd062 100644
--- a/lib/puppet/provider/augeas/augeas.rb
+++ b/lib/puppet/provider/augeas/augeas.rb
@@ -21,341 +21,341 @@ require 'augeas' if Puppet.features.augeas?
require 'strscan'
Puppet::Type.type(:augeas).provide(:augeas) do
- include Puppet::Util
-
- confine :true => Puppet.features.augeas?
-
- has_features :parse_commands, :need_to_run?,:execute_changes
-
- SAVE_NOOP = "noop"
- SAVE_OVERWRITE = "overwrite"
-
- COMMANDS = {
- "set" => [ :path, :string ],
- "rm" => [ :path ],
- "clear" => [ :path ],
- "insert" => [ :string, :string, :path ],
- "get" => [ :path, :comparator, :string ],
- "match" => [ :path, :glob ],
- "size" => [:comparator, :int],
- "include" => [:string],
- "not_include" => [:string],
- "==" => [:glob],
- "!=" => [:glob]
- }
-
- COMMANDS["ins"] = COMMANDS["insert"]
- COMMANDS["remove"] = COMMANDS["rm"]
-
- attr_accessor :aug
-
- # Extracts an 2 dimensional array of commands which are in the
- # form of command path value.
- # The input can be
- # - A string with one command
- # - A string with many commands per line
- # - An array of strings.
- def parse_commands(data)
- context = resource[:context]
- # Add a trailing / if it is not there
- if (context.length > 0)
- context << "/" if context[-1, 1] != "/"
- end
-
- data = data.split($/) if data.is_a?(String)
- data = data.flatten
- args = []
- data.each do |line|
- line.strip!
- next if line.nil? || line.empty?
- argline = []
- sc = StringScanner.new(line)
- cmd = sc.scan(/\w+|==|!=/)
- formals = COMMANDS[cmd]
- fail("Unknown command #{cmd}") unless formals
- argline << cmd
- narg = 0
- formals.each do |f|
- sc.skip(/\s+/)
- narg += 1
- if f == :path
- start = sc.pos
- nbracket = 0
- inSingleTick = false
- inDoubleTick = false
- begin
- sc.skip(/([^\]\[\s\\'"]|\\.)+/)
- ch = sc.getch
- nbracket += 1 if ch == "["
- nbracket -= 1 if ch == "]"
- inSingleTick = !inSingleTick if ch == "'"
- inDoubleTick = !inDoubleTick if ch == "\""
- fail("unmatched [") if nbracket < 0
- end until ((nbracket == 0 && !inSingleTick && !inDoubleTick && (ch =~ /\s/)) || sc.eos?)
- len = sc.pos - start
- len -= 1 unless sc.eos?
- unless p = sc.string[start, len]
- fail("missing path argument #{narg} for #{cmd}")
- end
- # Rip off any ticks if they are there.
- p = p[1, (p.size - 2)] if p[0,1] == "'" || p[0,1] == "\""
- p.chomp!("/")
- if p[0,1] != '$' && p[0,1] != "/"
- argline << context + p
- else
- argline << p
- end
- elsif f == :string
- delim = sc.peek(1)
- if delim == "'" || delim == "\""
- sc.getch
- argline << sc.scan(/([^\\#{delim}]|(\\.))*/)
- sc.getch
- else
- argline << sc.scan(/[^\s]+/)
- end
- fail("missing string argument #{narg} for #{cmd}") unless argline[-1]
- elsif f == :comparator
- argline << sc.scan(/(==|!=|=~|<|<=|>|>=)/)
- unless argline[-1]
- puts sc.rest
- fail("invalid comparator for command #{cmd}")
- end
- elsif f == :int
- argline << sc.scan(/\d+/).to_i
- elsif f== :glob
- argline << sc.rest
- end
- end
- args << argline
- end
- args
+ include Puppet::Util
+
+ confine :true => Puppet.features.augeas?
+
+ has_features :parse_commands, :need_to_run?,:execute_changes
+
+ SAVE_NOOP = "noop"
+ SAVE_OVERWRITE = "overwrite"
+
+ COMMANDS = {
+ "set" => [ :path, :string ],
+ "rm" => [ :path ],
+ "clear" => [ :path ],
+ "insert" => [ :string, :string, :path ],
+ "get" => [ :path, :comparator, :string ],
+ "match" => [ :path, :glob ],
+ "size" => [:comparator, :int],
+ "include" => [:string],
+ "not_include" => [:string],
+ "==" => [:glob],
+ "!=" => [:glob]
+ }
+
+ COMMANDS["ins"] = COMMANDS["insert"]
+ COMMANDS["remove"] = COMMANDS["rm"]
+
+ attr_accessor :aug
+
+ # Extracts an 2 dimensional array of commands which are in the
+ # form of command path value.
+ # The input can be
+ # - A string with one command
+ # - A string with many commands per line
+ # - An array of strings.
+ def parse_commands(data)
+ context = resource[:context]
+ # Add a trailing / if it is not there
+ if (context.length > 0)
+ context << "/" if context[-1, 1] != "/"
end
-
- def open_augeas
- unless @aug
- flags = Augeas::NONE
- flags = Augeas::TYPE_CHECK if resource[:type_check] == :true
- flags |= Augeas::NO_MODL_AUTOLOAD if resource[:incl]
- root = resource[:root]
- load_path = resource[:load_path]
- debug("Opening augeas with root #{root}, lens path #{load_path}, flags #{flags}")
- @aug = Augeas::open(root, load_path,flags)
-
- debug("Augeas version #{get_augeas_version} is installed") if get_augeas_version >= "0.3.6"
-
- if resource[:incl]
- aug.set("/augeas/load/Xfm/lens", resource[:lens])
- aug.set("/augeas/load/Xfm/incl", resource[:incl])
- aug.load
- end
+ data = data.split($/) if data.is_a?(String)
+ data = data.flatten
+ args = []
+ data.each do |line|
+ line.strip!
+ next if line.nil? || line.empty?
+ argline = []
+ sc = StringScanner.new(line)
+ cmd = sc.scan(/\w+|==|!=/)
+ formals = COMMANDS[cmd]
+ fail("Unknown command #{cmd}") unless formals
+ argline << cmd
+ narg = 0
+ formals.each do |f|
+ sc.skip(/\s+/)
+ narg += 1
+ if f == :path
+ start = sc.pos
+ nbracket = 0
+ inSingleTick = false
+ inDoubleTick = false
+ begin
+ sc.skip(/([^\]\[\s\\'"]|\\.)+/)
+ ch = sc.getch
+ nbracket += 1 if ch == "["
+ nbracket -= 1 if ch == "]"
+ inSingleTick = !inSingleTick if ch == "'"
+ inDoubleTick = !inDoubleTick if ch == "\""
+ fail("unmatched [") if nbracket < 0
+ end until ((nbracket == 0 && !inSingleTick && !inDoubleTick && (ch =~ /\s/)) || sc.eos?)
+ len = sc.pos - start
+ len -= 1 unless sc.eos?
+ unless p = sc.string[start, len]
+ fail("missing path argument #{narg} for #{cmd}")
+ end
+ # Rip off any ticks if they are there.
+ p = p[1, (p.size - 2)] if p[0,1] == "'" || p[0,1] == "\""
+ p.chomp!("/")
+ if p[0,1] != '$' && p[0,1] != "/"
+ argline << context + p
+ else
+ argline << p
+ end
+ elsif f == :string
+ delim = sc.peek(1)
+ if delim == "'" || delim == "\""
+ sc.getch
+ argline << sc.scan(/([^\\#{delim}]|(\\.))*/)
+ sc.getch
+ else
+ argline << sc.scan(/[^\s]+/)
+ end
+ fail("missing string argument #{narg} for #{cmd}") unless argline[-1]
+ elsif f == :comparator
+ argline << sc.scan(/(==|!=|=~|<|<=|>|>=)/)
+ unless argline[-1]
+ puts sc.rest
+ fail("invalid comparator for command #{cmd}")
+ end
+ elsif f == :int
+ argline << sc.scan(/\d+/).to_i
+ elsif f== :glob
+ argline << sc.rest
end
- @aug
+ end
+ args << argline
end
-
- def close_augeas
- if @aug
- @aug.close
- debug("Closed the augeas connection")
- @aug = nil
- end
+ args
+ end
+
+
+ def open_augeas
+ unless @aug
+ flags = Augeas::NONE
+ flags = Augeas::TYPE_CHECK if resource[:type_check] == :true
+ flags |= Augeas::NO_MODL_AUTOLOAD if resource[:incl]
+ root = resource[:root]
+ load_path = resource[:load_path]
+ debug("Opening augeas with root #{root}, lens path #{load_path}, flags #{flags}")
+ @aug = Augeas::open(root, load_path,flags)
+
+ debug("Augeas version #{get_augeas_version} is installed") if get_augeas_version >= "0.3.6"
+
+ if resource[:incl]
+ aug.set("/augeas/load/Xfm/lens", resource[:lens])
+ aug.set("/augeas/load/Xfm/incl", resource[:incl])
+ aug.load
+ end
end
-
- # Used by the need_to_run? method to process get filters. Returns
- # true if there is a match, false if otherwise
- # Assumes a syntax of get /files/path [COMPARATOR] value
- def process_get(cmd_array)
- return_value = false
-
- #validate and tear apart the command
- fail ("Invalid command: #{cmd_array.join(" ")}") if cmd_array.length < 4
- cmd = cmd_array.shift
- path = cmd_array.shift
- comparator = cmd_array.shift
- arg = cmd_array.join(" ")
-
- #check the value in augeas
- result = @aug.get(path) || ''
- case comparator
- when "!="
- return_value = (result != arg)
- when "=~"
- regex = Regexp.new(arg)
- return_value = (result =~ regex)
- else
- return_value = (result.send(comparator, arg))
- end
- !!return_value
+ @aug
+ end
+
+ def close_augeas
+ if @aug
+ @aug.close
+ debug("Closed the augeas connection")
+ @aug = nil
end
-
- # Used by the need_to_run? method to process match filters. Returns
- # true if there is a match, false if otherwise
- def process_match(cmd_array)
- return_value = false
-
- #validate and tear apart the command
- fail("Invalid command: #{cmd_array.join(" ")}") if cmd_array.length < 3
- cmd = cmd_array.shift
- path = cmd_array.shift
-
- # Need to break apart the clause
- clause_array = parse_commands(cmd_array.shift)[0]
- verb = clause_array.shift
-
- #Get the values from augeas
- result = @aug.match(path) || []
- fail("Error trying to match path '#{path}'") if (result == -1)
-
- # Now do the work
- case verb
- when "size"
- fail("Invalid command: #{cmd_array.join(" ")}") if clause_array.length != 2
- comparator = clause_array.shift
- arg = clause_array.shift
- return_value = (result.size.send(comparator, arg))
- when "include"
- arg = clause_array.shift
- return_value = result.include?(arg)
- when "not_include"
- arg = clause_array.shift
- return_value = !result.include?(arg)
- when "=="
- begin
- arg = clause_array.shift
- new_array = eval arg
- return_value = (result == new_array)
- rescue
- fail("Invalid array in command: #{cmd_array.join(" ")}")
- end
- when "!="
- begin
- arg = clause_array.shift
- new_array = eval arg
- return_value = (result != new_array)
- rescue
- fail("Invalid array in command: #{cmd_array.join(" ")}")
- end
- end
- !!return_value
- end
-
- def get_augeas_version
- @aug.get("/augeas/version") || ""
+ end
+
+ # Used by the need_to_run? method to process get filters. Returns
+ # true if there is a match, false if otherwise
+ # Assumes a syntax of get /files/path [COMPARATOR] value
+ def process_get(cmd_array)
+ return_value = false
+
+ #validate and tear apart the command
+ fail ("Invalid command: #{cmd_array.join(" ")}") if cmd_array.length < 4
+ cmd = cmd_array.shift
+ path = cmd_array.shift
+ comparator = cmd_array.shift
+ arg = cmd_array.join(" ")
+
+ #check the value in augeas
+ result = @aug.get(path) || ''
+ case comparator
+ when "!="
+ return_value = (result != arg)
+ when "=~"
+ regex = Regexp.new(arg)
+ return_value = (result =~ regex)
+ else
+ return_value = (result.send(comparator, arg))
end
-
- def set_augeas_save_mode(mode)
- @aug.set("/augeas/save", mode)
+ !!return_value
+ end
+
+ # Used by the need_to_run? method to process match filters. Returns
+ # true if there is a match, false if otherwise
+ def process_match(cmd_array)
+ return_value = false
+
+ #validate and tear apart the command
+ fail("Invalid command: #{cmd_array.join(" ")}") if cmd_array.length < 3
+ cmd = cmd_array.shift
+ path = cmd_array.shift
+
+ # Need to break apart the clause
+ clause_array = parse_commands(cmd_array.shift)[0]
+ verb = clause_array.shift
+
+ #Get the values from augeas
+ result = @aug.match(path) || []
+ fail("Error trying to match path '#{path}'") if (result == -1)
+
+ # Now do the work
+ case verb
+ when "size"
+ fail("Invalid command: #{cmd_array.join(" ")}") if clause_array.length != 2
+ comparator = clause_array.shift
+ arg = clause_array.shift
+ return_value = (result.size.send(comparator, arg))
+ when "include"
+ arg = clause_array.shift
+ return_value = result.include?(arg)
+ when "not_include"
+ arg = clause_array.shift
+ return_value = !result.include?(arg)
+ when "=="
+ begin
+ arg = clause_array.shift
+ new_array = eval arg
+ return_value = (result == new_array)
+ rescue
+ fail("Invalid array in command: #{cmd_array.join(" ")}")
+ end
+ when "!="
+ begin
+ arg = clause_array.shift
+ new_array = eval arg
+ return_value = (result != new_array)
+ rescue
+ fail("Invalid array in command: #{cmd_array.join(" ")}")
+ end
end
-
- def files_changed?
- saved_files = @aug.match("/augeas/events/saved")
- saved_files.size > 0
- end
-
- # Determines if augeas acutally needs to run.
- def need_to_run?
- force = resource[:force]
- return_value = true
+ !!return_value
+ end
+
+ def get_augeas_version
+ @aug.get("/augeas/version") || ""
+ end
+
+ def set_augeas_save_mode(mode)
+ @aug.set("/augeas/save", mode)
+ end
+
+ def files_changed?
+ saved_files = @aug.match("/augeas/events/saved")
+ saved_files.size > 0
+ end
+
+ # Determines if augeas acutally needs to run.
+ def need_to_run?
+ force = resource[:force]
+ return_value = true
+ begin
+ open_augeas
+ filter = resource[:onlyif]
+ unless filter == ""
+ cmd_array = parse_commands(filter)[0]
+ command = cmd_array[0];
begin
- open_augeas
- filter = resource[:onlyif]
- unless filter == ""
- cmd_array = parse_commands(filter)[0]
- command = cmd_array[0];
- begin
- case command
- when "get"; return_value = process_get(cmd_array)
- when "match"; return_value = process_match(cmd_array)
- end
- rescue SystemExit,NoMemoryError
- raise
- rescue Exception => e
- fail("Error sending command '#{command}' with params #{cmd_array[1..-1].inspect}/#{e.message}")
- end
- end
-
- unless force
- # If we have a verison of augeas which is at least 0.3.6 then we
- # can make the changes now, see if changes were made, and
- # actually do the save.
- if return_value and get_augeas_version >= "0.3.6"
- debug("Will attempt to save and only run if files changed")
- set_augeas_save_mode(SAVE_NOOP)
- do_execute_changes
- save_result = @aug.save
- saved_files = @aug.match("/augeas/events/saved")
- if save_result and not files_changed?
- debug("Skipping because no files were changed")
- return_value = false
- else
- debug("Files changed, should execute")
- end
- end
- end
- ensure
- close_augeas
+ case command
+ when "get"; return_value = process_get(cmd_array)
+ when "match"; return_value = process_match(cmd_array)
+ end
+ rescue SystemExit,NoMemoryError
+ raise
+ rescue Exception => e
+ fail("Error sending command '#{command}' with params #{cmd_array[1..-1].inspect}/#{e.message}")
+ end
+ end
+
+ unless force
+ # If we have a verison of augeas which is at least 0.3.6 then we
+ # can make the changes now, see if changes were made, and
+ # actually do the save.
+ if return_value and get_augeas_version >= "0.3.6"
+ debug("Will attempt to save and only run if files changed")
+ set_augeas_save_mode(SAVE_NOOP)
+ do_execute_changes
+ save_result = @aug.save
+ saved_files = @aug.match("/augeas/events/saved")
+ if save_result and not files_changed?
+ debug("Skipping because no files were changed")
+ return_value = false
+ else
+ debug("Files changed, should execute")
+ end
end
- return_value
+ end
+ ensure
+ close_augeas
end
+ return_value
+ end
- def execute_changes
- # Re-connect to augeas, and re-execute the changes
- begin
- open_augeas
- set_augeas_save_mode(SAVE_OVERWRITE) if get_augeas_version >= "0.3.6"
-
- do_execute_changes
+ def execute_changes
+ # Re-connect to augeas, and re-execute the changes
+ begin
+ open_augeas
+ set_augeas_save_mode(SAVE_OVERWRITE) if get_augeas_version >= "0.3.6"
- success = @aug.save
- fail("Save failed with return code #{success}") if success != true
- ensure
- close_augeas
- end
+ do_execute_changes
- :executed
+ success = @aug.save
+ fail("Save failed with return code #{success}") if success != true
+ ensure
+ close_augeas
end
- # Actually execute the augeas changes.
- def do_execute_changes
- commands = parse_commands(resource[:changes])
- commands.each do |cmd_array|
- fail("invalid command #{cmd_array.join[" "]}") if cmd_array.length < 2
- command = cmd_array[0]
- cmd_array.shift
- begin
- case command
- when "set"
- debug("sending command '#{command}' with params #{cmd_array.inspect}")
- rv = aug.set(cmd_array[0], cmd_array[1])
- fail("Error sending command '#{command}' with params #{cmd_array.inspect}") if (!rv)
- when "rm", "remove"
- debug("sending command '#{command}' with params #{cmd_array.inspect}")
- rv = aug.rm(cmd_array[0])
- fail("Error sending command '#{command}' with params #{cmd_array.inspect}") if (rv == -1)
- when "clear"
- debug("sending command '#{command}' with params #{cmd_array.inspect}")
- rv = aug.clear(cmd_array[0])
- fail("Error sending command '#{command}' with params #{cmd_array.inspect}") if (!rv)
- when "insert", "ins"
- label = cmd_array[0]
- where = cmd_array[1]
- path = cmd_array[2]
- case where
- when "before"; before = true
- when "after"; before = false
- else fail("Invalid value '#{where}' for where param")
- end
- debug("sending command '#{command}' with params #{[label, where, path].inspect}")
- rv = aug.insert(path, label, before)
- fail("Error sending command '#{command}' with params #{cmd_array.inspect}") if (rv == -1)
- else fail("Command '#{command}' is not supported")
- end
- rescue SystemExit,NoMemoryError
- raise
- rescue Exception => e
- fail("Error sending command '#{command}' with params #{cmd_array.inspect}/#{e.message}")
+ :executed
+ end
+
+ # Actually execute the augeas changes.
+ def do_execute_changes
+ commands = parse_commands(resource[:changes])
+ commands.each do |cmd_array|
+ fail("invalid command #{cmd_array.join[" "]}") if cmd_array.length < 2
+ command = cmd_array[0]
+ cmd_array.shift
+ begin
+ case command
+ when "set"
+ debug("sending command '#{command}' with params #{cmd_array.inspect}")
+ rv = aug.set(cmd_array[0], cmd_array[1])
+ fail("Error sending command '#{command}' with params #{cmd_array.inspect}") if (!rv)
+ when "rm", "remove"
+ debug("sending command '#{command}' with params #{cmd_array.inspect}")
+ rv = aug.rm(cmd_array[0])
+ fail("Error sending command '#{command}' with params #{cmd_array.inspect}") if (rv == -1)
+ when "clear"
+ debug("sending command '#{command}' with params #{cmd_array.inspect}")
+ rv = aug.clear(cmd_array[0])
+ fail("Error sending command '#{command}' with params #{cmd_array.inspect}") if (!rv)
+ when "insert", "ins"
+ label = cmd_array[0]
+ where = cmd_array[1]
+ path = cmd_array[2]
+ case where
+ when "before"; before = true
+ when "after"; before = false
+ else fail("Invalid value '#{where}' for where param")
end
+ debug("sending command '#{command}' with params #{[label, where, path].inspect}")
+ rv = aug.insert(path, label, before)
+ fail("Error sending command '#{command}' with params #{cmd_array.inspect}") if (rv == -1)
+ else fail("Command '#{command}' is not supported")
end
+ rescue SystemExit,NoMemoryError
+ raise
+ rescue Exception => e
+ fail("Error sending command '#{command}' with params #{cmd_array.inspect}/#{e.message}")
+ end
end
+ end
end
diff --git a/lib/puppet/provider/computer/computer.rb b/lib/puppet/provider/computer/computer.rb
index 73f2d2b..a6be6bd 100644
--- a/lib/puppet/provider/computer/computer.rb
+++ b/lib/puppet/provider/computer/computer.rb
@@ -1,22 +1,22 @@
require 'puppet/provider/nameservice/directoryservice'
Puppet::Type.type(:computer).provide :directoryservice, :parent => Puppet::Provider::NameService::DirectoryService do
- desc "Computer object management using DirectoryService on OS X.
- Note that these are distinctly different kinds of objects to 'hosts',
- as they require a MAC address and can have all sorts of policy attached to
- them.
+ desc "Computer object management using DirectoryService on OS X.
+ Note that these are distinctly different kinds of objects to 'hosts',
+ as they require a MAC address and can have all sorts of policy attached to
+ them.
- This provider only manages Computer objects in the local directory service
- domain, not in remote directories.
+ This provider only manages Computer objects in the local directory service
+ domain, not in remote directories.
- If you wish to manage /etc/hosts on Mac OS X, then simply use the host
- type as per other platforms.
+ If you wish to manage /etc/hosts on Mac OS X, then simply use the host
+ type as per other platforms.
- "
+ "
- confine :operatingsystem => :darwin
- defaultfor :operatingsystem => :darwin
+ confine :operatingsystem => :darwin
+ defaultfor :operatingsystem => :darwin
- # hurray for abstraction. The nameservice directoryservice provider can
- # handle everything we need. super.
+ # hurray for abstraction. The nameservice directoryservice provider can
+ # handle everything we need. super.
end
diff --git a/lib/puppet/provider/confine.rb b/lib/puppet/provider/confine.rb
index e75bc5c..6825def 100644
--- a/lib/puppet/provider/confine.rb
+++ b/lib/puppet/provider/confine.rb
@@ -3,78 +3,78 @@
require 'puppet/util'
class Puppet::Provider::Confine
- include Puppet::Util
+ include Puppet::Util
- @tests = {}
+ @tests = {}
- class << self
- attr_accessor :name
- end
+ class << self
+ attr_accessor :name
+ end
- def self.inherited(klass)
- name = klass.to_s.split("::").pop.downcase.to_sym
- raise "Test #{name} is already defined" if @tests.include?(name)
+ def self.inherited(klass)
+ name = klass.to_s.split("::").pop.downcase.to_sym
+ raise "Test #{name} is already defined" if @tests.include?(name)
- klass.name = name
+ klass.name = name
- @tests[name] = klass
- end
+ @tests[name] = klass
+ end
- def self.test(name)
- unless @tests[name]
- begin
- require "puppet/provider/confine/#{name}"
- rescue LoadError => detail
- unless detail.to_s =~ /No such file/i
- warn "Could not load confine test '#{name}': #{detail}"
- end
- # Could not find file
- end
+ def self.test(name)
+ unless @tests[name]
+ begin
+ require "puppet/provider/confine/#{name}"
+ rescue LoadError => detail
+ unless detail.to_s =~ /No such file/i
+ warn "Could not load confine test '#{name}': #{detail}"
end
- @tests[name]
- end
-
- attr_reader :values
-
- # Mark that this confine is used for testing binary existence.
- attr_accessor :for_binary
- def for_binary?
- for_binary
+ # Could not find file
+ end
end
-
- # Used for logging.
- attr_accessor :label
-
- def initialize(values)
- values = [values] unless values.is_a?(Array)
- @values = values
+ @tests[name]
+ end
+
+ attr_reader :values
+
+ # Mark that this confine is used for testing binary existence.
+ attr_accessor :for_binary
+ def for_binary?
+ for_binary
+ end
+
+ # Used for logging.
+ attr_accessor :label
+
+ def initialize(values)
+ values = [values] unless values.is_a?(Array)
+ @values = values
+ end
+
+ # Provide a hook for the message when there's a failure.
+ def message(value)
+ ""
+ end
+
+ # Collect the results of all of them.
+ def result
+ values.collect { |value| pass?(value) }
+ end
+
+ # Test whether our confine matches.
+ def valid?
+ values.each do |value|
+ unless pass?(value)
+ Puppet.debug(label + ": " + message(value))
+ return false
+ end
end
- # Provide a hook for the message when there's a failure.
- def message(value)
- ""
- end
+ return true
+ ensure
+ reset
+ end
- # Collect the results of all of them.
- def result
- values.collect { |value| pass?(value) }
- end
-
- # Test whether our confine matches.
- def valid?
- values.each do |value|
- unless pass?(value)
- Puppet.debug(label + ": " + message(value))
- return false
- end
- end
-
- return true
- ensure
- reset
- end
-
- # Provide a hook for subclasses.
- def reset
- end
+ # Provide a hook for subclasses.
+ def reset
+ end
end
diff --git a/lib/puppet/provider/confine/exists.rb b/lib/puppet/provider/confine/exists.rb
index 27c404a..085118b 100644
--- a/lib/puppet/provider/confine/exists.rb
+++ b/lib/puppet/provider/confine/exists.rb
@@ -1,22 +1,22 @@
require 'puppet/provider/confine'
class Puppet::Provider::Confine::Exists < Puppet::Provider::Confine
- def self.summarize(confines)
- confines.inject([]) { |total, confine| total + confine.summary }
- end
+ def self.summarize(confines)
+ confines.inject([]) { |total, confine| total + confine.summary }
+ end
- def pass?(value)
- if for_binary?
- return false unless value = binary(value)
- end
- value and FileTest.exist?(value)
+ def pass?(value)
+ if for_binary?
+ return false unless value = binary(value)
end
+ value and FileTest.exist?(value)
+ end
- def message(value)
- "file #{value} does not exist"
- end
+ def message(value)
+ "file #{value} does not exist"
+ end
- def summary
- result.zip(values).inject([]) { |array, args| val, f = args; array << f unless val; array }
- end
+ def summary
+ result.zip(values).inject([]) { |array, args| val, f = args; array << f unless val; array }
+ end
end
diff --git a/lib/puppet/provider/confine/false.rb b/lib/puppet/provider/confine/false.rb
index b5b2b51..1c11dd4 100644
--- a/lib/puppet/provider/confine/false.rb
+++ b/lib/puppet/provider/confine/false.rb
@@ -1,19 +1,19 @@
require 'puppet/provider/confine'
class Puppet::Provider::Confine::False < Puppet::Provider::Confine
- def self.summarize(confines)
- confines.inject(0) { |count, confine| count + confine.summary }
- end
+ def self.summarize(confines)
+ confines.inject(0) { |count, confine| count + confine.summary }
+ end
- def pass?(value)
- ! value
- end
+ def pass?(value)
+ ! value
+ end
- def message(value)
- "true value when expecting false"
- end
+ def message(value)
+ "true value when expecting false"
+ end
- def summary
- result.find_all { |v| v == false }.length
- end
+ def summary
+ result.find_all { |v| v == false }.length
+ end
end
diff --git a/lib/puppet/provider/confine/feature.rb b/lib/puppet/provider/confine/feature.rb
index 8cd5daa..b223b8b 100644
--- a/lib/puppet/provider/confine/feature.rb
+++ b/lib/puppet/provider/confine/feature.rb
@@ -1,17 +1,17 @@
require 'puppet/provider/confine'
class Puppet::Provider::Confine::Feature < Puppet::Provider::Confine
- def self.summarize(confines)
- confines.collect { |c| c.values }.flatten.uniq.find_all { |value| ! confines[0].pass?(value) }
- end
+ def self.summarize(confines)
+ confines.collect { |c| c.values }.flatten.uniq.find_all { |value| ! confines[0].pass?(value) }
+ end
- # Is the named feature available?
- def pass?(value)
- Puppet.features.send(value.to_s + "?")
- end
+ # Is the named feature available?
+ def pass?(value)
+ Puppet.features.send(value.to_s + "?")
+ end
- def message(value)
- "feature #{value} is missing"
- end
+ def message(value)
+ "feature #{value} is missing"
+ end
end
diff --git a/lib/puppet/provider/confine/true.rb b/lib/puppet/provider/confine/true.rb
index 86b3b14..559f267 100644
--- a/lib/puppet/provider/confine/true.rb
+++ b/lib/puppet/provider/confine/true.rb
@@ -1,20 +1,20 @@
require 'puppet/provider/confine'
class Puppet::Provider::Confine::True < Puppet::Provider::Confine
- def self.summarize(confines)
- confines.inject(0) { |count, confine| count + confine.summary }
- end
+ def self.summarize(confines)
+ confines.inject(0) { |count, confine| count + confine.summary }
+ end
- def pass?(value)
- # Double negate, so we only get true or false.
- ! ! value
- end
+ def pass?(value)
+ # Double negate, so we only get true or false.
+ ! ! value
+ end
- def message(value)
- "false value when expecting true"
- end
+ def message(value)
+ "false value when expecting true"
+ end
- def summary
- result.find_all { |v| v == true }.length
- end
+ def summary
+ result.find_all { |v| v == true }.length
+ end
end
diff --git a/lib/puppet/provider/confine/variable.rb b/lib/puppet/provider/confine/variable.rb
index 84f7e40..af8e5d3 100644
--- a/lib/puppet/provider/confine/variable.rb
+++ b/lib/puppet/provider/confine/variable.rb
@@ -5,55 +5,55 @@ require 'puppet/provider/confine'
# is set explicitly by the ConfineCollection class -- from this class,
# it's not obvious how the name would ever get set.
class Puppet::Provider::Confine::Variable < Puppet::Provider::Confine
- # Provide a hash summary of failing confines -- the key of the hash
- # is the name of the confine, and the value is the missing yet required values.
- # Only returns failed values, not all required values.
- def self.summarize(confines)
- result = Hash.new { |hash, key| hash[key] = [] }
- confines.inject(result) { |total, confine| total[confine.name] += confine.values unless confine.valid?; total }
- end
-
- # This is set by ConfineCollection.
- attr_accessor :name
-
- # Retrieve the value from facter
- def facter_value
- @facter_value ||= ::Facter.value(name).to_s.downcase
- end
-
- def initialize(values)
- super
- @values = @values.collect { |v| v.to_s.downcase }
- end
-
- def message(value)
- "facter value '#{test_value}' for '#{self.name}' not in required list '#{values.join(",")}'"
- end
-
- # Compare the passed-in value to the retrieved value.
- def pass?(value)
- test_value.downcase.to_s == value.to_s.downcase
- end
-
- def reset
- # Reset the cache. We want to cache it during a given
- # run, but not across runs.
- @facter_value = nil
- end
-
- def valid?
- @values.include?(test_value.to_s.downcase)
- ensure
- reset
- end
-
- private
-
- def setting?
- Puppet.settings.valid?(name)
- end
-
- def test_value
- setting? ? Puppet.settings[name] : facter_value
- end
+ # Provide a hash summary of failing confines -- the key of the hash
+ # is the name of the confine, and the value is the missing yet required values.
+ # Only returns failed values, not all required values.
+ def self.summarize(confines)
+ result = Hash.new { |hash, key| hash[key] = [] }
+ confines.inject(result) { |total, confine| total[confine.name] += confine.values unless confine.valid?; total }
+ end
+
+ # This is set by ConfineCollection.
+ attr_accessor :name
+
+ # Retrieve the value from facter
+ def facter_value
+ @facter_value ||= ::Facter.value(name).to_s.downcase
+ end
+
+ def initialize(values)
+ super
+ @values = @values.collect { |v| v.to_s.downcase }
+ end
+
+ def message(value)
+ "facter value '#{test_value}' for '#{self.name}' not in required list '#{values.join(",")}'"
+ end
+
+ # Compare the passed-in value to the retrieved value.
+ def pass?(value)
+ test_value.downcase.to_s == value.to_s.downcase
+ end
+
+ def reset
+ # Reset the cache. We want to cache it during a given
+ # run, but not across runs.
+ @facter_value = nil
+ end
+
+ def valid?
+ @values.include?(test_value.to_s.downcase)
+ ensure
+ reset
+ end
+
+ private
+
+ def setting?
+ Puppet.settings.valid?(name)
+ end
+
+ def test_value
+ setting? ? Puppet.settings[name] : facter_value
+ end
end
diff --git a/lib/puppet/provider/confine_collection.rb b/lib/puppet/provider/confine_collection.rb
index 0dbdc77..46fd3ba 100644
--- a/lib/puppet/provider/confine_collection.rb
+++ b/lib/puppet/provider/confine_collection.rb
@@ -3,48 +3,48 @@
require 'puppet/provider/confine'
class Puppet::Provider::ConfineCollection
- def confine(hash)
- if hash.include?(:for_binary)
- for_binary = true
- hash.delete(:for_binary)
- else
- for_binary = false
- end
- hash.each do |test, values|
- if klass = Puppet::Provider::Confine.test(test)
- @confines << klass.new(values)
- @confines[-1].for_binary = true if for_binary
- else
- confine = Puppet::Provider::Confine.test(:variable).new(values)
- confine.name = test
- @confines << confine
- end
- @confines[-1].label = self.label
- end
+ def confine(hash)
+ if hash.include?(:for_binary)
+ for_binary = true
+ hash.delete(:for_binary)
+ else
+ for_binary = false
end
-
- attr_reader :label
- def initialize(label)
- @label = label
- @confines = []
+ hash.each do |test, values|
+ if klass = Puppet::Provider::Confine.test(test)
+ @confines << klass.new(values)
+ @confines[-1].for_binary = true if for_binary
+ else
+ confine = Puppet::Provider::Confine.test(:variable).new(values)
+ confine.name = test
+ @confines << confine
+ end
+ @confines[-1].label = self.label
end
+ end
- # Return a hash of the whole confine set, used for the Provider
- # reference.
- def summary
- confines = Hash.new { |hash, key| hash[key] = [] }
- @confines.each { |confine| confines[confine.class] << confine }
- result = {}
- confines.each do |klass, list|
- value = klass.summarize(list)
- next if (value.respond_to?(:length) and value.length == 0) or (value == 0)
- result[klass.name] = value
+ attr_reader :label
+ def initialize(label)
+ @label = label
+ @confines = []
+ end
- end
- result
- end
+ # Return a hash of the whole confine set, used for the Provider
+ # reference.
+ def summary
+ confines = Hash.new { |hash, key| hash[key] = [] }
+ @confines.each { |confine| confines[confine.class] << confine }
+ result = {}
+ confines.each do |klass, list|
+ value = klass.summarize(list)
+ next if (value.respond_to?(:length) and value.length == 0) or (value == 0)
+ result[klass.name] = value
- def valid?
- ! @confines.detect { |c| ! c.valid? }
end
+ result
+ end
+
+ def valid?
+ ! @confines.detect { |c| ! c.valid? }
+ end
end
diff --git a/lib/puppet/provider/confiner.rb b/lib/puppet/provider/confiner.rb
index d776b68..6e1fb23 100644
--- a/lib/puppet/provider/confiner.rb
+++ b/lib/puppet/provider/confiner.rb
@@ -1,16 +1,16 @@
require 'puppet/provider/confine_collection'
module Puppet::Provider::Confiner
- def confine(hash)
- confine_collection.confine(hash)
- end
+ def confine(hash)
+ confine_collection.confine(hash)
+ end
- def confine_collection
- @confine_collection ||= Puppet::Provider::ConfineCollection.new(self.to_s)
- end
+ def confine_collection
+ @confine_collection ||= Puppet::Provider::ConfineCollection.new(self.to_s)
+ end
- # Check whether this implementation is suitable for our platform.
- def suitable?(short = true)
- return(short ? confine_collection.valid? : confine_collection.summary)
- end
+ # Check whether this implementation is suitable for our platform.
+ def suitable?(short = true)
+ return(short ? confine_collection.valid? : confine_collection.summary)
+ end
end
diff --git a/lib/puppet/provider/cron/crontab.rb b/lib/puppet/provider/cron/crontab.rb
index 7dd41c6..8a347b3 100755
--- a/lib/puppet/provider/cron/crontab.rb
+++ b/lib/puppet/provider/cron/crontab.rb
@@ -1,206 +1,206 @@
require 'puppet/provider/parsedfile'
tab = case Facter.value(:operatingsystem)
- when "Solaris"
- :suntab
- when "AIX"
- :aixtab
- else
- :crontab
- end
+ when "Solaris"
+ :suntab
+ when "AIX"
+ :aixtab
+ else
+ :crontab
+ end
- Puppet::Type.type(:cron).provide(
- :crontab,
- :parent => Puppet::Provider::ParsedFile,
- :default_target => ENV["USER"] || "root",
+ Puppet::Type.type(:cron).provide(
+ :crontab,
+ :parent => Puppet::Provider::ParsedFile,
+ :default_target => ENV["USER"] || "root",
- :filetype => tab
+ :filetype => tab
) do
- commands :crontab => "crontab"
+ commands :crontab => "crontab"
- text_line :comment, :match => %r{^#}, :post_parse => proc { |record|
- record[:name] = $1 if record[:line] =~ /Puppet Name: (.+)\s*$/
- }
+ text_line :comment, :match => %r{^#}, :post_parse => proc { |record|
+ record[:name] = $1 if record[:line] =~ /Puppet Name: (.+)\s*$/
+ }
- text_line :blank, :match => %r{^\s*$}
+ text_line :blank, :match => %r{^\s*$}
- text_line :environment, :match => %r{^\w+=}
+ text_line :environment, :match => %r{^\w+=}
- record_line :freebsd_special, :fields => %w{special command},
- :match => %r{^@(\w+)\s+(.+)$}, :pre_gen => proc { |record|
- record[:special] = "@" + record[:special]
- }
+ record_line :freebsd_special, :fields => %w{special command},
+ :match => %r{^@(\w+)\s+(.+)$}, :pre_gen => proc { |record|
+ record[:special] = "@" + record[:special]
+ }
- crontab = record_line :crontab, :fields => %w{minute hour monthday month weekday command},
- :match => %r{^\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.+)$},
- :optional => %w{minute hour weekday month monthday}, :absent => "*"
+ crontab = record_line :crontab, :fields => %w{minute hour monthday month weekday command},
+ :match => %r{^\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.+)$},
+ :optional => %w{minute hour weekday month monthday}, :absent => "*"
- class << crontab
- def numeric_fields
- fields - [:command]
- end
- # Do some post-processing of the parsed record. Basically just
- # split the numeric fields on ','.
- def post_parse(record)
- numeric_fields.each do |field|
- if val = record[field] and val != :absent
- record[field] = record[field].split(",")
- end
- end
+ class << crontab
+ def numeric_fields
+ fields - [:command]
+ end
+ # Do some post-processing of the parsed record. Basically just
+ # split the numeric fields on ','.
+ def post_parse(record)
+ numeric_fields.each do |field|
+ if val = record[field] and val != :absent
+ record[field] = record[field].split(",")
end
+ end
+ end
- # Join the fields back up based on ','.
- def pre_gen(record)
- numeric_fields.each do |field|
- if vals = record[field] and vals.is_a?(Array)
- record[field] = vals.join(",")
- end
- end
+ # Join the fields back up based on ','.
+ def pre_gen(record)
+ numeric_fields.each do |field|
+ if vals = record[field] and vals.is_a?(Array)
+ record[field] = vals.join(",")
end
+ end
+ end
- # Add name and environments as necessary.
- def to_line(record)
- str = ""
- str = "# Puppet Name: #{record[:name]}\n" if record[:name]
- if record[:environment] and record[:environment] != :absent and record[:environment] != [:absent]
- record[:environment].each do |env|
- str += env + "\n"
- end
- end
-
- if record[:special]
- str += "@#{record[:special]} #{record[:command]}"
- else
- str += join(record)
- end
- str
+ # Add name and environments as necessary.
+ def to_line(record)
+ str = ""
+ str = "# Puppet Name: #{record[:name]}\n" if record[:name]
+ if record[:environment] and record[:environment] != :absent and record[:environment] != [:absent]
+ record[:environment].each do |env|
+ str += env + "\n"
end
+ end
+
+ if record[:special]
+ str += "@#{record[:special]} #{record[:command]}"
+ else
+ str += join(record)
+ end
+ str
end
+ end
- # Return the header placed at the top of each generated file, warning
- # users that modifying this file manually is probably a bad idea.
- def self.header
+ # Return the header placed at the top of each generated file, warning
+ # users that modifying this file manually is probably a bad idea.
+ def self.header
%{# HEADER: This file was autogenerated at #{Time.now} by puppet.
# HEADER: While it can still be managed manually, it is definitely not recommended.
# HEADER: Note particularly that the comments starting with 'Puppet Name' should
# HEADER: not be deleted, as doing so could cause duplicate cron jobs.\n}
- end
-
- # See if we can match the record against an existing cron job.
- def self.match(record, resources)
- resources.each do |name, resource|
- # Match the command first, since it's the most important one.
- next unless record[:target] == resource.value(:target)
- next unless record[:command] == resource.value(:command)
-
- # Then check the @special stuff
- if record[:special]
- next unless resource.value(:special) == record[:special]
- end
-
- # Then the normal fields.
- matched = true
- record_type(record[:record_type]).fields.each do |field|
- next if field == :command
- next if field == :special
- if record[field] and ! resource.value(field)
- #Puppet.info "Cron is missing %s: %s and %s" %
- # [field, record[field].inspect, resource.value(field).inspect]
- matched = false
- break
- end
-
- if ! record[field] and resource.value(field)
- #Puppet.info "Hash is missing %s: %s and %s" %
- # [field, resource.value(field).inspect, record[field].inspect]
- matched = false
- break
- end
-
- # Yay differing definitions of absent.
- next if (record[field] == :absent and resource.value(field) == "*")
-
- # Everything should be in the form of arrays, not the normal text.
- next if (record[field] == resource.value(field))
- #Puppet.info "Did not match %s: %s vs %s" %
- # [field, resource.value(field).inspect, record[field].inspect]
- matched = false
- break
- end
- return resource if matched
+ end
+
+ # See if we can match the record against an existing cron job.
+ def self.match(record, resources)
+ resources.each do |name, resource|
+ # Match the command first, since it's the most important one.
+ next unless record[:target] == resource.value(:target)
+ next unless record[:command] == resource.value(:command)
+
+ # Then check the @special stuff
+ if record[:special]
+ next unless resource.value(:special) == record[:special]
+ end
+
+ # Then the normal fields.
+ matched = true
+ record_type(record[:record_type]).fields.each do |field|
+ next if field == :command
+ next if field == :special
+ if record[field] and ! resource.value(field)
+ #Puppet.info "Cron is missing %s: %s and %s" %
+ # [field, record[field].inspect, resource.value(field).inspect]
+ matched = false
+ break
end
- false
- end
+ if ! record[field] and resource.value(field)
+ #Puppet.info "Hash is missing %s: %s and %s" %
+ # [field, resource.value(field).inspect, record[field].inspect]
+ matched = false
+ break
+ end
- # Collapse name and env records.
- def self.prefetch_hook(records)
- name = nil
- envs = nil
- result = records.each { |record|
- case record[:record_type]
- when :comment
- if record[:name]
- name = record[:name]
- record[:skip] = true
-
- # Start collecting env values
- envs = []
- end
- when :environment
- # If we're collecting env values (meaning we're in a named cronjob),
- # store the line and skip the record.
- if envs
- envs << record[:line]
- record[:skip] = true
- end
- when :blank
- # nothing
- else
- if name
- record[:name] = name
- name = nil
- end
- if envs.nil? or envs.empty?
- record[:environment] = :absent
- else
- # Collect all of the environment lines, and mark the records to be skipped,
- # since their data is included in our crontab record.
- record[:environment] = envs
-
- # And turn off env collection again
- envs = nil
- end
- end
- }.reject { |record| record[:skip] }
- result
+ # Yay differing definitions of absent.
+ next if (record[field] == :absent and resource.value(field) == "*")
+
+ # Everything should be in the form of arrays, not the normal text.
+ next if (record[field] == resource.value(field))
+ #Puppet.info "Did not match %s: %s vs %s" %
+ # [field, resource.value(field).inspect, record[field].inspect]
+ matched = false
+ break
+ end
+ return resource if matched
end
- def self.to_file(records)
- text = super
- # Apparently Freebsd will "helpfully" add a new TZ line to every
- # single cron line, but not in all cases (e.g., it doesn't do it
- # on my machine). This is my attempt to fix it so the TZ lines don't
- # multiply.
- if text =~ /(^TZ=.+\n)/
- tz = $1
- text.sub!(tz, '')
- text = tz + text
+ false
+ end
+
+ # Collapse name and env records.
+ def self.prefetch_hook(records)
+ name = nil
+ envs = nil
+ result = records.each { |record|
+ case record[:record_type]
+ when :comment
+ if record[:name]
+ name = record[:name]
+ record[:skip] = true
+
+ # Start collecting env values
+ envs = []
+ end
+ when :environment
+ # If we're collecting env values (meaning we're in a named cronjob),
+ # store the line and skip the record.
+ if envs
+ envs << record[:line]
+ record[:skip] = true
end
- text
+ when :blank
+ # nothing
+ else
+ if name
+ record[:name] = name
+ name = nil
+ end
+ if envs.nil? or envs.empty?
+ record[:environment] = :absent
+ else
+ # Collect all of the environment lines, and mark the records to be skipped,
+ # since their data is included in our crontab record.
+ record[:environment] = envs
+
+ # And turn off env collection again
+ envs = nil
+ end
+ end
+ }.reject { |record| record[:skip] }
+ result
+ end
+
+ def self.to_file(records)
+ text = super
+ # Apparently Freebsd will "helpfully" add a new TZ line to every
+ # single cron line, but not in all cases (e.g., it doesn't do it
+ # on my machine). This is my attempt to fix it so the TZ lines don't
+ # multiply.
+ if text =~ /(^TZ=.+\n)/
+ tz = $1
+ text.sub!(tz, '')
+ text = tz + text
end
+ text
+ end
- def user=(user)
- @property_hash[:user] = user
- @property_hash[:target] = user
- end
+ def user=(user)
+ @property_hash[:user] = user
+ @property_hash[:target] = user
+ end
- def user
- @property_hash[:user] || @property_hash[:target]
- end
+ def user
+ @property_hash[:user] || @property_hash[:target]
+ end
end
diff --git a/lib/puppet/provider/file/posix.rb b/lib/puppet/provider/file/posix.rb
index d715d88..6cbf98e 100644
--- a/lib/puppet/provider/file/posix.rb
+++ b/lib/puppet/provider/file/posix.rb
@@ -1,99 +1,99 @@
Puppet::Type.type(:file).provide :posix do
- desc "Uses POSIX functionality to manage file's users and rights."
+ desc "Uses POSIX functionality to manage file's users and rights."
- confine :feature => :posix
+ confine :feature => :posix
- include Puppet::Util::POSIX
- include Puppet::Util::Warnings
+ include Puppet::Util::POSIX
+ include Puppet::Util::Warnings
- require 'etc'
+ require 'etc'
- def id2name(id)
- return id.to_s if id.is_a?(Symbol)
- return nil if id > Puppet[:maximum_uid].to_i
+ def id2name(id)
+ return id.to_s if id.is_a?(Symbol)
+ return nil if id > Puppet[:maximum_uid].to_i
- begin
- user = Etc.getpwuid(id)
- rescue TypeError
- return nil
- rescue ArgumentError
- return nil
- end
-
- if user.uid == ""
- return nil
- else
- return user.name
- end
+ begin
+ user = Etc.getpwuid(id)
+ rescue TypeError
+ return nil
+ rescue ArgumentError
+ return nil
end
- def insync?(current, should)
- return true unless should
-
- should.each do |value|
- if value =~ /^\d+$/
- uid = Integer(value)
- elsif value.is_a?(String)
- fail "Could not find user #{value}" unless uid = uid(value)
- else
- uid = value
- end
+ if user.uid == ""
+ return nil
+ else
+ return user.name
+ end
+ end
- return true if uid == current
- end
+ def insync?(current, should)
+ return true unless should
- unless Puppet.features.root?
- warnonce "Cannot manage ownership unless running as root"
- return true
- end
+ should.each do |value|
+ if value =~ /^\d+$/
+ uid = Integer(value)
+ elsif value.is_a?(String)
+ fail "Could not find user #{value}" unless uid = uid(value)
+ else
+ uid = value
+ end
- false
+ return true if uid == current
end
- # Determine if the user is valid, and if so, return the UID
- def validuser?(value)
- Integer(value) rescue uid(value) || false
+ unless Puppet.features.root?
+ warnonce "Cannot manage ownership unless running as root"
+ return true
end
- def retrieve(resource)
- unless stat = resource.stat(false)
- return :absent
- end
+ false
+ end
+
+ # Determine if the user is valid, and if so, return the UID
+ def validuser?(value)
+ Integer(value) rescue uid(value) || false
+ end
- currentvalue = stat.uid
+ def retrieve(resource)
+ unless stat = resource.stat(false)
+ return :absent
+ end
- # On OS X, files that are owned by -2 get returned as really
- # large UIDs instead of negative ones. This isn't a Ruby bug,
- # it's an OS X bug, since it shows up in perl, too.
- if currentvalue > Puppet[:maximum_uid].to_i
- self.warning "Apparently using negative UID (#{currentvalue}) on a platform that does not consistently handle them"
- currentvalue = :silly
- end
+ currentvalue = stat.uid
- currentvalue
+ # On OS X, files that are owned by -2 get returned as really
+ # large UIDs instead of negative ones. This isn't a Ruby bug,
+ # it's an OS X bug, since it shows up in perl, too.
+ if currentvalue > Puppet[:maximum_uid].to_i
+ self.warning "Apparently using negative UID (#{currentvalue}) on a platform that does not consistently handle them"
+ currentvalue = :silly
end
- def sync(path, links, should)
- # Set our method appropriately, depending on links.
- if links == :manage
- method = :lchown
- else
- method = :chown
- end
+ currentvalue
+ end
- uid = nil
- should.each do |user|
- break if uid = validuser?(user)
- end
+ def sync(path, links, should)
+ # Set our method appropriately, depending on links.
+ if links == :manage
+ method = :lchown
+ else
+ method = :chown
+ end
- raise Puppet::Error, "Could not find user(s) #{should.join(",")}" unless uid
+ uid = nil
+ should.each do |user|
+ break if uid = validuser?(user)
+ end
- begin
- File.send(method, uid, nil, path)
- rescue => detail
- raise Puppet::Error, "Failed to set owner to '#{uid}': #{detail}"
- end
+ raise Puppet::Error, "Could not find user(s) #{should.join(",")}" unless uid
- :file_changed
+ begin
+ File.send(method, uid, nil, path)
+ rescue => detail
+ raise Puppet::Error, "Failed to set owner to '#{uid}': #{detail}"
end
+
+ :file_changed
+ end
end
diff --git a/lib/puppet/provider/file/win32.rb b/lib/puppet/provider/file/win32.rb
index 93274ce..8ead69a 100644
--- a/lib/puppet/provider/file/win32.rb
+++ b/lib/puppet/provider/file/win32.rb
@@ -1,74 +1,74 @@
Puppet::Type.type(:file).provide :microsoft_windows do
- desc "Uses Microsoft Windows functionality to manage file's users and rights."
+ desc "Uses Microsoft Windows functionality to manage file's users and rights."
- confine :feature => :microsoft_windows
+ confine :feature => :microsoft_windows
- include Puppet::Util::Warnings
+ include Puppet::Util::Warnings
- require 'sys/admin' if Puppet.features.microsoft_windows?
+ require 'sys/admin' if Puppet.features.microsoft_windows?
- def id2name(id)
- return id.to_s if id.is_a?(Symbol)
- return nil if id > Puppet[:maximum_uid].to_i
- # should translate ID numbers to usernames
- id
- end
-
- def insync?(current, should)
- return true unless should
+ def id2name(id)
+ return id.to_s if id.is_a?(Symbol)
+ return nil if id > Puppet[:maximum_uid].to_i
+ # should translate ID numbers to usernames
+ id
+ end
- should.each do |value|
- if value =~ /^\d+$/
- uid = Integer(value)
- elsif value.is_a?(String)
- fail "Could not find user #{value}" unless uid = uid(value)
- else
- uid = value
- end
+ def insync?(current, should)
+ return true unless should
- return true if uid == current
- end
+ should.each do |value|
+ if value =~ /^\d+$/
+ uid = Integer(value)
+ elsif value.is_a?(String)
+ fail "Could not find user #{value}" unless uid = uid(value)
+ else
+ uid = value
+ end
- unless Puppet.features.root?
- warnonce "Cannot manage ownership unless running as root"
- return true
- end
-
- false
+ return true if uid == current
end
- # Determine if the user is valid, and if so, return the UID
- def validuser?(value)
- info "Is '#{value}' a valid user?"
- return 0
- begin
- number = Integer(value)
- return number
- rescue ArgumentError
- number = nil
- end
- (number = uid(value)) && number
+ unless Puppet.features.root?
+ warnonce "Cannot manage ownership unless running as root"
+ return true
end
- def retrieve(resource)
- unless stat = resource.stat(false)
- return :absent
- end
-
- currentvalue = stat.uid
+ false
+ end
- # On OS X, files that are owned by -2 get returned as really
- # large UIDs instead of negative ones. This isn't a Ruby bug,
- # it's an OS X bug, since it shows up in perl, too.
- if currentvalue > Puppet[:maximum_uid].to_i
- self.warning "Apparently using negative UID (#{currentvalue}) on a platform that does not consistently handle them"
- currentvalue = :silly
- end
+ # Determine if the user is valid, and if so, return the UID
+ def validuser?(value)
+ info "Is '#{value}' a valid user?"
+ return 0
+ begin
+ number = Integer(value)
+ return number
+ rescue ArgumentError
+ number = nil
+ end
+ (number = uid(value)) && number
+ end
- currentvalue
+ def retrieve(resource)
+ unless stat = resource.stat(false)
+ return :absent
end
- def sync(path, links, should)
- info("should set '%s'%%owner to '%s'" % [path, should])
+ currentvalue = stat.uid
+
+ # On OS X, files that are owned by -2 get returned as really
+ # large UIDs instead of negative ones. This isn't a Ruby bug,
+ # it's an OS X bug, since it shows up in perl, too.
+ if currentvalue > Puppet[:maximum_uid].to_i
+ self.warning "Apparently using negative UID (#{currentvalue}) on a platform that does not consistently handle them"
+ currentvalue = :silly
end
+
+ currentvalue
+ end
+
+ def sync(path, links, should)
+ info("should set '%s'%%owner to '%s'" % [path, should])
+ end
end
diff --git a/lib/puppet/provider/group/directoryservice.rb b/lib/puppet/provider/group/directoryservice.rb
index d022734..97fee88 100644
--- a/lib/puppet/provider/group/directoryservice.rb
+++ b/lib/puppet/provider/group/directoryservice.rb
@@ -15,12 +15,12 @@
require 'puppet/provider/nameservice/directoryservice'
Puppet::Type.type(:group).provide :directoryservice, :parent => Puppet::Provider::NameService::DirectoryService do
- desc "Group management using DirectoryService on OS X.
+ desc "Group management using DirectoryService on OS X.
- "
+ "
- commands :dscl => "/usr/bin/dscl"
- confine :operatingsystem => :darwin
- defaultfor :operatingsystem => :darwin
- has_feature :manages_members
+ commands :dscl => "/usr/bin/dscl"
+ confine :operatingsystem => :darwin
+ defaultfor :operatingsystem => :darwin
+ has_feature :manages_members
end
diff --git a/lib/puppet/provider/group/groupadd.rb b/lib/puppet/provider/group/groupadd.rb
index 496db3c..e661ddd 100644
--- a/lib/puppet/provider/group/groupadd.rb
+++ b/lib/puppet/provider/group/groupadd.rb
@@ -1,29 +1,29 @@
require 'puppet/provider/nameservice/objectadd'
Puppet::Type.type(:group).provide :groupadd, :parent => Puppet::Provider::NameService::ObjectAdd do
- desc "Group management via ``groupadd`` and its ilk.
+ desc "Group management via ``groupadd`` and its ilk.
- The default for most platforms
+ The default for most platforms
- "
+ "
- commands :add => "groupadd", :delete => "groupdel", :modify => "groupmod"
+ commands :add => "groupadd", :delete => "groupdel", :modify => "groupmod"
- verify :gid, "GID must be an integer" do |value|
- value.is_a? Integer
- end
+ verify :gid, "GID must be an integer" do |value|
+ value.is_a? Integer
+ end
- def addcmd
- cmd = [command(:add)]
- if gid = @resource.should(:gid)
- unless gid == :absent
- cmd << flag(:gid) << gid
- end
- end
- cmd << "-o" if @resource.allowdupe?
- cmd << @resource[:name]
-
- cmd
+ def addcmd
+ cmd = [command(:add)]
+ if gid = @resource.should(:gid)
+ unless gid == :absent
+ cmd << flag(:gid) << gid
+ end
end
+ cmd << "-o" if @resource.allowdupe?
+ cmd << @resource[:name]
+
+ cmd
+ end
end
diff --git a/lib/puppet/provider/group/ldap.rb b/lib/puppet/provider/group/ldap.rb
index d0eca0d..2737fee 100644
--- a/lib/puppet/provider/group/ldap.rb
+++ b/lib/puppet/provider/group/ldap.rb
@@ -1,47 +1,47 @@
require 'puppet/provider/ldap'
Puppet::Type.type(:group).provide :ldap, :parent => Puppet::Provider::Ldap do
- desc "Group management via ``ldap``.
-
- This provider requires that you have valid values for all of the
- ldap-related settings, including ``ldapbase``. You will also almost
- definitely need settings for ``ldapuser`` and ``ldappassword``, so that
- your clients can write to ldap.
-
- Note that this provider will automatically generate a GID for you if you do
- not specify one, but it is a potentially expensive operation, as it
- iterates across all existing groups to pick the appropriate next one.
-
- "
-
- confine :true => Puppet.features.ldap?, :false => (Puppet[:ldapuser] == "")
-
- # We're mapping 'members' here because we want to make it
- # easy for the ldap user provider to manage groups. This
- # way it can just use the 'update' method in the group manager,
- # whereas otherwise it would need to replicate that code.
- manages(:posixGroup).at("ou=Groups").and.maps :name => :cn, :gid => :gidNumber, :members => :memberUid
-
- # Find the next gid after the current largest gid.
- provider = self
- manager.generates(:gidNumber).with do
- largest = 500
- if existing = provider.manager.search
- existing.each do |hash|
- next unless value = hash[:gid]
- num = value[0].to_i
- largest = num if num > largest
- end
- end
- largest + 1
+ desc "Group management via ``ldap``.
+
+ This provider requires that you have valid values for all of the
+ ldap-related settings, including ``ldapbase``. You will also almost
+ definitely need settings for ``ldapuser`` and ``ldappassword``, so that
+ your clients can write to ldap.
+
+ Note that this provider will automatically generate a GID for you if you do
+ not specify one, but it is a potentially expensive operation, as it
+ iterates across all existing groups to pick the appropriate next one.
+
+ "
+
+ confine :true => Puppet.features.ldap?, :false => (Puppet[:ldapuser] == "")
+
+ # We're mapping 'members' here because we want to make it
+ # easy for the ldap user provider to manage groups. This
+ # way it can just use the 'update' method in the group manager,
+ # whereas otherwise it would need to replicate that code.
+ manages(:posixGroup).at("ou=Groups").and.maps :name => :cn, :gid => :gidNumber, :members => :memberUid
+
+ # Find the next gid after the current largest gid.
+ provider = self
+ manager.generates(:gidNumber).with do
+ largest = 500
+ if existing = provider.manager.search
+ existing.each do |hash|
+ next unless value = hash[:gid]
+ num = value[0].to_i
+ largest = num if num > largest
+ end
end
+ largest + 1
+ end
- # Convert a group name to an id.
- def self.name2id(group)
- return nil unless result = manager.search("cn=#{group}") and result.length > 0
+ # Convert a group name to an id.
+ def self.name2id(group)
+ return nil unless result = manager.search("cn=#{group}") and result.length > 0
- # Only use the first result.
- group = result[0]
- gid = group[:gid][0]
- end
+ # Only use the first result.
+ group = result[0]
+ gid = group[:gid][0]
+ end
end
diff --git a/lib/puppet/provider/group/pw.rb b/lib/puppet/provider/group/pw.rb
index 0f549f2..e3dd714 100644
--- a/lib/puppet/provider/group/pw.rb
+++ b/lib/puppet/provider/group/pw.rb
@@ -1,34 +1,34 @@
require 'puppet/provider/nameservice/pw'
Puppet::Type.type(:group).provide :pw, :parent => Puppet::Provider::NameService::PW do
- desc "Group management via ``pw``.
+ desc "Group management via ``pw``.
- Only works on FreeBSD.
+ Only works on FreeBSD.
- "
+ "
- commands :pw => "/usr/sbin/pw"
- defaultfor :operatingsystem => :freebsd
+ commands :pw => "/usr/sbin/pw"
+ defaultfor :operatingsystem => :freebsd
- verify :gid, "GID must be an integer" do |value|
- value.is_a? Integer
- end
+ verify :gid, "GID must be an integer" do |value|
+ value.is_a? Integer
+ end
- def addcmd
- cmd = [command(:pw), "groupadd", @resource[:name]]
- if gid = @resource.should(:gid)
- unless gid == :absent
- cmd << flag(:gid) << gid
- end
- end
-
- # Apparently, contrary to the man page, groupadd does
- # not accept -o.
- #if @parent[:allowdupe] == :true
- # cmd << "-o"
- #end
-
- cmd
+ def addcmd
+ cmd = [command(:pw), "groupadd", @resource[:name]]
+ if gid = @resource.should(:gid)
+ unless gid == :absent
+ cmd << flag(:gid) << gid
+ end
end
+
+ # Apparently, contrary to the man page, groupadd does
+ # not accept -o.
+ #if @parent[:allowdupe] == :true
+ # cmd << "-o"
+ #end
+
+ cmd
+ end
end
diff --git a/lib/puppet/provider/host/parsed.rb b/lib/puppet/provider/host/parsed.rb
index be2f735..4f15eff 100644
--- a/lib/puppet/provider/host/parsed.rb
+++ b/lib/puppet/provider/host/parsed.rb
@@ -4,70 +4,70 @@ hosts = nil
case Facter.value(:operatingsystem)
when "Solaris"; hosts = "/etc/inet/hosts"
else
- hosts = "/etc/hosts"
+ hosts = "/etc/hosts"
end
- Puppet::Type.type(:host).provide(
- :parsed,
- :parent => Puppet::Provider::ParsedFile,
- :default_target => hosts,
+ Puppet::Type.type(:host).provide(
+ :parsed,
+ :parent => Puppet::Provider::ParsedFile,
+ :default_target => hosts,
- :filetype => :flat
+ :filetype => :flat
) do
- confine :exists => hosts
+ confine :exists => hosts
- text_line :comment, :match => /^#/
- text_line :blank, :match => /^\s*$/
+ text_line :comment, :match => /^#/
+ text_line :blank, :match => /^\s*$/
- record_line :parsed, :fields => %w{ip name host_aliases},
- :optional => %w{host_aliases},
- :rts => true do |line|
- hash = {}
- if line.sub!(/^(\S+)\s+(\S+)\s*/, '')
- hash[:ip] = $1
- hash[:name] = $2
+ record_line :parsed, :fields => %w{ip name host_aliases},
+ :optional => %w{host_aliases},
+ :rts => true do |line|
+ hash = {}
+ if line.sub!(/^(\S+)\s+(\S+)\s*/, '')
+ hash[:ip] = $1
+ hash[:name] = $2
- if line.empty?
- hash[:host_aliases] = []
- else
- line.sub!(/\s*/, '')
- line.sub!(/^([^#]+)\s*/) do |value|
- aliases = $1
- unless aliases =~ /^\s*$/
- hash[:host_aliases] = aliases.split(/\s+/)
- end
+ if line.empty?
+ hash[:host_aliases] = []
+ else
+ line.sub!(/\s*/, '')
+ line.sub!(/^([^#]+)\s*/) do |value|
+ aliases = $1
+ unless aliases =~ /^\s*$/
+ hash[:host_aliases] = aliases.split(/\s+/)
+ end
- ""
- end
- end
- else
- raise Puppet::Error, "Could not match '#{line}'"
+ ""
end
-
- hash[:host_aliases] = [] if hash[:host_aliases] == ""
-
- return hash
+ end
+ else
+ raise Puppet::Error, "Could not match '#{line}'"
end
- # Convert the current object into a host-style string.
- def self.to_line(hash)
- return super unless hash[:record_type] == :parsed
- [:ip, :name].each do |n|
- raise ArgumentError, "#{n} is a required attribute for hosts" unless hash[n] and hash[n] != :absent
- end
+ hash[:host_aliases] = [] if hash[:host_aliases] == ""
- str = "#{hash[:ip]}\t#{hash[:name]}"
+ return hash
+ end
- if hash.include? :host_aliases and !hash[:host_aliases].empty?
- if hash[:host_aliases].is_a? Array
- str += "\t#{hash[:host_aliases].join("\t")}"
- else
- raise ArgumentError, "Host aliases must be specified as an array"
- end
- end
+ # Convert the current object into a host-style string.
+ def self.to_line(hash)
+ return super unless hash[:record_type] == :parsed
+ [:ip, :name].each do |n|
+ raise ArgumentError, "#{n} is a required attribute for hosts" unless hash[n] and hash[n] != :absent
+ end
+
+ str = "#{hash[:ip]}\t#{hash[:name]}"
- str
+ if hash.include? :host_aliases and !hash[:host_aliases].empty?
+ if hash[:host_aliases].is_a? Array
+ str += "\t#{hash[:host_aliases].join("\t")}"
+ else
+ raise ArgumentError, "Host aliases must be specified as an array"
+ end
end
+
+ str
+ end
end
diff --git a/lib/puppet/provider/ldap.rb b/lib/puppet/provider/ldap.rb
index cc5c67f..b7d6baa 100644
--- a/lib/puppet/provider/ldap.rb
+++ b/lib/puppet/provider/ldap.rb
@@ -2,132 +2,132 @@ require 'puppet/provider'
# The base class for LDAP providers.
class Puppet::Provider::Ldap < Puppet::Provider
- require 'puppet/util/ldap/manager'
-
- class << self
- attr_reader :manager
+ require 'puppet/util/ldap/manager'
+
+ class << self
+ attr_reader :manager
+ end
+
+ # Look up all instances at our location. Yay.
+ def self.instances
+ return [] unless list = manager.search
+
+ list.collect { |entry| new(entry) }
+ end
+
+ # Specify the ldap manager for this provider, which is
+ # used to figure out how we actually interact with ldap.
+ def self.manages(*args)
+ @manager = Puppet::Util::Ldap::Manager.new
+ @manager.manages(*args)
+
+ # Set up our getter/setter methods.
+ mk_resource_methods
+ @manager
+ end
+
+ # Query all of our resources from ldap.
+ def self.prefetch(resources)
+ resources.each do |name, resource|
+ if result = manager.find(name)
+ result[:ensure] = :present
+ resource.provider = new(result)
+ else
+ resource.provider = new(:ensure => :absent)
+ end
end
-
- # Look up all instances at our location. Yay.
- def self.instances
- return [] unless list = manager.search
-
- list.collect { |entry| new(entry) }
+ end
+
+ def manager
+ self.class.manager
+ end
+
+ def create
+ @property_hash[:ensure] = :present
+ self.class.resource_type.validproperties.each do |property|
+ if val = resource.should(property)
+ @property_hash[property] = val
+ end
end
-
- # Specify the ldap manager for this provider, which is
- # used to figure out how we actually interact with ldap.
- def self.manages(*args)
- @manager = Puppet::Util::Ldap::Manager.new
- @manager.manages(*args)
-
- # Set up our getter/setter methods.
- mk_resource_methods
- @manager
+ end
+
+ def delete
+ @property_hash[:ensure] = :absent
+ end
+
+ def exists?
+ @property_hash[:ensure] != :absent
+ end
+
+ # Apply our changes to ldap, yo.
+ def flush
+ # Just call the manager's update() method.
+ @property_hash.delete(:groups)
+ @ldap_properties.delete(:groups)
+ manager.update(name, ldap_properties, properties)
+ @property_hash.clear
+ @ldap_properties.clear
+ end
+
+ def initialize(*args)
+ raise(Puppet::DevError, "No LDAP Configuration defined for #{self.class}") unless self.class.manager
+ raise(Puppet::DevError, "Invalid LDAP Configuration defined for #{self.class}") unless self.class.manager.valid?
+ super
+
+ @property_hash = @property_hash.inject({}) do |result, ary|
+ param, values = ary
+
+ # Skip any attributes we don't manage.
+ next result unless self.class.resource_type.valid_parameter?(param)
+
+ paramclass = self.class.resource_type.attrclass(param)
+
+ unless values.is_a?(Array)
+ result[param] = values
+ next result
+ end
+
+ # Only use the first value if the attribute class doesn't manage
+ # arrays of values.
+ if paramclass.superclass == Puppet::Parameter or paramclass.array_matching == :first
+ result[param] = values[0]
+ else
+ result[param] = values
+ end
+ result
end
- # Query all of our resources from ldap.
- def self.prefetch(resources)
- resources.each do |name, resource|
- if result = manager.find(name)
- result[:ensure] = :present
- resource.provider = new(result)
- else
- resource.provider = new(:ensure => :absent)
- end
- end
+ # Make a duplicate, so that we have a copy for comparison
+ # at the end.
+ @ldap_properties = @property_hash.dup
+ end
+
+ # Return the current state of ldap.
+ def ldap_properties
+ @ldap_properties.dup
+ end
+
+ # Return (and look up if necessary) the desired state.
+ def properties
+ if @property_hash.empty?
+ @property_hash = query || {:ensure => :absent}
+ @property_hash[:ensure] = :absent if @property_hash.empty?
end
-
- def manager
- self.class.manager
+ @property_hash.dup
+ end
+
+ # Collect the current attributes from ldap. Returns
+ # the results, but also stores the attributes locally,
+ # so we have something to compare against when we update.
+ # LAK:NOTE This is normally not used, because we rely on prefetching.
+ def query
+ # Use the module function.
+ unless attributes = manager.find(name)
+ @ldap_properties = {}
+ return nil
end
- def create
- @property_hash[:ensure] = :present
- self.class.resource_type.validproperties.each do |property|
- if val = resource.should(property)
- @property_hash[property] = val
- end
- end
- end
-
- def delete
- @property_hash[:ensure] = :absent
- end
-
- def exists?
- @property_hash[:ensure] != :absent
- end
-
- # Apply our changes to ldap, yo.
- def flush
- # Just call the manager's update() method.
- @property_hash.delete(:groups)
- @ldap_properties.delete(:groups)
- manager.update(name, ldap_properties, properties)
- @property_hash.clear
- @ldap_properties.clear
- end
-
- def initialize(*args)
- raise(Puppet::DevError, "No LDAP Configuration defined for #{self.class}") unless self.class.manager
- raise(Puppet::DevError, "Invalid LDAP Configuration defined for #{self.class}") unless self.class.manager.valid?
- super
-
- @property_hash = @property_hash.inject({}) do |result, ary|
- param, values = ary
-
- # Skip any attributes we don't manage.
- next result unless self.class.resource_type.valid_parameter?(param)
-
- paramclass = self.class.resource_type.attrclass(param)
-
- unless values.is_a?(Array)
- result[param] = values
- next result
- end
-
- # Only use the first value if the attribute class doesn't manage
- # arrays of values.
- if paramclass.superclass == Puppet::Parameter or paramclass.array_matching == :first
- result[param] = values[0]
- else
- result[param] = values
- end
- result
- end
-
- # Make a duplicate, so that we have a copy for comparison
- # at the end.
- @ldap_properties = @property_hash.dup
- end
-
- # Return the current state of ldap.
- def ldap_properties
- @ldap_properties.dup
- end
-
- # Return (and look up if necessary) the desired state.
- def properties
- if @property_hash.empty?
- @property_hash = query || {:ensure => :absent}
- @property_hash[:ensure] = :absent if @property_hash.empty?
- end
- @property_hash.dup
- end
-
- # Collect the current attributes from ldap. Returns
- # the results, but also stores the attributes locally,
- # so we have something to compare against when we update.
- # LAK:NOTE This is normally not used, because we rely on prefetching.
- def query
- # Use the module function.
- unless attributes = manager.find(name)
- @ldap_properties = {}
- return nil
- end
-
- @ldap_properties = attributes
- @ldap_properties.dup
- end
+ @ldap_properties = attributes
+ @ldap_properties.dup
+ end
end
diff --git a/lib/puppet/provider/macauthorization/macauthorization.rb b/lib/puppet/provider/macauthorization/macauthorization.rb
index 4c55d72..fdf9fd1 100644
--- a/lib/puppet/provider/macauthorization/macauthorization.rb
+++ b/lib/puppet/provider/macauthorization/macauthorization.rb
@@ -5,309 +5,309 @@ require 'tempfile'
Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppet::Provider do
- desc "Manage Mac OS X authorization database rules and rights.
+ desc "Manage Mac OS X authorization database rules and rights.
- "
+ "
- commands :security => "/usr/bin/security"
- commands :sw_vers => "/usr/bin/sw_vers"
+ commands :security => "/usr/bin/security"
+ commands :sw_vers => "/usr/bin/sw_vers"
- confine :operatingsystem => :darwin
+ confine :operatingsystem => :darwin
- # This should be confined based on macosx_productversion once
- # http://projects.reductivelabs.com/issues/show/1796
- # is resolved.
- if FileTest.exists?("/usr/bin/sw_vers")
- product_version = sw_vers "-productVersion"
+ # This should be confined based on macosx_productversion once
+ # http://projects.reductivelabs.com/issues/show/1796
+ # is resolved.
+ if FileTest.exists?("/usr/bin/sw_vers")
+ product_version = sw_vers "-productVersion"
- confine :true => if /^10.5/.match(product_version) or /^10.6/.match(product_version)
- true
- end
+ confine :true => if /^10.5/.match(product_version) or /^10.6/.match(product_version)
+ true
end
+ end
- defaultfor :operatingsystem => :darwin
-
- AuthDB = "/etc/authorization"
-
- @rights = {}
- @rules = {}
- @parsed_auth_db = {}
- @comment = "" # Not implemented yet. Is there any real need to?
-
- # This map exists due to the use of hyphens and reserved words in
- # the authorization schema.
- PuppetToNativeAttributeMap = { :allow_root => "allow-root",
- :authenticate_user => "authenticate-user",
- :auth_class => "class",
- :k_of_n => "k-of-n",
- :session_owner => "session-owner", }
-
- class << self
- attr_accessor :parsed_auth_db
- attr_accessor :rights
- attr_accessor :rules
- attr_accessor :comments # Not implemented yet.
-
- def prefetch(resources)
- self.populate_rules_rights
- end
-
- def instances
- if self.parsed_auth_db == {}
- self.prefetch(nil)
- end
- self.parsed_auth_db.collect do |k,v|
- new(:name => k)
- end
- end
-
- def populate_rules_rights
- auth_plist = Plist::parse_xml(AuthDB)
- raise Puppet::Error.new("Cannot parse: #{AuthDB}") if not auth_plist
- self.rights = auth_plist["rights"].dup
- self.rules = auth_plist["rules"].dup
- self.parsed_auth_db = self.rights.dup
- self.parsed_auth_db.merge!(self.rules.dup)
- end
+ defaultfor :operatingsystem => :darwin
- end
+ AuthDB = "/etc/authorization"
- # standard required provider instance methods
+ @rights = {}
+ @rules = {}
+ @parsed_auth_db = {}
+ @comment = "" # Not implemented yet. Is there any real need to?
- def initialize(resource)
- if self.class.parsed_auth_db == {}
- self.class.prefetch(resource)
- end
- super
- end
+ # This map exists due to the use of hyphens and reserved words in
+ # the authorization schema.
+ PuppetToNativeAttributeMap = { :allow_root => "allow-root",
+ :authenticate_user => "authenticate-user",
+ :auth_class => "class",
+ :k_of_n => "k-of-n",
+ :session_owner => "session-owner", }
+ class << self
+ attr_accessor :parsed_auth_db
+ attr_accessor :rights
+ attr_accessor :rules
+ attr_accessor :comments # Not implemented yet.
- def create
- # we just fill the @property_hash in here and let the flush method
- # deal with it rather than repeating code.
- new_values = {}
- validprops = Puppet::Type.type(resource.class.name).validproperties
- validprops.each do |prop|
- next if prop == :ensure
- if value = resource.should(prop) and value != ""
- new_values[prop] = value
- end
- end
- @property_hash = new_values.dup
+ def prefetch(resources)
+ self.populate_rules_rights
end
- def destroy
- # We explicitly delete here rather than in the flush method.
- case resource[:auth_type]
- when :right
- destroy_right
- when :rule
- destroy_rule
- else
- raise Puppet::Error.new("Must specify auth_type when destroying.")
- end
+ def instances
+ if self.parsed_auth_db == {}
+ self.prefetch(nil)
+ end
+ self.parsed_auth_db.collect do |k,v|
+ new(:name => k)
+ end
end
- def exists?
- !!self.class.parsed_auth_db.has_key?(resource[:name])
+ def populate_rules_rights
+ auth_plist = Plist::parse_xml(AuthDB)
+ raise Puppet::Error.new("Cannot parse: #{AuthDB}") if not auth_plist
+ self.rights = auth_plist["rights"].dup
+ self.rules = auth_plist["rules"].dup
+ self.parsed_auth_db = self.rights.dup
+ self.parsed_auth_db.merge!(self.rules.dup)
end
+ end
- def flush
- # deletion happens in the destroy methods
- if resource[:ensure] != :absent
- case resource[:auth_type]
- when :right
- flush_right
- when :rule
- flush_rule
- else
- raise Puppet::Error.new("flush requested for unknown type.")
- end
- @property_hash.clear
- end
+ # standard required provider instance methods
+
+ def initialize(resource)
+ if self.class.parsed_auth_db == {}
+ self.class.prefetch(resource)
+ end
+ super
+ end
+
+
+ def create
+ # we just fill the @property_hash in here and let the flush method
+ # deal with it rather than repeating code.
+ new_values = {}
+ validprops = Puppet::Type.type(resource.class.name).validproperties
+ validprops.each do |prop|
+ next if prop == :ensure
+ if value = resource.should(prop) and value != ""
+ new_values[prop] = value
+ end
end
+ @property_hash = new_values.dup
+ end
+
+ def destroy
+ # We explicitly delete here rather than in the flush method.
+ case resource[:auth_type]
+ when :right
+ destroy_right
+ when :rule
+ destroy_rule
+ else
+ raise Puppet::Error.new("Must specify auth_type when destroying.")
+ end
+ end
+
+ def exists?
+ !!self.class.parsed_auth_db.has_key?(resource[:name])
+ end
+
+
+ def flush
+ # deletion happens in the destroy methods
+ if resource[:ensure] != :absent
+ case resource[:auth_type]
+ when :right
+ flush_right
+ when :rule
+ flush_rule
+ else
+ raise Puppet::Error.new("flush requested for unknown type.")
+ end
+ @property_hash.clear
+ end
+ end
- # utility methods below
+ # utility methods below
- def destroy_right
- security "authorizationdb", :remove, resource[:name]
- end
+ def destroy_right
+ security "authorizationdb", :remove, resource[:name]
+ end
- def destroy_rule
- authdb = Plist::parse_xml(AuthDB)
- authdb_rules = authdb["rules"].dup
- if authdb_rules[resource[:name]]
- begin
- authdb["rules"].delete(resource[:name])
- Plist::Emit.save_plist(authdb, AuthDB)
- rescue Errno::EACCES => e
- raise Puppet::Error.new("Error saving #{AuthDB}: #{e}")
- end
- end
+ def destroy_rule
+ authdb = Plist::parse_xml(AuthDB)
+ authdb_rules = authdb["rules"].dup
+ if authdb_rules[resource[:name]]
+ begin
+ authdb["rules"].delete(resource[:name])
+ Plist::Emit.save_plist(authdb, AuthDB)
+ rescue Errno::EACCES => e
+ raise Puppet::Error.new("Error saving #{AuthDB}: #{e}")
+ end
end
-
- def flush_right
- # first we re-read the right just to make sure we're in sync for
- # values that weren't specified in the manifest. As we're supplying
- # the whole plist when specifying the right it seems safest to be
- # paranoid given the low cost of quering the db once more.
- cmds = []
- cmds << :security << "authorizationdb" << "read" << resource[:name]
- output = execute(cmds, :combine => false)
- current_values = Plist::parse_xml(output)
- current_values ||= {}
- specified_values = convert_plist_to_native_attributes(@property_hash)
-
- # take the current values, merge the specified values to obtain a
- # complete description of the new values.
- new_values = current_values.merge(specified_values)
- set_right(resource[:name], new_values)
+ end
+
+ def flush_right
+ # first we re-read the right just to make sure we're in sync for
+ # values that weren't specified in the manifest. As we're supplying
+ # the whole plist when specifying the right it seems safest to be
+ # paranoid given the low cost of quering the db once more.
+ cmds = []
+ cmds << :security << "authorizationdb" << "read" << resource[:name]
+ output = execute(cmds, :combine => false)
+ current_values = Plist::parse_xml(output)
+ current_values ||= {}
+ specified_values = convert_plist_to_native_attributes(@property_hash)
+
+ # take the current values, merge the specified values to obtain a
+ # complete description of the new values.
+ new_values = current_values.merge(specified_values)
+ set_right(resource[:name], new_values)
+ end
+
+ def flush_rule
+ authdb = Plist::parse_xml(AuthDB)
+ authdb_rules = authdb["rules"].dup
+ current_values = {}
+ current_values = authdb_rules[resource[:name]] if authdb_rules[resource[:name]]
+ specified_values = convert_plist_to_native_attributes(@property_hash)
+ new_values = current_values.merge(specified_values)
+ set_rule(resource[:name], new_values)
+ end
+
+ def set_right(name, values)
+ # Both creates and modifies rights as it simply overwrites them.
+ # The security binary only allows for writes using stdin, so we
+ # dump the values to a tempfile.
+ values = convert_plist_to_native_attributes(values)
+ tmp = Tempfile.new('puppet_macauthorization')
+ begin
+ Plist::Emit.save_plist(values, tmp.path)
+ cmds = []
+ cmds << :security << "authorizationdb" << "write" << name
+
+ output = execute(
+ cmds, :combine => false,
+
+ :stdinfile => tmp.path.to_s)
+ rescue Errno::EACCES => e
+ raise Puppet::Error.new("Cannot save right to #{tmp.path}: #{e}")
+ ensure
+ tmp.close
+ tmp.unlink
end
-
- def flush_rule
- authdb = Plist::parse_xml(AuthDB)
- authdb_rules = authdb["rules"].dup
- current_values = {}
- current_values = authdb_rules[resource[:name]] if authdb_rules[resource[:name]]
- specified_values = convert_plist_to_native_attributes(@property_hash)
- new_values = current_values.merge(specified_values)
- set_rule(resource[:name], new_values)
+ end
+
+ def set_rule(name, values)
+ # Both creates and modifies rules as it overwrites the entry in the
+ # rules dictionary. Unfortunately the security binary doesn't
+ # support modifying rules at all so we have to twiddle the whole
+ # plist... :( See Apple Bug #6386000
+ values = convert_plist_to_native_attributes(values)
+ authdb = Plist::parse_xml(AuthDB)
+ authdb["rules"][name] = values
+
+ begin
+ Plist::Emit.save_plist(authdb, AuthDB)
+ rescue
+ raise Puppet::Error.new("Error writing to: #{AuthDB}")
end
-
- def set_right(name, values)
- # Both creates and modifies rights as it simply overwrites them.
- # The security binary only allows for writes using stdin, so we
- # dump the values to a tempfile.
- values = convert_plist_to_native_attributes(values)
- tmp = Tempfile.new('puppet_macauthorization')
- begin
- Plist::Emit.save_plist(values, tmp.path)
- cmds = []
- cmds << :security << "authorizationdb" << "write" << name
-
- output = execute(
- cmds, :combine => false,
-
- :stdinfile => tmp.path.to_s)
- rescue Errno::EACCES => e
- raise Puppet::Error.new("Cannot save right to #{tmp.path}: #{e}")
- ensure
- tmp.close
- tmp.unlink
- end
+ end
+
+ def convert_plist_to_native_attributes(propertylist)
+ # This mainly converts the keys from the puppet attributes to the
+ # 'native' ones, but also enforces that the keys are all Strings
+ # rather than Symbols so that any merges of the resultant Hash are
+ # sane. The exception is booleans, where we coerce to a proper bool
+ # if they come in as a symbol.
+ newplist = {}
+ propertylist.each_pair do |key, value|
+ next if key == :ensure # not part of the auth db schema.
+ next if key == :auth_type # not part of the auth db schema.
+ case value
+ when true, :true
+ value = true
+ when false, :false
+ value = false
+ end
+ new_key = key
+ if PuppetToNativeAttributeMap.has_key?(key)
+ new_key = PuppetToNativeAttributeMap[key].to_s
+ elsif not key.is_a?(String)
+ new_key = key.to_s
+ end
+ newplist[new_key] = value
end
+ newplist
+ end
- def set_rule(name, values)
- # Both creates and modifies rules as it overwrites the entry in the
- # rules dictionary. Unfortunately the security binary doesn't
- # support modifying rules at all so we have to twiddle the whole
- # plist... :( See Apple Bug #6386000
- values = convert_plist_to_native_attributes(values)
- authdb = Plist::parse_xml(AuthDB)
- authdb["rules"][name] = values
-
- begin
- Plist::Emit.save_plist(authdb, AuthDB)
- rescue
- raise Puppet::Error.new("Error writing to: #{AuthDB}")
- end
- end
+ def retrieve_value(resource_name, attribute)
+ # We set boolean values to symbols when retrieving values
+ raise Puppet::Error.new("Cannot find #{resource_name} in auth db") if not self.class.parsed_auth_db.has_key?(resource_name)
- def convert_plist_to_native_attributes(propertylist)
- # This mainly converts the keys from the puppet attributes to the
- # 'native' ones, but also enforces that the keys are all Strings
- # rather than Symbols so that any merges of the resultant Hash are
- # sane. The exception is booleans, where we coerce to a proper bool
- # if they come in as a symbol.
- newplist = {}
- propertylist.each_pair do |key, value|
- next if key == :ensure # not part of the auth db schema.
- next if key == :auth_type # not part of the auth db schema.
- case value
- when true, :true
- value = true
- when false, :false
- value = false
- end
- new_key = key
- if PuppetToNativeAttributeMap.has_key?(key)
- new_key = PuppetToNativeAttributeMap[key].to_s
- elsif not key.is_a?(String)
- new_key = key.to_s
- end
- newplist[new_key] = value
- end
- newplist
+ if PuppetToNativeAttributeMap.has_key?(attribute)
+ native_attribute = PuppetToNativeAttributeMap[attribute]
+ else
+ native_attribute = attribute.to_s
end
- def retrieve_value(resource_name, attribute)
- # We set boolean values to symbols when retrieving values
- raise Puppet::Error.new("Cannot find #{resource_name} in auth db") if not self.class.parsed_auth_db.has_key?(resource_name)
-
- if PuppetToNativeAttributeMap.has_key?(attribute)
- native_attribute = PuppetToNativeAttributeMap[attribute]
- else
- native_attribute = attribute.to_s
- end
-
- if self.class.parsed_auth_db[resource_name].has_key?(native_attribute)
- value = self.class.parsed_auth_db[resource_name][native_attribute]
- case value
- when true, :true
- value = :true
- when false, :false
- value = :false
- end
-
- @property_hash[attribute] = value
- return value
- else
- @property_hash.delete(attribute)
- return "" # so ralsh doesn't display it.
- end
+ if self.class.parsed_auth_db[resource_name].has_key?(native_attribute)
+ value = self.class.parsed_auth_db[resource_name][native_attribute]
+ case value
+ when true, :true
+ value = :true
+ when false, :false
+ value = :false
+ end
+
+ @property_hash[attribute] = value
+ return value
+ else
+ @property_hash.delete(attribute)
+ return "" # so ralsh doesn't display it.
end
+ end
- # property methods below
- #
- # We define them all dynamically apart from auth_type which is a special
- # case due to not being in the actual authorization db schema.
+ # property methods below
+ #
+ # We define them all dynamically apart from auth_type which is a special
+ # case due to not being in the actual authorization db schema.
- properties = [ :allow_root, :authenticate_user, :auth_class, :comment,
- :group, :k_of_n, :mechanisms, :rule, :session_owner,
- :shared, :timeout, :tries ]
+ properties = [ :allow_root, :authenticate_user, :auth_class, :comment,
+ :group, :k_of_n, :mechanisms, :rule, :session_owner,
+ :shared, :timeout, :tries ]
- properties.each do |field|
- define_method(field.to_s) do
- retrieve_value(resource[:name], field)
- end
-
- define_method(field.to_s + "=") do |value|
- @property_hash[field] = value
- end
+ properties.each do |field|
+ define_method(field.to_s) do
+ retrieve_value(resource[:name], field)
end
- def auth_type
- if resource.should(:auth_type) != nil
- return resource.should(:auth_type)
- elsif self.exists?
- # this is here just for ralsh, so it can work out what type it is.
- if self.class.rights.has_key?(resource[:name])
- return :right
- elsif self.class.rules.has_key?(resource[:name])
- return :rule
- else
- raise Puppet::Error.new("#{resource[:name]} is unknown type.")
- end
- else
- raise Puppet::Error.new("auth_type required for new resources.")
- end
+ define_method(field.to_s + "=") do |value|
+ @property_hash[field] = value
end
-
- def auth_type=(value)
- @property_hash[:auth_type] = value
+ end
+
+ def auth_type
+ if resource.should(:auth_type) != nil
+ return resource.should(:auth_type)
+ elsif self.exists?
+ # this is here just for ralsh, so it can work out what type it is.
+ if self.class.rights.has_key?(resource[:name])
+ return :right
+ elsif self.class.rules.has_key?(resource[:name])
+ return :rule
+ else
+ raise Puppet::Error.new("#{resource[:name]} is unknown type.")
+ end
+ else
+ raise Puppet::Error.new("auth_type required for new resources.")
end
+ end
+
+ def auth_type=(value)
+ @property_hash[:auth_type] = value
+ end
end
diff --git a/lib/puppet/provider/mailalias/aliases.rb b/lib/puppet/provider/mailalias/aliases.rb
index 388fd63..35c2f98 100755
--- a/lib/puppet/provider/mailalias/aliases.rb
+++ b/lib/puppet/provider/mailalias/aliases.rb
@@ -1,44 +1,44 @@
require 'puppet/provider/parsedfile'
- Puppet::Type.type(:mailalias).provide(
- :aliases,
- :parent => Puppet::Provider::ParsedFile,
- :default_target => "/etc/aliases",
+ Puppet::Type.type(:mailalias).provide(
+ :aliases,
+ :parent => Puppet::Provider::ParsedFile,
+ :default_target => "/etc/aliases",
- :filetype => :flat
+ :filetype => :flat
) do
- text_line :comment, :match => /^#/
- text_line :blank, :match => /^\s*$/
+ text_line :comment, :match => /^#/
+ text_line :blank, :match => /^\s*$/
- record_line :aliases, :fields => %w{name recipient}, :separator => /\s*:\s*/, :block_eval => :instance do
- def post_parse(record)
- # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
- # It's not sufficient to assign to an existing hash.
- recipient = record[:recipient].split(/\s*,\s*/).collect { |d| d.gsub(/^['"]|['"]$/, '') }
- record[:recipient] = recipient
- record
- end
+ record_line :aliases, :fields => %w{name recipient}, :separator => /\s*:\s*/, :block_eval => :instance do
+ def post_parse(record)
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ # It's not sufficient to assign to an existing hash.
+ recipient = record[:recipient].split(/\s*,\s*/).collect { |d| d.gsub(/^['"]|['"]$/, '') }
+ record[:recipient] = recipient
+ record
+ end
- def process(line)
- ret = {}
- records = line.split(':',2)
- ret[:name] = records[0].strip
- ret[:recipient] = records[1].strip
- ret
- end
+ def process(line)
+ ret = {}
+ records = line.split(':',2)
+ ret[:name] = records[0].strip
+ ret[:recipient] = records[1].strip
+ ret
+ end
- def to_line(record)
- dest = record[:recipient].collect do |d|
- # Quote aliases that have non-alpha chars
- if d =~ /[^-\w at .]/
- '"%s"' % d
- else
- d
- end
- end.join(",")
- "#{record[:name]}: #{dest}"
+ def to_line(record)
+ dest = record[:recipient].collect do |d|
+ # Quote aliases that have non-alpha chars
+ if d =~ /[^-\w at .]/
+ '"%s"' % d
+ else
+ d
end
+ end.join(",")
+ "#{record[:name]}: #{dest}"
end
+ end
end
diff --git a/lib/puppet/provider/maillist/mailman.rb b/lib/puppet/provider/maillist/mailman.rb
index cfb788b..4fdc20a 100755
--- a/lib/puppet/provider/maillist/mailman.rb
+++ b/lib/puppet/provider/maillist/mailman.rb
@@ -1,110 +1,110 @@
require 'puppet/provider/parsedfile'
Puppet::Type.type(:maillist).provide(:mailman) do
- if [ "CentOS", "RedHat", "Fedora" ].any? { |os| Facter.value(:operatingsystem) == os }
- commands :list_lists => "/usr/lib/mailman/bin/list_lists", :rmlist => "/usr/lib/mailman/bin/rmlist", :newlist => "/usr/lib/mailman/bin/newlist"
- commands :mailman => "/usr/lib/mailman/mail/mailman"
- else
- # This probably won't work for non-Debian installs, but this path is sure not to be in the PATH.
- commands :list_lists => "list_lists", :rmlist => "rmlist", :newlist => "newlist"
- commands :mailman => "/var/lib/mailman/mail/mailman"
- end
+ if [ "CentOS", "RedHat", "Fedora" ].any? { |os| Facter.value(:operatingsystem) == os }
+ commands :list_lists => "/usr/lib/mailman/bin/list_lists", :rmlist => "/usr/lib/mailman/bin/rmlist", :newlist => "/usr/lib/mailman/bin/newlist"
+ commands :mailman => "/usr/lib/mailman/mail/mailman"
+ else
+ # This probably won't work for non-Debian installs, but this path is sure not to be in the PATH.
+ commands :list_lists => "list_lists", :rmlist => "rmlist", :newlist => "newlist"
+ commands :mailman => "/var/lib/mailman/mail/mailman"
+ end
- mk_resource_methods
+ mk_resource_methods
- # Return a list of existing mailman instances.
- def self.instances
- list_lists.split("\n").reject { |line| line.include?("matching mailing lists") }.collect do |line|
- name, description = line.sub(/^\s+/, '').sub(/\s+$/, '').split(/\s+-\s+/)
- description = :absent if description.include?("no description available")
- new(:ensure => :present, :name => name, :description => description)
- end
+ # Return a list of existing mailman instances.
+ def self.instances
+ list_lists.split("\n").reject { |line| line.include?("matching mailing lists") }.collect do |line|
+ name, description = line.sub(/^\s+/, '').sub(/\s+$/, '').split(/\s+-\s+/)
+ description = :absent if description.include?("no description available")
+ new(:ensure => :present, :name => name, :description => description)
end
+ end
- # Prefetch our list list, yo.
- def self.prefetch(lists)
- instances.each do |prov|
- if list = lists[prov.name] || lists[prov.name.downcase]
- list.provider = prov
- end
- end
+ # Prefetch our list list, yo.
+ def self.prefetch(lists)
+ instances.each do |prov|
+ if list = lists[prov.name] || lists[prov.name.downcase]
+ list.provider = prov
+ end
end
+ end
- def aliases
- mailman = self.class.command(:mailman)
- name = self.name.downcase
- aliases = {name => "| #{mailman} post #{name}"}
- %w{admin bounces confirm join leave owner request subscribe unsubscribe}.each do |address|
- aliases["#{name}-#{address}"] = "| #{mailman} #{address} #{name}"
- end
- aliases
+ def aliases
+ mailman = self.class.command(:mailman)
+ name = self.name.downcase
+ aliases = {name => "| #{mailman} post #{name}"}
+ %w{admin bounces confirm join leave owner request subscribe unsubscribe}.each do |address|
+ aliases["#{name}-#{address}"] = "| #{mailman} #{address} #{name}"
end
+ aliases
+ end
- # Create the list.
- def create
- args = []
- if val = @resource[:mailserver]
- args << "--emailhost" << val
- end
- if val = @resource[:webserver]
- args << "--urlhost" << val
- end
-
- args << self.name
- if val = @resource[:admin]
- args << val
- else
- raise ArgumentError, "Mailman lists require an administrator email address"
- end
- if val = @resource[:password]
- args << val
- else
- raise ArgumentError, "Mailman lists require an administrator password"
- end
- newlist(*args)
+ # Create the list.
+ def create
+ args = []
+ if val = @resource[:mailserver]
+ args << "--emailhost" << val
end
-
- # Delete the list.
- def destroy(purge = false)
- args = []
- args << "--archives" if purge
- args << self.name
- rmlist(*args)
+ if val = @resource[:webserver]
+ args << "--urlhost" << val
end
- # Does our list exist already?
- def exists?
- properties[:ensure] != :absent
+ args << self.name
+ if val = @resource[:admin]
+ args << val
+ else
+ raise ArgumentError, "Mailman lists require an administrator email address"
end
-
- # Clear out the cached values.
- def flush
- @property_hash.clear
+ if val = @resource[:password]
+ args << val
+ else
+ raise ArgumentError, "Mailman lists require an administrator password"
end
+ newlist(*args)
+ end
- # Look up the current status.
- def properties
- if @property_hash.empty?
- @property_hash = query || {:ensure => :absent}
- @property_hash[:ensure] = :absent if @property_hash.empty?
- end
- @property_hash.dup
- end
+ # Delete the list.
+ def destroy(purge = false)
+ args = []
+ args << "--archives" if purge
+ args << self.name
+ rmlist(*args)
+ end
+
+ # Does our list exist already?
+ def exists?
+ properties[:ensure] != :absent
+ end
- # Remove the list and its archives.
- def purge
- destroy(true)
+ # Clear out the cached values.
+ def flush
+ @property_hash.clear
+ end
+
+ # Look up the current status.
+ def properties
+ if @property_hash.empty?
+ @property_hash = query || {:ensure => :absent}
+ @property_hash[:ensure] = :absent if @property_hash.empty?
end
+ @property_hash.dup
+ end
+
+ # Remove the list and its archives.
+ def purge
+ destroy(true)
+ end
- # Pull the current state of the list from the full list. We're
- # getting some double entendre here....
- def query
- self.class.instances.each do |list|
- if list.name == self.name or list.name.downcase == self.name
- return list.properties
- end
- end
- nil
+ # Pull the current state of the list from the full list. We're
+ # getting some double entendre here....
+ def query
+ self.class.instances.each do |list|
+ if list.name == self.name or list.name.downcase == self.name
+ return list.properties
+ end
end
+ nil
+ end
end
diff --git a/lib/puppet/provider/mcx/mcxcontent.rb b/lib/puppet/provider/mcx/mcxcontent.rb
index ba9ca31..cb5adc6 100644
--- a/lib/puppet/provider/mcx/mcxcontent.rb
+++ b/lib/puppet/provider/mcx/mcxcontent.rb
@@ -21,185 +21,185 @@ require 'tempfile'
Puppet::Type.type(:mcx).provide :mcxcontent, :parent => Puppet::Provider do
- desc "MCX Settings management using DirectoryService on OS X.
+ desc "MCX Settings management using DirectoryService on OS X.
- This provider manages the entire MCXSettings attribute available
- to some directory services nodes. This management is 'all or nothing'
- in that discrete application domain key value pairs are not managed
- by this provider.
+ This provider manages the entire MCXSettings attribute available
+ to some directory services nodes. This management is 'all or nothing'
+ in that discrete application domain key value pairs are not managed
+ by this provider.
- It is recommended to use WorkGroup Manager to configure Users, Groups,
- Computers, or ComputerLists, then use 'ralsh mcx' to generate a puppet
- manifest from the resulting configuration.
+ It is recommended to use WorkGroup Manager to configure Users, Groups,
+ Computers, or ComputerLists, then use 'ralsh mcx' to generate a puppet
+ manifest from the resulting configuration.
- Original Author: Jeff McCune (mccune.jeff at gmail.com)
+ Original Author: Jeff McCune (mccune.jeff at gmail.com)
"
- # This provides a mapping of puppet types to DirectoryService
- # type strings.
- TypeMap = {
- :user => "Users",
- :group => "Groups",
- :computer => "Computers",
- :computerlist => "ComputerLists",
- }
-
- class MCXContentProviderException < Exception
-
- end
-
- commands :dscl => "/usr/bin/dscl"
- confine :operatingsystem => :darwin
- defaultfor :operatingsystem => :darwin
-
- # self.instances is all important.
- # This is the only class method, it returns
- # an array of instances of this class.
- def self.instances
- mcx_list = []
- for ds_type in TypeMap.keys
- ds_path = "/Local/Default/#{TypeMap[ds_type]}"
- output = dscl 'localhost', '-list', ds_path
- member_list = output.split
- for ds_name in member_list
- content = mcxexport(ds_type, ds_name)
- if content.empty?
- Puppet.debug "/#{TypeMap[ds_type]}/#{ds_name} has no MCX data."
- else
- # This node has MCX data.
-
- rsrc = self.new(
- :name => "/#{TypeMap[ds_type]}/#{ds_name}",
- :ds_type => ds_type,
- :ds_name => ds_name,
-
- :content => content)
- mcx_list << rsrc
- end
- end
+ # This provides a mapping of puppet types to DirectoryService
+ # type strings.
+ TypeMap = {
+ :user => "Users",
+ :group => "Groups",
+ :computer => "Computers",
+ :computerlist => "ComputerLists",
+ }
+
+ class MCXContentProviderException < Exception
+
+ end
+
+ commands :dscl => "/usr/bin/dscl"
+ confine :operatingsystem => :darwin
+ defaultfor :operatingsystem => :darwin
+
+ # self.instances is all important.
+ # This is the only class method, it returns
+ # an array of instances of this class.
+ def self.instances
+ mcx_list = []
+ for ds_type in TypeMap.keys
+ ds_path = "/Local/Default/#{TypeMap[ds_type]}"
+ output = dscl 'localhost', '-list', ds_path
+ member_list = output.split
+ for ds_name in member_list
+ content = mcxexport(ds_type, ds_name)
+ if content.empty?
+ Puppet.debug "/#{TypeMap[ds_type]}/#{ds_name} has no MCX data."
+ else
+ # This node has MCX data.
+
+ rsrc = self.new(
+ :name => "/#{TypeMap[ds_type]}/#{ds_name}",
+ :ds_type => ds_type,
+ :ds_name => ds_name,
+
+ :content => content)
+ mcx_list << rsrc
end
- mcx_list
+ end
end
-
- private
-
- # mcxexport is used by instances, and therefore
- # a class method.
- def self.mcxexport(ds_type, ds_name)
- ds_t = TypeMap[ds_type]
- ds_n = ds_name.to_s
- ds_path = "/Local/Default/#{ds_t}/#{ds_n}"
- dscl 'localhost', '-mcxexport', ds_path
+ mcx_list
+ end
+
+ private
+
+ # mcxexport is used by instances, and therefore
+ # a class method.
+ def self.mcxexport(ds_type, ds_name)
+ ds_t = TypeMap[ds_type]
+ ds_n = ds_name.to_s
+ ds_path = "/Local/Default/#{ds_t}/#{ds_n}"
+ dscl 'localhost', '-mcxexport', ds_path
+ end
+
+ def mcximport(ds_type, ds_name, val)
+ ds_t = TypeMap[ds_type]
+ ds_n = ds_name.to_s
+ ds_path = "/Local/Default/#{ds_t}/#{ds_name}"
+
+ tmp = Tempfile.new('puppet_mcx')
+ begin
+ tmp << val
+ tmp.flush
+ dscl 'localhost', '-mcximport', ds_path, tmp.path
+ ensure
+ tmp.close
+ tmp.unlink
end
-
- def mcximport(ds_type, ds_name, val)
- ds_t = TypeMap[ds_type]
- ds_n = ds_name.to_s
- ds_path = "/Local/Default/#{ds_t}/#{ds_name}"
-
- tmp = Tempfile.new('puppet_mcx')
- begin
- tmp << val
- tmp.flush
- dscl 'localhost', '-mcximport', ds_path, tmp.path
- ensure
- tmp.close
- tmp.unlink
- end
+ end
+
+ # Given the resource name string, parse ds_type out.
+ def parse_type(name)
+ tmp = name.split('/')[1]
+ if ! tmp.is_a? String
+ raise MCXContentProviderException,
+ "Coult not parse ds_type from resource name '#{name}'. Specify with ds_type parameter."
end
-
- # Given the resource name string, parse ds_type out.
- def parse_type(name)
- tmp = name.split('/')[1]
- if ! tmp.is_a? String
- raise MCXContentProviderException,
- "Coult not parse ds_type from resource name '#{name}'. Specify with ds_type parameter."
- end
- # De-pluralize and downcase.
- tmp = tmp.chop.downcase.to_sym
- if not TypeMap.keys.member? tmp
- raise MCXContentProviderException,
- "Coult not parse ds_type from resource name '#{name}'. Specify with ds_type parameter."
- end
- tmp
+ # De-pluralize and downcase.
+ tmp = tmp.chop.downcase.to_sym
+ if not TypeMap.keys.member? tmp
+ raise MCXContentProviderException,
+ "Coult not parse ds_type from resource name '#{name}'. Specify with ds_type parameter."
end
-
- # Given the resource name string, parse ds_name out.
- def parse_name(name)
- ds_name = name.split('/')[2]
- if ! ds_name.is_a? String
- raise MCXContentProviderException,
- "Could not parse ds_name from resource name '#{name}'. Specify with ds_name parameter."
- end
- ds_name
+ tmp
+ end
+
+ # Given the resource name string, parse ds_name out.
+ def parse_name(name)
+ ds_name = name.split('/')[2]
+ if ! ds_name.is_a? String
+ raise MCXContentProviderException,
+ "Could not parse ds_name from resource name '#{name}'. Specify with ds_name parameter."
end
+ ds_name
+ end
+
+ # Gather ds_type and ds_name from resource or
+ # parse it out of the name.
+ # This is a private instance method, not a class method.
+ def get_dsparams
+ ds_type = resource[:ds_type]
+ ds_type ||= parse_type(resource[:name])
+ raise MCXContentProviderException unless TypeMap.keys.include? ds_type.to_sym
+
+ ds_name = resource[:ds_name]
+ ds_name ||= parse_name(resource[:name])
+
+ rval = {
+ :ds_type => ds_type.to_sym,
+ :ds_name => ds_name,
+ }
- # Gather ds_type and ds_name from resource or
- # parse it out of the name.
- # This is a private instance method, not a class method.
- def get_dsparams
- ds_type = resource[:ds_type]
- ds_type ||= parse_type(resource[:name])
- raise MCXContentProviderException unless TypeMap.keys.include? ds_type.to_sym
-
- ds_name = resource[:ds_name]
- ds_name ||= parse_name(resource[:name])
-
- rval = {
- :ds_type => ds_type.to_sym,
- :ds_name => ds_name,
- }
-
- return rval
+ return rval
- end
+ end
- public
+ public
- def create
- self.content=(resource[:content])
- end
+ def create
+ self.content=(resource[:content])
+ end
- def destroy
- ds_parms = get_dsparams
- ds_t = TypeMap[ds_parms[:ds_type]]
- ds_n = ds_parms[:ds_name].to_s
- ds_path = "/Local/Default/#{ds_t}/#{ds_n}"
+ def destroy
+ ds_parms = get_dsparams
+ ds_t = TypeMap[ds_parms[:ds_type]]
+ ds_n = ds_parms[:ds_name].to_s
+ ds_path = "/Local/Default/#{ds_t}/#{ds_n}"
- dscl 'localhost', '-mcxdelete', ds_path
- end
+ dscl 'localhost', '-mcxdelete', ds_path
+ end
- def exists?
- # JJM Just re-use the content method and see if it's empty.
- begin
- mcx = content
- rescue Puppet::ExecutionFailure => e
- return false
- end
- has_mcx = ! mcx.empty?
+ def exists?
+ # JJM Just re-use the content method and see if it's empty.
+ begin
+ mcx = content
+ rescue Puppet::ExecutionFailure => e
+ return false
end
+ has_mcx = ! mcx.empty?
+ end
- def content
- ds_parms = get_dsparams
+ def content
+ ds_parms = get_dsparams
- mcx = self.class.mcxexport(
- ds_parms[:ds_type],
+ mcx = self.class.mcxexport(
+ ds_parms[:ds_type],
- ds_parms[:ds_name])
- mcx
- end
+ ds_parms[:ds_name])
+ mcx
+ end
- def content=(value)
- # dscl localhost -mcximport
- ds_parms = get_dsparams
+ def content=(value)
+ # dscl localhost -mcximport
+ ds_parms = get_dsparams
- mcx = mcximport(
- ds_parms[:ds_type],
- ds_parms[:ds_name],
+ mcx = mcximport(
+ ds_parms[:ds_type],
+ ds_parms[:ds_name],
- resource[:content])
- mcx
- end
+ resource[:content])
+ mcx
+ end
end
diff --git a/lib/puppet/provider/mount.rb b/lib/puppet/provider/mount.rb
index 2136339..393ae56 100644
--- a/lib/puppet/provider/mount.rb
+++ b/lib/puppet/provider/mount.rb
@@ -6,46 +6,46 @@ require 'puppet'
# A module just to store the mount/unmount methods. Individual providers
# still need to add the mount commands manually.
module Puppet::Provider::Mount
- # This only works when the mount point is synced to the fstab.
- def mount
- # Manually pass the mount options in, since some OSes *cough*OS X*cough* don't
- # read from /etc/fstab but still want to use this type.
- args = []
- args << "-o" << self.options if self.options and self.options != :absent
- args << resource[:name]
+ # This only works when the mount point is synced to the fstab.
+ def mount
+ # Manually pass the mount options in, since some OSes *cough*OS X*cough* don't
+ # read from /etc/fstab but still want to use this type.
+ args = []
+ args << "-o" << self.options if self.options and self.options != :absent
+ args << resource[:name]
- flush if respond_to?(:flush)
- mountcmd(*args)
- end
+ flush if respond_to?(:flush)
+ mountcmd(*args)
+ end
- def remount
- info "Remounting"
- if resource[:remounts] == :true
- mountcmd "-o", "remount", resource[:name]
- else
- unmount
- mount
- end
+ def remount
+ info "Remounting"
+ if resource[:remounts] == :true
+ mountcmd "-o", "remount", resource[:name]
+ else
+ unmount
+ mount
end
+ end
- # This only works when the mount point is synced to the fstab.
- def unmount
- umount resource[:name]
- end
+ # This only works when the mount point is synced to the fstab.
+ def unmount
+ umount resource[:name]
+ end
- # Is the mount currently mounted?
- def mounted?
- platform = Facter.value("operatingsystem")
- name = resource[:name]
- mounts = mountcmd.split("\n").find do |line|
- case platform
- when "Darwin"
- line =~ / on #{name} / or line =~ %r{ on /private/var/automount#{name}}
- when "Solaris"
- line =~ /^#{name} on /
- else
- line =~ / on #{name} /
- end
- end
+ # Is the mount currently mounted?
+ def mounted?
+ platform = Facter.value("operatingsystem")
+ name = resource[:name]
+ mounts = mountcmd.split("\n").find do |line|
+ case platform
+ when "Darwin"
+ line =~ / on #{name} / or line =~ %r{ on /private/var/automount#{name}}
+ when "Solaris"
+ line =~ /^#{name} on /
+ else
+ line =~ / on #{name} /
+ end
end
+ end
end
diff --git a/lib/puppet/provider/mount/parsed.rb b/lib/puppet/provider/mount/parsed.rb
index 1100ad6..82d1628 100755
--- a/lib/puppet/provider/mount/parsed.rb
+++ b/lib/puppet/provider/mount/parsed.rb
@@ -5,43 +5,43 @@ fstab = nil
case Facter.value(:operatingsystem)
when "Solaris"; fstab = "/etc/vfstab"
else
- fstab = "/etc/fstab"
+ fstab = "/etc/fstab"
end
- Puppet::Type.type(:mount).provide(
- :parsed,
- :parent => Puppet::Provider::ParsedFile,
- :default_target => fstab,
+ Puppet::Type.type(:mount).provide(
+ :parsed,
+ :parent => Puppet::Provider::ParsedFile,
+ :default_target => fstab,
- :filetype => :flat
+ :filetype => :flat
) do
- include Puppet::Provider::Mount
- #confine :exists => fstab
+ include Puppet::Provider::Mount
+ #confine :exists => fstab
- commands :mountcmd => "mount", :umount => "umount"
+ commands :mountcmd => "mount", :umount => "umount"
- @platform = Facter["operatingsystem"].value
- case @platform
- when "Solaris"
- @fields = [:device, :blockdevice, :name, :fstype, :pass, :atboot, :options]
- else
- @fields = [:device, :name, :fstype, :options, :dump, :pass]
- @fielddefaults = [ nil ] * 4 + [ "0", "2" ]
- end
+ @platform = Facter["operatingsystem"].value
+ case @platform
+ when "Solaris"
+ @fields = [:device, :blockdevice, :name, :fstype, :pass, :atboot, :options]
+ else
+ @fields = [:device, :name, :fstype, :options, :dump, :pass]
+ @fielddefaults = [ nil ] * 4 + [ "0", "2" ]
+ end
- text_line :comment, :match => /^\s*#/
- text_line :blank, :match => /^\s*$/
+ text_line :comment, :match => /^\s*#/
+ text_line :blank, :match => /^\s*$/
- optional_fields = @fields - [:device, :name, :blockdevice]
- mandatory_fields = @fields - optional_fields
+ optional_fields = @fields - [:device, :name, :blockdevice]
+ mandatory_fields = @fields - optional_fields
- # fstab will ignore lines that have fewer than the mandatory number of columns,
- # so we should, too.
- field_pattern = '(\s*(?>\S+))'
- text_line :incomplete, :match => /^(?!#{field_pattern}{#{mandatory_fields.length}})/
+ # fstab will ignore lines that have fewer than the mandatory number of columns,
+ # so we should, too.
+ field_pattern = '(\s*(?>\S+))'
+ text_line :incomplete, :match => /^(?!#{field_pattern}{#{mandatory_fields.length}})/
- record_line self.name, :fields => @fields, :separator => /\s+/, :joiner => "\t", :optional => optional_fields
+ record_line self.name, :fields => @fields, :separator => /\s+/, :joiner => "\t", :optional => optional_fields
end
diff --git a/lib/puppet/provider/naginator.rb b/lib/puppet/provider/naginator.rb
index 1006a4c..5c610fb 100644
--- a/lib/puppet/provider/naginator.rb
+++ b/lib/puppet/provider/naginator.rb
@@ -7,52 +7,52 @@ require 'puppet/external/nagios'
# The base class for all Naginator providers.
class Puppet::Provider::Naginator < Puppet::Provider::ParsedFile
- NAME_STRING = "## --PUPPET_NAME-- (called '_naginator_name' in the manifest)"
- # Retrieve the associated class from Nagios::Base.
- def self.nagios_type
- unless @nagios_type
- name = resource_type.name.to_s.sub(/^nagios_/, '')
- unless @nagios_type = Nagios::Base.type(name.to_sym)
- raise Puppet::DevError, "Could not find nagios type '#{name}'"
- end
-
- # And add our 'ensure' settings, since they aren't a part of
- # Naginator by default
- @nagios_type.send(:attr_accessor, :ensure, :target, :on_disk)
- end
- @nagios_type
+ NAME_STRING = "## --PUPPET_NAME-- (called '_naginator_name' in the manifest)"
+ # Retrieve the associated class from Nagios::Base.
+ def self.nagios_type
+ unless @nagios_type
+ name = resource_type.name.to_s.sub(/^nagios_/, '')
+ unless @nagios_type = Nagios::Base.type(name.to_sym)
+ raise Puppet::DevError, "Could not find nagios type '#{name}'"
+ end
+
+ # And add our 'ensure' settings, since they aren't a part of
+ # Naginator by default
+ @nagios_type.send(:attr_accessor, :ensure, :target, :on_disk)
end
-
- def self.parse(text)
- Nagios::Parser.new.parse(text.gsub(NAME_STRING, "_naginator_name"))
- rescue => detail
- raise Puppet::Error, "Could not parse configuration for #{resource_type.name}: #{detail}"
- end
-
- def self.to_file(records)
- header + records.collect { |record| record.to_s }.join("\n").gsub("_naginator_name", NAME_STRING)
- end
-
- def self.skip_record?(record)
- false
- end
-
- def self.valid_attr?(klass, attr_name)
- nagios_type.parameters.include?(attr_name)
- end
-
- def initialize(resource = nil)
- if resource.is_a?(Nagios::Base)
- # We don't use a duplicate here, because some providers (ParsedFile, at least)
- # use the hash here for later events.
- @property_hash = resource
- elsif resource
- @resource = resource if resource
- # LAK 2007-05-09: Keep the model stuff around for backward compatibility
- @model = resource
- @property_hash = self.class.nagios_type.new
- else
- @property_hash = self.class.nagios_type.new
- end
+ @nagios_type
+ end
+
+ def self.parse(text)
+ Nagios::Parser.new.parse(text.gsub(NAME_STRING, "_naginator_name"))
+ rescue => detail
+ raise Puppet::Error, "Could not parse configuration for #{resource_type.name}: #{detail}"
+ end
+
+ def self.to_file(records)
+ header + records.collect { |record| record.to_s }.join("\n").gsub("_naginator_name", NAME_STRING)
+ end
+
+ def self.skip_record?(record)
+ false
+ end
+
+ def self.valid_attr?(klass, attr_name)
+ nagios_type.parameters.include?(attr_name)
+ end
+
+ def initialize(resource = nil)
+ if resource.is_a?(Nagios::Base)
+ # We don't use a duplicate here, because some providers (ParsedFile, at least)
+ # use the hash here for later events.
+ @property_hash = resource
+ elsif resource
+ @resource = resource if resource
+ # LAK 2007-05-09: Keep the model stuff around for backward compatibility
+ @model = resource
+ @property_hash = self.class.nagios_type.new
+ else
+ @property_hash = self.class.nagios_type.new
end
+ end
end
diff --git a/lib/puppet/provider/nameservice.rb b/lib/puppet/provider/nameservice.rb
index 6564a41..7339b64 100644
--- a/lib/puppet/provider/nameservice.rb
+++ b/lib/puppet/provider/nameservice.rb
@@ -4,270 +4,270 @@ require 'puppet'
# their backend, but they're pretty similar on the front-end. This class
# provides a way for them all to be as similar as possible.
class Puppet::Provider::NameService < Puppet::Provider
- class << self
- def autogen_default(param)
- defined?(@autogen_defaults) ? @autogen_defaults[symbolize(param)] : nil
- end
-
- def autogen_defaults(hash)
- @autogen_defaults ||= {}
- hash.each do |param, value|
- @autogen_defaults[symbolize(param)] = value
- end
- end
+ class << self
+ def autogen_default(param)
+ defined?(@autogen_defaults) ? @autogen_defaults[symbolize(param)] : nil
+ end
- def initvars
- @checks = {}
- super
- end
+ def autogen_defaults(hash)
+ @autogen_defaults ||= {}
+ hash.each do |param, value|
+ @autogen_defaults[symbolize(param)] = value
+ end
+ end
- def instances
- objects = []
- listbyname do |name|
- objects << new(:name => name, :ensure => :present)
- end
+ def initvars
+ @checks = {}
+ super
+ end
- objects
- end
+ def instances
+ objects = []
+ listbyname do |name|
+ objects << new(:name => name, :ensure => :present)
+ end
- def option(name, option)
- name = name.intern if name.is_a? String
- (defined?(@options) and @options.include? name and @options[name].include? option) ? @options[name][option] : nil
- end
+ objects
+ end
- def options(name, hash)
- raise Puppet::DevError, "#{name} is not a valid attribute for #{resource_type.name}" unless resource_type.valid_parameter?(name)
- @options ||= {}
- @options[name] ||= {}
+ def option(name, option)
+ name = name.intern if name.is_a? String
+ (defined?(@options) and @options.include? name and @options[name].include? option) ? @options[name][option] : nil
+ end
- # Set options individually, so we can call the options method
- # multiple times.
- hash.each do |param, value|
- @options[name][param] = value
- end
- end
+ def options(name, hash)
+ raise Puppet::DevError, "#{name} is not a valid attribute for #{resource_type.name}" unless resource_type.valid_parameter?(name)
+ @options ||= {}
+ @options[name] ||= {}
- # List everything out by name. Abstracted a bit so that it works
- # for both users and groups.
- def listbyname
- names = []
- Etc.send("set#{section()}ent")
- begin
- while ent = Etc.send("get#{section()}ent")
- names << ent.name
- yield ent.name if block_given?
- end
- ensure
- Etc.send("end#{section()}ent")
- end
-
- names
- end
+ # Set options individually, so we can call the options method
+ # multiple times.
+ hash.each do |param, value|
+ @options[name][param] = value
+ end
+ end
- def resource_type=(resource_type)
- super
- @resource_type.validproperties.each do |prop|
- next if prop == :ensure
- define_method(prop) { get(prop) || :absent} unless public_method_defined?(prop)
- define_method(prop.to_s + "=") { |*vals| set(prop, *vals) } unless public_method_defined?(prop.to_s + "=")
- end
+ # List everything out by name. Abstracted a bit so that it works
+ # for both users and groups.
+ def listbyname
+ names = []
+ Etc.send("set#{section()}ent")
+ begin
+ while ent = Etc.send("get#{section()}ent")
+ names << ent.name
+ yield ent.name if block_given?
end
+ ensure
+ Etc.send("end#{section()}ent")
+ end
- # This is annoying, but there really aren't that many options,
- # and this *is* built into Ruby.
- def section
- unless defined?(@resource_type)
- raise Puppet::DevError,
- "Cannot determine Etc section without a resource type"
-
- end
-
- if @resource_type.name == :group
- "gr"
- else
- "pw"
- end
- end
+ names
+ end
- def validate(name, value)
- name = name.intern if name.is_a? String
- if @checks.include? name
- block = @checks[name][:block]
- raise ArgumentError, "Invalid value #{value}: #{@checks[name][:error]}" unless block.call(value)
- end
- end
+ def resource_type=(resource_type)
+ super
+ @resource_type.validproperties.each do |prop|
+ next if prop == :ensure
+ define_method(prop) { get(prop) || :absent} unless public_method_defined?(prop)
+ define_method(prop.to_s + "=") { |*vals| set(prop, *vals) } unless public_method_defined?(prop.to_s + "=")
+ end
+ end
- def verify(name, error, &block)
- name = name.intern if name.is_a? String
- @checks[name] = {:error => error, :block => block}
- end
+ # This is annoying, but there really aren't that many options,
+ # and this *is* built into Ruby.
+ def section
+ unless defined?(@resource_type)
+ raise Puppet::DevError,
+ "Cannot determine Etc section without a resource type"
- private
+ end
- def op(property)
- @ops[property.name] || ("-#{property.name}")
- end
+ if @resource_type.name == :group
+ "gr"
+ else
+ "pw"
+ end
end
- # Autogenerate a value. Mostly used for uid/gid, but also used heavily
- # with DirectoryServices, because DirectoryServices is stupid.
- def autogen(field)
- field = symbolize(field)
- id_generators = {:user => :uid, :group => :gid}
- if id_generators[@resource.class.name] == field
- return autogen_id(field)
- else
- if value = self.class.autogen_default(field)
- return value
- elsif respond_to?("autogen_#{field}")
- return send("autogen_#{field}")
- else
- return nil
- end
- end
+ def validate(name, value)
+ name = name.intern if name.is_a? String
+ if @checks.include? name
+ block = @checks[name][:block]
+ raise ArgumentError, "Invalid value #{value}: #{@checks[name][:error]}" unless block.call(value)
+ end
end
- # Autogenerate either a uid or a gid. This is hard-coded: we can only
- # generate one field type per class.
- def autogen_id(field)
- highest = 0
-
- group = method = nil
- case @resource.class.name
- when :user; group = :passwd; method = :uid
- when :group; group = :group; method = :gid
- else
- raise Puppet::DevError, "Invalid resource name #{resource}"
- end
+ def verify(name, error, &block)
+ name = name.intern if name.is_a? String
+ @checks[name] = {:error => error, :block => block}
+ end
- # Make sure we don't use the same value multiple times
- if defined?(@@prevauto)
- @@prevauto += 1
- else
- Etc.send(group) { |obj|
- if obj.gid > highest
- highest = obj.send(method) unless obj.send(method) > 65000
- end
- }
-
- @@prevauto = highest + 1
- end
+ private
- @@prevauto
+ def op(property)
+ @ops[property.name] || ("-#{property.name}")
+ end
+ end
+
+ # Autogenerate a value. Mostly used for uid/gid, but also used heavily
+ # with DirectoryServices, because DirectoryServices is stupid.
+ def autogen(field)
+ field = symbolize(field)
+ id_generators = {:user => :uid, :group => :gid}
+ if id_generators[@resource.class.name] == field
+ return autogen_id(field)
+ else
+ if value = self.class.autogen_default(field)
+ return value
+ elsif respond_to?("autogen_#{field}")
+ return send("autogen_#{field}")
+ else
+ return nil
+ end
+ end
+ end
+
+ # Autogenerate either a uid or a gid. This is hard-coded: we can only
+ # generate one field type per class.
+ def autogen_id(field)
+ highest = 0
+
+ group = method = nil
+ case @resource.class.name
+ when :user; group = :passwd; method = :uid
+ when :group; group = :group; method = :gid
+ else
+ raise Puppet::DevError, "Invalid resource name #{resource}"
end
- def create
- if exists?
- info "already exists"
- # The object already exists
- return nil
+ # Make sure we don't use the same value multiple times
+ if defined?(@@prevauto)
+ @@prevauto += 1
+ else
+ Etc.send(group) { |obj|
+ if obj.gid > highest
+ highest = obj.send(method) unless obj.send(method) > 65000
end
+ }
- begin
- execute(self.addcmd)
- rescue Puppet::ExecutionFailure => detail
- raise Puppet::Error, "Could not create #{@resource.class.name} #{@resource.name}: #{detail}"
- end
+ @@prevauto = highest + 1
end
- def delete
- unless exists?
- info "already absent"
- # the object already doesn't exist
- return nil
- end
+ @@prevauto
+ end
- begin
- execute(self.deletecmd)
- rescue Puppet::ExecutionFailure => detail
- raise Puppet::Error, "Could not delete #{@resource.class.name} #{@resource.name}: #{detail}"
- end
+ def create
+ if exists?
+ info "already exists"
+ # The object already exists
+ return nil
end
- def ensure
- if exists?
- :present
- else
- :absent
- end
+ begin
+ execute(self.addcmd)
+ rescue Puppet::ExecutionFailure => detail
+ raise Puppet::Error, "Could not create #{@resource.class.name} #{@resource.name}: #{detail}"
end
+ end
- # Does our object exist?
- def exists?
- !!getinfo(true)
+ def delete
+ unless exists?
+ info "already absent"
+ # the object already doesn't exist
+ return nil
end
- # Retrieve a specific value by name.
- def get(param)
- (hash = getinfo(false)) ? hash[param] : nil
+ begin
+ execute(self.deletecmd)
+ rescue Puppet::ExecutionFailure => detail
+ raise Puppet::Error, "Could not delete #{@resource.class.name} #{@resource.name}: #{detail}"
end
+ end
- # Retrieve what we can about our object
- def getinfo(refresh)
- if @objectinfo.nil? or refresh == true
- @etcmethod ||= ("get" + self.class.section.to_s + "nam").intern
- begin
- @objectinfo = Etc.send(@etcmethod, @resource[:name])
- rescue ArgumentError => detail
- @objectinfo = nil
- end
- end
-
- # Now convert our Etc struct into a hash.
- @objectinfo ? info2hash(@objectinfo) : nil
+ def ensure
+ if exists?
+ :present
+ else
+ :absent
+ end
+ end
+
+ # Does our object exist?
+ def exists?
+ !!getinfo(true)
+ end
+
+ # Retrieve a specific value by name.
+ def get(param)
+ (hash = getinfo(false)) ? hash[param] : nil
+ end
+
+ # Retrieve what we can about our object
+ def getinfo(refresh)
+ if @objectinfo.nil? or refresh == true
+ @etcmethod ||= ("get" + self.class.section.to_s + "nam").intern
+ begin
+ @objectinfo = Etc.send(@etcmethod, @resource[:name])
+ rescue ArgumentError => detail
+ @objectinfo = nil
+ end
end
- # The list of all groups the user is a member of. Different
- # user mgmt systems will need to override this method.
- def groups
- groups = []
-
- # Reset our group list
- Etc.setgrent
+ # Now convert our Etc struct into a hash.
+ @objectinfo ? info2hash(@objectinfo) : nil
+ end
- user = @resource[:name]
+ # The list of all groups the user is a member of. Different
+ # user mgmt systems will need to override this method.
+ def groups
+ groups = []
- # Now iterate across all of the groups, adding each one our
- # user is a member of
- while group = Etc.getgrent
- members = group.mem
+ # Reset our group list
+ Etc.setgrent
- groups << group.name if members.include? user
- end
+ user = @resource[:name]
- # We have to close the file, so each listing is a separate
- # reading of the file.
- Etc.endgrent
+ # Now iterate across all of the groups, adding each one our
+ # user is a member of
+ while group = Etc.getgrent
+ members = group.mem
- groups.join(",")
+ groups << group.name if members.include? user
end
- # Convert the Etc struct into a hash.
- def info2hash(info)
- hash = {}
- self.class.resource_type.validproperties.each do |param|
- method = posixmethod(param)
- hash[param] = info.send(posixmethod(param)) if info.respond_to? method
- end
+ # We have to close the file, so each listing is a separate
+ # reading of the file.
+ Etc.endgrent
- hash
+ groups.join(",")
+ end
+
+ # Convert the Etc struct into a hash.
+ def info2hash(info)
+ hash = {}
+ self.class.resource_type.validproperties.each do |param|
+ method = posixmethod(param)
+ hash[param] = info.send(posixmethod(param)) if info.respond_to? method
end
- def initialize(resource)
- super
+ hash
+ end
- @objectinfo = nil
- end
+ def initialize(resource)
+ super
- def set(param, value)
- self.class.validate(param, value)
- cmd = modifycmd(param, value)
- raise Puppet::DevError, "Nameservice command must be an array" unless cmd.is_a?(Array)
- begin
- execute(cmd)
- rescue Puppet::ExecutionFailure => detail
- raise Puppet::Error, "Could not set #{param} on #{@resource.class.name}[#{@resource.name}]: #{detail}"
- end
+ @objectinfo = nil
+ end
+
+ def set(param, value)
+ self.class.validate(param, value)
+ cmd = modifycmd(param, value)
+ raise Puppet::DevError, "Nameservice command must be an array" unless cmd.is_a?(Array)
+ begin
+ execute(cmd)
+ rescue Puppet::ExecutionFailure => detail
+ raise Puppet::Error, "Could not set #{param} on #{@resource.class.name}[#{@resource.name}]: #{detail}"
end
+ end
end
diff --git a/lib/puppet/provider/nameservice/directoryservice.rb b/lib/puppet/provider/nameservice/directoryservice.rb
index 060ed4c..76fc466 100644
--- a/lib/puppet/provider/nameservice/directoryservice.rb
+++ b/lib/puppet/provider/nameservice/directoryservice.rb
@@ -20,497 +20,497 @@ require 'cgi'
class Puppet::Provider::NameService
class DirectoryService < Puppet::Provider::NameService
- # JJM: Dive into the singleton_class
- class << self
- # JJM: This allows us to pass information when calling
- # Puppet::Type.type
- # e.g. Puppet::Type.type(:user).provide :directoryservice, :ds_path => "Users"
- # This is referenced in the get_ds_path class method
- attr_writer :ds_path
- attr_writer :macosx_version_major
+ # JJM: Dive into the singleton_class
+ class << self
+ # JJM: This allows us to pass information when calling
+ # Puppet::Type.type
+ # e.g. Puppet::Type.type(:user).provide :directoryservice, :ds_path => "Users"
+ # This is referenced in the get_ds_path class method
+ attr_writer :ds_path
+ attr_writer :macosx_version_major
+ end
+
+ initvars
+
+ commands :dscl => "/usr/bin/dscl"
+ commands :dseditgroup => "/usr/sbin/dseditgroup"
+ commands :sw_vers => "/usr/bin/sw_vers"
+ confine :operatingsystem => :darwin
+ defaultfor :operatingsystem => :darwin
+
+
+ # JJM 2007-07-25: This map is used to map NameService attributes to their
+ # corresponding DirectoryService attribute names.
+ # See: http://images.apple.com/server/docs/Open_Directory_v10.4.pdf
+ # JJM: Note, this is de-coupled from the Puppet::Type, and must
+ # be actively maintained. There may also be collisions with different
+ # types (Users, Groups, Mounts, Hosts, etc...)
+ @@ds_to_ns_attribute_map = {
+ 'RecordName' => :name,
+ 'PrimaryGroupID' => :gid,
+ 'NFSHomeDirectory' => :home,
+ 'UserShell' => :shell,
+ 'UniqueID' => :uid,
+ 'RealName' => :comment,
+ 'Password' => :password,
+ 'GeneratedUID' => :guid,
+ 'IPAddress' => :ip_address,
+ 'ENetAddress' => :en_address,
+ 'GroupMembership' => :members,
+ }
+ # JJM The same table as above, inverted.
+ @@ns_to_ds_attribute_map = {
+ :name => 'RecordName',
+ :gid => 'PrimaryGroupID',
+ :home => 'NFSHomeDirectory',
+ :shell => 'UserShell',
+ :uid => 'UniqueID',
+ :comment => 'RealName',
+ :password => 'Password',
+ :guid => 'GeneratedUID',
+ :en_address => 'ENetAddress',
+ :ip_address => 'IPAddress',
+ :members => 'GroupMembership',
+ }
+
+ @@password_hash_dir = "/var/db/shadow/hash"
+
+ def self.instances
+ # JJM Class method that provides an array of instance objects of this
+ # type.
+ # JJM: Properties are dependent on the Puppet::Type we're managine.
+ type_property_array = [:name] + @resource_type.validproperties
+
+ # Create a new instance of this Puppet::Type for each object present
+ # on the system.
+ list_all_present.collect do |name_string|
+ self.new(single_report(name_string, *type_property_array))
end
-
- initvars
-
- commands :dscl => "/usr/bin/dscl"
- commands :dseditgroup => "/usr/sbin/dseditgroup"
- commands :sw_vers => "/usr/bin/sw_vers"
- confine :operatingsystem => :darwin
- defaultfor :operatingsystem => :darwin
-
-
- # JJM 2007-07-25: This map is used to map NameService attributes to their
- # corresponding DirectoryService attribute names.
- # See: http://images.apple.com/server/docs/Open_Directory_v10.4.pdf
- # JJM: Note, this is de-coupled from the Puppet::Type, and must
- # be actively maintained. There may also be collisions with different
- # types (Users, Groups, Mounts, Hosts, etc...)
- @@ds_to_ns_attribute_map = {
- 'RecordName' => :name,
- 'PrimaryGroupID' => :gid,
- 'NFSHomeDirectory' => :home,
- 'UserShell' => :shell,
- 'UniqueID' => :uid,
- 'RealName' => :comment,
- 'Password' => :password,
- 'GeneratedUID' => :guid,
- 'IPAddress' => :ip_address,
- 'ENetAddress' => :en_address,
- 'GroupMembership' => :members,
- }
- # JJM The same table as above, inverted.
- @@ns_to_ds_attribute_map = {
- :name => 'RecordName',
- :gid => 'PrimaryGroupID',
- :home => 'NFSHomeDirectory',
- :shell => 'UserShell',
- :uid => 'UniqueID',
- :comment => 'RealName',
- :password => 'Password',
- :guid => 'GeneratedUID',
- :en_address => 'ENetAddress',
- :ip_address => 'IPAddress',
- :members => 'GroupMembership',
- }
-
- @@password_hash_dir = "/var/db/shadow/hash"
-
- def self.instances
- # JJM Class method that provides an array of instance objects of this
- # type.
- # JJM: Properties are dependent on the Puppet::Type we're managine.
- type_property_array = [:name] + @resource_type.validproperties
-
- # Create a new instance of this Puppet::Type for each object present
- # on the system.
- list_all_present.collect do |name_string|
- self.new(single_report(name_string, *type_property_array))
- end
+ end
+
+ def self.get_ds_path
+ # JJM: 2007-07-24 This method dynamically returns the DS path we're concerned with.
+ # For example, if we're working with an user type, this will be /Users
+ # with a group type, this will be /Groups.
+ # @ds_path is an attribute of the class itself.
+ return @ds_path if defined?(@ds_path)
+ # JJM: "Users" or "Groups" etc ... (Based on the Puppet::Type)
+ # Remember this is a class method, so self.class is Class
+ # Also, @resource_type seems to be the reference to the
+ # Puppet::Type this class object is providing for.
+ @resource_type.name.to_s.capitalize + "s"
+ end
+
+ def self.get_macosx_version_major
+ return @macosx_version_major if defined?(@macosx_version_major)
+ begin
+ # Make sure we've loaded all of the facts
+ Facter.loadfacts
+
+ if Facter.value(:macosx_productversion_major)
+ product_version_major = Facter.value(:macosx_productversion_major)
+ else
+ # TODO: remove this code chunk once we require Facter 1.5.5 or higher.
+ Puppet.warning("DEPRECATION WARNING: Future versions of the directoryservice provider will require Facter 1.5.5 or newer.")
+ product_version = Facter.value(:macosx_productversion)
+ fail("Could not determine OS X version from Facter") if product_version.nil?
+ product_version_major = product_version.scan(/(\d+)\.(\d+)./).join(".")
+ end
+ fail("#{product_version_major} is not supported by the directoryservice provider") if %w{10.0 10.1 10.2 10.3}.include?(product_version_major)
+ @macosx_version_major = product_version_major
+ return @macosx_version_major
+ rescue Puppet::ExecutionFailure => detail
+ fail("Could not determine OS X version: #{detail}")
end
+ end
- def self.get_ds_path
- # JJM: 2007-07-24 This method dynamically returns the DS path we're concerned with.
- # For example, if we're working with an user type, this will be /Users
- # with a group type, this will be /Groups.
- # @ds_path is an attribute of the class itself.
- return @ds_path if defined?(@ds_path)
- # JJM: "Users" or "Groups" etc ... (Based on the Puppet::Type)
- # Remember this is a class method, so self.class is Class
- # Also, @resource_type seems to be the reference to the
- # Puppet::Type this class object is providing for.
- @resource_type.name.to_s.capitalize + "s"
- end
- def self.get_macosx_version_major
- return @macosx_version_major if defined?(@macosx_version_major)
- begin
- # Make sure we've loaded all of the facts
- Facter.loadfacts
-
- if Facter.value(:macosx_productversion_major)
- product_version_major = Facter.value(:macosx_productversion_major)
- else
- # TODO: remove this code chunk once we require Facter 1.5.5 or higher.
- Puppet.warning("DEPRECATION WARNING: Future versions of the directoryservice provider will require Facter 1.5.5 or newer.")
- product_version = Facter.value(:macosx_productversion)
- fail("Could not determine OS X version from Facter") if product_version.nil?
- product_version_major = product_version.scan(/(\d+)\.(\d+)./).join(".")
- end
- fail("#{product_version_major} is not supported by the directoryservice provider") if %w{10.0 10.1 10.2 10.3}.include?(product_version_major)
- @macosx_version_major = product_version_major
- return @macosx_version_major
- rescue Puppet::ExecutionFailure => detail
- fail("Could not determine OS X version: #{detail}")
- end
+ def self.list_all_present
+ # JJM: List all objects of this Puppet::Type already present on the system.
+ begin
+ dscl_output = execute(get_exec_preamble("-list"))
+ rescue Puppet::ExecutionFailure => detail
+ fail("Could not get #{@resource_type.name} list from DirectoryService")
end
-
-
- def self.list_all_present
- # JJM: List all objects of this Puppet::Type already present on the system.
- begin
- dscl_output = execute(get_exec_preamble("-list"))
- rescue Puppet::ExecutionFailure => detail
- fail("Could not get #{@resource_type.name} list from DirectoryService")
- end
- dscl_output.split("\n")
+ dscl_output.split("\n")
+ end
+
+ def self.parse_dscl_url_data(dscl_output)
+ # we need to construct a Hash from the dscl -url output to match
+ # that returned by the dscl -plist output for 10.5+ clients.
+ #
+ # Nasty assumptions:
+ # a) no values *end* in a colon ':', only keys
+ # b) if a line ends in a colon and the next line does start with
+ # a space, then the second line is a value of the first.
+ # c) (implied by (b)) keys don't start with spaces.
+
+ dscl_plist = {}
+ dscl_output.split("\n").inject([]) do |array, line|
+ if line =~ /^\s+/ # it's a value
+ array[-1] << line # add the value to the previous key
+ else
+ array << line
+ end
+ array
+ end.compact
+
+ dscl_output.each do |line|
+ # This should be a 'normal' entry. key and value on one line.
+ # We split on ': ' to deal with keys/values with a colon in them.
+ split_array = line.split(/:\s+/)
+ key = split_array.first
+ value = CGI::unescape(split_array.last.strip.chomp)
+ # We need to treat GroupMembership separately as it is currently
+ # the only attribute we care about multiple values for, and
+ # the values can never contain spaces (shortnames)
+ # We also make every value an array to be consistent with the
+ # output of dscl -plist under 10.5
+ if key == "GroupMembership"
+ dscl_plist[key] = value.split(/\s/)
+ else
+ dscl_plist[key] = [value]
+ end
end
-
- def self.parse_dscl_url_data(dscl_output)
- # we need to construct a Hash from the dscl -url output to match
- # that returned by the dscl -plist output for 10.5+ clients.
- #
- # Nasty assumptions:
- # a) no values *end* in a colon ':', only keys
- # b) if a line ends in a colon and the next line does start with
- # a space, then the second line is a value of the first.
- # c) (implied by (b)) keys don't start with spaces.
-
- dscl_plist = {}
- dscl_output.split("\n").inject([]) do |array, line|
- if line =~ /^\s+/ # it's a value
- array[-1] << line # add the value to the previous key
- else
- array << line
- end
- array
- end.compact
-
- dscl_output.each do |line|
- # This should be a 'normal' entry. key and value on one line.
- # We split on ': ' to deal with keys/values with a colon in them.
- split_array = line.split(/:\s+/)
- key = split_array.first
- value = CGI::unescape(split_array.last.strip.chomp)
- # We need to treat GroupMembership separately as it is currently
- # the only attribute we care about multiple values for, and
- # the values can never contain spaces (shortnames)
- # We also make every value an array to be consistent with the
- # output of dscl -plist under 10.5
- if key == "GroupMembership"
- dscl_plist[key] = value.split(/\s/)
- else
- dscl_plist[key] = [value]
- end
- end
- dscl_plist
+ dscl_plist
+ end
+
+ def self.parse_dscl_plist_data(dscl_output)
+ Plist.parse_xml(dscl_output)
+ end
+
+ def self.generate_attribute_hash(input_hash, *type_properties)
+ attribute_hash = {}
+ input_hash.keys.each do |key|
+ ds_attribute = key.sub("dsAttrTypeStandard:", "")
+ next unless (@@ds_to_ns_attribute_map.keys.include?(ds_attribute) and type_properties.include? @@ds_to_ns_attribute_map[ds_attribute])
+ ds_value = input_hash[key]
+ case @@ds_to_ns_attribute_map[ds_attribute]
+ when :members
+ ds_value = ds_value # only members uses arrays so far
+ when :gid, :uid
+ # OS X stores objects like uid/gid as strings.
+ # Try casting to an integer for these cases to be
+ # consistent with the other providers and the group type
+ # validation
+ begin
+ ds_value = Integer(ds_value[0])
+ rescue ArgumentError
+ ds_value = ds_value[0]
+ end
+ else ds_value = ds_value[0]
+ end
+ attribute_hash[@@ds_to_ns_attribute_map[ds_attribute]] = ds_value
end
- def self.parse_dscl_plist_data(dscl_output)
- Plist.parse_xml(dscl_output)
+ # NBK: need to read the existing password here as it's not actually
+ # stored in the user record. It is stored at a path that involves the
+ # UUID of the user record for non-Mobile local acccounts.
+ # Mobile Accounts are out of scope for this provider for now
+ attribute_hash[:password] = self.get_password(attribute_hash[:guid]) if @resource_type.validproperties.include?(:password) and Puppet.features.root?
+ attribute_hash
+ end
+
+ def self.single_report(resource_name, *type_properties)
+ # JJM 2007-07-24:
+ # Given a the name of an object and a list of properties of that
+ # object, return all property values in a hash.
+ #
+ # This class method returns nil if the object doesn't exist
+ # Otherwise, it returns a hash of the object properties.
+
+ all_present_str_array = list_all_present
+
+ # NBK: shortcut the process if the resource is missing
+ return nil unless all_present_str_array.include? resource_name
+
+ dscl_vector = get_exec_preamble("-read", resource_name)
+ begin
+ dscl_output = execute(dscl_vector)
+ rescue Puppet::ExecutionFailure => detail
+ fail("Could not get report. command execution failed.")
end
- def self.generate_attribute_hash(input_hash, *type_properties)
- attribute_hash = {}
- input_hash.keys.each do |key|
- ds_attribute = key.sub("dsAttrTypeStandard:", "")
- next unless (@@ds_to_ns_attribute_map.keys.include?(ds_attribute) and type_properties.include? @@ds_to_ns_attribute_map[ds_attribute])
- ds_value = input_hash[key]
- case @@ds_to_ns_attribute_map[ds_attribute]
- when :members
- ds_value = ds_value # only members uses arrays so far
- when :gid, :uid
- # OS X stores objects like uid/gid as strings.
- # Try casting to an integer for these cases to be
- # consistent with the other providers and the group type
- # validation
- begin
- ds_value = Integer(ds_value[0])
- rescue ArgumentError
- ds_value = ds_value[0]
- end
- else ds_value = ds_value[0]
- end
- attribute_hash[@@ds_to_ns_attribute_map[ds_attribute]] = ds_value
- end
-
- # NBK: need to read the existing password here as it's not actually
- # stored in the user record. It is stored at a path that involves the
- # UUID of the user record for non-Mobile local acccounts.
- # Mobile Accounts are out of scope for this provider for now
- attribute_hash[:password] = self.get_password(attribute_hash[:guid]) if @resource_type.validproperties.include?(:password) and Puppet.features.root?
- attribute_hash
+ # Two code paths is ugly, but until we can drop 10.4 support we don't
+ # have a lot of choice. Ultimately this should all be done using Ruby
+ # to access the DirectoryService APIs directly, but that's simply not
+ # feasible for a while yet.
+ case self.get_macosx_version_major
+ when "10.4"
+ dscl_plist = self.parse_dscl_url_data(dscl_output)
+ when "10.5", "10.6"
+ dscl_plist = self.parse_dscl_plist_data(dscl_output)
end
- def self.single_report(resource_name, *type_properties)
- # JJM 2007-07-24:
- # Given a the name of an object and a list of properties of that
- # object, return all property values in a hash.
- #
- # This class method returns nil if the object doesn't exist
- # Otherwise, it returns a hash of the object properties.
-
- all_present_str_array = list_all_present
-
- # NBK: shortcut the process if the resource is missing
- return nil unless all_present_str_array.include? resource_name
-
- dscl_vector = get_exec_preamble("-read", resource_name)
- begin
- dscl_output = execute(dscl_vector)
- rescue Puppet::ExecutionFailure => detail
- fail("Could not get report. command execution failed.")
- end
-
- # Two code paths is ugly, but until we can drop 10.4 support we don't
- # have a lot of choice. Ultimately this should all be done using Ruby
- # to access the DirectoryService APIs directly, but that's simply not
- # feasible for a while yet.
- case self.get_macosx_version_major
- when "10.4"
- dscl_plist = self.parse_dscl_url_data(dscl_output)
- when "10.5", "10.6"
- dscl_plist = self.parse_dscl_plist_data(dscl_output)
- end
-
- self.generate_attribute_hash(dscl_plist, *type_properties)
+ self.generate_attribute_hash(dscl_plist, *type_properties)
+ end
+
+ def self.get_exec_preamble(ds_action, resource_name = nil)
+ # JJM 2007-07-24
+ # DSCL commands are often repetitive and contain the same positional
+ # arguments over and over. See http://developer.apple.com/documentation/Porting/Conceptual/PortingUnix/additionalfeatures/chapter_10_section_9.html
+ # for an example of what I mean.
+ # This method spits out proper DSCL commands for us.
+ # We EXPECT name to be @resource[:name] when called from an instance object.
+
+ # 10.4 doesn't support the -plist option for dscl, and 10.5 has a
+ # different format for the -url output with objects with spaces in
+ # their values. *sigh*. Use -url for 10.4 in the hope this can be
+ # deprecated one day, and use -plist for 10.5 and higher.
+ case self.get_macosx_version_major
+ when "10.4"
+ command_vector = [ command(:dscl), "-url", "." ]
+ when "10.5", "10.6"
+ command_vector = [ command(:dscl), "-plist", "." ]
+ end
+ # JJM: The actual action to perform. See "man dscl"
+ # Common actiosn: -create, -delete, -merge, -append, -passwd
+ command_vector << ds_action
+ # JJM: get_ds_path will spit back "Users" or "Groups",
+ # etc... Depending on the Puppet::Type of our self.
+ if resource_name
+ command_vector << "/#{get_ds_path}/#{resource_name}"
+ else
+ command_vector << "/#{get_ds_path}"
+ end
+ # JJM: This returns most of the preamble of the command.
+ # e.g. 'dscl / -create /Users/mccune'
+ command_vector
+ end
+
+ def self.set_password(resource_name, guid, password_hash)
+ password_hash_file = "#{@@password_hash_dir}/#{guid}"
+ begin
+ File.open(password_hash_file, 'w') { |f| f.write(password_hash)}
+ rescue Errno::EACCES => detail
+ fail("Could not write to password hash file: #{detail}")
end
- def self.get_exec_preamble(ds_action, resource_name = nil)
- # JJM 2007-07-24
- # DSCL commands are often repetitive and contain the same positional
- # arguments over and over. See http://developer.apple.com/documentation/Porting/Conceptual/PortingUnix/additionalfeatures/chapter_10_section_9.html
- # for an example of what I mean.
- # This method spits out proper DSCL commands for us.
- # We EXPECT name to be @resource[:name] when called from an instance object.
-
- # 10.4 doesn't support the -plist option for dscl, and 10.5 has a
- # different format for the -url output with objects with spaces in
- # their values. *sigh*. Use -url for 10.4 in the hope this can be
- # deprecated one day, and use -plist for 10.5 and higher.
- case self.get_macosx_version_major
- when "10.4"
- command_vector = [ command(:dscl), "-url", "." ]
- when "10.5", "10.6"
- command_vector = [ command(:dscl), "-plist", "." ]
- end
- # JJM: The actual action to perform. See "man dscl"
- # Common actiosn: -create, -delete, -merge, -append, -passwd
- command_vector << ds_action
- # JJM: get_ds_path will spit back "Users" or "Groups",
- # etc... Depending on the Puppet::Type of our self.
- if resource_name
- command_vector << "/#{get_ds_path}/#{resource_name}"
+ # NBK: For shadow hashes, the user AuthenticationAuthority must contain a value of
+ # ";ShadowHash;". The LKDC in 10.5 makes this more interesting though as it
+ # will dynamically generate ;Kerberosv5;;username at LKDC:SHA1 attributes if
+ # missing. Thus we make sure we only set ;ShadowHash; if it is missing, and
+ # we can do this with the merge command. This allows people to continue to
+ # use other custom AuthenticationAuthority attributes without stomping on them.
+ #
+ # There is a potential problem here in that we're only doing this when setting
+ # the password, and the attribute could get modified at other times while the
+ # hash doesn't change and so this doesn't get called at all... but
+ # without switching all the other attributes to merge instead of create I can't
+ # see a simple enough solution for this that doesn't modify the user record
+ # every single time. This should be a rather rare edge case. (famous last words)
+
+ dscl_vector = self.get_exec_preamble("-merge", resource_name)
+ dscl_vector << "AuthenticationAuthority" << ";ShadowHash;"
+ begin
+ dscl_output = execute(dscl_vector)
+ rescue Puppet::ExecutionFailure => detail
+ fail("Could not set AuthenticationAuthority.")
+ end
+ end
+
+ def self.get_password(guid)
+ password_hash = nil
+ password_hash_file = "#{@@password_hash_dir}/#{guid}"
+ if File.exists?(password_hash_file) and File.file?(password_hash_file)
+ fail("Could not read password hash file at #{password_hash_file}") if not File.readable?(password_hash_file)
+ f = File.new(password_hash_file)
+ password_hash = f.read
+ f.close
+ end
+ password_hash
+ end
+
+ def ensure=(ensure_value)
+ super
+ # We need to loop over all valid properties for the type we're
+ # managing and call the method which sets that property value
+ # dscl can't create everything at once unfortunately.
+ if ensure_value == :present
+ @resource.class.validproperties.each do |name|
+ next if name == :ensure
+ # LAK: We use property.sync here rather than directly calling
+ # the settor method because the properties might do some kind
+ # of conversion. In particular, the user gid property might
+ # have a string and need to convert it to a number
+ if @resource.should(name)
+ @resource.property(name).sync
+ elsif value = autogen(name)
+ self.send(name.to_s + "=", value)
else
- command_vector << "/#{get_ds_path}"
+ next
end
- # JJM: This returns most of the preamble of the command.
- # e.g. 'dscl / -create /Users/mccune'
- command_vector
+ end
end
-
- def self.set_password(resource_name, guid, password_hash)
- password_hash_file = "#{@@password_hash_dir}/#{guid}"
- begin
- File.open(password_hash_file, 'w') { |f| f.write(password_hash)}
- rescue Errno::EACCES => detail
- fail("Could not write to password hash file: #{detail}")
- end
-
- # NBK: For shadow hashes, the user AuthenticationAuthority must contain a value of
- # ";ShadowHash;". The LKDC in 10.5 makes this more interesting though as it
- # will dynamically generate ;Kerberosv5;;username at LKDC:SHA1 attributes if
- # missing. Thus we make sure we only set ;ShadowHash; if it is missing, and
- # we can do this with the merge command. This allows people to continue to
- # use other custom AuthenticationAuthority attributes without stomping on them.
- #
- # There is a potential problem here in that we're only doing this when setting
- # the password, and the attribute could get modified at other times while the
- # hash doesn't change and so this doesn't get called at all... but
- # without switching all the other attributes to merge instead of create I can't
- # see a simple enough solution for this that doesn't modify the user record
- # every single time. This should be a rather rare edge case. (famous last words)
-
- dscl_vector = self.get_exec_preamble("-merge", resource_name)
- dscl_vector << "AuthenticationAuthority" << ";ShadowHash;"
- begin
- dscl_output = execute(dscl_vector)
- rescue Puppet::ExecutionFailure => detail
- fail("Could not set AuthenticationAuthority.")
- end
+ end
+
+ def password=(passphrase)
+ exec_arg_vector = self.class.get_exec_preamble("-read", @resource.name)
+ exec_arg_vector << @@ns_to_ds_attribute_map[:guid]
+ begin
+ guid_output = execute(exec_arg_vector)
+ guid_plist = Plist.parse_xml(guid_output)
+ # Although GeneratedUID like all DirectoryService values can be multi-valued
+ # according to the schema, in practice user accounts cannot have multiple UUIDs
+ # otherwise Bad Things Happen, so we just deal with the first value.
+ guid = guid_plist["dsAttrTypeStandard:#{@@ns_to_ds_attribute_map[:guid]}"][0]
+ self.class.set_password(@resource.name, guid, passphrase)
+ rescue Puppet::ExecutionFailure => detail
+ fail("Could not set #{param} on #{@resource.class.name}[#{@resource.name}]: #{detail}")
end
-
- def self.get_password(guid)
- password_hash = nil
- password_hash_file = "#{@@password_hash_dir}/#{guid}"
- if File.exists?(password_hash_file) and File.file?(password_hash_file)
- fail("Could not read password hash file at #{password_hash_file}") if not File.readable?(password_hash_file)
- f = File.new(password_hash_file)
- password_hash = f.read
- f.close
- end
- password_hash
+ end
+
+ # NBK: we override @parent.set as we need to execute a series of commands
+ # to deal with array values, rather than the single command nameservice.rb
+ # expects to be returned by modifycmd. Thus we don't bother defining modifycmd.
+
+ def set(param, value)
+ self.class.validate(param, value)
+ current_members = @property_value_cache_hash[:members]
+ if param == :members
+ # If we are meant to be authoritative for the group membership
+ # then remove all existing members who haven't been specified
+ # in the manifest.
+ remove_unwanted_members(current_members, value) if @resource[:auth_membership] and not current_members.nil?
+
+ # if they're not a member, make them one.
+ add_members(current_members, value)
+ else
+ exec_arg_vector = self.class.get_exec_preamble("-create", @resource[:name])
+ # JJM: The following line just maps the NS name to the DS name
+ # e.g. { :uid => 'UniqueID' }
+ exec_arg_vector << @@ns_to_ds_attribute_map[symbolize(param)]
+ # JJM: The following line sends the actual value to set the property to
+ exec_arg_vector << value.to_s
+ begin
+ execute(exec_arg_vector)
+ rescue Puppet::ExecutionFailure => detail
+ fail("Could not set #{param} on #{@resource.class.name}[#{@resource.name}]: #{detail}")
+ end
+ end
+ end
+
+ # NBK: we override @parent.create as we need to execute a series of commands
+ # to create objects with dscl, rather than the single command nameservice.rb
+ # expects to be returned by addcmd. Thus we don't bother defining addcmd.
+ def create
+ if exists?
+ info "already exists"
+ return nil
end
- def ensure=(ensure_value)
- super
- # We need to loop over all valid properties for the type we're
- # managing and call the method which sets that property value
- # dscl can't create everything at once unfortunately.
- if ensure_value == :present
- @resource.class.validproperties.each do |name|
- next if name == :ensure
- # LAK: We use property.sync here rather than directly calling
- # the settor method because the properties might do some kind
- # of conversion. In particular, the user gid property might
- # have a string and need to convert it to a number
- if @resource.should(name)
- @resource.property(name).sync
- elsif value = autogen(name)
- self.send(name.to_s + "=", value)
- else
- next
- end
- end
- end
+ # NBK: First we create the object with a known guid so we can set the contents
+ # of the password hash if required
+ # Shelling out sucks, but for a single use case it doesn't seem worth
+ # requiring people install a UUID library that doesn't come with the system.
+ # This should be revisited if Puppet starts managing UUIDs for other platform
+ # user records.
+ guid = %x{/usr/bin/uuidgen}.chomp
+
+ exec_arg_vector = self.class.get_exec_preamble("-create", @resource[:name])
+ exec_arg_vector << @@ns_to_ds_attribute_map[:guid] << guid
+ begin
+ execute(exec_arg_vector)
+ rescue Puppet::ExecutionFailure => detail
+ fail("Could not set GeneratedUID for #{@resource.class.name} #{@resource.name}: #{detail}")
end
- def password=(passphrase)
- exec_arg_vector = self.class.get_exec_preamble("-read", @resource.name)
- exec_arg_vector << @@ns_to_ds_attribute_map[:guid]
- begin
- guid_output = execute(exec_arg_vector)
- guid_plist = Plist.parse_xml(guid_output)
- # Although GeneratedUID like all DirectoryService values can be multi-valued
- # according to the schema, in practice user accounts cannot have multiple UUIDs
- # otherwise Bad Things Happen, so we just deal with the first value.
- guid = guid_plist["dsAttrTypeStandard:#{@@ns_to_ds_attribute_map[:guid]}"][0]
- self.class.set_password(@resource.name, guid, passphrase)
- rescue Puppet::ExecutionFailure => detail
- fail("Could not set #{param} on #{@resource.class.name}[#{@resource.name}]: #{detail}")
- end
+ if value = @resource.should(:password) and value != ""
+ self.class.set_password(@resource[:name], guid, value)
end
- # NBK: we override @parent.set as we need to execute a series of commands
- # to deal with array values, rather than the single command nameservice.rb
- # expects to be returned by modifycmd. Thus we don't bother defining modifycmd.
-
- def set(param, value)
- self.class.validate(param, value)
- current_members = @property_value_cache_hash[:members]
- if param == :members
- # If we are meant to be authoritative for the group membership
- # then remove all existing members who haven't been specified
- # in the manifest.
- remove_unwanted_members(current_members, value) if @resource[:auth_membership] and not current_members.nil?
-
- # if they're not a member, make them one.
- add_members(current_members, value)
+ # Now we create all the standard properties
+ Puppet::Type.type(@resource.class.name).validproperties.each do |property|
+ next if property == :ensure
+ if value = @resource.should(property) and value != ""
+ if property == :members
+ add_members(nil, value)
else
- exec_arg_vector = self.class.get_exec_preamble("-create", @resource[:name])
- # JJM: The following line just maps the NS name to the DS name
- # e.g. { :uid => 'UniqueID' }
- exec_arg_vector << @@ns_to_ds_attribute_map[symbolize(param)]
- # JJM: The following line sends the actual value to set the property to
- exec_arg_vector << value.to_s
- begin
- execute(exec_arg_vector)
- rescue Puppet::ExecutionFailure => detail
- fail("Could not set #{param} on #{@resource.class.name}[#{@resource.name}]: #{detail}")
- end
+ exec_arg_vector = self.class.get_exec_preamble("-create", @resource[:name])
+ exec_arg_vector << @@ns_to_ds_attribute_map[symbolize(property)]
+ next if property == :password # skip setting the password here
+ exec_arg_vector << value.to_s
+ begin
+ execute(exec_arg_vector)
+ rescue Puppet::ExecutionFailure => detail
+ fail("Could not create #{@resource.class.name} #{@resource.name}: #{detail}")
+ end
end
+ end
end
+ end
- # NBK: we override @parent.create as we need to execute a series of commands
- # to create objects with dscl, rather than the single command nameservice.rb
- # expects to be returned by addcmd. Thus we don't bother defining addcmd.
- def create
- if exists?
- info "already exists"
- return nil
- end
-
- # NBK: First we create the object with a known guid so we can set the contents
- # of the password hash if required
- # Shelling out sucks, but for a single use case it doesn't seem worth
- # requiring people install a UUID library that doesn't come with the system.
- # This should be revisited if Puppet starts managing UUIDs for other platform
- # user records.
- guid = %x{/usr/bin/uuidgen}.chomp
-
- exec_arg_vector = self.class.get_exec_preamble("-create", @resource[:name])
- exec_arg_vector << @@ns_to_ds_attribute_map[:guid] << guid
+ def remove_unwanted_members(current_members, new_members)
+ current_members.each do |member|
+ if not new_members.include?(member)
+ cmd = [:dseditgroup, "-o", "edit", "-n", ".", "-d", member, @resource[:name]]
begin
- execute(exec_arg_vector)
+ execute(cmd)
rescue Puppet::ExecutionFailure => detail
- fail("Could not set GeneratedUID for #{@resource.class.name} #{@resource.name}: #{detail}")
- end
-
- if value = @resource.should(:password) and value != ""
- self.class.set_password(@resource[:name], guid, value)
- end
-
- # Now we create all the standard properties
- Puppet::Type.type(@resource.class.name).validproperties.each do |property|
- next if property == :ensure
- if value = @resource.should(property) and value != ""
- if property == :members
- add_members(nil, value)
- else
- exec_arg_vector = self.class.get_exec_preamble("-create", @resource[:name])
- exec_arg_vector << @@ns_to_ds_attribute_map[symbolize(property)]
- next if property == :password # skip setting the password here
- exec_arg_vector << value.to_s
- begin
- execute(exec_arg_vector)
- rescue Puppet::ExecutionFailure => detail
- fail("Could not create #{@resource.class.name} #{@resource.name}: #{detail}")
- end
- end
- end
+ fail("Could not remove #{member} from group: #{@resource.name}, #{detail}")
end
+ end
end
+ end
- def remove_unwanted_members(current_members, new_members)
- current_members.each do |member|
- if not new_members.include?(member)
- cmd = [:dseditgroup, "-o", "edit", "-n", ".", "-d", member, @resource[:name]]
- begin
- execute(cmd)
- rescue Puppet::ExecutionFailure => detail
- fail("Could not remove #{member} from group: #{@resource.name}, #{detail}")
- end
- end
- end
- end
-
- def add_members(current_members, new_members)
- new_members.each do |new_member|
- if current_members.nil? or not current_members.include?(new_member)
- cmd = [:dseditgroup, "-o", "edit", "-n", ".", "-a", new_member, @resource[:name]]
- begin
- execute(cmd)
- rescue Puppet::ExecutionFailure => detail
- fail("Could not add #{new_member} to group: #{@resource.name}, #{detail}")
- end
- end
+ def add_members(current_members, new_members)
+ new_members.each do |new_member|
+ if current_members.nil? or not current_members.include?(new_member)
+ cmd = [:dseditgroup, "-o", "edit", "-n", ".", "-a", new_member, @resource[:name]]
+ begin
+ execute(cmd)
+ rescue Puppet::ExecutionFailure => detail
+ fail("Could not add #{new_member} to group: #{@resource.name}, #{detail}")
end
+ end
end
-
- def deletecmd
- # JJM: Like addcmd, only called when deleting the object itself
- # Note, this isn't used to delete properties of the object,
- # at least that's how I understand it...
- self.class.get_exec_preamble("-delete", @resource[:name])
- end
-
- def getinfo(refresh = false)
- # JJM 2007-07-24:
- # Override the getinfo method, which is also defined in nameservice.rb
- # This method returns and sets @infohash
- # I'm not re-factoring the name "getinfo" because this method will be
- # most likely called by nameservice.rb, which I didn't write.
- if refresh or (! defined?(@property_value_cache_hash) or ! @property_value_cache_hash)
- # JJM 2007-07-24: OK, there's a bit of magic that's about to
- # happen... Let's see how strong my grip has become... =)
- #
- # self is a provider instance of some Puppet::Type, like
- # Puppet::Type::User::ProviderDirectoryservice for the case of the
- # user type and this provider.
- #
- # self.class looks like "user provider directoryservice", if that
- # helps you ...
- #
- # self.class.resource_type is a reference to the Puppet::Type class,
- # probably Puppet::Type::User or Puppet::Type::Group, etc...
- #
- # self.class.resource_type.validproperties is a class method,
- # returning an Array of the valid properties of that specific
- # Puppet::Type.
- #
- # So... something like [:comment, :home, :password, :shell, :uid,
- # :groups, :ensure, :gid]
- #
- # Ultimately, we add :name to the list, delete :ensure from the
- # list, then report on the remaining list. Pretty whacky, ehh?
- type_properties = [:name] + self.class.resource_type.validproperties
- type_properties.delete(:ensure) if type_properties.include? :ensure
- type_properties << :guid # append GeneratedUID so we just get the report here
- @property_value_cache_hash = self.class.single_report(@resource[:name], *type_properties)
- [:uid, :gid].each do |param|
- @property_value_cache_hash[param] = @property_value_cache_hash[param].to_i if @property_value_cache_hash and @property_value_cache_hash.include?(param)
- end
- end
- @property_value_cache_hash
+ end
+
+ def deletecmd
+ # JJM: Like addcmd, only called when deleting the object itself
+ # Note, this isn't used to delete properties of the object,
+ # at least that's how I understand it...
+ self.class.get_exec_preamble("-delete", @resource[:name])
+ end
+
+ def getinfo(refresh = false)
+ # JJM 2007-07-24:
+ # Override the getinfo method, which is also defined in nameservice.rb
+ # This method returns and sets @infohash
+ # I'm not re-factoring the name "getinfo" because this method will be
+ # most likely called by nameservice.rb, which I didn't write.
+ if refresh or (! defined?(@property_value_cache_hash) or ! @property_value_cache_hash)
+ # JJM 2007-07-24: OK, there's a bit of magic that's about to
+ # happen... Let's see how strong my grip has become... =)
+ #
+ # self is a provider instance of some Puppet::Type, like
+ # Puppet::Type::User::ProviderDirectoryservice for the case of the
+ # user type and this provider.
+ #
+ # self.class looks like "user provider directoryservice", if that
+ # helps you ...
+ #
+ # self.class.resource_type is a reference to the Puppet::Type class,
+ # probably Puppet::Type::User or Puppet::Type::Group, etc...
+ #
+ # self.class.resource_type.validproperties is a class method,
+ # returning an Array of the valid properties of that specific
+ # Puppet::Type.
+ #
+ # So... something like [:comment, :home, :password, :shell, :uid,
+ # :groups, :ensure, :gid]
+ #
+ # Ultimately, we add :name to the list, delete :ensure from the
+ # list, then report on the remaining list. Pretty whacky, ehh?
+ type_properties = [:name] + self.class.resource_type.validproperties
+ type_properties.delete(:ensure) if type_properties.include? :ensure
+ type_properties << :guid # append GeneratedUID so we just get the report here
+ @property_value_cache_hash = self.class.single_report(@resource[:name], *type_properties)
+ [:uid, :gid].each do |param|
+ @property_value_cache_hash[param] = @property_value_cache_hash[param].to_i if @property_value_cache_hash and @property_value_cache_hash.include?(param)
+ end
end
+ @property_value_cache_hash
+ end
end
end
diff --git a/lib/puppet/provider/nameservice/objectadd.rb b/lib/puppet/provider/nameservice/objectadd.rb
index 25528be..80c1429 100644
--- a/lib/puppet/provider/nameservice/objectadd.rb
+++ b/lib/puppet/provider/nameservice/objectadd.rb
@@ -2,31 +2,31 @@ require 'puppet/provider/nameservice'
class Puppet::Provider::NameService
class ObjectAdd < Puppet::Provider::NameService
- def deletecmd
- [command(:delete), @resource[:name]]
- end
-
- # Determine the flag to pass to our command.
- def flag(name)
- name = name.intern if name.is_a? String
- self.class.option(name, :flag) || "-" + name.to_s[0,1]
- end
+ def deletecmd
+ [command(:delete), @resource[:name]]
+ end
- def modifycmd(param, value)
- cmd = [command(:modify), flag(param), value]
- if @resource.allowdupe? && ((param == :uid) || (param == :gid and self.class.name == :groupadd))
- cmd << "-o"
- end
- cmd << @resource[:name]
+ # Determine the flag to pass to our command.
+ def flag(name)
+ name = name.intern if name.is_a? String
+ self.class.option(name, :flag) || "-" + name.to_s[0,1]
+ end
- cmd
+ def modifycmd(param, value)
+ cmd = [command(:modify), flag(param), value]
+ if @resource.allowdupe? && ((param == :uid) || (param == :gid and self.class.name == :groupadd))
+ cmd << "-o"
end
+ cmd << @resource[:name]
- def posixmethod(name)
- name = name.intern if name.is_a? String
- method = self.class.option(name, :method) || name
+ cmd
+ end
- method
- end
+ def posixmethod(name)
+ name = name.intern if name.is_a? String
+ method = self.class.option(name, :method) || name
+
+ method
+ end
end
end
diff --git a/lib/puppet/provider/nameservice/pw.rb b/lib/puppet/provider/nameservice/pw.rb
index 702d705..74f1a9f 100644
--- a/lib/puppet/provider/nameservice/pw.rb
+++ b/lib/puppet/provider/nameservice/pw.rb
@@ -2,20 +2,20 @@ require 'puppet/provider/nameservice/objectadd'
class Puppet::Provider::NameService
class PW < ObjectAdd
- def deletecmd
- [command(:pw), "#{@resource.class.name.to_s}del", @resource[:name]]
- end
+ def deletecmd
+ [command(:pw), "#{@resource.class.name.to_s}del", @resource[:name]]
+ end
- def modifycmd(param, value)
- cmd = [
- command(:pw),
- "#{@resource.class.name.to_s}mod",
- @resource[:name],
- flag(param),
- value
- ]
- cmd
- end
+ def modifycmd(param, value)
+ cmd = [
+ command(:pw),
+ "#{@resource.class.name.to_s}mod",
+ @resource[:name],
+ flag(param),
+ value
+ ]
+ cmd
+ end
end
end
diff --git a/lib/puppet/provider/package.rb b/lib/puppet/provider/package.rb
index 0ce6cca..2f5f675 100644
--- a/lib/puppet/provider/package.rb
+++ b/lib/puppet/provider/package.rb
@@ -2,26 +2,26 @@
# Copyright (c) 2007. All rights reserved.
class Puppet::Provider::Package < Puppet::Provider
- # Prefetch our package list, yo.
- def self.prefetch(packages)
- instances.each do |prov|
- if pkg = packages[prov.name]
- pkg.provider = prov
- end
- end
+ # Prefetch our package list, yo.
+ def self.prefetch(packages)
+ instances.each do |prov|
+ if pkg = packages[prov.name]
+ pkg.provider = prov
+ end
end
+ end
- # Clear out the cached values.
- def flush
- @property_hash.clear
- end
+ # Clear out the cached values.
+ def flush
+ @property_hash.clear
+ end
- # Look up the current status.
- def properties
- if @property_hash.empty?
- @property_hash = query || {:ensure => :absent}
- @property_hash[:ensure] = :absent if @property_hash.empty?
- end
- @property_hash.dup
+ # Look up the current status.
+ def properties
+ if @property_hash.empty?
+ @property_hash = query || {:ensure => :absent}
+ @property_hash[:ensure] = :absent if @property_hash.empty?
end
+ @property_hash.dup
+ end
end
diff --git a/lib/puppet/provider/package/aix.rb b/lib/puppet/provider/package/aix.rb
index dce4ccb..134a845 100644
--- a/lib/puppet/provider/package/aix.rb
+++ b/lib/puppet/provider/package/aix.rb
@@ -2,127 +2,127 @@ require 'puppet/provider/package'
require 'puppet/util/package'
Puppet::Type.type(:package).provide :aix, :parent => Puppet::Provider::Package do
- desc "Installation from AIX Software directory"
+ desc "Installation from AIX Software directory"
- # The commands we are using on an AIX box are installed standard
- # (except nimclient) nimclient needs the bos.sysmgt.nim.client fileset.
- commands :lslpp => "/usr/bin/lslpp",
- :installp => "/usr/sbin/installp"
+ # The commands we are using on an AIX box are installed standard
+ # (except nimclient) nimclient needs the bos.sysmgt.nim.client fileset.
+ commands :lslpp => "/usr/bin/lslpp",
+ :installp => "/usr/sbin/installp"
- # AIX supports versionable packages with and without a NIM server
- has_feature :versionable
+ # AIX supports versionable packages with and without a NIM server
+ has_feature :versionable
- confine :operatingsystem => [ :aix ]
- defaultfor :operatingsystem => :aix
+ confine :operatingsystem => [ :aix ]
+ defaultfor :operatingsystem => :aix
- attr_accessor :latest_info
+ attr_accessor :latest_info
- def self.srclistcmd(source)
- [ command(:installp), "-L", "-d", source ]
- end
-
- def self.prefetch(packages)
- raise Puppet::Error, "The aix provider can only be used by root" if Process.euid != 0
+ def self.srclistcmd(source)
+ [ command(:installp), "-L", "-d", source ]
+ end
- return unless packages.detect { |name, package| package.should(:ensure) == :latest }
+ def self.prefetch(packages)
+ raise Puppet::Error, "The aix provider can only be used by root" if Process.euid != 0
- sources = packages.collect { |name, package| package[:source] }.uniq
+ return unless packages.detect { |name, package| package.should(:ensure) == :latest }
- updates = {}
- sources.each do |source|
- execute(self.srclistcmd(source)).each do |line|
- if line =~ /^[^#][^:]*:([^:]*):([^:]*)/
- current = {}
- current[:name] = $1
- current[:version] = $2
- current[:source] = source
+ sources = packages.collect { |name, package| package[:source] }.uniq
- if updates.key?(current[:name])
- previous = updates[current[:name]]
+ updates = {}
+ sources.each do |source|
+ execute(self.srclistcmd(source)).each do |line|
+ if line =~ /^[^#][^:]*:([^:]*):([^:]*)/
+ current = {}
+ current[:name] = $1
+ current[:version] = $2
+ current[:source] = source
- updates[ current[:name] ] = current unless Puppet::Util::Package.versioncmp(previous[:version], current[:version]) == 1
+ if updates.key?(current[:name])
+ previous = updates[current[:name]]
- else
- updates[current[:name]] = current
- end
- end
- end
- end
+ updates[ current[:name] ] = current unless Puppet::Util::Package.versioncmp(previous[:version], current[:version]) == 1
- packages.each do |name, package|
- if info = updates[package[:name]]
- package.provider.latest_info = info[0]
- end
+ else
+ updates[current[:name]] = current
+ end
end
+ end
end
- def uninstall
- # Automatically process dependencies when installing/uninstalling
- # with the -g option to installp.
- installp "-gu", @resource[:name]
+ packages.each do |name, package|
+ if info = updates[package[:name]]
+ package.provider.latest_info = info[0]
+ end
end
+ end
- def install(useversion = true)
- unless source = @resource[:source]
- self.fail "A directory is required which will be used to find packages"
- end
+ def uninstall
+ # Automatically process dependencies when installing/uninstalling
+ # with the -g option to installp.
+ installp "-gu", @resource[:name]
+ end
- pkg = @resource[:name]
+ def install(useversion = true)
+ unless source = @resource[:source]
+ self.fail "A directory is required which will be used to find packages"
+ end
- pkg << " #{@resource.should(:ensure)}" if (! @resource.should(:ensure).is_a? Symbol) and useversion
+ pkg = @resource[:name]
- installp "-acgwXY", "-d", source, pkg
- end
+ pkg << " #{@resource.should(:ensure)}" if (! @resource.should(:ensure).is_a? Symbol) and useversion
- def self.pkglist(hash = {})
- cmd = [command(:lslpp), "-qLc"]
+ installp "-acgwXY", "-d", source, pkg
+ end
- if name = hash[:pkgname]
- cmd << name
- end
+ def self.pkglist(hash = {})
+ cmd = [command(:lslpp), "-qLc"]
- begin
- list = execute(cmd).scan(/^[^#][^:]*:([^:]*):([^:]*)/).collect { |n,e|
- { :name => n, :ensure => e, :provider => self.name }
- }
- rescue Puppet::ExecutionFailure => detail
- if hash[:pkgname]
- return nil
- else
- raise Puppet::Error, "Could not list installed Packages: #{detail}"
- end
- end
+ if name = hash[:pkgname]
+ cmd << name
+ end
- if hash[:pkgname]
- return list.shift
- else
- return list
- end
+ begin
+ list = execute(cmd).scan(/^[^#][^:]*:([^:]*):([^:]*)/).collect { |n,e|
+ { :name => n, :ensure => e, :provider => self.name }
+ }
+ rescue Puppet::ExecutionFailure => detail
+ if hash[:pkgname]
+ return nil
+ else
+ raise Puppet::Error, "Could not list installed Packages: #{detail}"
+ end
end
- def self.instances
- pkglist.collect do |hash|
- new(hash)
- end
+ if hash[:pkgname]
+ return list.shift
+ else
+ return list
+ end
+ end
+
+ def self.instances
+ pkglist.collect do |hash|
+ new(hash)
end
+ end
- def latest
- upd = latest_info
+ def latest
+ upd = latest_info
- unless upd.nil?
- return "#{upd[:version]}"
- else
- raise Puppet::DevError, "Tried to get latest on a missing package" if properties[:ensure] == :absent
+ unless upd.nil?
+ return "#{upd[:version]}"
+ else
+ raise Puppet::DevError, "Tried to get latest on a missing package" if properties[:ensure] == :absent
- return properties[:ensure]
- end
+ return properties[:ensure]
end
+ end
- def query
- self.class.pkglist(:pkgname => @resource[:name])
- end
+ def query
+ self.class.pkglist(:pkgname => @resource[:name])
+ end
- def update
- self.install(false)
- end
+ def update
+ self.install(false)
+ end
end
diff --git a/lib/puppet/provider/package/appdmg.rb b/lib/puppet/provider/package/appdmg.rb
index 1185811..a49700e 100644
--- a/lib/puppet/provider/package/appdmg.rb
+++ b/lib/puppet/provider/package/appdmg.rb
@@ -14,97 +14,97 @@
require 'puppet/provider/package'
Puppet::Type.type(:package).provide(:appdmg, :parent => Puppet::Provider::Package) do
- desc "Package management which copies application bundles to a target."
+ desc "Package management which copies application bundles to a target."
- confine :operatingsystem => :darwin
+ confine :operatingsystem => :darwin
- commands :hdiutil => "/usr/bin/hdiutil"
- commands :curl => "/usr/bin/curl"
- commands :ditto => "/usr/bin/ditto"
+ commands :hdiutil => "/usr/bin/hdiutil"
+ commands :curl => "/usr/bin/curl"
+ commands :ditto => "/usr/bin/ditto"
- # JJM We store a cookie for each installed .app.dmg in /var/db
- def self.instances_by_name
- Dir.entries("/var/db").find_all { |f|
- f =~ /^\.puppet_appdmg_installed_/
- }.collect do |f|
- name = f.sub(/^\.puppet_appdmg_installed_/, '')
- yield name if block_given?
- name
- end
+ # JJM We store a cookie for each installed .app.dmg in /var/db
+ def self.instances_by_name
+ Dir.entries("/var/db").find_all { |f|
+ f =~ /^\.puppet_appdmg_installed_/
+ }.collect do |f|
+ name = f.sub(/^\.puppet_appdmg_installed_/, '')
+ yield name if block_given?
+ name
end
+ end
- def self.instances
- instances_by_name.collect do |name|
- new(:name => name, :provider => :appdmg, :ensure => :installed)
- end
+ def self.instances
+ instances_by_name.collect do |name|
+ new(:name => name, :provider => :appdmg, :ensure => :installed)
end
+ end
- def self.installapp(source, name, orig_source)
- appname = File.basename(source);
- ditto "--rsrc", source, "/Applications/#{appname}"
- File.open("/var/db/.puppet_appdmg_installed_#{name}", "w") do |t|
- t.print "name: '#{name}'\n"
- t.print "source: '#{orig_source}'\n"
- end
+ def self.installapp(source, name, orig_source)
+ appname = File.basename(source);
+ ditto "--rsrc", source, "/Applications/#{appname}"
+ File.open("/var/db/.puppet_appdmg_installed_#{name}", "w") do |t|
+ t.print "name: '#{name}'\n"
+ t.print "source: '#{orig_source}'\n"
end
+ end
- def self.installpkgdmg(source, name)
- unless source =~ /\.dmg$/i
- self.fail "Mac OS X PKG DMG's must specificy a source string ending in .dmg"
- end
- require 'open-uri'
- require 'facter/util/plist'
+ def self.installpkgdmg(source, name)
+ unless source =~ /\.dmg$/i
+ self.fail "Mac OS X PKG DMG's must specificy a source string ending in .dmg"
+ end
+ require 'open-uri'
+ require 'facter/util/plist'
+ cached_source = source
+ if %r{\A[A-Za-z][A-Za-z0-9+\-\.]*://} =~ cached_source
+ cached_source = "/tmp/#{name}"
+ begin
+ curl "-o", cached_source, "-C", "-", "-k", "-s", "--url", source
+ Puppet.debug "Success: curl transfered [#{name}]"
+ rescue Puppet::ExecutionFailure
+ Puppet.debug "curl did not transfer [#{name}]. Falling back to slower open-uri transfer methods."
cached_source = source
- if %r{\A[A-Za-z][A-Za-z0-9+\-\.]*://} =~ cached_source
- cached_source = "/tmp/#{name}"
- begin
- curl "-o", cached_source, "-C", "-", "-k", "-s", "--url", source
- Puppet.debug "Success: curl transfered [#{name}]"
- rescue Puppet::ExecutionFailure
- Puppet.debug "curl did not transfer [#{name}]. Falling back to slower open-uri transfer methods."
- cached_source = source
- end
- end
+ end
+ end
- begin
- open(cached_source) do |dmg|
- xml_str = hdiutil "mount", "-plist", "-nobrowse", "-readonly", "-mountrandom", "/tmp", dmg.path
- ptable = Plist::parse_xml xml_str
- # JJM Filter out all mount-paths into a single array, discard the rest.
- mounts = ptable['system-entities'].collect { |entity|
- entity['mount-point']
- }.select { |mountloc|; mountloc }
- begin
- mounts.each do |fspath|
- Dir.entries(fspath).select { |f|
- f =~ /\.app$/i
- }.each do |pkg|
- installapp("#{fspath}/#{pkg}", name, source)
- end
- end
- ensure
- hdiutil "eject", mounts[0]
- end
+ begin
+ open(cached_source) do |dmg|
+ xml_str = hdiutil "mount", "-plist", "-nobrowse", "-readonly", "-mountrandom", "/tmp", dmg.path
+ ptable = Plist::parse_xml xml_str
+ # JJM Filter out all mount-paths into a single array, discard the rest.
+ mounts = ptable['system-entities'].collect { |entity|
+ entity['mount-point']
+ }.select { |mountloc|; mountloc }
+ begin
+ mounts.each do |fspath|
+ Dir.entries(fspath).select { |f|
+ f =~ /\.app$/i
+ }.each do |pkg|
+ installapp("#{fspath}/#{pkg}", name, source)
+ end
end
- ensure
- # JJM Remove the file if open-uri didn't already do so.
- File.unlink(cached_source) if File.exist?(cached_source)
- end
+ ensure
+ hdiutil "eject", mounts[0]
+ end
+ end
+ ensure
+ # JJM Remove the file if open-uri didn't already do so.
+ File.unlink(cached_source) if File.exist?(cached_source)
end
+ end
- def query
- FileTest.exists?("/var/db/.puppet_appdmg_installed_#{@resource[:name]}") ? {:name => @resource[:name], :ensure => :present} : nil
- end
+ def query
+ FileTest.exists?("/var/db/.puppet_appdmg_installed_#{@resource[:name]}") ? {:name => @resource[:name], :ensure => :present} : nil
+ end
- def install
- source = nil
- unless source = @resource[:source]
- self.fail "Mac OS X PKG DMG's must specify a package source."
- end
- unless name = @resource[:name]
- self.fail "Mac OS X PKG DMG's must specify a package name."
- end
- self.class.installpkgdmg(source,name)
+ def install
+ source = nil
+ unless source = @resource[:source]
+ self.fail "Mac OS X PKG DMG's must specify a package source."
+ end
+ unless name = @resource[:name]
+ self.fail "Mac OS X PKG DMG's must specify a package name."
end
+ self.class.installpkgdmg(source,name)
+ end
end
diff --git a/lib/puppet/provider/package/apple.rb b/lib/puppet/provider/package/apple.rb
index 613e14e..0946de4 100755
--- a/lib/puppet/provider/package/apple.rb
+++ b/lib/puppet/provider/package/apple.rb
@@ -2,50 +2,50 @@ require 'puppet/provider/package'
# OS X Packaging sucks. We can install packages, but that's about it.
Puppet::Type.type(:package).provide :apple, :parent => Puppet::Provider::Package do
- desc "Package management based on OS X's builtin packaging system. This is
- essentially the simplest and least functional package system in existence --
- it only supports installation; no deletion or upgrades. The provider will
- automatically add the ``.pkg`` extension, so leave that off when specifying
- the package name."
+ desc "Package management based on OS X's builtin packaging system. This is
+ essentially the simplest and least functional package system in existence --
+ it only supports installation; no deletion or upgrades. The provider will
+ automatically add the ``.pkg`` extension, so leave that off when specifying
+ the package name."
- confine :operatingsystem => :darwin
- commands :installer => "/usr/sbin/installer"
+ confine :operatingsystem => :darwin
+ commands :installer => "/usr/sbin/installer"
- def self.instances
- instance_by_name.collect do |name|
+ def self.instances
+ instance_by_name.collect do |name|
- self.new(
+ self.new(
- :name => name,
- :provider => :apple,
+ :name => name,
+ :provider => :apple,
- :ensure => :installed
- )
- end
+ :ensure => :installed
+ )
end
-
- def self.instance_by_name
- Dir.entries("/Library/Receipts").find_all { |f|
- f =~ /\.pkg$/
- }.collect { |f|
- name = f.sub(/\.pkg/, '')
- yield name if block_given?
-
- name
- }
- end
-
- def query
- FileTest.exists?("/Library/Receipts/#{@resource[:name]}.pkg") ? {:name => @resource[:name], :ensure => :present} : nil
+ end
+
+ def self.instance_by_name
+ Dir.entries("/Library/Receipts").find_all { |f|
+ f =~ /\.pkg$/
+ }.collect { |f|
+ name = f.sub(/\.pkg/, '')
+ yield name if block_given?
+
+ name
+ }
+ end
+
+ def query
+ FileTest.exists?("/Library/Receipts/#{@resource[:name]}.pkg") ? {:name => @resource[:name], :ensure => :present} : nil
+ end
+
+ def install
+ source = nil
+ unless source = @resource[:source]
+ self.fail "Mac OS X packages must specify a package source"
end
- def install
- source = nil
- unless source = @resource[:source]
- self.fail "Mac OS X packages must specify a package source"
- end
-
- installer "-pkg", source, "-target", "/"
- end
+ installer "-pkg", source, "-target", "/"
+ end
end
diff --git a/lib/puppet/provider/package/apt.rb b/lib/puppet/provider/package/apt.rb
index deab234..d055e75 100755
--- a/lib/puppet/provider/package/apt.rb
+++ b/lib/puppet/provider/package/apt.rb
@@ -1,108 +1,108 @@
Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
- # Provide sorting functionality
- include Puppet::Util::Package
+ # Provide sorting functionality
+ include Puppet::Util::Package
- desc "Package management via ``apt-get``."
+ desc "Package management via ``apt-get``."
- has_feature :versionable
+ has_feature :versionable
- commands :aptget => "/usr/bin/apt-get"
- commands :aptcache => "/usr/bin/apt-cache"
- commands :preseed => "/usr/bin/debconf-set-selections"
+ commands :aptget => "/usr/bin/apt-get"
+ commands :aptcache => "/usr/bin/apt-cache"
+ commands :preseed => "/usr/bin/debconf-set-selections"
- defaultfor :operatingsystem => [:debian, :ubuntu]
+ defaultfor :operatingsystem => [:debian, :ubuntu]
- ENV['DEBIAN_FRONTEND'] = "noninteractive"
+ ENV['DEBIAN_FRONTEND'] = "noninteractive"
- # A derivative of DPKG; this is how most people actually manage
- # Debian boxes, and the only thing that differs is that it can
- # install packages from remote sites.
+ # A derivative of DPKG; this is how most people actually manage
+ # Debian boxes, and the only thing that differs is that it can
+ # install packages from remote sites.
- def checkforcdrom
- unless defined?(@@checkedforcdrom)
- if FileTest.exists? "/etc/apt/sources.list"
- @@checkedforcdrom = !!(File.read("/etc/apt/sources.list") =~ /^[^#]*cdrom:/)
- else
- # This is basically a pathalogical case, but we'll just
- # ignore it
- @@checkedforcdrom = false
- end
- end
+ def checkforcdrom
+ unless defined?(@@checkedforcdrom)
+ if FileTest.exists? "/etc/apt/sources.list"
+ @@checkedforcdrom = !!(File.read("/etc/apt/sources.list") =~ /^[^#]*cdrom:/)
+ else
+ # This is basically a pathalogical case, but we'll just
+ # ignore it
+ @@checkedforcdrom = false
+ end
+ end
- if @@checkedforcdrom and @resource[:allowcdrom] != :true
- raise Puppet::Error,
- "/etc/apt/sources.list contains a cdrom source; not installing. Use 'allowcdrom' to override this failure."
- end
+ if @@checkedforcdrom and @resource[:allowcdrom] != :true
+ raise Puppet::Error,
+ "/etc/apt/sources.list contains a cdrom source; not installing. Use 'allowcdrom' to override this failure."
+ end
+ end
+
+ # Install a package using 'apt-get'. This function needs to support
+ # installing a specific version.
+ def install
+ self.run_preseed if @resource[:responsefile]
+ should = @resource[:ensure]
+
+ checkforcdrom
+ cmd = %w{-q -y}
+
+ keep = ""
+ if config = @resource[:configfiles]
+ if config == :keep
+ cmd << "-o" << 'DPkg::Options::=--force-confold'
+ else
+ cmd << "-o" << 'DPkg::Options::=--force-confnew'
+ end
end
- # Install a package using 'apt-get'. This function needs to support
- # installing a specific version.
- def install
- self.run_preseed if @resource[:responsefile]
- should = @resource[:ensure]
-
- checkforcdrom
- cmd = %w{-q -y}
-
- keep = ""
- if config = @resource[:configfiles]
- if config == :keep
- cmd << "-o" << 'DPkg::Options::=--force-confold'
- else
- cmd << "-o" << 'DPkg::Options::=--force-confnew'
- end
- end
-
- str = @resource[:name]
- case should
- when true, false, Symbol
- # pass
- else
- # Add the package version and --force-yes option
- str += "=#{should}"
- cmd << "--force-yes"
- end
-
- cmd << :install << str
-
- aptget(*cmd)
+ str = @resource[:name]
+ case should
+ when true, false, Symbol
+ # pass
+ else
+ # Add the package version and --force-yes option
+ str += "=#{should}"
+ cmd << "--force-yes"
end
- # What's the latest package version available?
- def latest
- output = aptcache :policy, @resource[:name]
+ cmd << :install << str
- if output =~ /Candidate:\s+(\S+)\s/
- return $1
- else
- self.err "Could not find latest version"
- return nil
- end
- end
+ aptget(*cmd)
+ end
- #
- # preseeds answers to dpkg-set-selection from the "responsefile"
- #
- def run_preseed
- if response = @resource[:responsefile] and FileTest.exist?(response)
- self.info("Preseeding #{response} to debconf-set-selections")
-
- preseed response
- else
- self.info "No responsefile specified or non existant, not preseeding anything"
- end
- end
+ # What's the latest package version available?
+ def latest
+ output = aptcache :policy, @resource[:name]
- def uninstall
- self.run_preseed if @resource[:responsefile]
- aptget "-y", "-q", :remove, @resource[:name]
+ if output =~ /Candidate:\s+(\S+)\s/
+ return $1
+ else
+ self.err "Could not find latest version"
+ return nil
end
-
- def purge
- self.run_preseed if @resource[:responsefile]
- aptget '-y', '-q', :remove, '--purge', @resource[:name]
- # workaround a "bug" in apt, that already removed packages are not purged
- super
+ end
+
+ #
+ # preseeds answers to dpkg-set-selection from the "responsefile"
+ #
+ def run_preseed
+ if response = @resource[:responsefile] and FileTest.exist?(response)
+ self.info("Preseeding #{response} to debconf-set-selections")
+
+ preseed response
+ else
+ self.info "No responsefile specified or non existant, not preseeding anything"
end
+ end
+
+ def uninstall
+ self.run_preseed if @resource[:responsefile]
+ aptget "-y", "-q", :remove, @resource[:name]
+ end
+
+ def purge
+ self.run_preseed if @resource[:responsefile]
+ aptget '-y', '-q', :remove, '--purge', @resource[:name]
+ # workaround a "bug" in apt, that already removed packages are not purged
+ super
+ end
end
diff --git a/lib/puppet/provider/package/aptitude.rb b/lib/puppet/provider/package/aptitude.rb
index 5529535..557e657 100755
--- a/lib/puppet/provider/package/aptitude.rb
+++ b/lib/puppet/provider/package/aptitude.rb
@@ -1,29 +1,29 @@
Puppet::Type.type(:package).provide :aptitude, :parent => :apt, :source => :dpkg do
- desc "Package management via ``aptitude``."
+ desc "Package management via ``aptitude``."
- has_feature :versionable
+ has_feature :versionable
- commands :aptitude => "/usr/bin/aptitude"
- commands :aptcache => "/usr/bin/apt-cache"
+ commands :aptitude => "/usr/bin/aptitude"
+ commands :aptcache => "/usr/bin/apt-cache"
- ENV['DEBIAN_FRONTEND'] = "noninteractive"
+ ENV['DEBIAN_FRONTEND'] = "noninteractive"
- def aptget(*args)
- args.flatten!
- # Apparently aptitude hasn't always supported a -q flag.
- args.delete("-q") if args.include?("-q")
- output = aptitude(*args)
+ def aptget(*args)
+ args.flatten!
+ # Apparently aptitude hasn't always supported a -q flag.
+ args.delete("-q") if args.include?("-q")
+ output = aptitude(*args)
- # Yay, stupid aptitude doesn't throw an error when the package is missing.
- if args.include?(:install) and output =~ /Couldn't find any package/
- raise Puppet::Error.new(
- "Could not find package #{self.name}"
- )
- end
+ # Yay, stupid aptitude doesn't throw an error when the package is missing.
+ if args.include?(:install) and output =~ /Couldn't find any package/
+ raise Puppet::Error.new(
+ "Could not find package #{self.name}"
+ )
end
+ end
- def purge
- aptitude '-y', 'purge', @resource[:name]
- end
+ def purge
+ aptitude '-y', 'purge', @resource[:name]
+ end
end
diff --git a/lib/puppet/provider/package/aptrpm.rb b/lib/puppet/provider/package/aptrpm.rb
index 42f7e70..d784208 100644
--- a/lib/puppet/provider/package/aptrpm.rb
+++ b/lib/puppet/provider/package/aptrpm.rb
@@ -1,84 +1,84 @@
Puppet::Type.type(:package).provide :aptrpm, :parent => :rpm, :source => :rpm do
- # Provide sorting functionality
- include Puppet::Util::Package
-
- desc "Package management via ``apt-get`` ported to ``rpm``."
-
- has_feature :versionable
-
- commands :aptget => "apt-get"
- commands :aptcache => "apt-cache"
- commands :rpm => "rpm"
-
- if command('rpm')
- confine :true => begin
- rpm('-ql', 'rpm')
- rescue Puppet::ExecutionFailure
- false
- else
- true
- end
+ # Provide sorting functionality
+ include Puppet::Util::Package
+
+ desc "Package management via ``apt-get`` ported to ``rpm``."
+
+ has_feature :versionable
+
+ commands :aptget => "apt-get"
+ commands :aptcache => "apt-cache"
+ commands :rpm => "rpm"
+
+ if command('rpm')
+ confine :true => begin
+ rpm('-ql', 'rpm')
+ rescue Puppet::ExecutionFailure
+ false
+ else
+ true
+ end
+ end
+
+ # Install a package using 'apt-get'. This function needs to support
+ # installing a specific version.
+ def install
+ should = @resource.should(:ensure)
+
+ str = @resource[:name]
+ case should
+ when true, false, Symbol
+ # pass
+ else
+ # Add the package version
+ str += "=#{should}"
end
+ cmd = %w{-q -y}
- # Install a package using 'apt-get'. This function needs to support
- # installing a specific version.
- def install
- should = @resource.should(:ensure)
+ cmd << 'install' << str
- str = @resource[:name]
- case should
- when true, false, Symbol
- # pass
- else
- # Add the package version
- str += "=#{should}"
- end
- cmd = %w{-q -y}
+ aptget(*cmd)
+ end
- cmd << 'install' << str
+ # What's the latest package version available?
+ def latest
+ output = aptcache :showpkg, @resource[:name]
- aptget(*cmd)
- end
-
- # What's the latest package version available?
- def latest
- output = aptcache :showpkg, @resource[:name]
-
- if output =~ /Versions:\s*\n((\n|.)+)^$/
- versions = $1
- available_versions = versions.split(/\n/).collect { |version|
- if version =~ /^([^\(]+)\(/
- $1
- else
- self.warning "Could not match version '#{version}'"
- nil
- end
- }.reject { |vers| vers.nil? }.sort { |a,b|
- versioncmp(a,b)
- }
-
- if available_versions.length == 0
- self.debug "No latest version"
- print output if Puppet[:debug]
- end
-
- # Get the latest and greatest version number
- return available_versions.pop
+ if output =~ /Versions:\s*\n((\n|.)+)^$/
+ versions = $1
+ available_versions = versions.split(/\n/).collect { |version|
+ if version =~ /^([^\(]+)\(/
+ $1
else
- self.err "Could not match string"
+ self.warning "Could not match version '#{version}'"
+ nil
end
+ }.reject { |vers| vers.nil? }.sort { |a,b|
+ versioncmp(a,b)
+ }
+
+ if available_versions.length == 0
+ self.debug "No latest version"
+ print output if Puppet[:debug]
+ end
+
+ # Get the latest and greatest version number
+ return available_versions.pop
+ else
+ self.err "Could not match string"
end
+ end
- def update
- self.install
- end
+ def update
+ self.install
+ end
- def uninstall
- aptget "-y", "-q", 'remove', @resource[:name]
- end
+ def uninstall
+ aptget "-y", "-q", 'remove', @resource[:name]
+ end
- def purge
- aptget '-y', '-q', 'remove', '--purge', @resource[:name]
- end
+ def purge
+ aptget '-y', '-q', 'remove', '--purge', @resource[:name]
+ end
end
diff --git a/lib/puppet/provider/package/blastwave.rb b/lib/puppet/provider/package/blastwave.rb
index d1cfe6f..9f1f1ec 100755
--- a/lib/puppet/provider/package/blastwave.rb
+++ b/lib/puppet/provider/package/blastwave.rb
@@ -1,112 +1,112 @@
# Packaging using Blastwave's pkg-get program.
Puppet::Type.type(:package).provide :blastwave, :parent => :sun, :source => :sun do
- desc "Package management using Blastwave.org's ``pkg-get`` command on Solaris."
- pkgget = "pkg-get"
- pkgget = "/opt/csw/bin/pkg-get" if FileTest.executable?("/opt/csw/bin/pkg-get")
+ desc "Package management using Blastwave.org's ``pkg-get`` command on Solaris."
+ pkgget = "pkg-get"
+ pkgget = "/opt/csw/bin/pkg-get" if FileTest.executable?("/opt/csw/bin/pkg-get")
- confine :operatingsystem => :solaris
+ confine :operatingsystem => :solaris
- commands :pkgget => pkgget
+ commands :pkgget => pkgget
- def pkgget_with_cat(*args)
- Puppet::Util::Execution::withenv(:PAGER => "/usr/bin/cat") { pkgget(*args) }
- end
-
- def self.extended(mod)
- unless command(:pkgget) != "pkg-get"
- raise Puppet::Error,
- "The pkg-get command is missing; blastwave packaging unavailable"
- end
+ def pkgget_with_cat(*args)
+ Puppet::Util::Execution::withenv(:PAGER => "/usr/bin/cat") { pkgget(*args) }
+ end
- unless FileTest.exists?("/var/pkg-get/admin")
- Puppet.notice "It is highly recommended you create '/var/pkg-get/admin'."
- Puppet.notice "See /var/pkg-get/admin-fullauto"
- end
+ def self.extended(mod)
+ unless command(:pkgget) != "pkg-get"
+ raise Puppet::Error,
+ "The pkg-get command is missing; blastwave packaging unavailable"
end
- def self.instances(hash = {})
- blastlist(hash).collect do |bhash|
- bhash.delete(:avail)
- new(bhash)
- end
+ unless FileTest.exists?("/var/pkg-get/admin")
+ Puppet.notice "It is highly recommended you create '/var/pkg-get/admin'."
+ Puppet.notice "See /var/pkg-get/admin-fullauto"
end
+ end
- # Turn our blastwave listing into a bunch of hashes.
- def self.blastlist(hash)
- command = ["-c"]
-
- command << hash[:justme] if hash[:justme]
-
- output = Puppet::Util::Execution::withenv(:PAGER => "/usr/bin/cat") { pkgget command }
+ def self.instances(hash = {})
+ blastlist(hash).collect do |bhash|
+ bhash.delete(:avail)
+ new(bhash)
+ end
+ end
- list = output.split("\n").collect do |line|
- next if line =~ /^#/
- next if line =~ /^WARNING/
- next if line =~ /localrev\s+remoterev/
+ # Turn our blastwave listing into a bunch of hashes.
+ def self.blastlist(hash)
+ command = ["-c"]
- blastsplit(line)
- end.reject { |h| h.nil? }
+ command << hash[:justme] if hash[:justme]
- if hash[:justme]
- return list[0]
- else
- list.reject! { |h|
- h[:ensure] == :absent
- }
- return list
- end
+ output = Puppet::Util::Execution::withenv(:PAGER => "/usr/bin/cat") { pkgget command }
- end
+ list = output.split("\n").collect do |line|
+ next if line =~ /^#/
+ next if line =~ /^WARNING/
+ next if line =~ /localrev\s+remoterev/
- # Split the different lines into hashes.
- def self.blastsplit(line)
- if line =~ /\s*(\S+)\s+((\[Not installed\])|(\S+))\s+(\S+)/
- hash = {}
- hash[:name] = $1
- hash[:ensure] = if $2 == "[Not installed]"
- :absent
- else
- $2
- end
- hash[:avail] = $5
-
- hash[:avail] = hash[:ensure] if hash[:avail] == "SAME"
-
- # Use the name method, so it works with subclasses.
- hash[:provider] = self.name
-
- return hash
- else
- Puppet.warning "Cannot match #{line}"
- return nil
- end
- end
+ blastsplit(line)
+ end.reject { |h| h.nil? }
- def install
- pkgget_with_cat "-f", :install, @resource[:name]
+ if hash[:justme]
+ return list[0]
+ else
+ list.reject! { |h|
+ h[:ensure] == :absent
+ }
+ return list
end
- # Retrieve the version from the current package file.
- def latest
- hash = self.class.blastlist(:justme => @resource[:name])
- hash[:avail]
+ end
+
+ # Split the different lines into hashes.
+ def self.blastsplit(line)
+ if line =~ /\s*(\S+)\s+((\[Not installed\])|(\S+))\s+(\S+)/
+ hash = {}
+ hash[:name] = $1
+ hash[:ensure] = if $2 == "[Not installed]"
+ :absent
+ else
+ $2
+ end
+ hash[:avail] = $5
+
+ hash[:avail] = hash[:ensure] if hash[:avail] == "SAME"
+
+ # Use the name method, so it works with subclasses.
+ hash[:provider] = self.name
+
+ return hash
+ else
+ Puppet.warning "Cannot match #{line}"
+ return nil
end
-
- def query
- if hash = self.class.blastlist(:justme => @resource[:name])
- hash
- else
- {:ensure => :absent}
- end
+ end
+
+ def install
+ pkgget_with_cat "-f", :install, @resource[:name]
+ end
+
+ # Retrieve the version from the current package file.
+ def latest
+ hash = self.class.blastlist(:justme => @resource[:name])
+ hash[:avail]
+ end
+
+ def query
+ if hash = self.class.blastlist(:justme => @resource[:name])
+ hash
+ else
+ {:ensure => :absent}
end
+ end
- # Remove the old package, and install the new one
- def update
- pkgget_with_cat "-f", :upgrade, @resource[:name]
- end
+ # Remove the old package, and install the new one
+ def update
+ pkgget_with_cat "-f", :upgrade, @resource[:name]
+ end
- def uninstall
- pkgget_with_cat "-f", :remove, @resource[:name]
- end
+ def uninstall
+ pkgget_with_cat "-f", :remove, @resource[:name]
+ end
end
diff --git a/lib/puppet/provider/package/darwinport.rb b/lib/puppet/provider/package/darwinport.rb
index c746cc3..c5f9ba2 100755
--- a/lib/puppet/provider/package/darwinport.rb
+++ b/lib/puppet/provider/package/darwinport.rb
@@ -1,86 +1,86 @@
require 'puppet/provider/package'
Puppet::Type.type(:package).provide :darwinport, :parent => Puppet::Provider::Package do
- desc "Package management using DarwinPorts on OS X."
-
- confine :operatingsystem => :darwin
- commands :port => "/opt/local/bin/port"
-
- def self.eachpkgashash
- # list out all of the packages
- open("| #{command(:port)} list installed") { |process|
- regex = %r{(\S+)\s+@(\S+)\s+(\S+)}
- fields = [:name, :ensure, :location]
- hash = {}
-
- # now turn each returned line into a package object
- process.each { |line|
- hash.clear
-
- if match = regex.match(line)
- fields.zip(match.captures) { |field,value|
- hash[field] = value
- }
-
- hash.delete :location
- hash[:provider] = self.name
- yield hash.dup
- else
- raise Puppet::DevError,
- "Failed to match dpkg line #{line}"
- end
- }
- }
- end
-
- def self.instances
- packages = []
-
- eachpkgashash do |hash|
- packages << new(hash)
+ desc "Package management using DarwinPorts on OS X."
+
+ confine :operatingsystem => :darwin
+ commands :port => "/opt/local/bin/port"
+
+ def self.eachpkgashash
+ # list out all of the packages
+ open("| #{command(:port)} list installed") { |process|
+ regex = %r{(\S+)\s+@(\S+)\s+(\S+)}
+ fields = [:name, :ensure, :location]
+ hash = {}
+
+ # now turn each returned line into a package object
+ process.each { |line|
+ hash.clear
+
+ if match = regex.match(line)
+ fields.zip(match.captures) { |field,value|
+ hash[field] = value
+ }
+
+ hash.delete :location
+ hash[:provider] = self.name
+ yield hash.dup
+ else
+ raise Puppet::DevError,
+ "Failed to match dpkg line #{line}"
end
+ }
+ }
+ end
- packages
- end
+ def self.instances
+ packages = []
- def install
- should = @resource.should(:ensure)
-
- # Seems like you can always say 'upgrade'
- output = port "upgrade", @resource[:name]
- if output =~ /^Error: No port/
- raise Puppet::ExecutionFailure, "Could not find package #{@resource[:name]}"
- end
+ eachpkgashash do |hash|
+ packages << new(hash)
end
- def query
- version = nil
- self.class.eachpkgashash do |hash|
- return hash if hash[:name] == @resource[:name]
- end
+ packages
+ end
- nil
+ def install
+ should = @resource.should(:ensure)
+
+ # Seems like you can always say 'upgrade'
+ output = port "upgrade", @resource[:name]
+ if output =~ /^Error: No port/
+ raise Puppet::ExecutionFailure, "Could not find package #{@resource[:name]}"
end
+ end
- def latest
- info = port :search, "^#{@resource[:name]}$"
+ def query
+ version = nil
+ self.class.eachpkgashash do |hash|
+ return hash if hash[:name] == @resource[:name]
+ end
- if $CHILD_STATUS != 0 or info =~ /^Error/
- return nil
- end
+ nil
+ end
- ary = info.split(/\s+/)
- version = ary[2].sub(/^@/, '')
+ def latest
+ info = port :search, "^#{@resource[:name]}$"
- version
+ if $CHILD_STATUS != 0 or info =~ /^Error/
+ return nil
end
- def uninstall
- port :uninstall, @resource[:name]
- end
+ ary = info.split(/\s+/)
+ version = ary[2].sub(/^@/, '')
- def update
- install
- end
+ version
+ end
+
+ def uninstall
+ port :uninstall, @resource[:name]
+ end
+
+ def update
+ install
+ end
end
diff --git a/lib/puppet/provider/package/dpkg.rb b/lib/puppet/provider/package/dpkg.rb
index 06d3f58..bee63bf 100755
--- a/lib/puppet/provider/package/dpkg.rb
+++ b/lib/puppet/provider/package/dpkg.rb
@@ -1,156 +1,156 @@
require 'puppet/provider/package'
Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package do
- desc "Package management via ``dpkg``. Because this only uses ``dpkg``
- and not ``apt``, you must specify the source of any packages you want
- to manage."
-
- has_feature :holdable
-
- commands :dpkg => "/usr/bin/dpkg"
- commands :dpkg_deb => "/usr/bin/dpkg-deb"
- commands :dpkgquery => "/usr/bin/dpkg-query"
-
- def self.instances
- packages = []
-
- # list out all of the packages
- cmd = "#{command(:dpkgquery)} -W --showformat '${Status} ${Package} ${Version}\\n'"
- Puppet.debug "Executing '#{cmd}'"
- execpipe(cmd) do |process|
- # our regex for matching dpkg output
- regex = %r{^(\S+) +(\S+) +(\S+) (\S+) (\S*)$}
- fields = [:desired, :error, :status, :name, :ensure]
- hash = {}
-
- # now turn each returned line into a package object
- process.each { |line|
- if hash = parse_line(line)
- packages << new(hash)
- end
- }
+ desc "Package management via ``dpkg``. Because this only uses ``dpkg``
+ and not ``apt``, you must specify the source of any packages you want
+ to manage."
+
+ has_feature :holdable
+
+ commands :dpkg => "/usr/bin/dpkg"
+ commands :dpkg_deb => "/usr/bin/dpkg-deb"
+ commands :dpkgquery => "/usr/bin/dpkg-query"
+
+ def self.instances
+ packages = []
+
+ # list out all of the packages
+ cmd = "#{command(:dpkgquery)} -W --showformat '${Status} ${Package} ${Version}\\n'"
+ Puppet.debug "Executing '#{cmd}'"
+ execpipe(cmd) do |process|
+ # our regex for matching dpkg output
+ regex = %r{^(\S+) +(\S+) +(\S+) (\S+) (\S*)$}
+ fields = [:desired, :error, :status, :name, :ensure]
+ hash = {}
+
+ # now turn each returned line into a package object
+ process.each { |line|
+ if hash = parse_line(line)
+ packages << new(hash)
end
-
- packages
+ }
end
- self::REGEX = %r{^(\S+) +(\S+) +(\S+) (\S+) (\S*)$}
- self::FIELDS = [:desired, :error, :status, :name, :ensure]
+ packages
+ end
- def self.parse_line(line)
- if match = self::REGEX.match(line)
- hash = {}
+ self::REGEX = %r{^(\S+) +(\S+) +(\S+) (\S+) (\S*)$}
+ self::FIELDS = [:desired, :error, :status, :name, :ensure]
- self::FIELDS.zip(match.captures) { |field,value|
- hash[field] = value
- }
+ def self.parse_line(line)
+ if match = self::REGEX.match(line)
+ hash = {}
- hash[:provider] = self.name
+ self::FIELDS.zip(match.captures) { |field,value|
+ hash[field] = value
+ }
- if hash[:status] == 'not-installed'
- hash[:ensure] = :purged
- elsif ['config-files', 'half-installed', 'unpacked', 'half-configured'].include?(hash[:status])
- hash[:ensure] = :absent
- end
- hash[:ensure] = :held if hash[:desired] == 'hold'
- else
- Puppet.warning "Failed to match dpkg-query line #{line.inspect}"
- return nil
- end
+ hash[:provider] = self.name
- hash
+ if hash[:status] == 'not-installed'
+ hash[:ensure] = :purged
+ elsif ['config-files', 'half-installed', 'unpacked', 'half-configured'].include?(hash[:status])
+ hash[:ensure] = :absent
+ end
+ hash[:ensure] = :held if hash[:desired] == 'hold'
+ else
+ Puppet.warning "Failed to match dpkg-query line #{line.inspect}"
+ return nil
end
- def install
- unless file = @resource[:source]
- raise ArgumentError, "You cannot install dpkg packages without a source"
- end
+ hash
+ end
- args = []
+ def install
+ unless file = @resource[:source]
+ raise ArgumentError, "You cannot install dpkg packages without a source"
+ end
- # We always unhold when installing to remove any prior hold.
- self.unhold
+ args = []
- if @resource[:configfiles] == :keep
- args << '--force-confold'
- else
- args << '--force-confnew'
- end
- args << '-i' << file
+ # We always unhold when installing to remove any prior hold.
+ self.unhold
- dpkg(*args)
+ if @resource[:configfiles] == :keep
+ args << '--force-confold'
+ else
+ args << '--force-confnew'
end
+ args << '-i' << file
- def update
- self.install
- end
+ dpkg(*args)
+ end
- # Return the version from the package.
- def latest
- output = dpkg_deb "--show", @resource[:source]
- matches = /^(\S+)\t(\S+)$/.match(output).captures
- warning "source doesn't contain named package, but #{matches[0]}" unless matches[0].match( Regexp.escape(@resource[:name]) )
- matches[1]
- end
+ def update
+ self.install
+ end
- def query
- packages = []
+ # Return the version from the package.
+ def latest
+ output = dpkg_deb "--show", @resource[:source]
+ matches = /^(\S+)\t(\S+)$/.match(output).captures
+ warning "source doesn't contain named package, but #{matches[0]}" unless matches[0].match( Regexp.escape(@resource[:name]) )
+ matches[1]
+ end
- fields = [:desired, :error, :status, :name, :ensure]
+ def query
+ packages = []
- hash = {}
+ fields = [:desired, :error, :status, :name, :ensure]
- # list out our specific package
- begin
+ hash = {}
- output = dpkgquery(
- "-W", "--showformat",
-
- '${Status} ${Package} ${Version}\\n', @resource[:name]
- )
- rescue Puppet::ExecutionFailure
- # dpkg-query exits 1 if the package is not found.
- return {:ensure => :purged, :status => 'missing', :name => @resource[:name], :error => 'ok'}
+ # list out our specific package
+ begin
- end
-
- hash = self.class.parse_line(output) || {:ensure => :absent, :status => 'missing', :name => @resource[:name], :error => 'ok'}
-
- if hash[:error] != "ok"
- raise Puppet::Error.new(
- "Package #{hash[:name]}, version #{hash[:ensure]} is in error state: #{hash[:error]}"
- )
- end
+ output = dpkgquery(
+ "-W", "--showformat",
+
+ '${Status} ${Package} ${Version}\\n', @resource[:name]
+ )
+ rescue Puppet::ExecutionFailure
+ # dpkg-query exits 1 if the package is not found.
+ return {:ensure => :purged, :status => 'missing', :name => @resource[:name], :error => 'ok'}
- hash
end
- def uninstall
- dpkg "-r", @resource[:name]
- end
+ hash = self.class.parse_line(output) || {:ensure => :absent, :status => 'missing', :name => @resource[:name], :error => 'ok'}
- def purge
- dpkg "--purge", @resource[:name]
+ if hash[:error] != "ok"
+ raise Puppet::Error.new(
+ "Package #{hash[:name]}, version #{hash[:ensure]} is in error state: #{hash[:error]}"
+ )
end
- def hold
- self.install
- begin
- Tempfile.open('puppet_dpkg_set_selection') { |tmpfile|
- tmpfile.write("#{@resource[:name]} hold\n")
- tmpfile.flush
- execute([:dpkg, "--set-selections"], :stdinfile => tmpfile.path.to_s)
- }
- end
+ hash
+ end
+
+ def uninstall
+ dpkg "-r", @resource[:name]
+ end
+
+ def purge
+ dpkg "--purge", @resource[:name]
+ end
+
+ def hold
+ self.install
+ begin
+ Tempfile.open('puppet_dpkg_set_selection') { |tmpfile|
+ tmpfile.write("#{@resource[:name]} hold\n")
+ tmpfile.flush
+ execute([:dpkg, "--set-selections"], :stdinfile => tmpfile.path.to_s)
+ }
end
-
- def unhold
- begin
- Tempfile.open('puppet_dpkg_set_selection') { |tmpfile|
- tmpfile.write("#{@resource[:name]} install\n")
- tmpfile.flush
- execute([:dpkg, "--set-selections"], :stdinfile => tmpfile.path.to_s)
- }
- end
+ end
+
+ def unhold
+ begin
+ Tempfile.open('puppet_dpkg_set_selection') { |tmpfile|
+ tmpfile.write("#{@resource[:name]} install\n")
+ tmpfile.flush
+ execute([:dpkg, "--set-selections"], :stdinfile => tmpfile.path.to_s)
+ }
end
+ end
end
diff --git a/lib/puppet/provider/package/fink.rb b/lib/puppet/provider/package/fink.rb
index a7310b0..5cf4786 100755
--- a/lib/puppet/provider/package/fink.rb
+++ b/lib/puppet/provider/package/fink.rb
@@ -1,82 +1,82 @@
Puppet::Type.type(:package).provide :fink, :parent => :dpkg, :source => :dpkg do
- # Provide sorting functionality
- include Puppet::Util::Package
-
- desc "Package management via ``fink``."
-
- commands :fink => "/sw/bin/fink"
- commands :aptget => "/sw/bin/apt-get"
- commands :aptcache => "/sw/bin/apt-cache"
- commands :dpkgquery => "/sw/bin/dpkg-query"
+ # Provide sorting functionality
+ include Puppet::Util::Package
+
+ desc "Package management via ``fink``."
+
+ commands :fink => "/sw/bin/fink"
+ commands :aptget => "/sw/bin/apt-get"
+ commands :aptcache => "/sw/bin/apt-cache"
+ commands :dpkgquery => "/sw/bin/dpkg-query"
+
+ has_feature :versionable
+
+ # A derivative of DPKG; this is how most people actually manage
+ # Debian boxes, and the only thing that differs is that it can
+ # install packages from remote sites.
+
+ def finkcmd(*args)
+ fink(*args)
+ end
+
+ # Install a package using 'apt-get'. This function needs to support
+ # installing a specific version.
+ def install
+ self.run_preseed if @resource[:responsefile]
+ should = @resource.should(:ensure)
+
+ str = @resource[:name]
+ case should
+ when true, false, Symbol
+ # pass
+ else
+ # Add the package version
+ str += "=#{should}"
+ end
+ cmd = %w{-b -q -y}
- has_feature :versionable
+ keep = ""
- # A derivative of DPKG; this is how most people actually manage
- # Debian boxes, and the only thing that differs is that it can
- # install packages from remote sites.
+ cmd << :install << str
- def finkcmd(*args)
- fink(*args)
- end
+ finkcmd(cmd)
+ end
- # Install a package using 'apt-get'. This function needs to support
- # installing a specific version.
- def install
- self.run_preseed if @resource[:responsefile]
- should = @resource.should(:ensure)
+ # What's the latest package version available?
+ def latest
+ output = aptcache :policy, @resource[:name]
- str = @resource[:name]
- case should
- when true, false, Symbol
- # pass
+ if output =~ /Candidate:\s+(\S+)\s/
+ return $1
else
- # Add the package version
- str += "=#{should}"
+ self.err "Could not find latest version"
+ return nil
+ end
end
- cmd = %w{-b -q -y}
-
- keep = ""
- cmd << :install << str
+ #
+ # preseeds answers to dpkg-set-selection from the "responsefile"
+ #
+ def run_preseed
+ if response = @resource[:responsefile] and FileTest.exists?(response)
+ self.info("Preseeding #{response} to debconf-set-selections")
- finkcmd(cmd)
+ preseed response
+ else
+ self.info "No responsefile specified or non existant, not preseeding anything"
end
+ end
- # What's the latest package version available?
- def latest
- output = aptcache :policy, @resource[:name]
-
- if output =~ /Candidate:\s+(\S+)\s/
- return $1
- else
- self.err "Could not find latest version"
- return nil
- end
- end
-
- #
- # preseeds answers to dpkg-set-selection from the "responsefile"
- #
- def run_preseed
- if response = @resource[:responsefile] and FileTest.exists?(response)
- self.info("Preseeding #{response} to debconf-set-selections")
-
- preseed response
- else
- self.info "No responsefile specified or non existant, not preseeding anything"
- end
- end
-
- def update
- self.install
- end
+ def update
+ self.install
+ end
- def uninstall
- finkcmd "-y", "-q", :remove, @model[:name]
- end
+ def uninstall
+ finkcmd "-y", "-q", :remove, @model[:name]
+ end
- def purge
- aptget '-y', '-q', 'remove', '--purge', @resource[:name]
- end
+ def purge
+ aptget '-y', '-q', 'remove', '--purge', @resource[:name]
+ end
end
diff --git a/lib/puppet/provider/package/freebsd.rb b/lib/puppet/provider/package/freebsd.rb
index 95d15c7..2f012a4 100755
--- a/lib/puppet/provider/package/freebsd.rb
+++ b/lib/puppet/provider/package/freebsd.rb
@@ -1,50 +1,50 @@
Puppet::Type.type(:package).provide :freebsd, :parent => :openbsd do
- desc "The specific form of package management on FreeBSD. This is an
- extremely quirky packaging system, in that it freely mixes between
- ports and packages. Apparently all of the tools are written in Ruby,
- so there are plans to rewrite this support to directly use those
- libraries."
+ desc "The specific form of package management on FreeBSD. This is an
+ extremely quirky packaging system, in that it freely mixes between
+ ports and packages. Apparently all of the tools are written in Ruby,
+ so there are plans to rewrite this support to directly use those
+ libraries."
- commands :pkginfo => "/usr/sbin/pkg_info",
- :pkgadd => "/usr/sbin/pkg_add",
- :pkgdelete => "/usr/sbin/pkg_delete"
+ commands :pkginfo => "/usr/sbin/pkg_info",
+ :pkgadd => "/usr/sbin/pkg_add",
+ :pkgdelete => "/usr/sbin/pkg_delete"
- confine :operatingsystem => :freebsd
+ confine :operatingsystem => :freebsd
- def self.listcmd
- command(:pkginfo)
- end
+ def self.listcmd
+ command(:pkginfo)
+ end
- def install
- should = @resource.should(:ensure)
-
- if @resource[:source] =~ /\/$/
- if @resource[:source] =~ /^(ftp|https?):/
- withenv :PACKAGESITE => @resource[:source] do
- pkgadd "-r", @resource[:name]
- end
- else
- withenv :PKG_PATH => @resource[:source] do
- pkgadd @resource[:name]
- end
- end
- else
- Puppet.warning "source is defined but does not have trailing slash, ignoring #{@resource[:source]}" if @resource[:source]
- pkgadd "-r", @resource[:name]
- end
- end
+ def install
+ should = @resource.should(:ensure)
- def query
- self.class.instances.each do |provider|
- if provider.name == @resource.name
- return provider.properties
- end
+ if @resource[:source] =~ /\/$/
+ if @resource[:source] =~ /^(ftp|https?):/
+ withenv :PACKAGESITE => @resource[:source] do
+ pkgadd "-r", @resource[:name]
end
- nil
+ else
+ withenv :PKG_PATH => @resource[:source] do
+ pkgadd @resource[:name]
+ end
+ end
+ else
+ Puppet.warning "source is defined but does not have trailing slash, ignoring #{@resource[:source]}" if @resource[:source]
+ pkgadd "-r", @resource[:name]
end
+ end
- def uninstall
- pkgdelete "#{@resource[:name]}-#{@resource.should(:ensure)}"
+ def query
+ self.class.instances.each do |provider|
+ if provider.name == @resource.name
+ return provider.properties
+ end
end
+ nil
+ end
+
+ def uninstall
+ pkgdelete "#{@resource[:name]}-#{@resource.should(:ensure)}"
+ end
end
diff --git a/lib/puppet/provider/package/gem.rb b/lib/puppet/provider/package/gem.rb
index 90b436f..8d70b75 100755
--- a/lib/puppet/provider/package/gem.rb
+++ b/lib/puppet/provider/package/gem.rb
@@ -3,122 +3,122 @@ require 'uri'
# Ruby gems support.
Puppet::Type.type(:package).provide :gem, :parent => Puppet::Provider::Package do
- desc "Ruby Gem support. If a URL is passed via ``source``, then that URL is used as the
- remote gem repository; if a source is present but is not a valid URL, it will be
- interpreted as the path to a local gem file. If source is not present at all,
- the gem will be installed from the default gem repositories."
+ desc "Ruby Gem support. If a URL is passed via ``source``, then that URL is used as the
+ remote gem repository; if a source is present but is not a valid URL, it will be
+ interpreted as the path to a local gem file. If source is not present at all,
+ the gem will be installed from the default gem repositories."
- has_feature :versionable
+ has_feature :versionable
- commands :gemcmd => "gem"
+ commands :gemcmd => "gem"
- def self.gemlist(hash)
- command = [command(:gemcmd), "list"]
+ def self.gemlist(hash)
+ command = [command(:gemcmd), "list"]
- if hash[:local]
- command << "--local"
- else
- command << "--remote"
- end
-
- if name = hash[:justme]
- command << name
- end
-
- begin
- list = execute(command).split("\n").collect do |set|
- if gemhash = gemsplit(set)
- gemhash[:provider] = :gem
- gemhash
- else
- nil
- end
- end.compact
- rescue Puppet::ExecutionFailure => detail
- raise Puppet::Error, "Could not list gems: #{detail}"
- end
+ if hash[:local]
+ command << "--local"
+ else
+ command << "--remote"
+ end
- if hash[:justme]
- return list.shift
- else
- return list
- end
+ if name = hash[:justme]
+ command << name
end
- def self.gemsplit(desc)
- case desc
- when /^\*\*\*/, /^\s*$/, /^\s+/; return nil
- when /^(\S+)\s+\((.+)\)/
- name = $1
- version = $2.split(/,\s*/)[0]
- return {
- :name => name,
- :ensure => version
- }
+ begin
+ list = execute(command).split("\n").collect do |set|
+ if gemhash = gemsplit(set)
+ gemhash[:provider] = :gem
+ gemhash
else
- Puppet.warning "Could not match #{desc}"
- nil
+ nil
end
+ end.compact
+ rescue Puppet::ExecutionFailure => detail
+ raise Puppet::Error, "Could not list gems: #{detail}"
end
- def self.instances(justme = false)
- gemlist(:local => true).collect do |hash|
- new(hash)
- end
+ if hash[:justme]
+ return list.shift
+ else
+ return list
end
+ end
+
+ def self.gemsplit(desc)
+ case desc
+ when /^\*\*\*/, /^\s*$/, /^\s+/; return nil
+ when /^(\S+)\s+\((.+)\)/
+ name = $1
+ version = $2.split(/,\s*/)[0]
+ return {
+ :name => name,
+ :ensure => version
+ }
+ else
+ Puppet.warning "Could not match #{desc}"
+ nil
+ end
+ end
- def install(useversion = true)
- command = [command(:gemcmd), "install"]
- command << "-v" << resource[:ensure] if (! resource[:ensure].is_a? Symbol) and useversion
- # Always include dependencies
- command << "--include-dependencies"
-
- if source = resource[:source]
- begin
- uri = URI.parse(source)
- rescue => detail
- fail "Invalid source '#{uri}': #{detail}"
- end
-
- case uri.scheme
- when nil
- # no URI scheme => interpret the source as a local file
- command << source
- when /file/i
- command << uri.path
- when 'puppet'
- # we don't support puppet:// URLs (yet)
- raise Puppet::Error.new("puppet:// URLs are not supported as gem sources")
- else
- # interpret it as a gem repository
- command << "--source" << "#{source}" << resource[:name]
- end
- else
- command << resource[:name]
- end
-
- output = execute(command)
- # Apparently some stupid gem versions don't exit non-0 on failure
- self.fail "Could not install: #{output.chomp}" if output.include?("ERROR")
+ def self.instances(justme = false)
+ gemlist(:local => true).collect do |hash|
+ new(hash)
+ end
+ end
+
+ def install(useversion = true)
+ command = [command(:gemcmd), "install"]
+ command << "-v" << resource[:ensure] if (! resource[:ensure].is_a? Symbol) and useversion
+ # Always include dependencies
+ command << "--include-dependencies"
+
+ if source = resource[:source]
+ begin
+ uri = URI.parse(source)
+ rescue => detail
+ fail "Invalid source '#{uri}': #{detail}"
+ end
+
+ case uri.scheme
+ when nil
+ # no URI scheme => interpret the source as a local file
+ command << source
+ when /file/i
+ command << uri.path
+ when 'puppet'
+ # we don't support puppet:// URLs (yet)
+ raise Puppet::Error.new("puppet:// URLs are not supported as gem sources")
+ else
+ # interpret it as a gem repository
+ command << "--source" << "#{source}" << resource[:name]
+ end
+ else
+ command << resource[:name]
end
- def latest
- # This always gets the latest version available.
- hash = self.class.gemlist(:justme => resource[:name])
+ output = execute(command)
+ # Apparently some stupid gem versions don't exit non-0 on failure
+ self.fail "Could not install: #{output.chomp}" if output.include?("ERROR")
+ end
- hash[:ensure]
- end
+ def latest
+ # This always gets the latest version available.
+ hash = self.class.gemlist(:justme => resource[:name])
- def query
- self.class.gemlist(:justme => resource[:name], :local => true)
- end
+ hash[:ensure]
+ end
- def uninstall
- gemcmd "uninstall", "-x", "-a", resource[:name]
- end
+ def query
+ self.class.gemlist(:justme => resource[:name], :local => true)
+ end
- def update
- self.install(false)
- end
+ def uninstall
+ gemcmd "uninstall", "-x", "-a", resource[:name]
+ end
+
+ def update
+ self.install(false)
+ end
end
diff --git a/lib/puppet/provider/package/hpux.rb b/lib/puppet/provider/package/hpux.rb
index 4d53946..8396edf 100644
--- a/lib/puppet/provider/package/hpux.rb
+++ b/lib/puppet/provider/package/hpux.rb
@@ -4,41 +4,41 @@ require 'puppet/provider/package'
Puppet::Type.type(:package).provide :hpux, :parent => Puppet::Provider::Package do
- desc "HP-UX's packaging system."
-
- commands :swinstall => "/usr/sbin/swinstall",
- :swlist => "/usr/sbin/swlist",
- :swremove => "/usr/sbin/swremove"
-
- confine :operatingsystem => "hp-ux"
-
- defaultfor :operatingsystem => "hp-ux"
-
- def self.instances
- # TODO: This is very hard on HP-UX!
- []
- end
-
- # source and name are required
- def install
- raise ArgumentError, "source must be provided to install HP-UX packages" unless resource[:source]
- args = standard_args + ["-s", resource[:source], resource[:name]]
- swinstall(*args)
- end
-
- def query
- swlist resource[:name]
- {:ensure => :present}
- rescue
- {:ensure => :absent}
- end
-
- def uninstall
- args = standard_args + [resource[:name]]
- swremove(*args)
- end
-
- def standard_args
- ["-x", "mount_all_filesystems=false"]
- end
+ desc "HP-UX's packaging system."
+
+ commands :swinstall => "/usr/sbin/swinstall",
+ :swlist => "/usr/sbin/swlist",
+ :swremove => "/usr/sbin/swremove"
+
+ confine :operatingsystem => "hp-ux"
+
+ defaultfor :operatingsystem => "hp-ux"
+
+ def self.instances
+ # TODO: This is very hard on HP-UX!
+ []
+ end
+
+ # source and name are required
+ def install
+ raise ArgumentError, "source must be provided to install HP-UX packages" unless resource[:source]
+ args = standard_args + ["-s", resource[:source], resource[:name]]
+ swinstall(*args)
+ end
+
+ def query
+ swlist resource[:name]
+ {:ensure => :present}
+ rescue
+ {:ensure => :absent}
+ end
+
+ def uninstall
+ args = standard_args + [resource[:name]]
+ swremove(*args)
+ end
+
+ def standard_args
+ ["-x", "mount_all_filesystems=false"]
+ end
end
diff --git a/lib/puppet/provider/package/nim.rb b/lib/puppet/provider/package/nim.rb
index 33d4bf1..8f52016 100644
--- a/lib/puppet/provider/package/nim.rb
+++ b/lib/puppet/provider/package/nim.rb
@@ -2,34 +2,34 @@ require 'puppet/provider/package'
require 'puppet/util/package'
Puppet::Type.type(:package).provide :nim, :parent => :aix, :source => :aix do
- desc "Installation from NIM LPP source"
+ desc "Installation from NIM LPP source"
- # The commands we are using on an AIX box are installed standard
- # (except nimclient) nimclient needs the bos.sysmgt.nim.client fileset.
- commands :nimclient => "/usr/sbin/nimclient"
+ # The commands we are using on an AIX box are installed standard
+ # (except nimclient) nimclient needs the bos.sysmgt.nim.client fileset.
+ commands :nimclient => "/usr/sbin/nimclient"
- # If NIM has not been configured, /etc/niminfo will not be present.
- # However, we have no way of knowing if the NIM server is not configured
- # properly.
- confine :exists => "/etc/niminfo"
+ # If NIM has not been configured, /etc/niminfo will not be present.
+ # However, we have no way of knowing if the NIM server is not configured
+ # properly.
+ confine :exists => "/etc/niminfo"
- has_feature :versionable
+ has_feature :versionable
- attr_accessor :latest_info
+ attr_accessor :latest_info
- def self.srclistcmd(source)
- [ command(:nimclient), "-o", "showres", "-a", "installp_flags=L", "-a", "resource=#{source}" ]
- end
+ def self.srclistcmd(source)
+ [ command(:nimclient), "-o", "showres", "-a", "installp_flags=L", "-a", "resource=#{source}" ]
+ end
- def install(useversion = true)
- unless source = @resource[:source]
- self.fail "An LPP source location is required in 'source'"
- end
+ def install(useversion = true)
+ unless source = @resource[:source]
+ self.fail "An LPP source location is required in 'source'"
+ end
- pkg = @resource[:name]
+ pkg = @resource[:name]
- pkg << " " << @resource.should(:ensure) if (! @resource.should(:ensure).is_a? Symbol) and useversion
+ pkg << " " << @resource.should(:ensure) if (! @resource.should(:ensure).is_a? Symbol) and useversion
- nimclient "-o", "cust", "-a", "installp_flags=acgwXY", "-a", "lpp_source=#{source}", "-a", "filesets='#{pkg}'"
- end
+ nimclient "-o", "cust", "-a", "installp_flags=acgwXY", "-a", "lpp_source=#{source}", "-a", "filesets='#{pkg}'"
+ end
end
diff --git a/lib/puppet/provider/package/openbsd.rb b/lib/puppet/provider/package/openbsd.rb
index f6005ef..ca477e5 100755
--- a/lib/puppet/provider/package/openbsd.rb
+++ b/lib/puppet/provider/package/openbsd.rb
@@ -2,119 +2,119 @@ require 'puppet/provider/package'
# Packaging on OpenBSD. Doesn't work anywhere else that I know of.
Puppet::Type.type(:package).provide :openbsd, :parent => Puppet::Provider::Package do
- include Puppet::Util::Execution
- desc "OpenBSD's form of ``pkg_add`` support."
-
- commands :pkginfo => "pkg_info", :pkgadd => "pkg_add", :pkgdelete => "pkg_delete"
-
- defaultfor :operatingsystem => :openbsd
- confine :operatingsystem => :openbsd
-
- has_feature :versionable
-
- def self.instances
- packages = []
-
- begin
- execpipe(listcmd) do |process|
- # our regex for matching pkg_info output
- regex = /^(.*)-(\d[^-]*)[-]?(\D*)(.*)$/
- fields = [:name, :ensure, :flavor ]
- hash = {}
-
- # now turn each returned line into a package object
- process.each { |line|
- if match = regex.match(line.split[0])
- fields.zip(match.captures) { |field,value|
- hash[field] = value
- }
- yup = nil
- name = hash[:name]
-
- hash[:provider] = self.name
-
- packages << new(hash)
- hash = {}
- else
- # Print a warning on lines we can't match, but move
- # on, since it should be non-fatal
- warning("Failed to match line #{line}")
- end
- }
- end
-
- return packages
- rescue Puppet::ExecutionFailure
- return nil
- end
- end
+ include Puppet::Util::Execution
+ desc "OpenBSD's form of ``pkg_add`` support."
- def self.listcmd
- [command(:pkginfo), " -a"]
- end
+ commands :pkginfo => "pkg_info", :pkgadd => "pkg_add", :pkgdelete => "pkg_delete"
- def install
- should = @resource.should(:ensure)
+ defaultfor :operatingsystem => :openbsd
+ confine :operatingsystem => :openbsd
- unless @resource[:source]
- raise Puppet::Error,
- "You must specify a package source for BSD packages"
- end
+ has_feature :versionable
- old_ensure = @resource[:ensure]
+ def self.instances
+ packages = []
- if @resource[:source] =~ /\/$/
- withenv :PKG_PATH => @resource[:source] do
- @resource[:ensure] = old_ensure if (@resource[:ensure] = get_version) == nil
- full_name = [ @resource[:name], @resource[:ensure], @resource[:flavor] ]
- pkgadd full_name.join('-').chomp('-')
- end
- else
- pkgadd @resource[:source]
- end
+ begin
+ execpipe(listcmd) do |process|
+ # our regex for matching pkg_info output
+ regex = /^(.*)-(\d[^-]*)[-]?(\D*)(.*)$/
+ fields = [:name, :ensure, :flavor ]
+ hash = {}
+ # now turn each returned line into a package object
+ process.each { |line|
+ if match = regex.match(line.split[0])
+ fields.zip(match.captures) { |field,value|
+ hash[field] = value
+ }
+ yup = nil
+ name = hash[:name]
+
+ hash[:provider] = self.name
+
+ packages << new(hash)
+ hash = {}
+ else
+ # Print a warning on lines we can't match, but move
+ # on, since it should be non-fatal
+ warning("Failed to match line #{line}")
+ end
+ }
+ end
+
+ return packages
+ rescue Puppet::ExecutionFailure
+ return nil
end
+ end
- def get_version
- execpipe([command(:pkginfo), " -I ", @resource[:name]]) do |process|
- # our regex for matching pkg_info output
- regex = /^(.*)-(\d[^-]*)[-]?(\D*)(.*)$/
- fields = [ :name, :version, :flavor ]
- master_version = 0
-
- process.each do |line|
- if match = regex.match(line.split[0])
- # now we return the first version, unless ensure is latest
- version = match.captures[1]
- return version unless @resource[:ensure] == "latest"
-
- master_version = version unless master_version > version
- end
- end
-
- return master_version unless master_version == 0
- raise Puppet::Error, "#{version} is not available for this package"
- end
- rescue Puppet::ExecutionFailure
- return nil
+ def self.listcmd
+ [command(:pkginfo), " -a"]
+ end
+
+ def install
+ should = @resource.should(:ensure)
+
+ unless @resource[:source]
+ raise Puppet::Error,
+ "You must specify a package source for BSD packages"
end
- def query
- hash = {}
- info = pkginfo @resource[:name]
+ old_ensure = @resource[:ensure]
+
+ if @resource[:source] =~ /\/$/
+ withenv :PKG_PATH => @resource[:source] do
+ @resource[:ensure] = old_ensure if (@resource[:ensure] = get_version) == nil
+ full_name = [ @resource[:name], @resource[:ensure], @resource[:flavor] ]
+ pkgadd full_name.join('-').chomp('-')
+ end
+ else
+ pkgadd @resource[:source]
+ end
+
+ end
- # Search for the version info
- if info =~ /Information for (inst:)?#{@resource[:name]}-(\S+)/
- hash[:ensure] = $2
- else
- return nil
+ def get_version
+ execpipe([command(:pkginfo), " -I ", @resource[:name]]) do |process|
+ # our regex for matching pkg_info output
+ regex = /^(.*)-(\d[^-]*)[-]?(\D*)(.*)$/
+ fields = [ :name, :version, :flavor ]
+ master_version = 0
+
+ process.each do |line|
+ if match = regex.match(line.split[0])
+ # now we return the first version, unless ensure is latest
+ version = match.captures[1]
+ return version unless @resource[:ensure] == "latest"
+
+ master_version = version unless master_version > version
+ end
end
- hash
+ return master_version unless master_version == 0
+ raise Puppet::Error, "#{version} is not available for this package"
+ end
+ rescue Puppet::ExecutionFailure
+ return nil
+ end
+
+ def query
+ hash = {}
+ info = pkginfo @resource[:name]
+
+ # Search for the version info
+ if info =~ /Information for (inst:)?#{@resource[:name]}-(\S+)/
+ hash[:ensure] = $2
+ else
+ return nil
end
- def uninstall
- pkgdelete @resource[:name]
- end
+ hash
+ end
+
+ def uninstall
+ pkgdelete @resource[:name]
+ end
end
diff --git a/lib/puppet/provider/package/pkg.rb b/lib/puppet/provider/package/pkg.rb
index 35a7121..9a3733c 100644
--- a/lib/puppet/provider/package/pkg.rb
+++ b/lib/puppet/provider/package/pkg.rb
@@ -1,108 +1,108 @@
require 'puppet/provider/package'
Puppet::Type.type(:package).provide :pkg, :parent => Puppet::Provider::Package do
- desc "OpenSolaris image packaging system. See pkg(5) for more information"
+ desc "OpenSolaris image packaging system. See pkg(5) for more information"
- commands :pkg => "/usr/bin/pkg"
+ commands :pkg => "/usr/bin/pkg"
- confine :operatingsystem => :solaris
+ confine :operatingsystem => :solaris
- #defaultfor [:operatingsystem => :solaris, :kernelrelease => "5.11"]
+ #defaultfor [:operatingsystem => :solaris, :kernelrelease => "5.11"]
- def self.instances
- packages = []
+ def self.instances
+ packages = []
- cmd = "#{command(:pkg)} list -H"
- execpipe(cmd) do |process|
- hash = {}
+ cmd = "#{command(:pkg)} list -H"
+ execpipe(cmd) do |process|
+ hash = {}
- # now turn each returned line into a package object
- process.each { |line|
- if hash = parse_line(line)
- packages << new(hash)
- end
- }
+ # now turn each returned line into a package object
+ process.each { |line|
+ if hash = parse_line(line)
+ packages << new(hash)
end
-
- packages
+ }
end
- self::REGEX = %r{^(\S+)\s+(\S+)\s+(\S+)\s+}
- self::FIELDS = [:name, :version, :status]
+ packages
+ end
- def self.parse_line(line)
- hash = {}
- if match = self::REGEX.match(line)
+ self::REGEX = %r{^(\S+)\s+(\S+)\s+(\S+)\s+}
+ self::FIELDS = [:name, :version, :status]
- self::FIELDS.zip(match.captures) { |field,value|
- hash[field] = value
- }
+ def self.parse_line(line)
+ hash = {}
+ if match = self::REGEX.match(line)
- hash[:provider] = self.name
- hash[:error] = "ok"
+ self::FIELDS.zip(match.captures) { |field,value|
+ hash[field] = value
+ }
- if hash[:status] == "installed"
- hash[:ensure] = :present
- else
- hash[:ensure] = :absent
- end
- else
- Puppet.warning "Failed to match 'pkg list' line #{line.inspect}"
- return nil
- end
+ hash[:provider] = self.name
+ hash[:error] = "ok"
- hash
+ if hash[:status] == "installed"
+ hash[:ensure] = :present
+ else
+ hash[:ensure] = :absent
+ end
+ else
+ Puppet.warning "Failed to match 'pkg list' line #{line.inspect}"
+ return nil
end
- # return the version of the package
- # TODO deal with multiple publishers
- def latest
- version = nil
- pkg(:list, "-Ha", @resource[:name]).split("\n").each do |line|
- v = line.split[2]
- case v
- when "known"
- return v
- when "installed"
- version = v
- else
- Puppet.warn "unknown package state for #{@resource[:name]}: #{v}"
- end
- end
- version
+ hash
+ end
+
+ # return the version of the package
+ # TODO deal with multiple publishers
+ def latest
+ version = nil
+ pkg(:list, "-Ha", @resource[:name]).split("\n").each do |line|
+ v = line.split[2]
+ case v
+ when "known"
+ return v
+ when "installed"
+ version = v
+ else
+ Puppet.warn "unknown package state for #{@resource[:name]}: #{v}"
+ end
end
-
- # install the package
- def install
- pkg :install, @resource[:name]
+ version
+ end
+
+ # install the package
+ def install
+ pkg :install, @resource[:name]
+ end
+
+ # uninstall the package
+ def uninstall
+ pkg :uninstall, '-r', @resource[:name]
+ end
+
+ # update the package to the latest version available
+ def update
+ self.install
+ end
+
+ # list a specific package
+ def query
+ begin
+ output = pkg(:list, "-H", @resource[:name])
+ rescue Puppet::ExecutionFailure
+ # pkg returns 1 if the package is not found.
+ return {:ensure => :absent, :status => 'missing',
+ :name => @resource[:name], :error => 'ok'}
end
- # uninstall the package
- def uninstall
- pkg :uninstall, '-r', @resource[:name]
- end
+ hash = self.class.parse_line(output) ||
+ {:ensure => :absent, :status => 'missing', :name => @resource[:name], :error => 'ok'}
- # update the package to the latest version available
- def update
- self.install
- end
+ raise Puppet::Error.new( "Package #{hash[:name]}, version #{hash[:version]} is in error state: #{hash[:error]}") if hash[:error] != "ok"
- # list a specific package
- def query
- begin
- output = pkg(:list, "-H", @resource[:name])
- rescue Puppet::ExecutionFailure
- # pkg returns 1 if the package is not found.
- return {:ensure => :absent, :status => 'missing',
- :name => @resource[:name], :error => 'ok'}
- end
-
- hash = self.class.parse_line(output) ||
- {:ensure => :absent, :status => 'missing', :name => @resource[:name], :error => 'ok'}
-
- raise Puppet::Error.new( "Package #{hash[:name]}, version #{hash[:version]} is in error state: #{hash[:error]}") if hash[:error] != "ok"
-
- hash
- end
+ hash
+ end
end
diff --git a/lib/puppet/provider/package/pkgdmg.rb b/lib/puppet/provider/package/pkgdmg.rb
index b533f10..4506fbf 100644
--- a/lib/puppet/provider/package/pkgdmg.rb
+++ b/lib/puppet/provider/package/pkgdmg.rb
@@ -29,116 +29,116 @@ require 'puppet/provider/package'
require 'facter/util/plist'
Puppet::Type.type(:package).provide :pkgdmg, :parent => Puppet::Provider::Package do
- desc "Package management based on Apple's Installer.app and DiskUtility.app. This package works by checking the contents of a DMG image for Apple pkg or mpkg files. Any number of pkg or mpkg files may exist in the root directory of the DMG file system. Sub directories are not checked for packages. See `the wiki docs </trac/puppet/wiki/DmgPackages>` for more detail."
+ desc "Package management based on Apple's Installer.app and DiskUtility.app. This package works by checking the contents of a DMG image for Apple pkg or mpkg files. Any number of pkg or mpkg files may exist in the root directory of the DMG file system. Sub directories are not checked for packages. See `the wiki docs </trac/puppet/wiki/DmgPackages>` for more detail."
- confine :operatingsystem => :darwin
- defaultfor :operatingsystem => :darwin
- commands :installer => "/usr/sbin/installer"
- commands :hdiutil => "/usr/bin/hdiutil"
- commands :curl => "/usr/bin/curl"
+ confine :operatingsystem => :darwin
+ defaultfor :operatingsystem => :darwin
+ commands :installer => "/usr/sbin/installer"
+ commands :hdiutil => "/usr/bin/hdiutil"
+ commands :curl => "/usr/bin/curl"
- # JJM We store a cookie for each installed .pkg.dmg in /var/db
- def self.instance_by_name
- Dir.entries("/var/db").find_all { |f|
- f =~ /^\.puppet_pkgdmg_installed_/
- }.collect do |f|
- name = f.sub(/^\.puppet_pkgdmg_installed_/, '')
- yield name if block_given?
- name
- end
+ # JJM We store a cookie for each installed .pkg.dmg in /var/db
+ def self.instance_by_name
+ Dir.entries("/var/db").find_all { |f|
+ f =~ /^\.puppet_pkgdmg_installed_/
+ }.collect do |f|
+ name = f.sub(/^\.puppet_pkgdmg_installed_/, '')
+ yield name if block_given?
+ name
end
+ end
- def self.instances
- instance_by_name.collect do |name|
+ def self.instances
+ instance_by_name.collect do |name|
- new(
+ new(
- :name => name,
- :provider => :pkgdmg,
+ :name => name,
+ :provider => :pkgdmg,
- :ensure => :installed
- )
- end
+ :ensure => :installed
+ )
end
+ end
- def self.installpkg(source, name, orig_source)
- installer "-pkg", source, "-target", "/"
- # Non-zero exit status will throw an exception.
- File.open("/var/db/.puppet_pkgdmg_installed_#{name}", "w") do |t|
- t.print "name: '#{name}'\n"
- t.print "source: '#{orig_source}'\n"
- end
+ def self.installpkg(source, name, orig_source)
+ installer "-pkg", source, "-target", "/"
+ # Non-zero exit status will throw an exception.
+ File.open("/var/db/.puppet_pkgdmg_installed_#{name}", "w") do |t|
+ t.print "name: '#{name}'\n"
+ t.print "source: '#{orig_source}'\n"
end
+ end
- def self.installpkgdmg(source, name)
- unless source =~ /\.dmg$/i || source =~ /\.pkg$/i
- raise Puppet::Error.new("Mac OS X PKG DMG's must specificy a source string ending in .dmg or flat .pkg file")
- end
- require 'open-uri'
+ def self.installpkgdmg(source, name)
+ unless source =~ /\.dmg$/i || source =~ /\.pkg$/i
+ raise Puppet::Error.new("Mac OS X PKG DMG's must specificy a source string ending in .dmg or flat .pkg file")
+ end
+ require 'open-uri'
+ cached_source = source
+ if %r{\A[A-Za-z][A-Za-z0-9+\-\.]*://} =~ cached_source
+ cached_source = "/tmp/#{name}"
+ begin
+ curl "-o", cached_source, "-C", "-", "-k", "-s", "--url", source
+ Puppet.debug "Success: curl transfered [#{name}]"
+ rescue Puppet::ExecutionFailure
+ Puppet.debug "curl did not transfer [#{name}]. Falling back to slower open-uri transfer methods."
cached_source = source
- if %r{\A[A-Za-z][A-Za-z0-9+\-\.]*://} =~ cached_source
- cached_source = "/tmp/#{name}"
- begin
- curl "-o", cached_source, "-C", "-", "-k", "-s", "--url", source
- Puppet.debug "Success: curl transfered [#{name}]"
- rescue Puppet::ExecutionFailure
- Puppet.debug "curl did not transfer [#{name}]. Falling back to slower open-uri transfer methods."
- cached_source = source
- end
- end
+ end
+ end
- begin
- if source =~ /\.dmg$/i
- File.open(cached_source) do |dmg|
- xml_str = hdiutil "mount", "-plist", "-nobrowse", "-readonly", "-noidme", "-mountrandom", "/tmp", dmg.path
- hdiutil_info = Plist::parse_xml(xml_str)
- raise Puppet::Error.new("No disk entities returned by mount at #{dmg.path}") unless hdiutil_info.has_key?("system-entities")
- mounts = hdiutil_info["system-entities"].collect { |entity|
- entity["mount-point"]
- }.compact
- begin
- mounts.each do |mountpoint|
- Dir.entries(mountpoint).select { |f|
- f =~ /\.m{0,1}pkg$/i
- }.each do |pkg|
- installpkg("#{mountpoint}/#{pkg}", name, source)
- end
- end
- ensure
- mounts.each do |mountpoint|
- hdiutil "eject", mountpoint
- end
- end
- end
- elsif source =~ /\.pkg$/i
- installpkg(cached_source, name, source)
- else
- raise Puppet::Error.new("Mac OS X PKG DMG's must specificy a source string ending in .dmg or flat .pkg file")
+ begin
+ if source =~ /\.dmg$/i
+ File.open(cached_source) do |dmg|
+ xml_str = hdiutil "mount", "-plist", "-nobrowse", "-readonly", "-noidme", "-mountrandom", "/tmp", dmg.path
+ hdiutil_info = Plist::parse_xml(xml_str)
+ raise Puppet::Error.new("No disk entities returned by mount at #{dmg.path}") unless hdiutil_info.has_key?("system-entities")
+ mounts = hdiutil_info["system-entities"].collect { |entity|
+ entity["mount-point"]
+ }.compact
+ begin
+ mounts.each do |mountpoint|
+ Dir.entries(mountpoint).select { |f|
+ f =~ /\.m{0,1}pkg$/i
+ }.each do |pkg|
+ installpkg("#{mountpoint}/#{pkg}", name, source)
+ end
+ end
+ ensure
+ mounts.each do |mountpoint|
+ hdiutil "eject", mountpoint
end
- ensure
- # JJM Remove the file if open-uri didn't already do so.
- File.unlink(cached_source) if File.exist?(cached_source)
+ end
end
+ elsif source =~ /\.pkg$/i
+ installpkg(cached_source, name, source)
+ else
+ raise Puppet::Error.new("Mac OS X PKG DMG's must specificy a source string ending in .dmg or flat .pkg file")
+ end
+ ensure
+ # JJM Remove the file if open-uri didn't already do so.
+ File.unlink(cached_source) if File.exist?(cached_source)
end
+ end
- def query
- if FileTest.exists?("/var/db/.puppet_pkgdmg_installed_#{@resource[:name]}")
- Puppet.debug "/var/db/.puppet_pkgdmg_installed_#{@resource[:name]} found"
- return {:name => @resource[:name], :ensure => :present}
- else
- return nil
- end
+ def query
+ if FileTest.exists?("/var/db/.puppet_pkgdmg_installed_#{@resource[:name]}")
+ Puppet.debug "/var/db/.puppet_pkgdmg_installed_#{@resource[:name]} found"
+ return {:name => @resource[:name], :ensure => :present}
+ else
+ return nil
end
+ end
- def install
- source = nil
- unless source = @resource[:source]
- raise Puppet::Error.new("Mac OS X PKG DMG's must specify a package source.")
- end
- unless name = @resource[:name]
- raise Puppet::Error.new("Mac OS X PKG DMG's must specify a package name.")
- end
- self.class.installpkgdmg(source,name)
+ def install
+ source = nil
+ unless source = @resource[:source]
+ raise Puppet::Error.new("Mac OS X PKG DMG's must specify a package source.")
+ end
+ unless name = @resource[:name]
+ raise Puppet::Error.new("Mac OS X PKG DMG's must specify a package name.")
end
+ self.class.installpkgdmg(source,name)
+ end
end
diff --git a/lib/puppet/provider/package/portage.rb b/lib/puppet/provider/package/portage.rb
index 82d1669..30f0e4a 100644
--- a/lib/puppet/provider/package/portage.rb
+++ b/lib/puppet/provider/package/portage.rb
@@ -2,121 +2,121 @@ require 'puppet/provider/package'
require 'fileutils'
Puppet::Type.type(:package).provide :portage, :parent => Puppet::Provider::Package do
- desc "Provides packaging support for Gentoo's portage system."
+ desc "Provides packaging support for Gentoo's portage system."
- has_feature :versionable
+ has_feature :versionable
- commands :emerge => "/usr/bin/emerge", :eix => "/usr/bin/eix", :update_eix => "/usr/bin/eix-update"
+ commands :emerge => "/usr/bin/emerge", :eix => "/usr/bin/eix", :update_eix => "/usr/bin/eix-update"
- confine :operatingsystem => :gentoo
+ confine :operatingsystem => :gentoo
- defaultfor :operatingsystem => :gentoo
+ defaultfor :operatingsystem => :gentoo
- def self.instances
- result_format = /^(\S+)\s+(\S+)\s+\[(\S+)\]\s+\[(\S+)\]\s+(\S+)\s+(.*)$/
- result_fields = [:category, :name, :ensure, :version_available, :vendor, :description]
+ def self.instances
+ result_format = /^(\S+)\s+(\S+)\s+\[(\S+)\]\s+\[(\S+)\]\s+(\S+)\s+(.*)$/
+ result_fields = [:category, :name, :ensure, :version_available, :vendor, :description]
- version_format = "{last}<version>{}"
- search_format = "<category> <name> [<installedversions:LASTVERSION>] [<bestversion:LASTVERSION>] <homepage> <description>\n"
+ version_format = "{last}<version>{}"
+ search_format = "<category> <name> [<installedversions:LASTVERSION>] [<bestversion:LASTVERSION>] <homepage> <description>\n"
- begin
- update_eix if !FileUtils.uptodate?("/var/cache/eix", %w{/usr/bin/eix /usr/portage/metadata/timestamp})
+ begin
+ update_eix if !FileUtils.uptodate?("/var/cache/eix", %w{/usr/bin/eix /usr/portage/metadata/timestamp})
- search_output = nil
- Puppet::Util::Execution.withenv :LASTVERSION => version_format do
- search_output = eix "--nocolor", "--pure-packages", "--stable", "--installed", "--format", search_format
- end
+ search_output = nil
+ Puppet::Util::Execution.withenv :LASTVERSION => version_format do
+ search_output = eix "--nocolor", "--pure-packages", "--stable", "--installed", "--format", search_format
+ end
- packages = []
- search_output.each do |search_result|
- match = result_format.match(search_result)
+ packages = []
+ search_output.each do |search_result|
+ match = result_format.match(search_result)
- if match
- package = {}
- result_fields.zip(match.captures) do |field, value|
- package[field] = value unless !value or value.empty?
- end
- package[:provider] = :portage
- packages << new(package)
- end
- end
-
- return packages
- rescue Puppet::ExecutionFailure => detail
- raise Puppet::Error.new(detail)
+ if match
+ package = {}
+ result_fields.zip(match.captures) do |field, value|
+ package[field] = value unless !value or value.empty?
+ end
+ package[:provider] = :portage
+ packages << new(package)
end
- end
-
- def install
- should = @resource.should(:ensure)
- name = package_name
- unless should == :present or should == :latest
- # We must install a specific version
- name = "=#{name}-#{should}"
- end
- emerge name
- end
+ end
- # The common package name format.
- def package_name
- @resource[:category] ? "#{@resource[:category]}/#{@resource[:name]}" : @resource[:name]
+ return packages
+ rescue Puppet::ExecutionFailure => detail
+ raise Puppet::Error.new(detail)
end
-
- def uninstall
- emerge "--unmerge", package_name
- end
-
- def update
- self.install
+ end
+
+ def install
+ should = @resource.should(:ensure)
+ name = package_name
+ unless should == :present or should == :latest
+ # We must install a specific version
+ name = "=#{name}-#{should}"
end
-
- def query
- result_format = /^(\S+)\s+(\S+)\s+\[(\S*)\]\s+\[(\S+)\]\s+(\S+)\s+(.*)$/
- result_fields = [:category, :name, :ensure, :version_available, :vendor, :description]
-
- version_format = "{last}<version>{}"
- search_format = "<category> <name> [<installedversions:LASTVERSION>] [<bestversion:LASTVERSION>] <homepage> <description>\n"
-
- search_field = package_name.count('/') > 0 ? "--category-name" : "--name"
- search_value = package_name
-
- begin
- update_eix if !FileUtils.uptodate?("/var/cache/eix", %w{/usr/bin/eix /usr/portage/metadata/timestamp})
-
- search_output = nil
- Puppet::Util::Execution.withenv :LASTVERSION => version_format do
- search_output = eix "--nocolor", "--pure-packages", "--stable", "--format", search_format, "--exact", search_field, search_value
- end
-
- packages = []
- search_output.each do |search_result|
- match = result_format.match(search_result)
-
- if match
- package = {}
- result_fields.zip(match.captures) do |field, value|
- package[field] = value unless !value or value.empty?
- end
- package[:ensure] = package[:ensure] ? package[:ensure] : :absent
- packages << package
- end
- end
-
- case packages.size
- when 0
- not_found_value = "#{@resource[:category] ? @resource[:category] : "<unspecified category>"}/#{@resource[:name]}"
- raise Puppet::Error.new("No package found with the specified name [#{not_found_value}]")
- when 1
- return packages[0]
- else
- raise Puppet::Error.new("More than one package with the specified name [#{search_value}], please use the category parameter to disambiguate")
- end
- rescue Puppet::ExecutionFailure => detail
- raise Puppet::Error.new(detail)
+ emerge name
+ end
+
+ # The common package name format.
+ def package_name
+ @resource[:category] ? "#{@resource[:category]}/#{@resource[:name]}" : @resource[:name]
+ end
+
+ def uninstall
+ emerge "--unmerge", package_name
+ end
+
+ def update
+ self.install
+ end
+
+ def query
+ result_format = /^(\S+)\s+(\S+)\s+\[(\S*)\]\s+\[(\S+)\]\s+(\S+)\s+(.*)$/
+ result_fields = [:category, :name, :ensure, :version_available, :vendor, :description]
+
+ version_format = "{last}<version>{}"
+ search_format = "<category> <name> [<installedversions:LASTVERSION>] [<bestversion:LASTVERSION>] <homepage> <description>\n"
+
+ search_field = package_name.count('/') > 0 ? "--category-name" : "--name"
+ search_value = package_name
+
+ begin
+ update_eix if !FileUtils.uptodate?("/var/cache/eix", %w{/usr/bin/eix /usr/portage/metadata/timestamp})
+
+ search_output = nil
+ Puppet::Util::Execution.withenv :LASTVERSION => version_format do
+ search_output = eix "--nocolor", "--pure-packages", "--stable", "--format", search_format, "--exact", search_field, search_value
+ end
+
+ packages = []
+ search_output.each do |search_result|
+ match = result_format.match(search_result)
+
+ if match
+ package = {}
+ result_fields.zip(match.captures) do |field, value|
+ package[field] = value unless !value or value.empty?
+ end
+ package[:ensure] = package[:ensure] ? package[:ensure] : :absent
+ packages << package
end
+ end
+
+ case packages.size
+ when 0
+ not_found_value = "#{@resource[:category] ? @resource[:category] : "<unspecified category>"}/#{@resource[:name]}"
+ raise Puppet::Error.new("No package found with the specified name [#{not_found_value}]")
+ when 1
+ return packages[0]
+ else
+ raise Puppet::Error.new("More than one package with the specified name [#{search_value}], please use the category parameter to disambiguate")
+ end
+ rescue Puppet::ExecutionFailure => detail
+ raise Puppet::Error.new(detail)
end
+ end
- def latest
- self.query[:version_available]
- end
+ def latest
+ self.query[:version_available]
+ end
end
diff --git a/lib/puppet/provider/package/ports.rb b/lib/puppet/provider/package/ports.rb
index 1b8f0fb..c802092 100755
--- a/lib/puppet/provider/package/ports.rb
+++ b/lib/puppet/provider/package/ports.rb
@@ -1,95 +1,95 @@
Puppet::Type.type(:package).provide :ports, :parent => :freebsd, :source => :freebsd do
- desc "Support for FreeBSD's ports. Again, this still mixes packages and ports."
+ desc "Support for FreeBSD's ports. Again, this still mixes packages and ports."
- commands :portupgrade => "/usr/local/sbin/portupgrade",
- :portversion => "/usr/local/sbin/portversion",
- :portuninstall => "/usr/local/sbin/pkg_deinstall",
- :portinfo => "/usr/sbin/pkg_info"
+ commands :portupgrade => "/usr/local/sbin/portupgrade",
+ :portversion => "/usr/local/sbin/portversion",
+ :portuninstall => "/usr/local/sbin/pkg_deinstall",
+ :portinfo => "/usr/sbin/pkg_info"
- defaultfor :operatingsystem => :freebsd
+ defaultfor :operatingsystem => :freebsd
- # I hate ports
- %w{INTERACTIVE UNAME}.each do |var|
- ENV.delete(var) if ENV.include?(var)
- end
+ # I hate ports
+ %w{INTERACTIVE UNAME}.each do |var|
+ ENV.delete(var) if ENV.include?(var)
+ end
- def install
- # -N: install if the package is missing, otherwise upgrade
- # -M: yes, we're a batch, so don't ask any questions
- cmd = %w{-N -M BATCH=yes} << @resource[:name]
+ def install
+ # -N: install if the package is missing, otherwise upgrade
+ # -M: yes, we're a batch, so don't ask any questions
+ cmd = %w{-N -M BATCH=yes} << @resource[:name]
- output = portupgrade(*cmd)
- if output =~ /\*\* No such /
- raise Puppet::ExecutionFailure, "Could not find package #{@resource[:name]}"
- end
+ output = portupgrade(*cmd)
+ if output =~ /\*\* No such /
+ raise Puppet::ExecutionFailure, "Could not find package #{@resource[:name]}"
end
+ end
- # If there are multiple packages, we only use the last one
- def latest
- cmd = ["-v", @resource[:name]]
+ # If there are multiple packages, we only use the last one
+ def latest
+ cmd = ["-v", @resource[:name]]
- begin
- output = portversion(*cmd)
- rescue Puppet::ExecutionFailure
- raise Puppet::Error.new(output)
- end
- line = output.split("\n").pop
+ begin
+ output = portversion(*cmd)
+ rescue Puppet::ExecutionFailure
+ raise Puppet::Error.new(output)
+ end
+ line = output.split("\n").pop
- unless line =~ /^(\S+)\s+(\S)\s+(.+)$/
- # There's no "latest" version, so just return a placeholder
- return :latest
- end
+ unless line =~ /^(\S+)\s+(\S)\s+(.+)$/
+ # There's no "latest" version, so just return a placeholder
+ return :latest
+ end
- pkgstuff = $1
- match = $2
- info = $3
+ pkgstuff = $1
+ match = $2
+ info = $3
- unless pkgstuff =~ /^(\S+)-([^-\s]+)$/
- raise Puppet::Error,
- "Could not match package info '#{pkgstuff}'"
- end
+ unless pkgstuff =~ /^(\S+)-([^-\s]+)$/
+ raise Puppet::Error,
+ "Could not match package info '#{pkgstuff}'"
+ end
- name, version = $1, $2
+ name, version = $1, $2
- if match == "=" or match == ">"
- # we're up to date or more recent
- return version
- end
+ if match == "=" or match == ">"
+ # we're up to date or more recent
+ return version
+ end
- # Else, we need to be updated; we need to pull out the new version
+ # Else, we need to be updated; we need to pull out the new version
- unless info =~ /\((\w+) has (.+)\)/
- raise Puppet::Error,
- "Could not match version info '#{info}'"
- end
+ unless info =~ /\((\w+) has (.+)\)/
+ raise Puppet::Error,
+ "Could not match version info '#{info}'"
+ end
- source, newversion = $1, $2
+ source, newversion = $1, $2
- debug "Newer version in #{source}"
- newversion
- end
+ debug "Newer version in #{source}"
+ newversion
+ end
- def query
- # support portorigin_glob such as "mail/postfix"
- name = self.name
- if name =~ /\//
- name = self.name.split(/\//).slice(1)
- end
- self.class.instances.each do |instance|
- if instance.name == name
- return instance.properties
- end
- end
-
- nil
+ def query
+ # support portorigin_glob such as "mail/postfix"
+ name = self.name
+ if name =~ /\//
+ name = self.name.split(/\//).slice(1)
end
-
- def uninstall
- portuninstall @resource[:name]
+ self.class.instances.each do |instance|
+ if instance.name == name
+ return instance.properties
+ end
end
- def update
- install
- end
+ nil
+ end
+
+ def uninstall
+ portuninstall @resource[:name]
+ end
+
+ def update
+ install
+ end
end
diff --git a/lib/puppet/provider/package/portupgrade.rb b/lib/puppet/provider/package/portupgrade.rb
index 08cb52f..45e35bb 100644
--- a/lib/puppet/provider/package/portupgrade.rb
+++ b/lib/puppet/provider/package/portupgrade.rb
@@ -3,248 +3,248 @@
require 'puppet/provider/package'
Puppet::Type.type(:package).provide :portupgrade, :parent => Puppet::Provider::Package do
- include Puppet::Util::Execution
+ include Puppet::Util::Execution
- desc "Support for FreeBSD's ports using the portupgrade ports management software.
- Use the port's full origin as the resource name. eg (ports-mgmt/portupgrade)
- for the portupgrade port."
+ desc "Support for FreeBSD's ports using the portupgrade ports management software.
+ Use the port's full origin as the resource name. eg (ports-mgmt/portupgrade)
+ for the portupgrade port."
- ## has_features is usually autodetected based on defs below.
- # has_features :installable, :uninstallable, :upgradeable
+ ## has_features is usually autodetected based on defs below.
+ # has_features :installable, :uninstallable, :upgradeable
- commands :portupgrade => "/usr/local/sbin/portupgrade",
- :portinstall => "/usr/local/sbin/portinstall",
- :portversion => "/usr/local/sbin/portversion",
- :portuninstall => "/usr/local/sbin/pkg_deinstall",
- :portinfo => "/usr/sbin/pkg_info"
+ commands :portupgrade => "/usr/local/sbin/portupgrade",
+ :portinstall => "/usr/local/sbin/portinstall",
+ :portversion => "/usr/local/sbin/portversion",
+ :portuninstall => "/usr/local/sbin/pkg_deinstall",
+ :portinfo => "/usr/sbin/pkg_info"
- ## Activate this only once approved by someone important.
- # defaultfor :operatingsystem => :freebsd
+ ## Activate this only once approved by someone important.
+ # defaultfor :operatingsystem => :freebsd
- # Remove unwanted environment variables.
- %w{INTERACTIVE UNAME}.each do |var|
- if ENV.include?(var)
- ENV.delete(var)
- end
- end
-
- ######## instances sub command (builds the installed packages list)
-
- def self.instances
- Puppet.debug "portupgrade.rb Building packages list from installed ports"
-
- # regex to match output from pkg_info
- regex = %r{^(\S+)-([^-\s]+):(\S+)$}
- # Corresponding field names
- fields = [:portname, :ensure, :portorigin]
- # define Temporary hash used, packages array of hashes
- hash = Hash.new
- packages = []
-
- # exec command
- cmdline = ["-aoQ"]
- begin
- output = portinfo(*cmdline)
- rescue Puppet::ExecutionFailure
- raise Puppet::Error.new(output)
- return nil
- end
+ # Remove unwanted environment variables.
+ %w{INTERACTIVE UNAME}.each do |var|
+ if ENV.include?(var)
+ ENV.delete(var)
+ end
+ end
+
+ ######## instances sub command (builds the installed packages list)
+
+ def self.instances
+ Puppet.debug "portupgrade.rb Building packages list from installed ports"
+
+ # regex to match output from pkg_info
+ regex = %r{^(\S+)-([^-\s]+):(\S+)$}
+ # Corresponding field names
+ fields = [:portname, :ensure, :portorigin]
+ # define Temporary hash used, packages array of hashes
+ hash = Hash.new
+ packages = []
+
+ # exec command
+ cmdline = ["-aoQ"]
+ begin
+ output = portinfo(*cmdline)
+ rescue Puppet::ExecutionFailure
+ raise Puppet::Error.new(output)
+ return nil
+ end
- # split output and match it and populate temp hash
- output.split("\n").each { |data|
- # reset hash to nil for each line
- hash.clear
- if match = regex.match(data)
- # Output matched regex
- fields.zip(match.captures) { |field, value|
- hash[field] = value
- }
-
- # populate the actual :name field from the :portorigin
- # Set :provider to this object name
- hash[:name] = hash[:portorigin]
- hash[:provider] = self.name
-
- # Add to the full packages listing
- packages << new(hash)
-
- else
- # unrecognised output from pkg_info
- Puppet.debug "portupgrade.Instances() - unable to match output: #{data}"
- end
- }
-
- # return the packages array of hashes
- return packages
+ # split output and match it and populate temp hash
+ output.split("\n").each { |data|
+ # reset hash to nil for each line
+ hash.clear
+ if match = regex.match(data)
+ # Output matched regex
+ fields.zip(match.captures) { |field, value|
+ hash[field] = value
+ }
+
+ # populate the actual :name field from the :portorigin
+ # Set :provider to this object name
+ hash[:name] = hash[:portorigin]
+ hash[:provider] = self.name
+
+ # Add to the full packages listing
+ packages << new(hash)
+
+ else
+ # unrecognised output from pkg_info
+ Puppet.debug "portupgrade.Instances() - unable to match output: #{data}"
+ end
+ }
- end
+ # return the packages array of hashes
+ return packages
- ######## Installation sub command
+ end
- def install
- Puppet.debug "portupgrade.install() - Installation call on #{@resource[:name]}"
- # -M: yes, we're a batch, so don't ask any questions
- cmdline = ["-M BATCH=yes", @resource[:name]]
+ ######## Installation sub command
- # FIXME: it's possible that portinstall prompts for data so locks up.
- begin
- output = portinstall(*cmdline)
- rescue Puppet::ExecutionFailure
- raise Puppet::Error.new(output)
- end
+ def install
+ Puppet.debug "portupgrade.install() - Installation call on #{@resource[:name]}"
+ # -M: yes, we're a batch, so don't ask any questions
+ cmdline = ["-M BATCH=yes", @resource[:name]]
- if output =~ /\*\* No such /
- raise Puppet::ExecutionFailure, "Could not find package #{@resource[:name]}"
- end
+ # FIXME: it's possible that portinstall prompts for data so locks up.
+ begin
+ output = portinstall(*cmdline)
+ rescue Puppet::ExecutionFailure
+ raise Puppet::Error.new(output)
+ end
- # No return code required, so do nil to be clean
- return nil
+ if output =~ /\*\* No such /
+ raise Puppet::ExecutionFailure, "Could not find package #{@resource[:name]}"
end
- ######## Latest subcommand (returns the latest version available, or current version if installed is latest)
+ # No return code required, so do nil to be clean
+ return nil
+ end
- def latest
- Puppet.debug "portupgrade.latest() - Latest check called on #{@resource[:name]}"
- # search for latest version available, or return current version.
- # cmdline = "portversion -v <portorigin>", returns "<portname> <code> <stuff>"
- # or "** No matching package found: <portname>"
- cmdline = ["-v", @resource[:name]]
+ ######## Latest subcommand (returns the latest version available, or current version if installed is latest)
- begin
- output = portversion(*cmdline)
- rescue Puppet::ExecutionFailure
- raise Puppet::Error.new(output)
- end
+ def latest
+ Puppet.debug "portupgrade.latest() - Latest check called on #{@resource[:name]}"
+ # search for latest version available, or return current version.
+ # cmdline = "portversion -v <portorigin>", returns "<portname> <code> <stuff>"
+ # or "** No matching package found: <portname>"
+ cmdline = ["-v", @resource[:name]]
- # Check: output format.
- if output =~ /^\S+-([^-\s]+)\s+(\S)\s+(.*)/
- # $1 = installed version, $2 = comparison, $3 other data
- # latest installed
- installedversion = $1
- comparison = $2
- otherdata = $3
-
- # Only return a new version number when it's clear that there is a new version
- # all others return the current version so no unexpected 'upgrades' occur.
- case comparison
- when "=", ">"
- Puppet.debug "portupgrade.latest() - Installed package is latest (#{installedversion})"
- return installedversion
- when "<"
- # "portpkg-1.7_5 < needs updating (port has 1.14)"
- # "portpkg-1.7_5 < needs updating (port has 1.14) (=> 'newport/pkg')
- if otherdata =~ /\(port has (\S+)\)/
- newversion = $1
- Puppet.debug "portupgrade.latest() - Installed version needs updating to (#{newversion})"
- return newversion
- else
- Puppet.debug "portupgrade.latest() - Unable to determine new version from (#{otherdata})"
- return installedversion
- end
- when "?", "!", "#"
- Puppet.debug "portupgrade.latest() - Comparison Error reported from portversion (#{output})"
- return installedversion
- else
- Puppet.debug "portupgrade.latest() - Unknown code from portversion output (#{output})"
- return installedversion
- end
+ begin
+ output = portversion(*cmdline)
+ rescue Puppet::ExecutionFailure
+ raise Puppet::Error.new(output)
+ end
+ # Check: output format.
+ if output =~ /^\S+-([^-\s]+)\s+(\S)\s+(.*)/
+ # $1 = installed version, $2 = comparison, $3 other data
+ # latest installed
+ installedversion = $1
+ comparison = $2
+ otherdata = $3
+
+ # Only return a new version number when it's clear that there is a new version
+ # all others return the current version so no unexpected 'upgrades' occur.
+ case comparison
+ when "=", ">"
+ Puppet.debug "portupgrade.latest() - Installed package is latest (#{installedversion})"
+ return installedversion
+ when "<"
+ # "portpkg-1.7_5 < needs updating (port has 1.14)"
+ # "portpkg-1.7_5 < needs updating (port has 1.14) (=> 'newport/pkg')
+ if otherdata =~ /\(port has (\S+)\)/
+ newversion = $1
+ Puppet.debug "portupgrade.latest() - Installed version needs updating to (#{newversion})"
+ return newversion
else
- # error: output not parsed correctly, error out with nil.
- # Seriously - this section should never be called in a perfect world.
- # as verification that the port is installed has already happened in query.
- if output =~ /^\*\* No matching package /
- raise Puppet::ExecutionFailure, "Could not find package #{@resource[:name]}"
- else
- # Any other error (dump output to log)
- raise Puppet::ExecutionFailure, "Unexpected output from portversion: #{output}"
- end
-
- # Just in case we still are running, return nil
- return nil
+ Puppet.debug "portupgrade.latest() - Unable to determine new version from (#{otherdata})"
+ return installedversion
end
+ when "?", "!", "#"
+ Puppet.debug "portupgrade.latest() - Comparison Error reported from portversion (#{output})"
+ return installedversion
+ else
+ Puppet.debug "portupgrade.latest() - Unknown code from portversion output (#{output})"
+ return installedversion
+ end
- # At this point normal operation has finished and we shouldn't have been called.
- # Error out and let the admin deal with it.
- raise Puppet::Error, "portversion.latest() - fatal error with portversion: #{output}"
- return nil
+ else
+ # error: output not parsed correctly, error out with nil.
+ # Seriously - this section should never be called in a perfect world.
+ # as verification that the port is installed has already happened in query.
+ if output =~ /^\*\* No matching package /
+ raise Puppet::ExecutionFailure, "Could not find package #{@resource[:name]}"
+ else
+ # Any other error (dump output to log)
+ raise Puppet::ExecutionFailure, "Unexpected output from portversion: #{output}"
+ end
+ # Just in case we still are running, return nil
+ return nil
end
- ###### Query subcommand - return a hash of details if exists, or nil if it doesn't.
- # Used to make sure the package is installed
+ # At this point normal operation has finished and we shouldn't have been called.
+ # Error out and let the admin deal with it.
+ raise Puppet::Error, "portversion.latest() - fatal error with portversion: #{output}"
+ return nil
- def query
- Puppet.debug "portupgrade.query() - Called on #{@resource[:name]}"
+ end
- cmdline = ["-qO", @resource[:name]]
- begin
- output = portinfo(*cmdline)
- rescue Puppet::ExecutionFailure
- raise Puppet::Error.new(output)
- end
+ ###### Query subcommand - return a hash of details if exists, or nil if it doesn't.
+ # Used to make sure the package is installed
- # Check: if output isn't in the right format, return nil
- if output =~ /^(\S+)-([^-\s]+)/
- # Fill in the details
- hash = Hash.new
- hash[:portorigin] = self.name
- hash[:portname] = $1
- hash[:ensure] = $2
-
- # If more details are required, then we can do another pkg_info query here
- # and parse out that output and add to the hash
-
- # return the hash to the caller
- return hash
- else
- Puppet.debug "portupgrade.query() - package (#{@resource[:name]}) not installed"
- return nil
- end
+ def query
+ Puppet.debug "portupgrade.query() - Called on #{@resource[:name]}"
+ cmdline = ["-qO", @resource[:name]]
+ begin
+ output = portinfo(*cmdline)
+ rescue Puppet::ExecutionFailure
+ raise Puppet::Error.new(output)
end
- ####### Uninstall command
+ # Check: if output isn't in the right format, return nil
+ if output =~ /^(\S+)-([^-\s]+)/
+ # Fill in the details
+ hash = Hash.new
+ hash[:portorigin] = self.name
+ hash[:portname] = $1
+ hash[:ensure] = $2
+
+ # If more details are required, then we can do another pkg_info query here
+ # and parse out that output and add to the hash
+
+ # return the hash to the caller
+ return hash
+ else
+ Puppet.debug "portupgrade.query() - package (#{@resource[:name]}) not installed"
+ return nil
+ end
- def uninstall
- Puppet.debug "portupgrade.uninstall() - called on #{@resource[:name]}"
- # Get full package name from port origin to uninstall with
- cmdline = ["-qO", @resource[:name]]
- begin
- output = portinfo(*cmdline)
- rescue Puppet::ExecutionFailure
- raise Puppet::Error.new(output)
- end
+ end
- if output =~ /^(\S+)/
- # output matches, so uninstall it
- portuninstall $1
- end
+ ####### Uninstall command
+ def uninstall
+ Puppet.debug "portupgrade.uninstall() - called on #{@resource[:name]}"
+ # Get full package name from port origin to uninstall with
+ cmdline = ["-qO", @resource[:name]]
+ begin
+ output = portinfo(*cmdline)
+ rescue Puppet::ExecutionFailure
+ raise Puppet::Error.new(output)
end
- ######## Update/upgrade command
+ if output =~ /^(\S+)/
+ # output matches, so uninstall it
+ portuninstall $1
+ end
- def update
- Puppet.debug "portupgrade.update() - called on (#{@resource[:name]})"
+ end
- cmdline = ["-qO", @resource[:name]]
- begin
- output = portinfo(*cmdline)
- rescue Puppet::ExecutionFailure
- raise Puppet::Error.new(output)
- end
+ ######## Update/upgrade command
- if output =~ /^(\S+)/
- # output matches, so upgrade the software
- cmdline = ["-M BATCH=yes", $1]
- begin
- output = portupgrade(*cmdline)
- rescue Puppet::ExecutionFailure
- raise Puppet::Error.new(output)
- end
- end
+ def update
+ Puppet.debug "portupgrade.update() - called on (#{@resource[:name]})"
+
+ cmdline = ["-qO", @resource[:name]]
+ begin
+ output = portinfo(*cmdline)
+ rescue Puppet::ExecutionFailure
+ raise Puppet::Error.new(output)
+ end
+
+ if output =~ /^(\S+)/
+ # output matches, so upgrade the software
+ cmdline = ["-M BATCH=yes", $1]
+ begin
+ output = portupgrade(*cmdline)
+ rescue Puppet::ExecutionFailure
+ raise Puppet::Error.new(output)
+ end
end
+ end
## EOF
end
diff --git a/lib/puppet/provider/package/rpm.rb b/lib/puppet/provider/package/rpm.rb
index cabdd1b..d33a4f2 100755
--- a/lib/puppet/provider/package/rpm.rb
+++ b/lib/puppet/provider/package/rpm.rb
@@ -1,132 +1,132 @@
require 'puppet/provider/package'
# RPM packaging. Should work anywhere that has rpm installed.
Puppet::Type.type(:package).provide :rpm, :source => :rpm, :parent => Puppet::Provider::Package do
- desc "RPM packaging support; should work anywhere with a working ``rpm``
- binary."
-
- has_feature :versionable
-
- # The query format by which we identify installed packages
- NEVRAFORMAT = "%{NAME} %|EPOCH?{%{EPOCH}}:{0}| %{VERSION} %{RELEASE} %{ARCH}"
- NEVRA_FIELDS = [:name, :epoch, :version, :release, :arch]
-
- commands :rpm => "rpm"
-
- if command('rpm')
- confine :true => begin
- rpm('--version')
- rescue Puppet::ExecutionFailure
- false
- else
- true
- end
+ desc "RPM packaging support; should work anywhere with a working ``rpm``
+ binary."
+
+ has_feature :versionable
+
+ # The query format by which we identify installed packages
+ NEVRAFORMAT = "%{NAME} %|EPOCH?{%{EPOCH}}:{0}| %{VERSION} %{RELEASE} %{ARCH}"
+ NEVRA_FIELDS = [:name, :epoch, :version, :release, :arch]
+
+ commands :rpm => "rpm"
+
+ if command('rpm')
+ confine :true => begin
+ rpm('--version')
+ rescue Puppet::ExecutionFailure
+ false
+ else
+ true
+ end
+ end
+
+ def self.instances
+ packages = []
+
+ # rpm < 4.1 don't support --nosignature
+ output = rpm "--version"
+ sig = "--nosignature"
+ if output =~ /RPM version (([123].*)|(4\.0.*))/
+ sig = ""
end
- def self.instances
- packages = []
-
- # rpm < 4.1 don't support --nosignature
- output = rpm "--version"
- sig = "--nosignature"
- if output =~ /RPM version (([123].*)|(4\.0.*))/
- sig = ""
- end
-
- # list out all of the packages
- begin
- execpipe("#{command(:rpm)} -qa #{sig} --nodigest --qf '#{NEVRAFORMAT}\n'") { |process|
- # now turn each returned line into a package object
- process.each { |line|
- hash = nevra_to_hash(line)
- packages << new(hash)
- }
- }
- rescue Puppet::ExecutionFailure
- raise Puppet::Error, "Failed to list packages"
- end
-
- packages
+ # list out all of the packages
+ begin
+ execpipe("#{command(:rpm)} -qa #{sig} --nodigest --qf '#{NEVRAFORMAT}\n'") { |process|
+ # now turn each returned line into a package object
+ process.each { |line|
+ hash = nevra_to_hash(line)
+ packages << new(hash)
+ }
+ }
+ rescue Puppet::ExecutionFailure
+ raise Puppet::Error, "Failed to list packages"
end
- # Find the fully versioned package name and the version alone. Returns
- # a hash with entries :instance => fully versioned package name, and
- # :ensure => version-release
- def query
- #NOTE: Prior to a fix for issue 1243, this method potentially returned a cached value
- #IF YOU CALL THIS METHOD, IT WILL CALL RPM
- #Use get(:property) to check if cached values are available
- cmd = ["-q", @resource[:name], "--nosignature", "--nodigest", "--qf", "#{NEVRAFORMAT}\n"]
-
- begin
- output = rpm(*cmd)
- rescue Puppet::ExecutionFailure
- return nil
- end
-
- # FIXME: We could actually be getting back multiple packages
- # for multilib
- @property_hash.update(self.class.nevra_to_hash(output))
-
- @property_hash.dup
+ packages
+ end
+
+ # Find the fully versioned package name and the version alone. Returns
+ # a hash with entries :instance => fully versioned package name, and
+ # :ensure => version-release
+ def query
+ #NOTE: Prior to a fix for issue 1243, this method potentially returned a cached value
+ #IF YOU CALL THIS METHOD, IT WILL CALL RPM
+ #Use get(:property) to check if cached values are available
+ cmd = ["-q", @resource[:name], "--nosignature", "--nodigest", "--qf", "#{NEVRAFORMAT}\n"]
+
+ begin
+ output = rpm(*cmd)
+ rescue Puppet::ExecutionFailure
+ return nil
end
- # Here we just retrieve the version from the file specified in the source.
- def latest
- unless source = @resource[:source]
- @resource.fail "RPMs must specify a package source"
- end
+ # FIXME: We could actually be getting back multiple packages
+ # for multilib
+ @property_hash.update(self.class.nevra_to_hash(output))
- cmd = [command(:rpm), "-q", "--qf", "#{NEVRAFORMAT}\n", "-p", "#{@resource[:source]}"]
- h = self.class.nevra_to_hash(execfail(cmd, Puppet::Error))
- h[:ensure]
- end
+ @property_hash.dup
+ end
- def install
- source = nil
- unless source = @resource[:source]
- @resource.fail "RPMs must specify a package source"
- end
- # RPM gets pissy if you try to install an already
- # installed package
- if @resource.should(:ensure) == @property_hash[:ensure] or
- @resource.should(:ensure) == :latest && @property_hash[:ensure] == latest
- return
- end
-
- flag = "-i"
- flag = "-U" if @property_hash[:ensure] and @property_hash[:ensure] != :absent
-
- rpm flag, "--oldpackage", source
+ # Here we just retrieve the version from the file specified in the source.
+ def latest
+ unless source = @resource[:source]
+ @resource.fail "RPMs must specify a package source"
end
- def uninstall
- query unless get(:arch)
- nvr = "#{get(:name)}-#{get(:version)}-#{get(:release)}"
- arch = ".#{get(:arch)}"
- # If they specified an arch in the manifest, erase that Otherwise,
- # erase the arch we got back from the query. If multiple arches are
- # installed and only the package name is specified (without the
- # arch), this will uninstall all of them on successive runs of the
- # client, one after the other
- if @resource[:name][-arch.size, arch.size] == arch
- nvr += arch
- else
- nvr += ".#{get(:arch)}"
- end
- rpm "-e", nvr
- end
+ cmd = [command(:rpm), "-q", "--qf", "#{NEVRAFORMAT}\n", "-p", "#{@resource[:source]}"]
+ h = self.class.nevra_to_hash(execfail(cmd, Puppet::Error))
+ h[:ensure]
+ end
- def update
- self.install
+ def install
+ source = nil
+ unless source = @resource[:source]
+ @resource.fail "RPMs must specify a package source"
+ end
+ # RPM gets pissy if you try to install an already
+ # installed package
+ if @resource.should(:ensure) == @property_hash[:ensure] or
+ @resource.should(:ensure) == :latest && @property_hash[:ensure] == latest
+ return
end
- def self.nevra_to_hash(line)
- line.chomp!
- hash = {}
- NEVRA_FIELDS.zip(line.split) { |f, v| hash[f] = v }
- hash[:provider] = self.name
- hash[:ensure] = "#{hash[:version]}-#{hash[:release]}"
- hash
+ flag = "-i"
+ flag = "-U" if @property_hash[:ensure] and @property_hash[:ensure] != :absent
+
+ rpm flag, "--oldpackage", source
+ end
+
+ def uninstall
+ query unless get(:arch)
+ nvr = "#{get(:name)}-#{get(:version)}-#{get(:release)}"
+ arch = ".#{get(:arch)}"
+ # If they specified an arch in the manifest, erase that Otherwise,
+ # erase the arch we got back from the query. If multiple arches are
+ # installed and only the package name is specified (without the
+ # arch), this will uninstall all of them on successive runs of the
+ # client, one after the other
+ if @resource[:name][-arch.size, arch.size] == arch
+ nvr += arch
+ else
+ nvr += ".#{get(:arch)}"
end
+ rpm "-e", nvr
+ end
+
+ def update
+ self.install
+ end
+
+ def self.nevra_to_hash(line)
+ line.chomp!
+ hash = {}
+ NEVRA_FIELDS.zip(line.split) { |f, v| hash[f] = v }
+ hash[:provider] = self.name
+ hash[:ensure] = "#{hash[:version]}-#{hash[:release]}"
+ hash
+ end
end
diff --git a/lib/puppet/provider/package/rug.rb b/lib/puppet/provider/package/rug.rb
index 227edc7..7028cc9 100644
--- a/lib/puppet/provider/package/rug.rb
+++ b/lib/puppet/provider/package/rug.rb
@@ -1,52 +1,52 @@
Puppet::Type.type(:package).provide :rug, :parent => :rpm do
- desc "Support for suse ``rug`` package manager."
-
- has_feature :versionable
-
- commands :rug => "/usr/bin/rug"
- commands :rpm => "rpm"
- defaultfor :operatingsystem => [:suse, :sles]
- confine :operatingsystem => [:suse, :sles]
-
- # Install a package using 'rug'.
- def install
- should = @resource.should(:ensure)
- self.debug "Ensuring => #{should}"
- wanted = @resource[:name]
-
- # XXX: We don't actually deal with epochs here.
- case should
- when true, false, Symbol
- # pass
- else
- # Add the package version
- wanted += "-#{should}"
- end
- output = rug "--quiet", :install, "-y", wanted
-
- unless self.query
- raise Puppet::ExecutionFailure.new(
- "Could not find package #{self.name}"
- )
- end
+ desc "Support for suse ``rug`` package manager."
+
+ has_feature :versionable
+
+ commands :rug => "/usr/bin/rug"
+ commands :rpm => "rpm"
+ defaultfor :operatingsystem => [:suse, :sles]
+ confine :operatingsystem => [:suse, :sles]
+
+ # Install a package using 'rug'.
+ def install
+ should = @resource.should(:ensure)
+ self.debug "Ensuring => #{should}"
+ wanted = @resource[:name]
+
+ # XXX: We don't actually deal with epochs here.
+ case should
+ when true, false, Symbol
+ # pass
+ else
+ # Add the package version
+ wanted += "-#{should}"
end
+ output = rug "--quiet", :install, "-y", wanted
- # What's the latest package version available?
- def latest
- #rug can only get a list of *all* available packages?
- output = rug "list-updates"
-
- if output =~ /#{Regexp.escape @resource[:name]}\s*\|\s*([^\s\|]+)/
- return $1
- else
- # rug didn't find updates, pretend the current
- # version is the latest
- return @property_hash[:ensure]
- end
+ unless self.query
+ raise Puppet::ExecutionFailure.new(
+ "Could not find package #{self.name}"
+ )
end
-
- def update
- # rug install can be used for update, too
- self.install
+ end
+
+ # What's the latest package version available?
+ def latest
+ #rug can only get a list of *all* available packages?
+ output = rug "list-updates"
+
+ if output =~ /#{Regexp.escape @resource[:name]}\s*\|\s*([^\s\|]+)/
+ return $1
+ else
+ # rug didn't find updates, pretend the current
+ # version is the latest
+ return @property_hash[:ensure]
end
+ end
+
+ def update
+ # rug install can be used for update, too
+ self.install
+ end
end
diff --git a/lib/puppet/provider/package/sun.rb b/lib/puppet/provider/package/sun.rb
index c98636e..05bbe97 100755
--- a/lib/puppet/provider/package/sun.rb
+++ b/lib/puppet/provider/package/sun.rb
@@ -3,153 +3,153 @@
require 'puppet/provider/package'
Puppet::Type.type(:package).provide :sun, :parent => Puppet::Provider::Package do
- desc "Sun's packaging system. Requires that you specify the source for
- the packages you're managing."
- commands :pkginfo => "/usr/bin/pkginfo",
- :pkgadd => "/usr/sbin/pkgadd",
- :pkgrm => "/usr/sbin/pkgrm"
-
- confine :operatingsystem => :solaris
-
- defaultfor :operatingsystem => :solaris
-
- def self.instances
- packages = []
- hash = {}
- names = {
- "PKGINST" => :name,
- "NAME" => nil,
- "CATEGORY" => :category,
- "ARCH" => :platform,
- "VERSION" => :ensure,
- "BASEDIR" => :root,
- "HOTLINE" => nil,
- "EMAIL" => nil,
- "VENDOR" => :vendor,
- "DESC" => :description,
- "PSTAMP" => nil,
- "INSTDATE" => nil,
- "STATUS" => nil,
- "FILES" => nil
- }
-
- cmd = "#{command(:pkginfo)} -l"
-
- # list out all of the packages
- execpipe(cmd) { |process|
- # we're using the long listing, so each line is a separate
- # piece of information
- process.each { |line|
- case line
- when /^$/
- hash[:provider] = :sun
-
- packages << new(hash)
- hash = {}
- when /\s*(\w+):\s+(.+)/
- name = $1
- value = $2
- if names.include?(name)
- hash[names[name]] = value unless names[name].nil?
- end
- when /\s+\d+.+/
- # nothing; we're ignoring the FILES info
- end
- }
- }
- packages
- end
-
- # Get info on a package, optionally specifying a device.
- def info2hash(device = nil)
- names = {
- "PKGINST" => :name,
- "NAME" => nil,
- "CATEGORY" => :category,
- "ARCH" => :platform,
- "VERSION" => :ensure,
- "BASEDIR" => :root,
- "HOTLINE" => nil,
- "EMAIL" => nil,
- "VSTOCK" => nil,
- "VENDOR" => :vendor,
- "DESC" => :description,
- "PSTAMP" => nil,
- "INSTDATE" => nil,
- "STATUS" => nil,
- "FILES" => nil
- }
-
- hash = {}
- cmd = "#{command(:pkginfo)} -l"
- cmd += " -d #{device}" if device
- cmd += " #{@resource[:name]}"
-
- begin
- # list out all of the packages
- execpipe(cmd) { |process|
- # we're using the long listing, so each line is a separate
- # piece of information
- process.readlines.each { |line|
- case line
- when /^$/ # ignore
- when /\s*([A-Z]+):\s+(.+)/
- name = $1
- value = $2
- if names.include?(name)
- hash[names[name]] = value unless names[name].nil?
- end
- when /\s+\d+.+/
- # nothing; we're ignoring the FILES info
- end
- }
- }
- return hash
- rescue Puppet::ExecutionFailure => detail
- return {:ensure => :absent} if detail.message =~ /information for "#{Regexp.escape(@resource[:name])}" was not found/
- puts detail.backtrace if Puppet[:trace]
- raise Puppet::Error, "Unable to get information about package #{@resource[:name]} because of: #{detail}"
+ desc "Sun's packaging system. Requires that you specify the source for
+ the packages you're managing."
+ commands :pkginfo => "/usr/bin/pkginfo",
+ :pkgadd => "/usr/sbin/pkgadd",
+ :pkgrm => "/usr/sbin/pkgrm"
+
+ confine :operatingsystem => :solaris
+
+ defaultfor :operatingsystem => :solaris
+
+ def self.instances
+ packages = []
+ hash = {}
+ names = {
+ "PKGINST" => :name,
+ "NAME" => nil,
+ "CATEGORY" => :category,
+ "ARCH" => :platform,
+ "VERSION" => :ensure,
+ "BASEDIR" => :root,
+ "HOTLINE" => nil,
+ "EMAIL" => nil,
+ "VENDOR" => :vendor,
+ "DESC" => :description,
+ "PSTAMP" => nil,
+ "INSTDATE" => nil,
+ "STATUS" => nil,
+ "FILES" => nil
+ }
+
+ cmd = "#{command(:pkginfo)} -l"
+
+ # list out all of the packages
+ execpipe(cmd) { |process|
+ # we're using the long listing, so each line is a separate
+ # piece of information
+ process.each { |line|
+ case line
+ when /^$/
+ hash[:provider] = :sun
+
+ packages << new(hash)
+ hash = {}
+ when /\s*(\w+):\s+(.+)/
+ name = $1
+ value = $2
+ if names.include?(name)
+ hash[names[name]] = value unless names[name].nil?
+ end
+ when /\s+\d+.+/
+ # nothing; we're ignoring the FILES info
end
+ }
+ }
+ packages
+ end
+
+ # Get info on a package, optionally specifying a device.
+ def info2hash(device = nil)
+ names = {
+ "PKGINST" => :name,
+ "NAME" => nil,
+ "CATEGORY" => :category,
+ "ARCH" => :platform,
+ "VERSION" => :ensure,
+ "BASEDIR" => :root,
+ "HOTLINE" => nil,
+ "EMAIL" => nil,
+ "VSTOCK" => nil,
+ "VENDOR" => :vendor,
+ "DESC" => :description,
+ "PSTAMP" => nil,
+ "INSTDATE" => nil,
+ "STATUS" => nil,
+ "FILES" => nil
+ }
+
+ hash = {}
+ cmd = "#{command(:pkginfo)} -l"
+ cmd += " -d #{device}" if device
+ cmd += " #{@resource[:name]}"
+
+ begin
+ # list out all of the packages
+ execpipe(cmd) { |process|
+ # we're using the long listing, so each line is a separate
+ # piece of information
+ process.readlines.each { |line|
+ case line
+ when /^$/ # ignore
+ when /\s*([A-Z]+):\s+(.+)/
+ name = $1
+ value = $2
+ if names.include?(name)
+ hash[names[name]] = value unless names[name].nil?
+ end
+ when /\s+\d+.+/
+ # nothing; we're ignoring the FILES info
+ end
+ }
+ }
+ return hash
+ rescue Puppet::ExecutionFailure => detail
+ return {:ensure => :absent} if detail.message =~ /information for "#{Regexp.escape(@resource[:name])}" was not found/
+ puts detail.backtrace if Puppet[:trace]
+ raise Puppet::Error, "Unable to get information about package #{@resource[:name]} because of: #{detail}"
end
+ end
- def install
- raise Puppet::Error, "Sun packages must specify a package source" unless @resource[:source]
- cmd = []
+ def install
+ raise Puppet::Error, "Sun packages must specify a package source" unless @resource[:source]
+ cmd = []
- cmd << "-a" << @resource[:adminfile] if @resource[:adminfile]
+ cmd << "-a" << @resource[:adminfile] if @resource[:adminfile]
- cmd << "-r" << @resource[:responsefile] if @resource[:responsefile]
+ cmd << "-r" << @resource[:responsefile] if @resource[:responsefile]
- cmd << "-d" << @resource[:source]
- cmd << "-n" << @resource[:name]
+ cmd << "-d" << @resource[:source]
+ cmd << "-n" << @resource[:name]
- pkgadd cmd
- end
+ pkgadd cmd
+ end
- # Retrieve the version from the current package file.
- def latest
- hash = info2hash(@resource[:source])
- hash[:ensure]
- end
+ # Retrieve the version from the current package file.
+ def latest
+ hash = info2hash(@resource[:source])
+ hash[:ensure]
+ end
- def query
- info2hash()
- end
+ def query
+ info2hash()
+ end
- def uninstall
- command = ["-n"]
+ def uninstall
+ command = ["-n"]
- command << "-a" << @resource[:adminfile] if @resource[:adminfile]
+ command << "-a" << @resource[:adminfile] if @resource[:adminfile]
- command << @resource[:name]
- pkgrm command
- end
+ command << @resource[:name]
+ pkgrm command
+ end
- # Remove the old package, and install the new one. This will probably
- # often fail.
- def update
- self.uninstall if (@property_hash[:ensure] || info2hash()[:ensure]) != :absent
- self.install
- end
+ # Remove the old package, and install the new one. This will probably
+ # often fail.
+ def update
+ self.uninstall if (@property_hash[:ensure] || info2hash()[:ensure]) != :absent
+ self.install
+ end
end
diff --git a/lib/puppet/provider/package/sunfreeware.rb b/lib/puppet/provider/package/sunfreeware.rb
index d7bcd09..53f03ed 100755
--- a/lib/puppet/provider/package/sunfreeware.rb
+++ b/lib/puppet/provider/package/sunfreeware.rb
@@ -1,11 +1,11 @@
# At this point, it's an exact copy of the Blastwave stuff.
Puppet::Type.type(:package).provide :sunfreeware, :parent => :blastwave, :source => :sun do
- desc "Package management using sunfreeware.com's ``pkg-get`` command on Solaris.
- At this point, support is exactly the same as ``blastwave`` support and
- has not actually been tested."
- commands :pkgget => "pkg-get"
+ desc "Package management using sunfreeware.com's ``pkg-get`` command on Solaris.
+ At this point, support is exactly the same as ``blastwave`` support and
+ has not actually been tested."
+ commands :pkgget => "pkg-get"
- confine :operatingsystem => :solaris
+ confine :operatingsystem => :solaris
end
diff --git a/lib/puppet/provider/package/up2date.rb b/lib/puppet/provider/package/up2date.rb
index 8780e7f..5ff32be 100644
--- a/lib/puppet/provider/package/up2date.rb
+++ b/lib/puppet/provider/package/up2date.rb
@@ -1,42 +1,42 @@
Puppet::Type.type(:package).provide :up2date, :parent => :rpm, :source => :rpm do
- desc "Support for Red Hat's proprietary ``up2date`` package update
- mechanism."
+ desc "Support for Red Hat's proprietary ``up2date`` package update
+ mechanism."
- commands :up2date => "/usr/sbin/up2date-nox"
+ commands :up2date => "/usr/sbin/up2date-nox"
- defaultfor :operatingsystem => [:redhat, :oel, :ovm],
- :lsbdistrelease => ["2.1", "3", "4"]
+ defaultfor :operatingsystem => [:redhat, :oel, :ovm],
+ :lsbdistrelease => ["2.1", "3", "4"]
- confine :operatingsystem => [:redhat, :oel, :ovm]
+ confine :operatingsystem => [:redhat, :oel, :ovm]
- # Install a package using 'up2date'.
- def install
- up2date "-u", @resource[:name]
+ # Install a package using 'up2date'.
+ def install
+ up2date "-u", @resource[:name]
- unless self.query
- raise Puppet::ExecutionFailure.new(
- "Could not find package #{self.name}"
- )
- end
+ unless self.query
+ raise Puppet::ExecutionFailure.new(
+ "Could not find package #{self.name}"
+ )
end
-
- # What's the latest package version available?
- def latest
- #up2date can only get a list of *all* available packages?
- output = up2date "--showall"
-
- if output =~ /^#{Regexp.escape @resource[:name]}-(\d+.*)\.\w+/
- return $1
- else
- # up2date didn't find updates, pretend the current
- # version is the latest
- return @property_hash[:ensure]
- end
+ end
+
+ # What's the latest package version available?
+ def latest
+ #up2date can only get a list of *all* available packages?
+ output = up2date "--showall"
+
+ if output =~ /^#{Regexp.escape @resource[:name]}-(\d+.*)\.\w+/
+ return $1
+ else
+ # up2date didn't find updates, pretend the current
+ # version is the latest
+ return @property_hash[:ensure]
end
+ end
- def update
- # Install in up2date can be used for update, too
- self.install
- end
+ def update
+ # Install in up2date can be used for update, too
+ self.install
+ end
end
diff --git a/lib/puppet/provider/package/urpmi.rb b/lib/puppet/provider/package/urpmi.rb
index a7732c4..88a17cc 100644
--- a/lib/puppet/provider/package/urpmi.rb
+++ b/lib/puppet/provider/package/urpmi.rb
@@ -1,60 +1,60 @@
Puppet::Type.type(:package).provide :urpmi, :parent => :rpm, :source => :rpm do
- desc "Support via ``urpmi``."
- commands :urpmi => "urpmi", :urpmq => "urpmq", :rpm => "rpm"
-
- if command('rpm')
- confine :true => begin
- rpm('-ql', 'rpm')
- rescue Puppet::ExecutionFailure
- false
- else
- true
- end
+ desc "Support via ``urpmi``."
+ commands :urpmi => "urpmi", :urpmq => "urpmq", :rpm => "rpm"
+
+ if command('rpm')
+ confine :true => begin
+ rpm('-ql', 'rpm')
+ rescue Puppet::ExecutionFailure
+ false
+ else
+ true
+ end
+ end
+
+ defaultfor :operatingsystem => [:mandriva, :mandrake]
+
+ has_feature :versionable
+
+ def install
+ should = @resource.should(:ensure)
+ self.debug "Ensuring => #{should}"
+ wanted = @resource[:name]
+
+ # XXX: We don't actually deal with epochs here.
+ case should
+ when true, false, Symbol
+ # pass
+ else
+ # Add the package version
+ wanted += "-#{should}"
end
- defaultfor :operatingsystem => [:mandriva, :mandrake]
+ output = urpmi "--auto", wanted
- has_feature :versionable
-
- def install
- should = @resource.should(:ensure)
- self.debug "Ensuring => #{should}"
- wanted = @resource[:name]
-
- # XXX: We don't actually deal with epochs here.
- case should
- when true, false, Symbol
- # pass
- else
- # Add the package version
- wanted += "-#{should}"
- end
-
- output = urpmi "--auto", wanted
-
- unless self.query
- raise Puppet::Error.new(
- "Could not find package #{self.name}"
- )
- end
+ unless self.query
+ raise Puppet::Error.new(
+ "Could not find package #{self.name}"
+ )
end
-
- # What's the latest package version available?
- def latest
- output = urpmq "-S", @resource[:name]
-
- if output =~ /^#{Regexp.escape @resource[:name]}\s+:\s+.*\(\s+(\S+)\s+\)/
- return $1
- else
- # urpmi didn't find updates, pretend the current
- # version is the latest
- return @resource[:ensure]
- end
+ end
+
+ # What's the latest package version available?
+ def latest
+ output = urpmq "-S", @resource[:name]
+
+ if output =~ /^#{Regexp.escape @resource[:name]}\s+:\s+.*\(\s+(\S+)\s+\)/
+ return $1
+ else
+ # urpmi didn't find updates, pretend the current
+ # version is the latest
+ return @resource[:ensure]
end
+ end
- def update
- # Install in urpmi can be used for update, too
- self.install
- end
+ def update
+ # Install in urpmi can be used for update, too
+ self.install
+ end
end
diff --git a/lib/puppet/provider/package/yum.rb b/lib/puppet/provider/package/yum.rb
index 17981f0..07f68dd 100755
--- a/lib/puppet/provider/package/yum.rb
+++ b/lib/puppet/provider/package/yum.rb
@@ -1,100 +1,100 @@
Puppet::Type.type(:package).provide :yum, :parent => :rpm, :source => :rpm do
- desc "Support via ``yum``."
-
- has_feature :versionable
-
- commands :yum => "yum", :rpm => "rpm", :python => "python"
-
- YUMHELPER = File::join(File::dirname(__FILE__), "yumhelper.py")
-
- attr_accessor :latest_info
-
- if command('rpm')
- confine :true => begin
- rpm('--version')
- rescue Puppet::ExecutionFailure
- false
- else
- true
- end
- end
-
- defaultfor :operatingsystem => [:fedora, :centos, :redhat]
-
- def self.prefetch(packages)
- raise Puppet::Error, "The yum provider can only be used as root" if Process.euid != 0
- super
- return unless packages.detect { |name, package| package.should(:ensure) == :latest }
-
- # collect our 'latest' info
- updates = {}
- python(YUMHELPER).each_line do |l|
- l.chomp!
- next if l.empty?
- if l[0,4] == "_pkg"
- hash = nevra_to_hash(l[5..-1])
- [hash[:name], "#{hash[:name]}.#{hash[:arch]}"].each do |n|
- updates[n] ||= []
- updates[n] << hash
- end
- end
- end
-
- # Add our 'latest' info to the providers.
- packages.each do |name, package|
- if info = updates[package[:name]]
- package.provider.latest_info = info[0]
- end
+ desc "Support via ``yum``."
+
+ has_feature :versionable
+
+ commands :yum => "yum", :rpm => "rpm", :python => "python"
+
+ YUMHELPER = File::join(File::dirname(__FILE__), "yumhelper.py")
+
+ attr_accessor :latest_info
+
+ if command('rpm')
+ confine :true => begin
+ rpm('--version')
+ rescue Puppet::ExecutionFailure
+ false
+ else
+ true
+ end
+ end
+
+ defaultfor :operatingsystem => [:fedora, :centos, :redhat]
+
+ def self.prefetch(packages)
+ raise Puppet::Error, "The yum provider can only be used as root" if Process.euid != 0
+ super
+ return unless packages.detect { |name, package| package.should(:ensure) == :latest }
+
+ # collect our 'latest' info
+ updates = {}
+ python(YUMHELPER).each_line do |l|
+ l.chomp!
+ next if l.empty?
+ if l[0,4] == "_pkg"
+ hash = nevra_to_hash(l[5..-1])
+ [hash[:name], "#{hash[:name]}.#{hash[:arch]}"].each do |n|
+ updates[n] ||= []
+ updates[n] << hash
end
+ end
end
- def install
- should = @resource.should(:ensure)
- self.debug "Ensuring => #{should}"
- wanted = @resource[:name]
-
- # XXX: We don't actually deal with epochs here.
- case should
- when true, false, Symbol
- # pass
- should = nil
- else
- # Add the package version
- wanted += "-#{should}"
- end
-
- output = yum "-d", "0", "-e", "0", "-y", :install, wanted
-
- is = self.query
- raise Puppet::Error, "Could not find package #{self.name}" unless is
-
- # FIXME: Should we raise an exception even if should == :latest
- # and yum updated us to a version other than @param_hash[:ensure] ?
- raise Puppet::Error, "Failed to update to version #{should}, got version #{is[:ensure]} instead" if should && should != is[:ensure]
+ # Add our 'latest' info to the providers.
+ packages.each do |name, package|
+ if info = updates[package[:name]]
+ package.provider.latest_info = info[0]
+ end
end
-
- # What's the latest package version available?
- def latest
- upd = latest_info
- unless upd.nil?
- # FIXME: there could be more than one update for a package
- # because of multiarch
- return "#{upd[:version]}-#{upd[:release]}"
- else
- # Yum didn't find updates, pretend the current
- # version is the latest
- raise Puppet::DevError, "Tried to get latest on a missing package" if properties[:ensure] == :absent
- return properties[:ensure]
- end
+ end
+
+ def install
+ should = @resource.should(:ensure)
+ self.debug "Ensuring => #{should}"
+ wanted = @resource[:name]
+
+ # XXX: We don't actually deal with epochs here.
+ case should
+ when true, false, Symbol
+ # pass
+ should = nil
+ else
+ # Add the package version
+ wanted += "-#{should}"
end
- def update
- # Install in yum can be used for update, too
- self.install
+ output = yum "-d", "0", "-e", "0", "-y", :install, wanted
+
+ is = self.query
+ raise Puppet::Error, "Could not find package #{self.name}" unless is
+
+ # FIXME: Should we raise an exception even if should == :latest
+ # and yum updated us to a version other than @param_hash[:ensure] ?
+ raise Puppet::Error, "Failed to update to version #{should}, got version #{is[:ensure]} instead" if should && should != is[:ensure]
+ end
+
+ # What's the latest package version available?
+ def latest
+ upd = latest_info
+ unless upd.nil?
+ # FIXME: there could be more than one update for a package
+ # because of multiarch
+ return "#{upd[:version]}-#{upd[:release]}"
+ else
+ # Yum didn't find updates, pretend the current
+ # version is the latest
+ raise Puppet::DevError, "Tried to get latest on a missing package" if properties[:ensure] == :absent
+ return properties[:ensure]
end
+ end
- def purge
- yum "-y", :erase, @resource[:name]
- end
+ def update
+ # Install in yum can be used for update, too
+ self.install
+ end
+
+ def purge
+ yum "-y", :erase, @resource[:name]
+ end
end
diff --git a/lib/puppet/provider/package/zypper.rb b/lib/puppet/provider/package/zypper.rb
index 9f7386b..d56c725 100644
--- a/lib/puppet/provider/package/zypper.rb
+++ b/lib/puppet/provider/package/zypper.rb
@@ -1,52 +1,52 @@
Puppet::Type.type(:package).provide :zypper, :parent => :rpm do
- desc "Support for SuSE ``zypper`` package manager. Found in SLES10sp2+ and SLES11"
-
- has_feature :versionable
-
- commands :zypper => "/usr/bin/zypper"
- commands :rpm => "rpm"
-
- confine :operatingsystem => [:suse, :sles, :sled, :opensuse]
-
- # Install a package using 'zypper'.
- def install
- should = @resource.should(:ensure)
- self.debug "Ensuring => #{should}"
- wanted = @resource[:name]
-
- # XXX: We don't actually deal with epochs here.
- case should
- when true, false, Symbol
- # pass
- else
- # Add the package version
- wanted = "#{wanted}-#{should}"
- end
- output = zypper "--quiet", :install, "-l", "-y", wanted
-
- unless self.query
- raise Puppet::ExecutionFailure.new(
- "Could not find package #{self.name}"
- )
- end
- end
+ desc "Support for SuSE ``zypper`` package manager. Found in SLES10sp2+ and SLES11"
+
+ has_feature :versionable
+
+ commands :zypper => "/usr/bin/zypper"
+ commands :rpm => "rpm"
+
+ confine :operatingsystem => [:suse, :sles, :sled, :opensuse]
- # What's the latest package version available?
- def latest
- #zypper can only get a list of *all* available packages?
- output = zypper "list-updates"
-
- if output =~ /#{Regexp.escape @resource[:name]}\s*\|\s*([^\s\|]+)/
- return $1
- else
- # zypper didn't find updates, pretend the current
- # version is the latest
- return @property_hash[:ensure]
- end
+ # Install a package using 'zypper'.
+ def install
+ should = @resource.should(:ensure)
+ self.debug "Ensuring => #{should}"
+ wanted = @resource[:name]
+
+ # XXX: We don't actually deal with epochs here.
+ case should
+ when true, false, Symbol
+ # pass
+ else
+ # Add the package version
+ wanted = "#{wanted}-#{should}"
end
+ output = zypper "--quiet", :install, "-l", "-y", wanted
- def update
- # zypper install can be used for update, too
- self.install
+ unless self.query
+ raise Puppet::ExecutionFailure.new(
+ "Could not find package #{self.name}"
+ )
+ end
+ end
+
+ # What's the latest package version available?
+ def latest
+ #zypper can only get a list of *all* available packages?
+ output = zypper "list-updates"
+
+ if output =~ /#{Regexp.escape @resource[:name]}\s*\|\s*([^\s\|]+)/
+ return $1
+ else
+ # zypper didn't find updates, pretend the current
+ # version is the latest
+ return @property_hash[:ensure]
end
+ end
+
+ def update
+ # zypper install can be used for update, too
+ self.install
+ end
end
diff --git a/lib/puppet/provider/parsedfile.rb b/lib/puppet/provider/parsedfile.rb
index 811607a..ffd36e5 100755
--- a/lib/puppet/provider/parsedfile.rb
+++ b/lib/puppet/provider/parsedfile.rb
@@ -11,124 +11,124 @@ require 'puppet/util/fileparsing'
# Once the provider prefetches the data, it's the resource's job to copy
# that data over to the @is variables.
class Puppet::Provider::ParsedFile < Puppet::Provider
- extend Puppet::Util::FileParsing
+ extend Puppet::Util::FileParsing
- class << self
- attr_accessor :default_target, :target
- end
-
- attr_accessor :property_hash
+ class << self
+ attr_accessor :default_target, :target
+ end
- def self.clean(hash)
- newhash = hash.dup
- [:record_type, :on_disk].each do |p|
- newhash.delete(p) if newhash.include?(p)
- end
+ attr_accessor :property_hash
- newhash
+ def self.clean(hash)
+ newhash = hash.dup
+ [:record_type, :on_disk].each do |p|
+ newhash.delete(p) if newhash.include?(p)
end
- def self.clear
- @target_objects.clear
- @records.clear
- end
+ newhash
+ end
- def self.filetype
- @filetype ||= Puppet::Util::FileType.filetype(:flat)
- end
+ def self.clear
+ @target_objects.clear
+ @records.clear
+ end
- def self.filetype=(type)
- if type.is_a?(Class)
- @filetype = type
- elsif klass = Puppet::Util::FileType.filetype(type)
- @filetype = klass
- else
- raise ArgumentError, "Invalid filetype #{type}"
- end
+ def self.filetype
+ @filetype ||= Puppet::Util::FileType.filetype(:flat)
+ end
+
+ def self.filetype=(type)
+ if type.is_a?(Class)
+ @filetype = type
+ elsif klass = Puppet::Util::FileType.filetype(type)
+ @filetype = klass
+ else
+ raise ArgumentError, "Invalid filetype #{type}"
end
+ end
- # Flush all of the targets for which there are modified records. The only
- # reason we pass a record here is so that we can add it to the stack if
- # necessary -- it's passed from the instance calling 'flush'.
- def self.flush(record)
- # Make sure this record is on the list to be flushed.
- unless record[:on_disk]
- record[:on_disk] = true
- @records << record
-
- # If we've just added the record, then make sure our
- # target will get flushed.
- modified(record[:target] || default_target)
- end
+ # Flush all of the targets for which there are modified records. The only
+ # reason we pass a record here is so that we can add it to the stack if
+ # necessary -- it's passed from the instance calling 'flush'.
+ def self.flush(record)
+ # Make sure this record is on the list to be flushed.
+ unless record[:on_disk]
+ record[:on_disk] = true
+ @records << record
- return unless defined?(@modified) and ! @modified.empty?
+ # If we've just added the record, then make sure our
+ # target will get flushed.
+ modified(record[:target] || default_target)
+ end
- flushed = []
- @modified.sort { |a,b| a.to_s <=> b.to_s }.uniq.each do |target|
- Puppet.debug "Flushing #{@resource_type.name} provider target #{target}"
- flush_target(target)
- flushed << target
- end
+ return unless defined?(@modified) and ! @modified.empty?
- @modified.reject! { |t| flushed.include?(t) }
+ flushed = []
+ @modified.sort { |a,b| a.to_s <=> b.to_s }.uniq.each do |target|
+ Puppet.debug "Flushing #{@resource_type.name} provider target #{target}"
+ flush_target(target)
+ flushed << target
end
- # Make sure our file is backed up, but only back it up once per transaction.
- # We cheat and rely on the fact that @records is created on each prefetch.
- def self.backup_target(target)
- return nil unless target_object(target).respond_to?(:backup)
+ @modified.reject! { |t| flushed.include?(t) }
+ end
- @backup_stats ||= {}
- return nil if @backup_stats[target] == @records.object_id
+ # Make sure our file is backed up, but only back it up once per transaction.
+ # We cheat and rely on the fact that @records is created on each prefetch.
+ def self.backup_target(target)
+ return nil unless target_object(target).respond_to?(:backup)
- target_object(target).backup
- @backup_stats[target] = @records.object_id
- end
+ @backup_stats ||= {}
+ return nil if @backup_stats[target] == @records.object_id
- # Flush all of the records relating to a specific target.
- def self.flush_target(target)
- backup_target(target)
+ target_object(target).backup
+ @backup_stats[target] = @records.object_id
+ end
- records = target_records(target).reject { |r|
- r[:ensure] == :absent
- }
- target_object(target).write(to_file(records))
- end
+ # Flush all of the records relating to a specific target.
+ def self.flush_target(target)
+ backup_target(target)
- # Return the header placed at the top of each generated file, warning
- # users that modifying this file manually is probably a bad idea.
- def self.header
+ records = target_records(target).reject { |r|
+ r[:ensure] == :absent
+ }
+ target_object(target).write(to_file(records))
+ end
+
+ # Return the header placed at the top of each generated file, warning
+ # users that modifying this file manually is probably a bad idea.
+ def self.header
%{# HEADER: This file was autogenerated at #{Time.now}
# HEADER: by puppet. While it can still be managed manually, it
# HEADER: is definitely not recommended.\n}
- end
-
- # Add another type var.
- def self.initvars
- @records = []
- @target_objects = {}
-
- @target = nil
-
- # Default to flat files
- @filetype ||= Puppet::Util::FileType.filetype(:flat)
- super
- end
-
- # Return a list of all of the records we can find.
- def self.instances
- targets.collect do |target|
- prefetch_target(target)
- end.flatten.reject { |r| skip_record?(r) }.collect do |record|
- new(record)
- end
- end
-
- # Override the default method with a lot more functionality.
- def self.mk_resource_methods
- [resource_type.validproperties, resource_type.parameters].flatten.each do |attr|
- attr = symbolize(attr)
- define_method(attr) do
+ end
+
+ # Add another type var.
+ def self.initvars
+ @records = []
+ @target_objects = {}
+
+ @target = nil
+
+ # Default to flat files
+ @filetype ||= Puppet::Util::FileType.filetype(:flat)
+ super
+ end
+
+ # Return a list of all of the records we can find.
+ def self.instances
+ targets.collect do |target|
+ prefetch_target(target)
+ end.flatten.reject { |r| skip_record?(r) }.collect do |record|
+ new(record)
+ end
+ end
+
+ # Override the default method with a lot more functionality.
+ def self.mk_resource_methods
+ [resource_type.validproperties, resource_type.parameters].flatten.each do |attr|
+ attr = symbolize(attr)
+ define_method(attr) do
# if @property_hash.empty?
# # Note that this swaps the provider out from under us.
# prefetch
@@ -138,235 +138,235 @@ class Puppet::Provider::ParsedFile < Puppet::Provider
# return @resource.provider.send(attr)
# end
# end
- # If it's not a valid field for this record type (which can happen
- # when different platforms support different fields), then just
- # return the should value, so the resource shuts up.
- if @property_hash[attr] or self.class.valid_attr?(self.class.name, attr)
- @property_hash[attr] || :absent
- else
- if defined?(@resource)
- @resource.should(attr)
- else
- nil
- end
- end
- end
-
- define_method(attr.to_s + "=") do |val|
- mark_target_modified
- @property_hash[attr] = val
- end
- end
- end
-
- # Always make the resource methods.
- def self.resource_type=(resource)
- super
- mk_resource_methods
- end
-
- # Mark a target as modified so we know to flush it. This only gets
- # used within the attr= methods.
- def self.modified(target)
- @modified ||= []
- @modified << target unless @modified.include?(target)
- end
-
- # Retrieve all of the data from disk. There are three ways to know
- # which files to retrieve: We might have a list of file objects already
- # set up, there might be instances of our associated resource and they
- # will have a path parameter set, and we will have a default path
- # set. We need to turn those three locations into a list of files,
- # prefetch each one, and make sure they're associated with each appropriate
- # resource instance.
- def self.prefetch(resources = nil)
- # Reset the record list.
- @records = prefetch_all_targets(resources)
-
- match_providers_with_resources(resources)
- end
-
- def self.match_providers_with_resources(resources)
- return unless resources
- matchers = resources.dup
- @records.each do |record|
- # Skip things like comments and blank lines
- next if skip_record?(record)
-
- if name = record[:name] and resource = resources[name]
- resource.provider = new(record)
- elsif respond_to?(:match)
- if resource = match(record, matchers)
- # Remove this resource from circulation so we don't unnecessarily try to match
- matchers.delete(resource.title)
- record[:name] = resource[:name]
- resource.provider = new(record)
- end
- end
- end
- end
-
- def self.prefetch_all_targets(resources)
- records = []
- targets(resources).each do |target|
- records += prefetch_target(target)
+ # If it's not a valid field for this record type (which can happen
+ # when different platforms support different fields), then just
+ # return the should value, so the resource shuts up.
+ if @property_hash[attr] or self.class.valid_attr?(self.class.name, attr)
+ @property_hash[attr] || :absent
+ else
+ if defined?(@resource)
+ @resource.should(attr)
+ else
+ nil
+ end
end
- records
- end
+ end
- # Prefetch an individual target.
- def self.prefetch_target(target)
- target_records = retrieve(target).each do |r|
- r[:on_disk] = true
- r[:target] = target
- r[:ensure] = :present
+ define_method(attr.to_s + "=") do |val|
+ mark_target_modified
+ @property_hash[attr] = val
+ end
+ end
+ end
+
+ # Always make the resource methods.
+ def self.resource_type=(resource)
+ super
+ mk_resource_methods
+ end
+
+ # Mark a target as modified so we know to flush it. This only gets
+ # used within the attr= methods.
+ def self.modified(target)
+ @modified ||= []
+ @modified << target unless @modified.include?(target)
+ end
+
+ # Retrieve all of the data from disk. There are three ways to know
+ # which files to retrieve: We might have a list of file objects already
+ # set up, there might be instances of our associated resource and they
+ # will have a path parameter set, and we will have a default path
+ # set. We need to turn those three locations into a list of files,
+ # prefetch each one, and make sure they're associated with each appropriate
+ # resource instance.
+ def self.prefetch(resources = nil)
+ # Reset the record list.
+ @records = prefetch_all_targets(resources)
+
+ match_providers_with_resources(resources)
+ end
+
+ def self.match_providers_with_resources(resources)
+ return unless resources
+ matchers = resources.dup
+ @records.each do |record|
+ # Skip things like comments and blank lines
+ next if skip_record?(record)
+
+ if name = record[:name] and resource = resources[name]
+ resource.provider = new(record)
+ elsif respond_to?(:match)
+ if resource = match(record, matchers)
+ # Remove this resource from circulation so we don't unnecessarily try to match
+ matchers.delete(resource.title)
+ record[:name] = resource[:name]
+ resource.provider = new(record)
end
-
- target_records = prefetch_hook(target_records) if respond_to?(:prefetch_hook)
-
- raise Puppet::DevError, "Prefetching #{target} for provider #{self.name} returned nil" unless target_records
-
- target_records
- end
-
- # Is there an existing record with this name?
- def self.record?(name)
- return nil unless @records
- @records.find { |r| r[:name] == name }
- end
-
- # Retrieve the text for the file. Returns nil in the unlikely
- # event that it doesn't exist.
- def self.retrieve(path)
- # XXX We need to be doing something special here in case of failure.
- text = target_object(path).read
- if text.nil? or text == ""
- # there is no file
- return []
- else
- # Set the target, for logging.
- old = @target
- begin
- @target = path
- return self.parse(text)
- rescue Puppet::Error => detail
- detail.file = @target
- raise detail
- ensure
- @target = old
- end
+ end
+ end
+ end
+
+ def self.prefetch_all_targets(resources)
+ records = []
+ targets(resources).each do |target|
+ records += prefetch_target(target)
+ end
+ records
+ end
+
+ # Prefetch an individual target.
+ def self.prefetch_target(target)
+ target_records = retrieve(target).each do |r|
+ r[:on_disk] = true
+ r[:target] = target
+ r[:ensure] = :present
+ end
+
+ target_records = prefetch_hook(target_records) if respond_to?(:prefetch_hook)
+
+ raise Puppet::DevError, "Prefetching #{target} for provider #{self.name} returned nil" unless target_records
+
+ target_records
+ end
+
+ # Is there an existing record with this name?
+ def self.record?(name)
+ return nil unless @records
+ @records.find { |r| r[:name] == name }
+ end
+
+ # Retrieve the text for the file. Returns nil in the unlikely
+ # event that it doesn't exist.
+ def self.retrieve(path)
+ # XXX We need to be doing something special here in case of failure.
+ text = target_object(path).read
+ if text.nil? or text == ""
+ # there is no file
+ return []
+ else
+ # Set the target, for logging.
+ old = @target
+ begin
+ @target = path
+ return self.parse(text)
+ rescue Puppet::Error => detail
+ detail.file = @target
+ raise detail
+ ensure
+ @target = old
+ end
+ end
+ end
+
+ # Should we skip the record? Basically, we skip text records.
+ # This is only here so subclasses can override it.
+ def self.skip_record?(record)
+ record_type(record[:record_type]).text?
+ end
+
+ # Initialize the object if necessary.
+ def self.target_object(target)
+ @target_objects[target] ||= filetype.new(target)
+
+ @target_objects[target]
+ end
+
+ # Find all of the records for a given target
+ def self.target_records(target)
+ @records.find_all { |r| r[:target] == target }
+ end
+
+ # Find a list of all of the targets that we should be reading. This is
+ # used to figure out what targets we need to prefetch.
+ def self.targets(resources = nil)
+ targets = []
+ # First get the default target
+ raise Puppet::DevError, "Parsed Providers must define a default target" unless self.default_target
+ targets << self.default_target
+
+ # Then get each of the file objects
+ targets += @target_objects.keys
+
+ # Lastly, check the file from any resource instances
+ if resources
+ resources.each do |name, resource|
+ if value = resource.should(:target)
+ targets << value
end
+ end
end
- # Should we skip the record? Basically, we skip text records.
- # This is only here so subclasses can override it.
- def self.skip_record?(record)
- record_type(record[:record_type]).text?
- end
+ targets.uniq.compact
+ end
- # Initialize the object if necessary.
- def self.target_object(target)
- @target_objects[target] ||= filetype.new(target)
+ def self.to_file(records)
+ text = super
+ header + text
+ end
- @target_objects[target]
+ def create
+ @resource.class.validproperties.each do |property|
+ if value = @resource.should(property)
+ @property_hash[property] = value
+ end
end
+ mark_target_modified
+ (@resource.class.name.to_s + "_created").intern
+ end
- # Find all of the records for a given target
- def self.target_records(target)
- @records.find_all { |r| r[:target] == target }
- end
+ def destroy
+ # We use the method here so it marks the target as modified.
+ self.ensure = :absent
+ (@resource.class.name.to_s + "_deleted").intern
+ end
- # Find a list of all of the targets that we should be reading. This is
- # used to figure out what targets we need to prefetch.
- def self.targets(resources = nil)
- targets = []
- # First get the default target
- raise Puppet::DevError, "Parsed Providers must define a default target" unless self.default_target
- targets << self.default_target
-
- # Then get each of the file objects
- targets += @target_objects.keys
-
- # Lastly, check the file from any resource instances
- if resources
- resources.each do |name, resource|
- if value = resource.should(:target)
- targets << value
- end
- end
- end
+ def exists?
+ !(@property_hash[:ensure] == :absent or @property_hash[:ensure].nil?)
+ end
- targets.uniq.compact
- end
+ # Write our data to disk.
+ def flush
+ # Make sure we've got a target and name set.
- def self.to_file(records)
- text = super
- header + text
+ # If the target isn't set, then this is our first modification, so
+ # mark it for flushing.
+ unless @property_hash[:target]
+ @property_hash[:target] = @resource.should(:target) || self.class.default_target
+ self.class.modified(@property_hash[:target])
end
+ @property_hash[:name] ||= @resource.name
- def create
- @resource.class.validproperties.each do |property|
- if value = @resource.should(property)
- @property_hash[property] = value
- end
- end
- mark_target_modified
- (@resource.class.name.to_s + "_created").intern
- end
-
- def destroy
- # We use the method here so it marks the target as modified.
- self.ensure = :absent
- (@resource.class.name.to_s + "_deleted").intern
- end
-
- def exists?
- !(@property_hash[:ensure] == :absent or @property_hash[:ensure].nil?)
- end
-
- # Write our data to disk.
- def flush
- # Make sure we've got a target and name set.
+ self.class.flush(@property_hash)
- # If the target isn't set, then this is our first modification, so
- # mark it for flushing.
- unless @property_hash[:target]
- @property_hash[:target] = @resource.should(:target) || self.class.default_target
- self.class.modified(@property_hash[:target])
- end
- @property_hash[:name] ||= @resource.name
-
- self.class.flush(@property_hash)
-
- #@property_hash = {}
- end
+ #@property_hash = {}
+ end
- def initialize(record)
- super
+ def initialize(record)
+ super
- # The 'record' could be a resource or a record, depending on how the provider
- # is initialized. If we got an empty property hash (probably because the resource
- # is just being initialized), then we want to set up some defualts.
- @property_hash = self.class.record?(resource[:name]) || {:record_type => self.class.name, :ensure => :absent} if @property_hash.empty?
- end
+ # The 'record' could be a resource or a record, depending on how the provider
+ # is initialized. If we got an empty property hash (probably because the resource
+ # is just being initialized), then we want to set up some defualts.
+ @property_hash = self.class.record?(resource[:name]) || {:record_type => self.class.name, :ensure => :absent} if @property_hash.empty?
+ end
- # Retrieve the current state from disk.
- def prefetch
- raise Puppet::DevError, "Somehow got told to prefetch with no resource set" unless @resource
- self.class.prefetch(@resource[:name] => @resource)
- end
+ # Retrieve the current state from disk.
+ def prefetch
+ raise Puppet::DevError, "Somehow got told to prefetch with no resource set" unless @resource
+ self.class.prefetch(@resource[:name] => @resource)
+ end
- def record_type
- @property_hash[:record_type]
- end
+ def record_type
+ @property_hash[:record_type]
+ end
- private
+ private
- # Mark both the resource and provider target as modified.
- def mark_target_modified
- if defined?(@resource) and restarget = @resource.should(:target) and restarget != @property_hash[:target]
- self.class.modified(restarget)
- end
- self.class.modified(@property_hash[:target]) if @property_hash[:target] != :absent and @property_hash[:target]
+ # Mark both the resource and provider target as modified.
+ def mark_target_modified
+ if defined?(@resource) and restarget = @resource.should(:target) and restarget != @property_hash[:target]
+ self.class.modified(restarget)
end
+ self.class.modified(@property_hash[:target]) if @property_hash[:target] != :absent and @property_hash[:target]
+ end
end
diff --git a/lib/puppet/provider/selboolean/getsetsebool.rb b/lib/puppet/provider/selboolean/getsetsebool.rb
index 259d947..cacc413 100644
--- a/lib/puppet/provider/selboolean/getsetsebool.rb
+++ b/lib/puppet/provider/selboolean/getsetsebool.rb
@@ -1,47 +1,47 @@
Puppet::Type.type(:selboolean).provide(:getsetsebool) do
- desc "Manage SELinux booleans using the getsebool and setsebool binaries."
+ desc "Manage SELinux booleans using the getsebool and setsebool binaries."
- commands :getsebool => "/usr/sbin/getsebool"
- commands :setsebool => "/usr/sbin/setsebool"
+ commands :getsebool => "/usr/sbin/getsebool"
+ commands :setsebool => "/usr/sbin/setsebool"
- def value
- self.debug "Retrieving value of selboolean #{@resource[:name]}"
+ def value
+ self.debug "Retrieving value of selboolean #{@resource[:name]}"
- status = getsebool(@resource[:name])
+ status = getsebool(@resource[:name])
- if status =~ / off$/
- return :off
- elsif status =~ / on$/ then
- return :on
- else
- status.chomp!
- raise Puppet::Error, "Invalid response '#{status}' returned from getsebool"
- end
+ if status =~ / off$/
+ return :off
+ elsif status =~ / on$/ then
+ return :on
+ else
+ status.chomp!
+ raise Puppet::Error, "Invalid response '#{status}' returned from getsebool"
end
+ end
- def value=(new)
- persist = ""
- if @resource[:persistent] == :true
- self.debug "Enabling persistence"
- persist = "-P"
- end
- execoutput("#{command(:setsebool)} #{persist} #{@resource[:name]} #{new}")
- :file_changed
+ def value=(new)
+ persist = ""
+ if @resource[:persistent] == :true
+ self.debug "Enabling persistence"
+ persist = "-P"
end
+ execoutput("#{command(:setsebool)} #{persist} #{@resource[:name]} #{new}")
+ :file_changed
+ end
- # Required workaround, since SELinux policy prevents setsebool
- # from writing to any files, even tmp, preventing the standard
- # 'setsebool("...")' construct from working.
+ # Required workaround, since SELinux policy prevents setsebool
+ # from writing to any files, even tmp, preventing the standard
+ # 'setsebool("...")' construct from working.
- def execoutput (cmd)
- output = ''
- begin
- execpipe(cmd) do |out|
- output = out.readlines.join('').chomp!
- end
- rescue Puppet::ExecutionFailure
- raise Puppet::ExecutionFailure, output.split("\n")[0]
- end
- output
+ def execoutput (cmd)
+ output = ''
+ begin
+ execpipe(cmd) do |out|
+ output = out.readlines.join('').chomp!
+ end
+ rescue Puppet::ExecutionFailure
+ raise Puppet::ExecutionFailure, output.split("\n")[0]
end
+ output
+ end
end
diff --git a/lib/puppet/provider/selmodule/semodule.rb b/lib/puppet/provider/selmodule/semodule.rb
index d6bf09a..6419715 100644
--- a/lib/puppet/provider/selmodule/semodule.rb
+++ b/lib/puppet/provider/selmodule/semodule.rb
@@ -1,135 +1,135 @@
Puppet::Type.type(:selmodule).provide(:semodule) do
- desc "Manage SELinux policy modules using the semodule binary."
+ desc "Manage SELinux policy modules using the semodule binary."
- commands :semodule => "/usr/sbin/semodule"
+ commands :semodule => "/usr/sbin/semodule"
- def create
- begin
- execoutput("#{command(:semodule)} --install #{selmod_name_to_filename}")
- rescue Puppet::ExecutionFailure => detail
- raise Puppet::Error, "Could not load policy module: #{detail}";
- end
- :true
- end
-
- def destroy
- execoutput("#{command(:semodule)} --remove #{@resource[:name]}")
+ def create
+ begin
+ execoutput("#{command(:semodule)} --install #{selmod_name_to_filename}")
rescue Puppet::ExecutionFailure => detail
- raise Puppet::Error, "Could not remove policy module: #{detail}";
+ raise Puppet::Error, "Could not load policy module: #{detail}";
end
-
- def exists?
- self.debug "Checking for module #{@resource[:name]}"
- execpipe("#{command(:semodule)} --list") do |out|
- out.each do |line|
- if line =~ /#{@resource[:name]}\b/
- return :true
- end
- end
+ :true
+ end
+
+ def destroy
+ execoutput("#{command(:semodule)} --remove #{@resource[:name]}")
+ rescue Puppet::ExecutionFailure => detail
+ raise Puppet::Error, "Could not remove policy module: #{detail}";
+ end
+
+ def exists?
+ self.debug "Checking for module #{@resource[:name]}"
+ execpipe("#{command(:semodule)} --list") do |out|
+ out.each do |line|
+ if line =~ /#{@resource[:name]}\b/
+ return :true
end
- nil
+ end
end
+ nil
+ end
- def syncversion
- self.debug "Checking syncversion on #{@resource[:name]}"
+ def syncversion
+ self.debug "Checking syncversion on #{@resource[:name]}"
- loadver = selmodversion_loaded
+ loadver = selmodversion_loaded
- if(loadver) then
- filever = selmodversion_file
- if (filever == loadver)
- return :true
- end
- end
- :false
+ if(loadver) then
+ filever = selmodversion_file
+ if (filever == loadver)
+ return :true
+ end
end
-
- def syncversion= (dosync)
- execoutput("#{command(:semodule)} --upgrade #{selmod_name_to_filename}")
- rescue Puppet::ExecutionFailure => detail
- raise Puppet::Error, "Could not upgrade policy module: #{detail}";
+ :false
+ end
+
+ def syncversion= (dosync)
+ execoutput("#{command(:semodule)} --upgrade #{selmod_name_to_filename}")
+ rescue Puppet::ExecutionFailure => detail
+ raise Puppet::Error, "Could not upgrade policy module: #{detail}";
+ end
+
+ # Helper functions
+
+ def execoutput (cmd)
+ output = ''
+ begin
+ execpipe(cmd) do |out|
+ output = out.readlines.join('').chomp!
+ end
+ rescue Puppet::ExecutionFailure
+ raise Puppet::ExecutionFailure, output.split("\n")[0]
end
-
- # Helper functions
-
- def execoutput (cmd)
- output = ''
- begin
- execpipe(cmd) do |out|
- output = out.readlines.join('').chomp!
- end
- rescue Puppet::ExecutionFailure
- raise Puppet::ExecutionFailure, output.split("\n")[0]
- end
- output
+ output
+ end
+
+ def selmod_name_to_filename
+ if @resource[:selmodulepath]
+ return @resource[:selmodulepath]
+ else
+ return "#{@resource[:selmoduledir]}/#{@resource[:name]}.pp"
end
+ end
- def selmod_name_to_filename
- if @resource[:selmodulepath]
- return @resource[:selmodulepath]
- else
- return "#{@resource[:selmoduledir]}/#{@resource[:name]}.pp"
- end
- end
+ def selmod_readnext (handle)
+ len = handle.read(4).unpack('L')[0]
+ handle.read(len)
+ end
- def selmod_readnext (handle)
- len = handle.read(4).unpack('L')[0]
- handle.read(len)
- end
-
- def selmodversion_file
- magic = 0xF97CFF8F
+ def selmodversion_file
+ magic = 0xF97CFF8F
- filename = selmod_name_to_filename
- mod = File.new(filename, "r")
+ filename = selmod_name_to_filename
+ mod = File.new(filename, "r")
- (hdr, ver, numsec) = mod.read(12).unpack('LLL')
+ (hdr, ver, numsec) = mod.read(12).unpack('LLL')
- raise Puppet::Error, "Found #{hdr} instead of magic #{magic} in #{filename}" if hdr != magic
+ raise Puppet::Error, "Found #{hdr} instead of magic #{magic} in #{filename}" if hdr != magic
- raise Puppet::Error, "Unknown policy file version #{ver} in #{filename}" if ver != 1
+ raise Puppet::Error, "Unknown policy file version #{ver} in #{filename}" if ver != 1
- # Read through (and throw away) the file section offsets, and also
- # the magic header for the first section.
+ # Read through (and throw away) the file section offsets, and also
+ # the magic header for the first section.
- mod.read((numsec + 1) * 4)
+ mod.read((numsec + 1) * 4)
- ## Section 1 should be "SE Linux Module"
+ ## Section 1 should be "SE Linux Module"
- selmod_readnext(mod)
- selmod_readnext(mod)
+ selmod_readnext(mod)
+ selmod_readnext(mod)
- # Skip past the section headers
- mod.read(14)
+ # Skip past the section headers
+ mod.read(14)
- # Module name
- selmod_readnext(mod)
+ # Module name
+ selmod_readnext(mod)
- # At last! the version
+ # At last! the version
- v = selmod_readnext(mod)
+ v = selmod_readnext(mod)
- self.debug "file version #{v}"
- v
- end
+ self.debug "file version #{v}"
+ v
+ end
- def selmodversion_loaded
- lines = ()
- begin
- execpipe("#{command(:semodule)} --list") do |output|
- lines = output.readlines
- lines.each do |line|
- line.chomp!
- bits = line.split
- if bits[0] == @resource[:name]
- self.debug "load version #{bits[1]}"
- return bits[1]
- end
- end
- end
- rescue Puppet::ExecutionFailure
- raise Puppet::ExecutionFailure, "Could not list policy modules: #{lines.join(' ').chomp!}"
+ def selmodversion_loaded
+ lines = ()
+ begin
+ execpipe("#{command(:semodule)} --list") do |output|
+ lines = output.readlines
+ lines.each do |line|
+ line.chomp!
+ bits = line.split
+ if bits[0] == @resource[:name]
+ self.debug "load version #{bits[1]}"
+ return bits[1]
+ end
end
- nil
+ end
+ rescue Puppet::ExecutionFailure
+ raise Puppet::ExecutionFailure, "Could not list policy modules: #{lines.join(' ').chomp!}"
end
+ nil
+ end
end
diff --git a/lib/puppet/provider/service/base.rb b/lib/puppet/provider/service/base.rb
index 50e8790..70d7641 100755
--- a/lib/puppet/provider/service/base.rb
+++ b/lib/puppet/provider/service/base.rb
@@ -1,144 +1,144 @@
Puppet::Type.type(:service).provide :base do
- desc "The simplest form of service support.
-
- You have to specify enough about your service for this to work; the
- minimum you can specify is a binary for starting the process, and this
- same binary will be searched for in the process table to stop the
- service. It is preferable to specify start, stop, and status commands,
- akin to how you would do so using ``init``.
-
- "
-
- commands :kill => "kill"
-
- def self.instances
- []
- end
-
- # Get the process ID for a running process. Requires the 'pattern'
- # parameter.
- def getpid
- @resource.fail "Either stop/status commands or a pattern must be specified" unless @resource[:pattern]
- ps = Facter["ps"].value
- @resource.fail "You must upgrade Facter to a version that includes 'ps'" unless ps and ps != ""
- regex = Regexp.new(@resource[:pattern])
- self.debug "Executing '#{ps}'"
- IO.popen(ps) { |table|
- table.each { |line|
- if regex.match(line)
- ary = line.sub(/^\s+/, '').split(/\s+/)
- return ary[1]
- end
- }
- }
-
- nil
- end
-
- # How to restart the process.
- def restart
- if @resource[:restart] or restartcmd
- ucommand(:restart)
- else
- self.stop
- self.start
- end
- end
-
- # There is no default command, which causes other methods to be used
- def restartcmd
- end
-
- # Check if the process is running. Prefer the 'status' parameter,
- # then 'statuscmd' method, then look in the process table. We give
- # the object the option to not return a status command, which might
- # happen if, for instance, it has an init script (and thus responds to
- # 'statuscmd') but does not have 'hasstatus' enabled.
- def status
- if @resource[:status] or statuscmd
- # Don't fail when the exit status is not 0.
- ucommand(:status, false)
-
- # Expicitly calling exitstatus to facilitate testing
- if $CHILD_STATUS.exitstatus == 0
- return :running
- else
- return :stopped
- end
- elsif pid = self.getpid
- self.debug "PID is #{pid}"
- return :running
- else
- return :stopped
+ desc "The simplest form of service support.
+
+ You have to specify enough about your service for this to work; the
+ minimum you can specify is a binary for starting the process, and this
+ same binary will be searched for in the process table to stop the
+ service. It is preferable to specify start, stop, and status commands,
+ akin to how you would do so using ``init``.
+
+ "
+
+ commands :kill => "kill"
+
+ def self.instances
+ []
+ end
+
+ # Get the process ID for a running process. Requires the 'pattern'
+ # parameter.
+ def getpid
+ @resource.fail "Either stop/status commands or a pattern must be specified" unless @resource[:pattern]
+ ps = Facter["ps"].value
+ @resource.fail "You must upgrade Facter to a version that includes 'ps'" unless ps and ps != ""
+ regex = Regexp.new(@resource[:pattern])
+ self.debug "Executing '#{ps}'"
+ IO.popen(ps) { |table|
+ table.each { |line|
+ if regex.match(line)
+ ary = line.sub(/^\s+/, '').split(/\s+/)
+ return ary[1]
end
+ }
+ }
+
+ nil
+ end
+
+ # How to restart the process.
+ def restart
+ if @resource[:restart] or restartcmd
+ ucommand(:restart)
+ else
+ self.stop
+ self.start
end
-
- # There is no default command, which causes other methods to be used
- def statuscmd
+ end
+
+ # There is no default command, which causes other methods to be used
+ def restartcmd
+ end
+
+ # Check if the process is running. Prefer the 'status' parameter,
+ # then 'statuscmd' method, then look in the process table. We give
+ # the object the option to not return a status command, which might
+ # happen if, for instance, it has an init script (and thus responds to
+ # 'statuscmd') but does not have 'hasstatus' enabled.
+ def status
+ if @resource[:status] or statuscmd
+ # Don't fail when the exit status is not 0.
+ ucommand(:status, false)
+
+ # Expicitly calling exitstatus to facilitate testing
+ if $CHILD_STATUS.exitstatus == 0
+ return :running
+ else
+ return :stopped
+ end
+ elsif pid = self.getpid
+ self.debug "PID is #{pid}"
+ return :running
+ else
+ return :stopped
end
-
- # Run the 'start' parameter command, or the specified 'startcmd'.
- def start
- ucommand(:start)
+ end
+
+ # There is no default command, which causes other methods to be used
+ def statuscmd
+ end
+
+ # Run the 'start' parameter command, or the specified 'startcmd'.
+ def start
+ ucommand(:start)
+ end
+
+ # The command used to start. Generated if the 'binary' argument
+ # is passed.
+ def startcmd
+ if @resource[:binary]
+ return @resource[:binary]
+ else
+ raise Puppet::Error,
+ "Services must specify a start command or a binary"
end
-
- # The command used to start. Generated if the 'binary' argument
- # is passed.
- def startcmd
- if @resource[:binary]
- return @resource[:binary]
- else
- raise Puppet::Error,
- "Services must specify a start command or a binary"
- end
+ end
+
+ # Stop the service. If a 'stop' parameter is specified, it
+ # takes precedence; otherwise checks if the object responds to
+ # a 'stopcmd' method, and if so runs that; otherwise, looks
+ # for the process in the process table.
+ # This method will generally not be overridden by submodules.
+ def stop
+ if @resource[:stop] or stopcmd
+ ucommand(:stop)
+ else
+ pid = getpid
+ unless pid
+ self.info "#{self.name} is not running"
+ return false
+ end
+ begin
+ output = kill pid
+ rescue Puppet::ExecutionFailure => detail
+ @resource.fail "Could not kill #{self.name}, PID #{pid}: #{output}"
+ end
+ return true
end
-
- # Stop the service. If a 'stop' parameter is specified, it
- # takes precedence; otherwise checks if the object responds to
- # a 'stopcmd' method, and if so runs that; otherwise, looks
- # for the process in the process table.
- # This method will generally not be overridden by submodules.
- def stop
- if @resource[:stop] or stopcmd
- ucommand(:stop)
- else
- pid = getpid
- unless pid
- self.info "#{self.name} is not running"
- return false
- end
- begin
- output = kill pid
- rescue Puppet::ExecutionFailure => detail
- @resource.fail "Could not kill #{self.name}, PID #{pid}: #{output}"
- end
- return true
- end
+ end
+
+ # There is no default command, which causes other methods to be used
+ def stopcmd
+ end
+
+ # A simple wrapper so execution failures are a bit more informative.
+ def texecute(type, command, fof = true)
+ begin
+ # #565: Services generally produce no output, so squelch them.
+ execute(command, :failonfail => fof, :squelch => true)
+ rescue Puppet::ExecutionFailure => detail
+ @resource.fail "Could not #{type} #{@resource.ref}: #{detail}"
end
-
- # There is no default command, which causes other methods to be used
- def stopcmd
- end
-
- # A simple wrapper so execution failures are a bit more informative.
- def texecute(type, command, fof = true)
- begin
- # #565: Services generally produce no output, so squelch them.
- execute(command, :failonfail => fof, :squelch => true)
- rescue Puppet::ExecutionFailure => detail
- @resource.fail "Could not #{type} #{@resource.ref}: #{detail}"
- end
- nil
- end
-
- # Use either a specified command or the default for our provider.
- def ucommand(type, fof = true)
- if c = @resource[type]
- cmd = [c]
- else
- cmd = [send("#{type}cmd")].flatten
- end
- texecute(type, cmd, fof)
+ nil
+ end
+
+ # Use either a specified command or the default for our provider.
+ def ucommand(type, fof = true)
+ if c = @resource[type]
+ cmd = [c]
+ else
+ cmd = [send("#{type}cmd")].flatten
end
+ texecute(type, cmd, fof)
+ end
end
diff --git a/lib/puppet/provider/service/bsd.rb b/lib/puppet/provider/service/bsd.rb
index 15e4385..2e00c33 100644
--- a/lib/puppet/provider/service/bsd.rb
+++ b/lib/puppet/provider/service/bsd.rb
@@ -1,48 +1,48 @@
# Manage FreeBSD services.
Puppet::Type.type(:service).provide :bsd, :parent => :init do
- desc "FreeBSD's (and probably NetBSD?) form of ``init``-style service management.
+ desc "FreeBSD's (and probably NetBSD?) form of ``init``-style service management.
- Uses ``rc.conf.d`` for service enabling and disabling.
+ Uses ``rc.conf.d`` for service enabling and disabling.
"
- confine :operatingsystem => [:freebsd, :netbsd, :openbsd]
-
- @@rcconf_dir = '/etc/rc.conf.d'
-
- def self.defpath
- superclass.defpath
- end
-
- # remove service file from rc.conf.d to disable it
- def disable
- rcfile = File.join(@@rcconf_dir, @model[:name])
- File.delete(rcfile) if File.exists?(rcfile)
- end
-
- # if the service file exists in rc.conf.d then it's already enabled
- def enabled?
- rcfile = File.join(@@rcconf_dir, @model[:name])
- return :true if File.exists?(rcfile)
-
- :false
- end
-
- # enable service by creating a service file under rc.conf.d with the
- # proper contents
- def enable
- Dir.mkdir(@@rcconf_dir) if not File.exists?(@@rcconf_dir)
- rcfile = File.join(@@rcconf_dir, @model[:name])
- open(rcfile, 'w') { |f| f << "%s_enable=\"YES\"\n" % @model[:name] }
- end
-
- # Override stop/start commands to use one<cmd>'s and the avoid race condition
- # where provider trys to stop/start the service before it is enabled
- def startcmd
- [self.initscript, :onestart]
- end
-
- def stopcmd
- [self.initscript, :onestop]
- end
+ confine :operatingsystem => [:freebsd, :netbsd, :openbsd]
+
+ @@rcconf_dir = '/etc/rc.conf.d'
+
+ def self.defpath
+ superclass.defpath
+ end
+
+ # remove service file from rc.conf.d to disable it
+ def disable
+ rcfile = File.join(@@rcconf_dir, @model[:name])
+ File.delete(rcfile) if File.exists?(rcfile)
+ end
+
+ # if the service file exists in rc.conf.d then it's already enabled
+ def enabled?
+ rcfile = File.join(@@rcconf_dir, @model[:name])
+ return :true if File.exists?(rcfile)
+
+ :false
+ end
+
+ # enable service by creating a service file under rc.conf.d with the
+ # proper contents
+ def enable
+ Dir.mkdir(@@rcconf_dir) if not File.exists?(@@rcconf_dir)
+ rcfile = File.join(@@rcconf_dir, @model[:name])
+ open(rcfile, 'w') { |f| f << "%s_enable=\"YES\"\n" % @model[:name] }
+ end
+
+ # Override stop/start commands to use one<cmd>'s and the avoid race condition
+ # where provider trys to stop/start the service before it is enabled
+ def startcmd
+ [self.initscript, :onestart]
+ end
+
+ def stopcmd
+ [self.initscript, :onestop]
+ end
end
diff --git a/lib/puppet/provider/service/daemontools.rb b/lib/puppet/provider/service/daemontools.rb
index 7a584a1..65abf77 100644
--- a/lib/puppet/provider/service/daemontools.rb
+++ b/lib/puppet/provider/service/daemontools.rb
@@ -2,193 +2,193 @@
#
# author Brice Figureau <brice-puppet at daysofwonder.com>
Puppet::Type.type(:service).provide :daemontools, :parent => :base do
- desc "Daemontools service management.
+ desc "Daemontools service management.
- This provider manages daemons running supervised by D.J.Bernstein daemontools.
- It tries to detect the service directory, with by order of preference:
+ This provider manages daemons running supervised by D.J.Bernstein daemontools.
+ It tries to detect the service directory, with by order of preference:
- * /service
- * /etc/service
- * /var/lib/svscan
+ * /service
+ * /etc/service
+ * /var/lib/svscan
- The daemon directory should be placed in a directory that can be
- by default in:
+ The daemon directory should be placed in a directory that can be
+ by default in:
- * /var/lib/service
- * /etc
+ * /var/lib/service
+ * /etc
- or this can be overriden in the service resource parameters::
+ or this can be overriden in the service resource parameters::
- service {
- \"myservice\":
- provider => \"daemontools\", path => \"/path/to/daemons\";
- }
+ service {
+ \"myservice\":
+ provider => \"daemontools\", path => \"/path/to/daemons\";
+ }
- This provider supports out of the box:
+ This provider supports out of the box:
- * start/stop (mapped to enable/disable)
- * enable/disable
- * restart
- * status
+ * start/stop (mapped to enable/disable)
+ * enable/disable
+ * restart
+ * status
- If a service has ensure => \"running\", it will link /path/to/daemon to
- /path/to/service, which will automatically enable the service.
+ If a service has ensure => \"running\", it will link /path/to/daemon to
+ /path/to/service, which will automatically enable the service.
- If a service has ensure => \"stopped\", it will only down the service, not
- remove the /path/to/service link.
+ If a service has ensure => \"stopped\", it will only down the service, not
+ remove the /path/to/service link.
- "
+ "
- commands :svc => "/usr/bin/svc", :svstat => "/usr/bin/svstat"
+ commands :svc => "/usr/bin/svc", :svstat => "/usr/bin/svstat"
- class << self
- attr_writer :defpath
+ class << self
+ attr_writer :defpath
- # Determine the daemon path.
- def defpath(dummy_argument=:work_arround_for_ruby_GC_bug)
- unless @defpath
- ["/var/lib/service", "/etc"].each do |path|
- if FileTest.exist?(path)
- @defpath = path
- break
- end
- end
- raise "Could not find the daemon directory (tested [/var/lib/service,/etc])" unless @defpath
- end
- @defpath
+ # Determine the daemon path.
+ def defpath(dummy_argument=:work_arround_for_ruby_GC_bug)
+ unless @defpath
+ ["/var/lib/service", "/etc"].each do |path|
+ if FileTest.exist?(path)
+ @defpath = path
+ break
+ end
end
+ raise "Could not find the daemon directory (tested [/var/lib/service,/etc])" unless @defpath
+ end
+ @defpath
end
+ end
- attr_writer :servicedir
+ attr_writer :servicedir
- # returns all providers for all existing services in @defpath
- # ie enabled or not
- def self.instances
- path = self.defpath
- unless FileTest.directory?(path)
- Puppet.notice "Service path #{path} does not exist"
- next
- end
-
- # reject entries that aren't either a directory
- # or don't contain a run file
- Dir.entries(path).reject { |e|
- fullpath = File.join(path, e)
- e =~ /^\./ or ! FileTest.directory?(fullpath) or ! FileTest.exist?(File.join(fullpath,"run"))
- }.collect do |name|
- new(:name => name, :path => path)
- end
+ # returns all providers for all existing services in @defpath
+ # ie enabled or not
+ def self.instances
+ path = self.defpath
+ unless FileTest.directory?(path)
+ Puppet.notice "Service path #{path} does not exist"
+ next
end
- # returns the daemon dir on this node
- def self.daemondir
- self.defpath
+ # reject entries that aren't either a directory
+ # or don't contain a run file
+ Dir.entries(path).reject { |e|
+ fullpath = File.join(path, e)
+ e =~ /^\./ or ! FileTest.directory?(fullpath) or ! FileTest.exist?(File.join(fullpath,"run"))
+ }.collect do |name|
+ new(:name => name, :path => path)
end
-
- # find the service dir on this node
- def servicedir
- unless @servicedir
- ["/service", "/etc/service","/var/lib/svscan"].each do |path|
- if FileTest.exist?(path)
- @servicedir = path
- break
- end
- end
- raise "Could not find service directory" unless @servicedir
+ end
+
+ # returns the daemon dir on this node
+ def self.daemondir
+ self.defpath
+ end
+
+ # find the service dir on this node
+ def servicedir
+ unless @servicedir
+ ["/service", "/etc/service","/var/lib/svscan"].each do |path|
+ if FileTest.exist?(path)
+ @servicedir = path
+ break
end
- @servicedir
+ end
+ raise "Could not find service directory" unless @servicedir
end
-
- # returns the full path of this service when enabled
- # (ie in the service directory)
- def service
- File.join(self.servicedir, resource[:name])
+ @servicedir
+ end
+
+ # returns the full path of this service when enabled
+ # (ie in the service directory)
+ def service
+ File.join(self.servicedir, resource[:name])
+ end
+
+ # returns the full path to the current daemon directory
+ # note that this path can be overriden in the resource
+ # definition
+ def daemon
+ File.join(resource[:path], resource[:name])
+ end
+
+ def status
+ begin
+ output = svstat self.service
+ if output =~ /:\s+up \(/
+ return :running
+ end
+ rescue Puppet::ExecutionFailure => detail
+ raise Puppet::Error.new( "Could not get status for service #{resource.ref}: #{detail}" )
end
-
- # returns the full path to the current daemon directory
- # note that this path can be overriden in the resource
- # definition
- def daemon
- File.join(resource[:path], resource[:name])
+ :stopped
+ end
+
+ def setupservice
+ if resource[:manifest]
+ Puppet.notice "Configuring #{resource[:name]}"
+ command = [ resource[:manifest], resource[:name] ]
+ #texecute("setupservice", command)
+ rv = system("#{command}")
+ end
+ rescue Puppet::ExecutionFailure => detail
+ raise Puppet::Error.new( "Cannot config #{self.service} to enable it: #{detail}" )
+ end
+
+ def enabled?
+ case self.status
+ when :running
+ # obviously if the daemon is running then it is enabled
+ return :true
+ else
+ # the service is enabled if it is linked
+ return FileTest.symlink?(self.service) ? :true : :false
end
-
- def status
- begin
- output = svstat self.service
- if output =~ /:\s+up \(/
- return :running
- end
- rescue Puppet::ExecutionFailure => detail
- raise Puppet::Error.new( "Could not get status for service #{resource.ref}: #{detail}" )
+ end
+
+ def enable
+ if ! FileTest.directory?(self.daemon)
+ Puppet.notice "No daemon dir, calling setupservice for #{resource[:name]}"
+ self.setupservice
+ end
+ if self.daemon
+ if ! FileTest.symlink?(self.service)
+ Puppet.notice "Enabling #{self.service}: linking #{self.daemon} -> #{self.service}"
+ File.symlink(self.daemon, self.service)
end
- :stopped
- end
-
- def setupservice
- if resource[:manifest]
- Puppet.notice "Configuring #{resource[:name]}"
- command = [ resource[:manifest], resource[:name] ]
- #texecute("setupservice", command)
- rv = system("#{command}")
- end
- rescue Puppet::ExecutionFailure => detail
- raise Puppet::Error.new( "Cannot config #{self.service} to enable it: #{detail}" )
- end
-
- def enabled?
- case self.status
- when :running
- # obviously if the daemon is running then it is enabled
- return :true
- else
- # the service is enabled if it is linked
- return FileTest.symlink?(self.service) ? :true : :false
+ end
+ rescue Puppet::ExecutionFailure => detail
+ raise Puppet::Error.new( "No daemon directory found for #{self.service}")
+ end
+
+ def disable
+ begin
+ if ! FileTest.directory?(self.daemon)
+ Puppet.notice "No daemon dir, calling setupservice for #{resource[:name]}"
+ self.setupservice
+ end
+ if self.daemon
+ if FileTest.symlink?(self.service)
+ Puppet.notice "Disabling #{self.service}: removing link #{self.daemon} -> #{self.service}"
+ File.unlink(self.service)
end
- end
-
- def enable
- if ! FileTest.directory?(self.daemon)
- Puppet.notice "No daemon dir, calling setupservice for #{resource[:name]}"
- self.setupservice
- end
- if self.daemon
- if ! FileTest.symlink?(self.service)
- Puppet.notice "Enabling #{self.service}: linking #{self.daemon} -> #{self.service}"
- File.symlink(self.daemon, self.service)
- end
- end
+ end
rescue Puppet::ExecutionFailure => detail
- raise Puppet::Error.new( "No daemon directory found for #{self.service}")
- end
-
- def disable
- begin
- if ! FileTest.directory?(self.daemon)
- Puppet.notice "No daemon dir, calling setupservice for #{resource[:name]}"
- self.setupservice
- end
- if self.daemon
- if FileTest.symlink?(self.service)
- Puppet.notice "Disabling #{self.service}: removing link #{self.daemon} -> #{self.service}"
- File.unlink(self.service)
- end
- end
- rescue Puppet::ExecutionFailure => detail
- raise Puppet::Error.new( "No daemon directory found for #{self.service}")
- end
- self.stop
+ raise Puppet::Error.new( "No daemon directory found for #{self.service}")
end
+ self.stop
+ end
- def restart
- svc "-t", self.service
- end
+ def restart
+ svc "-t", self.service
+ end
- def start
- enable unless enabled? == :true
- svc "-u", self.service
- end
+ def start
+ enable unless enabled? == :true
+ svc "-u", self.service
+ end
- def stop
- svc "-d", self.service
- end
+ def stop
+ svc "-d", self.service
+ end
end
diff --git a/lib/puppet/provider/service/debian.rb b/lib/puppet/provider/service/debian.rb
index 746ed1c..4379f1b 100755
--- a/lib/puppet/provider/service/debian.rb
+++ b/lib/puppet/provider/service/debian.rb
@@ -1,48 +1,48 @@
# Manage debian services. Start/stop is the same as InitSvc, but enable/disable
# is special.
Puppet::Type.type(:service).provide :debian, :parent => :init do
- desc "Debian's form of ``init``-style management.
-
- The only difference is that this supports service enabling and disabling
- via ``update-rc.d`` and determines enabled status via ``invoke-rc.d``.
-
- "
-
- commands :update_rc => "/usr/sbin/update-rc.d"
- # note this isn't being used as a command until
- # http://projects.reductivelabs.com/issues/2538
- # is resolved.
- commands :invoke_rc => "/usr/sbin/invoke-rc.d"
-
- defaultfor :operatingsystem => [:debian, :ubuntu]
-
- def self.defpath
- superclass.defpath
+ desc "Debian's form of ``init``-style management.
+
+ The only difference is that this supports service enabling and disabling
+ via ``update-rc.d`` and determines enabled status via ``invoke-rc.d``.
+
+ "
+
+ commands :update_rc => "/usr/sbin/update-rc.d"
+ # note this isn't being used as a command until
+ # http://projects.reductivelabs.com/issues/2538
+ # is resolved.
+ commands :invoke_rc => "/usr/sbin/invoke-rc.d"
+
+ defaultfor :operatingsystem => [:debian, :ubuntu]
+
+ def self.defpath
+ superclass.defpath
+ end
+
+ # Remove the symlinks
+ def disable
+ update_rc "-f", @resource[:name], "remove"
+ update_rc @resource[:name], "stop", "00", "1", "2", "3", "4", "5", "6", "."
+ end
+
+ def enabled?
+ # TODO: Replace system call when Puppet::Util.execute gives us a way
+ # to determine exit status. http://projects.reductivelabs.com/issues/2538
+ system("/usr/sbin/invoke-rc.d", "--quiet", "--query", @resource[:name], "start")
+
+ # 104 is the exit status when you query start an enabled service.
+ # 106 is the exit status when the policy layer supplies a fallback action
+ # See x-man-page://invoke-rc.d
+ if [104, 106].include?($CHILD_STATUS.exitstatus)
+ return :true
+ else
+ return :false
end
+ end
- # Remove the symlinks
- def disable
- update_rc "-f", @resource[:name], "remove"
- update_rc @resource[:name], "stop", "00", "1", "2", "3", "4", "5", "6", "."
- end
-
- def enabled?
- # TODO: Replace system call when Puppet::Util.execute gives us a way
- # to determine exit status. http://projects.reductivelabs.com/issues/2538
- system("/usr/sbin/invoke-rc.d", "--quiet", "--query", @resource[:name], "start")
-
- # 104 is the exit status when you query start an enabled service.
- # 106 is the exit status when the policy layer supplies a fallback action
- # See x-man-page://invoke-rc.d
- if [104, 106].include?($CHILD_STATUS.exitstatus)
- return :true
- else
- return :false
- end
- end
-
- def enable
- update_rc "-f", @resource[:name], "remove"
- update_rc @resource[:name], "defaults"
- end
+ def enable
+ update_rc "-f", @resource[:name], "remove"
+ update_rc @resource[:name], "defaults"
+ end
end
diff --git a/lib/puppet/provider/service/freebsd.rb b/lib/puppet/provider/service/freebsd.rb
index f491d70..10970e4 100644
--- a/lib/puppet/provider/service/freebsd.rb
+++ b/lib/puppet/provider/service/freebsd.rb
@@ -1,136 +1,136 @@
Puppet::Type.type(:service).provide :freebsd, :parent => :init do
- desc "Provider for FreeBSD. Makes use of rcvar argument of init scripts and parses/edits rc files."
-
- confine :operatingsystem => [:freebsd]
- defaultfor :operatingsystem => [:freebsd]
-
- @@rcconf = '/etc/rc.conf'
- @@rcconf_local = '/etc/rc.conf.local'
- @@rcconf_dir = '/etc/rc.conf.d'
-
- def self.defpath
- superclass.defpath
- end
-
- # Executing an init script with the 'rcvar' argument returns
- # the service name, rcvar name and whether it's enabled/disabled
- def rcvar
- rcvar = execute([self.initscript, :rcvar], :failonfail => true, :squelch => false)
- rcvar = rcvar.split("\n")
- end
-
- # Extract service name
- def service_name
- name = self.rcvar[0]
- self.error("No service name found in rcvar") if name.nil?
- name = name.gsub!(/# (.*)/, '\1')
- self.error("Service name is empty") if name.nil?
- self.debug("Service name is #{name}")
- name
- end
-
- # Extract rcvar name
- def rcvar_name
- name = self.rcvar[1]
- self.error("No rcvar name found in rcvar") if name.nil?
- name = name.gsub!(/(.*)_enable=(.*)/, '\1')
- self.error("rcvar name is empty") if name.nil?
- self.debug("rcvar name is #{name}")
- name
- end
-
- # Extract rcvar value
- def rcvar_value
- value = self.rcvar[1]
- self.error("No rcvar value found in rcvar") if value.nil?
- value = value.gsub!(/(.*)_enable=\"?(.*)\"?/, '\2')
- self.error("rcvar value is empty") if value.nil?
- self.debug("rcvar value is #{value}")
- value
- end
-
- # Edit rc files and set the service to yes/no
- def rc_edit(yesno)
- service = self.service_name
- rcvar = self.rcvar_name
- self.debug("Editing rc files: setting #{rcvar} to #{yesno} for #{service}")
- self.rc_add(service, rcvar, yesno) if not self.rc_replace(service, rcvar, yesno)
- end
-
- # Try to find an existing setting in the rc files
- # and replace the value
- def rc_replace(service, rcvar, yesno)
- success = false
- # Replace in all files, not just in the first found with a match
- [@@rcconf, @@rcconf_local, @@rcconf_dir + "/#{service}"].each do |filename|
- if File.exists?(filename)
- s = File.read(filename)
- if s.gsub!(/(#{rcvar}_enable)=\"?(YES|NO)\"?/, "\\1=\"#{yesno}\"")
- File.open(filename, File::WRONLY) { |f| f << s }
- self.debug("Replaced in #{filename}")
- success = true
- end
- end
- end
- success
- end
-
- # Add a new setting to the rc files
- def rc_add(service, rcvar, yesno)
- append = "\n\# Added by Puppet\n#{rcvar}_enable=\"#{yesno}\""
- # First, try the one-file-per-service style
- if File.exists?(@@rcconf_dir)
- File.open(@@rcconf_dir + "/#{service}", File::WRONLY | File::APPEND | File::CREAT, 0644) {
- |f| f << append
- self.debug("Appended to #{f.path}")
- }
- else
- # Else, check the local rc file first, but don't create it
- if File.exists?(@@rcconf_local)
- File.open(@@rcconf_local, File::WRONLY | File::APPEND) {
- |f| f << append
- self.debug("Appended to #{f.path}")
- }
- else
- # At last use the standard rc.conf file
- File.open(@@rcconf, File::WRONLY | File::APPEND | File::CREAT, 0644) {
- |f| f << append
- self.debug("Appended to #{f.path}")
- }
- end
- end
- end
-
- def enabled?
- if /YES$/ =~ self.rcvar_value
- self.debug("Is enabled")
- return :true
+ desc "Provider for FreeBSD. Makes use of rcvar argument of init scripts and parses/edits rc files."
+
+ confine :operatingsystem => [:freebsd]
+ defaultfor :operatingsystem => [:freebsd]
+
+ @@rcconf = '/etc/rc.conf'
+ @@rcconf_local = '/etc/rc.conf.local'
+ @@rcconf_dir = '/etc/rc.conf.d'
+
+ def self.defpath
+ superclass.defpath
+ end
+
+ # Executing an init script with the 'rcvar' argument returns
+ # the service name, rcvar name and whether it's enabled/disabled
+ def rcvar
+ rcvar = execute([self.initscript, :rcvar], :failonfail => true, :squelch => false)
+ rcvar = rcvar.split("\n")
+ end
+
+ # Extract service name
+ def service_name
+ name = self.rcvar[0]
+ self.error("No service name found in rcvar") if name.nil?
+ name = name.gsub!(/# (.*)/, '\1')
+ self.error("Service name is empty") if name.nil?
+ self.debug("Service name is #{name}")
+ name
+ end
+
+ # Extract rcvar name
+ def rcvar_name
+ name = self.rcvar[1]
+ self.error("No rcvar name found in rcvar") if name.nil?
+ name = name.gsub!(/(.*)_enable=(.*)/, '\1')
+ self.error("rcvar name is empty") if name.nil?
+ self.debug("rcvar name is #{name}")
+ name
+ end
+
+ # Extract rcvar value
+ def rcvar_value
+ value = self.rcvar[1]
+ self.error("No rcvar value found in rcvar") if value.nil?
+ value = value.gsub!(/(.*)_enable=\"?(.*)\"?/, '\2')
+ self.error("rcvar value is empty") if value.nil?
+ self.debug("rcvar value is #{value}")
+ value
+ end
+
+ # Edit rc files and set the service to yes/no
+ def rc_edit(yesno)
+ service = self.service_name
+ rcvar = self.rcvar_name
+ self.debug("Editing rc files: setting #{rcvar} to #{yesno} for #{service}")
+ self.rc_add(service, rcvar, yesno) if not self.rc_replace(service, rcvar, yesno)
+ end
+
+ # Try to find an existing setting in the rc files
+ # and replace the value
+ def rc_replace(service, rcvar, yesno)
+ success = false
+ # Replace in all files, not just in the first found with a match
+ [@@rcconf, @@rcconf_local, @@rcconf_dir + "/#{service}"].each do |filename|
+ if File.exists?(filename)
+ s = File.read(filename)
+ if s.gsub!(/(#{rcvar}_enable)=\"?(YES|NO)\"?/, "\\1=\"#{yesno}\"")
+ File.open(filename, File::WRONLY) { |f| f << s }
+ self.debug("Replaced in #{filename}")
+ success = true
end
- self.debug("Is disabled")
- :false
+ end
end
-
- def enable
- self.debug("Enabling")
- self.rc_edit("YES")
- end
-
- def disable
- self.debug("Disabling")
- self.rc_edit("NO")
- end
-
- def startcmd
- [self.initscript, :onestart]
- end
-
- def stopcmd
- [self.initscript, :onestop]
+ success
+ end
+
+ # Add a new setting to the rc files
+ def rc_add(service, rcvar, yesno)
+ append = "\n\# Added by Puppet\n#{rcvar}_enable=\"#{yesno}\""
+ # First, try the one-file-per-service style
+ if File.exists?(@@rcconf_dir)
+ File.open(@@rcconf_dir + "/#{service}", File::WRONLY | File::APPEND | File::CREAT, 0644) {
+ |f| f << append
+ self.debug("Appended to #{f.path}")
+ }
+ else
+ # Else, check the local rc file first, but don't create it
+ if File.exists?(@@rcconf_local)
+ File.open(@@rcconf_local, File::WRONLY | File::APPEND) {
+ |f| f << append
+ self.debug("Appended to #{f.path}")
+ }
+ else
+ # At last use the standard rc.conf file
+ File.open(@@rcconf, File::WRONLY | File::APPEND | File::CREAT, 0644) {
+ |f| f << append
+ self.debug("Appended to #{f.path}")
+ }
+ end
end
+ end
- def statuscmd
- [self.initscript, :onestatus]
+ def enabled?
+ if /YES$/ =~ self.rcvar_value
+ self.debug("Is enabled")
+ return :true
end
+ self.debug("Is disabled")
+ :false
+ end
+
+ def enable
+ self.debug("Enabling")
+ self.rc_edit("YES")
+ end
+
+ def disable
+ self.debug("Disabling")
+ self.rc_edit("NO")
+ end
+
+ def startcmd
+ [self.initscript, :onestart]
+ end
+
+ def stopcmd
+ [self.initscript, :onestop]
+ end
+
+ def statuscmd
+ [self.initscript, :onestatus]
+ end
end
diff --git a/lib/puppet/provider/service/gentoo.rb b/lib/puppet/provider/service/gentoo.rb
index 109524b..08250a0 100644
--- a/lib/puppet/provider/service/gentoo.rb
+++ b/lib/puppet/provider/service/gentoo.rb
@@ -1,52 +1,52 @@
# Manage gentoo services. Start/stop is the same as InitSvc, but enable/disable
# is special.
Puppet::Type.type(:service).provide :gentoo, :parent => :init do
- desc "Gentoo's form of ``init``-style service management.
+ desc "Gentoo's form of ``init``-style service management.
- Uses ``rc-update`` for service enabling and disabling.
+ Uses ``rc-update`` for service enabling and disabling.
- "
+ "
- commands :update => "/sbin/rc-update"
+ commands :update => "/sbin/rc-update"
- confine :operatingsystem => :gentoo
+ confine :operatingsystem => :gentoo
- defaultfor :operatingsystem => :gentoo
+ defaultfor :operatingsystem => :gentoo
- def self.defpath
- superclass.defpath
- end
+ def self.defpath
+ superclass.defpath
+ end
+
+ def disable
+ output = update :del, @resource[:name], :default
+ rescue Puppet::ExecutionFailure
+ raise Puppet::Error, "Could not disable #{self.name}: #{output}"
+ end
- def disable
- output = update :del, @resource[:name], :default
+ def enabled?
+ begin
+ output = update :show
rescue Puppet::ExecutionFailure
- raise Puppet::Error, "Could not disable #{self.name}: #{output}"
+ return :false
end
- def enabled?
- begin
- output = update :show
- rescue Puppet::ExecutionFailure
- return :false
- end
-
- line = output.split(/\n/).find { |l| l.include?(@resource[:name]) }
+ line = output.split(/\n/).find { |l| l.include?(@resource[:name]) }
- return :false unless line
+ return :false unless line
- # If it's enabled then it will print output showing service | runlevel
- if output =~ /^\s*#{@resource[:name]}\s*\|\s*(boot|default)/
- return :true
- else
- return :false
- end
+ # If it's enabled then it will print output showing service | runlevel
+ if output =~ /^\s*#{@resource[:name]}\s*\|\s*(boot|default)/
+ return :true
+ else
+ return :false
end
+ end
- def enable
- output = update :add, @resource[:name], :default
- rescue Puppet::ExecutionFailure
- raise Puppet::Error, "Could not enable #{self.name}: #{output}"
- end
+ def enable
+ output = update :add, @resource[:name], :default
+ rescue Puppet::ExecutionFailure
+ raise Puppet::Error, "Could not enable #{self.name}: #{output}"
+ end
end
# $Id $
diff --git a/lib/puppet/provider/service/init.rb b/lib/puppet/provider/service/init.rb
index 17d3bad..6abff12 100755
--- a/lib/puppet/provider/service/init.rb
+++ b/lib/puppet/provider/service/init.rb
@@ -1,141 +1,141 @@
# The standard init-based service type. Many other service types are
# customizations of this module.
Puppet::Type.type(:service).provide :init, :parent => :base do
- desc "Standard init service management.
+ desc "Standard init service management.
- This provider assumes that the init script has no ``status`` command,
- because so few scripts do, so you need to either provide a status
- command or specify via ``hasstatus`` that one already exists in the
- init script.
+ This provider assumes that the init script has no ``status`` command,
+ because so few scripts do, so you need to either provide a status
+ command or specify via ``hasstatus`` that one already exists in the
+ init script.
"
- class << self
- attr_accessor :defpath
+ class << self
+ attr_accessor :defpath
+ end
+
+ case Facter["operatingsystem"].value
+ when "FreeBSD"
+ @defpath = ["/etc/rc.d", "/usr/local/etc/rc.d"]
+ when "HP-UX"
+ @defpath = "/sbin/init.d"
+ else
+ @defpath = "/etc/init.d"
+ end
+
+ # We can't confine this here, because the init path can be overridden.
+ #confine :exists => @defpath
+
+ # List all services of this type.
+ def self.instances
+ get_services(self.defpath)
+ end
+
+ def self.get_services(defpath, exclude=[])
+ defpath = [defpath] unless defpath.is_a? Array
+ instances = []
+ defpath.each do |path|
+ unless FileTest.directory?(path)
+ Puppet.debug "Service path #{path} does not exist"
+ next
+ end
+
+ check = [:ensure]
+
+ check << :enable if public_method_defined? :enabled?
+
+ Dir.entries(path).each do |name|
+ fullpath = File.join(path, name)
+ next if name =~ /^\./
+ next if exclude.include? name
+ next if not FileTest.executable?(fullpath)
+ instances << new(:name => name, :path => path, :hasstatus => true)
+ end
end
-
- case Facter["operatingsystem"].value
- when "FreeBSD"
- @defpath = ["/etc/rc.d", "/usr/local/etc/rc.d"]
- when "HP-UX"
- @defpath = "/sbin/init.d"
+ instances
+ end
+
+ # Mark that our init script supports 'status' commands.
+ def hasstatus=(value)
+ case value
+ when true, "true"; @parameters[:hasstatus] = true
+ when false, "false"; @parameters[:hasstatus] = false
else
- @defpath = "/etc/init.d"
- end
-
- # We can't confine this here, because the init path can be overridden.
- #confine :exists => @defpath
-
- # List all services of this type.
- def self.instances
- get_services(self.defpath)
- end
-
- def self.get_services(defpath, exclude=[])
- defpath = [defpath] unless defpath.is_a? Array
- instances = []
- defpath.each do |path|
- unless FileTest.directory?(path)
- Puppet.debug "Service path #{path} does not exist"
- next
- end
-
- check = [:ensure]
-
- check << :enable if public_method_defined? :enabled?
-
- Dir.entries(path).each do |name|
- fullpath = File.join(path, name)
- next if name =~ /^\./
- next if exclude.include? name
- next if not FileTest.executable?(fullpath)
- instances << new(:name => name, :path => path, :hasstatus => true)
- end
- end
- instances
+ raise Puppet::Error, "Invalid 'hasstatus' value #{value.inspect}"
end
-
- # Mark that our init script supports 'status' commands.
- def hasstatus=(value)
- case value
- when true, "true"; @parameters[:hasstatus] = true
- when false, "false"; @parameters[:hasstatus] = false
+ end
+
+ # Where is our init script?
+ def initscript
+ @initscript ||= self.search(@resource[:name])
+ end
+
+ def paths
+ @paths ||= @resource[:path].find_all do |path|
+ if File.directory?(path)
+ true
+ else
+ if File.exist?(path) and ! File.directory?(path)
+ self.debug "Search path #{path} is not a directory"
else
- raise Puppet::Error, "Invalid 'hasstatus' value #{value.inspect}"
+ self.debug "Search path #{path} does not exist"
end
+ false
+ end
end
-
- # Where is our init script?
- def initscript
- @initscript ||= self.search(@resource[:name])
- end
-
- def paths
- @paths ||= @resource[:path].find_all do |path|
- if File.directory?(path)
- true
- else
- if File.exist?(path) and ! File.directory?(path)
- self.debug "Search path #{path} is not a directory"
- else
- self.debug "Search path #{path} does not exist"
- end
- false
- end
- end
- end
-
- def search(name)
- paths.each { |path|
- fqname = File.join(path,name)
- begin
- stat = File.stat(fqname)
- rescue
- # should probably rescue specific errors...
- self.debug("Could not find #{name} in #{path}")
- next
- end
-
- # if we've gotten this far, we found a valid script
- return fqname
- }
-
- paths.each { |path|
- fqname_sh = File.join(path,"#{name}.sh")
- begin
- stat = File.stat(fqname_sh)
- rescue
- # should probably rescue specific errors...
- self.debug("Could not find #{name}.sh in #{path}")
- next
- end
-
- # if we've gotten this far, we found a valid script
- return fqname_sh
- }
- raise Puppet::Error, "Could not find init script for '#{name}'"
- end
-
- # The start command is just the init scriptwith 'start'.
- def startcmd
- [initscript, :start]
- end
-
- # The stop command is just the init script with 'stop'.
- def stopcmd
- [initscript, :stop]
- end
-
- def restartcmd
- (@resource[:hasrestart] == :true) && [initscript, :restart]
- end
-
- # If it was specified that the init script has a 'status' command, then
- # we just return that; otherwise, we return false, which causes it to
- # fallback to other mechanisms.
- def statuscmd
- (@resource[:hasstatus] == :true) && [initscript, :status]
- end
+ end
+
+ def search(name)
+ paths.each { |path|
+ fqname = File.join(path,name)
+ begin
+ stat = File.stat(fqname)
+ rescue
+ # should probably rescue specific errors...
+ self.debug("Could not find #{name} in #{path}")
+ next
+ end
+
+ # if we've gotten this far, we found a valid script
+ return fqname
+ }
+
+ paths.each { |path|
+ fqname_sh = File.join(path,"#{name}.sh")
+ begin
+ stat = File.stat(fqname_sh)
+ rescue
+ # should probably rescue specific errors...
+ self.debug("Could not find #{name}.sh in #{path}")
+ next
+ end
+
+ # if we've gotten this far, we found a valid script
+ return fqname_sh
+ }
+ raise Puppet::Error, "Could not find init script for '#{name}'"
+ end
+
+ # The start command is just the init scriptwith 'start'.
+ def startcmd
+ [initscript, :start]
+ end
+
+ # The stop command is just the init script with 'stop'.
+ def stopcmd
+ [initscript, :stop]
+ end
+
+ def restartcmd
+ (@resource[:hasrestart] == :true) && [initscript, :restart]
+ end
+
+ # If it was specified that the init script has a 'status' command, then
+ # we just return that; otherwise, we return false, which causes it to
+ # fallback to other mechanisms.
+ def statuscmd
+ (@resource[:hasstatus] == :true) && [initscript, :status]
+ end
end
diff --git a/lib/puppet/provider/service/launchd.rb b/lib/puppet/provider/service/launchd.rb
index 9be961b..9703595 100644
--- a/lib/puppet/provider/service/launchd.rb
+++ b/lib/puppet/provider/service/launchd.rb
@@ -1,256 +1,256 @@
require 'facter/util/plist'
Puppet::Type.type(:service).provide :launchd, :parent => :base do
- desc "launchd service management framework.
-
- This provider manages launchd jobs, the default service framework for
- Mac OS X, that has also been open sourced by Apple for possible use on
- other platforms.
-
- See:
- * http://developer.apple.com/macosx/launchd.html
- * http://launchd.macosforge.org/
-
- This provider reads plists out of the following directories:
- * /System/Library/LaunchDaemons
- * /System/Library/LaunchAgents
- * /Library/LaunchDaemons
- * /Library/LaunchAgents
-
- and builds up a list of services based upon each plists \"Label\" entry.
-
- This provider supports:
- * ensure => running/stopped,
- * enable => true/false
- * status
- * restart
-
- Here is how the Puppet states correspond to launchd states:
- * stopped => job unloaded
- * started => job loaded
- * enabled => 'Disable' removed from job plist file
- * disabled => 'Disable' added to job plist file
-
- Note that this allows you to do something launchctl can't do, which is to
- be in a state of \"stopped/enabled\ or \"running/disabled\".
-
- "
-
- commands :launchctl => "/bin/launchctl"
- commands :sw_vers => "/usr/bin/sw_vers"
-
- defaultfor :operatingsystem => :darwin
- confine :operatingsystem => :darwin
-
- has_feature :enableable
-
- Launchd_Paths = ["/Library/LaunchAgents",
- "/Library/LaunchDaemons",
- "/System/Library/LaunchAgents",
- "/System/Library/LaunchDaemons",]
-
- Launchd_Overrides = "/var/db/launchd.db/com.apple.launchd/overrides.plist"
-
-
- # returns a label => path map for either all jobs, or just a single
- # job if the label is specified
- def self.jobsearch(label=nil)
- label_to_path_map = {}
- Launchd_Paths.each do |path|
- if FileTest.exists?(path)
- Dir.entries(path).each do |f|
- next if f =~ /^\..*$/
- next if FileTest.directory?(f)
- fullpath = File.join(path, f)
- job = Plist::parse_xml(fullpath)
- if job and job.has_key?("Label")
- if job["Label"] == label
- return { label => fullpath }
- else
- label_to_path_map[job["Label"]] = fullpath
- end
- end
- end
+ desc "launchd service management framework.
+
+ This provider manages launchd jobs, the default service framework for
+ Mac OS X, that has also been open sourced by Apple for possible use on
+ other platforms.
+
+ See:
+ * http://developer.apple.com/macosx/launchd.html
+ * http://launchd.macosforge.org/
+
+ This provider reads plists out of the following directories:
+ * /System/Library/LaunchDaemons
+ * /System/Library/LaunchAgents
+ * /Library/LaunchDaemons
+ * /Library/LaunchAgents
+
+ and builds up a list of services based upon each plists \"Label\" entry.
+
+ This provider supports:
+ * ensure => running/stopped,
+ * enable => true/false
+ * status
+ * restart
+
+ Here is how the Puppet states correspond to launchd states:
+ * stopped => job unloaded
+ * started => job loaded
+ * enabled => 'Disable' removed from job plist file
+ * disabled => 'Disable' added to job plist file
+
+ Note that this allows you to do something launchctl can't do, which is to
+ be in a state of \"stopped/enabled\ or \"running/disabled\".
+
+ "
+
+ commands :launchctl => "/bin/launchctl"
+ commands :sw_vers => "/usr/bin/sw_vers"
+
+ defaultfor :operatingsystem => :darwin
+ confine :operatingsystem => :darwin
+
+ has_feature :enableable
+
+ Launchd_Paths = ["/Library/LaunchAgents",
+ "/Library/LaunchDaemons",
+ "/System/Library/LaunchAgents",
+ "/System/Library/LaunchDaemons",]
+
+ Launchd_Overrides = "/var/db/launchd.db/com.apple.launchd/overrides.plist"
+
+
+ # returns a label => path map for either all jobs, or just a single
+ # job if the label is specified
+ def self.jobsearch(label=nil)
+ label_to_path_map = {}
+ Launchd_Paths.each do |path|
+ if FileTest.exists?(path)
+ Dir.entries(path).each do |f|
+ next if f =~ /^\..*$/
+ next if FileTest.directory?(f)
+ fullpath = File.join(path, f)
+ job = Plist::parse_xml(fullpath)
+ if job and job.has_key?("Label")
+ if job["Label"] == label
+ return { label => fullpath }
+ else
+ label_to_path_map[job["Label"]] = fullpath
end
+ end
end
-
- # if we didn't find the job above and we should have, error.
- raise Puppet::Error.new("Unable to find launchd plist for job: #{label}") if label
- # if returning all jobs
- label_to_path_map
- end
-
-
- def self.instances
- jobs = self.jobsearch
- jobs.keys.collect do |job|
- new(:name => job, :provider => :launchd, :path => jobs[job])
- end
+ end
end
+ # if we didn't find the job above and we should have, error.
+ raise Puppet::Error.new("Unable to find launchd plist for job: #{label}") if label
+ # if returning all jobs
+ label_to_path_map
+ end
- def self.get_macosx_version_major
- return @macosx_version_major if defined?(@macosx_version_major)
- begin
- # Make sure we've loaded all of the facts
- Facter.loadfacts
- if Facter.value(:macosx_productversion_major)
- product_version_major = Facter.value(:macosx_productversion_major)
- else
- # TODO: remove this code chunk once we require Facter 1.5.5 or higher.
- Puppet.warning("DEPRECATION WARNING: Future versions of the launchd provider will require Facter 1.5.5 or newer.")
- product_version = Facter.value(:macosx_productversion)
- fail("Could not determine OS X version from Facter") if product_version.nil?
- product_version_major = product_version.scan(/(\d+)\.(\d+)./).join(".")
- end
- fail("#{product_version_major} is not supported by the launchd provider") if %w{10.0 10.1 10.2 10.3}.include?(product_version_major)
- @macosx_version_major = product_version_major
- return @macosx_version_major
- rescue Puppet::ExecutionFailure => detail
- fail("Could not determine OS X version: #{detail}")
- end
+ def self.instances
+ jobs = self.jobsearch
+ jobs.keys.collect do |job|
+ new(:name => job, :provider => :launchd, :path => jobs[job])
end
-
-
- # finds the path for a given label and returns the path and parsed plist
- # as an array of [path, plist]. Note plist is really a Hash here.
- def plist_from_label(label)
- job = self.class.jobsearch(label)
- job_path = job[label]
- job_plist = Plist::parse_xml(job_path)
- raise Puppet::Error.new("Unable to parse launchd plist at path: #{job_path}") if not job_plist
- [job_path, job_plist]
+ end
+
+
+ def self.get_macosx_version_major
+ return @macosx_version_major if defined?(@macosx_version_major)
+ begin
+ # Make sure we've loaded all of the facts
+ Facter.loadfacts
+
+ if Facter.value(:macosx_productversion_major)
+ product_version_major = Facter.value(:macosx_productversion_major)
+ else
+ # TODO: remove this code chunk once we require Facter 1.5.5 or higher.
+ Puppet.warning("DEPRECATION WARNING: Future versions of the launchd provider will require Facter 1.5.5 or newer.")
+ product_version = Facter.value(:macosx_productversion)
+ fail("Could not determine OS X version from Facter") if product_version.nil?
+ product_version_major = product_version.scan(/(\d+)\.(\d+)./).join(".")
+ end
+ fail("#{product_version_major} is not supported by the launchd provider") if %w{10.0 10.1 10.2 10.3}.include?(product_version_major)
+ @macosx_version_major = product_version_major
+ return @macosx_version_major
+ rescue Puppet::ExecutionFailure => detail
+ fail("Could not determine OS X version: #{detail}")
end
-
-
- def status
- # launchctl list <jobname> exits zero if the job is loaded
- # and non-zero if it isn't. Simple way to check... but is only
- # available on OS X 10.5 unfortunately, so we grab the whole list
- # and check if our resource is included. The output formats differ
- # between 10.4 and 10.5, thus the necessity for splitting
- begin
- output = launchctl :list
- raise Puppet::Error.new("launchctl list failed to return any data.") if output.nil?
- output.split("\n").each do |j|
- return :running if j.split(/\s/).last == resource[:name]
- end
- return :stopped
- rescue Puppet::ExecutionFailure
- raise Puppet::Error.new("Unable to determine status of #{resource[:name]}")
- end
+ end
+
+
+ # finds the path for a given label and returns the path and parsed plist
+ # as an array of [path, plist]. Note plist is really a Hash here.
+ def plist_from_label(label)
+ job = self.class.jobsearch(label)
+ job_path = job[label]
+ job_plist = Plist::parse_xml(job_path)
+ raise Puppet::Error.new("Unable to parse launchd plist at path: #{job_path}") if not job_plist
+ [job_path, job_plist]
+ end
+
+
+ def status
+ # launchctl list <jobname> exits zero if the job is loaded
+ # and non-zero if it isn't. Simple way to check... but is only
+ # available on OS X 10.5 unfortunately, so we grab the whole list
+ # and check if our resource is included. The output formats differ
+ # between 10.4 and 10.5, thus the necessity for splitting
+ begin
+ output = launchctl :list
+ raise Puppet::Error.new("launchctl list failed to return any data.") if output.nil?
+ output.split("\n").each do |j|
+ return :running if j.split(/\s/).last == resource[:name]
+ end
+ return :stopped
+ rescue Puppet::ExecutionFailure
+ raise Puppet::Error.new("Unable to determine status of #{resource[:name]}")
end
-
-
- # start the service. To get to a state of running/enabled, we need to
- # conditionally enable at load, then disable by modifying the plist file
- # directly.
- def start
- job_path, job_plist = plist_from_label(resource[:name])
- did_enable_job = false
- cmds = []
- cmds << :launchctl << :load
- if self.enabled? == :false # launchctl won't load disabled jobs
- cmds << "-w"
- did_enable_job = true
- end
- cmds << job_path
- begin
- execute(cmds)
- rescue Puppet::ExecutionFailure
- raise Puppet::Error.new("Unable to start service: #{resource[:name]} at path: #{job_path}")
- end
- # As load -w clears the Disabled flag, we need to add it in after
- self.disable if did_enable_job and resource[:enable] == :false
+ end
+
+
+ # start the service. To get to a state of running/enabled, we need to
+ # conditionally enable at load, then disable by modifying the plist file
+ # directly.
+ def start
+ job_path, job_plist = plist_from_label(resource[:name])
+ did_enable_job = false
+ cmds = []
+ cmds << :launchctl << :load
+ if self.enabled? == :false # launchctl won't load disabled jobs
+ cmds << "-w"
+ did_enable_job = true
end
-
-
- def stop
- job_path, job_plist = plist_from_label(resource[:name])
- did_disable_job = false
- cmds = []
- cmds << :launchctl << :unload
- if self.enabled? == :true # keepalive jobs can't be stopped without disabling
- cmds << "-w"
- did_disable_job = true
- end
- cmds << job_path
- begin
- execute(cmds)
- rescue Puppet::ExecutionFailure
- raise Puppet::Error.new("Unable to stop service: #{resource[:name]} at path: #{job_path}")
- end
- # As unload -w sets the Disabled flag, we need to add it in after
- self.enable if did_disable_job and resource[:enable] == :true
+ cmds << job_path
+ begin
+ execute(cmds)
+ rescue Puppet::ExecutionFailure
+ raise Puppet::Error.new("Unable to start service: #{resource[:name]} at path: #{job_path}")
end
-
-
- # launchd jobs are enabled by default. They are only disabled if the key
- # "Disabled" is set to true, but it can also be set to false to enable it.
- # In 10.6, the Disabled key in the job plist is consulted, but only if there
- # is no entry in the global overrides plist.
- # We need to draw a distinction between undefined, true and false for both
- # locations where the Disabled flag can be defined.
- def enabled?
- job_plist_disabled = nil
- overrides_disabled = nil
-
- job_path, job_plist = plist_from_label(resource[:name])
- job_plist_disabled = job_plist["Disabled"] if job_plist.has_key?("Disabled")
-
- if self.class.get_macosx_version_major == "10.6":
- overrides = Plist::parse_xml(Launchd_Overrides)
-
- unless overrides.nil?
- if overrides.has_key?(resource[:name])
- overrides_disabled = overrides[resource[:name]]["Disabled"] if overrides[resource[:name]].has_key?("Disabled")
- end
- end
- end
-
- if overrides_disabled.nil?
- if job_plist_disabled.nil? or job_plist_disabled == false
- return :true
- end
- elsif overrides_disabled == false
- return :true
- end
- :false
+ # As load -w clears the Disabled flag, we need to add it in after
+ self.disable if did_enable_job and resource[:enable] == :false
+ end
+
+
+ def stop
+ job_path, job_plist = plist_from_label(resource[:name])
+ did_disable_job = false
+ cmds = []
+ cmds << :launchctl << :unload
+ if self.enabled? == :true # keepalive jobs can't be stopped without disabling
+ cmds << "-w"
+ did_disable_job = true
end
-
-
- # enable and disable are a bit hacky. We write out the plist with the appropriate value
- # rather than dealing with launchctl as it is unable to change the Disabled flag
- # without actually loading/unloading the job.
- # In 10.6 we need to write out a disabled key to the global overrides plist, in earlier
- # versions this is stored in the job plist itself.
- def enable
- if self.class.get_macosx_version_major == "10.6"
- overrides = Plist::parse_xml(Launchd_Overrides)
- overrides[resource[:name]] = { "Disabled" => false }
- Plist::Emit.save_plist(overrides, Launchd_Overrides)
- else
- job_path, job_plist = plist_from_label(resource[:name])
- if self.enabled? == :false
- job_plist.delete("Disabled")
- Plist::Emit.save_plist(job_plist, job_path)
- end
+ cmds << job_path
+ begin
+ execute(cmds)
+ rescue Puppet::ExecutionFailure
+ raise Puppet::Error.new("Unable to stop service: #{resource[:name]} at path: #{job_path}")
+ end
+ # As unload -w sets the Disabled flag, we need to add it in after
+ self.enable if did_disable_job and resource[:enable] == :true
+ end
+
+
+ # launchd jobs are enabled by default. They are only disabled if the key
+ # "Disabled" is set to true, but it can also be set to false to enable it.
+ # In 10.6, the Disabled key in the job plist is consulted, but only if there
+ # is no entry in the global overrides plist.
+ # We need to draw a distinction between undefined, true and false for both
+ # locations where the Disabled flag can be defined.
+ def enabled?
+ job_plist_disabled = nil
+ overrides_disabled = nil
+
+ job_path, job_plist = plist_from_label(resource[:name])
+ job_plist_disabled = job_plist["Disabled"] if job_plist.has_key?("Disabled")
+
+ if self.class.get_macosx_version_major == "10.6":
+ overrides = Plist::parse_xml(Launchd_Overrides)
+
+ unless overrides.nil?
+ if overrides.has_key?(resource[:name])
+ overrides_disabled = overrides[resource[:name]]["Disabled"] if overrides[resource[:name]].has_key?("Disabled")
end
+ end
end
-
- def disable
- if self.class.get_macosx_version_major == "10.6"
- overrides = Plist::parse_xml(Launchd_Overrides)
- overrides[resource[:name]] = { "Disabled" => true }
- Plist::Emit.save_plist(overrides, Launchd_Overrides)
- else
- job_path, job_plist = plist_from_label(resource[:name])
- job_plist["Disabled"] = true
- Plist::Emit.save_plist(job_plist, job_path)
- end
+ if overrides_disabled.nil?
+ if job_plist_disabled.nil? or job_plist_disabled == false
+ return :true
+ end
+ elsif overrides_disabled == false
+ return :true
+ end
+ :false
+ end
+
+
+ # enable and disable are a bit hacky. We write out the plist with the appropriate value
+ # rather than dealing with launchctl as it is unable to change the Disabled flag
+ # without actually loading/unloading the job.
+ # In 10.6 we need to write out a disabled key to the global overrides plist, in earlier
+ # versions this is stored in the job plist itself.
+ def enable
+ if self.class.get_macosx_version_major == "10.6"
+ overrides = Plist::parse_xml(Launchd_Overrides)
+ overrides[resource[:name]] = { "Disabled" => false }
+ Plist::Emit.save_plist(overrides, Launchd_Overrides)
+ else
+ job_path, job_plist = plist_from_label(resource[:name])
+ if self.enabled? == :false
+ job_plist.delete("Disabled")
+ Plist::Emit.save_plist(job_plist, job_path)
+ end
+ end
+ end
+
+
+ def disable
+ if self.class.get_macosx_version_major == "10.6"
+ overrides = Plist::parse_xml(Launchd_Overrides)
+ overrides[resource[:name]] = { "Disabled" => true }
+ Plist::Emit.save_plist(overrides, Launchd_Overrides)
+ else
+ job_path, job_plist = plist_from_label(resource[:name])
+ job_plist["Disabled"] = true
+ Plist::Emit.save_plist(job_plist, job_path)
end
+ end
end
diff --git a/lib/puppet/provider/service/redhat.rb b/lib/puppet/provider/service/redhat.rb
index 3a25db3..3ca67d6 100755
--- a/lib/puppet/provider/service/redhat.rb
+++ b/lib/puppet/provider/service/redhat.rb
@@ -1,76 +1,76 @@
# Manage Red Hat services. Start/stop uses /sbin/service and enable/disable uses chkconfig
Puppet::Type.type(:service).provide :redhat, :parent => :init, :source => :init do
- desc "Red Hat's (and probably many others) form of ``init``-style service management:
+ desc "Red Hat's (and probably many others) form of ``init``-style service management:
- Uses ``chkconfig`` for service enabling and disabling.
+ Uses ``chkconfig`` for service enabling and disabling.
- "
+ "
- commands :chkconfig => "/sbin/chkconfig", :service => "/sbin/service"
+ commands :chkconfig => "/sbin/chkconfig", :service => "/sbin/service"
- defaultfor :operatingsystem => [:redhat, :fedora, :suse, :centos, :sles, :oel, :ovm]
+ defaultfor :operatingsystem => [:redhat, :fedora, :suse, :centos, :sles, :oel, :ovm]
- def self.instances
- # this exclude list is all from /sbin/service (5.x), but I did not exclude kudzu
- self.get_services(['/etc/init.d'], ['functions', 'halt', 'killall', 'single', 'linuxconf'])
- end
-
- def self.defpath
- superclass.defpath
- end
-
- # Remove the symlinks
- def disable
- output = chkconfig(@resource[:name], :off)
- rescue Puppet::ExecutionFailure
- raise Puppet::Error, "Could not disable #{self.name}: #{output}"
- end
-
- def enabled?
- begin
- output = chkconfig(@resource[:name])
- rescue Puppet::ExecutionFailure
- return :false
- end
-
- # If it's disabled on SuSE, then it will print output showing "off"
- # at the end
- if output =~ /.* off$/
- return :false
- end
+ def self.instances
+ # this exclude list is all from /sbin/service (5.x), but I did not exclude kudzu
+ self.get_services(['/etc/init.d'], ['functions', 'halt', 'killall', 'single', 'linuxconf'])
+ end
- :true
- end
-
- # Don't support them specifying runlevels; always use the runlevels
- # in the init scripts.
- def enable
- output = chkconfig(@resource[:name], :on)
- rescue Puppet::ExecutionFailure => detail
- raise Puppet::Error, "Could not enable #{self.name}: #{detail}"
- end
-
- def initscript
- raise Puppet::Error, "Do not directly call the init script for '#{@resource[:name]}'; use 'service' instead"
- end
+ def self.defpath
+ superclass.defpath
+ end
- # use hasstatus=>true when its set for the provider.
- def statuscmd
- ((@resource.provider.get(:hasstatus) == true) || (@resource[:hasstatus] == :true)) && [command(:service), @resource[:name], "status"]
- end
+ # Remove the symlinks
+ def disable
+ output = chkconfig(@resource[:name], :off)
+ rescue Puppet::ExecutionFailure
+ raise Puppet::Error, "Could not disable #{self.name}: #{output}"
+ end
- def restartcmd
- (@resource[:hasrestart] == :true) && [command(:service), @resource[:name], "restart"]
+ def enabled?
+ begin
+ output = chkconfig(@resource[:name])
+ rescue Puppet::ExecutionFailure
+ return :false
end
- def startcmd
- [command(:service), @resource[:name], "start"]
+ # If it's disabled on SuSE, then it will print output showing "off"
+ # at the end
+ if output =~ /.* off$/
+ return :false
end
- def stopcmd
- [command(:service), @resource[:name], "stop"]
- end
+ :true
+ end
+
+ # Don't support them specifying runlevels; always use the runlevels
+ # in the init scripts.
+ def enable
+ output = chkconfig(@resource[:name], :on)
+ rescue Puppet::ExecutionFailure => detail
+ raise Puppet::Error, "Could not enable #{self.name}: #{detail}"
+ end
+
+ def initscript
+ raise Puppet::Error, "Do not directly call the init script for '#{@resource[:name]}'; use 'service' instead"
+ end
+
+ # use hasstatus=>true when its set for the provider.
+ def statuscmd
+ ((@resource.provider.get(:hasstatus) == true) || (@resource[:hasstatus] == :true)) && [command(:service), @resource[:name], "status"]
+ end
+
+ def restartcmd
+ (@resource[:hasrestart] == :true) && [command(:service), @resource[:name], "restart"]
+ end
+
+ def startcmd
+ [command(:service), @resource[:name], "start"]
+ end
+
+ def stopcmd
+ [command(:service), @resource[:name], "stop"]
+ end
end
diff --git a/lib/puppet/provider/service/runit.rb b/lib/puppet/provider/service/runit.rb
index c2603c9..0315b95 100644
--- a/lib/puppet/provider/service/runit.rb
+++ b/lib/puppet/provider/service/runit.rb
@@ -2,102 +2,102 @@
#
# author Brice Figureau <brice-puppet at daysofwonder.com>
Puppet::Type.type(:service).provide :runit, :parent => :daemontools do
- desc "Runit service management.
+ desc "Runit service management.
- This provider manages daemons running supervised by Runit.
- It tries to detect the service directory, with by order of preference:
+ This provider manages daemons running supervised by Runit.
+ It tries to detect the service directory, with by order of preference:
- * /service
- * /var/service
- * /etc/service
+ * /service
+ * /var/service
+ * /etc/service
- The daemon directory should be placed in a directory that can be
- by default in:
+ The daemon directory should be placed in a directory that can be
+ by default in:
- * /etc/sv
+ * /etc/sv
- or this can be overriden in the service resource parameters::
+ or this can be overriden in the service resource parameters::
- service {
- \"myservice\":
- provider => \"runit\", path => \"/path/to/daemons\";
- }
+ service {
+ \"myservice\":
+ provider => \"runit\", path => \"/path/to/daemons\";
+ }
- This provider supports out of the box:
+ This provider supports out of the box:
- * start/stop
- * enable/disable
- * restart
- * status
+ * start/stop
+ * enable/disable
+ * restart
+ * status
"
- commands :sv => "/usr/bin/sv"
-
- class << self
- # this is necessary to autodetect a valid resource
- # default path, since there is no standard for such directory.
- def defpath(dummy_argument=:work_arround_for_ruby_GC_bug)
- unless @defpath
- ["/etc/sv", "/var/lib/service"].each do |path|
- if FileTest.exist?(path)
- @defpath = path
- break
- end
- end
- raise "Could not find the daemon directory (tested [/var/lib/service,/etc])" unless @defpath
- end
- @defpath
+ commands :sv => "/usr/bin/sv"
+
+ class << self
+ # this is necessary to autodetect a valid resource
+ # default path, since there is no standard for such directory.
+ def defpath(dummy_argument=:work_arround_for_ruby_GC_bug)
+ unless @defpath
+ ["/etc/sv", "/var/lib/service"].each do |path|
+ if FileTest.exist?(path)
+ @defpath = path
+ break
+ end
end
+ raise "Could not find the daemon directory (tested [/var/lib/service,/etc])" unless @defpath
+ end
+ @defpath
end
-
- # find the service dir on this node
- def servicedir
- unless @servicedir
- ["/service", "/etc/service","/var/service"].each do |path|
- if FileTest.exist?(path)
- @servicedir = path
- break
- end
- end
- raise "Could not find service directory" unless @servicedir
- end
- @servicedir
- end
-
- def status
- begin
- output = sv "status", self.daemon
- return :running if output =~ /^run: /
- rescue Puppet::ExecutionFailure => detail
- unless detail.message =~ /(warning: |runsv not running$)/
- raise Puppet::Error.new( "Could not get status for service #{resource.ref}: #{detail}" )
- end
+ end
+
+ # find the service dir on this node
+ def servicedir
+ unless @servicedir
+ ["/service", "/etc/service","/var/service"].each do |path|
+ if FileTest.exist?(path)
+ @servicedir = path
+ break
end
- :stopped
- end
-
- def stop
- sv "stop", self.service
+ end
+ raise "Could not find service directory" unless @servicedir
end
-
- def start
- enable unless enabled? == :true
- sv "start", self.service
- end
-
- def restart
- sv "restart", self.service
- end
-
- # disable by removing the symlink so that runit
- # doesn't restart our service behind our back
- # note that runit doesn't need to perform a stop
- # before a disable
- def disable
- # unlink the daemon symlink to disable it
- File.unlink(self.service) if FileTest.symlink?(self.service)
+ @servicedir
+ end
+
+ def status
+ begin
+ output = sv "status", self.daemon
+ return :running if output =~ /^run: /
+ rescue Puppet::ExecutionFailure => detail
+ unless detail.message =~ /(warning: |runsv not running$)/
+ raise Puppet::Error.new( "Could not get status for service #{resource.ref}: #{detail}" )
+ end
end
+ :stopped
+ end
+
+ def stop
+ sv "stop", self.service
+ end
+
+ def start
+ enable unless enabled? == :true
+ sv "start", self.service
+ end
+
+ def restart
+ sv "restart", self.service
+ end
+
+ # disable by removing the symlink so that runit
+ # doesn't restart our service behind our back
+ # note that runit doesn't need to perform a stop
+ # before a disable
+ def disable
+ # unlink the daemon symlink to disable it
+ File.unlink(self.service) if FileTest.symlink?(self.service)
+ end
end
diff --git a/lib/puppet/provider/service/smf.rb b/lib/puppet/provider/service/smf.rb
index ca7af94..3efb2eb 100755
--- a/lib/puppet/provider/service/smf.rb
+++ b/lib/puppet/provider/service/smf.rb
@@ -1,103 +1,103 @@
# Solaris 10 SMF-style services.
Puppet::Type.type(:service).provide :smf, :parent => :base do
- desc "Support for Sun's new Service Management Framework.
+ desc "Support for Sun's new Service Management Framework.
- Starting a service is effectively equivalent to enabling it, so there is
- only support for starting and stopping services, which also enables and
- disables them, respectively.
+ Starting a service is effectively equivalent to enabling it, so there is
+ only support for starting and stopping services, which also enables and
+ disables them, respectively.
- By specifying manifest => \"/path/to/service.xml\", the SMF manifest will
- be imported if it does not exist.
+ By specifying manifest => \"/path/to/service.xml\", the SMF manifest will
+ be imported if it does not exist.
- "
+ "
- defaultfor :operatingsystem => :solaris
+ defaultfor :operatingsystem => :solaris
- confine :operatingsystem => :solaris
+ confine :operatingsystem => :solaris
- commands :adm => "/usr/sbin/svcadm", :svcs => "/usr/bin/svcs"
- commands :svccfg => "/usr/sbin/svccfg"
+ commands :adm => "/usr/sbin/svcadm", :svcs => "/usr/bin/svcs"
+ commands :svccfg => "/usr/sbin/svccfg"
- def setupservice
- if resource[:manifest]
- [command(:svcs), "-l", @resource[:name]]
- if $CHILD_STATUS.exitstatus == 1
- Puppet.notice "Importing #{@resource[:manifest]} for #{@resource[:name]}"
- svccfg :import, resource[:manifest]
- end
- end
- rescue Puppet::ExecutionFailure => detail
- raise Puppet::Error.new( "Cannot config #{self.service} to enable it: #{detail}" )
- end
-
- def enable
- self.start
- end
-
- def enabled?
- case self.status
- when :running
- return :true
- else
- return :false
+ def setupservice
+ if resource[:manifest]
+ [command(:svcs), "-l", @resource[:name]]
+ if $CHILD_STATUS.exitstatus == 1
+ Puppet.notice "Importing #{@resource[:manifest]} for #{@resource[:name]}"
+ svccfg :import, resource[:manifest]
end
+ end
+ rescue Puppet::ExecutionFailure => detail
+ raise Puppet::Error.new( "Cannot config #{self.service} to enable it: #{detail}" )
+ end
+
+ def enable
+ self.start
+ end
+
+ def enabled?
+ case self.status
+ when :running
+ return :true
+ else
+ return :false
end
-
- def disable
- self.stop
+ end
+
+ def disable
+ self.stop
+ end
+
+ def restartcmd
+ [command(:adm), :restart, @resource[:name]]
+ end
+
+ def startcmd
+ self.setupservice
+ case self.status
+ when :stopped
+ [command(:adm), :enable, @resource[:name]]
+ when :maintenance
+ [command(:adm), :clear, @resource[:name]]
end
+ end
- def restartcmd
- [command(:adm), :restart, @resource[:name]]
+ def status
+ if @resource[:status]
+ super
+ return
end
- def startcmd
- self.setupservice
- case self.status
- when :stopped
- [command(:adm), :enable, @resource[:name]]
- when :maintenance
- [command(:adm), :clear, @resource[:name]]
- end
+ begin
+ # get the current state and the next state, and if the next
+ # state is set (i.e. not "-") use it for state comparison
+ states = svcs("-H", "-o", "state,nstate", @resource[:name]).chomp.split
+ state = states[1] == "-" ? states[0] : states[1]
+ rescue Puppet::ExecutionFailure
+ info "Could not get status on service #{self.name}"
+ return :stopped
end
- def status
- if @resource[:status]
- super
- return
- end
-
- begin
- # get the current state and the next state, and if the next
- # state is set (i.e. not "-") use it for state comparison
- states = svcs("-H", "-o", "state,nstate", @resource[:name]).chomp.split
- state = states[1] == "-" ? states[0] : states[1]
- rescue Puppet::ExecutionFailure
- info "Could not get status on service #{self.name}"
- return :stopped
- end
-
- case state
- when "online"
- #self.warning "matched running #{line.inspect}"
- return :running
- when "offline", "disabled", "uninitialized"
- #self.warning "matched stopped #{line.inspect}"
- return :stopped
- when "maintenance"
- return :maintenance
- when "legacy_run"
- raise Puppet::Error,
- "Cannot manage legacy services through SMF"
- else
- raise Puppet::Error,
- "Unmanageable state '#{state}' on service #{self.name}"
- end
-
+ case state
+ when "online"
+ #self.warning "matched running #{line.inspect}"
+ return :running
+ when "offline", "disabled", "uninitialized"
+ #self.warning "matched stopped #{line.inspect}"
+ return :stopped
+ when "maintenance"
+ return :maintenance
+ when "legacy_run"
+ raise Puppet::Error,
+ "Cannot manage legacy services through SMF"
+ else
+ raise Puppet::Error,
+ "Unmanageable state '#{state}' on service #{self.name}"
end
- def stopcmd
- [command(:adm), :disable, @resource[:name]]
- end
+ end
+
+ def stopcmd
+ [command(:adm), :disable, @resource[:name]]
+ end
end
diff --git a/lib/puppet/provider/service/src.rb b/lib/puppet/provider/service/src.rb
index aed88d5..2bd643c 100755
--- a/lib/puppet/provider/service/src.rb
+++ b/lib/puppet/provider/service/src.rb
@@ -1,87 +1,87 @@
# AIX System Resource controller (SRC)
Puppet::Type.type(:service).provide :src, :parent => :base do
- desc "Support for AIX's System Resource controller.
-
- Services are started/stopped based on the stopsrc and startsrc
- commands, and some services can be refreshed with refresh command.
-
- * Enabling and disableing services is not supported, as it requires
- modifications to /etc/inittab.
-
- * Starting and stopping groups of subsystems is not yet supported
- "
-
- defaultfor :operatingsystem => :aix
- confine :operatingsystem => :aix
-
- commands :stopsrc => "/usr/bin/stopsrc"
- commands :startsrc => "/usr/bin/startsrc"
- commands :refresh => "/usr/bin/refresh"
- commands :lssrc => "/usr/bin/lssrc"
-
- has_feature :refreshable
-
- def startcmd
- [command(:startsrc), "-s", @resource[:name]]
- end
-
- def stopcmd
- [command(:stopsrc), "-s", @resource[:name]]
- end
-
- def restart
- execute([command(:lssrc), "-Ss", @resource[:name]]).each do |line|
- args = line.split(":")
-
- next unless args[0] == @resource[:name]
-
- # Subsystems with the -K flag can get refreshed (HUPed)
- # While subsystems with -S (signals) must be stopped/started
- method = args[11]
- do_refresh = case method
- when "-K" then :true
- when "-S" then :false
- else self.fail("Unknown service communication method #{method}")
- end
-
- begin
- if do_refresh == :true
- execute([command(:refresh), "-s", @resource[:name]])
- else
- self.stop
- self.start
- end
- return :true
- rescue Puppet::ExecutionFailure => detail
- raise Puppet::Error.new("Unable to restart service #{@resource[:name]}, error was: #{detail}" )
- end
- end
- self.fail("No such service found")
- rescue Puppet::ExecutionFailure => detail
- raise Puppet::Error.new("Cannot get status of #{@resource[:name]}, error was: #{detail}" )
- end
-
- def status
- execute([command(:lssrc), "-s", @resource[:name]]).each do |line|
- args = line.split
-
- # This is the header line
- next unless args[0] == @resource[:name]
-
- # PID is the 3rd field, but inoperative subsystems
- # skip this so split doesn't work right
- state = case args[-1]
- when "active" then :running
- when "inoperative" then :stopped
- end
- Puppet.debug("Service #{@resource[:name]} is #{args[-1]}")
- return state
- end
- self.fail("No such service found")
- rescue Puppet::ExecutionFailure => detail
- raise Puppet::Error.new("Cannot get status of #{@resource[:name]}, error was: #{detail}" )
- end
+ desc "Support for AIX's System Resource controller.
+
+ Services are started/stopped based on the stopsrc and startsrc
+ commands, and some services can be refreshed with refresh command.
+
+ * Enabling and disableing services is not supported, as it requires
+ modifications to /etc/inittab.
+
+ * Starting and stopping groups of subsystems is not yet supported
+ "
+
+ defaultfor :operatingsystem => :aix
+ confine :operatingsystem => :aix
+
+ commands :stopsrc => "/usr/bin/stopsrc"
+ commands :startsrc => "/usr/bin/startsrc"
+ commands :refresh => "/usr/bin/refresh"
+ commands :lssrc => "/usr/bin/lssrc"
+
+ has_feature :refreshable
+
+ def startcmd
+ [command(:startsrc), "-s", @resource[:name]]
+ end
+
+ def stopcmd
+ [command(:stopsrc), "-s", @resource[:name]]
+ end
+
+ def restart
+ execute([command(:lssrc), "-Ss", @resource[:name]]).each do |line|
+ args = line.split(":")
+
+ next unless args[0] == @resource[:name]
+
+ # Subsystems with the -K flag can get refreshed (HUPed)
+ # While subsystems with -S (signals) must be stopped/started
+ method = args[11]
+ do_refresh = case method
+ when "-K" then :true
+ when "-S" then :false
+ else self.fail("Unknown service communication method #{method}")
+ end
+
+ begin
+ if do_refresh == :true
+ execute([command(:refresh), "-s", @resource[:name]])
+ else
+ self.stop
+ self.start
+ end
+ return :true
+ rescue Puppet::ExecutionFailure => detail
+ raise Puppet::Error.new("Unable to restart service #{@resource[:name]}, error was: #{detail}" )
+ end
+ end
+ self.fail("No such service found")
+ rescue Puppet::ExecutionFailure => detail
+ raise Puppet::Error.new("Cannot get status of #{@resource[:name]}, error was: #{detail}" )
+ end
+
+ def status
+ execute([command(:lssrc), "-s", @resource[:name]]).each do |line|
+ args = line.split
+
+ # This is the header line
+ next unless args[0] == @resource[:name]
+
+ # PID is the 3rd field, but inoperative subsystems
+ # skip this so split doesn't work right
+ state = case args[-1]
+ when "active" then :running
+ when "inoperative" then :stopped
+ end
+ Puppet.debug("Service #{@resource[:name]} is #{args[-1]}")
+ return state
+ end
+ self.fail("No such service found")
+ rescue Puppet::ExecutionFailure => detail
+ raise Puppet::Error.new("Cannot get status of #{@resource[:name]}, error was: #{detail}" )
+ end
end
diff --git a/lib/puppet/provider/ssh_authorized_key/parsed.rb b/lib/puppet/provider/ssh_authorized_key/parsed.rb
index a9738e7..82f6b88 100644
--- a/lib/puppet/provider/ssh_authorized_key/parsed.rb
+++ b/lib/puppet/provider/ssh_authorized_key/parsed.rb
@@ -1,89 +1,89 @@
require 'puppet/provider/parsedfile'
- Puppet::Type.type(:ssh_authorized_key).provide(
- :parsed,
- :parent => Puppet::Provider::ParsedFile,
- :filetype => :flat,
+ Puppet::Type.type(:ssh_authorized_key).provide(
+ :parsed,
+ :parent => Puppet::Provider::ParsedFile,
+ :filetype => :flat,
- :default_target => ''
+ :default_target => ''
) do
- desc "Parse and generate authorized_keys files for SSH."
+ desc "Parse and generate authorized_keys files for SSH."
- text_line :comment, :match => /^#/
- text_line :blank, :match => /^\s+/
+ text_line :comment, :match => /^#/
+ text_line :blank, :match => /^\s+/
- record_line :parsed,
- :fields => %w{options type key name},
- :optional => %w{options},
- :rts => /^\s+/,
- :match => /^(?:(.+) )?(ssh-dss|ssh-rsa) ([^ ]+) ?(.*)$/,
- :post_parse => proc { |h|
- h[:name] = "" if h[:name] == :absent
- h[:options] ||= [:absent]
- h[:options] = Puppet::Type::Ssh_authorized_key::ProviderParsed.parse_options(h[:options]) if h[:options].is_a? String
- },
- :pre_gen => proc { |h|
- h[:options] = [] if h[:options].include?(:absent)
- h[:options] = h[:options].join(',')
- }
+ record_line :parsed,
+ :fields => %w{options type key name},
+ :optional => %w{options},
+ :rts => /^\s+/,
+ :match => /^(?:(.+) )?(ssh-dss|ssh-rsa) ([^ ]+) ?(.*)$/,
+ :post_parse => proc { |h|
+ h[:name] = "" if h[:name] == :absent
+ h[:options] ||= [:absent]
+ h[:options] = Puppet::Type::Ssh_authorized_key::ProviderParsed.parse_options(h[:options]) if h[:options].is_a? String
+ },
+ :pre_gen => proc { |h|
+ h[:options] = [] if h[:options].include?(:absent)
+ h[:options] = h[:options].join(',')
+ }
- record_line :key_v1,
- :fields => %w{options bits exponent modulus name},
- :optional => %w{options},
- :rts => /^\s+/,
- :match => /^(?:(.+) )?(\d+) (\d+) (\d+)(?: (.+))?$/
+ record_line :key_v1,
+ :fields => %w{options bits exponent modulus name},
+ :optional => %w{options},
+ :rts => /^\s+/,
+ :match => /^(?:(.+) )?(\d+) (\d+) (\d+)(?: (.+))?$/
- def dir_perm
- 0700
- end
+ def dir_perm
+ 0700
+ end
- def file_perm
- 0600
- end
+ def file_perm
+ 0600
+ end
- def target
- @resource.should(:target) || File.expand_path("~#{@resource.should(:user)}/.ssh/authorized_keys")
- rescue
- raise Puppet::Error, "Target not defined and/or specified user does not exist yet"
- end
+ def target
+ @resource.should(:target) || File.expand_path("~#{@resource.should(:user)}/.ssh/authorized_keys")
+ rescue
+ raise Puppet::Error, "Target not defined and/or specified user does not exist yet"
+ end
- def user
- uid = File.stat(target).uid
- Etc.getpwuid(uid).name
- end
+ def user
+ uid = File.stat(target).uid
+ Etc.getpwuid(uid).name
+ end
- def flush
- raise Puppet::Error, "Cannot write SSH authorized keys without user" unless @resource.should(:user)
- raise Puppet::Error, "User '#{@resource.should(:user)}' does not exist" unless uid = Puppet::Util.uid(@resource.should(:user))
- unless File.exist?(dir = File.dirname(target))
- Puppet.debug "Creating #{dir}"
- Dir.mkdir(dir, dir_perm)
- File.chown(uid, nil, dir)
- end
- Puppet::Util::SUIDManager.asuser(@resource.should(:user)) { super }
- File.chown(uid, nil, target)
- File.chmod(file_perm, target)
+ def flush
+ raise Puppet::Error, "Cannot write SSH authorized keys without user" unless @resource.should(:user)
+ raise Puppet::Error, "User '#{@resource.should(:user)}' does not exist" unless uid = Puppet::Util.uid(@resource.should(:user))
+ unless File.exist?(dir = File.dirname(target))
+ Puppet.debug "Creating #{dir}"
+ Dir.mkdir(dir, dir_perm)
+ File.chown(uid, nil, dir)
end
+ Puppet::Util::SUIDManager.asuser(@resource.should(:user)) { super }
+ File.chown(uid, nil, target)
+ File.chmod(file_perm, target)
+ end
- # parse sshv2 option strings, wich is a comma separated list of
- # either key="values" elements or bare-word elements
- def self.parse_options(options)
- result = []
- scanner = StringScanner.new(options)
- while !scanner.eos?
- scanner.skip(/[ \t]*/)
- # scan a long option
- if out = scanner.scan(/[-a-z0-9A-Z_]+=\".*?\"/) or out = scanner.scan(/[-a-z0-9A-Z_]+/)
- result << out
- else
- # found an unscannable token, let's abort
- break
- end
- # eat a comma
- scanner.skip(/[ \t]*,[ \t]*/)
- end
- result
+ # parse sshv2 option strings, wich is a comma separated list of
+ # either key="values" elements or bare-word elements
+ def self.parse_options(options)
+ result = []
+ scanner = StringScanner.new(options)
+ while !scanner.eos?
+ scanner.skip(/[ \t]*/)
+ # scan a long option
+ if out = scanner.scan(/[-a-z0-9A-Z_]+=\".*?\"/) or out = scanner.scan(/[-a-z0-9A-Z_]+/)
+ result << out
+ else
+ # found an unscannable token, let's abort
+ break
+ end
+ # eat a comma
+ scanner.skip(/[ \t]*,[ \t]*/)
end
+ result
+ end
end
diff --git a/lib/puppet/provider/sshkey/parsed.rb b/lib/puppet/provider/sshkey/parsed.rb
index 4fefc40..dcc55b4 100755
--- a/lib/puppet/provider/sshkey/parsed.rb
+++ b/lib/puppet/provider/sshkey/parsed.rb
@@ -4,35 +4,35 @@ known = nil
case Facter.value(:operatingsystem)
when "Darwin"; known = "/etc/ssh_known_hosts"
else
- known = "/etc/ssh/ssh_known_hosts"
+ known = "/etc/ssh/ssh_known_hosts"
end
- Puppet::Type.type(:sshkey).provide(
- :parsed,
- :parent => Puppet::Provider::ParsedFile,
- :default_target => known,
+ Puppet::Type.type(:sshkey).provide(
+ :parsed,
+ :parent => Puppet::Provider::ParsedFile,
+ :default_target => known,
- :filetype => :flat
+ :filetype => :flat
) do
- desc "Parse and generate host-wide known hosts files for SSH."
+ desc "Parse and generate host-wide known hosts files for SSH."
- text_line :comment, :match => /^#/
- text_line :blank, :match => /^\s+/
+ text_line :comment, :match => /^#/
+ text_line :blank, :match => /^\s+/
- record_line :parsed, :fields => %w{name type key},
- :post_parse => proc { |hash|
- names = hash[:name].split(",", -1)
- hash[:name] = names.shift
- hash[:host_aliases] = names
- },
- :pre_gen => proc { |hash|
- if hash[:host_aliases]
- names = [hash[:name], hash[:host_aliases]].flatten
+ record_line :parsed, :fields => %w{name type key},
+ :post_parse => proc { |hash|
+ names = hash[:name].split(",", -1)
+ hash[:name] = names.shift
+ hash[:host_aliases] = names
+ },
+ :pre_gen => proc { |hash|
+ if hash[:host_aliases]
+ names = [hash[:name], hash[:host_aliases]].flatten
- hash[:name] = [hash[:name], hash[:host_aliases]].flatten.join(",")
- hash.delete(:host_aliases)
- end
- }
+ hash[:name] = [hash[:name], hash[:host_aliases]].flatten.join(",")
+ hash.delete(:host_aliases)
+ end
+ }
end
diff --git a/lib/puppet/provider/user/directoryservice.rb b/lib/puppet/provider/user/directoryservice.rb
index 46d017e..4b62a6a 100644
--- a/lib/puppet/provider/user/directoryservice.rb
+++ b/lib/puppet/provider/user/directoryservice.rb
@@ -15,86 +15,86 @@
require 'puppet/provider/nameservice/directoryservice'
Puppet::Type.type(:user).provide :directoryservice, :parent => Puppet::Provider::NameService::DirectoryService do
- desc "User management using DirectoryService on OS X."
+ desc "User management using DirectoryService on OS X."
- commands :dscl => "/usr/bin/dscl"
- confine :operatingsystem => :darwin
- defaultfor :operatingsystem => :darwin
+ commands :dscl => "/usr/bin/dscl"
+ confine :operatingsystem => :darwin
+ defaultfor :operatingsystem => :darwin
- # JJM: DirectoryService can manage passwords.
- # This needs to be a special option to dscl though (-passwd)
- has_feature :manages_passwords
+ # JJM: DirectoryService can manage passwords.
+ # This needs to be a special option to dscl though (-passwd)
+ has_feature :manages_passwords
- # JJM: comment matches up with the /etc/passwd concept of an user
- options :comment, :key => "realname"
- options :password, :key => "passwd"
+ # JJM: comment matches up with the /etc/passwd concept of an user
+ options :comment, :key => "realname"
+ options :password, :key => "passwd"
- autogen_defaults :home => "/var/empty", :shell => "/usr/bin/false"
+ autogen_defaults :home => "/var/empty", :shell => "/usr/bin/false"
- verify :gid, "GID must be an integer" do |value|
- value.is_a? Integer
- end
+ verify :gid, "GID must be an integer" do |value|
+ value.is_a? Integer
+ end
- verify :uid, "UID must be an integer" do |value|
- value.is_a? Integer
- end
+ verify :uid, "UID must be an integer" do |value|
+ value.is_a? Integer
+ end
- def autogen_comment
- @resource[:name].capitalize
- end
+ def autogen_comment
+ @resource[:name].capitalize
+ end
- # The list of all groups the user is a member of.
- # JJM: FIXME: Override this method...
- def groups
- groups = []
- groups.join(",")
- end
+ # The list of all groups the user is a member of.
+ # JJM: FIXME: Override this method...
+ def groups
+ groups = []
+ groups.join(",")
+ end
- # This is really lame. We have to iterate over each
- # of the groups and add us to them.
- def groups=(groups)
- # case groups
- # when Fixnum
- # groups = [groups.to_s]
- # when String
- # groups = groups.split(/\s*,\s*/)
- # else
- # raise Puppet::DevError, "got invalid groups value #{groups.class} of type #{groups}"
- # end
- # # Get just the groups we need to modify
- # diff = groups - (@is || [])
- #
- # data = {}
- # open("| #{command(:nireport)} / /groups name users") do |file|
- # file.each do |line|
- # name, members = line.split(/\s+/)
- #
- # if members.nil? or members =~ /NoValue/
- # data[name] = []
- # else
- # # Add each diff group's current members
- # data[name] = members.split(/,/)
- # end
- # end
- # end
- #
- # user = @resource[:name]
- # data.each do |name, members|
- # if members.include? user and groups.include? name
- # # I'm in the group and should be
- # next
- # elsif members.include? user
- # # I'm in the group and shouldn't be
- # setuserlist(name, members - [user])
- # elsif groups.include? name
- # # I'm not in the group and should be
- # setuserlist(name, members + [user])
- # else
- # # I'm not in the group and shouldn't be
- # next
- # end
- # end
- end
+ # This is really lame. We have to iterate over each
+ # of the groups and add us to them.
+ def groups=(groups)
+ # case groups
+ # when Fixnum
+ # groups = [groups.to_s]
+ # when String
+ # groups = groups.split(/\s*,\s*/)
+ # else
+ # raise Puppet::DevError, "got invalid groups value #{groups.class} of type #{groups}"
+ # end
+ # # Get just the groups we need to modify
+ # diff = groups - (@is || [])
+ #
+ # data = {}
+ # open("| #{command(:nireport)} / /groups name users") do |file|
+ # file.each do |line|
+ # name, members = line.split(/\s+/)
+ #
+ # if members.nil? or members =~ /NoValue/
+ # data[name] = []
+ # else
+ # # Add each diff group's current members
+ # data[name] = members.split(/,/)
+ # end
+ # end
+ # end
+ #
+ # user = @resource[:name]
+ # data.each do |name, members|
+ # if members.include? user and groups.include? name
+ # # I'm in the group and should be
+ # next
+ # elsif members.include? user
+ # # I'm in the group and shouldn't be
+ # setuserlist(name, members - [user])
+ # elsif groups.include? name
+ # # I'm not in the group and should be
+ # setuserlist(name, members + [user])
+ # else
+ # # I'm not in the group and shouldn't be
+ # next
+ # end
+ # end
+ end
end
diff --git a/lib/puppet/provider/user/hpux.rb b/lib/puppet/provider/user/hpux.rb
index db8dd19..50506c4 100644
--- a/lib/puppet/provider/user/hpux.rb
+++ b/lib/puppet/provider/user/hpux.rb
@@ -1,30 +1,30 @@
Puppet::Type.type(:user).provide :hpuxuseradd, :parent => :useradd do
- desc "User management for hp-ux! Undocumented switch to special usermod because HP-UX regular usermod is TOO STUPID to change stuff while the user is logged in."
+ desc "User management for hp-ux! Undocumented switch to special usermod because HP-UX regular usermod is TOO STUPID to change stuff while the user is logged in."
- defaultfor :operatingsystem => "hp-ux"
- confine :operatingsystem => "hp-ux"
+ defaultfor :operatingsystem => "hp-ux"
+ confine :operatingsystem => "hp-ux"
- commands :modify => "/usr/sam/lbin/usermod.sam", :delete => "/usr/sam/lbin/userdel.sam", :add => "/usr/sbin/useradd"
- options :comment, :method => :gecos
- options :groups, :flag => "-G"
- options :home, :flag => "-d", :method => :dir
+ commands :modify => "/usr/sam/lbin/usermod.sam", :delete => "/usr/sam/lbin/userdel.sam", :add => "/usr/sbin/useradd"
+ options :comment, :method => :gecos
+ options :groups, :flag => "-G"
+ options :home, :flag => "-d", :method => :dir
- verify :gid, "GID must be an integer" do |value|
- value.is_a? Integer
- end
+ verify :gid, "GID must be an integer" do |value|
+ value.is_a? Integer
+ end
- verify :groups, "Groups must be comma-separated" do |value|
- value !~ /\s/
- end
+ verify :groups, "Groups must be comma-separated" do |value|
+ value !~ /\s/
+ end
- has_features :manages_homedir, :allows_duplicates
+ has_features :manages_homedir, :allows_duplicates
- def deletecmd
- super.insert(1,"-F")
- end
+ def deletecmd
+ super.insert(1,"-F")
+ end
- def modifycmd(param,value)
- super.insert(1,"-F")
- end
+ def modifycmd(param,value)
+ super.insert(1,"-F")
+ end
end
diff --git a/lib/puppet/provider/user/ldap.rb b/lib/puppet/provider/user/ldap.rb
index 406ed0f..df082c5 100644
--- a/lib/puppet/provider/user/ldap.rb
+++ b/lib/puppet/provider/user/ldap.rb
@@ -1,129 +1,129 @@
require 'puppet/provider/ldap'
Puppet::Type.type(:user).provide :ldap, :parent => Puppet::Provider::Ldap do
- desc "User management via ``ldap``. This provider requires that you
- have valid values for all of the ldap-related settings,
- including ``ldapbase``. You will also almost definitely need settings
- for ``ldapuser`` and ``ldappassword``, so that your clients can write
- to ldap.
-
- Note that this provider will automatically generate a UID for you if
- you do not specify one, but it is a potentially expensive operation,
- as it iterates across all existing users to pick the appropriate next
- one."
-
- confine :feature => :ldap, :false => (Puppet[:ldapuser] == "")
-
- has_feature :manages_passwords
-
- manages(:posixAccount, :person).at("ou=People").named_by(:uid).and.maps :name => :uid,
- :password => :userPassword,
- :comment => :cn,
- :uid => :uidNumber,
- :gid => :gidNumber,
- :home => :homeDirectory,
- :shell => :loginShell
-
- # Use the last field of a space-separated array as
- # the sn. LDAP requires a surname, for some stupid reason.
- manager.generates(:sn).from(:cn).with do |cn|
- x = 1
- cn[0].split(/\s+/)[-1]
+ desc "User management via ``ldap``. This provider requires that you
+ have valid values for all of the ldap-related settings,
+ including ``ldapbase``. You will also almost definitely need settings
+ for ``ldapuser`` and ``ldappassword``, so that your clients can write
+ to ldap.
+
+ Note that this provider will automatically generate a UID for you if
+ you do not specify one, but it is a potentially expensive operation,
+ as it iterates across all existing users to pick the appropriate next
+ one."
+
+ confine :feature => :ldap, :false => (Puppet[:ldapuser] == "")
+
+ has_feature :manages_passwords
+
+ manages(:posixAccount, :person).at("ou=People").named_by(:uid).and.maps :name => :uid,
+ :password => :userPassword,
+ :comment => :cn,
+ :uid => :uidNumber,
+ :gid => :gidNumber,
+ :home => :homeDirectory,
+ :shell => :loginShell
+
+ # Use the last field of a space-separated array as
+ # the sn. LDAP requires a surname, for some stupid reason.
+ manager.generates(:sn).from(:cn).with do |cn|
+ x = 1
+ cn[0].split(/\s+/)[-1]
+ end
+
+ # Find the next uid after the current largest uid.
+ provider = self
+ manager.generates(:uidNumber).with do
+ largest = 500
+ if existing = provider.manager.search
+ existing.each do |hash|
+ next unless value = hash[:uid]
+ num = value[0].to_i
+ largest = num if num > largest
+ end
end
-
- # Find the next uid after the current largest uid.
- provider = self
- manager.generates(:uidNumber).with do
- largest = 500
- if existing = provider.manager.search
- existing.each do |hash|
- next unless value = hash[:uid]
- num = value[0].to_i
- largest = num if num > largest
- end
- end
- largest + 1
+ largest + 1
+ end
+
+ # Convert our gid to a group name, if necessary.
+ def gid=(value)
+ value = group2id(value) unless [Fixnum, Bignum].include?(value.class)
+
+ @property_hash[:gid] = value
+ end
+
+ # Find all groups this user is a member of in ldap.
+ def groups
+ # We want to cache the current result, so we know if we
+ # have to remove old values.
+ unless @property_hash[:groups]
+ unless result = group_manager.search("memberUid=#{name}")
+ return @property_hash[:groups] = :absent
+ end
+
+ return @property_hash[:groups] = result.collect { |r| r[:name] }.sort.join(",")
end
+ @property_hash[:groups]
+ end
- # Convert our gid to a group name, if necessary.
- def gid=(value)
- value = group2id(value) unless [Fixnum, Bignum].include?(value.class)
+ # Manage the list of groups this user is a member of.
+ def groups=(values)
+ should = values.split(",")
- @property_hash[:gid] = value
+ if groups == :absent
+ is = []
+ else
+ is = groups.split(",")
end
- # Find all groups this user is a member of in ldap.
- def groups
- # We want to cache the current result, so we know if we
- # have to remove old values.
- unless @property_hash[:groups]
- unless result = group_manager.search("memberUid=#{name}")
- return @property_hash[:groups] = :absent
- end
-
- return @property_hash[:groups] = result.collect { |r| r[:name] }.sort.join(",")
- end
- @property_hash[:groups]
- end
+ modes = {}
+ [is, should].flatten.uniq.each do |group|
+ # Skip it when they're in both
+ next if is.include?(group) and should.include?(group)
- # Manage the list of groups this user is a member of.
- def groups=(values)
- should = values.split(",")
+ # We're adding a group.
+ modes[group] = :add and next unless is.include?(group)
- if groups == :absent
- is = []
- else
- is = groups.split(",")
- end
+ # We're removing a group.
+ modes[group] = :remove and next unless should.include?(group)
+ end
- modes = {}
- [is, should].flatten.uniq.each do |group|
- # Skip it when they're in both
- next if is.include?(group) and should.include?(group)
+ modes.each do |group, form|
+ self.fail "Could not find ldap group #{group}" unless ldap_group = group_manager.find(group)
- # We're adding a group.
- modes[group] = :add and next unless is.include?(group)
+ current = ldap_group[:members]
- # We're removing a group.
- modes[group] = :remove and next unless should.include?(group)
+ if form == :add
+ if current.is_a?(Array) and ! current.empty?
+ new = current + [name]
+ else
+ new = [name]
end
+ else
+ new = current - [name]
+ new = :absent if new.empty?
+ end
- modes.each do |group, form|
- self.fail "Could not find ldap group #{group}" unless ldap_group = group_manager.find(group)
-
- current = ldap_group[:members]
-
- if form == :add
- if current.is_a?(Array) and ! current.empty?
- new = current + [name]
- else
- new = [name]
- end
- else
- new = current - [name]
- new = :absent if new.empty?
- end
-
- group_manager.update(group, {:ensure => :present, :members => current}, {:ensure => :present, :members => new})
- end
+ group_manager.update(group, {:ensure => :present, :members => current}, {:ensure => :present, :members => new})
end
+ end
- # Convert a gropu name to an id.
- def group2id(group)
- Puppet::Type.type(:group).provider(:ldap).name2id(group)
- end
+ # Convert a gropu name to an id.
+ def group2id(group)
+ Puppet::Type.type(:group).provider(:ldap).name2id(group)
+ end
- private
+ private
- def group_manager
- Puppet::Type.type(:group).provider(:ldap).manager
- end
+ def group_manager
+ Puppet::Type.type(:group).provider(:ldap).manager
+ end
- def group_properties(values)
- if values.empty? or values == :absent
- {:ensure => :present}
- else
- {:ensure => :present, :members => values}
- end
+ def group_properties(values)
+ if values.empty? or values == :absent
+ {:ensure => :present}
+ else
+ {:ensure => :present, :members => values}
end
+ end
end
diff --git a/lib/puppet/provider/user/pw.rb b/lib/puppet/provider/user/pw.rb
index 7d3eda2..345d924 100644
--- a/lib/puppet/provider/user/pw.rb
+++ b/lib/puppet/provider/user/pw.rb
@@ -1,41 +1,41 @@
require 'puppet/provider/nameservice/pw'
Puppet::Type.type(:user).provide :pw, :parent => Puppet::Provider::NameService::PW do
- desc "User management via ``pw`` on FreeBSD."
-
- commands :pw => "pw"
- has_features :manages_homedir, :allows_duplicates
-
- defaultfor :operatingsystem => :freebsd
-
- options :home, :flag => "-d", :method => :dir
- options :comment, :method => :gecos
- options :groups, :flag => "-G"
-
- verify :gid, "GID must be an integer" do |value|
- value.is_a? Integer
+ desc "User management via ``pw`` on FreeBSD."
+
+ commands :pw => "pw"
+ has_features :manages_homedir, :allows_duplicates
+
+ defaultfor :operatingsystem => :freebsd
+
+ options :home, :flag => "-d", :method => :dir
+ options :comment, :method => :gecos
+ options :groups, :flag => "-G"
+
+ verify :gid, "GID must be an integer" do |value|
+ value.is_a? Integer
+ end
+
+ verify :groups, "Groups must be comma-separated" do |value|
+ value !~ /\s/
+ end
+
+ def addcmd
+ cmd = [command(:pw), "useradd", @resource[:name]]
+ @resource.class.validproperties.each do |property|
+ next if property == :ensure
+ # the value needs to be quoted, mostly because -c might
+ # have spaces in it
+ if value = @resource.should(property) and value != ""
+ cmd << flag(property) << value
+ end
end
- verify :groups, "Groups must be comma-separated" do |value|
- value !~ /\s/
- end
-
- def addcmd
- cmd = [command(:pw), "useradd", @resource[:name]]
- @resource.class.validproperties.each do |property|
- next if property == :ensure
- # the value needs to be quoted, mostly because -c might
- # have spaces in it
- if value = @resource.should(property) and value != ""
- cmd << flag(property) << value
- end
- end
+ cmd << "-o" if @resource.allowdupe?
- cmd << "-o" if @resource.allowdupe?
+ cmd << "-m" if @resource.managehome?
- cmd << "-m" if @resource.managehome?
-
- cmd
- end
+ cmd
+ end
end
diff --git a/lib/puppet/provider/user/user_role_add.rb b/lib/puppet/provider/user/user_role_add.rb
index 7c7c9e3..ea1b01b 100644
--- a/lib/puppet/provider/user/user_role_add.rb
+++ b/lib/puppet/provider/user/user_role_add.rb
@@ -2,177 +2,177 @@ require 'puppet/util/user_attr'
Puppet::Type.type(:user).provide :user_role_add, :parent => :useradd, :source => :useradd do
- desc "User management inherits ``useradd`` and adds logic to manage roles on Solaris using roleadd."
-
- defaultfor :operatingsystem => :solaris
-
- commands :add => "useradd", :delete => "userdel", :modify => "usermod", :role_add => "roleadd", :role_delete => "roledel", :role_modify => "rolemod"
- options :home, :flag => "-d", :method => :dir
- options :comment, :method => :gecos
- options :groups, :flag => "-G"
- options :roles, :flag => "-R"
- options :auths, :flag => "-A"
- options :profiles, :flag => "-P"
-
- verify :gid, "GID must be an integer" do |value|
- value.is_a? Integer
- end
-
- verify :groups, "Groups must be comma-separated" do |value|
- value !~ /\s/
- end
-
- has_features :manages_homedir, :allows_duplicates, :manages_solaris_rbac, :manages_passwords
-
- #must override this to hand the keyvalue pairs
- def add_properties
- cmd = []
- Puppet::Type.type(:user).validproperties.each do |property|
- #skip the password because we can't create it with the solaris useradd
- next if [:ensure, :password].include?(property)
- # 1680 Now you can set the hashed passwords on solaris:lib/puppet/provider/user/user_role_add.rb
- # the value needs to be quoted, mostly because -c might
- # have spaces in it
- if value = @resource.should(property) and value != ""
- if property == :keys
- cmd += build_keys_cmd(value)
- else
- cmd << flag(property) << value
- end
- end
- end
- cmd
- end
-
- def user_attributes
- @user_attributes ||= UserAttr.get_attributes_by_name(@resource[:name])
- end
-
- def flush
- @user_attributes = nil
- end
-
- def command(cmd)
- cmd = ("role_#{cmd}").intern if is_role? or (!exists? and @resource[:ensure] == :role)
- super(cmd)
- end
-
- def is_role?
- user_attributes and user_attributes[:type] == "role"
- end
-
- def run(cmd, msg)
- execute(cmd)
- rescue Puppet::ExecutionFailure => detail
- raise Puppet::Error, "Could not #{msg} #{@resource.class.name} #{@resource.name}: #{detail}"
- end
-
- def transition(type)
- cmd = [command(:modify)]
- cmd << "-K" << "type=#{type}"
- cmd += add_properties
- cmd << @resource[:name]
- end
-
- def create
- if is_role?
- run(transition("normal"), "transition role to")
+ desc "User management inherits ``useradd`` and adds logic to manage roles on Solaris using roleadd."
+
+ defaultfor :operatingsystem => :solaris
+
+ commands :add => "useradd", :delete => "userdel", :modify => "usermod", :role_add => "roleadd", :role_delete => "roledel", :role_modify => "rolemod"
+ options :home, :flag => "-d", :method => :dir
+ options :comment, :method => :gecos
+ options :groups, :flag => "-G"
+ options :roles, :flag => "-R"
+ options :auths, :flag => "-A"
+ options :profiles, :flag => "-P"
+
+ verify :gid, "GID must be an integer" do |value|
+ value.is_a? Integer
+ end
+
+ verify :groups, "Groups must be comma-separated" do |value|
+ value !~ /\s/
+ end
+
+ has_features :manages_homedir, :allows_duplicates, :manages_solaris_rbac, :manages_passwords
+
+ #must override this to hand the keyvalue pairs
+ def add_properties
+ cmd = []
+ Puppet::Type.type(:user).validproperties.each do |property|
+ #skip the password because we can't create it with the solaris useradd
+ next if [:ensure, :password].include?(property)
+ # 1680 Now you can set the hashed passwords on solaris:lib/puppet/provider/user/user_role_add.rb
+ # the value needs to be quoted, mostly because -c might
+ # have spaces in it
+ if value = @resource.should(property) and value != ""
+ if property == :keys
+ cmd += build_keys_cmd(value)
else
- run(addcmd, "create")
+ cmd << flag(property) << value
end
- # added to handle case when password is specified
- self.password = @resource[:password] if @resource[:password]
- end
-
- def destroy
- run(deletecmd, "delete "+ (is_role? ? "role" : "user"))
- end
-
- def create_role
- if exists? and !is_role?
- run(transition("role"), "transition user to")
- else
- run(addcmd, "create role")
- end
- end
-
- def roles
- user_attributes[:roles] if user_attributes
- end
-
- def auths
- user_attributes[:auths] if user_attributes
- end
-
- def profiles
- user_attributes[:profiles] if user_attributes
- end
-
- def project
- user_attributes[:project] if user_attributes
- end
-
- def managed_attributes
- [:name, :type, :roles, :auths, :profiles, :project]
- end
-
- def remove_managed_attributes
- managed = managed_attributes
- user_attributes.select { |k,v| !managed.include?(k) }.inject({}) { |hash, array| hash[array[0]] = array[1]; hash }
- end
-
- def keys
- if user_attributes
- #we have to get rid of all the keys we are managing another way
- remove_managed_attributes
- end
- end
-
- def build_keys_cmd(keys_hash)
- cmd = []
- keys_hash.each do |k,v|
- cmd << "-K" << "#{k}=#{v}"
- end
- cmd
- end
-
- def keys=(keys_hash)
- run([command(:modify)] + build_keys_cmd(keys_hash) << @resource[:name], "modify attribute key pairs")
- end
-
- #Read in /etc/shadow, find the line for this user (skipping comments, because who knows) and return the hashed pw (the second entry)
- #No abstraction, all esoteric knowledge of file formats, yay
- def password
- #got perl?
- if ary = File.readlines("/etc/shadow").reject { |r| r =~ /^[^\w]/}.collect { |l| l.split(':')[0..1] }.find { |user, passwd| user == @resource[:name] }
- pass = ary[1]
- end
- pass
- end
-
- #Read in /etc/shadow, find the line for our used and rewrite it with the new pw
- #Smooth like 80 grit
- def password=(cryptopw)
- begin
- File.open("/etc/shadow", "r") do |shadow|
- File.open("/etc/shadow_tmp", "w", 0600) do |shadow_tmp|
- while line = shadow.gets
- line_arr = line.split(':')
- if line_arr[0] == @resource[:name]
- line_arr[1] = cryptopw
- line = line_arr.join(':')
- end
- shadow_tmp.print line
- end
- end
+ end
+ end
+ cmd
+ end
+
+ def user_attributes
+ @user_attributes ||= UserAttr.get_attributes_by_name(@resource[:name])
+ end
+
+ def flush
+ @user_attributes = nil
+ end
+
+ def command(cmd)
+ cmd = ("role_#{cmd}").intern if is_role? or (!exists? and @resource[:ensure] == :role)
+ super(cmd)
+ end
+
+ def is_role?
+ user_attributes and user_attributes[:type] == "role"
+ end
+
+ def run(cmd, msg)
+ execute(cmd)
+ rescue Puppet::ExecutionFailure => detail
+ raise Puppet::Error, "Could not #{msg} #{@resource.class.name} #{@resource.name}: #{detail}"
+ end
+
+ def transition(type)
+ cmd = [command(:modify)]
+ cmd << "-K" << "type=#{type}"
+ cmd += add_properties
+ cmd << @resource[:name]
+ end
+
+ def create
+ if is_role?
+ run(transition("normal"), "transition role to")
+ else
+ run(addcmd, "create")
+ end
+ # added to handle case when password is specified
+ self.password = @resource[:password] if @resource[:password]
+ end
+
+ def destroy
+ run(deletecmd, "delete "+ (is_role? ? "role" : "user"))
+ end
+
+ def create_role
+ if exists? and !is_role?
+ run(transition("role"), "transition user to")
+ else
+ run(addcmd, "create role")
+ end
+ end
+
+ def roles
+ user_attributes[:roles] if user_attributes
+ end
+
+ def auths
+ user_attributes[:auths] if user_attributes
+ end
+
+ def profiles
+ user_attributes[:profiles] if user_attributes
+ end
+
+ def project
+ user_attributes[:project] if user_attributes
+ end
+
+ def managed_attributes
+ [:name, :type, :roles, :auths, :profiles, :project]
+ end
+
+ def remove_managed_attributes
+ managed = managed_attributes
+ user_attributes.select { |k,v| !managed.include?(k) }.inject({}) { |hash, array| hash[array[0]] = array[1]; hash }
+ end
+
+ def keys
+ if user_attributes
+ #we have to get rid of all the keys we are managing another way
+ remove_managed_attributes
+ end
+ end
+
+ def build_keys_cmd(keys_hash)
+ cmd = []
+ keys_hash.each do |k,v|
+ cmd << "-K" << "#{k}=#{v}"
+ end
+ cmd
+ end
+
+ def keys=(keys_hash)
+ run([command(:modify)] + build_keys_cmd(keys_hash) << @resource[:name], "modify attribute key pairs")
+ end
+
+ #Read in /etc/shadow, find the line for this user (skipping comments, because who knows) and return the hashed pw (the second entry)
+ #No abstraction, all esoteric knowledge of file formats, yay
+ def password
+ #got perl?
+ if ary = File.readlines("/etc/shadow").reject { |r| r =~ /^[^\w]/}.collect { |l| l.split(':')[0..1] }.find { |user, passwd| user == @resource[:name] }
+ pass = ary[1]
+ end
+ pass
+ end
+
+ #Read in /etc/shadow, find the line for our used and rewrite it with the new pw
+ #Smooth like 80 grit
+ def password=(cryptopw)
+ begin
+ File.open("/etc/shadow", "r") do |shadow|
+ File.open("/etc/shadow_tmp", "w", 0600) do |shadow_tmp|
+ while line = shadow.gets
+ line_arr = line.split(':')
+ if line_arr[0] == @resource[:name]
+ line_arr[1] = cryptopw
+ line = line_arr.join(':')
end
- File.rename("/etc/shadow_tmp", "/etc/shadow")
- rescue => detail
- fail "Could not write temporary shadow file: #{detail}"
- ensure
- # Make sure this *always* gets deleted
- File.unlink("/etc/shadow_tmp") if File.exist?("/etc/shadow_tmp")
+ shadow_tmp.print line
+ end
end
- end
+ end
+ File.rename("/etc/shadow_tmp", "/etc/shadow")
+ rescue => detail
+ fail "Could not write temporary shadow file: #{detail}"
+ ensure
+ # Make sure this *always* gets deleted
+ File.unlink("/etc/shadow_tmp") if File.exist?("/etc/shadow_tmp")
+ end
+ end
end
diff --git a/lib/puppet/provider/user/useradd.rb b/lib/puppet/provider/user/useradd.rb
index 7645969..ec87694 100644
--- a/lib/puppet/provider/user/useradd.rb
+++ b/lib/puppet/provider/user/useradd.rb
@@ -1,69 +1,69 @@
require 'puppet/provider/nameservice/objectadd'
Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameService::ObjectAdd do
- desc "User management via ``useradd`` and its ilk. Note that you will need to install the ``Shadow Password`` Ruby library often known as ruby-libshadow to manage user passwords."
+ desc "User management via ``useradd`` and its ilk. Note that you will need to install the ``Shadow Password`` Ruby library often known as ruby-libshadow to manage user passwords."
- commands :add => "useradd", :delete => "userdel", :modify => "usermod"
+ commands :add => "useradd", :delete => "userdel", :modify => "usermod"
- options :home, :flag => "-d", :method => :dir
- options :comment, :method => :gecos
- options :groups, :flag => "-G"
+ options :home, :flag => "-d", :method => :dir
+ options :comment, :method => :gecos
+ options :groups, :flag => "-G"
- verify :gid, "GID must be an integer" do |value|
- value.is_a? Integer
- end
+ verify :gid, "GID must be an integer" do |value|
+ value.is_a? Integer
+ end
- verify :groups, "Groups must be comma-separated" do |value|
- value !~ /\s/
- end
+ verify :groups, "Groups must be comma-separated" do |value|
+ value !~ /\s/
+ end
- has_features :manages_homedir, :allows_duplicates
+ has_features :manages_homedir, :allows_duplicates
- has_feature :manages_passwords if Puppet.features.libshadow?
+ has_feature :manages_passwords if Puppet.features.libshadow?
- def check_allow_dup
- @resource.allowdupe? ? ["-o"] : []
- end
+ def check_allow_dup
+ @resource.allowdupe? ? ["-o"] : []
+ end
- def check_manage_home
- cmd = []
- if @resource.managehome?
- cmd << "-m"
- elsif %w{Fedora RedHat CentOS OEL OVS}.include?(Facter.value("operatingsystem"))
- cmd << "-M"
- end
- cmd
+ def check_manage_home
+ cmd = []
+ if @resource.managehome?
+ cmd << "-m"
+ elsif %w{Fedora RedHat CentOS OEL OVS}.include?(Facter.value("operatingsystem"))
+ cmd << "-M"
end
+ cmd
+ end
- def add_properties
- cmd = []
- Puppet::Type.type(:user).validproperties.each do |property|
- next if property == :ensure
- # the value needs to be quoted, mostly because -c might
- # have spaces in it
- if value = @resource.should(property) and value != ""
- cmd << flag(property) << value
- end
- end
- cmd
+ def add_properties
+ cmd = []
+ Puppet::Type.type(:user).validproperties.each do |property|
+ next if property == :ensure
+ # the value needs to be quoted, mostly because -c might
+ # have spaces in it
+ if value = @resource.should(property) and value != ""
+ cmd << flag(property) << value
+ end
end
+ cmd
+ end
- def addcmd
- cmd = [command(:add)]
- cmd += add_properties
- cmd += check_allow_dup
- cmd += check_manage_home
- cmd << @resource[:name]
- end
+ def addcmd
+ cmd = [command(:add)]
+ cmd += add_properties
+ cmd += check_allow_dup
+ cmd += check_manage_home
+ cmd << @resource[:name]
+ end
- # Retrieve the password using the Shadow Password library
- def password
- if Puppet.features.libshadow?
- if ent = Shadow::Passwd.getspnam(@resource.name)
- return ent.sp_pwdp
- end
- end
- :absent
+ # Retrieve the password using the Shadow Password library
+ def password
+ if Puppet.features.libshadow?
+ if ent = Shadow::Passwd.getspnam(@resource.name)
+ return ent.sp_pwdp
+ end
end
+ :absent
+ end
end
diff --git a/lib/puppet/provider/zfs/solaris.rb b/lib/puppet/provider/zfs/solaris.rb
index 418c902..85d054f 100644
--- a/lib/puppet/provider/zfs/solaris.rb
+++ b/lib/puppet/provider/zfs/solaris.rb
@@ -1,45 +1,45 @@
Puppet::Type.type(:zfs).provide(:solaris) do
- desc "Provider for Solaris zfs."
-
- commands :zfs => "/usr/sbin/zfs"
- defaultfor :operatingsystem => :solaris
-
- def add_properties
- properties = []
- Puppet::Type.type(:zfs).validproperties.each do |property|
- next if property == :ensure
- if value = @resource[property] and value != ""
- properties << "-o" << "#{property}=#{value}"
- end
- end
- properties
+ desc "Provider for Solaris zfs."
+
+ commands :zfs => "/usr/sbin/zfs"
+ defaultfor :operatingsystem => :solaris
+
+ def add_properties
+ properties = []
+ Puppet::Type.type(:zfs).validproperties.each do |property|
+ next if property == :ensure
+ if value = @resource[property] and value != ""
+ properties << "-o" << "#{property}=#{value}"
+ end
end
-
- def create
- zfs *([:create] + add_properties + [@resource[:name]])
- end
-
- def destroy
- zfs(:destroy, @resource[:name])
+ properties
+ end
+
+ def create
+ zfs *([:create] + add_properties + [@resource[:name]])
+ end
+
+ def destroy
+ zfs(:destroy, @resource[:name])
+ end
+
+ def exists?
+ if zfs(:list).split("\n").detect { |line| line.split("\s")[0] == @resource[:name] }
+ true
+ else
+ false
end
+ end
- def exists?
- if zfs(:list).split("\n").detect { |line| line.split("\s")[0] == @resource[:name] }
- true
- else
- false
- end
+ [:mountpoint, :compression, :copies, :quota, :reservation, :sharenfs, :snapdir].each do |field|
+ define_method(field) do
+ zfs(:get, "-H", "-o", "value", field, @resource[:name]).strip
end
- [:mountpoint, :compression, :copies, :quota, :reservation, :sharenfs, :snapdir].each do |field|
- define_method(field) do
- zfs(:get, "-H", "-o", "value", field, @resource[:name]).strip
- end
-
- define_method(field.to_s + "=") do |should|
- zfs(:set, "#{field}=#{should}", @resource[:name])
- end
+ define_method(field.to_s + "=") do |should|
+ zfs(:set, "#{field}=#{should}", @resource[:name])
end
+ end
end
diff --git a/lib/puppet/provider/zone/solaris.rb b/lib/puppet/provider/zone/solaris.rb
index 33b1bc1..c114449 100644
--- a/lib/puppet/provider/zone/solaris.rb
+++ b/lib/puppet/provider/zone/solaris.rb
@@ -1,257 +1,257 @@
Puppet::Type.type(:zone).provide(:solaris) do
- desc "Provider for Solaris Zones."
+ desc "Provider for Solaris Zones."
- commands :adm => "/usr/sbin/zoneadm", :cfg => "/usr/sbin/zonecfg"
- defaultfor :operatingsystem => :solaris
+ commands :adm => "/usr/sbin/zoneadm", :cfg => "/usr/sbin/zonecfg"
+ defaultfor :operatingsystem => :solaris
- mk_resource_methods
+ mk_resource_methods
- # Convert the output of a list into a hash
- def self.line2hash(line)
- fields = [:id, :name, :ensure, :path]
+ # Convert the output of a list into a hash
+ def self.line2hash(line)
+ fields = [:id, :name, :ensure, :path]
- properties = {}
- line.split(":").each_with_index { |value, index|
- next unless fields[index]
- properties[fields[index]] = value
- }
+ properties = {}
+ line.split(":").each_with_index { |value, index|
+ next unless fields[index]
+ properties[fields[index]] = value
+ }
- # Configured but not installed zones do not have IDs
- properties.delete(:id) if properties[:id] == "-"
+ # Configured but not installed zones do not have IDs
+ properties.delete(:id) if properties[:id] == "-"
- properties[:ensure] = symbolize(properties[:ensure])
+ properties[:ensure] = symbolize(properties[:ensure])
- properties
- end
+ properties
+ end
- def self.instances
- # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
- x = adm(:list, "-cp").split("\n").collect do |line|
- new(line2hash(line))
- end
+ def self.instances
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = adm(:list, "-cp").split("\n").collect do |line|
+ new(line2hash(line))
end
-
- # Perform all of our configuration steps.
- def configure
- # If the thing is entirely absent, then we need to create the config.
- # Is there someway to get this on one line?
- str = "create -b #{@resource[:create_args]}\nset zonepath=#{@resource[:path]}\n"
-
- # Then perform all of our configuration steps. It's annoying
- # that we need this much internal info on the resource.
- @resource.send(:properties).each do |property|
- str += property.configtext + "\n" if property.is_a? ZoneConfigProperty and ! property.insync?(properties[property.name])
- end
-
- str += "commit\n"
- setconfig(str)
+ end
+
+ # Perform all of our configuration steps.
+ def configure
+ # If the thing is entirely absent, then we need to create the config.
+ # Is there someway to get this on one line?
+ str = "create -b #{@resource[:create_args]}\nset zonepath=#{@resource[:path]}\n"
+
+ # Then perform all of our configuration steps. It's annoying
+ # that we need this much internal info on the resource.
+ @resource.send(:properties).each do |property|
+ str += property.configtext + "\n" if property.is_a? ZoneConfigProperty and ! property.insync?(properties[property.name])
end
- def destroy
- zonecfg :delete, "-F"
+ str += "commit\n"
+ setconfig(str)
+ end
+
+ def destroy
+ zonecfg :delete, "-F"
+ end
+
+ def exists?
+ properties[:ensure] != :absent
+ end
+
+ # Clear out the cached values.
+ def flush
+ @property_hash.clear
+ end
+
+ def install(dummy_argument=:work_arround_for_ruby_GC_bug)
+ if @resource[:clone] # TODO: add support for "-s snapshot"
+ zoneadm :clone, @resource[:clone]
+ elsif @resource[:install_args]
+ zoneadm :install, @resource[:install_args].split(" ")
+ else
+ zoneadm :install
end
+ end
+
+ # Look up the current status.
+ def properties
+ if @property_hash.empty?
+ @property_hash = status || {}
+ if @property_hash.empty?
+ @property_hash[:ensure] = :absent
+ else
+ @resource.class.validproperties.each do |name|
+ @property_hash[name] ||= :absent
+ end
+ end
- def exists?
- properties[:ensure] != :absent
end
-
- # Clear out the cached values.
- def flush
- @property_hash.clear
+ @property_hash.dup
+ end
+
+ # We need a way to test whether a zone is in process. Our 'ensure'
+ # property models the static states, but we need to handle the temporary ones.
+ def processing?
+ if hash = status
+ case hash[:ensure]
+ when "incomplete", "ready", "shutting_down"
+ true
+ else
+ false
+ end
+ else
+ false
end
-
- def install(dummy_argument=:work_arround_for_ruby_GC_bug)
- if @resource[:clone] # TODO: add support for "-s snapshot"
- zoneadm :clone, @resource[:clone]
- elsif @resource[:install_args]
- zoneadm :install, @resource[:install_args].split(" ")
+ end
+
+ # Collect the configuration of the zone.
+ def getconfig
+ output = zonecfg :info
+
+ name = nil
+ current = nil
+ hash = {}
+ output.split("\n").each do |line|
+ case line
+ when /^(\S+):\s*$/
+ name = $1
+ current = nil # reset it
+ when /^(\S+):\s*(.+)$/
+ hash[$1.intern] = $2
+ when /^\s+(\S+):\s*(.+)$/
+ if name
+ hash[name] = [] unless hash.include? name
+
+ unless current
+ current = {}
+ hash[name] << current
+ end
+ current[$1.intern] = $2
else
- zoneadm :install
+ err "Ignoring '#{line}'"
end
+ else
+ debug "Ignoring zone output '#{line}'"
+ end
end
- # Look up the current status.
- def properties
- if @property_hash.empty?
- @property_hash = status || {}
- if @property_hash.empty?
- @property_hash[:ensure] = :absent
- else
- @resource.class.validproperties.each do |name|
- @property_hash[name] ||= :absent
- end
- end
+ hash
+ end
- end
- @property_hash.dup
+ # Execute a configuration string. Can't be private because it's called
+ # by the properties.
+ def setconfig(str)
+ command = "#{command(:cfg)} -z #{@resource[:name]} -f -"
+ debug "Executing '#{command}' in zone #{@resource[:name]} with '#{str}'"
+ IO.popen(command, "w") do |pipe|
+ pipe.puts str
end
- # We need a way to test whether a zone is in process. Our 'ensure'
- # property models the static states, but we need to handle the temporary ones.
- def processing?
- if hash = status
- case hash[:ensure]
- when "incomplete", "ready", "shutting_down"
- true
- else
- false
- end
- else
- false
- end
+ unless $CHILD_STATUS == 0
+ raise ArgumentError, "Failed to apply configuration"
end
+ end
- # Collect the configuration of the zone.
- def getconfig
- output = zonecfg :info
-
- name = nil
- current = nil
- hash = {}
- output.split("\n").each do |line|
- case line
- when /^(\S+):\s*$/
- name = $1
- current = nil # reset it
- when /^(\S+):\s*(.+)$/
- hash[$1.intern] = $2
- when /^\s+(\S+):\s*(.+)$/
- if name
- hash[name] = [] unless hash.include? name
-
- unless current
- current = {}
- hash[name] << current
- end
- current[$1.intern] = $2
- else
- err "Ignoring '#{line}'"
- end
- else
- debug "Ignoring zone output '#{line}'"
- end
- end
+ def start
+ # Check the sysidcfg stuff
+ if cfg = @resource[:sysidcfg]
+ zoneetc = File.join(@resource[:path], "root", "etc")
+ sysidcfg = File.join(zoneetc, "sysidcfg")
- hash
- end
+ # if the zone root isn't present "ready" the zone
+ # which makes zoneadmd mount the zone root
+ zoneadm :ready unless File.directory?(zoneetc)
- # Execute a configuration string. Can't be private because it's called
- # by the properties.
- def setconfig(str)
- command = "#{command(:cfg)} -z #{@resource[:name]} -f -"
- debug "Executing '#{command}' in zone #{@resource[:name]} with '#{str}'"
- IO.popen(command, "w") do |pipe|
- pipe.puts str
- end
-
- unless $CHILD_STATUS == 0
- raise ArgumentError, "Failed to apply configuration"
+ unless File.exists?(sysidcfg)
+ begin
+ File.open(sysidcfg, "w", 0600) do |f|
+ f.puts cfg
+ end
+ rescue => detail
+ puts detail.stacktrace if Puppet[:debug]
+ raise Puppet::Error, "Could not create sysidcfg: #{detail}"
end
+ end
end
- def start
- # Check the sysidcfg stuff
- if cfg = @resource[:sysidcfg]
- zoneetc = File.join(@resource[:path], "root", "etc")
- sysidcfg = File.join(zoneetc, "sysidcfg")
-
- # if the zone root isn't present "ready" the zone
- # which makes zoneadmd mount the zone root
- zoneadm :ready unless File.directory?(zoneetc)
-
- unless File.exists?(sysidcfg)
- begin
- File.open(sysidcfg, "w", 0600) do |f|
- f.puts cfg
- end
- rescue => detail
- puts detail.stacktrace if Puppet[:debug]
- raise Puppet::Error, "Could not create sysidcfg: #{detail}"
- end
- end
- end
+ zoneadm :boot
+ end
- zoneadm :boot
+ # Return a hash of the current status of this zone.
+ def status
+ begin
+ output = adm "-z", @resource[:name], :list, "-p"
+ rescue Puppet::ExecutionFailure
+ return nil
end
- # Return a hash of the current status of this zone.
- def status
- begin
- output = adm "-z", @resource[:name], :list, "-p"
- rescue Puppet::ExecutionFailure
- return nil
- end
-
- main = self.class.line2hash(output.chomp)
+ main = self.class.line2hash(output.chomp)
- # Now add in the configuration information
- config_status.each do |name, value|
- main[name] = value
- end
-
- main
+ # Now add in the configuration information
+ config_status.each do |name, value|
+ main[name] = value
end
- def ready
- zoneadm :ready
- end
+ main
+ end
- def stop
- zoneadm :halt
- end
+ def ready
+ zoneadm :ready
+ end
- def unconfigure
- zonecfg :delete, "-F"
- end
+ def stop
+ zoneadm :halt
+ end
- def uninstall
- zoneadm :uninstall, "-F"
- end
+ def unconfigure
+ zonecfg :delete, "-F"
+ end
- private
+ def uninstall
+ zoneadm :uninstall, "-F"
+ end
- # Turn the results of getconfig into status information.
- def config_status
- config = getconfig
- result = {}
+ private
- result[:autoboot] = config[:autoboot] ? config[:autoboot].intern : :absent
- result[:pool] = config[:pool]
- result[:shares] = config[:shares]
- if dir = config["inherit-pkg-dir"]
- result[:inherit] = dir.collect { |dirs| dirs[:dir] }
- end
- result[:iptype] = config[:"ip-type"]
- if net = config["net"]
- result[:ip] = net.collect do |params|
- if params[:defrouter]
- "#{params[:physical]}:#{params[:address]}:#{params[:defrouter]}"
- elsif params[:address]
- "#{params[:physical]}:#{params[:address]}"
- else
- params[:physical]
- end
- end
- end
+ # Turn the results of getconfig into status information.
+ def config_status
+ config = getconfig
+ result = {}
- result
+ result[:autoboot] = config[:autoboot] ? config[:autoboot].intern : :absent
+ result[:pool] = config[:pool]
+ result[:shares] = config[:shares]
+ if dir = config["inherit-pkg-dir"]
+ result[:inherit] = dir.collect { |dirs| dirs[:dir] }
end
-
- def zoneadm(*cmd)
- adm("-z", @resource[:name], *cmd)
- rescue Puppet::ExecutionFailure => detail
- self.fail "Could not #{cmd[0]} zone: #{detail}"
+ result[:iptype] = config[:"ip-type"]
+ if net = config["net"]
+ result[:ip] = net.collect do |params|
+ if params[:defrouter]
+ "#{params[:physical]}:#{params[:address]}:#{params[:defrouter]}"
+ elsif params[:address]
+ "#{params[:physical]}:#{params[:address]}"
+ else
+ params[:physical]
+ end
+ end
end
- def zonecfg(*cmd)
- # You apparently can't get the configuration of the global zone
- return "" if self.name == "global"
+ result
+ end
- begin
- cfg("-z", self.name, *cmd)
- rescue Puppet::ExecutionFailure => detail
- self.fail "Could not #{cmd[0]} zone: #{detail}"
- end
+ def zoneadm(*cmd)
+ adm("-z", @resource[:name], *cmd)
+ rescue Puppet::ExecutionFailure => detail
+ self.fail "Could not #{cmd[0]} zone: #{detail}"
+ end
+
+ def zonecfg(*cmd)
+ # You apparently can't get the configuration of the global zone
+ return "" if self.name == "global"
+
+ begin
+ cfg("-z", self.name, *cmd)
+ rescue Puppet::ExecutionFailure => detail
+ self.fail "Could not #{cmd[0]} zone: #{detail}"
end
+ end
end
diff --git a/lib/puppet/provider/zpool/solaris.rb b/lib/puppet/provider/zpool/solaris.rb
index bfd3708..e597c2a 100644
--- a/lib/puppet/provider/zpool/solaris.rb
+++ b/lib/puppet/provider/zpool/solaris.rb
@@ -1,114 +1,114 @@
Puppet::Type.type(:zpool).provide(:solaris) do
- desc "Provider for Solaris zpool."
-
- commands :zpool => "/usr/sbin/zpool"
- defaultfor :operatingsystem => :solaris
-
- def process_zpool_data(pool_array)
- if pool_array == []
- return Hash.new(:absent)
- end
- #get the name and get rid of it
- pool = Hash.new
- pool[:pool] = pool_array[0]
- pool_array.shift
-
- tmp = []
-
- #order matters here :(
- pool_array.reverse.each do |value|
- sym = nil
- case value
- when "spares"; sym = :spare
- when "logs"; sym = :log
- when "mirror", "raidz1", "raidz2"
- sym = value == "mirror" ? :mirror : :raidz
- pool[:raid_parity] = "raidz2" if value == "raidz2"
- else
- tmp << value
- sym = :disk if value == pool_array.first
- end
-
- if sym
- pool[sym] = pool[sym] ? pool[sym].unshift(tmp.reverse.join(' ')) : [tmp.reverse.join(' ')]
- tmp.clear
- end
- end
-
- pool
- end
+ desc "Provider for Solaris zpool."
- def get_pool_data
- #this is all voodoo dependent on the output from zpool
- zpool_data = %x{ zpool status #{@resource[:pool]}}.split("\n").select { |line| line.index("\t") == 0 }.collect { |l| l.strip.split("\s")[0] }
- zpool_data.shift
- zpool_data
- end
+ commands :zpool => "/usr/sbin/zpool"
+ defaultfor :operatingsystem => :solaris
- def current_pool
- @current_pool = process_zpool_data(get_pool_data) unless (defined?(@current_pool) and @current_pool)
- @current_pool
+ def process_zpool_data(pool_array)
+ if pool_array == []
+ return Hash.new(:absent)
end
-
- def flush
- @current_pool= nil
+ #get the name and get rid of it
+ pool = Hash.new
+ pool[:pool] = pool_array[0]
+ pool_array.shift
+
+ tmp = []
+
+ #order matters here :(
+ pool_array.reverse.each do |value|
+ sym = nil
+ case value
+ when "spares"; sym = :spare
+ when "logs"; sym = :log
+ when "mirror", "raidz1", "raidz2"
+ sym = value == "mirror" ? :mirror : :raidz
+ pool[:raid_parity] = "raidz2" if value == "raidz2"
+ else
+ tmp << value
+ sym = :disk if value == pool_array.first
+ end
+
+ if sym
+ pool[sym] = pool[sym] ? pool[sym].unshift(tmp.reverse.join(' ')) : [tmp.reverse.join(' ')]
+ tmp.clear
+ end
end
- #Adds log and spare
- def build_named(name)
- if prop = @resource[name.intern]
- [name] + prop.collect { |p| p.split(' ') }.flatten
- else
- []
- end
+ pool
+ end
+
+ def get_pool_data
+ #this is all voodoo dependent on the output from zpool
+ zpool_data = %x{ zpool status #{@resource[:pool]}}.split("\n").select { |line| line.index("\t") == 0 }.collect { |l| l.strip.split("\s")[0] }
+ zpool_data.shift
+ zpool_data
+ end
+
+ def current_pool
+ @current_pool = process_zpool_data(get_pool_data) unless (defined?(@current_pool) and @current_pool)
+ @current_pool
+ end
+
+ def flush
+ @current_pool= nil
+ end
+
+ #Adds log and spare
+ def build_named(name)
+ if prop = @resource[name.intern]
+ [name] + prop.collect { |p| p.split(' ') }.flatten
+ else
+ []
end
-
- #query for parity and set the right string
- def raidzarity
- @resource[:raid_parity] ? @resource[:raid_parity] : "raidz1"
+ end
+
+ #query for parity and set the right string
+ def raidzarity
+ @resource[:raid_parity] ? @resource[:raid_parity] : "raidz1"
+ end
+
+ #handle mirror or raid
+ def handle_multi_arrays(prefix, array)
+ array.collect{ |a| [prefix] + a.split(' ') }.flatten
+ end
+
+ #builds up the vdevs for create command
+ def build_vdevs
+ if disk = @resource[:disk]
+ disk.collect { |d| d.split(' ') }.flatten
+ elsif mirror = @resource[:mirror]
+ handle_multi_arrays("mirror", mirror)
+ elsif raidz = @resource[:raidz]
+ handle_multi_arrays(raidzarity, raidz)
end
+ end
- #handle mirror or raid
- def handle_multi_arrays(prefix, array)
- array.collect{ |a| [prefix] + a.split(' ') }.flatten
- end
+ def create
+ zpool(*([:create, @resource[:pool]] + build_vdevs + build_named("spare") + build_named("log")))
+ end
- #builds up the vdevs for create command
- def build_vdevs
- if disk = @resource[:disk]
- disk.collect { |d| d.split(' ') }.flatten
- elsif mirror = @resource[:mirror]
- handle_multi_arrays("mirror", mirror)
- elsif raidz = @resource[:raidz]
- handle_multi_arrays(raidzarity, raidz)
- end
- end
-
- def create
- zpool(*([:create, @resource[:pool]] + build_vdevs + build_named("spare") + build_named("log")))
- end
+ def delete
+ zpool :destroy, @resource[:pool]
+ end
- def delete
- zpool :destroy, @resource[:pool]
+ def exists?
+ if current_pool[:pool] == :absent
+ false
+ else
+ true
end
+ end
- def exists?
- if current_pool[:pool] == :absent
- false
- else
- true
- end
+ [:disk, :mirror, :raidz, :log, :spare].each do |field|
+ define_method(field) do
+ current_pool[field]
end
- [:disk, :mirror, :raidz, :log, :spare].each do |field|
- define_method(field) do
- current_pool[field]
- end
-
- define_method(field.to_s + "=") do |should|
- Puppet.warning "NO CHANGES BEING MADE: zpool #{field} does not match, should be '#{should}' currently is '#{current_pool[field]}'"
- end
+ define_method(field.to_s + "=") do |should|
+ Puppet.warning "NO CHANGES BEING MADE: zpool #{field} does not match, should be '#{should}' currently is '#{current_pool[field]}'"
end
+ end
end
diff --git a/lib/puppet/rails.rb b/lib/puppet/rails.rb
index f1d97bf..414b1bc 100644
--- a/lib/puppet/rails.rb
+++ b/lib/puppet/rails.rb
@@ -4,132 +4,132 @@ require 'facter'
require 'puppet'
module Puppet::Rails
- TIME_DEBUG = true
-
- def self.connect
- # This global init does not work for testing, because we remove
- # the state dir on every test.
- return if ActiveRecord::Base.connected?
-
- Puppet.settings.use(:main, :rails, :master)
-
- ActiveRecord::Base.logger = Logger.new(Puppet[:railslog])
- begin
- loglevel = Logger.const_get(Puppet[:rails_loglevel].upcase)
- ActiveRecord::Base.logger.level = loglevel
- rescue => detail
- Puppet.warning "'#{Puppet[:rails_loglevel]}' is not a valid Rails log level; using debug"
- ActiveRecord::Base.logger.level = Logger::DEBUG
- end
-
- if (::ActiveRecord::VERSION::MAJOR == 2 and ::ActiveRecord::VERSION::MINOR <= 1)
- ActiveRecord::Base.allow_concurrency = true
- end
-
- ActiveRecord::Base.verify_active_connections!
-
- begin
- args = database_arguments
- Puppet.info "Connecting to #{args[:adapter]} database: #{args[:database]}"
- ActiveRecord::Base.establish_connection(args)
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- raise Puppet::Error, "Could not connect to database: #{detail}"
- end
+ TIME_DEBUG = true
+
+ def self.connect
+ # This global init does not work for testing, because we remove
+ # the state dir on every test.
+ return if ActiveRecord::Base.connected?
+
+ Puppet.settings.use(:main, :rails, :master)
+
+ ActiveRecord::Base.logger = Logger.new(Puppet[:railslog])
+ begin
+ loglevel = Logger.const_get(Puppet[:rails_loglevel].upcase)
+ ActiveRecord::Base.logger.level = loglevel
+ rescue => detail
+ Puppet.warning "'#{Puppet[:rails_loglevel]}' is not a valid Rails log level; using debug"
+ ActiveRecord::Base.logger.level = Logger::DEBUG
end
- # The arguments for initializing the database connection.
- def self.database_arguments
- adapter = Puppet[:dbadapter]
-
- args = {:adapter => adapter, :log_level => Puppet[:rails_loglevel]}
-
- case adapter
- when "sqlite3"
- args[:database] = Puppet[:dblocation]
- when "mysql", "postgresql"
- args[:host] = Puppet[:dbserver] unless Puppet[:dbserver].to_s.empty?
- args[:port] = Puppet[:dbport] unless Puppet[:dbport].to_s.empty?
- args[:username] = Puppet[:dbuser] unless Puppet[:dbuser].to_s.empty?
- args[:password] = Puppet[:dbpassword] unless Puppet[:dbpassword].to_s.empty?
- args[:database] = Puppet[:dbname]
- args[:reconnect]= true
-
- socket = Puppet[:dbsocket]
- args[:socket] = socket unless socket.to_s.empty?
-
- connections = Puppet[:dbconnections].to_i
- args[:pool] = connections if connections > 0
- when "oracle_enhanced":
- args[:database] = Puppet[:dbname] unless Puppet[:dbname].to_s.empty?
- args[:username] = Puppet[:dbuser] unless Puppet[:dbuser].to_s.empty?
- args[:password] = Puppet[:dbpassword] unless Puppet[:dbpassword].to_s.empty?
-
- connections = Puppet[:dbconnections].to_i
- args[:pool] = connections if connections > 0
- else
- raise ArgumentError, "Invalid db adapter #{adapter}"
- end
- args
+ if (::ActiveRecord::VERSION::MAJOR == 2 and ::ActiveRecord::VERSION::MINOR <= 1)
+ ActiveRecord::Base.allow_concurrency = true
end
- # Set up our database connection. It'd be nice to have a "use" system
- # that could make callbacks.
- def self.init
- raise Puppet::DevError, "No activerecord, cannot init Puppet::Rails" unless Puppet.features.rails?
+ ActiveRecord::Base.verify_active_connections!
- connect
+ begin
+ args = database_arguments
+ Puppet.info "Connecting to #{args[:adapter]} database: #{args[:database]}"
+ ActiveRecord::Base.establish_connection(args)
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ raise Puppet::Error, "Could not connect to database: #{detail}"
+ end
+ end
+
+ # The arguments for initializing the database connection.
+ def self.database_arguments
+ adapter = Puppet[:dbadapter]
+
+ args = {:adapter => adapter, :log_level => Puppet[:rails_loglevel]}
+
+ case adapter
+ when "sqlite3"
+ args[:database] = Puppet[:dblocation]
+ when "mysql", "postgresql"
+ args[:host] = Puppet[:dbserver] unless Puppet[:dbserver].to_s.empty?
+ args[:port] = Puppet[:dbport] unless Puppet[:dbport].to_s.empty?
+ args[:username] = Puppet[:dbuser] unless Puppet[:dbuser].to_s.empty?
+ args[:password] = Puppet[:dbpassword] unless Puppet[:dbpassword].to_s.empty?
+ args[:database] = Puppet[:dbname]
+ args[:reconnect]= true
+
+ socket = Puppet[:dbsocket]
+ args[:socket] = socket unless socket.to_s.empty?
+
+ connections = Puppet[:dbconnections].to_i
+ args[:pool] = connections if connections > 0
+ when "oracle_enhanced":
+ args[:database] = Puppet[:dbname] unless Puppet[:dbname].to_s.empty?
+ args[:username] = Puppet[:dbuser] unless Puppet[:dbuser].to_s.empty?
+ args[:password] = Puppet[:dbpassword] unless Puppet[:dbpassword].to_s.empty?
+
+ connections = Puppet[:dbconnections].to_i
+ args[:pool] = connections if connections > 0
+ else
+ raise ArgumentError, "Invalid db adapter #{adapter}"
+ end
+ args
+ end
+
+ # Set up our database connection. It'd be nice to have a "use" system
+ # that could make callbacks.
+ def self.init
+ raise Puppet::DevError, "No activerecord, cannot init Puppet::Rails" unless Puppet.features.rails?
- unless ActiveRecord::Base.connection.tables.include?("resources")
- require 'puppet/rails/database/schema'
- Puppet::Rails::Schema.init
- end
+ connect
- migrate if Puppet[:dbmigrate]
+ unless ActiveRecord::Base.connection.tables.include?("resources")
+ require 'puppet/rails/database/schema'
+ Puppet::Rails::Schema.init
end
- # Migrate to the latest db schema.
- def self.migrate
- dbdir = nil
- $LOAD_PATH.each { |d|
- tmp = File.join(d, "puppet/rails/database")
- if FileTest.directory?(tmp)
- dbdir = tmp
- break
- end
- }
-
- raise Puppet::Error, "Could not find Puppet::Rails database dir" unless dbdir
-
- raise Puppet::Error, "Database has problems, can't migrate." unless ActiveRecord::Base.connection.tables.include?("resources")
-
- Puppet.notice "Migrating"
-
- begin
- ActiveRecord::Migrator.migrate(dbdir)
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- raise Puppet::Error, "Could not migrate database: #{detail}"
- end
+ migrate if Puppet[:dbmigrate]
+ end
+
+ # Migrate to the latest db schema.
+ def self.migrate
+ dbdir = nil
+ $LOAD_PATH.each { |d|
+ tmp = File.join(d, "puppet/rails/database")
+ if FileTest.directory?(tmp)
+ dbdir = tmp
+ break
+ end
+ }
+
+ raise Puppet::Error, "Could not find Puppet::Rails database dir" unless dbdir
+
+ raise Puppet::Error, "Database has problems, can't migrate." unless ActiveRecord::Base.connection.tables.include?("resources")
+
+ Puppet.notice "Migrating"
+
+ begin
+ ActiveRecord::Migrator.migrate(dbdir)
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ raise Puppet::Error, "Could not migrate database: #{detail}"
end
+ end
- # Tear down the database. Mostly only used during testing.
- def self.teardown
- raise Puppet::DevError, "No activerecord, cannot init Puppet::Rails" unless Puppet.features.rails?
+ # Tear down the database. Mostly only used during testing.
+ def self.teardown
+ raise Puppet::DevError, "No activerecord, cannot init Puppet::Rails" unless Puppet.features.rails?
- Puppet.settings.use(:master, :rails)
+ Puppet.settings.use(:master, :rails)
- begin
- ActiveRecord::Base.establish_connection(database_arguments)
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- raise Puppet::Error, "Could not connect to database: #{detail}"
- end
+ begin
+ ActiveRecord::Base.establish_connection(database_arguments)
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ raise Puppet::Error, "Could not connect to database: #{detail}"
+ end
- ActiveRecord::Base.connection.tables.each do |t|
- ActiveRecord::Base.connection.drop_table t
- end
+ ActiveRecord::Base.connection.tables.each do |t|
+ ActiveRecord::Base.connection.drop_table t
end
+ end
end
require 'puppet/rails/host' if Puppet.features.rails?
diff --git a/lib/puppet/rails/benchmark.rb b/lib/puppet/rails/benchmark.rb
index 35e6fdc..375674e 100644
--- a/lib/puppet/rails/benchmark.rb
+++ b/lib/puppet/rails/benchmark.rb
@@ -1,63 +1,63 @@
require 'benchmark'
module Puppet::Rails::Benchmark
- $benchmarks = {:accumulated => {}}
+ $benchmarks = {:accumulated => {}}
- def time_debug?
- Puppet::Rails::TIME_DEBUG
- end
+ def time_debug?
+ Puppet::Rails::TIME_DEBUG
+ end
- def railsmark(message)
- result = nil
- seconds = Benchmark.realtime { result = yield }
- Puppet.debug(message + " in %0.2f seconds" % seconds)
+ def railsmark(message)
+ result = nil
+ seconds = Benchmark.realtime { result = yield }
+ Puppet.debug(message + " in %0.2f seconds" % seconds)
- $benchmarks[message] = seconds if time_debug?
- result
- end
+ $benchmarks[message] = seconds if time_debug?
+ result
+ end
- def debug_benchmark(message)
- return yield unless Puppet::Rails::TIME_DEBUG
+ def debug_benchmark(message)
+ return yield unless Puppet::Rails::TIME_DEBUG
- railsmark(message) { yield }
- end
+ railsmark(message) { yield }
+ end
- # Collect partial benchmarks to be logged when they're
- # all done.
- # These are always low-level debugging so we only
- # print them if time_debug is enabled.
- def accumulate_benchmark(message, label)
- return yield unless time_debug?
+ # Collect partial benchmarks to be logged when they're
+ # all done.
+ # These are always low-level debugging so we only
+ # print them if time_debug is enabled.
+ def accumulate_benchmark(message, label)
+ return yield unless time_debug?
- $benchmarks[:accumulated][message] ||= Hash.new(0)
- $benchmarks[:accumulated][message][label] += Benchmark.realtime { yield }
- end
+ $benchmarks[:accumulated][message] ||= Hash.new(0)
+ $benchmarks[:accumulated][message][label] += Benchmark.realtime { yield }
+ end
- # Log the accumulated marks.
- def log_accumulated_marks(message)
- return unless time_debug?
+ # Log the accumulated marks.
+ def log_accumulated_marks(message)
+ return unless time_debug?
- return if $benchmarks[:accumulated].empty? or $benchmarks[:accumulated][message].nil? or $benchmarks[:accumulated][message].empty?
+ return if $benchmarks[:accumulated].empty? or $benchmarks[:accumulated][message].nil? or $benchmarks[:accumulated][message].empty?
- $benchmarks[:accumulated][message].each do |label, value|
- Puppet.debug(message + ("(#{label})") + (" in %0.2f seconds" % value))
- end
+ $benchmarks[:accumulated][message].each do |label, value|
+ Puppet.debug(message + ("(#{label})") + (" in %0.2f seconds" % value))
end
+ end
- def write_benchmarks
- return unless time_debug?
+ def write_benchmarks
+ return unless time_debug?
- branch = %x{git branch}.split("\n").find { |l| l =~ /^\*/ }.sub("* ", '')
+ branch = %x{git branch}.split("\n").find { |l| l =~ /^\*/ }.sub("* ", '')
- file = "/tmp/time_debugging.yaml"
+ file = "/tmp/time_debugging.yaml"
- require 'yaml'
+ require 'yaml'
- if FileTest.exist?(file)
- data = YAML.load_file(file)
- else
- data = {}
- end
- data[branch] = $benchmarks
- Puppet::Util.secure_open(file, "w") { |f| f.print YAML.dump(data) }
+ if FileTest.exist?(file)
+ data = YAML.load_file(file)
+ else
+ data = {}
end
+ data[branch] = $benchmarks
+ Puppet::Util.secure_open(file, "w") { |f| f.print YAML.dump(data) }
+ end
end
diff --git a/lib/puppet/rails/database/001_add_created_at_to_all_tables.rb b/lib/puppet/rails/database/001_add_created_at_to_all_tables.rb
index 65432a6..22dffb8 100644
--- a/lib/puppet/rails/database/001_add_created_at_to_all_tables.rb
+++ b/lib/puppet/rails/database/001_add_created_at_to_all_tables.rb
@@ -1,13 +1,13 @@
class AddCreatedAtToAllTables < ActiveRecord::Migration
- def self.up
- ActiveRecord::Base.connection.tables.each do |t|
- add_column t.to_s, :created_at, :datetime unless ActiveRecord::Base.connection.columns(t).collect {|c| c.name}.include?("created_at")
- end
+ def self.up
+ ActiveRecord::Base.connection.tables.each do |t|
+ add_column t.to_s, :created_at, :datetime unless ActiveRecord::Base.connection.columns(t).collect {|c| c.name}.include?("created_at")
end
+ end
- def self.down
- ActiveRecord::Base.connection.tables.each do |t|
- remove_column t.to_s, :created_at unless ActiveRecord::Base.connection.columns(t).collect {|c| c.name}.include?("created_at")
- end
+ def self.down
+ ActiveRecord::Base.connection.tables.each do |t|
+ remove_column t.to_s, :created_at unless ActiveRecord::Base.connection.columns(t).collect {|c| c.name}.include?("created_at")
end
+ end
end
diff --git a/lib/puppet/rails/database/002_remove_duplicated_index_on_all_tables.rb b/lib/puppet/rails/database/002_remove_duplicated_index_on_all_tables.rb
index c1e60db..021889d 100644
--- a/lib/puppet/rails/database/002_remove_duplicated_index_on_all_tables.rb
+++ b/lib/puppet/rails/database/002_remove_duplicated_index_on_all_tables.rb
@@ -1,13 +1,13 @@
class RemoveDuplicatedIndexOnAllTables < ActiveRecord::Migration
- def self.up
- ActiveRecord::Base.connection.tables.each do |t|
- remove_index t.to_s, :id if ActiveRecord::Base.connection.indexes(t).collect {|c| c.columns}.include?("id")
- end
+ def self.up
+ ActiveRecord::Base.connection.tables.each do |t|
+ remove_index t.to_s, :id if ActiveRecord::Base.connection.indexes(t).collect {|c| c.columns}.include?("id")
end
+ end
- def self.down
- ActiveRecord::Base.connection.tables.each do |t|
- add_index t.to_s, :id, :integer => true unless ActiveRecord::Base.connection.indexes(t).collect {|c| c.columns}.include?("id")
- end
+ def self.down
+ ActiveRecord::Base.connection.tables.each do |t|
+ add_index t.to_s, :id, :integer => true unless ActiveRecord::Base.connection.indexes(t).collect {|c| c.columns}.include?("id")
end
+ end
end
diff --git a/lib/puppet/rails/database/003_add_environment_to_host.rb b/lib/puppet/rails/database/003_add_environment_to_host.rb
index 95f036d..5c06bb8 100644
--- a/lib/puppet/rails/database/003_add_environment_to_host.rb
+++ b/lib/puppet/rails/database/003_add_environment_to_host.rb
@@ -1,9 +1,9 @@
class AddEnvironmentToHost < ActiveRecord::Migration
- def self.up
- add_column :hosts, :environment, :string unless ActiveRecord::Base.connection.columns(:hosts).collect {|c| c.name}.include?("environment")
- end
+ def self.up
+ add_column :hosts, :environment, :string unless ActiveRecord::Base.connection.columns(:hosts).collect {|c| c.name}.include?("environment")
+ end
- def self.down
- remove_column :hosts, :environment if ActiveRecord::Base.connection.columns(:hosts).collect {|c| c.name}.include?("environment")
- end
+ def self.down
+ remove_column :hosts, :environment if ActiveRecord::Base.connection.columns(:hosts).collect {|c| c.name}.include?("environment")
+ end
end
diff --git a/lib/puppet/rails/database/schema.rb b/lib/puppet/rails/database/schema.rb
index 8cb7350..8b389d7 100644
--- a/lib/puppet/rails/database/schema.rb
+++ b/lib/puppet/rails/database/schema.rb
@@ -1,114 +1,114 @@
class Puppet::Rails::Schema
- def self.init
- oldout = nil
- Puppet::Util.benchmark(Puppet, :notice, "Initialized database") do
- # We want to rewrite stdout, so we don't get migration messages.
- oldout = $stdout
- $stdout = File.open("/dev/null", "w")
- ActiveRecord::Schema.define do
- create_table :resources do |t|
- t.column :title, :text, :null => false
- t.column :restype, :string, :null => false
- t.column :host_id, :integer
- t.column :source_file_id, :integer
- t.column :exported, :boolean
- t.column :line, :integer
- t.column :updated_at, :datetime
- t.column :created_at, :datetime
- end
- add_index :resources, :host_id, :integer => true
- add_index :resources, :source_file_id, :integer => true
+ def self.init
+ oldout = nil
+ Puppet::Util.benchmark(Puppet, :notice, "Initialized database") do
+ # We want to rewrite stdout, so we don't get migration messages.
+ oldout = $stdout
+ $stdout = File.open("/dev/null", "w")
+ ActiveRecord::Schema.define do
+ create_table :resources do |t|
+ t.column :title, :text, :null => false
+ t.column :restype, :string, :null => false
+ t.column :host_id, :integer
+ t.column :source_file_id, :integer
+ t.column :exported, :boolean
+ t.column :line, :integer
+ t.column :updated_at, :datetime
+ t.column :created_at, :datetime
+ end
+ add_index :resources, :host_id, :integer => true
+ add_index :resources, :source_file_id, :integer => true
- # Thanks, mysql! MySQL requires a length on indexes in text fields.
- # So, we provide them for mysql and handle everything else specially.
- # Oracle doesn't index on CLOB fields, so we skip it
- if Puppet[:dbadapter] == "mysql"
- execute "CREATE INDEX typentitle ON resources (restype,title(50));"
- elsif Puppet[:dbadapter] != "oracle_enhanced"
- add_index :resources, [:title, :restype]
- end
+ # Thanks, mysql! MySQL requires a length on indexes in text fields.
+ # So, we provide them for mysql and handle everything else specially.
+ # Oracle doesn't index on CLOB fields, so we skip it
+ if Puppet[:dbadapter] == "mysql"
+ execute "CREATE INDEX typentitle ON resources (restype,title(50));"
+ elsif Puppet[:dbadapter] != "oracle_enhanced"
+ add_index :resources, [:title, :restype]
+ end
- create_table :source_files do |t|
- t.column :filename, :string
- t.column :path, :string
- t.column :updated_at, :datetime
- t.column :created_at, :datetime
- end
- add_index :source_files, :filename
+ create_table :source_files do |t|
+ t.column :filename, :string
+ t.column :path, :string
+ t.column :updated_at, :datetime
+ t.column :created_at, :datetime
+ end
+ add_index :source_files, :filename
- create_table :resource_tags do |t|
- t.column :resource_id, :integer
- t.column :puppet_tag_id, :integer
- t.column :updated_at, :datetime
- t.column :created_at, :datetime
- end
- add_index :resource_tags, :resource_id, :integer => true
- add_index :resource_tags, :puppet_tag_id, :integer => true
+ create_table :resource_tags do |t|
+ t.column :resource_id, :integer
+ t.column :puppet_tag_id, :integer
+ t.column :updated_at, :datetime
+ t.column :created_at, :datetime
+ end
+ add_index :resource_tags, :resource_id, :integer => true
+ add_index :resource_tags, :puppet_tag_id, :integer => true
- create_table :puppet_tags do |t|
- t.column :name, :string
- t.column :updated_at, :datetime
- t.column :created_at, :datetime
- end
+ create_table :puppet_tags do |t|
+ t.column :name, :string
+ t.column :updated_at, :datetime
+ t.column :created_at, :datetime
+ end
- # Oracle automatically creates a primary key index
- add_index :puppet_tags, :id, :integer => true if Puppet[:dbadapter] != "oracle_enhanced"
+ # Oracle automatically creates a primary key index
+ add_index :puppet_tags, :id, :integer => true if Puppet[:dbadapter] != "oracle_enhanced"
- create_table :hosts do |t|
- t.column :name, :string, :null => false
- t.column :ip, :string
- t.column :environment, :text
- t.column :last_compile, :datetime
- t.column :last_freshcheck, :datetime
- t.column :last_report, :datetime
- #Use updated_at to automatically add timestamp on save.
- t.column :updated_at, :datetime
- t.column :source_file_id, :integer
- t.column :created_at, :datetime
- end
- add_index :hosts, :source_file_id, :integer => true
- add_index :hosts, :name
+ create_table :hosts do |t|
+ t.column :name, :string, :null => false
+ t.column :ip, :string
+ t.column :environment, :text
+ t.column :last_compile, :datetime
+ t.column :last_freshcheck, :datetime
+ t.column :last_report, :datetime
+ #Use updated_at to automatically add timestamp on save.
+ t.column :updated_at, :datetime
+ t.column :source_file_id, :integer
+ t.column :created_at, :datetime
+ end
+ add_index :hosts, :source_file_id, :integer => true
+ add_index :hosts, :name
- create_table :fact_names do |t|
- t.column :name, :string, :null => false
- t.column :updated_at, :datetime
- t.column :created_at, :datetime
- end
- add_index :fact_names, :name
+ create_table :fact_names do |t|
+ t.column :name, :string, :null => false
+ t.column :updated_at, :datetime
+ t.column :created_at, :datetime
+ end
+ add_index :fact_names, :name
- create_table :fact_values do |t|
- t.column :value, :text, :null => false
- t.column :fact_name_id, :integer, :null => false
- t.column :host_id, :integer, :null => false
- t.column :updated_at, :datetime
- t.column :created_at, :datetime
- end
- add_index :fact_values, :fact_name_id, :integer => true
- add_index :fact_values, :host_id, :integer => true
+ create_table :fact_values do |t|
+ t.column :value, :text, :null => false
+ t.column :fact_name_id, :integer, :null => false
+ t.column :host_id, :integer, :null => false
+ t.column :updated_at, :datetime
+ t.column :created_at, :datetime
+ end
+ add_index :fact_values, :fact_name_id, :integer => true
+ add_index :fact_values, :host_id, :integer => true
- create_table :param_values do |t|
- t.column :value, :text, :null => false
- t.column :param_name_id, :integer, :null => false
- t.column :line, :integer
- t.column :resource_id, :integer
- t.column :updated_at, :datetime
- t.column :created_at, :datetime
- end
- add_index :param_values, :param_name_id, :integer => true
- add_index :param_values, :resource_id, :integer => true
+ create_table :param_values do |t|
+ t.column :value, :text, :null => false
+ t.column :param_name_id, :integer, :null => false
+ t.column :line, :integer
+ t.column :resource_id, :integer
+ t.column :updated_at, :datetime
+ t.column :created_at, :datetime
+ end
+ add_index :param_values, :param_name_id, :integer => true
+ add_index :param_values, :resource_id, :integer => true
- create_table :param_names do |t|
- t.column :name, :string, :null => false
- t.column :updated_at, :datetime
- t.column :created_at, :datetime
- end
- add_index :param_names, :name
- end
+ create_table :param_names do |t|
+ t.column :name, :string, :null => false
+ t.column :updated_at, :datetime
+ t.column :created_at, :datetime
end
- ensure
- $stdout.close
- $stdout = oldout if oldout
- oldout = nil
+ add_index :param_names, :name
+ end
end
+ ensure
+ $stdout.close
+ $stdout = oldout if oldout
+ oldout = nil
+ end
end
diff --git a/lib/puppet/rails/fact_name.rb b/lib/puppet/rails/fact_name.rb
index e6e7c5d..fb40ec4 100644
--- a/lib/puppet/rails/fact_name.rb
+++ b/lib/puppet/rails/fact_name.rb
@@ -1,7 +1,7 @@
require 'puppet/rails/fact_value'
class Puppet::Rails::FactName < ActiveRecord::Base
- has_many :fact_values, :dependent => :destroy
+ has_many :fact_values, :dependent => :destroy
end
# $Id: fact_name.rb 1952 2006-12-19 05:47:57Z luke $
diff --git a/lib/puppet/rails/fact_value.rb b/lib/puppet/rails/fact_value.rb
index a451cbb..45a88b2 100644
--- a/lib/puppet/rails/fact_value.rb
+++ b/lib/puppet/rails/fact_value.rb
@@ -1,10 +1,10 @@
class Puppet::Rails::FactValue < ActiveRecord::Base
- belongs_to :fact_name
- belongs_to :host
+ belongs_to :fact_name
+ belongs_to :host
- def to_label
- "#{self.fact_name.name}"
- end
+ def to_label
+ "#{self.fact_name.name}"
+ end
end
# $Id: fact_value.rb 1952 2006-12-19 05:47:57Z luke $
diff --git a/lib/puppet/rails/host.rb b/lib/puppet/rails/host.rb
index 5107902..6c008bc 100644
--- a/lib/puppet/rails/host.rb
+++ b/lib/puppet/rails/host.rb
@@ -5,318 +5,318 @@ require 'puppet/rails/benchmark'
require 'puppet/util/rails/collection_merger'
class Puppet::Rails::Host < ActiveRecord::Base
- include Puppet::Rails::Benchmark
- extend Puppet::Rails::Benchmark
- include Puppet::Util
- include Puppet::Util::CollectionMerger
-
- has_many :fact_values, :dependent => :destroy, :class_name => "Puppet::Rails::FactValue"
- has_many :fact_names, :through => :fact_values, :class_name => "Puppet::Rails::FactName"
- belongs_to :source_file
- has_many :resources, :dependent => :destroy, :class_name => "Puppet::Rails::Resource"
-
- # If the host already exists, get rid of its objects
- def self.clean(host)
- if obj = self.find_by_name(host)
- obj.rails_objects.clear
- return obj
- else
- return nil
- end
+ include Puppet::Rails::Benchmark
+ extend Puppet::Rails::Benchmark
+ include Puppet::Util
+ include Puppet::Util::CollectionMerger
+
+ has_many :fact_values, :dependent => :destroy, :class_name => "Puppet::Rails::FactValue"
+ has_many :fact_names, :through => :fact_values, :class_name => "Puppet::Rails::FactName"
+ belongs_to :source_file
+ has_many :resources, :dependent => :destroy, :class_name => "Puppet::Rails::Resource"
+
+ # If the host already exists, get rid of its objects
+ def self.clean(host)
+ if obj = self.find_by_name(host)
+ obj.rails_objects.clear
+ return obj
+ else
+ return nil
end
+ end
- def self.from_puppet(node)
- host = find_by_name(node.name) || new(:name => node.name)
-
- {"ipaddress" => "ip", "environment" => "environment"}.each do |myparam, itsparam|
- if value = node.send(myparam)
- host.send(itsparam + "=", value)
- end
- end
+ def self.from_puppet(node)
+ host = find_by_name(node.name) || new(:name => node.name)
- host
+ {"ipaddress" => "ip", "environment" => "environment"}.each do |myparam, itsparam|
+ if value = node.send(myparam)
+ host.send(itsparam + "=", value)
+ end
end
- # Store our host in the database.
- def self.store(node, resources)
- args = {}
-
- host = nil
- railsmark "Stored node" do
- transaction do
- #unless host = find_by_name(name)
-
- debug_benchmark("Searched for host")do
- unless host = find_by_name(node.name)
- host = new(:name => node.name)
- end
- end
- if ip = node.parameters["ipaddress"]
- host.ip = ip
- end
-
- if env = node.environment
- host.environment = env
- end
-
- # Store the facts into the database.
- host.merge_facts(node.parameters)
+ host
+ end
- debug_benchmark("Handled resources") {
- host.merge_resources(resources)
- }
+ # Store our host in the database.
+ def self.store(node, resources)
+ args = {}
- host.last_compile = Time.now
-
- debug_benchmark("Saved host") {
- host.save
- }
- end
+ host = nil
+ railsmark "Stored node" do
+ transaction do
+ #unless host = find_by_name(name)
+ debug_benchmark("Searched for host")do
+ unless host = find_by_name(node.name)
+ host = new(:name => node.name)
+ end
+ end
+ if ip = node.parameters["ipaddress"]
+ host.ip = ip
end
- # This only runs if time debugging is enabled.
- write_benchmarks
+ if env = node.environment
+ host.environment = env
+ end
- host
- end
+ # Store the facts into the database.
+ host.merge_facts(node.parameters)
- # Return the value of a fact.
- def fact(name)
+ debug_benchmark("Handled resources") {
+ host.merge_resources(resources)
+ }
- if fv = self.fact_values.find(
- :all, :include => :fact_name,
+ host.last_compile = Time.now
- :conditions => "fact_names.name = '#{name}'")
- return fv
- else
- return nil
- end
- end
+ debug_benchmark("Saved host") {
+ host.save
+ }
+ end
- # returns a hash of fact_names.name => [ fact_values ] for this host.
- # Note that 'fact_values' is actually a list of the value instances, not
- # just actual values.
- def get_facts_hash
- fact_values = self.fact_values.find(:all, :include => :fact_name)
- return fact_values.inject({}) do | hash, value |
- hash[value.fact_name.name] ||= []
- hash[value.fact_name.name] << value
- hash
- end
end
+ # This only runs if time debugging is enabled.
+ write_benchmarks
- # This is *very* similar to the merge_parameters method
- # of Puppet::Rails::Resource.
- def merge_facts(facts)
- db_facts = {}
+ host
+ end
- deletions = []
- self.fact_values.find(:all, :include => :fact_name).each do |value|
- deletions << value['id'] and next unless facts.include?(value['name'])
- # Now store them for later testing.
- db_facts[value['name']] ||= []
- db_facts[value['name']] << value
- end
+ # Return the value of a fact.
+ def fact(name)
- # Now get rid of any parameters whose value list is different.
- # This might be extra work in cases where an array has added or lost
- # a single value, but in the most common case (a single value has changed)
- # this makes sense.
- db_facts.each do |name, value_hashes|
- values = value_hashes.collect { |v| v['value'] }
+ if fv = self.fact_values.find(
+ :all, :include => :fact_name,
- unless values == facts[name]
- value_hashes.each { |v| deletions << v['id'] }
- end
- end
+ :conditions => "fact_names.name = '#{name}'")
+ return fv
+ else
+ return nil
+ end
+ end
+
+ # returns a hash of fact_names.name => [ fact_values ] for this host.
+ # Note that 'fact_values' is actually a list of the value instances, not
+ # just actual values.
+ def get_facts_hash
+ fact_values = self.fact_values.find(:all, :include => :fact_name)
+ return fact_values.inject({}) do | hash, value |
+ hash[value.fact_name.name] ||= []
+ hash[value.fact_name.name] << value
+ hash
+ end
+ end
- # Perform our deletions.
- Puppet::Rails::FactValue.delete(deletions) unless deletions.empty?
- # Lastly, add any new parameters.
- facts.each do |name, value|
- next if db_facts.include?(name)
- values = value.is_a?(Array) ? value : [value]
+ # This is *very* similar to the merge_parameters method
+ # of Puppet::Rails::Resource.
+ def merge_facts(facts)
+ db_facts = {}
- values.each do |v|
- fact_values.build(:value => v, :fact_name => Puppet::Rails::FactName.find_or_create_by_name(name))
- end
- end
+ deletions = []
+ self.fact_values.find(:all, :include => :fact_name).each do |value|
+ deletions << value['id'] and next unless facts.include?(value['name'])
+ # Now store them for later testing.
+ db_facts[value['name']] ||= []
+ db_facts[value['name']] << value
end
- # Set our resources.
- def merge_resources(list)
- # keep only exported resources in thin_storeconfig mode
- list = list.select { |r| r.exported? } if Puppet.settings[:thin_storeconfigs]
-
- resources_by_id = nil
- debug_benchmark("Searched for resources") {
- resources_by_id = find_resources
- }
-
- debug_benchmark("Searched for resource params and tags") {
- find_resources_parameters_tags(resources_by_id)
- } if id
+ # Now get rid of any parameters whose value list is different.
+ # This might be extra work in cases where an array has added or lost
+ # a single value, but in the most common case (a single value has changed)
+ # this makes sense.
+ db_facts.each do |name, value_hashes|
+ values = value_hashes.collect { |v| v['value'] }
- debug_benchmark("Performed resource comparison") {
- compare_to_catalog(resources_by_id, list)
- }
+ unless values == facts[name]
+ value_hashes.each { |v| deletions << v['id'] }
+ end
end
- def find_resources
- condition = { :exported => true } if Puppet.settings[:thin_storeconfigs]
+ # Perform our deletions.
+ Puppet::Rails::FactValue.delete(deletions) unless deletions.empty?
- resources.find(:all, :include => :source_file, :conditions => condition || {}).inject({}) do | hash, resource |
- hash[resource.id] = resource
- hash
- end
- end
+ # Lastly, add any new parameters.
+ facts.each do |name, value|
+ next if db_facts.include?(name)
+ values = value.is_a?(Array) ? value : [value]
- def find_resources_parameters_tags(resources)
- find_resources_parameters(resources)
- find_resources_tags(resources)
+ values.each do |v|
+ fact_values.build(:value => v, :fact_name => Puppet::Rails::FactName.find_or_create_by_name(name))
+ end
end
+ end
- def compare_to_catalog(existing, list)
- compiled = list.inject({}) do |hash, resource|
- hash[resource.ref] = resource
- hash
- end
+ # Set our resources.
+ def merge_resources(list)
+ # keep only exported resources in thin_storeconfig mode
+ list = list.select { |r| r.exported? } if Puppet.settings[:thin_storeconfigs]
- resources = nil
- debug_benchmark("Resource removal") {
- resources = remove_unneeded_resources(compiled, existing)
- }
+ resources_by_id = nil
+ debug_benchmark("Searched for resources") {
+ resources_by_id = find_resources
+ }
- # Now for all resources in the catalog but not in the db, we're pretty easy.
- additions = nil
- debug_benchmark("Resource merger") {
- additions = perform_resource_merger(compiled, resources)
- }
+ debug_benchmark("Searched for resource params and tags") {
+ find_resources_parameters_tags(resources_by_id)
+ } if id
- debug_benchmark("Resource addition") {
- additions.each do |resource|
- build_rails_resource_from_parser_resource(resource)
- end
+ debug_benchmark("Performed resource comparison") {
+ compare_to_catalog(resources_by_id, list)
+ }
+ end
- log_accumulated_marks "Added resources"
- }
- end
+ def find_resources
+ condition = { :exported => true } if Puppet.settings[:thin_storeconfigs]
- def add_new_resources(additions)
- additions.each do |resource|
- Puppet::Rails::Resource.from_parser_resource(self, resource)
- end
+ resources.find(:all, :include => :source_file, :conditions => condition || {}).inject({}) do | hash, resource |
+ hash[resource.id] = resource
+ hash
end
+ end
- # Turn a parser resource into a Rails resource.
- def build_rails_resource_from_parser_resource(resource)
- db_resource = nil
- accumulate_benchmark("Added resources", :initialization) {
- args = Puppet::Rails::Resource.rails_resource_initial_args(resource)
+ def find_resources_parameters_tags(resources)
+ find_resources_parameters(resources)
+ find_resources_tags(resources)
+ end
- db_resource = self.resources.build(args)
+ def compare_to_catalog(existing, list)
+ compiled = list.inject({}) do |hash, resource|
+ hash[resource.ref] = resource
+ hash
+ end
- # Our file= method does the name to id conversion.
- db_resource.file = resource.file
- }
+ resources = nil
+ debug_benchmark("Resource removal") {
+ resources = remove_unneeded_resources(compiled, existing)
+ }
+
+ # Now for all resources in the catalog but not in the db, we're pretty easy.
+ additions = nil
+ debug_benchmark("Resource merger") {
+ additions = perform_resource_merger(compiled, resources)
+ }
+
+ debug_benchmark("Resource addition") {
+ additions.each do |resource|
+ build_rails_resource_from_parser_resource(resource)
+ end
+
+ log_accumulated_marks "Added resources"
+ }
+ end
+
+ def add_new_resources(additions)
+ additions.each do |resource|
+ Puppet::Rails::Resource.from_parser_resource(self, resource)
+ end
+ end
+ # Turn a parser resource into a Rails resource.
+ def build_rails_resource_from_parser_resource(resource)
+ db_resource = nil
+ accumulate_benchmark("Added resources", :initialization) {
+ args = Puppet::Rails::Resource.rails_resource_initial_args(resource)
- accumulate_benchmark("Added resources", :parameters) {
- resource.each do |param, value|
- Puppet::Rails::ParamValue.from_parser_param(param, value).each do |value_hash|
- db_resource.param_values.build(value_hash)
- end
- end
- }
+ db_resource = self.resources.build(args)
- accumulate_benchmark("Added resources", :tags) {
- resource.tags.each { |tag| db_resource.add_resource_tag(tag) }
- }
+ # Our file= method does the name to id conversion.
+ db_resource.file = resource.file
+ }
- db_resource.save
- db_resource
- end
+ accumulate_benchmark("Added resources", :parameters) {
+ resource.each do |param, value|
+ Puppet::Rails::ParamValue.from_parser_param(param, value).each do |value_hash|
+ db_resource.param_values.build(value_hash)
+ end
+ end
+ }
+ accumulate_benchmark("Added resources", :tags) {
+ resource.tags.each { |tag| db_resource.add_resource_tag(tag) }
+ }
- def perform_resource_merger(compiled, resources)
- return compiled.values if resources.empty?
+ db_resource.save
- # Now for all resources in the catalog but not in the db, we're pretty easy.
- additions = []
- compiled.each do |ref, resource|
- if db_resource = resources[ref]
- db_resource.merge_parser_resource(resource)
- else
- additions << resource
- end
- end
- log_accumulated_marks "Resource merger"
+ db_resource
+ end
- additions
- end
- def remove_unneeded_resources(compiled, existing)
- deletions = []
- resources = {}
- existing.each do |id, resource|
- # it seems that it can happen (see bug #2010) some resources are duplicated in the
- # database (ie logically corrupted database), in which case we remove the extraneous
- # entries.
- if resources.include?(resource.ref)
- deletions << id
- next
- end
-
- # If the resource is in the db but not in the catalog, mark it
- # for removal.
- unless compiled.include?(resource.ref)
- deletions << id
- next
- end
-
- resources[resource.ref] = resource
- end
- # We need to use 'destroy' here, not 'delete', so that all
- # dependent objects get removed, too.
- Puppet::Rails::Resource.destroy(deletions) unless deletions.empty?
+ def perform_resource_merger(compiled, resources)
+ return compiled.values if resources.empty?
- resources
+ # Now for all resources in the catalog but not in the db, we're pretty easy.
+ additions = []
+ compiled.each do |ref, resource|
+ if db_resource = resources[ref]
+ db_resource.merge_parser_resource(resource)
+ else
+ additions << resource
+ end
end
-
- def find_resources_parameters(resources)
- params = Puppet::Rails::ParamValue.find_all_params_from_host(self)
-
- # assign each loaded parameters/tags to the resource it belongs to
- params.each do |param|
- resources[param['resource_id']].add_param_to_list(param) if resources.include?(param['resource_id'])
- end
+ log_accumulated_marks "Resource merger"
+
+ additions
+ end
+
+ def remove_unneeded_resources(compiled, existing)
+ deletions = []
+ resources = {}
+ existing.each do |id, resource|
+ # it seems that it can happen (see bug #2010) some resources are duplicated in the
+ # database (ie logically corrupted database), in which case we remove the extraneous
+ # entries.
+ if resources.include?(resource.ref)
+ deletions << id
+ next
+ end
+
+ # If the resource is in the db but not in the catalog, mark it
+ # for removal.
+ unless compiled.include?(resource.ref)
+ deletions << id
+ next
+ end
+
+ resources[resource.ref] = resource
end
+ # We need to use 'destroy' here, not 'delete', so that all
+ # dependent objects get removed, too.
+ Puppet::Rails::Resource.destroy(deletions) unless deletions.empty?
- def find_resources_tags(resources)
- tags = Puppet::Rails::ResourceTag.find_all_tags_from_host(self)
+ resources
+ end
- tags.each do |tag|
- resources[tag['resource_id']].add_tag_to_list(tag) if resources.include?(tag['resource_id'])
- end
- end
+ def find_resources_parameters(resources)
+ params = Puppet::Rails::ParamValue.find_all_params_from_host(self)
- def update_connect_time
- self.last_connect = Time.now
- save
+ # assign each loaded parameters/tags to the resource it belongs to
+ params.each do |param|
+ resources[param['resource_id']].add_param_to_list(param) if resources.include?(param['resource_id'])
end
+ end
- def to_puppet
- node = Puppet::Node.new(self.name)
- {"ip" => "ipaddress", "environment" => "environment"}.each do |myparam, itsparam|
- if value = send(myparam)
- node.send(itsparam + "=", value)
- end
- end
+ def find_resources_tags(resources)
+ tags = Puppet::Rails::ResourceTag.find_all_tags_from_host(self)
- node
+ tags.each do |tag|
+ resources[tag['resource_id']].add_tag_to_list(tag) if resources.include?(tag['resource_id'])
+ end
+ end
+
+ def update_connect_time
+ self.last_connect = Time.now
+ save
+ end
+
+ def to_puppet
+ node = Puppet::Node.new(self.name)
+ {"ip" => "ipaddress", "environment" => "environment"}.each do |myparam, itsparam|
+ if value = send(myparam)
+ node.send(itsparam + "=", value)
+ end
end
+
+ node
+ end
end
diff --git a/lib/puppet/rails/param_name.rb b/lib/puppet/rails/param_name.rb
index 69e2fb6..91cf456 100644
--- a/lib/puppet/rails/param_name.rb
+++ b/lib/puppet/rails/param_name.rb
@@ -3,23 +3,23 @@ require 'puppet/rails/param_value'
require 'puppet/util/rails/cache_accumulator'
class Puppet::Rails::ParamName < ActiveRecord::Base
- include Puppet::Util::CollectionMerger
- has_many :param_values, :dependent => :destroy
+ include Puppet::Util::CollectionMerger
+ has_many :param_values, :dependent => :destroy
- include Puppet::Util::CacheAccumulator
- accumulates :name
+ include Puppet::Util::CacheAccumulator
+ accumulates :name
- def to_resourceparam(resource, source)
- hash = {}
- hash[:name] = self.name.to_sym
- hash[:source] = source
- hash[:value] = resource.param_values.find(:all, :conditions => [ "param_name_id = ?", self.id]).collect { |v| v.value }
- if hash[:value].length == 1
- hash[:value] = hash[:value].shift
- elsif hash[:value].empty?
- hash[:value] = nil
- end
- Puppet::Parser::Resource::Param.new hash
+ def to_resourceparam(resource, source)
+ hash = {}
+ hash[:name] = self.name.to_sym
+ hash[:source] = source
+ hash[:value] = resource.param_values.find(:all, :conditions => [ "param_name_id = ?", self.id]).collect { |v| v.value }
+ if hash[:value].length == 1
+ hash[:value] = hash[:value].shift
+ elsif hash[:value].empty?
+ hash[:value] = nil
end
+ Puppet::Parser::Resource::Param.new hash
+ end
end
diff --git a/lib/puppet/rails/param_value.rb b/lib/puppet/rails/param_value.rb
index e4b5a66..d7c88f8 100644
--- a/lib/puppet/rails/param_value.rb
+++ b/lib/puppet/rails/param_value.rb
@@ -1,74 +1,74 @@
require 'puppet/util/rails/reference_serializer'
class Puppet::Rails::ParamValue < ActiveRecord::Base
- include Puppet::Util::ReferenceSerializer
- extend Puppet::Util::ReferenceSerializer
+ include Puppet::Util::ReferenceSerializer
+ extend Puppet::Util::ReferenceSerializer
- belongs_to :param_name
- belongs_to :resource
+ belongs_to :param_name
+ belongs_to :resource
- # Store a new parameter in a Rails db.
- def self.from_parser_param(param, values)
- values = munge_parser_values(values)
+ # Store a new parameter in a Rails db.
+ def self.from_parser_param(param, values)
+ values = munge_parser_values(values)
- param_name = Puppet::Rails::ParamName.find_or_create_by_name(param.to_s)
- return values.collect do |v|
- {:value => v, :param_name => param_name}
- end
+ param_name = Puppet::Rails::ParamName.find_or_create_by_name(param.to_s)
+ return values.collect do |v|
+ {:value => v, :param_name => param_name}
end
+ end
- # Make sure an array (or possibly not an array) of values is correctly
- # set up for Rails. The main thing is that Resource::Reference objects
- # should stay objects, so they just get serialized.
- def self.munge_parser_values(value)
- values = value.is_a?(Array) ? value : [value]
- values.map do |v|
- if v.is_a?(Puppet::Resource)
- v
- else
- v.to_s
- end
- end
+ # Make sure an array (or possibly not an array) of values is correctly
+ # set up for Rails. The main thing is that Resource::Reference objects
+ # should stay objects, so they just get serialized.
+ def self.munge_parser_values(value)
+ values = value.is_a?(Array) ? value : [value]
+ values.map do |v|
+ if v.is_a?(Puppet::Resource)
+ v
+ else
+ v.to_s
+ end
end
+ end
- def value
- unserialize_value(self[:value])
- end
+ def value
+ unserialize_value(self[:value])
+ end
- # I could not find a cleaner way to handle making sure that resource references
- # were consistently serialized and deserialized.
- def value=(val)
- self[:value] = serialize_value(val)
- end
+ # I could not find a cleaner way to handle making sure that resource references
+ # were consistently serialized and deserialized.
+ def value=(val)
+ self[:value] = serialize_value(val)
+ end
- def to_label
- "#{self.param_name.name}"
- end
+ def to_label
+ "#{self.param_name.name}"
+ end
- # returns an array of hash containing all the parameters of a given resource
- def self.find_all_params_from_resource(db_resource)
- params = db_resource.connection.select_all("SELECT v.id, v.value, v.line, v.resource_id, v.param_name_id, n.name FROM param_values v INNER JOIN param_names n ON v.param_name_id=n.id WHERE v.resource_id=#{db_resource.id}")
- params.each do |val|
- val['value'] = unserialize_value(val['value'])
- val['line'] = val['line'] ? Integer(val['line']) : nil
- val['resource_id'] = Integer(val['resource_id'])
- end
- params
+ # returns an array of hash containing all the parameters of a given resource
+ def self.find_all_params_from_resource(db_resource)
+ params = db_resource.connection.select_all("SELECT v.id, v.value, v.line, v.resource_id, v.param_name_id, n.name FROM param_values v INNER JOIN param_names n ON v.param_name_id=n.id WHERE v.resource_id=#{db_resource.id}")
+ params.each do |val|
+ val['value'] = unserialize_value(val['value'])
+ val['line'] = val['line'] ? Integer(val['line']) : nil
+ val['resource_id'] = Integer(val['resource_id'])
end
+ params
+ end
- # returns an array of hash containing all the parameters of a given host
- def self.find_all_params_from_host(db_host)
- params = db_host.connection.select_all("SELECT v.id, v.value, v.line, v.resource_id, v.param_name_id, n.name FROM param_values v INNER JOIN resources r ON v.resource_id=r.id INNER JOIN param_names n ON v.param_name_id=n.id WHERE r.host_id=#{db_host.id}")
- params.each do |val|
- val['value'] = unserialize_value(val['value'])
- val['line'] = val['line'] ? Integer(val['line']) : nil
- val['resource_id'] = Integer(val['resource_id'])
- end
- params
+ # returns an array of hash containing all the parameters of a given host
+ def self.find_all_params_from_host(db_host)
+ params = db_host.connection.select_all("SELECT v.id, v.value, v.line, v.resource_id, v.param_name_id, n.name FROM param_values v INNER JOIN resources r ON v.resource_id=r.id INNER JOIN param_names n ON v.param_name_id=n.id WHERE r.host_id=#{db_host.id}")
+ params.each do |val|
+ val['value'] = unserialize_value(val['value'])
+ val['line'] = val['line'] ? Integer(val['line']) : nil
+ val['resource_id'] = Integer(val['resource_id'])
end
+ params
+ end
- def to_s
- "#{self.name} => #{self.value}"
- end
+ def to_s
+ "#{self.name} => #{self.value}"
+ end
end
diff --git a/lib/puppet/rails/puppet_tag.rb b/lib/puppet/rails/puppet_tag.rb
index 2cc2c13..fadbfa6 100644
--- a/lib/puppet/rails/puppet_tag.rb
+++ b/lib/puppet/rails/puppet_tag.rb
@@ -2,9 +2,9 @@ require 'puppet/rails/resource_tag'
require 'puppet/util/rails/cache_accumulator'
class Puppet::Rails::PuppetTag < ActiveRecord::Base
- has_many :resource_tags, :dependent => :destroy
- has_many :resources, :through => :resource_tags
+ has_many :resource_tags, :dependent => :destroy
+ has_many :resources, :through => :resource_tags
- include Puppet::Util::CacheAccumulator
- accumulates :name
+ include Puppet::Util::CacheAccumulator
+ accumulates :name
end
diff --git a/lib/puppet/rails/resource.rb b/lib/puppet/rails/resource.rb
index f485909..a5cdd0c 100644
--- a/lib/puppet/rails/resource.rb
+++ b/lib/puppet/rails/resource.rb
@@ -6,226 +6,226 @@ require 'puppet/rails/benchmark'
require 'puppet/util/rails/collection_merger'
class Puppet::Rails::Resource < ActiveRecord::Base
- include Puppet::Util::CollectionMerger
- include Puppet::Util::ReferenceSerializer
- include Puppet::Rails::Benchmark
+ include Puppet::Util::CollectionMerger
+ include Puppet::Util::ReferenceSerializer
+ include Puppet::Rails::Benchmark
+
+ has_many :param_values, :dependent => :destroy, :class_name => "Puppet::Rails::ParamValue"
+ has_many :param_names, :through => :param_values, :class_name => "Puppet::Rails::ParamName"
- has_many :param_values, :dependent => :destroy, :class_name => "Puppet::Rails::ParamValue"
- has_many :param_names, :through => :param_values, :class_name => "Puppet::Rails::ParamName"
+ has_many :resource_tags, :dependent => :destroy, :class_name => "Puppet::Rails::ResourceTag"
+ has_many :puppet_tags, :through => :resource_tags, :class_name => "Puppet::Rails::PuppetTag"
- has_many :resource_tags, :dependent => :destroy, :class_name => "Puppet::Rails::ResourceTag"
- has_many :puppet_tags, :through => :resource_tags, :class_name => "Puppet::Rails::PuppetTag"
+ belongs_to :source_file
+ belongs_to :host
- belongs_to :source_file
- belongs_to :host
+ @tags = {}
+ def self.tags
+ @tags
+ end
- @tags = {}
- def self.tags
- @tags
+ # Determine the basic details on the resource.
+ def self.rails_resource_initial_args(resource)
+ result = [:type, :title, :line].inject({}) do |hash, param|
+ # 'type' isn't a valid column name, so we have to use another name.
+ to = (param == :type) ? :restype : param
+ if value = resource.send(param)
+ hash[to] = value
+ end
+ hash
end
- # Determine the basic details on the resource.
- def self.rails_resource_initial_args(resource)
- result = [:type, :title, :line].inject({}) do |hash, param|
- # 'type' isn't a valid column name, so we have to use another name.
- to = (param == :type) ? :restype : param
- if value = resource.send(param)
- hash[to] = value
- end
- hash
- end
-
- # We always want a value here, regardless of what the resource has,
- # so we break it out separately.
- result[:exported] = resource.exported || false
-
- result
- end
+ # We always want a value here, regardless of what the resource has,
+ # so we break it out separately.
+ result[:exported] = resource.exported || false
- def add_resource_tag(tag)
- pt = Puppet::Rails::PuppetTag.accumulate_by_name(tag)
- resource_tags.build(:puppet_tag => pt)
- end
+ result
+ end
- def file
- (f = self.source_file) ? f.filename : nil
- end
+ def add_resource_tag(tag)
+ pt = Puppet::Rails::PuppetTag.accumulate_by_name(tag)
+ resource_tags.build(:puppet_tag => pt)
+ end
- def file=(file)
- self.source_file = Puppet::Rails::SourceFile.find_or_create_by_filename(file)
- end
+ def file
+ (f = self.source_file) ? f.filename : nil
+ end
- def title
- unserialize_value(self[:title])
- end
+ def file=(file)
+ self.source_file = Puppet::Rails::SourceFile.find_or_create_by_filename(file)
+ end
- def params_list
- @params_list ||= []
- end
+ def title
+ unserialize_value(self[:title])
+ end
- def params_list=(params)
- @params_list = params
- end
+ def params_list
+ @params_list ||= []
+ end
- def add_param_to_list(param)
- params_list << param
- end
+ def params_list=(params)
+ @params_list = params
+ end
- def tags_list
- @tags_list ||= []
- end
+ def add_param_to_list(param)
+ params_list << param
+ end
- def tags_list=(tags)
- @tags_list = tags
- end
+ def tags_list
+ @tags_list ||= []
+ end
- def add_tag_to_list(tag)
- tags_list << tag
- end
+ def tags_list=(tags)
+ @tags_list = tags
+ end
- def [](param)
- super || parameter(param)
- end
+ def add_tag_to_list(tag)
+ tags_list << tag
+ end
- # Make sure this resource is equivalent to the provided Parser resource.
- def merge_parser_resource(resource)
- accumulate_benchmark("Individual resource merger", :attributes) { merge_attributes(resource) }
- accumulate_benchmark("Individual resource merger", :parameters) { merge_parameters(resource) }
- accumulate_benchmark("Individual resource merger", :tags) { merge_tags(resource) }
- save
- end
+ def [](param)
+ super || parameter(param)
+ end
- def merge_attributes(resource)
- args = self.class.rails_resource_initial_args(resource)
- args.each do |param, value|
- self[param] = value unless resource[param] == value
- end
+ # Make sure this resource is equivalent to the provided Parser resource.
+ def merge_parser_resource(resource)
+ accumulate_benchmark("Individual resource merger", :attributes) { merge_attributes(resource) }
+ accumulate_benchmark("Individual resource merger", :parameters) { merge_parameters(resource) }
+ accumulate_benchmark("Individual resource merger", :tags) { merge_tags(resource) }
+ save
+ end
- # Handle file specially
- self.file = resource.file if (resource.file and (!resource.file or self.file != resource.file))
+ def merge_attributes(resource)
+ args = self.class.rails_resource_initial_args(resource)
+ args.each do |param, value|
+ self[param] = value unless resource[param] == value
end
- def merge_parameters(resource)
- catalog_params = {}
- resource.each do |param, value|
- catalog_params[param.to_s] = value
- end
-
- db_params = {}
-
- deletions = []
- params_list.each do |value|
- # First remove any parameters our catalog resource doesn't have at all.
- deletions << value['id'] and next unless catalog_params.include?(value['name'])
-
- # Now store them for later testing.
- db_params[value['name']] ||= []
- db_params[value['name']] << value
- end
-
- # Now get rid of any parameters whose value list is different.
- # This might be extra work in cases where an array has added or lost
- # a single value, but in the most common case (a single value has changed)
- # this makes sense.
- db_params.each do |name, value_hashes|
- values = value_hashes.collect { |v| v['value'] }
-
- value_hashes.each { |v| deletions << v['id'] } unless value_compare(catalog_params[name], values)
- end
-
- # Perform our deletions.
- Puppet::Rails::ParamValue.delete(deletions) unless deletions.empty?
-
- # Lastly, add any new parameters.
- catalog_params.each do |name, value|
- next if db_params.include?(name) && ! db_params[name].find{ |val| deletions.include?( val["id"] ) }
- values = value.is_a?(Array) ? value : [value]
-
- values.each do |v|
- param_values.build(:value => serialize_value(v), :line => resource.line, :param_name => Puppet::Rails::ParamName.accumulate_by_name(name))
- end
- end
- end
+ # Handle file specially
+ self.file = resource.file if (resource.file and (!resource.file or self.file != resource.file))
+ end
- # Make sure the tag list is correct.
- def merge_tags(resource)
- in_db = []
- deletions = []
- resource_tags = resource.tags
- tags_list.each do |tag|
- deletions << tag['id'] and next unless resource_tags.include?(tag['name'])
- in_db << tag['name']
- end
- Puppet::Rails::ResourceTag.delete(deletions) unless deletions.empty?
-
- (resource_tags - in_db).each do |tag|
- add_resource_tag(tag)
- end
+ def merge_parameters(resource)
+ catalog_params = {}
+ resource.each do |param, value|
+ catalog_params[param.to_s] = value
end
- def value_compare(v,db_value)
- v = [v] unless v.is_a?(Array)
+ db_params = {}
- v == db_value
- end
+ deletions = []
+ params_list.each do |value|
+ # First remove any parameters our catalog resource doesn't have at all.
+ deletions << value['id'] and next unless catalog_params.include?(value['name'])
+
+ # Now store them for later testing.
+ db_params[value['name']] ||= []
+ db_params[value['name']] << value
+ end
+
+ # Now get rid of any parameters whose value list is different.
+ # This might be extra work in cases where an array has added or lost
+ # a single value, but in the most common case (a single value has changed)
+ # this makes sense.
+ db_params.each do |name, value_hashes|
+ values = value_hashes.collect { |v| v['value'] }
- def name
- ref
+ value_hashes.each { |v| deletions << v['id'] } unless value_compare(catalog_params[name], values)
end
- def parameter(param)
- if pn = param_names.find_by_name(param)
- return (pv = param_values.find(:first, :conditions => [ 'param_name_id = ?', pn])) ? pv.value : nil
- end
- end
+ # Perform our deletions.
+ Puppet::Rails::ParamValue.delete(deletions) unless deletions.empty?
+
+ # Lastly, add any new parameters.
+ catalog_params.each do |name, value|
+ next if db_params.include?(name) && ! db_params[name].find{ |val| deletions.include?( val["id"] ) }
+ values = value.is_a?(Array) ? value : [value]
+
+ values.each do |v|
+ param_values.build(:value => serialize_value(v), :line => resource.line, :param_name => Puppet::Rails::ParamName.accumulate_by_name(name))
+ end
+ end
+ end
- def ref(dummy_argument=:work_arround_for_ruby_GC_bug)
- "#{self[:restype].split("::").collect { |s| s.capitalize }.join("::")}[#{self.title}]"
- end
+ # Make sure the tag list is correct.
+ def merge_tags(resource)
+ in_db = []
+ deletions = []
+ resource_tags = resource.tags
+ tags_list.each do |tag|
+ deletions << tag['id'] and next unless resource_tags.include?(tag['name'])
+ in_db << tag['name']
+ end
+ Puppet::Rails::ResourceTag.delete(deletions) unless deletions.empty?
- # Returns a hash of parameter names and values, no ActiveRecord instances.
- def to_hash
- Puppet::Rails::ParamValue.find_all_params_from_resource(self).inject({}) do |hash, value|
- hash[value['name']] ||= []
- hash[value['name']] << value.value
- hash
- end
+ (resource_tags - in_db).each do |tag|
+ add_resource_tag(tag)
+ end
+ end
+
+ def value_compare(v,db_value)
+ v = [v] unless v.is_a?(Array)
+
+ v == db_value
+ end
+
+ def name
+ ref
+ end
+
+ def parameter(param)
+ if pn = param_names.find_by_name(param)
+ return (pv = param_values.find(:first, :conditions => [ 'param_name_id = ?', pn])) ? pv.value : nil
+ end
+ end
+
+ def ref(dummy_argument=:work_arround_for_ruby_GC_bug)
+ "#{self[:restype].split("::").collect { |s| s.capitalize }.join("::")}[#{self.title}]"
+ end
+
+ # Returns a hash of parameter names and values, no ActiveRecord instances.
+ def to_hash
+ Puppet::Rails::ParamValue.find_all_params_from_resource(self).inject({}) do |hash, value|
+ hash[value['name']] ||= []
+ hash[value['name']] << value.value
+ hash
end
+ end
+
+ # Convert our object to a resource. Do not retain whether the object
+ # is exported, though, since that would cause it to get stripped
+ # from the configuration.
+ def to_resource(scope)
+ hash = self.attributes
+ hash["type"] = hash["restype"]
+ hash.delete("restype")
- # Convert our object to a resource. Do not retain whether the object
- # is exported, though, since that would cause it to get stripped
- # from the configuration.
- def to_resource(scope)
- hash = self.attributes
- hash["type"] = hash["restype"]
- hash.delete("restype")
-
- # FIXME At some point, we're going to want to retain this information
- # for logging and auditing.
- hash.delete("host_id")
- hash.delete("updated_at")
- hash.delete("source_file_id")
- hash.delete("created_at")
- hash.delete("id")
- hash.each do |p, v|
- hash.delete(p) if v.nil?
- end
- hash[:scope] = scope
- hash[:source] = scope.source
- hash[:params] = []
- names = []
- self.param_names.each do |pname|
- # We can get the same name multiple times because of how the
- # db layout works.
- next if names.include?(pname.name)
- names << pname.name
- hash[:params] << pname.to_resourceparam(self, scope.source)
- end
- obj = Puppet::Parser::Resource.new(hash)
-
- # Store the ID, so we can check if we're re-collecting the same resource.
- obj.rails_id = self.id
-
- obj
+ # FIXME At some point, we're going to want to retain this information
+ # for logging and auditing.
+ hash.delete("host_id")
+ hash.delete("updated_at")
+ hash.delete("source_file_id")
+ hash.delete("created_at")
+ hash.delete("id")
+ hash.each do |p, v|
+ hash.delete(p) if v.nil?
end
+ hash[:scope] = scope
+ hash[:source] = scope.source
+ hash[:params] = []
+ names = []
+ self.param_names.each do |pname|
+ # We can get the same name multiple times because of how the
+ # db layout works.
+ next if names.include?(pname.name)
+ names << pname.name
+ hash[:params] << pname.to_resourceparam(self, scope.source)
+ end
+ obj = Puppet::Parser::Resource.new(hash)
+
+ # Store the ID, so we can check if we're re-collecting the same resource.
+ obj.rails_id = self.id
+
+ obj
+ end
end
diff --git a/lib/puppet/rails/resource_tag.rb b/lib/puppet/rails/resource_tag.rb
index 0bbac11..1c1aa45 100644
--- a/lib/puppet/rails/resource_tag.rb
+++ b/lib/puppet/rails/resource_tag.rb
@@ -1,26 +1,26 @@
class Puppet::Rails::ResourceTag < ActiveRecord::Base
- belongs_to :puppet_tag
- belongs_to :resource
+ belongs_to :puppet_tag
+ belongs_to :resource
- def to_label
- "#{self.puppet_tag.name}"
- end
+ def to_label
+ "#{self.puppet_tag.name}"
+ end
- # returns an array of hash containing tags of resource
- def self.find_all_tags_from_resource(db_resource)
- tags = db_resource.connection.select_all("SELECT t.id, t.resource_id, p.name FROM resource_tags t INNER JOIN puppet_tags p ON t.puppet_tag_id=p.id WHERE t.resource_id=#{db_resource.id}")
- tags.each do |val|
- val['resource_id'] = Integer(val['resource_id'])
- end
- tags
+ # returns an array of hash containing tags of resource
+ def self.find_all_tags_from_resource(db_resource)
+ tags = db_resource.connection.select_all("SELECT t.id, t.resource_id, p.name FROM resource_tags t INNER JOIN puppet_tags p ON t.puppet_tag_id=p.id WHERE t.resource_id=#{db_resource.id}")
+ tags.each do |val|
+ val['resource_id'] = Integer(val['resource_id'])
end
+ tags
+ end
- # returns an array of hash containing tags of a host
- def self.find_all_tags_from_host(db_host)
- tags = db_host.connection.select_all("SELECT t.id, t.resource_id, p.name FROM resource_tags t INNER JOIN resources r ON t.resource_id=r.id INNER JOIN puppet_tags p ON t.puppet_tag_id=p.id WHERE r.host_id=#{db_host.id}")
- tags.each do |val|
- val['resource_id'] = Integer(val['resource_id'])
- end
- tags
+ # returns an array of hash containing tags of a host
+ def self.find_all_tags_from_host(db_host)
+ tags = db_host.connection.select_all("SELECT t.id, t.resource_id, p.name FROM resource_tags t INNER JOIN resources r ON t.resource_id=r.id INNER JOIN puppet_tags p ON t.puppet_tag_id=p.id WHERE r.host_id=#{db_host.id}")
+ tags.each do |val|
+ val['resource_id'] = Integer(val['resource_id'])
end
+ tags
+ end
end
diff --git a/lib/puppet/rails/source_file.rb b/lib/puppet/rails/source_file.rb
index 6a69189..02557ff 100644
--- a/lib/puppet/rails/source_file.rb
+++ b/lib/puppet/rails/source_file.rb
@@ -1,8 +1,8 @@
class Puppet::Rails::SourceFile < ActiveRecord::Base
- has_one :host
- has_one :resource
+ has_one :host
+ has_one :resource
- def to_label
- "#{self.filename}"
- end
+ def to_label
+ "#{self.filename}"
+ end
end
diff --git a/lib/puppet/reference/configuration.rb b/lib/puppet/reference/configuration.rb
index 2f60ecc..bfa2cb8 100644
--- a/lib/puppet/reference/configuration.rb
+++ b/lib/puppet/reference/configuration.rb
@@ -1,44 +1,44 @@
config = Puppet::Util::Reference.newreference(:configuration, :depth => 1, :doc => "A reference for all configuration parameters") do
- docs = {}
- Puppet.settings.each do |name, object|
- docs[name] = object
+ docs = {}
+ Puppet.settings.each do |name, object|
+ docs[name] = object
+ end
+
+ str = ""
+ docs.sort { |a, b|
+ a[0].to_s <=> b[0].to_s
+ }.each do |name, object|
+ # Make each name an anchor
+ header = name.to_s
+ str += h(header, 3)
+
+ # Print the doc string itself
+ begin
+ str += object.desc.gsub(/\n/, " ")
+ rescue => detail
+ puts detail.backtrace
+ puts detail
+ end
+ str += "\n\n"
+
+ # Now print the data about the item.
+ str += ""
+ val = object.default
+ if name.to_s == "vardir"
+ val = "/var/lib/puppet"
+ elsif name.to_s == "confdir"
+ val = "/etc/puppet"
end
- str = ""
- docs.sort { |a, b|
- a[0].to_s <=> b[0].to_s
- }.each do |name, object|
- # Make each name an anchor
- header = name.to_s
- str += h(header, 3)
-
- # Print the doc string itself
- begin
- str += object.desc.gsub(/\n/, " ")
- rescue => detail
- puts detail.backtrace
- puts detail
- end
- str += "\n\n"
-
- # Now print the data about the item.
- str += ""
- val = object.default
- if name.to_s == "vardir"
- val = "/var/lib/puppet"
- elsif name.to_s == "confdir"
- val = "/etc/puppet"
- end
-
- # Leave out the section information; it was apparently confusing people.
- #str += "- **Section**: #{object.section}\n"
- unless val == ""
- str += "- **Default**: #{val}\n"
- end
- str += "\n"
+ # Leave out the section information; it was apparently confusing people.
+ #str += "- **Section**: #{object.section}\n"
+ unless val == ""
+ str += "- **Default**: #{val}\n"
end
+ str += "\n"
+ end
- return str
+ return str
end
config.header = "
@@ -57,14 +57,14 @@ These parameters can be supplied to the executables either as command-line
options or in the configuration file. For instance, the command-line
invocation below would set the configuration directory to ``/private/puppet``::
- $ puppet agent --confdir=/private/puppet
+ $ puppet agent --confdir=/private/puppet
Note that boolean options are turned on and off with a slightly different
syntax on the command line::
- $ puppet agent --storeconfigs
+ $ puppet agent --storeconfigs
- $ puppet agent --no-storeconfigs
+ $ puppet agent --no-storeconfigs
The invocations above will enable and disable, respectively, the storage of
the client configuration.
@@ -89,9 +89,9 @@ File Format
The file follows INI-style formatting. Here is an example of a very simple
``puppet.conf`` file::
- [main]
- confdir = /private/puppet
- storeconfigs = true
+ [main]
+ confdir = /private/puppet
+ storeconfigs = true
Note that boolean parameters must be explicitly specified as `true` or
`false` as seen above.
@@ -99,8 +99,8 @@ Note that boolean parameters must be explicitly specified as `true` or
If you need to change file parameters (e.g., reset the mode or owner), do
so within curly braces on the same line::
- [main]
- myfile = /tmp/whatever {owner = root, mode = 644}
+ [main]
+ myfile = /tmp/whatever {owner = root, mode = 644}
If you're starting out with a fresh configuration, you may wish to let
the executable generate a template configuration file for you by invoking
@@ -108,7 +108,7 @@ the executable in question with the `--genconfig` command. The executable
will print a template configuration to standard output, which can be
redirected to a file like so::
- $ puppet agent --genconfig > /etc/puppet/puppet.conf
+ $ puppet agent --genconfig > /etc/puppet/puppet.conf
Note that this invocation will replace the contents of any pre-existing
`puppet.conf` file, so make a backup of your present config if it contains
@@ -119,12 +119,12 @@ argument, which will generate a manifest that can be used to manage all of
Puppet's directories and files and prints it to standard output. This can
likewise be redirected to a file::
- $ puppet agent --genmanifest > /etc/puppet/manifests/site.pp
+ $ puppet agent --genmanifest > /etc/puppet/manifests/site.pp
Puppet can also create user and group accounts for itself (one `puppet` group
and one `puppet` user) if it is invoked as `root` with the `--mkusers` argument::
- $ puppet agent --mkusers
+ $ puppet agent --mkusers
Signals
-------
diff --git a/lib/puppet/reference/function.rb b/lib/puppet/reference/function.rb
index 0dc2f79..1333e0d 100644
--- a/lib/puppet/reference/function.rb
+++ b/lib/puppet/reference/function.rb
@@ -1,5 +1,5 @@
function = Puppet::Util::Reference.newreference :function, :doc => "All functions available in the parser" do
- Puppet::Parser::Functions.functiondocs
+ Puppet::Parser::Functions.functiondocs
end
function.header = "
There are two types of functions in Puppet: Statements and rvalues.
diff --git a/lib/puppet/reference/indirection.rb b/lib/puppet/reference/indirection.rb
index 13c014e..549299b 100644
--- a/lib/puppet/reference/indirection.rb
+++ b/lib/puppet/reference/indirection.rb
@@ -4,24 +4,24 @@ require 'puppet/file_serving/content'
require 'puppet/file_serving/metadata'
reference = Puppet::Util::Reference.newreference :indirection, :doc => "Indirection types and their terminus classes" do
- text = ""
- Puppet::Indirector::Indirection.instances.sort { |a,b| a.to_s <=> b.to_s }.each do |indirection|
- ind = Puppet::Indirector::Indirection.instance(indirection)
- name = indirection.to_s.capitalize
- text += indirection.to_s + "\n" + ("-" * name.length) + "\n\n"
+ text = ""
+ Puppet::Indirector::Indirection.instances.sort { |a,b| a.to_s <=> b.to_s }.each do |indirection|
+ ind = Puppet::Indirector::Indirection.instance(indirection)
+ name = indirection.to_s.capitalize
+ text += indirection.to_s + "\n" + ("-" * name.length) + "\n\n"
- text += ind.doc + "\n\n"
+ text += ind.doc + "\n\n"
- Puppet::Indirector::Terminus.terminus_classes(ind.name).sort { |a,b| a.to_s <=> b.to_s }.each do |terminus|
- text += terminus.to_s + "\n" + ("+" * terminus.to_s.length) + "\n\n"
+ Puppet::Indirector::Terminus.terminus_classes(ind.name).sort { |a,b| a.to_s <=> b.to_s }.each do |terminus|
+ text += terminus.to_s + "\n" + ("+" * terminus.to_s.length) + "\n\n"
- term_class = Puppet::Indirector::Terminus.terminus_class(ind.name, terminus)
+ term_class = Puppet::Indirector::Terminus.terminus_class(ind.name, terminus)
- text += Puppet::Util::Docs.scrub(term_class.doc) + "\n\n"
- end
+ text += Puppet::Util::Docs.scrub(term_class.doc) + "\n\n"
end
+ end
- text
+ text
end
reference.header = "This is the list of all indirections, their associated terminus classes, and how you select between them.
diff --git a/lib/puppet/reference/metaparameter.rb b/lib/puppet/reference/metaparameter.rb
index 9368de1..6a319f1 100644
--- a/lib/puppet/reference/metaparameter.rb
+++ b/lib/puppet/reference/metaparameter.rb
@@ -1,48 +1,48 @@
metaparameter = Puppet::Util::Reference.newreference :metaparameter, :doc => "All Puppet metaparameters and all their details" do
- types = {}
- Puppet::Type.loadall
+ types = {}
+ Puppet::Type.loadall
- Puppet::Type.eachtype { |type|
- next if type.name == :puppet
- next if type.name == :component
- types[type.name] = type
- }
+ Puppet::Type.eachtype { |type|
+ next if type.name == :puppet
+ next if type.name == :component
+ types[type.name] = type
+ }
- str = %{
- Metaparameters
- --------------
- Metaparameters are parameters that work with any resource type; they are part of the
- Puppet framework itself rather than being part of the implementation of any
- given instance. Thus, any defined metaparameter can be used with any instance
- in your manifest, including defined components.
+ str = %{
+ Metaparameters
+ --------------
+ Metaparameters are parameters that work with any resource type; they are part of the
+ Puppet framework itself rather than being part of the implementation of any
+ given instance. Thus, any defined metaparameter can be used with any instance
+ in your manifest, including defined components.
- Available Metaparameters
- ++++++++++++++++++++++++
- }
- begin
- params = []
- Puppet::Type.eachmetaparam { |param|
- params << param
- }
+ Available Metaparameters
+ ++++++++++++++++++++++++
+ }
+ begin
+ params = []
+ Puppet::Type.eachmetaparam { |param|
+ params << param
+ }
- params.sort { |a,b|
- a.to_s <=> b.to_s
- }.each { |param|
- str += paramwrap(param.to_s, scrub(Puppet::Type.metaparamdoc(param)), :level => 4)
- #puts "<dt>#{param}</dt>"
- #puts tab(1) + Puppet::Type.metaparamdoc(param).scrub.indent($tab)gsub(/\n\s*/,' ')
- #puts "<dd>"
- #puts indent(scrub(Puppet::Type.metaparamdoc(param)), $tab)
- #puts scrub(Puppet::Type.metaparamdoc(param))
- #puts "</dd>"
+ params.sort { |a,b|
+ a.to_s <=> b.to_s
+ }.each { |param|
+ str += paramwrap(param.to_s, scrub(Puppet::Type.metaparamdoc(param)), :level => 4)
+ #puts "<dt>#{param}</dt>"
+ #puts tab(1) + Puppet::Type.metaparamdoc(param).scrub.indent($tab)gsub(/\n\s*/,' ')
+ #puts "<dd>"
+ #puts indent(scrub(Puppet::Type.metaparamdoc(param)), $tab)
+ #puts scrub(Puppet::Type.metaparamdoc(param))
+ #puts "</dd>"
- #puts ""
- }
- rescue => detail
- puts detail.backtrace
- puts "incorrect metaparams: #{detail}"
- exit(1)
- end
+ #puts ""
+ }
+ rescue => detail
+ puts detail.backtrace
+ puts "incorrect metaparams: #{detail}"
+ exit(1)
+ end
- str
+ str
end
diff --git a/lib/puppet/reference/network.rb b/lib/puppet/reference/network.rb
index 14b26dd..a3bff65 100644
--- a/lib/puppet/reference/network.rb
+++ b/lib/puppet/reference/network.rb
@@ -1,23 +1,23 @@
network = Puppet::Util::Reference.newreference :network, :depth => 2, :doc => "Available network handlers and clients" do
- ret = ""
- Puppet::Network::Handler.subclasses.sort { |a,b| a.to_s <=> b.to_s }.each do |name|
- handler = Puppet::Network::Handler.handler(name)
+ ret = ""
+ Puppet::Network::Handler.subclasses.sort { |a,b| a.to_s <=> b.to_s }.each do |name|
+ handler = Puppet::Network::Handler.handler(name)
- next if ! handler.doc or handler.doc == ""
+ next if ! handler.doc or handler.doc == ""
- interface = handler.interface
+ interface = handler.interface
- ret += h(name, 2)
+ ret += h(name, 2)
- ret += scrub(handler.doc)
- ret += "\n\n"
- ret += option(:prefix, interface.prefix)
- ret += option(:side, handler.side.to_s.capitalize)
- ret += option(:methods, interface.methods.collect { |ary| ary[0] }.join(", ") )
- ret += "\n\n"
- end
+ ret += scrub(handler.doc)
+ ret += "\n\n"
+ ret += option(:prefix, interface.prefix)
+ ret += option(:side, handler.side.to_s.capitalize)
+ ret += option(:methods, interface.methods.collect { |ary| ary[0] }.join(", ") )
+ ret += "\n\n"
+ end
- ret
+ ret
end
network.header = "
diff --git a/lib/puppet/reference/providers.rb b/lib/puppet/reference/providers.rb
index b195493..a0f1063 100644
--- a/lib/puppet/reference/providers.rb
+++ b/lib/puppet/reference/providers.rb
@@ -1,114 +1,114 @@
# This doesn't get stored in trac, since it changes every time.
providers = Puppet::Util::Reference.newreference :providers, :title => "Provider Suitability Report", :depth => 1, :dynamic => true, :doc => "Which providers are valid for this machine" do
- types = []
- Puppet::Type.loadall
- Puppet::Type.eachtype do |klass|
- next unless klass.providers.length > 0
- types << klass
+ types = []
+ Puppet::Type.loadall
+ Puppet::Type.eachtype do |klass|
+ next unless klass.providers.length > 0
+ types << klass
+ end
+ types.sort! { |a,b| a.name.to_s <=> b.name.to_s }
+
+ command_line = Puppet::Util::CommandLine.new
+ types.reject! { |type| ! command_line.args.include?(type.name.to_s) } unless command_line.args.empty?
+
+ ret = "Details about this host:\n\n"
+
+ # Throw some facts in there, so we know where the report is from.
+ ["Ruby Version", "Puppet Version", "Operating System", "Operating System Release"].each do |label|
+ name = label.gsub(/\s+/, '')
+ value = Facter.value(name)
+ ret += option(label, value)
+ end
+ ret += "\n"
+
+ count = 1
+
+ # Produce output for each type.
+ types.each do |type|
+ features = type.features
+ ret += "\n" # add a trailing newline
+
+ # Now build up a table of provider suitability.
+ headers = %w{Provider Suitable?} + features.collect { |f| f.to_s }.sort
+
+ table_data = {}
+
+ functional = false
+ notes = []
+ begin
+ default = type.defaultprovider.name
+ rescue Puppet::DevError
+ default = "none"
end
- types.sort! { |a,b| a.name.to_s <=> b.name.to_s }
-
- command_line = Puppet::Util::CommandLine.new
- types.reject! { |type| ! command_line.args.include?(type.name.to_s) } unless command_line.args.empty?
-
- ret = "Details about this host:\n\n"
-
- # Throw some facts in there, so we know where the report is from.
- ["Ruby Version", "Puppet Version", "Operating System", "Operating System Release"].each do |label|
- name = label.gsub(/\s+/, '')
- value = Facter.value(name)
- ret += option(label, value)
- end
- ret += "\n"
-
- count = 1
-
- # Produce output for each type.
- types.each do |type|
- features = type.features
- ret += "\n" # add a trailing newline
-
- # Now build up a table of provider suitability.
- headers = %w{Provider Suitable?} + features.collect { |f| f.to_s }.sort
-
- table_data = {}
-
- functional = false
- notes = []
- begin
- default = type.defaultprovider.name
- rescue Puppet::DevError
- default = "none"
- end
- type.providers.sort { |a,b| a.to_s <=> b.to_s }.each do |pname|
- data = []
- table_data[pname] = data
- provider = type.provider(pname)
-
- # Add the suitability note
- if missing = provider.suitable?(false) and missing.empty?
- data << "**X**"
- suit = true
- functional = true
- else
- data << "[#{count}]_" # A pointer to the appropriate footnote
- suit = false
+ type.providers.sort { |a,b| a.to_s <=> b.to_s }.each do |pname|
+ data = []
+ table_data[pname] = data
+ provider = type.provider(pname)
+
+ # Add the suitability note
+ if missing = provider.suitable?(false) and missing.empty?
+ data << "**X**"
+ suit = true
+ functional = true
+ else
+ data << "[#{count}]_" # A pointer to the appropriate footnote
+ suit = false
+ end
+
+ # Add a footnote with the details about why this provider is unsuitable, if that's the case
+ unless suit
+ details = ".. [#{count}]\n"
+ missing.each do |test, values|
+ case test
+ when :exists
+ details += " - Missing files #{values.join(", ")}\n"
+ when :variable
+ values.each do |name, facts|
+ if Puppet.settings.valid?(name)
+ details += " - Setting #{name} (currently #{Puppet.settings.value(name).inspect}) not in list #{facts.join(", ")}\n"
+ else
+ details += " - Fact #{name} (currently #{Facter.value(name).inspect}) not in list #{facts.join(", ")}\n"
+ end
end
+ when :true
+ details += " - Got #{values} true tests that should have been false\n"
+ when :false
+ details += " - Got #{values} false tests that should have been true\n"
+ when :feature
+ details += " - Missing features #{values.collect { |f| f.to_s }.join(",")}\n"
+ end
+ end
+ notes << details
- # Add a footnote with the details about why this provider is unsuitable, if that's the case
- unless suit
- details = ".. [#{count}]\n"
- missing.each do |test, values|
- case test
- when :exists
- details += " - Missing files #{values.join(", ")}\n"
- when :variable
- values.each do |name, facts|
- if Puppet.settings.valid?(name)
- details += " - Setting #{name} (currently #{Puppet.settings.value(name).inspect}) not in list #{facts.join(", ")}\n"
- else
- details += " - Fact #{name} (currently #{Facter.value(name).inspect}) not in list #{facts.join(", ")}\n"
- end
- end
- when :true
- details += " - Got #{values} true tests that should have been false\n"
- when :false
- details += " - Got #{values} false tests that should have been true\n"
- when :feature
- details += " - Missing features #{values.collect { |f| f.to_s }.join(",")}\n"
- end
- end
- notes << details
-
- count += 1
- end
+ count += 1
+ end
- # Add a note for every feature
- features.each do |feature|
- if provider.features.include?(feature)
- data << "**X**"
- else
- data << ""
- end
- end
+ # Add a note for every feature
+ features.each do |feature|
+ if provider.features.include?(feature)
+ data << "**X**"
+ else
+ data << ""
end
+ end
+ end
- ret += h(type.name.to_s + "_", 2)
-
- ret += ".. _#{type.name}: #{"http://reductivelabs.com/trac/puppet/wiki/TypeReference##{type.name}"}\n\n"
- ret += option("Default provider", default)
- ret += doctable(headers, table_data)
+ ret += h(type.name.to_s + "_", 2)
- notes.each do |note|
- ret += note + "\n"
- end
+ ret += ".. _#{type.name}: #{"http://reductivelabs.com/trac/puppet/wiki/TypeReference##{type.name}"}\n\n"
+ ret += option("Default provider", default)
+ ret += doctable(headers, table_data)
- ret += "\n"
+ notes.each do |note|
+ ret += note + "\n"
end
ret += "\n"
+ end
+
+ ret += "\n"
- ret
+ ret
end
providers.header = "
Puppet resource types are usually backed by multiple implementations called ``providers``,
diff --git a/lib/puppet/reference/report.rb b/lib/puppet/reference/report.rb
index 2ea00b6..481ca2d 100644
--- a/lib/puppet/reference/report.rb
+++ b/lib/puppet/reference/report.rb
@@ -1,7 +1,7 @@
require 'puppet/reports'
report = Puppet::Util::Reference.newreference :report, :doc => "All available transaction reports" do
- Puppet::Reports.reportdocs
+ Puppet::Reports.reportdocs
end
report.header = "
diff --git a/lib/puppet/reference/type.rb b/lib/puppet/reference/type.rb
index c52e764..be8742e 100644
--- a/lib/puppet/reference/type.rb
+++ b/lib/puppet/reference/type.rb
@@ -1,113 +1,113 @@
type = Puppet::Util::Reference.newreference :type, :doc => "All Puppet resource types and all their details" do
- types = {}
- Puppet::Type.loadall
+ types = {}
+ Puppet::Type.loadall
- Puppet::Type.eachtype { |type|
- next if type.name == :puppet
- next if type.name == :component
- types[type.name] = type
- }
+ Puppet::Type.eachtype { |type|
+ next if type.name == :puppet
+ next if type.name == :component
+ types[type.name] = type
+ }
- str = %{
+ str = %{
- Resource Types
- --------------
+ Resource Types
+ --------------
- - The *namevar* is the parameter used to uniquely identify a type instance.
- This is the parameter that gets assigned when a string is provided before
- the colon in a type declaration. In general, only developers will need to
- worry about which parameter is the ``namevar``.
+ - The *namevar* is the parameter used to uniquely identify a type instance.
+ This is the parameter that gets assigned when a string is provided before
+ the colon in a type declaration. In general, only developers will need to
+ worry about which parameter is the ``namevar``.
- In the following code::
+ In the following code::
- file { "/etc/passwd":
- owner => root,
- group => root,
- mode => 644
- }
+ file { "/etc/passwd":
+ owner => root,
+ group => root,
+ mode => 644
+ }
- ``/etc/passwd`` is considered the title of the file object (used for things like
- dependency handling), and because ``path`` is the namevar for ``file``, that
- string is assigned to the ``path`` parameter.
+ ``/etc/passwd`` is considered the title of the file object (used for things like
+ dependency handling), and because ``path`` is the namevar for ``file``, that
+ string is assigned to the ``path`` parameter.
- *Parameters* determine the specific configuration of the instance. They either
- directly modify the system (internally, these are called properties) or they affect
- how the instance behaves (e.g., adding a search path for ``exec`` instances or determining recursion on ``file`` instances).
+ directly modify the system (internally, these are called properties) or they affect
+ how the instance behaves (e.g., adding a search path for ``exec`` instances or determining recursion on ``file`` instances).
- *Providers* provide low-level functionality for a given resource type. This is
- usually in the form of calling out to external commands.
+ usually in the form of calling out to external commands.
- When required binaries are specified for providers, fully qualifed paths
- indicate that the binary must exist at that specific path and unqualified
- binaries indicate that Puppet will search for the binary using the shell
- path.
+ When required binaries are specified for providers, fully qualifed paths
+ indicate that the binary must exist at that specific path and unqualified
+ binaries indicate that Puppet will search for the binary using the shell
+ path.
- *Features* are abilities that some providers might not support. You can use the list
- of supported features to determine how a given provider can be used.
+ of supported features to determine how a given provider can be used.
- Resource types define features they can use, and providers can be tested to see
- which features they provide.
+ Resource types define features they can use, and providers can be tested to see
+ which features they provide.
- }
+ }
- types.sort { |a,b|
- a.to_s <=> b.to_s
- }.each { |name,type|
+ types.sort { |a,b|
+ a.to_s <=> b.to_s
+ }.each { |name,type|
- str += "
+ str += "
----------------
"
- str += h(name, 3)
- str += scrub(type.doc) + "\n\n"
-
- # Handle the feature docs.
- if featuredocs = type.featuredocs
- str += h("Features", 4)
- str += featuredocs
- end
-
- docs = {}
- type.validproperties.sort { |a,b|
- a.to_s <=> b.to_s
- }.reject { |sname|
- property = type.propertybyname(sname)
- property.nodoc
- }.each { |sname|
- property = type.propertybyname(sname)
-
- raise "Could not retrieve property #{sname} on type #{type.name}" unless property
-
- doc = nil
- unless doc = property.doc
- $stderr.puts "No docs for #{type}[#{sname}]"
- next
- end
- doc = doc.dup
- tmp = doc
- tmp = scrub(tmp)
-
- docs[sname] = tmp
- }
-
- str += h("Parameters", 4) + "\n"
- type.parameters.sort { |a,b|
- a.to_s <=> b.to_s
- }.each { |name,param|
- #docs[name] = indent(scrub(type.paramdoc(name)), $tab)
- docs[name] = scrub(type.paramdoc(name))
- }
-
- additional_key_attributes = type.key_attributes - [:name]
- docs.sort { |a, b|
- a[0].to_s <=> b[0].to_s
- }.each { |name, doc|
- str += paramwrap(name, doc, :namevar => additional_key_attributes.include?(name))
- }
- str += "\n"
+ str += h(name, 3)
+ str += scrub(type.doc) + "\n\n"
+
+ # Handle the feature docs.
+ if featuredocs = type.featuredocs
+ str += h("Features", 4)
+ str += featuredocs
+ end
+
+ docs = {}
+ type.validproperties.sort { |a,b|
+ a.to_s <=> b.to_s
+ }.reject { |sname|
+ property = type.propertybyname(sname)
+ property.nodoc
+ }.each { |sname|
+ property = type.propertybyname(sname)
+
+ raise "Could not retrieve property #{sname} on type #{type.name}" unless property
+
+ doc = nil
+ unless doc = property.doc
+ $stderr.puts "No docs for #{type}[#{sname}]"
+ next
+ end
+ doc = doc.dup
+ tmp = doc
+ tmp = scrub(tmp)
+
+ docs[sname] = tmp
+ }
+
+ str += h("Parameters", 4) + "\n"
+ type.parameters.sort { |a,b|
+ a.to_s <=> b.to_s
+ }.each { |name,param|
+ #docs[name] = indent(scrub(type.paramdoc(name)), $tab)
+ docs[name] = scrub(type.paramdoc(name))
+ }
+
+ additional_key_attributes = type.key_attributes - [:name]
+ docs.sort { |a, b|
+ a[0].to_s <=> b[0].to_s
+ }.each { |name, doc|
+ str += paramwrap(name, doc, :namevar => additional_key_attributes.include?(name))
}
+ str += "\n"
+ }
- str
+ str
end
diff --git a/lib/puppet/relationship.rb b/lib/puppet/relationship.rb
index b390870..7079fb4 100644
--- a/lib/puppet/relationship.rb
+++ b/lib/puppet/relationship.rb
@@ -12,83 +12,83 @@ require 'puppet/util/pson'
# It used to be a subclass of GRATR::Edge, but that class has weird hash
# overrides that dramatically slow down the graphing.
class Puppet::Relationship
- extend Puppet::Util::Pson
- attr_accessor :source, :target, :callback
+ extend Puppet::Util::Pson
+ attr_accessor :source, :target, :callback
- attr_reader :event
+ attr_reader :event
- def self.from_pson(pson)
- source = pson["source"]
- target = pson["target"]
+ def self.from_pson(pson)
+ source = pson["source"]
+ target = pson["target"]
- args = {}
- if event = pson["event"]
- args[:event] = event
- end
- if callback = pson["callback"]
- args[:callback] = callback
- end
-
- new(source, target, args)
+ args = {}
+ if event = pson["event"]
+ args[:event] = event
end
-
- def event=(event)
- raise ArgumentError, "You must pass a callback for non-NONE events" if event != :NONE and ! callback
- @event = event
+ if callback = pson["callback"]
+ args[:callback] = callback
end
- def initialize(source, target, options = {})
- @source, @target = source, target
+ new(source, target, args)
+ end
- options = (options || {}).inject({}) { |h,a| h[a[0].to_sym] = a[1]; h }
- [:callback, :event].each do |option|
- if value = options[option]
- send(option.to_s + "=", value)
- end
- end
- end
+ def event=(event)
+ raise ArgumentError, "You must pass a callback for non-NONE events" if event != :NONE and ! callback
+ @event = event
+ end
- # Does the passed event match our event? This is where the meaning
- # of :NONE comes from.
- def match?(event)
- if self.event.nil? or event == :NONE or self.event == :NONE
- return false
- elsif self.event == :ALL_EVENTS or event == self.event
- return true
- else
- return false
- end
- end
+ def initialize(source, target, options = {})
+ @source, @target = source, target
- def label
- result = {}
- result[:callback] = callback if callback
- result[:event] = event if event
- result
+ options = (options || {}).inject({}) { |h,a| h[a[0].to_sym] = a[1]; h }
+ [:callback, :event].each do |option|
+ if value = options[option]
+ send(option.to_s + "=", value)
+ end
end
-
- def ref
- "#{source} => #{target}"
+ end
+
+ # Does the passed event match our event? This is where the meaning
+ # of :NONE comes from.
+ def match?(event)
+ if self.event.nil? or event == :NONE or self.event == :NONE
+ return false
+ elsif self.event == :ALL_EVENTS or event == self.event
+ return true
+ else
+ return false
end
-
- def to_pson_data_hash
- data = {
- 'source' => source.to_s,
- 'target' => target.to_s
- }
-
- ["event", "callback"].each do |attr|
- next unless value = send(attr)
- data[attr] = value
- end
- data
+ end
+
+ def label
+ result = {}
+ result[:callback] = callback if callback
+ result[:event] = event if event
+ result
+ end
+
+ def ref
+ "#{source} => #{target}"
+ end
+
+ def to_pson_data_hash
+ data = {
+ 'source' => source.to_s,
+ 'target' => target.to_s
+ }
+
+ ["event", "callback"].each do |attr|
+ next unless value = send(attr)
+ data[attr] = value
end
+ data
+ end
- def to_pson(*args)
- to_pson_data_hash.to_pson(*args)
- end
+ def to_pson(*args)
+ to_pson_data_hash.to_pson(*args)
+ end
- def to_s
- ref
- end
+ def to_s
+ ref
+ end
end
diff --git a/lib/puppet/reports.rb b/lib/puppet/reports.rb
index 2e1f1e2..3ebd16e 100755
--- a/lib/puppet/reports.rb
+++ b/lib/puppet/reports.rb
@@ -2,48 +2,48 @@ require 'puppet/util/instance_loader'
# A simple mechanism for loading and returning reports.
class Puppet::Reports
- extend Puppet::Util::ClassGen
- extend Puppet::Util::InstanceLoader
+ extend Puppet::Util::ClassGen
+ extend Puppet::Util::InstanceLoader
- # Set up autoloading and retrieving of reports.
- instance_load :report, 'puppet/reports'
+ # Set up autoloading and retrieving of reports.
+ instance_load :report, 'puppet/reports'
- class << self
- attr_reader :hooks
- end
+ class << self
+ attr_reader :hooks
+ end
- # Add a new report type.
- def self.register_report(name, options = {}, &block)
- name = symbolize(name)
+ # Add a new report type.
+ def self.register_report(name, options = {}, &block)
+ name = symbolize(name)
- mod = genmodule(name, :extend => Puppet::Util::Docs, :hash => instance_hash(:report), :block => block)
+ mod = genmodule(name, :extend => Puppet::Util::Docs, :hash => instance_hash(:report), :block => block)
- mod.useyaml = true if options[:useyaml]
+ mod.useyaml = true if options[:useyaml]
- mod.send(:define_method, :report_name) do
- name
- end
+ mod.send(:define_method, :report_name) do
+ name
end
+ end
- # Collect the docs for all of our reports.
- def self.reportdocs
- docs = ""
-
- # Use this method so they all get loaded
- instance_loader(:report).loadall
- loaded_instances(:report).sort { |a,b| a.to_s <=> b.to_s }.each do |name|
- mod = self.report(name)
- docs += "#{name}\n#{"-" * name.to_s.length}\n"
+ # Collect the docs for all of our reports.
+ def self.reportdocs
+ docs = ""
- docs += Puppet::Util::Docs.scrub(mod.doc) + "\n\n"
- end
+ # Use this method so they all get loaded
+ instance_loader(:report).loadall
+ loaded_instances(:report).sort { |a,b| a.to_s <=> b.to_s }.each do |name|
+ mod = self.report(name)
+ docs += "#{name}\n#{"-" * name.to_s.length}\n"
- docs
+ docs += Puppet::Util::Docs.scrub(mod.doc) + "\n\n"
end
- # List each of the reports.
- def self.reports
- instance_loader(:report).loadall
- loaded_instances(:report)
- end
+ docs
+ end
+
+ # List each of the reports.
+ def self.reports
+ instance_loader(:report).loadall
+ loaded_instances(:report)
+ end
end
diff --git a/lib/puppet/reports/http.rb b/lib/puppet/reports/http.rb
index d74782c..f1a7419 100644
--- a/lib/puppet/reports/http.rb
+++ b/lib/puppet/reports/http.rb
@@ -4,19 +4,19 @@ require 'uri'
Puppet::Reports.register_report(:http) do
- desc <<-DESC
- Send report information via HTTP to the ``reporturl``. Each host sends
- its report as a YAML dump and this sends this YAML to a client via HTTP POST.
- The YAML is the `report` parameter of the request."
- DESC
+ desc <<-DESC
+ Send report information via HTTP to the ``reporturl``. Each host sends
+ its report as a YAML dump and this sends this YAML to a client via HTTP POST.
+ The YAML is the `report` parameter of the request."
+ DESC
- def process
- url = URI.parse(Puppet[:reporturl])
- req = Net::HTTP::Post.new(url.path)
- req.body = self.to_yaml
- req.content_type = "application/x-yaml"
- Net::HTTP.new(url.host, url.port).start {|http|
- http.request(req)
- }
- end
+ def process
+ url = URI.parse(Puppet[:reporturl])
+ req = Net::HTTP::Post.new(url.path)
+ req.body = self.to_yaml
+ req.content_type = "application/x-yaml"
+ Net::HTTP.new(url.host, url.port).start {|http|
+ http.request(req)
+ }
+ end
end
diff --git a/lib/puppet/reports/log.rb b/lib/puppet/reports/log.rb
index 827572c..1fc6876 100644
--- a/lib/puppet/reports/log.rb
+++ b/lib/puppet/reports/log.rb
@@ -1,14 +1,14 @@
require 'puppet/reports'
Puppet::Reports.register_report(:log) do
- desc "Send all received logs to the local log destinations. Usually
- the log destination is syslog."
+ desc "Send all received logs to the local log destinations. Usually
+ the log destination is syslog."
- def process
- self.logs.each do |log|
- log.source = "//#{self.host}/#{log.source}"
- Puppet::Util::Log.newmessage(log)
- end
+ def process
+ self.logs.each do |log|
+ log.source = "//#{self.host}/#{log.source}"
+ Puppet::Util::Log.newmessage(log)
end
+ end
end
diff --git a/lib/puppet/reports/rrdgraph.rb b/lib/puppet/reports/rrdgraph.rb
index 2f27f63..9fbeb60 100644
--- a/lib/puppet/reports/rrdgraph.rb
+++ b/lib/puppet/reports/rrdgraph.rb
@@ -1,129 +1,129 @@
Puppet::Reports.register_report(:rrdgraph) do
- desc "Graph all available data about hosts using the RRD library. You
- must have the Ruby RRDtool library installed to use this report, which
- you can get from `the RubyRRDTool RubyForge page`_. This package may also
- be available as ``ruby-rrd`` or ``rrdtool-ruby`` in your distribution's package
- management system. The library and/or package will both require the binary
- ``rrdtool`` package from your distribution to be installed.
-
- .. _the RubyRRDTool RubyForge page: http://rubyforge.org/projects/rubyrrdtool/
-
- This report will create, manage, and graph RRD database files for each
- of the metrics generated during transactions, and it will create a
- few simple html files to display the reporting host's graphs. At this
- point, it will not create a common index file to display links to
- all hosts.
-
- All RRD files and graphs get created in the ``rrddir`` directory. If
- you want to serve these publicly, you should be able to just alias that
- directory in a web server.
-
- If you really know what you're doing, you can tune the ``rrdinterval``,
- which defaults to the ``runinterval``."
-
- def hostdir
- @hostdir ||= File.join(Puppet[:rrddir], self.host)
- end
-
- def htmlfile(type, graphs, field)
- file = File.join(hostdir, "#{type}.html")
- File.open(file, "w") do |of|
- of.puts "<html><head><title>#{type.capitalize} graphs for #{host}</title></head><body>"
-
- graphs.each do |graph|
- if field == :first
- name = graph.sub(/-\w+.png/, '').capitalize
- else
- name = graph.sub(/\w+-/, '').sub(".png", '').capitalize
- end
- of.puts "<img src=#{graph}><br>"
- end
- of.puts "</body></html>"
+ desc "Graph all available data about hosts using the RRD library. You
+ must have the Ruby RRDtool library installed to use this report, which
+ you can get from `the RubyRRDTool RubyForge page`_. This package may also
+ be available as ``ruby-rrd`` or ``rrdtool-ruby`` in your distribution's package
+ management system. The library and/or package will both require the binary
+ ``rrdtool`` package from your distribution to be installed.
+
+ .. _the RubyRRDTool RubyForge page: http://rubyforge.org/projects/rubyrrdtool/
+
+ This report will create, manage, and graph RRD database files for each
+ of the metrics generated during transactions, and it will create a
+ few simple html files to display the reporting host's graphs. At this
+ point, it will not create a common index file to display links to
+ all hosts.
+
+ All RRD files and graphs get created in the ``rrddir`` directory. If
+ you want to serve these publicly, you should be able to just alias that
+ directory in a web server.
+
+ If you really know what you're doing, you can tune the ``rrdinterval``,
+ which defaults to the ``runinterval``."
+
+ def hostdir
+ @hostdir ||= File.join(Puppet[:rrddir], self.host)
+ end
+
+ def htmlfile(type, graphs, field)
+ file = File.join(hostdir, "#{type}.html")
+ File.open(file, "w") do |of|
+ of.puts "<html><head><title>#{type.capitalize} graphs for #{host}</title></head><body>"
+
+ graphs.each do |graph|
+ if field == :first
+ name = graph.sub(/-\w+.png/, '').capitalize
+ else
+ name = graph.sub(/\w+-/, '').sub(".png", '').capitalize
end
-
- file
+ of.puts "<img src=#{graph}><br>"
+ end
+ of.puts "</body></html>"
end
- def mkhtml
- images = Dir.entries(hostdir).find_all { |d| d =~ /\.png/ }
+ file
+ end
- periodorder = %w{daily weekly monthly yearly}
+ def mkhtml
+ images = Dir.entries(hostdir).find_all { |d| d =~ /\.png/ }
- periods = {}
- types = {}
- images.each do |n|
- type, period = n.sub(".png", '').split("-")
- periods[period] ||= []
- types[type] ||= []
- periods[period] << n
- types[type] << n
- end
+ periodorder = %w{daily weekly monthly yearly}
- files = []
- # Make the period html files
- periodorder.each do |period|
- unless ary = periods[period]
- raise Puppet::Error, "Could not find graphs for #{period}"
- end
- files << htmlfile(period, ary, :first)
- end
+ periods = {}
+ types = {}
+ images.each do |n|
+ type, period = n.sub(".png", '').split("-")
+ periods[period] ||= []
+ types[type] ||= []
+ periods[period] << n
+ types[type] << n
+ end
- # make the type html files
- types.sort { |a,b| a[0] <=> b[0] }.each do |type, ary|
- newary = []
- periodorder.each do |period|
- if graph = ary.find { |g| g.include?("-#{period}.png") }
- newary << graph
- else
- raise "Could not find #{type}-#{period} graph"
- end
- end
-
- files << htmlfile(type, newary, :second)
- end
+ files = []
+ # Make the period html files
+ periodorder.each do |period|
+ unless ary = periods[period]
+ raise Puppet::Error, "Could not find graphs for #{period}"
+ end
+ files << htmlfile(period, ary, :first)
+ end
- File.open(File.join(hostdir, "index.html"), "w") do |of|
- of.puts "<html><head><title>Report graphs for #{host}</title></head><body>"
- files.each do |file|
- of.puts "<a href='#{File.basename(file)}'>#{File.basename(file).sub(".html",'').capitalize}</a><br/>"
- end
- of.puts "</body></html>"
+ # make the type html files
+ types.sort { |a,b| a[0] <=> b[0] }.each do |type, ary|
+ newary = []
+ periodorder.each do |period|
+ if graph = ary.find { |g| g.include?("-#{period}.png") }
+ newary << graph
+ else
+ raise "Could not find #{type}-#{period} graph"
end
+ end
+
+ files << htmlfile(type, newary, :second)
end
- def process(time = nil)
- time ||= Time.now.to_i
+ File.open(File.join(hostdir, "index.html"), "w") do |of|
+ of.puts "<html><head><title>Report graphs for #{host}</title></head><body>"
+ files.each do |file|
+ of.puts "<a href='#{File.basename(file)}'>#{File.basename(file).sub(".html",'').capitalize}</a><br/>"
+ end
+ of.puts "</body></html>"
+ end
+ end
- unless File.directory?(hostdir) and FileTest.writable?(hostdir)
- # Some hackishness to create the dir with all of the right modes and ownership
- config = Puppet::Util::Settings.new
- config.setdefaults(:reports, :hostdir => {:default => hostdir, :owner => 'service', :mode => 0755, :group => 'service', :desc => "eh"})
+ def process(time = nil)
+ time ||= Time.now.to_i
- # This creates the dir.
- config.use(:reports)
- end
+ unless File.directory?(hostdir) and FileTest.writable?(hostdir)
+ # Some hackishness to create the dir with all of the right modes and ownership
+ config = Puppet::Util::Settings.new
+ config.setdefaults(:reports, :hostdir => {:default => hostdir, :owner => 'service', :mode => 0755, :group => 'service', :desc => "eh"})
- self.metrics.each do |name, metric|
- metric.basedir = hostdir
+ # This creates the dir.
+ config.use(:reports)
+ end
- if name == "time"
- timeclean(metric)
- end
+ self.metrics.each do |name, metric|
+ metric.basedir = hostdir
- metric.store(time)
+ if name == "time"
+ timeclean(metric)
+ end
- metric.graph
- end
+ metric.store(time)
- mkhtml unless FileTest.exists?(File.join(hostdir, "index.html"))
+ metric.graph
end
- # Unfortunately, RRD does not deal well with changing lists of values,
- # so we have to pick a list of values and stick with it. In this case,
- # that means we record the total time, the config time, and that's about
- # it. We should probably send each type's time as a separate metric.
- def timeclean(metric)
- metric.values = metric.values.find_all { |name, label, value| [:total, :config_retrieval].include?(name) }
- end
+ mkhtml unless FileTest.exists?(File.join(hostdir, "index.html"))
+ end
+
+ # Unfortunately, RRD does not deal well with changing lists of values,
+ # so we have to pick a list of values and stick with it. In this case,
+ # that means we record the total time, the config time, and that's about
+ # it. We should probably send each type's time as a separate metric.
+ def timeclean(metric)
+ metric.values = metric.values.find_all { |name, label, value| [:total, :config_retrieval].include?(name) }
+ end
end
diff --git a/lib/puppet/reports/store.rb b/lib/puppet/reports/store.rb
index 384f0eb..65159fc 100644
--- a/lib/puppet/reports/store.rb
+++ b/lib/puppet/reports/store.rb
@@ -1,60 +1,60 @@
require 'puppet'
Puppet::Reports.register_report(:store) do
- desc "Store the yaml report on disk. Each host sends its report as a YAML dump
- and this just stores the file on disk, in the ``reportdir`` directory.
-
- These files collect quickly -- one every half hour -- so it is a good idea
- to perform some maintenance on them if you use this report (it's the only
- default report)."
-
- def mkclientdir(client, dir)
- config = Puppet::Util::Settings.new
-
- config.setdefaults(
- "reportclient-#{client}".to_sym,
- "client-#{client}-dir" => { :default => dir,
- :mode => 0750,
- :desc => "Client dir for #{client}",
- :owner => 'service',
- :group => 'service'
- },
+ desc "Store the yaml report on disk. Each host sends its report as a YAML dump
+ and this just stores the file on disk, in the ``reportdir`` directory.
+
+ These files collect quickly -- one every half hour -- so it is a good idea
+ to perform some maintenance on them if you use this report (it's the only
+ default report)."
+
+ def mkclientdir(client, dir)
+ config = Puppet::Util::Settings.new
+
+ config.setdefaults(
+ "reportclient-#{client}".to_sym,
+ "client-#{client}-dir" => { :default => dir,
+ :mode => 0750,
+ :desc => "Client dir for #{client}",
+ :owner => 'service',
+ :group => 'service'
+ },
- :noop => [false, "Used by settings internally."]
- )
+ :noop => [false, "Used by settings internally."]
+ )
- config.use("reportclient-#{client}".to_sym)
- end
-
- def process
- # We don't want any tracking back in the fs. Unlikely, but there
- # you go.
- client = self.host.gsub("..",".")
+ config.use("reportclient-#{client}".to_sym)
+ end
- dir = File.join(Puppet[:reportdir], client)
+ def process
+ # We don't want any tracking back in the fs. Unlikely, but there
+ # you go.
+ client = self.host.gsub("..",".")
- mkclientdir(client, dir) unless FileTest.exists?(dir)
+ dir = File.join(Puppet[:reportdir], client)
- # Now store the report.
- now = Time.now.gmtime
- name = %w{year month day hour min}.collect do |method|
- # Make sure we're at least two digits everywhere
- "%02d" % now.send(method).to_s
- end.join("") + ".yaml"
+ mkclientdir(client, dir) unless FileTest.exists?(dir)
- file = File.join(dir, name)
+ # Now store the report.
+ now = Time.now.gmtime
+ name = %w{year month day hour min}.collect do |method|
+ # Make sure we're at least two digits everywhere
+ "%02d" % now.send(method).to_s
+ end.join("") + ".yaml"
- begin
- File.open(file, "w", 0640) do |f|
- f.print to_yaml
- end
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.warning "Could not write report for #{client} at #{file}: #{detail}"
- end
+ file = File.join(dir, name)
- # Only testing cares about the return value
- file
+ begin
+ File.open(file, "w", 0640) do |f|
+ f.print to_yaml
+ end
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.warning "Could not write report for #{client} at #{file}: #{detail}"
end
+
+ # Only testing cares about the return value
+ file
+ end
end
diff --git a/lib/puppet/reports/tagmail.rb b/lib/puppet/reports/tagmail.rb
index f77d3c9..6521040 100644
--- a/lib/puppet/reports/tagmail.rb
+++ b/lib/puppet/reports/tagmail.rb
@@ -5,165 +5,165 @@ require 'net/smtp'
require 'time'
Puppet::Reports.register_report(:tagmail) do
- desc "This report sends specific log messages to specific email addresses
- based on the tags in the log messages. See the
- `UsingTags tag documentation`:trac: for more information
- on tags.
-
- To use this report, you must create a ``tagmail.conf`` (in the location
- specified by ``tagmap``). This is a simple file that maps tags to
- email addresses: Any log messages in the report that match the specified
- tags will be sent to the specified email addresses.
-
- Tags must be comma-separated, and they can be negated so that messages
- only match when they do not have that tag. The tags are separated from
- the email addresses by a colon, and the email addresses should also
- be comma-separated.
-
- Lastly, there is an ``all`` tag that will always match all log messages.
-
- Here is an example tagmail.conf::
-
- all: me at domain.com
- webserver, !mailserver: httpadmins at domain.com
-
- This will send all messages to ``me at domain.com``, and all messages from
- webservers that are not also from mailservers to ``httpadmins at domain.com``.
-
- If you are using anti-spam controls, such as grey-listing, on your mail
- server you should whitelist the sending email (controlled by ``reportform`` configuration option) to ensure your email is not discarded as spam.
- "
-
-
- # Find all matching messages.
- def match(taglists)
- matching_logs = []
- taglists.each do |emails, pos, neg|
- # First find all of the messages matched by our positive tags
- messages = nil
- if pos.include?("all")
- messages = self.logs
- else
- # Find all of the messages that are tagged with any of our
- # tags.
- messages = self.logs.find_all do |log|
- pos.detect { |tag| log.tagged?(tag) }
- end
- end
-
- # Now go through and remove any messages that match our negative tags
- messages = messages.reject do |log|
- true if neg.detect do |tag| log.tagged?(tag) end
- end
-
- if messages.empty?
- Puppet.info "No messages to report to #{emails.join(",")}"
- next
- else
- matching_logs << [emails, messages.collect { |m| m.to_report }.join("\n")]
- end
+ desc "This report sends specific log messages to specific email addresses
+ based on the tags in the log messages. See the
+ `UsingTags tag documentation`:trac: for more information
+ on tags.
+
+ To use this report, you must create a ``tagmail.conf`` (in the location
+ specified by ``tagmap``). This is a simple file that maps tags to
+ email addresses: Any log messages in the report that match the specified
+ tags will be sent to the specified email addresses.
+
+ Tags must be comma-separated, and they can be negated so that messages
+ only match when they do not have that tag. The tags are separated from
+ the email addresses by a colon, and the email addresses should also
+ be comma-separated.
+
+ Lastly, there is an ``all`` tag that will always match all log messages.
+
+ Here is an example tagmail.conf::
+
+ all: me at domain.com
+ webserver, !mailserver: httpadmins at domain.com
+
+ This will send all messages to ``me at domain.com``, and all messages from
+ webservers that are not also from mailservers to ``httpadmins at domain.com``.
+
+ If you are using anti-spam controls, such as grey-listing, on your mail
+ server you should whitelist the sending email (controlled by ``reportform`` configuration option) to ensure your email is not discarded as spam.
+ "
+
+
+ # Find all matching messages.
+ def match(taglists)
+ matching_logs = []
+ taglists.each do |emails, pos, neg|
+ # First find all of the messages matched by our positive tags
+ messages = nil
+ if pos.include?("all")
+ messages = self.logs
+ else
+ # Find all of the messages that are tagged with any of our
+ # tags.
+ messages = self.logs.find_all do |log|
+ pos.detect { |tag| log.tagged?(tag) }
end
-
- matching_logs
+ end
+
+ # Now go through and remove any messages that match our negative tags
+ messages = messages.reject do |log|
+ true if neg.detect do |tag| log.tagged?(tag) end
+ end
+
+ if messages.empty?
+ Puppet.info "No messages to report to #{emails.join(",")}"
+ next
+ else
+ matching_logs << [emails, messages.collect { |m| m.to_report }.join("\n")]
+ end
end
- # Load the config file
- def parse(text)
- taglists = []
- text.split("\n").each do |line|
- taglist = emails = nil
- case line.chomp
- when /^\s*#/; next
- when /^\s*$/; next
- when /^\s*(.+)\s*:\s*(.+)\s*$/
- taglist = $1
- emails = $2.sub(/#.*$/,'')
- else
- raise ArgumentError, "Invalid tagmail config file"
- end
-
- pos = []
- neg = []
- taglist.sub(/\s+$/,'').split(/\s*,\s*/).each do |tag|
- unless tag =~ /^!?[-\w]+$/
- raise ArgumentError, "Invalid tag #{tag.inspect}"
- end
- case tag
- when /^\w+/; pos << tag
- when /^!\w+/; neg << tag.sub("!", '')
- else
- raise Puppet::Error, "Invalid tag '#{tag}'"
- end
- end
-
- # Now split the emails
- emails = emails.sub(/\s+$/,'').split(/\s*,\s*/)
- taglists << [emails, pos, neg]
+ matching_logs
+ end
+
+ # Load the config file
+ def parse(text)
+ taglists = []
+ text.split("\n").each do |line|
+ taglist = emails = nil
+ case line.chomp
+ when /^\s*#/; next
+ when /^\s*$/; next
+ when /^\s*(.+)\s*:\s*(.+)\s*$/
+ taglist = $1
+ emails = $2.sub(/#.*$/,'')
+ else
+ raise ArgumentError, "Invalid tagmail config file"
+ end
+
+ pos = []
+ neg = []
+ taglist.sub(/\s+$/,'').split(/\s*,\s*/).each do |tag|
+ unless tag =~ /^!?[-\w]+$/
+ raise ArgumentError, "Invalid tag #{tag.inspect}"
end
- taglists
- end
-
- # Process the report. This just calls the other associated messages.
- def process
- unless FileTest.exists?(Puppet[:tagmap])
- Puppet.notice "Cannot send tagmail report; no tagmap file #{Puppet[:tagmap]}"
- return
+ case tag
+ when /^\w+/; pos << tag
+ when /^!\w+/; neg << tag.sub("!", '')
+ else
+ raise Puppet::Error, "Invalid tag '#{tag}'"
end
+ end
- taglists = parse(File.read(Puppet[:tagmap]))
-
- # Now find any appropriately tagged messages.
- reports = match(taglists)
-
- send(reports)
+ # Now split the emails
+ emails = emails.sub(/\s+$/,'').split(/\s*,\s*/)
+ taglists << [emails, pos, neg]
+ end
+ taglists
+ end
+
+ # Process the report. This just calls the other associated messages.
+ def process
+ unless FileTest.exists?(Puppet[:tagmap])
+ Puppet.notice "Cannot send tagmail report; no tagmap file #{Puppet[:tagmap]}"
+ return
end
- # Send the email reports.
- def send(reports)
- pid = fork do
- if Puppet[:smtpserver] != "none"
- begin
- Net::SMTP.start(Puppet[:smtpserver]) do |smtp|
- reports.each do |emails, messages|
- smtp.open_message_stream(Puppet[:reportfrom], *emails) do |p|
- p.puts "From: #{Puppet[:reportfrom]}"
- p.puts "Subject: Puppet Report for #{self.host}"
- p.puts "To: " + emails.join(", ")
- p.puts "Date: #{Time.now.rfc2822}"
- p.puts
- p.puts messages
- end
- end
- end
- rescue => detail
- puts detail.backtrace if Puppet[:debug]
- raise Puppet::Error,
- "Could not send report emails through smtp: #{detail}"
- end
- elsif Puppet[:sendmail] != ""
- begin
- reports.each do |emails, messages|
- # We need to open a separate process for every set of email addresses
- IO.popen(Puppet[:sendmail] + " " + emails.join(" "), "w") do |p|
- p.puts "From: #{Puppet[:reportfrom]}"
- p.puts "Subject: Puppet Report for #{self.host}"
- p.puts "To: " + emails.join(", ")
-
- p.puts messages
- end
- end
- rescue => detail
- puts detail.backtrace if Puppet[:debug]
- raise Puppet::Error,
- "Could not send report emails via sendmail: #{detail}"
- end
- else
- raise Puppet::Error, "SMTP server is unset and could not find sendmail"
+ taglists = parse(File.read(Puppet[:tagmap]))
+
+ # Now find any appropriately tagged messages.
+ reports = match(taglists)
+
+ send(reports)
+ end
+
+ # Send the email reports.
+ def send(reports)
+ pid = fork do
+ if Puppet[:smtpserver] != "none"
+ begin
+ Net::SMTP.start(Puppet[:smtpserver]) do |smtp|
+ reports.each do |emails, messages|
+ smtp.open_message_stream(Puppet[:reportfrom], *emails) do |p|
+ p.puts "From: #{Puppet[:reportfrom]}"
+ p.puts "Subject: Puppet Report for #{self.host}"
+ p.puts "To: " + emails.join(", ")
+ p.puts "Date: #{Time.now.rfc2822}"
+ p.puts
+ p.puts messages
+ end
end
+ end
+ rescue => detail
+ puts detail.backtrace if Puppet[:debug]
+ raise Puppet::Error,
+ "Could not send report emails through smtp: #{detail}"
end
-
- # Don't bother waiting for the pid to return.
- Process.detach(pid)
+ elsif Puppet[:sendmail] != ""
+ begin
+ reports.each do |emails, messages|
+ # We need to open a separate process for every set of email addresses
+ IO.popen(Puppet[:sendmail] + " " + emails.join(" "), "w") do |p|
+ p.puts "From: #{Puppet[:reportfrom]}"
+ p.puts "Subject: Puppet Report for #{self.host}"
+ p.puts "To: " + emails.join(", ")
+
+ p.puts messages
+ end
+ end
+ rescue => detail
+ puts detail.backtrace if Puppet[:debug]
+ raise Puppet::Error,
+ "Could not send report emails via sendmail: #{detail}"
+ end
+ else
+ raise Puppet::Error, "SMTP server is unset and could not find sendmail"
+ end
end
+
+ # Don't bother waiting for the pid to return.
+ Process.detach(pid)
+ end
end
diff --git a/lib/puppet/resource.rb b/lib/puppet/resource.rb
index cc84b76..9894f2f 100644
--- a/lib/puppet/resource.rb
+++ b/lib/puppet/resource.rb
@@ -5,475 +5,475 @@ require 'puppet/util/pson'
# The simplest resource class. Eventually it will function as the
# base class for all resource-like behaviour.
class Puppet::Resource
- include Puppet::Util::Tagging
+ include Puppet::Util::Tagging
- require 'puppet/resource/type_collection_helper'
- include Puppet::Resource::TypeCollectionHelper
+ require 'puppet/resource/type_collection_helper'
+ include Puppet::Resource::TypeCollectionHelper
- extend Puppet::Util::Pson
- include Enumerable
- attr_accessor :file, :line, :catalog, :exported, :virtual, :validate_parameters, :strict
- attr_reader :namespaces
+ extend Puppet::Util::Pson
+ include Enumerable
+ attr_accessor :file, :line, :catalog, :exported, :virtual, :validate_parameters, :strict
+ attr_reader :namespaces
- require 'puppet/indirector'
- extend Puppet::Indirector
- indirects :resource, :terminus_class => :ral
+ require 'puppet/indirector'
+ extend Puppet::Indirector
+ indirects :resource, :terminus_class => :ral
- ATTRIBUTES = [:file, :line, :exported]
+ ATTRIBUTES = [:file, :line, :exported]
- def self.from_pson(pson)
- raise ArgumentError, "No resource type provided in pson data" unless type = pson['type']
- raise ArgumentError, "No resource title provided in pson data" unless title = pson['title']
+ def self.from_pson(pson)
+ raise ArgumentError, "No resource type provided in pson data" unless type = pson['type']
+ raise ArgumentError, "No resource title provided in pson data" unless title = pson['title']
- resource = new(type, title)
+ resource = new(type, title)
- if params = pson['parameters']
- params.each { |param, value| resource[param] = value }
- end
-
- if tags = pson['tags']
- tags.each { |tag| resource.tag(tag) }
- end
-
- ATTRIBUTES.each do |a|
- if value = pson[a.to_s]
- resource.send(a.to_s + "=", value)
- end
- end
-
- resource.exported ||= false
-
- resource
+ if params = pson['parameters']
+ params.each { |param, value| resource[param] = value }
end
- def to_pson_data_hash
- data = ([:type, :title, :tags] + ATTRIBUTES).inject({}) do |hash, param|
- next hash unless value = self.send(param)
- hash[param.to_s] = value
- hash
- end
-
- data["exported"] ||= false
-
- params = self.to_hash.inject({}) do |hash, ary|
- param, value = ary
-
- # Don't duplicate the title as the namevar
- next hash if param == namevar and value == title
- if value.is_a? Puppet::Resource
- hash[param] = value.to_s
- else
- hash[param] = value
- end
- hash
- end
-
- data["parameters"] = params unless params.empty?
-
- data
+ if tags = pson['tags']
+ tags.each { |tag| resource.tag(tag) }
end
- def to_pson(*args)
- to_pson_data_hash.to_pson(*args)
+ ATTRIBUTES.each do |a|
+ if value = pson[a.to_s]
+ resource.send(a.to_s + "=", value)
+ end
end
- # Proxy these methods to the parameters hash. It's likely they'll
- # be overridden at some point, but this works for now.
- %w{has_key? keys length delete empty? <<}.each do |method|
- define_method(method) do |*args|
- @parameters.send(method, *args)
- end
- end
+ resource.exported ||= false
- # Set a given parameter. Converts all passed names
- # to lower-case symbols.
- def []=(param, value)
- validate_parameter(param) if validate_parameters
- @parameters[parameter_name(param)] = value
- end
+ resource
+ end
- # Return a given parameter's value. Converts all passed names
- # to lower-case symbols.
- def [](param)
- @parameters[parameter_name(param)]
+ def to_pson_data_hash
+ data = ([:type, :title, :tags] + ATTRIBUTES).inject({}) do |hash, param|
+ next hash unless value = self.send(param)
+ hash[param.to_s] = value
+ hash
end
- def ==(other)
- return false unless other.respond_to?(:title) and self.type == other.type and self.title == other.title
+ data["exported"] ||= false
- return false unless to_hash == other.to_hash
- true
- end
-
- # Compatibility method.
- def builtin?
- builtin_type?
- end
-
- # Is this a builtin resource type?
- def builtin_type?
- resource_type.is_a?(Class)
- end
-
- # Iterate over each param/value pair, as required for Enumerable.
- def each
- @parameters.each { |p,v| yield p, v }
- end
-
- def include?(parameter)
- super || @parameters.keys.include?( parameter_name(parameter) )
- end
-
- # These two methods are extracted into a Helper
- # module, but file load order prevents me
- # from including them in the class, and I had weird
- # behaviour (i.e., sometimes it didn't work) when
- # I directly extended each resource with the helper.
- def environment
- Puppet::Node::Environment.new(@environment)
- end
-
- def environment=(env)
- if env.is_a?(String) or env.is_a?(Symbol)
- @environment = env
- else
- @environment = env.name
- end
- end
+ params = self.to_hash.inject({}) do |hash, ary|
+ param, value = ary
- %w{exported virtual strict}.each do |m|
- define_method(m+"?") do
- self.send(m)
- end
+ # Don't duplicate the title as the namevar
+ next hash if param == namevar and value == title
+ if value.is_a? Puppet::Resource
+ hash[param] = value.to_s
+ else
+ hash[param] = value
+ end
+ hash
end
- # Create our resource.
- def initialize(type, title = nil, attributes = {})
- @parameters = {}
- @namespaces = [""]
+ data["parameters"] = params unless params.empty?
- # Set things like namespaces and strictness first.
- attributes.each do |attr, value|
- next if attr == :parameters
- send(attr.to_s + "=", value)
- end
-
- # We do namespaces first, and use tmp variables, so our title
- # canonicalization works (i.e., namespaces are set and resource
- # types can be looked up)
- tmp_type, tmp_title = extract_type_and_title(type, title)
- self.type = tmp_type
- self.title = tmp_title
-
- if params = attributes[:parameters]
- extract_parameters(params)
- end
-
- resolve_type_and_title
+ data
+ end
- tag(self.type)
- tag(self.title) if valid_tag?(self.title)
+ def to_pson(*args)
+ to_pson_data_hash.to_pson(*args)
+ end
- raise ArgumentError, "Invalid resource type #{type}" if strict? and ! resource_type
+ # Proxy these methods to the parameters hash. It's likely they'll
+ # be overridden at some point, but this works for now.
+ %w{has_key? keys length delete empty? <<}.each do |method|
+ define_method(method) do |*args|
+ @parameters.send(method, *args)
end
+ end
- def ref
- to_s
- end
+ # Set a given parameter. Converts all passed names
+ # to lower-case symbols.
+ def []=(param, value)
+ validate_parameter(param) if validate_parameters
+ @parameters[parameter_name(param)] = value
+ end
- # Find our resource.
- def resolve
- return(catalog ? catalog.resource(to_s) : nil)
- end
+ # Return a given parameter's value. Converts all passed names
+ # to lower-case symbols.
+ def [](param)
+ @parameters[parameter_name(param)]
+ end
- def title=(value)
- @unresolved_title = value
- @title = nil
- end
+ def ==(other)
+ return false unless other.respond_to?(:title) and self.type == other.type and self.title == other.title
- def resource_type
- case type
- when "Class"; find_hostclass(title)
- when "Node"; find_node(title)
- else
- find_resource_type(type)
- end
- end
+ return false unless to_hash == other.to_hash
+ true
+ end
- # Produce a simple hash of our parameters.
- def to_hash
- parse_title.merge @parameters
- end
+ # Compatibility method.
+ def builtin?
+ builtin_type?
+ end
- def to_s
- "#{type}[#{title}]"
- end
+ # Is this a builtin resource type?
+ def builtin_type?
+ resource_type.is_a?(Class)
+ end
- def uniqueness_key
- self.to_hash.values_at(*key_attributes.sort_by { |k| k.to_s })
- end
+ # Iterate over each param/value pair, as required for Enumerable.
+ def each
+ @parameters.each { |p,v| yield p, v }
+ end
- def key_attributes
- return(resource_type.respond_to? :key_attributes) ? resource_type.key_attributes : [:name]
- end
+ def include?(parameter)
+ super || @parameters.keys.include?( parameter_name(parameter) )
+ end
- # Convert our resource to Puppet code.
- def to_manifest
- "%s { '%s':\n%s\n}" % [self.type.to_s.downcase, self.title,
- @parameters.collect { |p, v|
- if v.is_a? Array
- " #{p} => [\'#{v.join("','")}\']"
- else
- " #{p} => \'#{v}\'"
- end
- }.join(",\n")
- ]
- end
+ # These two methods are extracted into a Helper
+ # module, but file load order prevents me
+ # from including them in the class, and I had weird
+ # behaviour (i.e., sometimes it didn't work) when
+ # I directly extended each resource with the helper.
+ def environment
+ Puppet::Node::Environment.new(@environment)
+ end
- def to_ref
- ref
+ def environment=(env)
+ if env.is_a?(String) or env.is_a?(Symbol)
+ @environment = env
+ else
+ @environment = env.name
end
+ end
- # Convert our resource to a RAL resource instance. Creates component
- # instances for resource types that don't exist.
- def to_ral
- if typeklass = Puppet::Type.type(self.type)
- return typeklass.new(self)
+ %w{exported virtual strict}.each do |m|
+ define_method(m+"?") do
+ self.send(m)
+ end
+ end
+
+ # Create our resource.
+ def initialize(type, title = nil, attributes = {})
+ @parameters = {}
+ @namespaces = [""]
+
+ # Set things like namespaces and strictness first.
+ attributes.each do |attr, value|
+ next if attr == :parameters
+ send(attr.to_s + "=", value)
+ end
+
+ # We do namespaces first, and use tmp variables, so our title
+ # canonicalization works (i.e., namespaces are set and resource
+ # types can be looked up)
+ tmp_type, tmp_title = extract_type_and_title(type, title)
+ self.type = tmp_type
+ self.title = tmp_title
+
+ if params = attributes[:parameters]
+ extract_parameters(params)
+ end
+
+ resolve_type_and_title
+
+ tag(self.type)
+ tag(self.title) if valid_tag?(self.title)
+
+ raise ArgumentError, "Invalid resource type #{type}" if strict? and ! resource_type
+ end
+
+ def ref
+ to_s
+ end
+
+ # Find our resource.
+ def resolve
+ return(catalog ? catalog.resource(to_s) : nil)
+ end
+
+ def title=(value)
+ @unresolved_title = value
+ @title = nil
+ end
+
+ def resource_type
+ case type
+ when "Class"; find_hostclass(title)
+ when "Node"; find_node(title)
+ else
+ find_resource_type(type)
+ end
+ end
+
+ # Produce a simple hash of our parameters.
+ def to_hash
+ parse_title.merge @parameters
+ end
+
+ def to_s
+ "#{type}[#{title}]"
+ end
+
+ def uniqueness_key
+ self.to_hash.values_at(*key_attributes.sort_by { |k| k.to_s })
+ end
+
+ def key_attributes
+ return(resource_type.respond_to? :key_attributes) ? resource_type.key_attributes : [:name]
+ end
+
+ # Convert our resource to Puppet code.
+ def to_manifest
+ "%s { '%s':\n%s\n}" % [self.type.to_s.downcase, self.title,
+ @parameters.collect { |p, v|
+ if v.is_a? Array
+ " #{p} => [\'#{v.join("','")}\']"
else
- return Puppet::Type::Component.new(self)
+ " #{p} => \'#{v}\'"
end
- end
-
- # Translate our object to a backward-compatible transportable object.
- def to_trans
- if builtin_type? and type.downcase.to_s != "stage"
- result = to_transobject
- else
- result = to_transbucket
- end
-
- result.file = self.file
- result.line = self.line
-
- result
- end
-
- def to_trans_ref
- [type.to_s, title.to_s]
- end
-
- # Create an old-style TransObject instance, for builtin resource types.
- def to_transobject
- # Now convert to a transobject
- result = Puppet::TransObject.new(title, type)
- to_hash.each do |p, v|
- if v.is_a?(Puppet::Resource)
- v = v.to_trans_ref
- elsif v.is_a?(Array)
- v = v.collect { |av|
- av = av.to_trans_ref if av.is_a?(Puppet::Resource)
- av
- }
- end
-
- # If the value is an array with only one value, then
- # convert it to a single value. This is largely so that
- # the database interaction doesn't have to worry about
- # whether it returns an array or a string.
- result[p.to_s] = if v.is_a?(Array) and v.length == 1
- v[0]
- else
- v
- end
- end
-
- result.tags = self.tags
-
- result
- end
-
- def name
- # this is potential namespace conflict
- # between the notion of an "indirector name"
- # and a "resource name"
- [ type, title ].join('/')
- end
-
- def to_resource
- self
- end
-
- # We have to lazy-evaluate this.
- def title=(value)
- @title = nil
- @unresolved_title = value
- end
-
- # We have to lazy-evaluate this.
- def type=(value)
- @type = nil
- @unresolved_type = value || "Class"
- end
-
- def title
- resolve_type_and_title unless @title
- @title
- end
-
- def type
- resolve_type_and_title unless @type
- @type
- end
-
- def valid_parameter?(name)
- resource_type.valid_parameter?(name)
- end
-
- def validate_parameter(name)
- raise ArgumentError, "Invalid parameter #{name}" unless valid_parameter?(name)
- end
-
- private
-
- def find_node(name)
- known_resource_types.node(name)
- end
-
- def find_hostclass(title)
- name = title == :main ? "" : title
- known_resource_types.find_hostclass(namespaces, name)
- end
-
- def find_resource_type(type)
- # It still works fine without the type == 'class' short-cut, but it is a lot slower.
- find_builtin_resource_type(type) || find_defined_resource_type(type) unless type.to_s.downcase == 'class'
- end
-
- def find_builtin_resource_type(type)
- Puppet::Type.type(type.to_s.downcase.to_sym)
- end
-
- def find_defined_resource_type(type)
- known_resource_types.find_definition(namespaces, type.to_s.downcase)
- end
-
- # Produce a canonical method name.
- def parameter_name(param)
- param = param.to_s.downcase.to_sym
- if param == :name and n = namevar
- param = namevar
- end
- param
- end
-
- def namespaces=(ns)
- @namespaces = Array(ns)
- end
-
- # The namevar for our resource type. If the type doesn't exist,
- # always use :name.
- def namevar
- if builtin_type? and t = resource_type and t.key_attributes.length == 1
- t.key_attributes.first
- else
- :name
- end
- end
-
- # Create an old-style TransBucket instance, for non-builtin resource types.
- def to_transbucket
- bucket = Puppet::TransBucket.new([])
-
- bucket.type = self.type
- bucket.name = self.title
-
- # TransBuckets don't support parameters, which is why they're being deprecated.
- bucket
- end
-
- def extract_parameters(params)
- params.each do |param, value|
- validate_parameter(param) if strict?
- self[param] = value
- end
- end
-
- def extract_type_and_title(argtype, argtitle)
- if (argtitle || argtype) =~ /^([^\[\]]+)\[(.+)\]$/m then [ $1, $2 ]
- elsif argtitle then [ argtype, argtitle ]
- elsif argtype.is_a?(Puppet::Type) then [ argtype.class.name, argtype.title ]
- else raise ArgumentError, "No title provided and #{argtype.inspect} is not a valid resource reference"
- end
- end
-
- def munge_type_name(value)
- return :main if value == :main
- return "Class" if value == "" or value.nil? or value.to_s.downcase == "component"
-
- value.to_s.split("::").collect { |s| s.capitalize }.join("::")
- end
-
- # This is an annoyingly complicated method for resolving qualified
- # types as necessary, and putting them in type or title attributes.
- def resolve_type_and_title
- if @unresolved_type
- @type = resolve_type
- @unresolved_type = nil
- end
- if @unresolved_title
- @title = resolve_title
- @unresolved_title = nil
- end
- end
-
- def resolve_type
- case type = munge_type_name(@unresolved_type)
- when "Class", "Node";
- type
- else
- # Otherwise, some kind of builtin or defined resource type
- munge_type_name( (r = find_resource_type(type)) ? r.name : type)
- end
- end
-
- # This method only works if resolve_type was called first
- def resolve_title
- case @type
- when "Node"; return @unresolved_title
- when "Class";
- resolve_title_for_class(@unresolved_title)
- else
- @unresolved_title
- end
- end
-
- def resolve_title_for_class(title)
- if title == "" or title == :main
- return :main
- end
-
- if klass = find_hostclass(title)
- result = klass.name
- end
- munge_type_name(result || title)
- end
-
- def parse_title
- h = {}
- type = find_resource_type(@type)
- if type.respond_to? :title_patterns
- type.title_patterns.each { |regexp, symbols_and_lambdas|
- if captures = regexp.match(title.to_s)
- symbols_and_lambdas.zip(captures[1..-1]).each { |symbol_and_lambda,capture|
- sym, lam = symbol_and_lambda
- #self[sym] = lam.call(capture)
- h[sym] = lam.call(capture)
- }
- return h
- end
- }
- else
- return { :name => title.to_s }
+ }.join(",\n")
+ ]
+ end
+
+ def to_ref
+ ref
+ end
+
+ # Convert our resource to a RAL resource instance. Creates component
+ # instances for resource types that don't exist.
+ def to_ral
+ if typeklass = Puppet::Type.type(self.type)
+ return typeklass.new(self)
+ else
+ return Puppet::Type::Component.new(self)
+ end
+ end
+
+ # Translate our object to a backward-compatible transportable object.
+ def to_trans
+ if builtin_type? and type.downcase.to_s != "stage"
+ result = to_transobject
+ else
+ result = to_transbucket
+ end
+
+ result.file = self.file
+ result.line = self.line
+
+ result
+ end
+
+ def to_trans_ref
+ [type.to_s, title.to_s]
+ end
+
+ # Create an old-style TransObject instance, for builtin resource types.
+ def to_transobject
+ # Now convert to a transobject
+ result = Puppet::TransObject.new(title, type)
+ to_hash.each do |p, v|
+ if v.is_a?(Puppet::Resource)
+ v = v.to_trans_ref
+ elsif v.is_a?(Array)
+ v = v.collect { |av|
+ av = av.to_trans_ref if av.is_a?(Puppet::Resource)
+ av
+ }
+ end
+
+ # If the value is an array with only one value, then
+ # convert it to a single value. This is largely so that
+ # the database interaction doesn't have to worry about
+ # whether it returns an array or a string.
+ result[p.to_s] = if v.is_a?(Array) and v.length == 1
+ v[0]
+ else
+ v
+ end
+ end
+
+ result.tags = self.tags
+
+ result
+ end
+
+ def name
+ # this is potential namespace conflict
+ # between the notion of an "indirector name"
+ # and a "resource name"
+ [ type, title ].join('/')
+ end
+
+ def to_resource
+ self
+ end
+
+ # We have to lazy-evaluate this.
+ def title=(value)
+ @title = nil
+ @unresolved_title = value
+ end
+
+ # We have to lazy-evaluate this.
+ def type=(value)
+ @type = nil
+ @unresolved_type = value || "Class"
+ end
+
+ def title
+ resolve_type_and_title unless @title
+ @title
+ end
+
+ def type
+ resolve_type_and_title unless @type
+ @type
+ end
+
+ def valid_parameter?(name)
+ resource_type.valid_parameter?(name)
+ end
+
+ def validate_parameter(name)
+ raise ArgumentError, "Invalid parameter #{name}" unless valid_parameter?(name)
+ end
+
+ private
+
+ def find_node(name)
+ known_resource_types.node(name)
+ end
+
+ def find_hostclass(title)
+ name = title == :main ? "" : title
+ known_resource_types.find_hostclass(namespaces, name)
+ end
+
+ def find_resource_type(type)
+ # It still works fine without the type == 'class' short-cut, but it is a lot slower.
+ find_builtin_resource_type(type) || find_defined_resource_type(type) unless type.to_s.downcase == 'class'
+ end
+
+ def find_builtin_resource_type(type)
+ Puppet::Type.type(type.to_s.downcase.to_sym)
+ end
+
+ def find_defined_resource_type(type)
+ known_resource_types.find_definition(namespaces, type.to_s.downcase)
+ end
+
+ # Produce a canonical method name.
+ def parameter_name(param)
+ param = param.to_s.downcase.to_sym
+ if param == :name and n = namevar
+ param = namevar
+ end
+ param
+ end
+
+ def namespaces=(ns)
+ @namespaces = Array(ns)
+ end
+
+ # The namevar for our resource type. If the type doesn't exist,
+ # always use :name.
+ def namevar
+ if builtin_type? and t = resource_type and t.key_attributes.length == 1
+ t.key_attributes.first
+ else
+ :name
+ end
+ end
+
+ # Create an old-style TransBucket instance, for non-builtin resource types.
+ def to_transbucket
+ bucket = Puppet::TransBucket.new([])
+
+ bucket.type = self.type
+ bucket.name = self.title
+
+ # TransBuckets don't support parameters, which is why they're being deprecated.
+ bucket
+ end
+
+ def extract_parameters(params)
+ params.each do |param, value|
+ validate_parameter(param) if strict?
+ self[param] = value
+ end
+ end
+
+ def extract_type_and_title(argtype, argtitle)
+ if (argtitle || argtype) =~ /^([^\[\]]+)\[(.+)\]$/m then [ $1, $2 ]
+ elsif argtitle then [ argtype, argtitle ]
+ elsif argtype.is_a?(Puppet::Type) then [ argtype.class.name, argtype.title ]
+ else raise ArgumentError, "No title provided and #{argtype.inspect} is not a valid resource reference"
+ end
+ end
+
+ def munge_type_name(value)
+ return :main if value == :main
+ return "Class" if value == "" or value.nil? or value.to_s.downcase == "component"
+
+ value.to_s.split("::").collect { |s| s.capitalize }.join("::")
+ end
+
+ # This is an annoyingly complicated method for resolving qualified
+ # types as necessary, and putting them in type or title attributes.
+ def resolve_type_and_title
+ if @unresolved_type
+ @type = resolve_type
+ @unresolved_type = nil
+ end
+ if @unresolved_title
+ @title = resolve_title
+ @unresolved_title = nil
+ end
+ end
+
+ def resolve_type
+ case type = munge_type_name(@unresolved_type)
+ when "Class", "Node";
+ type
+ else
+ # Otherwise, some kind of builtin or defined resource type
+ munge_type_name( (r = find_resource_type(type)) ? r.name : type)
+ end
+ end
+
+ # This method only works if resolve_type was called first
+ def resolve_title
+ case @type
+ when "Node"; return @unresolved_title
+ when "Class";
+ resolve_title_for_class(@unresolved_title)
+ else
+ @unresolved_title
+ end
+ end
+
+ def resolve_title_for_class(title)
+ if title == "" or title == :main
+ return :main
+ end
+
+ if klass = find_hostclass(title)
+ result = klass.name
+ end
+ munge_type_name(result || title)
+ end
+
+ def parse_title
+ h = {}
+ type = find_resource_type(@type)
+ if type.respond_to? :title_patterns
+ type.title_patterns.each { |regexp, symbols_and_lambdas|
+ if captures = regexp.match(title.to_s)
+ symbols_and_lambdas.zip(captures[1..-1]).each { |symbol_and_lambda,capture|
+ sym, lam = symbol_and_lambda
+ #self[sym] = lam.call(capture)
+ h[sym] = lam.call(capture)
+ }
+ return h
end
+ }
+ else
+ return { :name => title.to_s }
end
+ end
end
diff --git a/lib/puppet/resource/catalog.rb b/lib/puppet/resource/catalog.rb
index 7988852..e8c1429 100644
--- a/lib/puppet/resource/catalog.rb
+++ b/lib/puppet/resource/catalog.rb
@@ -13,579 +13,579 @@ require 'puppet/util/tagging'
# of the information in the catalog, including the resources
# and the relationships between them.
class Puppet::Resource::Catalog < Puppet::SimpleGraph
- class DuplicateResourceError < Puppet::Error; end
+ class DuplicateResourceError < Puppet::Error; end
- extend Puppet::Indirector
- indirects :catalog, :terminus_setting => :catalog_terminus
+ extend Puppet::Indirector
+ indirects :catalog, :terminus_setting => :catalog_terminus
- include Puppet::Util::Tagging
- extend Puppet::Util::Pson
- include Puppet::Util::Cacher::Expirer
+ include Puppet::Util::Tagging
+ extend Puppet::Util::Pson
+ include Puppet::Util::Cacher::Expirer
- # The host name this is a catalog for.
- attr_accessor :name
+ # The host name this is a catalog for.
+ attr_accessor :name
- # The catalog version. Used for testing whether a catalog
- # is up to date.
- attr_accessor :version
+ # The catalog version. Used for testing whether a catalog
+ # is up to date.
+ attr_accessor :version
- # How long this catalog took to retrieve. Used for reporting stats.
- attr_accessor :retrieval_duration
+ # How long this catalog took to retrieve. Used for reporting stats.
+ attr_accessor :retrieval_duration
- # Whether this is a host catalog, which behaves very differently.
- # In particular, reports are sent, graphs are made, and state is
- # stored in the state database. If this is set incorrectly, then you often
- # end up in infinite loops, because catalogs are used to make things
- # that the host catalog needs.
- attr_accessor :host_config
+ # Whether this is a host catalog, which behaves very differently.
+ # In particular, reports are sent, graphs are made, and state is
+ # stored in the state database. If this is set incorrectly, then you often
+ # end up in infinite loops, because catalogs are used to make things
+ # that the host catalog needs.
+ attr_accessor :host_config
- # Whether this catalog was retrieved from the cache, which affects
- # whether it is written back out again.
- attr_accessor :from_cache
+ # Whether this catalog was retrieved from the cache, which affects
+ # whether it is written back out again.
+ attr_accessor :from_cache
- # Some metadata to help us compile and generally respond to the current state.
- attr_accessor :client_version, :server_version
+ # Some metadata to help us compile and generally respond to the current state.
+ attr_accessor :client_version, :server_version
- # Add classes to our class list.
- def add_class(*classes)
- classes.each do |klass|
- @classes << klass
- end
-
- # Add the class names as tags, too.
- tag(*classes)
+ # Add classes to our class list.
+ def add_class(*classes)
+ classes.each do |klass|
+ @classes << klass
end
- def title_key_for_ref( ref )
- ref =~ /^(.+)\[(.*)\]/
- [$1, $2]
- end
+ # Add the class names as tags, too.
+ tag(*classes)
+ end
- # Add one or more resources to our graph and to our resource table.
- # This is actually a relatively complicated method, because it handles multiple
- # aspects of Catalog behaviour:
- # * Add the resource to the resource table
- # * Add the resource to the resource graph
- # * Add the resource to the relationship graph
- # * Add any aliases that make sense for the resource (e.g., name != title)
- def add_resource(*resources)
- resources.each do |resource|
- raise ArgumentError, "Can only add objects that respond to :ref, not instances of #{resource.class}" unless resource.respond_to?(:ref)
- end.each { |resource| fail_on_duplicate_type_and_title(resource) }.each do |resource|
- title_key = title_key_for_ref(resource.ref)
-
- @transient_resources << resource if applying?
- @resource_table[title_key] = resource
-
- # If the name and title differ, set up an alias
-
- if resource.respond_to?(:name) and resource.respond_to?(:title) and resource.respond_to?(:isomorphic?) and resource.name != resource.title
- self.alias(resource, resource.uniqueness_key) if resource.isomorphic?
- end
+ def title_key_for_ref( ref )
+ ref =~ /^(.+)\[(.*)\]/
+ [$1, $2]
+ end
- resource.catalog = self if resource.respond_to?(:catalog=)
+ # Add one or more resources to our graph and to our resource table.
+ # This is actually a relatively complicated method, because it handles multiple
+ # aspects of Catalog behaviour:
+ # * Add the resource to the resource table
+ # * Add the resource to the resource graph
+ # * Add the resource to the relationship graph
+ # * Add any aliases that make sense for the resource (e.g., name != title)
+ def add_resource(*resources)
+ resources.each do |resource|
+ raise ArgumentError, "Can only add objects that respond to :ref, not instances of #{resource.class}" unless resource.respond_to?(:ref)
+ end.each { |resource| fail_on_duplicate_type_and_title(resource) }.each do |resource|
+ title_key = title_key_for_ref(resource.ref)
- add_vertex(resource)
+ @transient_resources << resource if applying?
+ @resource_table[title_key] = resource
- @relationship_graph.add_vertex(resource) if @relationship_graph
+ # If the name and title differ, set up an alias
- yield(resource) if block_given?
- end
- end
+ if resource.respond_to?(:name) and resource.respond_to?(:title) and resource.respond_to?(:isomorphic?) and resource.name != resource.title
+ self.alias(resource, resource.uniqueness_key) if resource.isomorphic?
+ end
- # Create an alias for a resource.
- def alias(resource, key)
- resource.ref =~ /^(.+)\[/
- class_name = $1 || resource.class.name
+ resource.catalog = self if resource.respond_to?(:catalog=)
- newref = [class_name, key]
+ add_vertex(resource)
- if key.is_a? String
- ref_string = "#{class_name}[#{key}]"
- return if ref_string == resource.ref
- end
+ @relationship_graph.add_vertex(resource) if @relationship_graph
- # LAK:NOTE It's important that we directly compare the references,
- # because sometimes an alias is created before the resource is
- # added to the catalog, so comparing inside the below if block
- # isn't sufficient.
- if existing = @resource_table[newref]
- return if existing == resource
- raise(ArgumentError, "Cannot alias #{resource.ref} to #{key.inspect}; resource #{newref.inspect} already exists")
- end
- @resource_table[newref] = resource
- @aliases[resource.ref] ||= []
- @aliases[resource.ref] << newref
+ yield(resource) if block_given?
end
+ end
- # Apply our catalog to the local host. Valid options
- # are:
- # :tags - set the tags that restrict what resources run
- # during the transaction
- # :ignoreschedules - tell the transaction to ignore schedules
- # when determining the resources to run
- def apply(options = {})
- @applying = true
-
- # Expire all of the resource data -- this ensures that all
- # data we're operating against is entirely current.
- expire
-
- Puppet::Util::Storage.load if host_config?
- transaction = Puppet::Transaction.new(self)
-
- transaction.report = options[:report] if options[:report]
- transaction.tags = options[:tags] if options[:tags]
- transaction.ignoreschedules = true if options[:ignoreschedules]
-
- transaction.add_times :config_retrieval => self.retrieval_duration || 0
-
- begin
- transaction.evaluate
- rescue Puppet::Error => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Could not apply complete catalog: #{detail}"
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Got an uncaught exception of type #{detail.class}: #{detail}"
- ensure
- # Don't try to store state unless we're a host config
- # too recursive.
- Puppet::Util::Storage.store if host_config?
- end
+ # Create an alias for a resource.
+ def alias(resource, key)
+ resource.ref =~ /^(.+)\[/
+ class_name = $1 || resource.class.name
- yield transaction if block_given?
+ newref = [class_name, key]
- return transaction
- ensure
- @applying = false
- cleanup
+ if key.is_a? String
+ ref_string = "#{class_name}[#{key}]"
+ return if ref_string == resource.ref
end
- # Are we in the middle of applying the catalog?
- def applying?
- @applying
+ # LAK:NOTE It's important that we directly compare the references,
+ # because sometimes an alias is created before the resource is
+ # added to the catalog, so comparing inside the below if block
+ # isn't sufficient.
+ if existing = @resource_table[newref]
+ return if existing == resource
+ raise(ArgumentError, "Cannot alias #{resource.ref} to #{key.inspect}; resource #{newref.inspect} already exists")
end
+ @resource_table[newref] = resource
+ @aliases[resource.ref] ||= []
+ @aliases[resource.ref] << newref
+ end
- def clear(remove_resources = true)
- super()
- # We have to do this so that the resources clean themselves up.
- @resource_table.values.each { |resource| resource.remove } if remove_resources
- @resource_table.clear
-
- if @relationship_graph
- @relationship_graph.clear
- @relationship_graph = nil
- end
- end
+ # Apply our catalog to the local host. Valid options
+ # are:
+ # :tags - set the tags that restrict what resources run
+ # during the transaction
+ # :ignoreschedules - tell the transaction to ignore schedules
+ # when determining the resources to run
+ def apply(options = {})
+ @applying = true
- def classes
- @classes.dup
- end
+ # Expire all of the resource data -- this ensures that all
+ # data we're operating against is entirely current.
+ expire
- # Create a new resource and register it in the catalog.
- def create_resource(type, options)
- unless klass = Puppet::Type.type(type)
- raise ArgumentError, "Unknown resource type #{type}"
- end
- return unless resource = klass.new(options)
+ Puppet::Util::Storage.load if host_config?
+ transaction = Puppet::Transaction.new(self)
+
+ transaction.report = options[:report] if options[:report]
+ transaction.tags = options[:tags] if options[:tags]
+ transaction.ignoreschedules = true if options[:ignoreschedules]
- add_resource(resource)
- resource
- end
+ transaction.add_times :config_retrieval => self.retrieval_duration || 0
- def dependent_data_expired?(ts)
- if applying?
- return super
- else
- return true
- end
+ begin
+ transaction.evaluate
+ rescue Puppet::Error => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Could not apply complete catalog: #{detail}"
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Got an uncaught exception of type #{detail.class}: #{detail}"
+ ensure
+ # Don't try to store state unless we're a host config
+ # too recursive.
+ Puppet::Util::Storage.store if host_config?
end
- # Turn our catalog graph into an old-style tree of TransObjects and TransBuckets.
- # LAK:NOTE(20081211): This is a pre-0.25 backward compatibility method.
- # It can be removed as soon as xmlrpc is killed.
- def extract
- top = nil
- current = nil
- buckets = {}
-
- unless main = resource(:stage, "main")
- raise Puppet::DevError, "Could not find 'main' stage; cannot generate catalog"
- end
-
- if stages = vertices.find_all { |v| v.type == "Stage" and v.title != "main" } and ! stages.empty?
- Puppet.warning "Stages are not supported by 0.24.x client; stage(s) #{stages.collect { |s| s.to_s }.join(', ') } will be ignored"
- end
-
- bucket = nil
- walk(main, :out) do |source, target|
- # The sources are always non-builtins.
- unless tmp = buckets[source.to_s]
- if tmp = buckets[source.to_s] = source.to_trans
- bucket = tmp
- else
- # This is because virtual resources return nil. If a virtual
- # container resource contains realized resources, we still need to get
- # to them. So, we keep a reference to the last valid bucket
- # we returned and use that if the container resource is virtual.
- end
- end
- bucket = tmp || bucket
- if child = target.to_trans
- raise "No bucket created for #{source}" unless bucket
- bucket.push child
-
- # It's important that we keep a reference to any TransBuckets we've created, so
- # we don't create multiple buckets for children.
- buckets[target.to_s] = child unless target.builtin?
- end
- end
-
- # Retrieve the bucket for the top-level scope and set the appropriate metadata.
- unless result = buckets[main.to_s]
- # This only happens when the catalog is entirely empty.
- result = buckets[main.to_s] = main.to_trans
- end
-
- result.classes = classes
-
- # Clear the cache to encourage the GC
- buckets.clear
- result
- end
+ yield transaction if block_given?
- # Make sure all of our resources are "finished".
- def finalize
- make_default_resources
+ return transaction
+ ensure
+ @applying = false
+ cleanup
+ end
- @resource_table.values.each { |resource| resource.finish }
+ # Are we in the middle of applying the catalog?
+ def applying?
+ @applying
+ end
- write_graph(:resources)
- end
+ def clear(remove_resources = true)
+ super()
+ # We have to do this so that the resources clean themselves up.
+ @resource_table.values.each { |resource| resource.remove } if remove_resources
+ @resource_table.clear
- def host_config?
- host_config
+ if @relationship_graph
+ @relationship_graph.clear
+ @relationship_graph = nil
end
+ end
- def initialize(name = nil)
- super()
- @name = name if name
- @classes = []
- @resource_table = {}
- @transient_resources = []
- @applying = false
- @relationship_graph = nil
-
- @host_config = true
-
- @aliases = {}
+ def classes
+ @classes.dup
+ end
- if block_given?
- yield(self)
- finalize
- end
+ # Create a new resource and register it in the catalog.
+ def create_resource(type, options)
+ unless klass = Puppet::Type.type(type)
+ raise ArgumentError, "Unknown resource type #{type}"
end
+ return unless resource = klass.new(options)
- # Make the default objects necessary for function.
- def make_default_resources
- # We have to add the resources to the catalog, or else they won't get cleaned up after
- # the transaction.
-
- # First create the default scheduling objects
- Puppet::Type.type(:schedule).mkdefaultschedules.each { |res| add_resource(res) unless resource(res.ref) }
+ add_resource(resource)
+ resource
+ end
- # And filebuckets
- if bucket = Puppet::Type.type(:filebucket).mkdefaultbucket
- add_resource(bucket) unless resource(bucket.ref)
- end
+ def dependent_data_expired?(ts)
+ if applying?
+ return super
+ else
+ return true
end
+ end
- # Create a graph of all of the relationships in our catalog.
- def relationship_graph
- unless @relationship_graph
- # It's important that we assign the graph immediately, because
- # the debug messages below use the relationships in the
- # relationship graph to determine the path to the resources
- # spitting out the messages. If this is not set,
- # then we get into an infinite loop.
- @relationship_graph = Puppet::SimpleGraph.new
-
- # First create the dependency graph
- self.vertices.each do |vertex|
- @relationship_graph.add_vertex vertex
- vertex.builddepends.each do |edge|
- @relationship_graph.add_edge(edge)
- end
- end
-
- # Lastly, add in any autorequires
- @relationship_graph.vertices.each do |vertex|
- vertex.autorequire(self).each do |edge|
- unless @relationship_graph.edge?(edge.source, edge.target) # don't let automatic relationships conflict with manual ones.
- unless @relationship_graph.edge?(edge.target, edge.source)
- vertex.debug "Autorequiring #{edge.source}"
- @relationship_graph.add_edge(edge)
- else
- vertex.debug "Skipping automatic relationship with #{(edge.source == vertex ? edge.target : edge.source)}"
- end
- end
- end
- end
- @relationship_graph.write_graph(:relationships) if host_config?
-
- # Then splice in the container information
- @relationship_graph.splice!(self, Puppet::Type::Component)
+ # Turn our catalog graph into an old-style tree of TransObjects and TransBuckets.
+ # LAK:NOTE(20081211): This is a pre-0.25 backward compatibility method.
+ # It can be removed as soon as xmlrpc is killed.
+ def extract
+ top = nil
+ current = nil
+ buckets = {}
- @relationship_graph.write_graph(:expanded_relationships) if host_config?
- end
- @relationship_graph
+ unless main = resource(:stage, "main")
+ raise Puppet::DevError, "Could not find 'main' stage; cannot generate catalog"
end
- # Remove the resource from our catalog. Notice that we also call
- # 'remove' on the resource, at least until resource classes no longer maintain
- # references to the resource instances.
- def remove_resource(*resources)
- resources.each do |resource|
- @resource_table.delete(resource.ref)
- if aliases = @aliases[resource.ref]
- aliases.each { |res_alias| @resource_table.delete(res_alias) }
- @aliases.delete(resource.ref)
- end
- remove_vertex!(resource) if vertex?(resource)
- @relationship_graph.remove_vertex!(resource) if @relationship_graph and @relationship_graph.vertex?(resource)
- resource.remove
- end
+ if stages = vertices.find_all { |v| v.type == "Stage" and v.title != "main" } and ! stages.empty?
+ Puppet.warning "Stages are not supported by 0.24.x client; stage(s) #{stages.collect { |s| s.to_s }.join(', ') } will be ignored"
end
- # Look a resource up by its reference (e.g., File[/etc/passwd]).
- def resource(type, title = nil)
- # Always create a resource reference, so that it always canonizes how we
- # are referring to them.
- if title
- res = Puppet::Resource.new(type, title)
+ bucket = nil
+ walk(main, :out) do |source, target|
+ # The sources are always non-builtins.
+ unless tmp = buckets[source.to_s]
+ if tmp = buckets[source.to_s] = source.to_trans
+ bucket = tmp
else
- # If they didn't provide a title, then we expect the first
- # argument to be of the form 'Class[name]', which our
- # Reference class canonizes for us.
- res = Puppet::Resource.new(nil, type)
- end
- title_key = [res.type, res.title.to_s]
- uniqueness_key = [res.type, res.uniqueness_key]
- @resource_table[title_key] || @resource_table[uniqueness_key]
- end
-
- def resource_refs
- resource_keys.collect{ |type, name| name.is_a?( String ) ? "#{type}[#{name}]" : nil}.compact
- end
-
- def resource_keys
- @resource_table.keys
- end
-
- def self.from_pson(data)
- result = new(data['name'])
-
- if tags = data['tags']
- result.tag(*tags)
- end
-
- if version = data['version']
- result.version = version
- end
-
- if resources = data['resources']
- resources = PSON.parse(resources) if resources.is_a?(String)
- resources.each do |res|
- resource_from_pson(result, res)
- end
- end
-
- if edges = data['edges']
- edges = PSON.parse(edges) if edges.is_a?(String)
- edges.each do |edge|
- edge_from_pson(result, edge)
- end
- end
-
- if classes = data['classes']
- result.add_class(*classes)
- end
-
- result
- end
-
- def self.edge_from_pson(result, edge)
- # If no type information was presented, we manually find
- # the class.
- edge = Puppet::Relationship.from_pson(edge) if edge.is_a?(Hash)
- unless source = result.resource(edge.source)
- raise ArgumentError, "Could not convert from pson: Could not find relationship source #{edge.source.inspect}"
- end
- edge.source = source
-
- unless target = result.resource(edge.target)
- raise ArgumentError, "Could not convert from pson: Could not find relationship target #{edge.target.inspect}"
+ # This is because virtual resources return nil. If a virtual
+ # container resource contains realized resources, we still need to get
+ # to them. So, we keep a reference to the last valid bucket
+ # we returned and use that if the container resource is virtual.
end
- edge.target = target
+ end
+ bucket = tmp || bucket
+ if child = target.to_trans
+ raise "No bucket created for #{source}" unless bucket
+ bucket.push child
- result.add_edge(edge)
+ # It's important that we keep a reference to any TransBuckets we've created, so
+ # we don't create multiple buckets for children.
+ buckets[target.to_s] = child unless target.builtin?
+ end
end
- def self.resource_from_pson(result, res)
- res = Puppet::Resource.from_pson(res) if res.is_a? Hash
- result.add_resource(res)
+ # Retrieve the bucket for the top-level scope and set the appropriate metadata.
+ unless result = buckets[main.to_s]
+ # This only happens when the catalog is entirely empty.
+ result = buckets[main.to_s] = main.to_trans
end
- PSON.register_document_type('Catalog',self)
- def to_pson_data_hash
- {
- 'document_type' => 'Catalog',
- 'data' => {
- 'tags' => tags,
- 'name' => name,
- 'version' => version,
- 'resources' => vertices.collect { |v| v.to_pson_data_hash },
- 'edges' => edges. collect { |e| e.to_pson_data_hash },
- 'classes' => classes
- },
- 'metadata' => {
- 'api_version' => 1
- }
- }
- end
+ result.classes = classes
- def to_pson(*args)
- to_pson_data_hash.to_pson(*args)
- end
+ # Clear the cache to encourage the GC
+ buckets.clear
+ result
+ end
- # Convert our catalog into a RAL catalog.
- def to_ral
- to_catalog :to_ral
- end
+ # Make sure all of our resources are "finished".
+ def finalize
+ make_default_resources
- # Convert our catalog into a catalog of Puppet::Resource instances.
- def to_resource
- to_catalog :to_resource
- end
+ @resource_table.values.each { |resource| resource.finish }
- # filter out the catalog, applying +block+ to each resource.
- # If the block result is false, the resource will
- # be kept otherwise it will be skipped
- def filter(&block)
- to_catalog :to_resource, &block
- end
+ write_graph(:resources)
+ end
- # Store the classes in the classfile.
- def write_class_file
- ::File.open(Puppet[:classfile], "w") do |f|
- f.puts classes.join("\n")
- end
- rescue => detail
- Puppet.err "Could not create class file #{Puppet[:classfile]}: #{detail}"
- end
+ def host_config?
+ host_config
+ end
- # Produce the graph files if requested.
- def write_graph(name)
- # We only want to graph the main host catalog.
- return unless host_config?
+ def initialize(name = nil)
+ super()
+ @name = name if name
+ @classes = []
+ @resource_table = {}
+ @transient_resources = []
+ @applying = false
+ @relationship_graph = nil
- super
- end
+ @host_config = true
- private
+ @aliases = {}
- def cleanup
- # Expire any cached data the resources are keeping.
- expire
+ if block_given?
+ yield(self)
+ finalize
end
+ end
- # Verify that the given resource isn't defined elsewhere.
- def fail_on_duplicate_type_and_title(resource)
- # Short-curcuit the common case,
- return unless existing_resource = @resource_table[title_key_for_ref(resource.ref)]
-
- # If we've gotten this far, it's a real conflict
- msg = "Duplicate definition: #{resource.ref} is already defined"
+ # Make the default objects necessary for function.
+ def make_default_resources
+ # We have to add the resources to the catalog, or else they won't get cleaned up after
+ # the transaction.
- msg << " in file #{existing_resource.file} at line #{existing_resource.line}" if existing_resource.file and existing_resource.line
+ # First create the default scheduling objects
+ Puppet::Type.type(:schedule).mkdefaultschedules.each { |res| add_resource(res) unless resource(res.ref) }
- msg << "; cannot redefine" if resource.line or resource.file
-
- raise DuplicateResourceError.new(msg)
+ # And filebuckets
+ if bucket = Puppet::Type.type(:filebucket).mkdefaultbucket
+ add_resource(bucket) unless resource(bucket.ref)
end
+ end
- # An abstracted method for converting one catalog into another type of catalog.
- # This pretty much just converts all of the resources from one class to another, using
- # a conversion method.
- def to_catalog(convert)
- result = self.class.new(self.name)
-
- result.version = self.version
-
- map = {}
- vertices.each do |resource|
- next if virtual_not_exported?(resource)
- next if block_given? and yield resource
-
- #This is hackity hack for 1094
- #Aliases aren't working in the ral catalog because the current instance of the resource
- #has a reference to the catalog being converted. . . So, give it a reference to the new one
- #problem solved. . .
- if resource.class == Puppet::Resource
- resource = resource.dup
- resource.catalog = result
- elsif resource.is_a?(Puppet::TransObject)
- resource = resource.dup
- resource.catalog = result
- elsif resource.is_a?(Puppet::Parser::Resource)
- resource = resource.to_resource
- resource.catalog = result
- end
+ # Create a graph of all of the relationships in our catalog.
+ def relationship_graph
+ unless @relationship_graph
+ # It's important that we assign the graph immediately, because
+ # the debug messages below use the relationships in the
+ # relationship graph to determine the path to the resources
+ # spitting out the messages. If this is not set,
+ # then we get into an infinite loop.
+ @relationship_graph = Puppet::SimpleGraph.new
- if resource.is_a?(Puppet::Resource) and convert.to_s == "to_resource"
- newres = resource
+ # First create the dependency graph
+ self.vertices.each do |vertex|
+ @relationship_graph.add_vertex vertex
+ vertex.builddepends.each do |edge|
+ @relationship_graph.add_edge(edge)
+ end
+ end
+
+ # Lastly, add in any autorequires
+ @relationship_graph.vertices.each do |vertex|
+ vertex.autorequire(self).each do |edge|
+ unless @relationship_graph.edge?(edge.source, edge.target) # don't let automatic relationships conflict with manual ones.
+ unless @relationship_graph.edge?(edge.target, edge.source)
+ vertex.debug "Autorequiring #{edge.source}"
+ @relationship_graph.add_edge(edge)
else
- newres = resource.send(convert)
+ vertex.debug "Skipping automatic relationship with #{(edge.source == vertex ? edge.target : edge.source)}"
end
-
- # We can't guarantee that resources don't munge their names
- # (like files do with trailing slashes), so we have to keep track
- # of what a resource got converted to.
- map[resource.ref] = newres
-
- result.add_resource newres
+ end
end
+ end
+ @relationship_graph.write_graph(:relationships) if host_config?
- message = convert.to_s.gsub "_", " "
- edges.each do |edge|
- # Skip edges between virtual resources.
- next if virtual_not_exported?(edge.source)
- next if block_given? and yield edge.source
-
- next if virtual_not_exported?(edge.target)
- next if block_given? and yield edge.target
+ # Then splice in the container information
+ @relationship_graph.splice!(self, Puppet::Type::Component)
- unless source = map[edge.source.ref]
- raise Puppet::DevError, "Could not find resource #{edge.source.ref} when converting #{message} resources"
- end
-
- unless target = map[edge.target.ref]
- raise Puppet::DevError, "Could not find resource #{edge.target.ref} when converting #{message} resources"
- end
+ @relationship_graph.write_graph(:expanded_relationships) if host_config?
+ end
+ @relationship_graph
+ end
- result.add_edge(source, target, edge.label)
- end
+ # Remove the resource from our catalog. Notice that we also call
+ # 'remove' on the resource, at least until resource classes no longer maintain
+ # references to the resource instances.
+ def remove_resource(*resources)
+ resources.each do |resource|
+ @resource_table.delete(resource.ref)
+ if aliases = @aliases[resource.ref]
+ aliases.each { |res_alias| @resource_table.delete(res_alias) }
+ @aliases.delete(resource.ref)
+ end
+ remove_vertex!(resource) if vertex?(resource)
+ @relationship_graph.remove_vertex!(resource) if @relationship_graph and @relationship_graph.vertex?(resource)
+ resource.remove
+ end
+ end
+
+ # Look a resource up by its reference (e.g., File[/etc/passwd]).
+ def resource(type, title = nil)
+ # Always create a resource reference, so that it always canonizes how we
+ # are referring to them.
+ if title
+ res = Puppet::Resource.new(type, title)
+ else
+ # If they didn't provide a title, then we expect the first
+ # argument to be of the form 'Class[name]', which our
+ # Reference class canonizes for us.
+ res = Puppet::Resource.new(nil, type)
+ end
+ title_key = [res.type, res.title.to_s]
+ uniqueness_key = [res.type, res.uniqueness_key]
+ @resource_table[title_key] || @resource_table[uniqueness_key]
+ end
+
+ def resource_refs
+ resource_keys.collect{ |type, name| name.is_a?( String ) ? "#{type}[#{name}]" : nil}.compact
+ end
+
+ def resource_keys
+ @resource_table.keys
+ end
+
+ def self.from_pson(data)
+ result = new(data['name'])
+
+ if tags = data['tags']
+ result.tag(*tags)
+ end
+
+ if version = data['version']
+ result.version = version
+ end
+
+ if resources = data['resources']
+ resources = PSON.parse(resources) if resources.is_a?(String)
+ resources.each do |res|
+ resource_from_pson(result, res)
+ end
+ end
+
+ if edges = data['edges']
+ edges = PSON.parse(edges) if edges.is_a?(String)
+ edges.each do |edge|
+ edge_from_pson(result, edge)
+ end
+ end
+
+ if classes = data['classes']
+ result.add_class(*classes)
+ end
+
+ result
+ end
+
+ def self.edge_from_pson(result, edge)
+ # If no type information was presented, we manually find
+ # the class.
+ edge = Puppet::Relationship.from_pson(edge) if edge.is_a?(Hash)
+ unless source = result.resource(edge.source)
+ raise ArgumentError, "Could not convert from pson: Could not find relationship source #{edge.source.inspect}"
+ end
+ edge.source = source
+
+ unless target = result.resource(edge.target)
+ raise ArgumentError, "Could not convert from pson: Could not find relationship target #{edge.target.inspect}"
+ end
+ edge.target = target
+
+ result.add_edge(edge)
+ end
+
+ def self.resource_from_pson(result, res)
+ res = Puppet::Resource.from_pson(res) if res.is_a? Hash
+ result.add_resource(res)
+ end
+
+ PSON.register_document_type('Catalog',self)
+ def to_pson_data_hash
+ {
+ 'document_type' => 'Catalog',
+ 'data' => {
+ 'tags' => tags,
+ 'name' => name,
+ 'version' => version,
+ 'resources' => vertices.collect { |v| v.to_pson_data_hash },
+ 'edges' => edges. collect { |e| e.to_pson_data_hash },
+ 'classes' => classes
+ },
+ 'metadata' => {
+ 'api_version' => 1
+ }
+ }
+ end
+
+ def to_pson(*args)
+ to_pson_data_hash.to_pson(*args)
+ end
+
+ # Convert our catalog into a RAL catalog.
+ def to_ral
+ to_catalog :to_ral
+ end
+
+ # Convert our catalog into a catalog of Puppet::Resource instances.
+ def to_resource
+ to_catalog :to_resource
+ end
+
+ # filter out the catalog, applying +block+ to each resource.
+ # If the block result is false, the resource will
+ # be kept otherwise it will be skipped
+ def filter(&block)
+ to_catalog :to_resource, &block
+ end
+
+ # Store the classes in the classfile.
+ def write_class_file
+ ::File.open(Puppet[:classfile], "w") do |f|
+ f.puts classes.join("\n")
+ end
+ rescue => detail
+ Puppet.err "Could not create class file #{Puppet[:classfile]}: #{detail}"
+ end
+
+ # Produce the graph files if requested.
+ def write_graph(name)
+ # We only want to graph the main host catalog.
+ return unless host_config?
+
+ super
+ end
+
+ private
+
+ def cleanup
+ # Expire any cached data the resources are keeping.
+ expire
+ end
+
+ # Verify that the given resource isn't defined elsewhere.
+ def fail_on_duplicate_type_and_title(resource)
+ # Short-curcuit the common case,
+ return unless existing_resource = @resource_table[title_key_for_ref(resource.ref)]
+
+ # If we've gotten this far, it's a real conflict
+ msg = "Duplicate definition: #{resource.ref} is already defined"
+
+ msg << " in file #{existing_resource.file} at line #{existing_resource.line}" if existing_resource.file and existing_resource.line
+
+ msg << "; cannot redefine" if resource.line or resource.file
+
+ raise DuplicateResourceError.new(msg)
+ end
+
+ # An abstracted method for converting one catalog into another type of catalog.
+ # This pretty much just converts all of the resources from one class to another, using
+ # a conversion method.
+ def to_catalog(convert)
+ result = self.class.new(self.name)
+
+ result.version = self.version
+
+ map = {}
+ vertices.each do |resource|
+ next if virtual_not_exported?(resource)
+ next if block_given? and yield resource
+
+ #This is hackity hack for 1094
+ #Aliases aren't working in the ral catalog because the current instance of the resource
+ #has a reference to the catalog being converted. . . So, give it a reference to the new one
+ #problem solved. . .
+ if resource.class == Puppet::Resource
+ resource = resource.dup
+ resource.catalog = result
+ elsif resource.is_a?(Puppet::TransObject)
+ resource = resource.dup
+ resource.catalog = result
+ elsif resource.is_a?(Puppet::Parser::Resource)
+ resource = resource.to_resource
+ resource.catalog = result
+ end
+
+ if resource.is_a?(Puppet::Resource) and convert.to_s == "to_resource"
+ newres = resource
+ else
+ newres = resource.send(convert)
+ end
+
+ # We can't guarantee that resources don't munge their names
+ # (like files do with trailing slashes), so we have to keep track
+ # of what a resource got converted to.
+ map[resource.ref] = newres
+
+ result.add_resource newres
+ end
+
+ message = convert.to_s.gsub "_", " "
+ edges.each do |edge|
+ # Skip edges between virtual resources.
+ next if virtual_not_exported?(edge.source)
+ next if block_given? and yield edge.source
+
+ next if virtual_not_exported?(edge.target)
+ next if block_given? and yield edge.target
+
+ unless source = map[edge.source.ref]
+ raise Puppet::DevError, "Could not find resource #{edge.source.ref} when converting #{message} resources"
+ end
+
+ unless target = map[edge.target.ref]
+ raise Puppet::DevError, "Could not find resource #{edge.target.ref} when converting #{message} resources"
+ end
- map.clear
+ result.add_edge(source, target, edge.label)
+ end
+
+ map.clear
- result.add_class(*self.classes)
- result.tag(*self.tags)
+ result.add_class(*self.classes)
+ result.tag(*self.tags)
- result
- end
+ result
+ end
- def virtual_not_exported?(resource)
- resource.respond_to?(:virtual?) and resource.virtual? and (resource.respond_to?(:exported?) and not resource.exported?)
- end
+ def virtual_not_exported?(resource)
+ resource.respond_to?(:virtual?) and resource.virtual? and (resource.respond_to?(:exported?) and not resource.exported?)
+ end
end
diff --git a/lib/puppet/resource/status.rb b/lib/puppet/resource/status.rb
index a52b927..2bdfbbf 100644
--- a/lib/puppet/resource/status.rb
+++ b/lib/puppet/resource/status.rb
@@ -1,58 +1,58 @@
module Puppet
- class Resource
- class Status
- include Puppet::Util::Tagging
- include Puppet::Util::Logging
-
- ATTRIBUTES = [:resource, :node, :version, :file, :line, :current_values, :skipped_reason, :status, :evaluation_time, :change_count]
- attr_accessor *ATTRIBUTES
-
- STATES = [:skipped, :failed, :failed_to_restart, :restarted, :changed, :out_of_sync, :scheduled]
- attr_accessor *STATES
-
- attr_reader :source_description, :default_log_level, :time, :resource
-
- # Provide a boolean method for each of the states.
- STATES.each do |attr|
- define_method("#{attr}?") do
- !! send(attr)
- end
- end
-
- def <<(event)
- add_event(event)
- self
- end
-
- def add_event(event)
- @events << event
- if event.status == 'failure'
- self.failed = true
- end
- end
-
- def events
- @events
- end
-
- def initialize(resource)
- @source_description = resource.path
- @resource = resource.to_s
-
- [:file, :line, :version].each do |attr|
- send(attr.to_s + "=", resource.send(attr))
- end
-
- tag(*resource.tags)
- @time = Time.now
- @events = []
- end
-
- private
-
- def log_source
- source_description
- end
+ class Resource
+ class Status
+ include Puppet::Util::Tagging
+ include Puppet::Util::Logging
+
+ ATTRIBUTES = [:resource, :node, :version, :file, :line, :current_values, :skipped_reason, :status, :evaluation_time, :change_count]
+ attr_accessor *ATTRIBUTES
+
+ STATES = [:skipped, :failed, :failed_to_restart, :restarted, :changed, :out_of_sync, :scheduled]
+ attr_accessor *STATES
+
+ attr_reader :source_description, :default_log_level, :time, :resource
+
+ # Provide a boolean method for each of the states.
+ STATES.each do |attr|
+ define_method("#{attr}?") do
+ !! send(attr)
+ end
+ end
+
+ def <<(event)
+ add_event(event)
+ self
+ end
+
+ def add_event(event)
+ @events << event
+ if event.status == 'failure'
+ self.failed = true
end
+ end
+
+ def events
+ @events
+ end
+
+ def initialize(resource)
+ @source_description = resource.path
+ @resource = resource.to_s
+
+ [:file, :line, :version].each do |attr|
+ send(attr.to_s + "=", resource.send(attr))
+ end
+
+ tag(*resource.tags)
+ @time = Time.now
+ @events = []
+ end
+
+ private
+
+ def log_source
+ source_description
+ end
end
+ end
end
diff --git a/lib/puppet/resource/type.rb b/lib/puppet/resource/type.rb
index 572a4f8..c2b4271 100644
--- a/lib/puppet/resource/type.rb
+++ b/lib/puppet/resource/type.rb
@@ -6,298 +6,298 @@ require 'puppet/parser/ast/leaf'
require 'puppet/dsl'
class Puppet::Resource::Type
- Puppet::ResourceType = self
- include Puppet::Util::InlineDocs
- include Puppet::Util::Warnings
- include Puppet::Util::Errors
+ Puppet::ResourceType = self
+ include Puppet::Util::InlineDocs
+ include Puppet::Util::Warnings
+ include Puppet::Util::Errors
- RESOURCE_SUPERTYPES = [:hostclass, :node, :definition]
+ RESOURCE_SUPERTYPES = [:hostclass, :node, :definition]
- attr_accessor :file, :line, :doc, :code, :ruby_code, :parent, :resource_type_collection, :module_name
- attr_reader :type, :namespace, :arguments, :behaves_like
+ attr_accessor :file, :line, :doc, :code, :ruby_code, :parent, :resource_type_collection, :module_name
+ attr_reader :type, :namespace, :arguments, :behaves_like
- RESOURCE_SUPERTYPES.each do |t|
- define_method("#{t}?") { self.type == t }
- end
-
- require 'puppet/indirector'
- extend Puppet::Indirector
- indirects :resource_type, :terminus_class => :parser
+ RESOURCE_SUPERTYPES.each do |t|
+ define_method("#{t}?") { self.type == t }
+ end
- def self.from_pson(data)
- name = data.delete('name') or raise ArgumentError, "Resource Type names must be specified"
- type = data.delete('type') || "definition"
+ require 'puppet/indirector'
+ extend Puppet::Indirector
+ indirects :resource_type, :terminus_class => :parser
- data = data.inject({}) { |result, ary| result[ary[0].intern] = ary[1]; result }
-
- new(type, name, data)
- end
+ def self.from_pson(data)
+ name = data.delete('name') or raise ArgumentError, "Resource Type names must be specified"
+ type = data.delete('type') || "definition"
- def to_pson_data_hash
- data = [:code, :doc, :line, :file, :parent].inject({}) do |hash, param|
- next hash unless value = self.send(param)
- hash[param.to_s] = value
- hash
- end
+ data = data.inject({}) { |result, ary| result[ary[0].intern] = ary[1]; result }
- data['arguments'] = arguments.dup
+ new(type, name, data)
+ end
- data['name'] = name
- data['type'] = type
-
- data
+ def to_pson_data_hash
+ data = [:code, :doc, :line, :file, :parent].inject({}) do |hash, param|
+ next hash unless value = self.send(param)
+ hash[param.to_s] = value
+ hash
end
- def to_pson(*args)
- to_pson_data_hash.to_pson(*args)
- end
+ data['arguments'] = arguments.dup
- # Are we a child of the passed class? Do a recursive search up our
- # parentage tree to figure it out.
- def child_of?(klass)
- return false unless parent
+ data['name'] = name
+ data['type'] = type
- return(klass == parent_type ? true : parent_type.child_of?(klass))
- end
+ data
+ end
- # Now evaluate the code associated with this class or definition.
- def evaluate_code(resource)
- scope = resource.scope
+ def to_pson(*args)
+ to_pson_data_hash.to_pson(*args)
+ end
- if tmp = evaluate_parent_type(resource)
- scope = tmp
- end
+ # Are we a child of the passed class? Do a recursive search up our
+ # parentage tree to figure it out.
+ def child_of?(klass)
+ return false unless parent
- scope = subscope(scope, resource) unless resource.title == :main
+ return(klass == parent_type ? true : parent_type.child_of?(klass))
+ end
- set_resource_parameters(resource, scope)
+ # Now evaluate the code associated with this class or definition.
+ def evaluate_code(resource)
+ scope = resource.scope
- code.safeevaluate(scope) if code
-
- evaluate_ruby_code(resource, scope) if ruby_code
+ if tmp = evaluate_parent_type(resource)
+ scope = tmp
end
- def initialize(type, name, options = {})
- @type = type.to_s.downcase.to_sym
- raise ArgumentError, "Invalid resource supertype '#{type}'" unless RESOURCE_SUPERTYPES.include?(@type)
-
- name = convert_from_ast(name) if name.is_a?(Puppet::Parser::AST::HostName)
-
- set_name_and_namespace(name)
+ scope = subscope(scope, resource) unless resource.title == :main
- [:code, :doc, :line, :file, :parent].each do |param|
- next unless value = options[param]
- send(param.to_s + "=", value)
- end
+ set_resource_parameters(resource, scope)
- set_arguments(options[:arguments])
- end
+ code.safeevaluate(scope) if code
- # This is only used for node names, and really only when the node name
- # is a regexp.
- def match(string)
- return string.to_s.downcase == name unless name_is_regex?
+ evaluate_ruby_code(resource, scope) if ruby_code
+ end
- @name =~ string
- end
+ def initialize(type, name, options = {})
+ @type = type.to_s.downcase.to_sym
+ raise ArgumentError, "Invalid resource supertype '#{type}'" unless RESOURCE_SUPERTYPES.include?(@type)
- # Add code from a new instance to our code.
- def merge(other)
- fail "#{name} is not a class; cannot add code to it" unless type == :hostclass
- fail "#{other.name} is not a class; cannot add code from it" unless other.type == :hostclass
- fail "Cannot have code outside of a class/node/define because 'freeze_main' is enabled" if name == "" and Puppet.settings[:freeze_main]
+ name = convert_from_ast(name) if name.is_a?(Puppet::Parser::AST::HostName)
- if parent and other.parent and parent != other.parent
- fail "Cannot merge classes with different parent classes (#{name} => #{parent} vs. #{other.name} => #{other.parent})"
- end
+ set_name_and_namespace(name)
- # We know they're either equal or only one is set, so keep whichever parent is specified.
- self.parent ||= other.parent
+ [:code, :doc, :line, :file, :parent].each do |param|
+ next unless value = options[param]
+ send(param.to_s + "=", value)
+ end
- if other.doc
- self.doc ||= ""
- self.doc += other.doc
- end
+ set_arguments(options[:arguments])
+ end
- # This might just be an empty, stub class.
- return unless other.code
+ # This is only used for node names, and really only when the node name
+ # is a regexp.
+ def match(string)
+ return string.to_s.downcase == name unless name_is_regex?
- unless self.code
- self.code = other.code
- return
- end
+ @name =~ string
+ end
- array_class = Puppet::Parser::AST::ASTArray
- self.code = array_class.new(:children => [self.code]) unless self.code.is_a?(array_class)
+ # Add code from a new instance to our code.
+ def merge(other)
+ fail "#{name} is not a class; cannot add code to it" unless type == :hostclass
+ fail "#{other.name} is not a class; cannot add code from it" unless other.type == :hostclass
+ fail "Cannot have code outside of a class/node/define because 'freeze_main' is enabled" if name == "" and Puppet.settings[:freeze_main]
- if other.code.is_a?(array_class)
- code.children += other.code.children
- else
- code.children << other.code
- end
+ if parent and other.parent and parent != other.parent
+ fail "Cannot merge classes with different parent classes (#{name} => #{parent} vs. #{other.name} => #{other.parent})"
end
- # Make an instance of our resource type. This is only possible
- # for those classes and nodes that don't have any arguments, and is
- # only useful for things like the 'include' function.
- def mk_plain_resource(scope)
- type == :definition and raise ArgumentError, "Cannot create resources for defined resource types"
- resource_type = type == :hostclass ? :class : :node
-
- # Make sure our parent class has been evaluated, if we have one.
- parent_type.mk_plain_resource(scope) if parent and ! scope.catalog.resource(resource_type, parent)
-
- # Do nothing if the resource already exists; this makes sure we don't
- # get multiple copies of the class resource, which helps provide the
- # singleton nature of classes.
- if resource = scope.catalog.resource(resource_type, name)
- return resource
- end
-
- resource = Puppet::Parser::Resource.new(resource_type, name, :scope => scope, :source => self)
- scope.compiler.add_resource(scope, resource)
- scope.catalog.tag(*resource.tags)
- resource
- end
+ # We know they're either equal or only one is set, so keep whichever parent is specified.
+ self.parent ||= other.parent
- def name
- return @name unless @name.is_a?(Regexp)
- @name.source.downcase.gsub(/[^-\w:.]/,'').sub(/^\.+/,'')
+ if other.doc
+ self.doc ||= ""
+ self.doc += other.doc
end
- def name_is_regex?
- @name.is_a?(Regexp)
- end
+ # This might just be an empty, stub class.
+ return unless other.code
- def parent_type
- return nil unless parent
+ unless self.code
+ self.code = other.code
+ return
+ end
- unless @parent_type ||= resource_type_collection.send(type, parent)
- fail Puppet::ParseError, "Could not find parent resource type '#{parent}' of type #{type}"
- end
+ array_class = Puppet::Parser::AST::ASTArray
+ self.code = array_class.new(:children => [self.code]) unless self.code.is_a?(array_class)
- @parent_type
+ if other.code.is_a?(array_class)
+ code.children += other.code.children
+ else
+ code.children << other.code
+ end
+ end
+
+ # Make an instance of our resource type. This is only possible
+ # for those classes and nodes that don't have any arguments, and is
+ # only useful for things like the 'include' function.
+ def mk_plain_resource(scope)
+ type == :definition and raise ArgumentError, "Cannot create resources for defined resource types"
+ resource_type = type == :hostclass ? :class : :node
+
+ # Make sure our parent class has been evaluated, if we have one.
+ parent_type.mk_plain_resource(scope) if parent and ! scope.catalog.resource(resource_type, parent)
+
+ # Do nothing if the resource already exists; this makes sure we don't
+ # get multiple copies of the class resource, which helps provide the
+ # singleton nature of classes.
+ if resource = scope.catalog.resource(resource_type, name)
+ return resource
end
- # Set any arguments passed by the resource as variables in the scope.
- def set_resource_parameters(resource, scope)
- set = {}
- resource.to_hash.each do |param, value|
- param = param.to_sym
- fail Puppet::ParseError, "#{resource.ref} does not accept attribute #{param}" unless valid_parameter?(param)
+ resource = Puppet::Parser::Resource.new(resource_type, name, :scope => scope, :source => self)
+ scope.compiler.add_resource(scope, resource)
+ scope.catalog.tag(*resource.tags)
+ resource
+ end
- exceptwrap { scope.setvar(param.to_s, value) }
+ def name
+ return @name unless @name.is_a?(Regexp)
+ @name.source.downcase.gsub(/[^-\w:.]/,'').sub(/^\.+/,'')
+ end
- set[param] = true
- end
+ def name_is_regex?
+ @name.is_a?(Regexp)
+ end
- # Verify that all required arguments are either present or
- # have been provided with defaults.
- arguments.each do |param, default|
- param = param.to_sym
- next if set.include?(param)
+ def parent_type
+ return nil unless parent
- # Even if 'default' is a false value, it's an AST value, so this works fine
- fail Puppet::ParseError, "Must pass #{param} to #{resource.ref}" unless default
+ unless @parent_type ||= resource_type_collection.send(type, parent)
+ fail Puppet::ParseError, "Could not find parent resource type '#{parent}' of type #{type}"
+ end
- value = default.safeevaluate(scope)
- scope.setvar(param.to_s, value)
+ @parent_type
+ end
- # Set it in the resource, too, so the value makes it to the client.
- resource[param] = value
- end
+ # Set any arguments passed by the resource as variables in the scope.
+ def set_resource_parameters(resource, scope)
+ set = {}
+ resource.to_hash.each do |param, value|
+ param = param.to_sym
+ fail Puppet::ParseError, "#{resource.ref} does not accept attribute #{param}" unless valid_parameter?(param)
- scope.setvar("title", resource.title) unless set.include? :title
- scope.setvar("name", resource.name) unless set.include? :name
- scope.setvar("module_name", module_name) if module_name and ! set.include? :module_name
+ exceptwrap { scope.setvar(param.to_s, value) }
- if caller_name = scope.parent_module_name and ! set.include?(:caller_module_name)
- scope.setvar("caller_module_name", caller_name)
- end
- scope.class_set(self.name,scope) if hostclass? or node?
+ set[param] = true
end
- # Create a new subscope in which to evaluate our code.
- def subscope(scope, resource)
- scope.newscope :resource => resource, :namespace => self.namespace, :source => self
- end
+ # Verify that all required arguments are either present or
+ # have been provided with defaults.
+ arguments.each do |param, default|
+ param = param.to_sym
+ next if set.include?(param)
- # Check whether a given argument is valid.
- def valid_parameter?(param)
- param = param.to_s
+ # Even if 'default' is a false value, it's an AST value, so this works fine
+ fail Puppet::ParseError, "Must pass #{param} to #{resource.ref}" unless default
- return true if param == "name"
- return true if Puppet::Type.metaparam?(param)
- return false unless defined?(@arguments)
- return(arguments.include?(param) ? true : false)
- end
+ value = default.safeevaluate(scope)
+ scope.setvar(param.to_s, value)
- def set_arguments(arguments)
- @arguments = {}
- return if arguments.nil?
-
- arguments.each do |arg, default|
- arg = arg.to_s
- warn_if_metaparam(arg, default)
- @arguments[arg] = default
- end
+ # Set it in the resource, too, so the value makes it to the client.
+ resource[param] = value
end
- private
-
- def convert_from_ast(name)
- value = name.value
- if value.is_a?(Puppet::Parser::AST::Regex)
- name = value.value
- else
- name = value
- end
- end
+ scope.setvar("title", resource.title) unless set.include? :title
+ scope.setvar("name", resource.name) unless set.include? :name
+ scope.setvar("module_name", module_name) if module_name and ! set.include? :module_name
- def evaluate_parent_type(resource)
- return unless klass = parent_type and parent_resource = resource.scope.compiler.catalog.resource(:class, klass.name) || resource.scope.compiler.catalog.resource(:node, klass.name)
- parent_resource.evaluate unless parent_resource.evaluated?
- parent_scope(resource.scope, klass)
+ if caller_name = scope.parent_module_name and ! set.include?(:caller_module_name)
+ scope.setvar("caller_module_name", caller_name)
end
-
- def evaluate_ruby_code(resource, scope)
- Puppet::DSL::ResourceAPI.new(resource, scope, ruby_code).evaluate
+ scope.class_set(self.name,scope) if hostclass? or node?
+ end
+
+ # Create a new subscope in which to evaluate our code.
+ def subscope(scope, resource)
+ scope.newscope :resource => resource, :namespace => self.namespace, :source => self
+ end
+
+ # Check whether a given argument is valid.
+ def valid_parameter?(param)
+ param = param.to_s
+
+ return true if param == "name"
+ return true if Puppet::Type.metaparam?(param)
+ return false unless defined?(@arguments)
+ return(arguments.include?(param) ? true : false)
+ end
+
+ def set_arguments(arguments)
+ @arguments = {}
+ return if arguments.nil?
+
+ arguments.each do |arg, default|
+ arg = arg.to_s
+ warn_if_metaparam(arg, default)
+ @arguments[arg] = default
end
+ end
- # Split an fq name into a namespace and name
- def namesplit(fullname)
- ary = fullname.split("::")
- n = ary.pop || ""
- ns = ary.join("::")
- return ns, n
- end
+ private
- def parent_scope(scope, klass)
- scope.class_scope(klass) || raise(Puppet::DevError, "Could not find scope for #{klass.name}")
+ def convert_from_ast(name)
+ value = name.value
+ if value.is_a?(Puppet::Parser::AST::Regex)
+ name = value.value
+ else
+ name = value
end
-
- def set_name_and_namespace(name)
- if name.is_a?(Regexp)
- @name = name
- @namespace = ""
- else
- @name = name.to_s.downcase
-
- # Note we're doing something somewhat weird here -- we're setting
- # the class's namespace to its fully qualified name. This means
- # anything inside that class starts looking in that namespace first.
- @namespace, ignored_shortname = @type == :hostclass ? [@name, ''] : namesplit(@name)
- end
+ end
+
+ def evaluate_parent_type(resource)
+ return unless klass = parent_type and parent_resource = resource.scope.compiler.catalog.resource(:class, klass.name) || resource.scope.compiler.catalog.resource(:node, klass.name)
+ parent_resource.evaluate unless parent_resource.evaluated?
+ parent_scope(resource.scope, klass)
+ end
+
+ def evaluate_ruby_code(resource, scope)
+ Puppet::DSL::ResourceAPI.new(resource, scope, ruby_code).evaluate
+ end
+
+ # Split an fq name into a namespace and name
+ def namesplit(fullname)
+ ary = fullname.split("::")
+ n = ary.pop || ""
+ ns = ary.join("::")
+ return ns, n
+ end
+
+ def parent_scope(scope, klass)
+ scope.class_scope(klass) || raise(Puppet::DevError, "Could not find scope for #{klass.name}")
+ end
+
+ def set_name_and_namespace(name)
+ if name.is_a?(Regexp)
+ @name = name
+ @namespace = ""
+ else
+ @name = name.to_s.downcase
+
+ # Note we're doing something somewhat weird here -- we're setting
+ # the class's namespace to its fully qualified name. This means
+ # anything inside that class starts looking in that namespace first.
+ @namespace, ignored_shortname = @type == :hostclass ? [@name, ''] : namesplit(@name)
end
+ end
- def warn_if_metaparam(param, default)
- return unless Puppet::Type.metaparamclass(param)
+ def warn_if_metaparam(param, default)
+ return unless Puppet::Type.metaparamclass(param)
- if default
- warnonce "#{param} is a metaparam; this value will inherit to all contained resources"
- else
- raise Puppet::ParseError, "#{param} is a metaparameter; please choose another parameter name in the #{self.name} definition"
- end
+ if default
+ warnonce "#{param} is a metaparam; this value will inherit to all contained resources"
+ else
+ raise Puppet::ParseError, "#{param} is a metaparameter; please choose another parameter name in the #{self.name} definition"
end
+ end
end
diff --git a/lib/puppet/resource/type_collection.rb b/lib/puppet/resource/type_collection.rb
index 39883ac..58e8b94 100644
--- a/lib/puppet/resource/type_collection.rb
+++ b/lib/puppet/resource/type_collection.rb
@@ -1,221 +1,221 @@
class Puppet::Resource::TypeCollection
- attr_reader :environment
+ attr_reader :environment
- def clear
- @hostclasses.clear
- @definitions.clear
- @nodes.clear
- end
+ def clear
+ @hostclasses.clear
+ @definitions.clear
+ @nodes.clear
+ end
- def initialize(env)
- @environment = env.is_a?(String) ? Puppet::Node::Environment.new(env) : env
- @hostclasses = {}
- @definitions = {}
- @nodes = {}
+ def initialize(env)
+ @environment = env.is_a?(String) ? Puppet::Node::Environment.new(env) : env
+ @hostclasses = {}
+ @definitions = {}
+ @nodes = {}
- # So we can keep a list and match the first-defined regex
- @node_list = []
+ # So we can keep a list and match the first-defined regex
+ @node_list = []
- @watched_files = {}
- end
+ @watched_files = {}
+ end
- def <<(thing)
- add(thing)
- self
- end
+ def <<(thing)
+ add(thing)
+ self
+ end
- def add(instance)
- if instance.type == :hostclass and other = @hostclasses[instance.name] and other.type == :hostclass
- other.merge(instance)
- return other
- end
- method = "add_#{instance.type}"
- send(method, instance)
- instance.resource_type_collection = self
- instance
+ def add(instance)
+ if instance.type == :hostclass and other = @hostclasses[instance.name] and other.type == :hostclass
+ other.merge(instance)
+ return other
end
+ method = "add_#{instance.type}"
+ send(method, instance)
+ instance.resource_type_collection = self
+ instance
+ end
- def add_hostclass(instance)
- dupe_check(instance, @hostclasses) { |dupe| "Class '#{instance.name}' is already defined#{dupe.error_context}; cannot redefine" }
- dupe_check(instance, @definitions) { |dupe| "Definition '#{instance.name}' is already defined#{dupe.error_context}; cannot be redefined as a class" }
+ def add_hostclass(instance)
+ dupe_check(instance, @hostclasses) { |dupe| "Class '#{instance.name}' is already defined#{dupe.error_context}; cannot redefine" }
+ dupe_check(instance, @definitions) { |dupe| "Definition '#{instance.name}' is already defined#{dupe.error_context}; cannot be redefined as a class" }
- @hostclasses[instance.name] = instance
- instance
- end
+ @hostclasses[instance.name] = instance
+ instance
+ end
- def hostclass(name)
- @hostclasses[munge_name(name)]
- end
-
- def add_node(instance)
- dupe_check(instance, @nodes) { |dupe| "Node '#{instance.name}' is already defined#{dupe.error_context}; cannot redefine" }
+ def hostclass(name)
+ @hostclasses[munge_name(name)]
+ end
- @node_list << instance
- @nodes[instance.name] = instance
- instance
- end
+ def add_node(instance)
+ dupe_check(instance, @nodes) { |dupe| "Node '#{instance.name}' is already defined#{dupe.error_context}; cannot redefine" }
- def loader
- require 'puppet/parser/type_loader'
- @loader ||= Puppet::Parser::TypeLoader.new(environment)
- end
+ @node_list << instance
+ @nodes[instance.name] = instance
+ instance
+ end
- def node(name)
- name = munge_name(name)
+ def loader
+ require 'puppet/parser/type_loader'
+ @loader ||= Puppet::Parser::TypeLoader.new(environment)
+ end
- if node = @nodes[name]
- return node
- end
+ def node(name)
+ name = munge_name(name)
- @node_list.each do |node|
- next unless node.name_is_regex?
- return node if node.match(name)
- end
- nil
+ if node = @nodes[name]
+ return node
end
- def node_exists?(name)
- @nodes[munge_name(name)]
+ @node_list.each do |node|
+ next unless node.name_is_regex?
+ return node if node.match(name)
end
+ nil
+ end
- def nodes?
- @nodes.length > 0
- end
+ def node_exists?(name)
+ @nodes[munge_name(name)]
+ end
- def add_definition(instance)
- dupe_check(instance, @hostclasses) { |dupe| "'#{instance.name}' is already defined#{dupe.error_context} as a class; cannot redefine as a definition" }
- dupe_check(instance, @definitions) { |dupe| "Definition '#{instance.name}' is already defined#{dupe.error_context}; cannot be redefined" }
- @definitions[instance.name] = instance
- end
+ def nodes?
+ @nodes.length > 0
+ end
+
+ def add_definition(instance)
+ dupe_check(instance, @hostclasses) { |dupe| "'#{instance.name}' is already defined#{dupe.error_context} as a class; cannot redefine as a definition" }
+ dupe_check(instance, @definitions) { |dupe| "Definition '#{instance.name}' is already defined#{dupe.error_context}; cannot be redefined" }
+ @definitions[instance.name] = instance
+ end
- def definition(name)
- @definitions[munge_name(name)]
+ def definition(name)
+ @definitions[munge_name(name)]
+ end
+
+ def find(namespaces, name, type)
+ #Array("") == [] for some reason
+ namespaces = [namespaces] unless namespaces.is_a?(Array)
+
+ if r = find_fully_qualified(name, type)
+ return r
end
- def find(namespaces, name, type)
- #Array("") == [] for some reason
- namespaces = [namespaces] unless namespaces.is_a?(Array)
+ namespaces.each do |namespace|
+ ary = namespace.split("::")
- if r = find_fully_qualified(name, type)
- return r
+ while ary.length > 0
+ tmp_namespace = ary.join("::")
+ if r = find_partially_qualified(tmp_namespace, name, type)
+ return r
end
- namespaces.each do |namespace|
- ary = namespace.split("::")
+ # Delete the second to last object, which reduces our namespace by one.
+ ary.pop
+ end
- while ary.length > 0
- tmp_namespace = ary.join("::")
- if r = find_partially_qualified(tmp_namespace, name, type)
- return r
- end
+ if result = send(type, name)
+ return result
+ end
+ end
+ nil
+ end
- # Delete the second to last object, which reduces our namespace by one.
- ary.pop
- end
+ def find_or_load(namespaces, name, type)
+ name = name.downcase
+ namespaces = [namespaces] unless namespaces.is_a?(Array)
+ namespaces = namespaces.collect { |ns| ns.downcase }
- if result = send(type, name)
- return result
- end
- end
- nil
+ # This could be done in the load_until, but the knowledge seems to
+ # belong here.
+ if r = find(namespaces, name, type)
+ return r
end
- def find_or_load(namespaces, name, type)
- name = name.downcase
- namespaces = [namespaces] unless namespaces.is_a?(Array)
- namespaces = namespaces.collect { |ns| ns.downcase }
+ loader.load_until(namespaces, name) { find(namespaces, name, type) }
+ end
- # This could be done in the load_until, but the knowledge seems to
- # belong here.
- if r = find(namespaces, name, type)
- return r
- end
+ def find_node(name)
+ find("", name, :node)
+ end
- loader.load_until(namespaces, name) { find(namespaces, name, type) }
- end
+ def find_hostclass(namespaces, name)
+ find_or_load(namespaces, name, :hostclass)
+ end
- def find_node(name)
- find("", name, :node)
- end
+ def find_definition(namespaces, name)
+ find_or_load(namespaces, name, :definition)
+ end
- def find_hostclass(namespaces, name)
- find_or_load(namespaces, name, :hostclass)
+ [:hostclasses, :nodes, :definitions].each do |m|
+ define_method(m) do
+ instance_variable_get("@#{m}").dup
end
+ end
- def find_definition(namespaces, name)
- find_or_load(namespaces, name, :definition)
+ def perform_initial_import
+ parser = Puppet::Parser::Parser.new(environment)
+ if code = Puppet.settings.uninterpolated_value(:code, environment.to_s) and code != ""
+ parser.string = code
+ else
+ file = Puppet.settings.value(:manifest, environment.to_s)
+ return unless File.exist?(file)
+ parser.file = file
end
+ parser.parse
+ rescue => detail
+ msg = "Could not parse for environment #{environment}: #{detail}"
+ error = Puppet::Error.new(msg)
+ error.set_backtrace(detail.backtrace)
+ raise error
+ end
- [:hostclasses, :nodes, :definitions].each do |m|
- define_method(m) do
- instance_variable_get("@#{m}").dup
- end
- end
+ def stale?
+ @watched_files.values.detect { |file| file.changed? }
+ end
- def perform_initial_import
- parser = Puppet::Parser::Parser.new(environment)
- if code = Puppet.settings.uninterpolated_value(:code, environment.to_s) and code != ""
- parser.string = code
- else
- file = Puppet.settings.value(:manifest, environment.to_s)
- return unless File.exist?(file)
- parser.file = file
- end
- parser.parse
- rescue => detail
- msg = "Could not parse for environment #{environment}: #{detail}"
- error = Puppet::Error.new(msg)
- error.set_backtrace(detail.backtrace)
- raise error
- end
+ def version
+ return @version if defined?(@version)
- def stale?
- @watched_files.values.detect { |file| file.changed? }
+ if environment[:config_version] == ""
+ @version = Time.now.to_i
+ return @version
end
- def version
- return @version if defined?(@version)
+ @version = Puppet::Util.execute([environment[:config_version]]).strip
- if environment[:config_version] == ""
- @version = Time.now.to_i
- return @version
- end
+ rescue Puppet::ExecutionFailure => e
+ raise Puppet::ParseError, "Unable to set config_version: #{e.message}"
+ end
- @version = Puppet::Util.execute([environment[:config_version]]).strip
+ def watch_file(file)
+ @watched_files[file] = Puppet::Util::LoadedFile.new(file)
+ end
- rescue Puppet::ExecutionFailure => e
- raise Puppet::ParseError, "Unable to set config_version: #{e.message}"
- end
+ def watching_file?(file)
+ @watched_files.include?(file)
+ end
- def watch_file(file)
- @watched_files[file] = Puppet::Util::LoadedFile.new(file)
- end
-
- def watching_file?(file)
- @watched_files.include?(file)
- end
-
- private
+ private
- def find_fully_qualified(name, type)
- return nil unless name =~ /^::/
+ def find_fully_qualified(name, type)
+ return nil unless name =~ /^::/
- name = name.sub(/^::/, '')
+ name = name.sub(/^::/, '')
- send(type, name)
- end
+ send(type, name)
+ end
- def find_partially_qualified(namespace, name, type)
- send(type, [namespace, name].join("::"))
- end
+ def find_partially_qualified(namespace, name, type)
+ send(type, [namespace, name].join("::"))
+ end
- def munge_name(name)
- name.to_s.downcase
- end
+ def munge_name(name)
+ name.to_s.downcase
+ end
- def dupe_check(instance, hash)
- return unless dupe = hash[instance.name]
- message = yield dupe
- instance.fail Puppet::ParseError, message
- end
+ def dupe_check(instance, hash)
+ return unless dupe = hash[instance.name]
+ message = yield dupe
+ instance.fail Puppet::ParseError, message
+ end
end
diff --git a/lib/puppet/resource/type_collection_helper.rb b/lib/puppet/resource/type_collection_helper.rb
index 819cfba..9dc3cce 100644
--- a/lib/puppet/resource/type_collection_helper.rb
+++ b/lib/puppet/resource/type_collection_helper.rb
@@ -1,7 +1,7 @@
require 'puppet/resource/type_collection'
module Puppet::Resource::TypeCollectionHelper
- def known_resource_types
- environment.known_resource_types
- end
+ def known_resource_types
+ environment.known_resource_types
+ end
end
diff --git a/lib/puppet/run.rb b/lib/puppet/run.rb
index 658b967..150e644 100644
--- a/lib/puppet/run.rb
+++ b/lib/puppet/run.rb
@@ -5,73 +5,73 @@ require 'puppet/indirector'
# A basic class for running the agent. Used by
# puppetrun to kick off agents remotely.
class Puppet::Run
- extend Puppet::Indirector
- indirects :run, :terminus_class => :local
+ extend Puppet::Indirector
+ indirects :run, :terminus_class => :local
- attr_reader :status, :background, :options
+ attr_reader :status, :background, :options
- def agent
- Puppet::Agent.new(Puppet::Configurer)
- end
+ def agent
+ Puppet::Agent.new(Puppet::Configurer)
+ end
+
+ def background?
+ background
+ end
- def background?
- background
+ def initialize(options = {})
+ if options.include?(:background)
+ @background = options[:background]
+ options.delete(:background)
end
- def initialize(options = {})
- if options.include?(:background)
- @background = options[:background]
- options.delete(:background)
- end
+ valid_options = [:tags, :ignoreschedules]
+ options.each do |key, value|
+ raise ArgumentError, "Run does not accept #{key}" unless valid_options.include?(key)
+ end
- valid_options = [:tags, :ignoreschedules]
- options.each do |key, value|
- raise ArgumentError, "Run does not accept #{key}" unless valid_options.include?(key)
- end
+ @options = options
+ end
- @options = options
+ def log_run
+ msg = ""
+ msg += "triggered run" % if options[:tags]
+ msg += " with tags #{options[:tags].inspect}"
end
- def log_run
- msg = ""
- msg += "triggered run" % if options[:tags]
- msg += " with tags #{options[:tags].inspect}"
- end
+ msg += " ignoring schedules" if options[:ignoreschedules]
- msg += " ignoring schedules" if options[:ignoreschedules]
+ Puppet.notice msg
+ end
- Puppet.notice msg
+ def run
+ if agent.running?
+ @status = "running"
+ return self
end
- def run
- if agent.running?
- @status = "running"
- return self
- end
+ log_run
- log_run
+ if background?
+ Thread.new { agent.run(options) }
+ else
+ agent.run(options)
+ end
- if background?
- Thread.new { agent.run(options) }
- else
- agent.run(options)
- end
+ @status = "success"
- @status = "success"
+ self
+ end
- self
+ def self.from_pson( pson )
+ options = {}
+ pson.each do |key, value|
+ options[key.to_sym] = value
end
- def self.from_pson( pson )
- options = {}
- pson.each do |key, value|
- options[key.to_sym] = value
- end
+ new(options)
+ end
- new(options)
- end
-
- def to_pson
- @options.merge(:background => @background).to_pson
- end
+ def to_pson
+ @options.merge(:background => @background).to_pson
+ end
end
diff --git a/lib/puppet/simple_graph.rb b/lib/puppet/simple_graph.rb
index 172a0f7..945b1be 100644
--- a/lib/puppet/simple_graph.rb
+++ b/lib/puppet/simple_graph.rb
@@ -7,295 +7,295 @@ require 'set'
# A hopefully-faster graph class to replace the use of GRATR.
class Puppet::SimpleGraph
- # An internal class for handling a vertex's edges.
- class VertexWrapper
- attr_accessor :in, :out, :vertex
-
- # Remove all references to everything.
- def clear
- @adjacencies[:in].clear
- @adjacencies[:out].clear
- @vertex = nil
- end
-
- def initialize(vertex)
- @vertex = vertex
- @adjacencies = {:in => {}, :out => {}}
- end
-
- # Find adjacent vertices or edges.
- def adjacent(options)
- direction = options[:direction] || :out
- options[:type] ||= :vertices
-
- return send(direction.to_s + "_edges") if options[:type] == :edges
-
- @adjacencies[direction].keys.reject { |vertex| @adjacencies[direction][vertex].empty? }
- end
-
- # Add an edge to our list.
- def add_edge(direction, edge)
- opposite_adjacencies(direction, edge) << edge
- end
-
- # Return all known edges.
- def edges
- in_edges + out_edges
- end
+ # An internal class for handling a vertex's edges.
+ class VertexWrapper
+ attr_accessor :in, :out, :vertex
- # Test whether we share an edge with a given vertex.
- def has_edge?(direction, vertex)
- return(vertex_adjacencies(direction, vertex).length > 0 ? true : false)
- end
-
- # Create methods for returning the degree and edges.
- [:in, :out].each do |direction|
- # LAK:NOTE If you decide to create methods for directly
- # testing the degree, you'll have to get the values and flatten
- # the results -- you might have duplicate edges, which can give
- # a false impression of what the degree is. That's just
- # as expensive as just getting the edge list, so I've decided
- # to only add this method.
- define_method("#{direction}_edges") do
- @adjacencies[direction].values.inject([]) { |total, adjacent| total += adjacent.to_a; total }
- end
- end
-
- # The other vertex in the edge.
- def other_vertex(direction, edge)
- case direction
- when :in; edge.source
- else
- edge.target
- end
- end
-
- # Remove an edge from our list. Assumes that we've already checked
- # that the edge is valid.
- def remove_edge(direction, edge)
- opposite_adjacencies(direction, edge).delete(edge)
- end
-
- def to_s
- vertex.to_s
- end
-
- private
-
- # These methods exist so we don't need a Hash with a default proc.
-
- # Look up the adjacencies for a vertex at the other end of an
- # edge.
- def opposite_adjacencies(direction, edge)
- opposite_vertex = other_vertex(direction, edge)
- vertex_adjacencies(direction, opposite_vertex)
- end
-
- # Look up the adjacencies for a given vertex.
- def vertex_adjacencies(direction, vertex)
- @adjacencies[direction][vertex] ||= Set.new
- @adjacencies[direction][vertex]
- end
- end
-
- def initialize
- @vertices = {}
- @edges = []
- end
-
- # Clear our graph.
+ # Remove all references to everything.
def clear
- @vertices.each { |vertex, wrapper| wrapper.clear }
- @vertices.clear
- @edges.clear
+ @adjacencies[:in].clear
+ @adjacencies[:out].clear
+ @vertex = nil
end
- # Which resources a given resource depends upon.
- def dependents(resource)
- tree_from_vertex(resource).keys
+ def initialize(vertex)
+ @vertex = vertex
+ @adjacencies = {:in => {}, :out => {}}
end
- # Which resources depend upon the given resource.
- def dependencies(resource)
- # Cache the reversal graph, because it's somewhat expensive
- # to create.
- @reversal ||= reversal
- # Strangely, it's significantly faster to search a reversed
- # tree in the :out direction than to search a normal tree
- # in the :in direction.
- @reversal.tree_from_vertex(resource, :out).keys
- end
+ # Find adjacent vertices or edges.
+ def adjacent(options)
+ direction = options[:direction] || :out
+ options[:type] ||= :vertices
- # Whether our graph is directed. Always true. Used to produce dot files.
- def directed?
- true
- end
+ return send(direction.to_s + "_edges") if options[:type] == :edges
- # Determine all of the leaf nodes below a given vertex.
- def leaves(vertex, direction = :out)
- tree = tree_from_vertex(vertex, direction)
- l = tree.keys.find_all { |c| adjacent(c, :direction => direction).empty? }
+ @adjacencies[direction].keys.reject { |vertex| @adjacencies[direction][vertex].empty? }
end
- # Collect all of the edges that the passed events match. Returns
- # an array of edges.
- def matching_edges(event, base = nil)
- source = base || event.resource
-
- unless vertex?(source)
- Puppet.warning "Got an event from invalid vertex #{source.ref}"
- return []
- end
- # Get all of the edges that this vertex should forward events
- # to, which is the same thing as saying all edges directly below
- # This vertex in the graph.
- adjacent(source, :direction => :out, :type => :edges).find_all do |edge|
- edge.match?(event.name)
- end
+ # Add an edge to our list.
+ def add_edge(direction, edge)
+ opposite_adjacencies(direction, edge) << edge
end
- # Return a reversed version of this graph.
- def reversal
- result = self.class.new
- vertices.each { |vertex| result.add_vertex(vertex) }
- edges.each do |edge|
- newedge = edge.class.new(edge.target, edge.source, edge.label)
- result.add_edge(newedge)
- end
- result
+ # Return all known edges.
+ def edges
+ in_edges + out_edges
end
- # Return the size of the graph.
- def size
- @vertices.length
+ # Test whether we share an edge with a given vertex.
+ def has_edge?(direction, vertex)
+ return(vertex_adjacencies(direction, vertex).length > 0 ? true : false)
end
- # Return the graph as an array.
- def to_a
- @vertices.keys
+ # Create methods for returning the degree and edges.
+ [:in, :out].each do |direction|
+ # LAK:NOTE If you decide to create methods for directly
+ # testing the degree, you'll have to get the values and flatten
+ # the results -- you might have duplicate edges, which can give
+ # a false impression of what the degree is. That's just
+ # as expensive as just getting the edge list, so I've decided
+ # to only add this method.
+ define_method("#{direction}_edges") do
+ @adjacencies[direction].values.inject([]) { |total, adjacent| total += adjacent.to_a; total }
+ end
end
- # Provide a topological sort.
- def topsort
- degree = {}
- zeros = []
- result = []
-
- # Collect each of our vertices, with the number of in-edges each has.
- @vertices.each do |name, wrapper|
- edges = wrapper.in_edges
- zeros << wrapper if edges.length == 0
- degree[wrapper.vertex] = edges
- end
-
- # Iterate over each 0-degree vertex, decrementing the degree of
- # each of its out-edges.
- while wrapper = zeros.pop
- result << wrapper.vertex
- wrapper.out_edges.each do |edge|
- degree[edge.target].delete(edge)
- zeros << @vertices[edge.target] if degree[edge.target].length == 0
- end
- end
-
- # If we have any vertices left with non-zero in-degrees, then we've found a cycle.
- if cycles = degree.find_all { |vertex, edges| edges.length > 0 } and cycles.length > 0
- message = cycles.collect { |vertex, edges| edges.collect { |e| e.to_s }.join(", ") }.join(", ")
- raise Puppet::Error, "Found dependency cycles in the following relationships: #{message}; try using the '--graph' option and open the '.dot' files in OmniGraffle or GraphViz"
- end
-
- result
+ # The other vertex in the edge.
+ def other_vertex(direction, edge)
+ case direction
+ when :in; edge.source
+ else
+ edge.target
+ end
end
- # Add a new vertex to the graph.
- def add_vertex(vertex)
- @reversal = nil
- return false if vertex?(vertex)
- setup_vertex(vertex)
- true # don't return the VertexWrapper instance.
+ # Remove an edge from our list. Assumes that we've already checked
+ # that the edge is valid.
+ def remove_edge(direction, edge)
+ opposite_adjacencies(direction, edge).delete(edge)
end
- # Remove a vertex from the graph.
- def remove_vertex!(vertex)
- return nil unless vertex?(vertex)
- @vertices[vertex].edges.each { |edge| remove_edge!(edge) }
- @edges -= @vertices[vertex].edges
- @vertices[vertex].clear
- @vertices.delete(vertex)
+ def to_s
+ vertex.to_s
end
- # Test whether a given vertex is in the graph.
- def vertex?(vertex)
- @vertices.include?(vertex)
- end
+ private
- # Return a list of all vertices.
- def vertices
- @vertices.keys
- end
+ # These methods exist so we don't need a Hash with a default proc.
- # Add a new edge. The graph user has to create the edge instance,
- # since they have to specify what kind of edge it is.
- def add_edge(source, target = nil, label = nil)
- @reversal = nil
- if target
- edge = Puppet::Relationship.new(source, target, label)
- else
- edge = source
- end
- [edge.source, edge.target].each { |vertex| setup_vertex(vertex) unless vertex?(vertex) }
- @vertices[edge.source].add_edge :out, edge
- @vertices[edge.target].add_edge :in, edge
- @edges << edge
- true
+ # Look up the adjacencies for a vertex at the other end of an
+ # edge.
+ def opposite_adjacencies(direction, edge)
+ opposite_vertex = other_vertex(direction, edge)
+ vertex_adjacencies(direction, opposite_vertex)
end
- # Find a matching edge. Note that this only finds the first edge,
- # not all of them or whatever.
- def edge(source, target)
- @edges.each_with_index { |test_edge, index| return test_edge if test_edge.source == source and test_edge.target == target }
+ # Look up the adjacencies for a given vertex.
+ def vertex_adjacencies(direction, vertex)
+ @adjacencies[direction][vertex] ||= Set.new
+ @adjacencies[direction][vertex]
end
-
- def edge_label(source, target)
- return nil unless edge = edge(source, target)
- edge.label
+ end
+
+ def initialize
+ @vertices = {}
+ @edges = []
+ end
+
+ # Clear our graph.
+ def clear
+ @vertices.each { |vertex, wrapper| wrapper.clear }
+ @vertices.clear
+ @edges.clear
+ end
+
+ # Which resources a given resource depends upon.
+ def dependents(resource)
+ tree_from_vertex(resource).keys
+ end
+
+ # Which resources depend upon the given resource.
+ def dependencies(resource)
+ # Cache the reversal graph, because it's somewhat expensive
+ # to create.
+ @reversal ||= reversal
+ # Strangely, it's significantly faster to search a reversed
+ # tree in the :out direction than to search a normal tree
+ # in the :in direction.
+ @reversal.tree_from_vertex(resource, :out).keys
+ end
+
+ # Whether our graph is directed. Always true. Used to produce dot files.
+ def directed?
+ true
+ end
+
+ # Determine all of the leaf nodes below a given vertex.
+ def leaves(vertex, direction = :out)
+ tree = tree_from_vertex(vertex, direction)
+ l = tree.keys.find_all { |c| adjacent(c, :direction => direction).empty? }
+ end
+
+ # Collect all of the edges that the passed events match. Returns
+ # an array of edges.
+ def matching_edges(event, base = nil)
+ source = base || event.resource
+
+ unless vertex?(source)
+ Puppet.warning "Got an event from invalid vertex #{source.ref}"
+ return []
end
-
- # Is there an edge between the two vertices?
- def edge?(source, target)
- return false unless vertex?(source) and vertex?(target)
-
- @vertices[source].has_edge?(:out, target)
+ # Get all of the edges that this vertex should forward events
+ # to, which is the same thing as saying all edges directly below
+ # This vertex in the graph.
+ adjacent(source, :direction => :out, :type => :edges).find_all do |edge|
+ edge.match?(event.name)
end
-
- def edges
- @edges.dup
+ end
+
+ # Return a reversed version of this graph.
+ def reversal
+ result = self.class.new
+ vertices.each { |vertex| result.add_vertex(vertex) }
+ edges.each do |edge|
+ newedge = edge.class.new(edge.target, edge.source, edge.label)
+ result.add_edge(newedge)
end
-
- # Remove an edge from our graph.
- def remove_edge!(edge)
- @vertices[edge.source].remove_edge(:out, edge)
- @vertices[edge.target].remove_edge(:in, edge)
-
- @edges.delete(edge)
- nil
+ result
+ end
+
+ # Return the size of the graph.
+ def size
+ @vertices.length
+ end
+
+ # Return the graph as an array.
+ def to_a
+ @vertices.keys
+ end
+
+ # Provide a topological sort.
+ def topsort
+ degree = {}
+ zeros = []
+ result = []
+
+ # Collect each of our vertices, with the number of in-edges each has.
+ @vertices.each do |name, wrapper|
+ edges = wrapper.in_edges
+ zeros << wrapper if edges.length == 0
+ degree[wrapper.vertex] = edges
end
- # Find adjacent edges.
- def adjacent(vertex, options = {})
- return [] unless wrapper = @vertices[vertex]
- wrapper.adjacent(options)
+ # Iterate over each 0-degree vertex, decrementing the degree of
+ # each of its out-edges.
+ while wrapper = zeros.pop
+ result << wrapper.vertex
+ wrapper.out_edges.each do |edge|
+ degree[edge.target].delete(edge)
+ zeros << @vertices[edge.target] if degree[edge.target].length == 0
+ end
end
- private
-
- # An internal method that skips the validation, so we don't have
- # duplicate validation calls.
- def setup_vertex(vertex)
- @vertices[vertex] = VertexWrapper.new(vertex)
+ # If we have any vertices left with non-zero in-degrees, then we've found a cycle.
+ if cycles = degree.find_all { |vertex, edges| edges.length > 0 } and cycles.length > 0
+ message = cycles.collect { |vertex, edges| edges.collect { |e| e.to_s }.join(", ") }.join(", ")
+ raise Puppet::Error, "Found dependency cycles in the following relationships: #{message}; try using the '--graph' option and open the '.dot' files in OmniGraffle or GraphViz"
end
- public
+ result
+ end
+
+ # Add a new vertex to the graph.
+ def add_vertex(vertex)
+ @reversal = nil
+ return false if vertex?(vertex)
+ setup_vertex(vertex)
+ true # don't return the VertexWrapper instance.
+ end
+
+ # Remove a vertex from the graph.
+ def remove_vertex!(vertex)
+ return nil unless vertex?(vertex)
+ @vertices[vertex].edges.each { |edge| remove_edge!(edge) }
+ @edges -= @vertices[vertex].edges
+ @vertices[vertex].clear
+ @vertices.delete(vertex)
+ end
+
+ # Test whether a given vertex is in the graph.
+ def vertex?(vertex)
+ @vertices.include?(vertex)
+ end
+
+ # Return a list of all vertices.
+ def vertices
+ @vertices.keys
+ end
+
+ # Add a new edge. The graph user has to create the edge instance,
+ # since they have to specify what kind of edge it is.
+ def add_edge(source, target = nil, label = nil)
+ @reversal = nil
+ if target
+ edge = Puppet::Relationship.new(source, target, label)
+ else
+ edge = source
+ end
+ [edge.source, edge.target].each { |vertex| setup_vertex(vertex) unless vertex?(vertex) }
+ @vertices[edge.source].add_edge :out, edge
+ @vertices[edge.target].add_edge :in, edge
+ @edges << edge
+ true
+ end
+
+ # Find a matching edge. Note that this only finds the first edge,
+ # not all of them or whatever.
+ def edge(source, target)
+ @edges.each_with_index { |test_edge, index| return test_edge if test_edge.source == source and test_edge.target == target }
+ end
+
+ def edge_label(source, target)
+ return nil unless edge = edge(source, target)
+ edge.label
+ end
+
+ # Is there an edge between the two vertices?
+ def edge?(source, target)
+ return false unless vertex?(source) and vertex?(target)
+
+ @vertices[source].has_edge?(:out, target)
+ end
+
+ def edges
+ @edges.dup
+ end
+
+ # Remove an edge from our graph.
+ def remove_edge!(edge)
+ @vertices[edge.source].remove_edge(:out, edge)
+ @vertices[edge.target].remove_edge(:in, edge)
+
+ @edges.delete(edge)
+ nil
+ end
+
+ # Find adjacent edges.
+ def adjacent(vertex, options = {})
+ return [] unless wrapper = @vertices[vertex]
+ wrapper.adjacent(options)
+ end
+
+ private
+
+ # An internal method that skips the validation, so we don't have
+ # duplicate validation calls.
+ def setup_vertex(vertex)
+ @vertices[vertex] = VertexWrapper.new(vertex)
+ end
+
+ public
# # For some reason, unconnected vertices do not show up in
# # this graph.
@@ -306,144 +306,144 @@ class Puppet::SimpleGraph
# end
# end
- # Take container information from another graph and use it
- # to replace any container vertices with their respective leaves.
- # This creates direct relationships where there were previously
- # indirect relationships through the containers.
- def splice!(other, type)
- # We have to get the container list via a topological sort on the
- # configuration graph, because otherwise containers that contain
- # other containers will add those containers back into the
- # graph. We could get a similar affect by only setting relationships
- # to container leaves, but that would result in many more
- # relationships.
- stage_class = Puppet::Type.type(:stage)
- containers = other.topsort.find_all { |v| (v.is_a?(type) or v.is_a?(stage_class)) and vertex?(v) }
- containers.each do |container|
- # Get the list of children from the other graph.
- children = other.adjacent(container, :direction => :out)
-
- # Just remove the container if it's empty.
- if children.empty?
- remove_vertex!(container)
- next
- end
-
- # First create new edges for each of the :in edges
- [:in, :out].each do |dir|
- edges = adjacent(container, :direction => dir, :type => :edges)
- edges.each do |edge|
- children.each do |child|
- if dir == :in
- s = edge.source
- t = child
- else
- s = child
- t = edge.target
- end
-
- add_edge(s, t, edge.label)
- end
-
- # Now get rid of the edge, so remove_vertex! works correctly.
- remove_edge!(edge)
- end
+ # Take container information from another graph and use it
+ # to replace any container vertices with their respective leaves.
+ # This creates direct relationships where there were previously
+ # indirect relationships through the containers.
+ def splice!(other, type)
+ # We have to get the container list via a topological sort on the
+ # configuration graph, because otherwise containers that contain
+ # other containers will add those containers back into the
+ # graph. We could get a similar affect by only setting relationships
+ # to container leaves, but that would result in many more
+ # relationships.
+ stage_class = Puppet::Type.type(:stage)
+ containers = other.topsort.find_all { |v| (v.is_a?(type) or v.is_a?(stage_class)) and vertex?(v) }
+ containers.each do |container|
+ # Get the list of children from the other graph.
+ children = other.adjacent(container, :direction => :out)
+
+ # Just remove the container if it's empty.
+ if children.empty?
+ remove_vertex!(container)
+ next
+ end
+
+ # First create new edges for each of the :in edges
+ [:in, :out].each do |dir|
+ edges = adjacent(container, :direction => dir, :type => :edges)
+ edges.each do |edge|
+ children.each do |child|
+ if dir == :in
+ s = edge.source
+ t = child
+ else
+ s = child
+ t = edge.target
end
- remove_vertex!(container)
- end
- end
- # Just walk the tree and pass each edge.
- def walk(source, direction)
- # Use an iterative, breadth-first traversal of the graph. One could do
- # this recursively, but Ruby's slow function calls and even slower
- # recursion make the shorter, recursive algorithm cost-prohibitive.
- stack = [source]
- seen = Set.new
- until stack.empty?
- node = stack.shift
- next if seen.member? node
- connected = adjacent(node, :direction => direction)
- connected.each do |target|
- yield node, target
- end
- stack.concat(connected)
- seen << node
- end
- end
+ add_edge(s, t, edge.label)
+ end
- # A different way of walking a tree, and a much faster way than the
- # one that comes with GRATR.
- def tree_from_vertex(start, direction = :out)
- predecessor={}
- walk(start, direction) do |parent, child|
- predecessor[child] = parent
+ # Now get rid of the edge, so remove_vertex! works correctly.
+ remove_edge!(edge)
end
- predecessor
+ end
+ remove_vertex!(container)
end
-
- # LAK:FIXME This is just a paste of the GRATR code with slight modifications.
-
- # Return a DOT::DOTDigraph for directed graphs or a DOT::DOTSubgraph for an
- # undirected Graph. _params_ can contain any graph property specified in
- # rdot.rb. If an edge or vertex label is a kind of Hash then the keys
- # which match +dot+ properties will be used as well.
- def to_dot_graph (params = {})
- params['name'] ||= self.class.name.gsub(/:/,'_')
- fontsize = params['fontsize'] ? params['fontsize'] : '8'
- graph = (directed? ? DOT::DOTDigraph : DOT::DOTSubgraph).new(params)
- edge_klass = directed? ? DOT::DOTDirectedEdge : DOT::DOTEdge
- vertices.each do |v|
- name = v.to_s
- params = {'name' => '"'+name+'"',
- 'fontsize' => fontsize,
- 'label' => name}
- v_label = v.to_s
- params.merge!(v_label) if v_label and v_label.kind_of? Hash
- graph << DOT::DOTNode.new(params)
- end
- edges.each do |e|
- params = {'from' => '"'+ e.source.to_s + '"',
- 'to' => '"'+ e.target.to_s + '"',
- 'fontsize' => fontsize }
- e_label = e.to_s
- params.merge!(e_label) if e_label and e_label.kind_of? Hash
- graph << edge_klass.new(params)
- end
- graph
+ end
+
+ # Just walk the tree and pass each edge.
+ def walk(source, direction)
+ # Use an iterative, breadth-first traversal of the graph. One could do
+ # this recursively, but Ruby's slow function calls and even slower
+ # recursion make the shorter, recursive algorithm cost-prohibitive.
+ stack = [source]
+ seen = Set.new
+ until stack.empty?
+ node = stack.shift
+ next if seen.member? node
+ connected = adjacent(node, :direction => direction)
+ connected.each do |target|
+ yield node, target
+ end
+ stack.concat(connected)
+ seen << node
end
-
- # Output the dot format as a string
- def to_dot (params={}) to_dot_graph(params).to_s; end
-
- # Call +dotty+ for the graph which is written to the file 'graph.dot'
- # in the # current directory.
- def dotty (params = {}, dotfile = 'graph.dot')
- File.open(dotfile, 'w') {|f| f << to_dot(params) }
- system('dotty', dotfile)
+ end
+
+ # A different way of walking a tree, and a much faster way than the
+ # one that comes with GRATR.
+ def tree_from_vertex(start, direction = :out)
+ predecessor={}
+ walk(start, direction) do |parent, child|
+ predecessor[child] = parent
end
-
- # Use +dot+ to create a graphical representation of the graph. Returns the
- # filename of the graphics file.
- def write_to_graphic_file (fmt='png', dotfile='graph')
- src = dotfile + '.dot'
- dot = dotfile + '.' + fmt
-
- File.open(src, 'w') {|f| f << self.to_dot << "\n"}
-
- system( "dot -T#{fmt} #{src} -o #{dot}" )
- dot
+ predecessor
+ end
+
+ # LAK:FIXME This is just a paste of the GRATR code with slight modifications.
+
+ # Return a DOT::DOTDigraph for directed graphs or a DOT::DOTSubgraph for an
+ # undirected Graph. _params_ can contain any graph property specified in
+ # rdot.rb. If an edge or vertex label is a kind of Hash then the keys
+ # which match +dot+ properties will be used as well.
+ def to_dot_graph (params = {})
+ params['name'] ||= self.class.name.gsub(/:/,'_')
+ fontsize = params['fontsize'] ? params['fontsize'] : '8'
+ graph = (directed? ? DOT::DOTDigraph : DOT::DOTSubgraph).new(params)
+ edge_klass = directed? ? DOT::DOTDirectedEdge : DOT::DOTEdge
+ vertices.each do |v|
+ name = v.to_s
+ params = {'name' => '"'+name+'"',
+ 'fontsize' => fontsize,
+ 'label' => name}
+ v_label = v.to_s
+ params.merge!(v_label) if v_label and v_label.kind_of? Hash
+ graph << DOT::DOTNode.new(params)
end
-
- # Produce the graph files if requested.
- def write_graph(name)
- return unless Puppet[:graph]
-
- Puppet.settings.use(:graphing)
-
- file = File.join(Puppet[:graphdir], "#{name}.dot")
- File.open(file, "w") { |f|
- f.puts to_dot("name" => name.to_s.capitalize)
- }
+ edges.each do |e|
+ params = {'from' => '"'+ e.source.to_s + '"',
+ 'to' => '"'+ e.target.to_s + '"',
+ 'fontsize' => fontsize }
+ e_label = e.to_s
+ params.merge!(e_label) if e_label and e_label.kind_of? Hash
+ graph << edge_klass.new(params)
end
+ graph
+ end
+
+ # Output the dot format as a string
+ def to_dot (params={}) to_dot_graph(params).to_s; end
+
+ # Call +dotty+ for the graph which is written to the file 'graph.dot'
+ # in the # current directory.
+ def dotty (params = {}, dotfile = 'graph.dot')
+ File.open(dotfile, 'w') {|f| f << to_dot(params) }
+ system('dotty', dotfile)
+ end
+
+ # Use +dot+ to create a graphical representation of the graph. Returns the
+ # filename of the graphics file.
+ def write_to_graphic_file (fmt='png', dotfile='graph')
+ src = dotfile + '.dot'
+ dot = dotfile + '.' + fmt
+
+ File.open(src, 'w') {|f| f << self.to_dot << "\n"}
+
+ system( "dot -T#{fmt} #{src} -o #{dot}" )
+ dot
+ end
+
+ # Produce the graph files if requested.
+ def write_graph(name)
+ return unless Puppet[:graph]
+
+ Puppet.settings.use(:graphing)
+
+ file = File.join(Puppet[:graphdir], "#{name}.dot")
+ File.open(file, "w") { |f|
+ f.puts to_dot("name" => name.to_s.capitalize)
+ }
+ end
end
diff --git a/lib/puppet/ssl.rb b/lib/puppet/ssl.rb
index 9cb67a6..8f71ba8 100644
--- a/lib/puppet/ssl.rb
+++ b/lib/puppet/ssl.rb
@@ -3,6 +3,6 @@ require 'puppet'
require 'openssl'
module Puppet::SSL # :nodoc:
- CA_NAME = "ca"
- require 'puppet/ssl/host'
+ CA_NAME = "ca"
+ require 'puppet/ssl/host'
end
diff --git a/lib/puppet/ssl/base.rb b/lib/puppet/ssl/base.rb
index 745d733..f9bbcac 100644
--- a/lib/puppet/ssl/base.rb
+++ b/lib/puppet/ssl/base.rb
@@ -2,78 +2,78 @@ require 'puppet/ssl'
# The base class for wrapping SSL instances.
class Puppet::SSL::Base
- # For now, use the YAML separator.
- SEPARATOR = "\n---\n"
-
- def self.from_multiple_s(text)
- text.split(SEPARATOR).collect { |inst| from_s(inst) }
- end
-
- def self.to_multiple_s(instances)
- instances.collect { |inst| inst.to_s }.join(SEPARATOR)
- end
-
- def self.wraps(klass)
- @wrapped_class = klass
- end
-
- def self.wrapped_class
- raise(Puppet::DevError, "#{self} has not declared what class it wraps") unless defined?(@wrapped_class)
- @wrapped_class
- end
-
- attr_accessor :name, :content
-
- # Is this file for the CA?
- def ca?
- name == Puppet::SSL::Host.ca_name
- end
-
- def generate
- raise Puppet::DevError, "#{self.class} did not override 'generate'"
- end
-
- def initialize(name)
- @name = name.to_s.downcase
+ # For now, use the YAML separator.
+ SEPARATOR = "\n---\n"
+
+ def self.from_multiple_s(text)
+ text.split(SEPARATOR).collect { |inst| from_s(inst) }
+ end
+
+ def self.to_multiple_s(instances)
+ instances.collect { |inst| inst.to_s }.join(SEPARATOR)
+ end
+
+ def self.wraps(klass)
+ @wrapped_class = klass
+ end
+
+ def self.wrapped_class
+ raise(Puppet::DevError, "#{self} has not declared what class it wraps") unless defined?(@wrapped_class)
+ @wrapped_class
+ end
+
+ attr_accessor :name, :content
+
+ # Is this file for the CA?
+ def ca?
+ name == Puppet::SSL::Host.ca_name
+ end
+
+ def generate
+ raise Puppet::DevError, "#{self.class} did not override 'generate'"
+ end
+
+ def initialize(name)
+ @name = name.to_s.downcase
+ end
+
+ # Read content from disk appropriately.
+ def read(path)
+ @content = wrapped_class.new(File.read(path))
+ end
+
+ # Convert our thing to pem.
+ def to_s
+ return "" unless content
+ content.to_pem
+ end
+
+ # Provide the full text of the thing we're dealing with.
+ def to_text
+ return "" unless content
+ content.to_text
+ end
+
+ def fingerprint(md = :MD5)
+ require 'openssl/digest'
+
+ # ruby 1.8.x openssl digest constants are string
+ # but in 1.9.x they are symbols
+ mds = md.to_s.upcase
+ if OpenSSL::Digest.constants.include?(mds)
+ md = mds
+ elsif OpenSSL::Digest.constants.include?(mds.to_sym)
+ md = mds.to_sym
+ else
+ raise ArgumentError, "#{md} is not a valid digest algorithm for fingerprinting certificate #{name}"
end
- # Read content from disk appropriately.
- def read(path)
- @content = wrapped_class.new(File.read(path))
- end
+ OpenSSL::Digest.const_get(md).hexdigest(content.to_der).scan(/../).join(':').upcase
+ end
- # Convert our thing to pem.
- def to_s
- return "" unless content
- content.to_pem
- end
+ private
- # Provide the full text of the thing we're dealing with.
- def to_text
- return "" unless content
- content.to_text
- end
-
- def fingerprint(md = :MD5)
- require 'openssl/digest'
-
- # ruby 1.8.x openssl digest constants are string
- # but in 1.9.x they are symbols
- mds = md.to_s.upcase
- if OpenSSL::Digest.constants.include?(mds)
- md = mds
- elsif OpenSSL::Digest.constants.include?(mds.to_sym)
- md = mds.to_sym
- else
- raise ArgumentError, "#{md} is not a valid digest algorithm for fingerprinting certificate #{name}"
- end
-
- OpenSSL::Digest.const_get(md).hexdigest(content.to_der).scan(/../).join(':').upcase
- end
-
- private
-
- def wrapped_class
- self.class.wrapped_class
- end
+ def wrapped_class
+ self.class.wrapped_class
+ end
end
diff --git a/lib/puppet/ssl/certificate.rb b/lib/puppet/ssl/certificate.rb
index 07dd0c8..a0e6002 100644
--- a/lib/puppet/ssl/certificate.rb
+++ b/lib/puppet/ssl/certificate.rb
@@ -6,29 +6,29 @@ require 'puppet/ssl/base'
# retrieve them from the CA (or not, as is often
# the case).
class Puppet::SSL::Certificate < Puppet::SSL::Base
- # This is defined from the base class
- wraps OpenSSL::X509::Certificate
+ # This is defined from the base class
+ wraps OpenSSL::X509::Certificate
- extend Puppet::Indirector
- indirects :certificate, :terminus_class => :file
+ extend Puppet::Indirector
+ indirects :certificate, :terminus_class => :file
- # Convert a string into an instance.
- def self.from_s(string)
- instance = wrapped_class.new(string)
- name = instance.subject.to_s.sub(/\/CN=/i, '').downcase
- result = new(name)
- result.content = instance
- result
- end
+ # Convert a string into an instance.
+ def self.from_s(string)
+ instance = wrapped_class.new(string)
+ name = instance.subject.to_s.sub(/\/CN=/i, '').downcase
+ result = new(name)
+ result.content = instance
+ result
+ end
- # Because of how the format handler class is included, this
- # can't be in the base class.
- def self.supported_formats
- [:s]
- end
+ # Because of how the format handler class is included, this
+ # can't be in the base class.
+ def self.supported_formats
+ [:s]
+ end
- def expiration
- return nil unless content
- content.not_after
- end
+ def expiration
+ return nil unless content
+ content.not_after
+ end
end
diff --git a/lib/puppet/ssl/certificate_authority.rb b/lib/puppet/ssl/certificate_authority.rb
index 26febb3..efe562d 100644
--- a/lib/puppet/ssl/certificate_authority.rb
+++ b/lib/puppet/ssl/certificate_authority.rb
@@ -11,274 +11,274 @@ require 'puppet/util/cacher'
# it can also be seen as a general interface into all of the
# SSL stuff.
class Puppet::SSL::CertificateAuthority
- require 'puppet/ssl/certificate_factory'
- require 'puppet/ssl/inventory'
- require 'puppet/ssl/certificate_revocation_list'
+ require 'puppet/ssl/certificate_factory'
+ require 'puppet/ssl/inventory'
+ require 'puppet/ssl/certificate_revocation_list'
- require 'puppet/ssl/certificate_authority/interface'
+ require 'puppet/ssl/certificate_authority/interface'
- class CertificateVerificationError < RuntimeError
- attr_accessor :error_code
+ class CertificateVerificationError < RuntimeError
+ attr_accessor :error_code
- def initialize(code)
- @error_code = code
- end
+ def initialize(code)
+ @error_code = code
end
+ end
- class << self
- include Puppet::Util::Cacher
+ class << self
+ include Puppet::Util::Cacher
- cached_attr(:singleton_instance) { new }
- end
+ cached_attr(:singleton_instance) { new }
+ end
- def self.ca?
- return false unless Puppet[:ca]
- return false unless Puppet.run_mode.master?
- true
- end
+ def self.ca?
+ return false unless Puppet[:ca]
+ return false unless Puppet.run_mode.master?
+ true
+ end
- # If this process can function as a CA, then return a singleton
- # instance.
- def self.instance
- return nil unless ca?
+ # If this process can function as a CA, then return a singleton
+ # instance.
+ def self.instance
+ return nil unless ca?
- singleton_instance
- end
+ singleton_instance
+ end
- attr_reader :name, :host
+ attr_reader :name, :host
- # Create and run an applicator. I wanted to build an interface where you could do
- # something like 'ca.apply(:generate).to(:all) but I don't think it's really possible.
- def apply(method, options)
- raise ArgumentError, "You must specify the hosts to apply to; valid values are an array or the symbol :all" unless options[:to]
- applier = Interface.new(method, options)
+ # Create and run an applicator. I wanted to build an interface where you could do
+ # something like 'ca.apply(:generate).to(:all) but I don't think it's really possible.
+ def apply(method, options)
+ raise ArgumentError, "You must specify the hosts to apply to; valid values are an array or the symbol :all" unless options[:to]
+ applier = Interface.new(method, options)
- applier.apply(self)
- end
+ applier.apply(self)
+ end
- # If autosign is configured, then autosign all CSRs that match our configuration.
- def autosign
- return unless auto = autosign?
+ # If autosign is configured, then autosign all CSRs that match our configuration.
+ def autosign
+ return unless auto = autosign?
- store = nil
- store = autosign_store(auto) if auto != true
+ store = nil
+ store = autosign_store(auto) if auto != true
- Puppet::SSL::CertificateRequest.search("*").each do |csr|
- sign(csr.name) if auto == true or store.allowed?(csr.name, "127.1.1.1")
- end
+ Puppet::SSL::CertificateRequest.search("*").each do |csr|
+ sign(csr.name) if auto == true or store.allowed?(csr.name, "127.1.1.1")
+ end
+ end
+
+ # Do we autosign? This returns true, false, or a filename.
+ def autosign?
+ auto = Puppet[:autosign]
+ return false if ['false', false].include?(auto)
+ return true if ['true', true].include?(auto)
+
+ raise ArgumentError, "The autosign configuration '#{auto}' must be a fully qualified file" unless auto =~ /^\//
+ FileTest.exist?(auto) && auto
+ end
+
+ # Create an AuthStore for autosigning.
+ def autosign_store(file)
+ auth = Puppet::Network::AuthStore.new
+ File.readlines(file).each do |line|
+ next if line =~ /^\s*#/
+ next if line =~ /^\s*$/
+ auth.allow(line.chomp)
end
- # Do we autosign? This returns true, false, or a filename.
- def autosign?
- auto = Puppet[:autosign]
- return false if ['false', false].include?(auto)
- return true if ['true', true].include?(auto)
-
- raise ArgumentError, "The autosign configuration '#{auto}' must be a fully qualified file" unless auto =~ /^\//
- FileTest.exist?(auto) && auto
+ auth
+ end
+
+ # Retrieve (or create, if necessary) the certificate revocation list.
+ def crl
+ unless defined?(@crl)
+ unless @crl = Puppet::SSL::CertificateRevocationList.find(Puppet::SSL::CA_NAME)
+ @crl = Puppet::SSL::CertificateRevocationList.new(Puppet::SSL::CA_NAME)
+ @crl.generate(host.certificate.content, host.key.content)
+ @crl.save
+ end
end
+ @crl
+ end
- # Create an AuthStore for autosigning.
- def autosign_store(file)
- auth = Puppet::Network::AuthStore.new
- File.readlines(file).each do |line|
- next if line =~ /^\s*#/
- next if line =~ /^\s*$/
- auth.allow(line.chomp)
- end
+ # Delegate this to our Host class.
+ def destroy(name)
+ Puppet::SSL::Host.destroy(name)
+ end
- auth
- end
+ # Generate a new certificate.
+ def generate(name)
+ raise ArgumentError, "A Certificate already exists for #{name}" if Puppet::SSL::Certificate.find(name)
+ host = Puppet::SSL::Host.new(name)
- # Retrieve (or create, if necessary) the certificate revocation list.
- def crl
- unless defined?(@crl)
- unless @crl = Puppet::SSL::CertificateRevocationList.find(Puppet::SSL::CA_NAME)
- @crl = Puppet::SSL::CertificateRevocationList.new(Puppet::SSL::CA_NAME)
- @crl.generate(host.certificate.content, host.key.content)
- @crl.save
- end
- end
- @crl
- end
+ host.generate_certificate_request
- # Delegate this to our Host class.
- def destroy(name)
- Puppet::SSL::Host.destroy(name)
- end
+ sign(name)
+ end
- # Generate a new certificate.
- def generate(name)
- raise ArgumentError, "A Certificate already exists for #{name}" if Puppet::SSL::Certificate.find(name)
- host = Puppet::SSL::Host.new(name)
+ # Generate our CA certificate.
+ def generate_ca_certificate
+ generate_password unless password?
- host.generate_certificate_request
+ host.generate_key unless host.key
- sign(name)
- end
+ # Create a new cert request. We do this
+ # specially, because we don't want to actually
+ # save the request anywhere.
+ request = Puppet::SSL::CertificateRequest.new(host.name)
+ request.generate(host.key)
- # Generate our CA certificate.
- def generate_ca_certificate
- generate_password unless password?
+ # Create a self-signed certificate.
+ @certificate = sign(host.name, :ca, request)
- host.generate_key unless host.key
+ # And make sure we initialize our CRL.
+ crl
+ end
- # Create a new cert request. We do this
- # specially, because we don't want to actually
- # save the request anywhere.
- request = Puppet::SSL::CertificateRequest.new(host.name)
- request.generate(host.key)
+ def initialize
+ Puppet.settings.use :main, :ssl, :ca
- # Create a self-signed certificate.
- @certificate = sign(host.name, :ca, request)
+ @name = Puppet[:certname]
- # And make sure we initialize our CRL.
- crl
- end
+ @host = Puppet::SSL::Host.new(Puppet::SSL::Host.ca_name)
- def initialize
- Puppet.settings.use :main, :ssl, :ca
+ setup
+ end
- @name = Puppet[:certname]
+ # Retrieve (or create, if necessary) our inventory manager.
+ def inventory
+ @inventory ||= Puppet::SSL::Inventory.new
+ end
- @host = Puppet::SSL::Host.new(Puppet::SSL::Host.ca_name)
+ # Generate a new password for the CA.
+ def generate_password
+ pass = ""
+ 20.times { pass += (rand(74) + 48).chr }
- setup
+ begin
+ Puppet.settings.write(:capass) { |f| f.print pass }
+ rescue Errno::EACCES => detail
+ raise Puppet::Error, "Could not write CA password: #{detail}"
end
- # Retrieve (or create, if necessary) our inventory manager.
- def inventory
- @inventory ||= Puppet::SSL::Inventory.new
- end
+ @password = pass
- # Generate a new password for the CA.
- def generate_password
- pass = ""
- 20.times { pass += (rand(74) + 48).chr }
+ pass
+ end
- begin
- Puppet.settings.write(:capass) { |f| f.print pass }
- rescue Errno::EACCES => detail
- raise Puppet::Error, "Could not write CA password: #{detail}"
- end
+ # List all signed certificates.
+ def list
+ Puppet::SSL::Certificate.search("*").collect { |c| c.name }
+ end
- @password = pass
+ # Read the next serial from the serial file, and increment the
+ # file so this one is considered used.
+ def next_serial
+ serial = nil
- pass
- end
+ # This is slightly odd. If the file doesn't exist, our readwritelock creates
+ # it, but with a mode we can't actually read in some cases. So, use
+ # a default before the lock.
+ serial = 0x1 unless FileTest.exist?(Puppet[:serial])
- # List all signed certificates.
- def list
- Puppet::SSL::Certificate.search("*").collect { |c| c.name }
- end
+ Puppet.settings.readwritelock(:serial) { |f|
+ serial ||= File.read(Puppet.settings[:serial]).chomp.hex if FileTest.exist?(Puppet[:serial])
- # Read the next serial from the serial file, and increment the
- # file so this one is considered used.
- def next_serial
- serial = nil
+ # We store the next valid serial, not the one we just used.
+ f << "%04X" % (serial + 1)
+ }
- # This is slightly odd. If the file doesn't exist, our readwritelock creates
- # it, but with a mode we can't actually read in some cases. So, use
- # a default before the lock.
- serial = 0x1 unless FileTest.exist?(Puppet[:serial])
+ serial
+ end
- Puppet.settings.readwritelock(:serial) { |f|
- serial ||= File.read(Puppet.settings[:serial]).chomp.hex if FileTest.exist?(Puppet[:serial])
+ # Does the password file exist?
+ def password?
+ FileTest.exist? Puppet[:capass]
+ end
- # We store the next valid serial, not the one we just used.
- f << "%04X" % (serial + 1)
- }
+ # Print a given host's certificate as text.
+ def print(name)
+ (cert = Puppet::SSL::Certificate.find(name)) ? cert.to_text : nil
+ end
- serial
- end
+ # Revoke a given certificate.
+ def revoke(name)
+ raise ArgumentError, "Cannot revoke certificates when the CRL is disabled" unless crl
- # Does the password file exist?
- def password?
- FileTest.exist? Puppet[:capass]
+ if cert = Puppet::SSL::Certificate.find(name)
+ serial = cert.content.serial
+ elsif ! serial = inventory.serial(name)
+ raise ArgumentError, "Could not find a serial number for #{name}"
end
-
- # Print a given host's certificate as text.
- def print(name)
- (cert = Puppet::SSL::Certificate.find(name)) ? cert.to_text : nil
+ crl.revoke(serial, host.key.content)
+ end
+
+ # This initializes our CA so it actually works. This should be a private
+ # method, except that you can't any-instance stub private methods, which is
+ # *awesome*. This method only really exists to provide a stub-point during
+ # testing.
+ def setup
+ generate_ca_certificate unless @host.certificate
+ end
+
+ # Sign a given certificate request.
+ def sign(hostname, cert_type = :server, self_signing_csr = nil)
+ # This is a self-signed certificate
+ if self_signing_csr
+ csr = self_signing_csr
+ issuer = csr.content
+ else
+ unless csr = Puppet::SSL::CertificateRequest.find(hostname)
+ raise ArgumentError, "Could not find certificate request for #{hostname}"
+ end
+ issuer = host.certificate.content
end
- # Revoke a given certificate.
- def revoke(name)
- raise ArgumentError, "Cannot revoke certificates when the CRL is disabled" unless crl
+ cert = Puppet::SSL::Certificate.new(hostname)
+ cert.content = Puppet::SSL::CertificateFactory.new(cert_type, csr.content, issuer, next_serial).result
+ cert.content.sign(host.key.content, OpenSSL::Digest::SHA1.new)
- if cert = Puppet::SSL::Certificate.find(name)
- serial = cert.content.serial
- elsif ! serial = inventory.serial(name)
- raise ArgumentError, "Could not find a serial number for #{name}"
- end
- crl.revoke(serial, host.key.content)
- end
+ Puppet.notice "Signed certificate request for #{hostname}"
- # This initializes our CA so it actually works. This should be a private
- # method, except that you can't any-instance stub private methods, which is
- # *awesome*. This method only really exists to provide a stub-point during
- # testing.
- def setup
- generate_ca_certificate unless @host.certificate
- end
+ # Add the cert to the inventory before we save it, since
+ # otherwise we could end up with it being duplicated, if
+ # this is the first time we build the inventory file.
+ inventory.add(cert)
- # Sign a given certificate request.
- def sign(hostname, cert_type = :server, self_signing_csr = nil)
- # This is a self-signed certificate
- if self_signing_csr
- csr = self_signing_csr
- issuer = csr.content
- else
- unless csr = Puppet::SSL::CertificateRequest.find(hostname)
- raise ArgumentError, "Could not find certificate request for #{hostname}"
- end
- issuer = host.certificate.content
- end
-
- cert = Puppet::SSL::Certificate.new(hostname)
- cert.content = Puppet::SSL::CertificateFactory.new(cert_type, csr.content, issuer, next_serial).result
- cert.content.sign(host.key.content, OpenSSL::Digest::SHA1.new)
-
- Puppet.notice "Signed certificate request for #{hostname}"
-
- # Add the cert to the inventory before we save it, since
- # otherwise we could end up with it being duplicated, if
- # this is the first time we build the inventory file.
- inventory.add(cert)
-
- # Save the now-signed cert. This should get routed correctly depending
- # on the certificate type.
- cert.save
-
- # And remove the CSR if this wasn't self signed.
- Puppet::SSL::CertificateRequest.destroy(csr.name) unless self_signing_csr
-
- cert
- end
+ # Save the now-signed cert. This should get routed correctly depending
+ # on the certificate type.
+ cert.save
- # Verify a given host's certificate.
- def verify(name)
- unless cert = Puppet::SSL::Certificate.find(name)
- raise ArgumentError, "Could not find a certificate for #{name}"
- end
- store = OpenSSL::X509::Store.new
- store.add_file Puppet[:cacert]
- store.add_crl crl.content if self.crl
- store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
- store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK if Puppet.settings[:certificate_revocation]
-
- raise CertificateVerificationError.new(store.error), store.error_string unless store.verify(cert.content)
- end
+ # And remove the CSR if this wasn't self signed.
+ Puppet::SSL::CertificateRequest.destroy(csr.name) unless self_signing_csr
- def fingerprint(name, md = :MD5)
- unless cert = Puppet::SSL::Certificate.find(name) || Puppet::SSL::CertificateRequest.find(name)
- raise ArgumentError, "Could not find a certificate or csr for #{name}"
- end
- cert.fingerprint(md)
- end
+ cert
+ end
- # List the waiting certificate requests.
- def waiting?
- Puppet::SSL::CertificateRequest.search("*").collect { |r| r.name }
+ # Verify a given host's certificate.
+ def verify(name)
+ unless cert = Puppet::SSL::Certificate.find(name)
+ raise ArgumentError, "Could not find a certificate for #{name}"
end
+ store = OpenSSL::X509::Store.new
+ store.add_file Puppet[:cacert]
+ store.add_crl crl.content if self.crl
+ store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
+ store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK if Puppet.settings[:certificate_revocation]
+
+ raise CertificateVerificationError.new(store.error), store.error_string unless store.verify(cert.content)
+ end
+
+ def fingerprint(name, md = :MD5)
+ unless cert = Puppet::SSL::Certificate.find(name) || Puppet::SSL::CertificateRequest.find(name)
+ raise ArgumentError, "Could not find a certificate or csr for #{name}"
+ end
+ cert.fingerprint(md)
+ end
+
+ # List the waiting certificate requests.
+ def waiting?
+ Puppet::SSL::CertificateRequest.search("*").collect { |r| r.name }
+ end
end
diff --git a/lib/puppet/ssl/certificate_authority/interface.rb b/lib/puppet/ssl/certificate_authority/interface.rb
index e5ede3c..f73eff5 100644
--- a/lib/puppet/ssl/certificate_authority/interface.rb
+++ b/lib/puppet/ssl/certificate_authority/interface.rb
@@ -2,133 +2,133 @@
# on the CA. It's only used by the 'puppetca' executable, and its
# job is to provide a CLI-like interface to the CA class.
module Puppet
- module SSL
- class CertificateAuthority
- class Interface
- INTERFACE_METHODS = [:destroy, :list, :revoke, :generate, :sign, :print, :verify, :fingerprint]
-
- class InterfaceError < ArgumentError; end
-
- attr_reader :method, :subjects, :digest
-
- # Actually perform the work.
- def apply(ca)
- unless subjects or method == :list
- raise ArgumentError, "You must provide hosts or :all when using #{method}"
- end
-
- begin
- return send(method, ca) if respond_to?(method)
-
- (subjects == :all ? ca.list : subjects).each do |host|
- ca.send(method, host)
- end
- rescue InterfaceError
- raise
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Could not call #{method}: #{detail}"
- end
- end
-
- def generate(ca)
- raise InterfaceError, "It makes no sense to generate all hosts; you must specify a list" if subjects == :all
-
- subjects.each do |host|
- ca.generate(host)
- end
- end
-
- def initialize(method, options)
- self.method = method
- self.subjects = options[:to]
- @digest = options[:digest] || :MD5
- end
-
- # List the hosts.
- def list(ca)
- unless subjects
- puts ca.waiting?.join("\n")
- return nil
- end
-
- signed = ca.list
- requests = ca.waiting?
-
- if subjects == :all
- hosts = [signed, requests].flatten
- elsif subjects == :signed
- hosts = signed.flatten
- else
- hosts = subjects
- end
-
- hosts.uniq.sort.each do |host|
- invalid = false
- begin
- ca.verify(host) unless requests.include?(host)
- rescue Puppet::SSL::CertificateAuthority::CertificateVerificationError => details
- invalid = details.to_s
- end
- if not invalid and signed.include?(host)
- puts "+ #{host} (#{ca.fingerprint(host, @digest)})"
- elsif invalid
- puts "- #{host} (#{ca.fingerprint(host, @digest)}) (#{invalid})"
- else
- puts "#{host} (#{ca.fingerprint(host, @digest)})"
- end
- end
- end
-
- # Set the method to apply.
- def method=(method)
- raise ArgumentError, "Invalid method #{method} to apply" unless INTERFACE_METHODS.include?(method)
- @method = method
- end
-
- # Print certificate information.
- def print(ca)
- (subjects == :all ? ca.list : subjects).each do |host|
- if value = ca.print(host)
- puts value
- else
- Puppet.err "Could not find certificate for #{host}"
- end
- end
- end
-
- # Print certificate information.
- def fingerprint(ca)
- (subjects == :all ? ca.list + ca.waiting?: subjects).each do |host|
- if value = ca.fingerprint(host, @digest)
- puts "#{host} #{value}"
- else
- Puppet.err "Could not find certificate for #{host}"
- end
- end
- end
-
- # Sign a given certificate.
- def sign(ca)
- list = subjects == :all ? ca.waiting? : subjects
- raise InterfaceError, "No waiting certificate requests to sign" if list.empty?
- list.each do |host|
- ca.sign(host)
- end
- end
-
- # Set the list of hosts we're operating on. Also supports keywords.
- def subjects=(value)
- unless value == :all or value == :signed or value.is_a?(Array)
- raise ArgumentError, "Subjects must be an array or :all; not #{value}"
- end
-
- value = nil if value.is_a?(Array) and value.empty?
-
- @subjects = value
- end
+ module SSL
+ class CertificateAuthority
+ class Interface
+ INTERFACE_METHODS = [:destroy, :list, :revoke, :generate, :sign, :print, :verify, :fingerprint]
+
+ class InterfaceError < ArgumentError; end
+
+ attr_reader :method, :subjects, :digest
+
+ # Actually perform the work.
+ def apply(ca)
+ unless subjects or method == :list
+ raise ArgumentError, "You must provide hosts or :all when using #{method}"
+ end
+
+ begin
+ return send(method, ca) if respond_to?(method)
+
+ (subjects == :all ? ca.list : subjects).each do |host|
+ ca.send(method, host)
+ end
+ rescue InterfaceError
+ raise
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Could not call #{method}: #{detail}"
+ end
+ end
+
+ def generate(ca)
+ raise InterfaceError, "It makes no sense to generate all hosts; you must specify a list" if subjects == :all
+
+ subjects.each do |host|
+ ca.generate(host)
+ end
+ end
+
+ def initialize(method, options)
+ self.method = method
+ self.subjects = options[:to]
+ @digest = options[:digest] || :MD5
+ end
+
+ # List the hosts.
+ def list(ca)
+ unless subjects
+ puts ca.waiting?.join("\n")
+ return nil
+ end
+
+ signed = ca.list
+ requests = ca.waiting?
+
+ if subjects == :all
+ hosts = [signed, requests].flatten
+ elsif subjects == :signed
+ hosts = signed.flatten
+ else
+ hosts = subjects
+ end
+
+ hosts.uniq.sort.each do |host|
+ invalid = false
+ begin
+ ca.verify(host) unless requests.include?(host)
+ rescue Puppet::SSL::CertificateAuthority::CertificateVerificationError => details
+ invalid = details.to_s
+ end
+ if not invalid and signed.include?(host)
+ puts "+ #{host} (#{ca.fingerprint(host, @digest)})"
+ elsif invalid
+ puts "- #{host} (#{ca.fingerprint(host, @digest)}) (#{invalid})"
+ else
+ puts "#{host} (#{ca.fingerprint(host, @digest)})"
end
+ end
+ end
+
+ # Set the method to apply.
+ def method=(method)
+ raise ArgumentError, "Invalid method #{method} to apply" unless INTERFACE_METHODS.include?(method)
+ @method = method
+ end
+
+ # Print certificate information.
+ def print(ca)
+ (subjects == :all ? ca.list : subjects).each do |host|
+ if value = ca.print(host)
+ puts value
+ else
+ Puppet.err "Could not find certificate for #{host}"
+ end
+ end
+ end
+
+ # Print certificate information.
+ def fingerprint(ca)
+ (subjects == :all ? ca.list + ca.waiting?: subjects).each do |host|
+ if value = ca.fingerprint(host, @digest)
+ puts "#{host} #{value}"
+ else
+ Puppet.err "Could not find certificate for #{host}"
+ end
+ end
+ end
+
+ # Sign a given certificate.
+ def sign(ca)
+ list = subjects == :all ? ca.waiting? : subjects
+ raise InterfaceError, "No waiting certificate requests to sign" if list.empty?
+ list.each do |host|
+ ca.sign(host)
+ end
+ end
+
+ # Set the list of hosts we're operating on. Also supports keywords.
+ def subjects=(value)
+ unless value == :all or value == :signed or value.is_a?(Array)
+ raise ArgumentError, "Subjects must be an array or :all; not #{value}"
+ end
+
+ value = nil if value.is_a?(Array) and value.empty?
+
+ @subjects = value
end
+ end
end
+ end
end
diff --git a/lib/puppet/ssl/certificate_factory.rb b/lib/puppet/ssl/certificate_factory.rb
index 9a5507d..73290e9 100644
--- a/lib/puppet/ssl/certificate_factory.rb
+++ b/lib/puppet/ssl/certificate_factory.rb
@@ -3,143 +3,143 @@ require 'puppet/ssl'
# The tedious class that does all the manipulations to the
# certificate to correctly sign it. Yay.
class Puppet::SSL::CertificateFactory
- # How we convert from various units to the required seconds.
- UNITMAP = {
- "y" => 365 * 24 * 60 * 60,
- "d" => 24 * 60 * 60,
- "h" => 60 * 60,
- "s" => 1
- }
+ # How we convert from various units to the required seconds.
+ UNITMAP = {
+ "y" => 365 * 24 * 60 * 60,
+ "d" => 24 * 60 * 60,
+ "h" => 60 * 60,
+ "s" => 1
+ }
- attr_reader :name, :cert_type, :csr, :issuer, :serial
+ attr_reader :name, :cert_type, :csr, :issuer, :serial
- def initialize(cert_type, csr, issuer, serial)
- @cert_type, @csr, @issuer, @serial = cert_type, csr, issuer, serial
+ def initialize(cert_type, csr, issuer, serial)
+ @cert_type, @csr, @issuer, @serial = cert_type, csr, issuer, serial
- @name = @csr.subject
- end
-
- # Actually generate our certificate.
- def result
- @cert = OpenSSL::X509::Certificate.new
-
- @cert.version = 2 # X509v3
- @cert.subject = @csr.subject
- @cert.issuer = @issuer.subject
- @cert.public_key = @csr.public_key
- @cert.serial = @serial
-
- build_extensions
-
- set_ttl
-
- @cert
- end
-
- private
-
- # This is pretty ugly, but I'm not really sure it's even possible to do
- # it any other way.
- def build_extensions
- @ef = OpenSSL::X509::ExtensionFactory.new
-
- @ef.subject_certificate = @cert
+ @name = @csr.subject
+ end
- if @issuer.is_a?(OpenSSL::X509::Request) # It's a self-signed cert
- @ef.issuer_certificate = @cert
- else
- @ef.issuer_certificate = @issuer
- end
+ # Actually generate our certificate.
+ def result
+ @cert = OpenSSL::X509::Certificate.new
- @subject_alt_name = []
- @key_usage = nil
- @ext_key_usage = nil
- @extensions = []
+ @cert.version = 2 # X509v3
+ @cert.subject = @csr.subject
+ @cert.issuer = @issuer.subject
+ @cert.public_key = @csr.public_key
+ @cert.serial = @serial
- method = "add_#{@cert_type.to_s}_extensions"
+ build_extensions
- begin
- send(method)
- rescue NoMethodError
- raise ArgumentError, "#{@cert_type} is an invalid certificate type"
- end
+ set_ttl
- @extensions << @ef.create_extension("nsComment", "Puppet Ruby/OpenSSL Generated Certificate")
- @extensions << @ef.create_extension("basicConstraints", @basic_constraint, true)
- @extensions << @ef.create_extension("subjectKeyIdentifier", "hash")
- @extensions << @ef.create_extension("keyUsage", @key_usage.join(",")) if @key_usage
- @extensions << @ef.create_extension("extendedKeyUsage", @ext_key_usage.join(",")) if @ext_key_usage
- @extensions << @ef.create_extension("subjectAltName", @subject_alt_name.join(",")) if ! @subject_alt_name.empty?
+ @cert
+ end
- @cert.extensions = @extensions
+ private
- # for some reason this _must_ be the last extension added
- @extensions << @ef.create_extension("authorityKeyIdentifier", "keyid:always,issuer:always") if @cert_type == :ca
- end
-
- # TTL for new certificates in seconds. If config param :ca_ttl is set,
- # use that, otherwise use :ca_days for backwards compatibility
- def ttl
- ttl = Puppet.settings[:ca_ttl]
-
- return ttl unless ttl.is_a?(String)
-
- raise ArgumentError, "Invalid ca_ttl #{ttl}" unless ttl =~ /^(\d+)(y|d|h|s)$/
-
- $1.to_i * UNITMAP[$2]
- end
+ # This is pretty ugly, but I'm not really sure it's even possible to do
+ # it any other way.
+ def build_extensions
+ @ef = OpenSSL::X509::ExtensionFactory.new
- def set_ttl
- # Make the certificate valid as of yesterday, because
- # so many people's clocks are out of sync.
- from = Time.now - (60*60*24)
- @cert.not_before = from
- @cert.not_after = from + ttl
- end
+ @ef.subject_certificate = @cert
- # Woot! We're a CA.
- def add_ca_extensions
- @basic_constraint = "CA:TRUE"
- @key_usage = %w{cRLSign keyCertSign}
+ if @issuer.is_a?(OpenSSL::X509::Request) # It's a self-signed cert
+ @ef.issuer_certificate = @cert
+ else
+ @ef.issuer_certificate = @issuer
end
- # We're a terminal CA, probably not self-signed.
- def add_terminalsubca_extensions
- @basic_constraint = "CA:TRUE,pathlen:0"
- @key_usage = %w{cRLSign keyCertSign}
- end
+ @subject_alt_name = []
+ @key_usage = nil
+ @ext_key_usage = nil
+ @extensions = []
- # We're a normal server.
- def add_server_extensions
- @basic_constraint = "CA:FALSE"
- dnsnames = Puppet[:certdnsnames]
- name = @name.to_s.sub(%r{/CN=},'')
- if dnsnames != ""
- dnsnames.split(':').each { |d| @subject_alt_name << 'DNS:' + d }
- @subject_alt_name << 'DNS:' + name # Add the fqdn as an alias
- elsif name == Facter.value(:fqdn) # we're a CA server, and thus probably the server
- @subject_alt_name << 'DNS:' + "puppet" # Add 'puppet' as an alias
- @subject_alt_name << 'DNS:' + name # Add the fqdn as an alias
- @subject_alt_name << 'DNS:' + name.sub(/^[^.]+./, "puppet.") # add puppet.domain as an alias
- end
- @key_usage = %w{digitalSignature keyEncipherment}
- @ext_key_usage = %w{serverAuth clientAuth emailProtection}
- end
+ method = "add_#{@cert_type.to_s}_extensions"
- # Um, no idea.
- def add_ocsp_extensions
- @basic_constraint = "CA:FALSE"
- @key_usage = %w{nonRepudiation digitalSignature}
- @ext_key_usage = %w{serverAuth OCSPSigning}
+ begin
+ send(method)
+ rescue NoMethodError
+ raise ArgumentError, "#{@cert_type} is an invalid certificate type"
end
- # Normal client.
- def add_client_extensions
- @basic_constraint = "CA:FALSE"
- @key_usage = %w{nonRepudiation digitalSignature keyEncipherment}
- @ext_key_usage = %w{clientAuth emailProtection}
-
- @extensions << @ef.create_extension("nsCertType", "client,email")
+ @extensions << @ef.create_extension("nsComment", "Puppet Ruby/OpenSSL Generated Certificate")
+ @extensions << @ef.create_extension("basicConstraints", @basic_constraint, true)
+ @extensions << @ef.create_extension("subjectKeyIdentifier", "hash")
+ @extensions << @ef.create_extension("keyUsage", @key_usage.join(",")) if @key_usage
+ @extensions << @ef.create_extension("extendedKeyUsage", @ext_key_usage.join(",")) if @ext_key_usage
+ @extensions << @ef.create_extension("subjectAltName", @subject_alt_name.join(",")) if ! @subject_alt_name.empty?
+
+ @cert.extensions = @extensions
+
+ # for some reason this _must_ be the last extension added
+ @extensions << @ef.create_extension("authorityKeyIdentifier", "keyid:always,issuer:always") if @cert_type == :ca
+ end
+
+ # TTL for new certificates in seconds. If config param :ca_ttl is set,
+ # use that, otherwise use :ca_days for backwards compatibility
+ def ttl
+ ttl = Puppet.settings[:ca_ttl]
+
+ return ttl unless ttl.is_a?(String)
+
+ raise ArgumentError, "Invalid ca_ttl #{ttl}" unless ttl =~ /^(\d+)(y|d|h|s)$/
+
+ $1.to_i * UNITMAP[$2]
+ end
+
+ def set_ttl
+ # Make the certificate valid as of yesterday, because
+ # so many people's clocks are out of sync.
+ from = Time.now - (60*60*24)
+ @cert.not_before = from
+ @cert.not_after = from + ttl
+ end
+
+ # Woot! We're a CA.
+ def add_ca_extensions
+ @basic_constraint = "CA:TRUE"
+ @key_usage = %w{cRLSign keyCertSign}
+ end
+
+ # We're a terminal CA, probably not self-signed.
+ def add_terminalsubca_extensions
+ @basic_constraint = "CA:TRUE,pathlen:0"
+ @key_usage = %w{cRLSign keyCertSign}
+ end
+
+ # We're a normal server.
+ def add_server_extensions
+ @basic_constraint = "CA:FALSE"
+ dnsnames = Puppet[:certdnsnames]
+ name = @name.to_s.sub(%r{/CN=},'')
+ if dnsnames != ""
+ dnsnames.split(':').each { |d| @subject_alt_name << 'DNS:' + d }
+ @subject_alt_name << 'DNS:' + name # Add the fqdn as an alias
+ elsif name == Facter.value(:fqdn) # we're a CA server, and thus probably the server
+ @subject_alt_name << 'DNS:' + "puppet" # Add 'puppet' as an alias
+ @subject_alt_name << 'DNS:' + name # Add the fqdn as an alias
+ @subject_alt_name << 'DNS:' + name.sub(/^[^.]+./, "puppet.") # add puppet.domain as an alias
end
+ @key_usage = %w{digitalSignature keyEncipherment}
+ @ext_key_usage = %w{serverAuth clientAuth emailProtection}
+ end
+
+ # Um, no idea.
+ def add_ocsp_extensions
+ @basic_constraint = "CA:FALSE"
+ @key_usage = %w{nonRepudiation digitalSignature}
+ @ext_key_usage = %w{serverAuth OCSPSigning}
+ end
+
+ # Normal client.
+ def add_client_extensions
+ @basic_constraint = "CA:FALSE"
+ @key_usage = %w{nonRepudiation digitalSignature keyEncipherment}
+ @ext_key_usage = %w{clientAuth emailProtection}
+
+ @extensions << @ef.create_extension("nsCertType", "client,email")
+ end
end
diff --git a/lib/puppet/ssl/certificate_request.rb b/lib/puppet/ssl/certificate_request.rb
index 3cd3ce0..e4d06a0 100644
--- a/lib/puppet/ssl/certificate_request.rb
+++ b/lib/puppet/ssl/certificate_request.rb
@@ -2,57 +2,57 @@ require 'puppet/ssl/base'
# Manage certificate requests.
class Puppet::SSL::CertificateRequest < Puppet::SSL::Base
- wraps OpenSSL::X509::Request
-
- extend Puppet::Indirector
- indirects :certificate_request, :terminus_class => :file
-
- # Convert a string into an instance.
- def self.from_s(string)
- instance = wrapped_class.new(string)
- name = instance.subject.to_s.sub(/\/CN=/i, '').downcase
- result = new(name)
- result.content = instance
- result
- end
-
- # Because of how the format handler class is included, this
- # can't be in the base class.
- def self.supported_formats
- [:s]
- end
-
- # How to create a certificate request with our system defaults.
- def generate(key)
- Puppet.info "Creating a new SSL certificate request for #{name}"
-
- # Support either an actual SSL key, or a Puppet key.
- key = key.content if key.is_a?(Puppet::SSL::Key)
-
- # If we're a CSR for the CA, then use the real certname, rather than the
- # fake 'ca' name. This is mostly for backward compatibility with 0.24.x,
- # but it's also just a good idea.
- common_name = name == Puppet::SSL::CA_NAME ? Puppet.settings[:ca_name] : name
-
- csr = OpenSSL::X509::Request.new
- csr.version = 0
- csr.subject = OpenSSL::X509::Name.new([["CN", common_name]])
- csr.public_key = key.public_key
- csr.sign(key, OpenSSL::Digest::MD5.new)
-
- raise Puppet::Error, "CSR sign verification failed; you need to clean the certificate request for #{name} on the server" unless csr.verify(key.public_key)
-
- @content = csr
- Puppet.info "Certificate Request fingerprint (md5): #{fingerprint}"
- @content
- end
-
- def save(args = {})
- super()
-
- # Try to autosign the CSR.
- if ca = Puppet::SSL::CertificateAuthority.instance
- ca.autosign
- end
+ wraps OpenSSL::X509::Request
+
+ extend Puppet::Indirector
+ indirects :certificate_request, :terminus_class => :file
+
+ # Convert a string into an instance.
+ def self.from_s(string)
+ instance = wrapped_class.new(string)
+ name = instance.subject.to_s.sub(/\/CN=/i, '').downcase
+ result = new(name)
+ result.content = instance
+ result
+ end
+
+ # Because of how the format handler class is included, this
+ # can't be in the base class.
+ def self.supported_formats
+ [:s]
+ end
+
+ # How to create a certificate request with our system defaults.
+ def generate(key)
+ Puppet.info "Creating a new SSL certificate request for #{name}"
+
+ # Support either an actual SSL key, or a Puppet key.
+ key = key.content if key.is_a?(Puppet::SSL::Key)
+
+ # If we're a CSR for the CA, then use the real certname, rather than the
+ # fake 'ca' name. This is mostly for backward compatibility with 0.24.x,
+ # but it's also just a good idea.
+ common_name = name == Puppet::SSL::CA_NAME ? Puppet.settings[:ca_name] : name
+
+ csr = OpenSSL::X509::Request.new
+ csr.version = 0
+ csr.subject = OpenSSL::X509::Name.new([["CN", common_name]])
+ csr.public_key = key.public_key
+ csr.sign(key, OpenSSL::Digest::MD5.new)
+
+ raise Puppet::Error, "CSR sign verification failed; you need to clean the certificate request for #{name} on the server" unless csr.verify(key.public_key)
+
+ @content = csr
+ Puppet.info "Certificate Request fingerprint (md5): #{fingerprint}"
+ @content
+ end
+
+ def save(args = {})
+ super()
+
+ # Try to autosign the CSR.
+ if ca = Puppet::SSL::CertificateAuthority.instance
+ ca.autosign
end
+ end
end
diff --git a/lib/puppet/ssl/certificate_revocation_list.rb b/lib/puppet/ssl/certificate_revocation_list.rb
index b2bff48..44e0a9e 100644
--- a/lib/puppet/ssl/certificate_revocation_list.rb
+++ b/lib/puppet/ssl/certificate_revocation_list.rb
@@ -3,82 +3,82 @@ require 'puppet/indirector'
# Manage the CRL.
class Puppet::SSL::CertificateRevocationList < Puppet::SSL::Base
- wraps OpenSSL::X509::CRL
-
- extend Puppet::Indirector
- indirects :certificate_revocation_list, :terminus_class => :file
-
- # Convert a string into an instance.
- def self.from_s(string)
- instance = wrapped_class.new(string)
- result = new('foo') # The name doesn't matter
- result.content = instance
- result
- end
-
- # Because of how the format handler class is included, this
- # can't be in the base class.
- def self.supported_formats
- [:s]
- end
-
- # Knows how to create a CRL with our system defaults.
- def generate(cert, cakey)
- Puppet.info "Creating a new certificate revocation list"
- @content = wrapped_class.new
- @content.issuer = cert.subject
- @content.version = 1
-
- # Init the CRL number.
- crlNum = OpenSSL::ASN1::Integer(0)
- @content.extensions = [OpenSSL::X509::Extension.new("crlNumber", crlNum)]
-
- # Set last/next update
- @content.last_update = Time.now
- # Keep CRL valid for 5 years
- @content.next_update = Time.now + 5 * 365*24*60*60
-
- @content.sign(cakey, OpenSSL::Digest::SHA1.new)
-
- @content
- end
-
- # The name doesn't actually matter; there's only one CRL.
- # We just need the name so our Indirector stuff all works more easily.
- def initialize(fakename)
- @name = "crl"
- end
-
- # Revoke the certificate with serial number SERIAL issued by this
- # CA, then write the CRL back to disk. The REASON must be one of the
- # OpenSSL::OCSP::REVOKED_* reasons
- def revoke(serial, cakey, reason = OpenSSL::OCSP::REVOKED_STATUS_KEYCOMPROMISE)
- Puppet.notice "Revoked certificate with serial #{serial}"
- time = Time.now
-
- # Add our revocation to the CRL.
- revoked = OpenSSL::X509::Revoked.new
- revoked.serial = serial
- revoked.time = time
- enum = OpenSSL::ASN1::Enumerated(reason)
- ext = OpenSSL::X509::Extension.new("CRLReason", enum)
- revoked.add_extension(ext)
- @content.add_revoked(revoked)
-
- # Increment the crlNumber
- e = @content.extensions.find { |e| e.oid == 'crlNumber' }
- ext = @content.extensions.reject { |e| e.oid == 'crlNumber' }
- crlNum = OpenSSL::ASN1::Integer(e ? e.value.to_i + 1 : 0)
- ext << OpenSSL::X509::Extension.new("crlNumber", crlNum)
- @content.extensions = ext
-
- # Set last/next update
- @content.last_update = time
- # Keep CRL valid for 5 years
- @content.next_update = time + 5 * 365*24*60*60
-
- @content.sign(cakey, OpenSSL::Digest::SHA1.new)
-
- save
- end
+ wraps OpenSSL::X509::CRL
+
+ extend Puppet::Indirector
+ indirects :certificate_revocation_list, :terminus_class => :file
+
+ # Convert a string into an instance.
+ def self.from_s(string)
+ instance = wrapped_class.new(string)
+ result = new('foo') # The name doesn't matter
+ result.content = instance
+ result
+ end
+
+ # Because of how the format handler class is included, this
+ # can't be in the base class.
+ def self.supported_formats
+ [:s]
+ end
+
+ # Knows how to create a CRL with our system defaults.
+ def generate(cert, cakey)
+ Puppet.info "Creating a new certificate revocation list"
+ @content = wrapped_class.new
+ @content.issuer = cert.subject
+ @content.version = 1
+
+ # Init the CRL number.
+ crlNum = OpenSSL::ASN1::Integer(0)
+ @content.extensions = [OpenSSL::X509::Extension.new("crlNumber", crlNum)]
+
+ # Set last/next update
+ @content.last_update = Time.now
+ # Keep CRL valid for 5 years
+ @content.next_update = Time.now + 5 * 365*24*60*60
+
+ @content.sign(cakey, OpenSSL::Digest::SHA1.new)
+
+ @content
+ end
+
+ # The name doesn't actually matter; there's only one CRL.
+ # We just need the name so our Indirector stuff all works more easily.
+ def initialize(fakename)
+ @name = "crl"
+ end
+
+ # Revoke the certificate with serial number SERIAL issued by this
+ # CA, then write the CRL back to disk. The REASON must be one of the
+ # OpenSSL::OCSP::REVOKED_* reasons
+ def revoke(serial, cakey, reason = OpenSSL::OCSP::REVOKED_STATUS_KEYCOMPROMISE)
+ Puppet.notice "Revoked certificate with serial #{serial}"
+ time = Time.now
+
+ # Add our revocation to the CRL.
+ revoked = OpenSSL::X509::Revoked.new
+ revoked.serial = serial
+ revoked.time = time
+ enum = OpenSSL::ASN1::Enumerated(reason)
+ ext = OpenSSL::X509::Extension.new("CRLReason", enum)
+ revoked.add_extension(ext)
+ @content.add_revoked(revoked)
+
+ # Increment the crlNumber
+ e = @content.extensions.find { |e| e.oid == 'crlNumber' }
+ ext = @content.extensions.reject { |e| e.oid == 'crlNumber' }
+ crlNum = OpenSSL::ASN1::Integer(e ? e.value.to_i + 1 : 0)
+ ext << OpenSSL::X509::Extension.new("crlNumber", crlNum)
+ @content.extensions = ext
+
+ # Set last/next update
+ @content.last_update = time
+ # Keep CRL valid for 5 years
+ @content.next_update = time + 5 * 365*24*60*60
+
+ @content.sign(cakey, OpenSSL::Digest::SHA1.new)
+
+ save
+ end
end
diff --git a/lib/puppet/ssl/host.rb b/lib/puppet/ssl/host.rb
index 9aaff8a..8a6f0aa 100644
--- a/lib/puppet/ssl/host.rb
+++ b/lib/puppet/ssl/host.rb
@@ -8,255 +8,255 @@ require 'puppet/util/cacher'
# The class that manages all aspects of our SSL certificates --
# private keys, public keys, requests, etc.
class Puppet::SSL::Host
- # Yay, ruby's strange constant lookups.
- Key = Puppet::SSL::Key
- CA_NAME = Puppet::SSL::CA_NAME
- Certificate = Puppet::SSL::Certificate
- CertificateRequest = Puppet::SSL::CertificateRequest
- CertificateRevocationList = Puppet::SSL::CertificateRevocationList
-
- attr_reader :name
- attr_accessor :ca
-
- attr_writer :key, :certificate, :certificate_request
-
- class << self
- include Puppet::Util::Cacher
-
- cached_attr(:localhost) do
- result = new
- result.generate unless result.certificate
- result.key # Make sure it's read in
- result
- end
+ # Yay, ruby's strange constant lookups.
+ Key = Puppet::SSL::Key
+ CA_NAME = Puppet::SSL::CA_NAME
+ Certificate = Puppet::SSL::Certificate
+ CertificateRequest = Puppet::SSL::CertificateRequest
+ CertificateRevocationList = Puppet::SSL::CertificateRevocationList
+
+ attr_reader :name
+ attr_accessor :ca
+
+ attr_writer :key, :certificate, :certificate_request
+
+ class << self
+ include Puppet::Util::Cacher
+
+ cached_attr(:localhost) do
+ result = new
+ result.generate unless result.certificate
+ result.key # Make sure it's read in
+ result
end
-
- # This is the constant that people will use to mark that a given host is
- # a certificate authority.
- def self.ca_name
- CA_NAME
+ end
+
+ # This is the constant that people will use to mark that a given host is
+ # a certificate authority.
+ def self.ca_name
+ CA_NAME
+ end
+
+ class << self
+ attr_reader :ca_location
+ end
+
+ # Configure how our various classes interact with their various terminuses.
+ def self.configure_indirection(terminus, cache = nil)
+ Certificate.terminus_class = terminus
+ CertificateRequest.terminus_class = terminus
+ CertificateRevocationList.terminus_class = terminus
+
+ if cache
+ # This is weird; we don't actually cache our keys, we
+ # use what would otherwise be the cache as our normal
+ # terminus.
+ Key.terminus_class = cache
+ else
+ Key.terminus_class = terminus
end
- class << self
- attr_reader :ca_location
+ if cache
+ Certificate.cache_class = cache
+ CertificateRequest.cache_class = cache
+ CertificateRevocationList.cache_class = cache
+ else
+ # Make sure we have no cache configured. puppet master
+ # switches the configurations around a bit, so it's important
+ # that we specify the configs for absolutely everything, every
+ # time.
+ Certificate.cache_class = nil
+ CertificateRequest.cache_class = nil
+ CertificateRevocationList.cache_class = nil
end
-
- # Configure how our various classes interact with their various terminuses.
- def self.configure_indirection(terminus, cache = nil)
- Certificate.terminus_class = terminus
- CertificateRequest.terminus_class = terminus
- CertificateRevocationList.terminus_class = terminus
-
- if cache
- # This is weird; we don't actually cache our keys, we
- # use what would otherwise be the cache as our normal
- # terminus.
- Key.terminus_class = cache
- else
- Key.terminus_class = terminus
- end
-
- if cache
- Certificate.cache_class = cache
- CertificateRequest.cache_class = cache
- CertificateRevocationList.cache_class = cache
- else
- # Make sure we have no cache configured. puppet master
- # switches the configurations around a bit, so it's important
- # that we specify the configs for absolutely everything, every
- # time.
- Certificate.cache_class = nil
- CertificateRequest.cache_class = nil
- CertificateRevocationList.cache_class = nil
- end
+ end
+
+ CA_MODES = {
+ # Our ca is local, so we use it as the ultimate source of information
+ # And we cache files locally.
+ :local => [:ca, :file],
+ # We're a remote CA client.
+ :remote => [:rest, :file],
+ # We are the CA, so we don't have read/write access to the normal certificates.
+ :only => [:ca],
+ # We have no CA, so we just look in the local file store.
+ :none => [:file]
+ }
+
+ # Specify how we expect to interact with our certificate authority.
+ def self.ca_location=(mode)
+ raise ArgumentError, "CA Mode can only be #{CA_MODES.collect { |m| m.to_s }.join(", ")}" unless CA_MODES.include?(mode)
+
+ @ca_location = mode
+
+ configure_indirection(*CA_MODES[@ca_location])
+ end
+
+ # Remove all traces of a given host
+ def self.destroy(name)
+ [Key, Certificate, CertificateRequest].collect { |part| part.destroy(name) }.any? { |x| x }
+ end
+
+ # Search for more than one host, optionally only specifying
+ # an interest in hosts with a given file type.
+ # This just allows our non-indirected class to have one of
+ # indirection methods.
+ def self.search(options = {})
+ classlist = [options[:for] || [Key, CertificateRequest, Certificate]].flatten
+
+ # Collect the results from each class, flatten them, collect all of the names, make the name list unique,
+ # then create a Host instance for each one.
+ classlist.collect { |klass| klass.search }.flatten.collect { |r| r.name }.uniq.collect do |name|
+ new(name)
end
-
- CA_MODES = {
- # Our ca is local, so we use it as the ultimate source of information
- # And we cache files locally.
- :local => [:ca, :file],
- # We're a remote CA client.
- :remote => [:rest, :file],
- # We are the CA, so we don't have read/write access to the normal certificates.
- :only => [:ca],
- # We have no CA, so we just look in the local file store.
- :none => [:file]
- }
-
- # Specify how we expect to interact with our certificate authority.
- def self.ca_location=(mode)
- raise ArgumentError, "CA Mode can only be #{CA_MODES.collect { |m| m.to_s }.join(", ")}" unless CA_MODES.include?(mode)
-
- @ca_location = mode
-
- configure_indirection(*CA_MODES[@ca_location])
+ end
+
+ # Is this a ca host, meaning that all of its files go in the CA location?
+ def ca?
+ ca
+ end
+
+ def key
+ @key ||= Key.find(name)
+ end
+
+ # This is the private key; we can create it from scratch
+ # with no inputs.
+ def generate_key
+ @key = Key.new(name)
+ @key.generate
+ begin
+ @key.save
+ rescue
+ @key = nil
+ raise
end
-
- # Remove all traces of a given host
- def self.destroy(name)
- [Key, Certificate, CertificateRequest].collect { |part| part.destroy(name) }.any? { |x| x }
+ true
+ end
+
+ def certificate_request
+ @certificate_request ||= CertificateRequest.find(name)
+ end
+
+ # Our certificate request requires the key but that's all.
+ def generate_certificate_request
+ generate_key unless key
+ @certificate_request = CertificateRequest.new(name)
+ @certificate_request.generate(key.content)
+ begin
+ @certificate_request.save
+ rescue
+ @certificate_request = nil
+ raise
end
- # Search for more than one host, optionally only specifying
- # an interest in hosts with a given file type.
- # This just allows our non-indirected class to have one of
- # indirection methods.
- def self.search(options = {})
- classlist = [options[:for] || [Key, CertificateRequest, Certificate]].flatten
-
- # Collect the results from each class, flatten them, collect all of the names, make the name list unique,
- # then create a Host instance for each one.
- classlist.collect { |klass| klass.search }.flatten.collect { |r| r.name }.uniq.collect do |name|
- new(name)
- end
- end
+ true
+ end
- # Is this a ca host, meaning that all of its files go in the CA location?
- def ca?
- ca
- end
+ def certificate
+ unless @certificate
+ generate_key unless key
- def key
- @key ||= Key.find(name)
- end
+ # get the CA cert first, since it's required for the normal cert
+ # to be of any use.
+ return nil unless Certificate.find("ca") unless ca?
+ return nil unless @certificate = Certificate.find(name)
- # This is the private key; we can create it from scratch
- # with no inputs.
- def generate_key
- @key = Key.new(name)
- @key.generate
- begin
- @key.save
- rescue
- @key = nil
- raise
- end
- true
+ unless certificate_matches_key?
+ raise Puppet::Error, "Retrieved certificate does not match private key; please remove certificate from server and regenerate it with the current key"
+ end
end
-
- def certificate_request
- @certificate_request ||= CertificateRequest.find(name)
+ @certificate
+ end
+
+ def certificate_matches_key?
+ return false unless key
+ return false unless certificate
+
+ certificate.content.check_private_key(key.content)
+ end
+
+ # Generate all necessary parts of our ssl host.
+ def generate
+ generate_key unless key
+ generate_certificate_request unless certificate_request
+
+ # If we can get a CA instance, then we're a valid CA, and we
+ # should use it to sign our request; else, just try to read
+ # the cert.
+ if ! certificate and ca = Puppet::SSL::CertificateAuthority.instance
+ ca.sign(self.name)
end
-
- # Our certificate request requires the key but that's all.
- def generate_certificate_request
- generate_key unless key
- @certificate_request = CertificateRequest.new(name)
- @certificate_request.generate(key.content)
- begin
- @certificate_request.save
- rescue
- @certificate_request = nil
- raise
- end
-
- true
+ end
+
+ def initialize(name = nil)
+ @name = (name || Puppet[:certname]).downcase
+ @key = @certificate = @certificate_request = nil
+ @ca = (name == self.class.ca_name)
+ end
+
+ # Extract the public key from the private key.
+ def public_key
+ key.content.public_key
+ end
+
+ # Create/return a store that uses our SSL info to validate
+ # connections.
+ def ssl_store(purpose = OpenSSL::X509::PURPOSE_ANY)
+ unless @ssl_store
+ @ssl_store = OpenSSL::X509::Store.new
+ @ssl_store.purpose = purpose
+
+ # Use the file path here, because we don't want to cause
+ # a lookup in the middle of setting our ssl connection.
+ @ssl_store.add_file(Puppet[:localcacert])
+
+ # If there's a CRL, add it to our store.
+ if crl = Puppet::SSL::CertificateRevocationList.find(CA_NAME)
+ @ssl_store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK if Puppet.settings[:certificate_revocation]
+ @ssl_store.add_crl(crl.content)
+ end
+ return @ssl_store
end
-
- def certificate
- unless @certificate
- generate_key unless key
-
- # get the CA cert first, since it's required for the normal cert
- # to be of any use.
- return nil unless Certificate.find("ca") unless ca?
- return nil unless @certificate = Certificate.find(name)
-
- unless certificate_matches_key?
- raise Puppet::Error, "Retrieved certificate does not match private key; please remove certificate from server and regenerate it with the current key"
- end
- end
- @certificate
- end
-
- def certificate_matches_key?
- return false unless key
- return false unless certificate
-
- certificate.content.check_private_key(key.content)
- end
-
- # Generate all necessary parts of our ssl host.
- def generate
- generate_key unless key
- generate_certificate_request unless certificate_request
-
- # If we can get a CA instance, then we're a valid CA, and we
- # should use it to sign our request; else, just try to read
- # the cert.
- if ! certificate and ca = Puppet::SSL::CertificateAuthority.instance
- ca.sign(self.name)
- end
- end
-
- def initialize(name = nil)
- @name = (name || Puppet[:certname]).downcase
- @key = @certificate = @certificate_request = nil
- @ca = (name == self.class.ca_name)
- end
-
- # Extract the public key from the private key.
- def public_key
- key.content.public_key
+ @ssl_store
+ end
+
+ # Attempt to retrieve a cert, if we don't already have one.
+ def wait_for_cert(time)
+ begin
+ return if certificate
+ generate
+ return if certificate
+ rescue SystemExit,NoMemoryError
+ raise
+ rescue Exception => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Could not request certificate: #{detail}"
+ if time < 1
+ puts "Exiting; failed to retrieve certificate and waitforcert is disabled"
+ exit(1)
+ else
+ sleep(time)
+ end
+ retry
end
- # Create/return a store that uses our SSL info to validate
- # connections.
- def ssl_store(purpose = OpenSSL::X509::PURPOSE_ANY)
- unless @ssl_store
- @ssl_store = OpenSSL::X509::Store.new
- @ssl_store.purpose = purpose
-
- # Use the file path here, because we don't want to cause
- # a lookup in the middle of setting our ssl connection.
- @ssl_store.add_file(Puppet[:localcacert])
-
- # If there's a CRL, add it to our store.
- if crl = Puppet::SSL::CertificateRevocationList.find(CA_NAME)
- @ssl_store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK if Puppet.settings[:certificate_revocation]
- @ssl_store.add_crl(crl.content)
- end
- return @ssl_store
- end
- @ssl_store
+ if time < 1
+ puts "Exiting; no certificate found and waitforcert is disabled"
+ exit(1)
end
- # Attempt to retrieve a cert, if we don't already have one.
- def wait_for_cert(time)
- begin
- return if certificate
- generate
- return if certificate
- rescue SystemExit,NoMemoryError
- raise
- rescue Exception => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Could not request certificate: #{detail}"
- if time < 1
- puts "Exiting; failed to retrieve certificate and waitforcert is disabled"
- exit(1)
- else
- sleep(time)
- end
- retry
- end
-
- if time < 1
- puts "Exiting; no certificate found and waitforcert is disabled"
- exit(1)
- end
-
- while true
- sleep time
- begin
- break if certificate
- Puppet.notice "Did not receive certificate"
- rescue StandardError => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Could not request certificate: #{detail}"
- end
- end
+ while true
+ sleep time
+ begin
+ break if certificate
+ Puppet.notice "Did not receive certificate"
+ rescue StandardError => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Could not request certificate: #{detail}"
+ end
end
+ end
end
require 'puppet/ssl/certificate_authority'
diff --git a/lib/puppet/ssl/inventory.rb b/lib/puppet/ssl/inventory.rb
index 6fb2ea8..b2b402a 100644
--- a/lib/puppet/ssl/inventory.rb
+++ b/lib/puppet/ssl/inventory.rb
@@ -3,50 +3,50 @@ require 'puppet/ssl/certificate'
# Keep track of all of our known certificates.
class Puppet::SSL::Inventory
- attr_reader :path
+ attr_reader :path
- # Add a certificate to our inventory.
- def add(cert)
- cert = cert.content if cert.is_a?(Puppet::SSL::Certificate)
+ # Add a certificate to our inventory.
+ def add(cert)
+ cert = cert.content if cert.is_a?(Puppet::SSL::Certificate)
- # Create our file, if one does not already exist.
- rebuild unless FileTest.exist?(@path)
+ # Create our file, if one does not already exist.
+ rebuild unless FileTest.exist?(@path)
- Puppet.settings.write(:cert_inventory, "a") do |f|
- f.print format(cert)
- end
+ Puppet.settings.write(:cert_inventory, "a") do |f|
+ f.print format(cert)
end
+ end
- # Format our certificate for output.
- def format(cert)
- iso = '%Y-%m-%dT%H:%M:%S%Z'
- "0x%04x %s %s %s\n" % [cert.serial, cert.not_before.strftime(iso), cert.not_after.strftime(iso), cert.subject]
- end
-
- def initialize
- @path = Puppet[:cert_inventory]
- end
+ # Format our certificate for output.
+ def format(cert)
+ iso = '%Y-%m-%dT%H:%M:%S%Z'
+ "0x%04x %s %s %s\n" % [cert.serial, cert.not_before.strftime(iso), cert.not_after.strftime(iso), cert.subject]
+ end
- # Rebuild the inventory from scratch. This should happen if
- # the file is entirely missing or if it's somehow corrupted.
- def rebuild
- Puppet.notice "Rebuilding inventory file"
+ def initialize
+ @path = Puppet[:cert_inventory]
+ end
- Puppet.settings.write(:cert_inventory) do |f|
- f.print "# Inventory of signed certificates\n# SERIAL NOT_BEFORE NOT_AFTER SUBJECT\n"
- end
+ # Rebuild the inventory from scratch. This should happen if
+ # the file is entirely missing or if it's somehow corrupted.
+ def rebuild
+ Puppet.notice "Rebuilding inventory file"
- Puppet::SSL::Certificate.search("*").each { |cert| add(cert) }
+ Puppet.settings.write(:cert_inventory) do |f|
+ f.print "# Inventory of signed certificates\n# SERIAL NOT_BEFORE NOT_AFTER SUBJECT\n"
end
- # Find the serial number for a given certificate.
- def serial(name)
- return nil unless FileTest.exist?(@path)
+ Puppet::SSL::Certificate.search("*").each { |cert| add(cert) }
+ end
+
+ # Find the serial number for a given certificate.
+ def serial(name)
+ return nil unless FileTest.exist?(@path)
- File.readlines(@path).each do |line|
- next unless line =~ /^(\S+).+\/CN=#{name}$/
+ File.readlines(@path).each do |line|
+ next unless line =~ /^(\S+).+\/CN=#{name}$/
- return Integer($1)
- end
+ return Integer($1)
end
+ end
end
diff --git a/lib/puppet/ssl/key.rb b/lib/puppet/ssl/key.rb
index cb03729..0ddc962 100644
--- a/lib/puppet/ssl/key.rb
+++ b/lib/puppet/ssl/key.rb
@@ -3,54 +3,54 @@ require 'puppet/indirector'
# Manage private and public keys as a pair.
class Puppet::SSL::Key < Puppet::SSL::Base
- wraps OpenSSL::PKey::RSA
+ wraps OpenSSL::PKey::RSA
- extend Puppet::Indirector
- indirects :key, :terminus_class => :file
+ extend Puppet::Indirector
+ indirects :key, :terminus_class => :file
- # Because of how the format handler class is included, this
- # can't be in the base class.
- def self.supported_formats
- [:s]
- end
+ # Because of how the format handler class is included, this
+ # can't be in the base class.
+ def self.supported_formats
+ [:s]
+ end
- attr_accessor :password_file
+ attr_accessor :password_file
- # Knows how to create keys with our system defaults.
- def generate
- Puppet.info "Creating a new SSL key for #{name}"
- @content = OpenSSL::PKey::RSA.new(Puppet[:keylength].to_i)
- end
+ # Knows how to create keys with our system defaults.
+ def generate
+ Puppet.info "Creating a new SSL key for #{name}"
+ @content = OpenSSL::PKey::RSA.new(Puppet[:keylength].to_i)
+ end
- def initialize(name)
- super
+ def initialize(name)
+ super
- if ca?
- @password_file = Puppet[:capass]
- else
- @password_file = Puppet[:passfile]
- end
+ if ca?
+ @password_file = Puppet[:capass]
+ else
+ @password_file = Puppet[:passfile]
end
+ end
- def password
- return nil unless password_file and FileTest.exist?(password_file)
+ def password
+ return nil unless password_file and FileTest.exist?(password_file)
- ::File.read(password_file)
- end
+ ::File.read(password_file)
+ end
- # Optionally support specifying a password file.
- def read(path)
- return super unless password_file
+ # Optionally support specifying a password file.
+ def read(path)
+ return super unless password_file
- #@content = wrapped_class.new(::File.read(path), password)
- @content = wrapped_class.new(::File.read(path), password)
- end
+ #@content = wrapped_class.new(::File.read(path), password)
+ @content = wrapped_class.new(::File.read(path), password)
+ end
- def to_s
- if pass = password
- @content.export(OpenSSL::Cipher::DES.new(:EDE3, :CBC), pass)
- else
- return super
- end
+ def to_s
+ if pass = password
+ @content.export(OpenSSL::Cipher::DES.new(:EDE3, :CBC), pass)
+ else
+ return super
end
+ end
end
diff --git a/lib/puppet/sslcertificates.rb b/lib/puppet/sslcertificates.rb
index 02cb9fe..4e94124 100755
--- a/lib/puppet/sslcertificates.rb
+++ b/lib/puppet/sslcertificates.rb
@@ -5,142 +5,142 @@ require 'puppet'
raise Puppet::Error, "You must have the Ruby openssl library installed" unless Puppet.features.openssl?
module Puppet::SSLCertificates
- #def self.mkcert(type, name, dnsnames, ttl, issuercert, issuername, serial, publickey)
- def self.mkcert(hash)
- [:type, :name, :ttl, :issuer, :serial, :publickey].each { |param|
- raise ArgumentError, "mkcert called without #{param}" unless hash.include?(param)
- }
-
- cert = OpenSSL::X509::Certificate.new
- # Make the certificate valid as of yesterday, because
- # so many people's clocks are out of sync.
- from = Time.now - (60*60*24)
-
- cert.subject = hash[:name]
- if hash[:issuer]
- cert.issuer = hash[:issuer].subject
- else
- # we're a self-signed cert
- cert.issuer = hash[:name]
- end
- cert.not_before = from
- cert.not_after = from + hash[:ttl]
- cert.version = 2 # X509v3
-
- cert.public_key = hash[:publickey]
- cert.serial = hash[:serial]
-
- basic_constraint = nil
- key_usage = nil
- ext_key_usage = nil
- subject_alt_name = []
-
- ef = OpenSSL::X509::ExtensionFactory.new
-
- ef.subject_certificate = cert
-
- if hash[:issuer]
- ef.issuer_certificate = hash[:issuer]
- else
- ef.issuer_certificate = cert
- end
-
- ex = []
- case hash[:type]
- when :ca
- basic_constraint = "CA:TRUE"
- key_usage = %w{cRLSign keyCertSign}
- when :terminalsubca
- basic_constraint = "CA:TRUE,pathlen:0"
- key_usage = %w{cRLSign keyCertSign}
- when :server
- basic_constraint = "CA:FALSE"
- dnsnames = Puppet[:certdnsnames]
- name = hash[:name].to_s.sub(%r{/CN=},'')
- if dnsnames != ""
- dnsnames.split(':').each { |d| subject_alt_name << 'DNS:' + d }
- subject_alt_name << 'DNS:' + name # Add the fqdn as an alias
- elsif name == Facter.value(:fqdn) # we're a CA server, and thus probably the server
- subject_alt_name << 'DNS:' + "puppet" # Add 'puppet' as an alias
- subject_alt_name << 'DNS:' + name # Add the fqdn as an alias
- subject_alt_name << 'DNS:' + name.sub(/^[^.]+./, "puppet.") # add puppet.domain as an alias
- end
- key_usage = %w{digitalSignature keyEncipherment}
- ext_key_usage = %w{serverAuth clientAuth emailProtection}
- when :ocsp
- basic_constraint = "CA:FALSE"
- key_usage = %w{nonRepudiation digitalSignature}
- ext_key_usage = %w{serverAuth OCSPSigning}
- when :client
- basic_constraint = "CA:FALSE"
- key_usage = %w{nonRepudiation digitalSignature keyEncipherment}
- ext_key_usage = %w{clientAuth emailProtection}
- ex << ef.create_extension("nsCertType", "client,email")
- else
- raise Puppet::Error, "unknown cert type '#{hash[:type]}'"
- end
-
-
- ex << ef.create_extension(
- "nsComment",
+ #def self.mkcert(type, name, dnsnames, ttl, issuercert, issuername, serial, publickey)
+ def self.mkcert(hash)
+ [:type, :name, :ttl, :issuer, :serial, :publickey].each { |param|
+ raise ArgumentError, "mkcert called without #{param}" unless hash.include?(param)
+ }
+
+ cert = OpenSSL::X509::Certificate.new
+ # Make the certificate valid as of yesterday, because
+ # so many people's clocks are out of sync.
+ from = Time.now - (60*60*24)
+
+ cert.subject = hash[:name]
+ if hash[:issuer]
+ cert.issuer = hash[:issuer].subject
+ else
+ # we're a self-signed cert
+ cert.issuer = hash[:name]
+ end
+ cert.not_before = from
+ cert.not_after = from + hash[:ttl]
+ cert.version = 2 # X509v3
- "Puppet Ruby/OpenSSL Generated Certificate")
- ex << ef.create_extension("basicConstraints", basic_constraint, true)
- ex << ef.create_extension("subjectKeyIdentifier", "hash")
+ cert.public_key = hash[:publickey]
+ cert.serial = hash[:serial]
- ex << ef.create_extension("keyUsage", key_usage.join(",")) if key_usage
- ex << ef.create_extension("extendedKeyUsage", ext_key_usage.join(",")) if ext_key_usage
- ex << ef.create_extension("subjectAltName", subject_alt_name.join(",")) if ! subject_alt_name.empty?
+ basic_constraint = nil
+ key_usage = nil
+ ext_key_usage = nil
+ subject_alt_name = []
- #if @ca_config[:cdp_location] then
- # ex << ef.create_extension("crlDistributionPoints",
- # @ca_config[:cdp_location])
- #end
+ ef = OpenSSL::X509::ExtensionFactory.new
- #if @ca_config[:ocsp_location] then
- # ex << ef.create_extension("authorityInfoAccess",
- # "OCSP;" << @ca_config[:ocsp_location])
- #end
- cert.extensions = ex
+ ef.subject_certificate = cert
- # for some reason this _must_ be the last extension added
- ex << ef.create_extension("authorityKeyIdentifier", "keyid:always,issuer:always") if hash[:type] == :ca
+ if hash[:issuer]
+ ef.issuer_certificate = hash[:issuer]
+ else
+ ef.issuer_certificate = cert
+ end
- cert
+ ex = []
+ case hash[:type]
+ when :ca
+ basic_constraint = "CA:TRUE"
+ key_usage = %w{cRLSign keyCertSign}
+ when :terminalsubca
+ basic_constraint = "CA:TRUE,pathlen:0"
+ key_usage = %w{cRLSign keyCertSign}
+ when :server
+ basic_constraint = "CA:FALSE"
+ dnsnames = Puppet[:certdnsnames]
+ name = hash[:name].to_s.sub(%r{/CN=},'')
+ if dnsnames != ""
+ dnsnames.split(':').each { |d| subject_alt_name << 'DNS:' + d }
+ subject_alt_name << 'DNS:' + name # Add the fqdn as an alias
+ elsif name == Facter.value(:fqdn) # we're a CA server, and thus probably the server
+ subject_alt_name << 'DNS:' + "puppet" # Add 'puppet' as an alias
+ subject_alt_name << 'DNS:' + name # Add the fqdn as an alias
+ subject_alt_name << 'DNS:' + name.sub(/^[^.]+./, "puppet.") # add puppet.domain as an alias
+ end
+ key_usage = %w{digitalSignature keyEncipherment}
+ ext_key_usage = %w{serverAuth clientAuth emailProtection}
+ when :ocsp
+ basic_constraint = "CA:FALSE"
+ key_usage = %w{nonRepudiation digitalSignature}
+ ext_key_usage = %w{serverAuth OCSPSigning}
+ when :client
+ basic_constraint = "CA:FALSE"
+ key_usage = %w{nonRepudiation digitalSignature keyEncipherment}
+ ext_key_usage = %w{clientAuth emailProtection}
+ ex << ef.create_extension("nsCertType", "client,email")
+ else
+ raise Puppet::Error, "unknown cert type '#{hash[:type]}'"
end
- def self.mkhash(dir, cert, certfile)
- # Make sure the hash is zero-padded to 8 chars
- hash = "%08x" % cert.issuer.hash
- hashpath = nil
- 10.times { |i|
- path = File.join(dir, "#{hash}.#{i}")
- if FileTest.exists?(path)
- if FileTest.symlink?(path)
- dest = File.readlink(path)
- if dest == certfile
- # the correct link already exists
- hashpath = path
- break
- else
- next
- end
- else
- next
- end
- end
-
- File.symlink(certfile, path)
+ ex << ef.create_extension(
+ "nsComment",
+
+ "Puppet Ruby/OpenSSL Generated Certificate")
+ ex << ef.create_extension("basicConstraints", basic_constraint, true)
+ ex << ef.create_extension("subjectKeyIdentifier", "hash")
+
+ ex << ef.create_extension("keyUsage", key_usage.join(",")) if key_usage
+ ex << ef.create_extension("extendedKeyUsage", ext_key_usage.join(",")) if ext_key_usage
+ ex << ef.create_extension("subjectAltName", subject_alt_name.join(",")) if ! subject_alt_name.empty?
+
+ #if @ca_config[:cdp_location] then
+ # ex << ef.create_extension("crlDistributionPoints",
+ # @ca_config[:cdp_location])
+ #end
+
+ #if @ca_config[:ocsp_location] then
+ # ex << ef.create_extension("authorityInfoAccess",
+ # "OCSP;" << @ca_config[:ocsp_location])
+ #end
+ cert.extensions = ex
+
+ # for some reason this _must_ be the last extension added
+ ex << ef.create_extension("authorityKeyIdentifier", "keyid:always,issuer:always") if hash[:type] == :ca
+
+ cert
+ end
+
+ def self.mkhash(dir, cert, certfile)
+ # Make sure the hash is zero-padded to 8 chars
+ hash = "%08x" % cert.issuer.hash
+ hashpath = nil
+ 10.times { |i|
+ path = File.join(dir, "#{hash}.#{i}")
+ if FileTest.exists?(path)
+ if FileTest.symlink?(path)
+ dest = File.readlink(path)
+ if dest == certfile
+ # the correct link already exists
hashpath = path
break
- }
+ else
+ next
+ end
+ else
+ next
+ end
+ end
+ File.symlink(certfile, path)
- hashpath
- end
- require 'puppet/sslcertificates/certificate'
- require 'puppet/sslcertificates/inventory'
- require 'puppet/sslcertificates/ca'
+ hashpath = path
+ break
+ }
+
+
+ hashpath
+ end
+ require 'puppet/sslcertificates/certificate'
+ require 'puppet/sslcertificates/inventory'
+ require 'puppet/sslcertificates/ca'
end
diff --git a/lib/puppet/sslcertificates/ca.rb b/lib/puppet/sslcertificates/ca.rb
index e9e66bc..63e6b92 100644
--- a/lib/puppet/sslcertificates/ca.rb
+++ b/lib/puppet/sslcertificates/ca.rb
@@ -1,381 +1,381 @@
require 'sync'
class Puppet::SSLCertificates::CA
- include Puppet::Util::Warnings
+ include Puppet::Util::Warnings
- Certificate = Puppet::SSLCertificates::Certificate
- attr_accessor :keyfile, :file, :config, :dir, :cert, :crl
+ Certificate = Puppet::SSLCertificates::Certificate
+ attr_accessor :keyfile, :file, :config, :dir, :cert, :crl
- def certfile
- @config[:cacert]
- end
-
- # Remove all traces of a given host. This is kind of hackish, but, eh.
- def clean(host)
- host = host.downcase
- [:csrdir, :signeddir, :publickeydir, :privatekeydir, :certdir].each do |name|
- dir = Puppet[name]
-
- file = File.join(dir, host + ".pem")
-
- if FileTest.exists?(file)
- begin
- if Puppet[:name] == "cert"
- puts "Removing #{file}"
- else
- Puppet.info "Removing #{file}"
- end
- File.unlink(file)
- rescue => detail
- raise Puppet::Error, "Could not delete #{file}: #{detail}"
- end
- end
-
- end
- end
-
- def host2csrfile(hostname)
- File.join(Puppet[:csrdir], [hostname.downcase, "pem"].join("."))
- end
+ def certfile
+ @config[:cacert]
+ end
- # this stores signed certs in a directory unrelated to
- # normal client certs
- def host2certfile(hostname)
- File.join(Puppet[:signeddir], [hostname.downcase, "pem"].join("."))
- end
-
- # Turn our hostname into a Name object
- def thing2name(thing)
- thing.subject.to_a.find { |ary|
- ary[0] == "CN"
- }[1]
- end
-
- def initialize(hash = {})
- Puppet.settings.use(:main, :ca, :ssl)
- self.setconfig(hash)
-
- if Puppet[:capass]
- if FileTest.exists?(Puppet[:capass])
- #puts "Reading #{Puppet[:capass]}"
- #system "ls -al #{Puppet[:capass]}"
- #File.read Puppet[:capass]
- @config[:password] = self.getpass
- else
- # Don't create a password if the cert already exists
- @config[:password] = self.genpass unless FileTest.exists?(@config[:cacert])
- end
- end
-
- self.getcert
- init_crl
- unless FileTest.exists?(@config[:serial])
- Puppet.settings.write(:serial) do |f|
- f << "%04X" % 1
- end
- end
- end
+ # Remove all traces of a given host. This is kind of hackish, but, eh.
+ def clean(host)
+ host = host.downcase
+ [:csrdir, :signeddir, :publickeydir, :privatekeydir, :certdir].each do |name|
+ dir = Puppet[name]
- # Generate a new password for the CA.
- def genpass
- pass = ""
- 20.times { pass += (rand(74) + 48).chr }
+ file = File.join(dir, host + ".pem")
+ if FileTest.exists?(file)
begin
- Puppet.settings.write(:capass) { |f| f.print pass }
- rescue Errno::EACCES => detail
- raise Puppet::Error, detail.to_s
+ if Puppet[:name] == "cert"
+ puts "Removing #{file}"
+ else
+ Puppet.info "Removing #{file}"
+ end
+ File.unlink(file)
+ rescue => detail
+ raise Puppet::Error, "Could not delete #{file}: #{detail}"
end
- pass
- end
+ end
- # Get the CA password.
- def getpass
- if @config[:capass] and File.readable?(@config[:capass])
- return File.read(@config[:capass])
- else
- raise Puppet::Error, "Could not decrypt CA key with password: #{detail}"
- end
end
-
- # Get the CA cert.
- def getcert
- if FileTest.exists?(@config[:cacert])
- @cert = OpenSSL::X509::Certificate.new(
- File.read(@config[:cacert])
- )
- else
- self.mkrootcert
- end
+ end
+
+ def host2csrfile(hostname)
+ File.join(Puppet[:csrdir], [hostname.downcase, "pem"].join("."))
+ end
+
+ # this stores signed certs in a directory unrelated to
+ # normal client certs
+ def host2certfile(hostname)
+ File.join(Puppet[:signeddir], [hostname.downcase, "pem"].join("."))
+ end
+
+ # Turn our hostname into a Name object
+ def thing2name(thing)
+ thing.subject.to_a.find { |ary|
+ ary[0] == "CN"
+ }[1]
+ end
+
+ def initialize(hash = {})
+ Puppet.settings.use(:main, :ca, :ssl)
+ self.setconfig(hash)
+
+ if Puppet[:capass]
+ if FileTest.exists?(Puppet[:capass])
+ #puts "Reading #{Puppet[:capass]}"
+ #system "ls -al #{Puppet[:capass]}"
+ #File.read Puppet[:capass]
+ @config[:password] = self.getpass
+ else
+ # Don't create a password if the cert already exists
+ @config[:password] = self.genpass unless FileTest.exists?(@config[:cacert])
+ end
end
- # Retrieve a client's CSR.
- def getclientcsr(host)
- csrfile = host2csrfile(host)
- return nil unless File.exists?(csrfile)
-
- OpenSSL::X509::Request.new(File.read(csrfile))
+ self.getcert
+ init_crl
+ unless FileTest.exists?(@config[:serial])
+ Puppet.settings.write(:serial) do |f|
+ f << "%04X" % 1
+ end
end
+ end
- # Retrieve a client's certificate.
- def getclientcert(host)
- certfile = host2certfile(host)
- return [nil, nil] unless File.exists?(certfile)
+ # Generate a new password for the CA.
+ def genpass
+ pass = ""
+ 20.times { pass += (rand(74) + 48).chr }
- [OpenSSL::X509::Certificate.new(File.read(certfile)), @cert]
+ begin
+ Puppet.settings.write(:capass) { |f| f.print pass }
+ rescue Errno::EACCES => detail
+ raise Puppet::Error, detail.to_s
end
-
- # List certificates waiting to be signed. This returns a list of hostnames, not actual
- # files -- the names can be converted to full paths with host2csrfile.
- def list(dummy_argument=:work_arround_for_ruby_GC_bug)
- return Dir.entries(Puppet[:csrdir]).find_all { |file|
- file =~ /\.pem$/
- }.collect { |file|
- file.sub(/\.pem$/, '')
- }
+ pass
+ end
+
+ # Get the CA password.
+ def getpass
+ if @config[:capass] and File.readable?(@config[:capass])
+ return File.read(@config[:capass])
+ else
+ raise Puppet::Error, "Could not decrypt CA key with password: #{detail}"
end
-
- # List signed certificates. This returns a list of hostnames, not actual
- # files -- the names can be converted to full paths with host2csrfile.
- def list_signed(dummy_argument=:work_arround_for_ruby_GC_bug)
- return Dir.entries(Puppet[:signeddir]).find_all { |file|
- file =~ /\.pem$/
- }.collect { |file|
- file.sub(/\.pem$/, '')
- }
+ end
+
+ # Get the CA cert.
+ def getcert
+ if FileTest.exists?(@config[:cacert])
+ @cert = OpenSSL::X509::Certificate.new(
+ File.read(@config[:cacert])
+ )
+ else
+ self.mkrootcert
+ end
+ end
+
+ # Retrieve a client's CSR.
+ def getclientcsr(host)
+ csrfile = host2csrfile(host)
+ return nil unless File.exists?(csrfile)
+
+ OpenSSL::X509::Request.new(File.read(csrfile))
+ end
+
+ # Retrieve a client's certificate.
+ def getclientcert(host)
+ certfile = host2certfile(host)
+ return [nil, nil] unless File.exists?(certfile)
+
+ [OpenSSL::X509::Certificate.new(File.read(certfile)), @cert]
+ end
+
+ # List certificates waiting to be signed. This returns a list of hostnames, not actual
+ # files -- the names can be converted to full paths with host2csrfile.
+ def list(dummy_argument=:work_arround_for_ruby_GC_bug)
+ return Dir.entries(Puppet[:csrdir]).find_all { |file|
+ file =~ /\.pem$/
+ }.collect { |file|
+ file.sub(/\.pem$/, '')
+ }
+ end
+
+ # List signed certificates. This returns a list of hostnames, not actual
+ # files -- the names can be converted to full paths with host2csrfile.
+ def list_signed(dummy_argument=:work_arround_for_ruby_GC_bug)
+ return Dir.entries(Puppet[:signeddir]).find_all { |file|
+ file =~ /\.pem$/
+ }.collect { |file|
+ file.sub(/\.pem$/, '')
+ }
+ end
+
+ # Create the root certificate.
+ def mkrootcert
+ # Make the root cert's name the FQDN of the host running the CA.
+ name = Facter["hostname"].value
+ if domain = Facter["domain"].value
+ name += ".#{domain}"
end
- # Create the root certificate.
- def mkrootcert
- # Make the root cert's name the FQDN of the host running the CA.
- name = Facter["hostname"].value
- if domain = Facter["domain"].value
- name += ".#{domain}"
- end
-
- cert = Certificate.new(
+ cert = Certificate.new(
- :name => name,
- :cert => @config[:cacert],
- :encrypt => @config[:capass],
- :key => @config[:cakey],
- :selfsign => true,
- :ttl => ttl,
+ :name => name,
+ :cert => @config[:cacert],
+ :encrypt => @config[:capass],
+ :key => @config[:cakey],
+ :selfsign => true,
+ :ttl => ttl,
- :type => :ca
- )
+ :type => :ca
+ )
- # This creates the cakey file
- Puppet::Util::SUIDManager.asuser(Puppet[:user], Puppet[:group]) do
- @cert = cert.mkselfsigned
- end
- Puppet.settings.write(:cacert) do |f|
- f.puts @cert.to_pem
- end
- Puppet.settings.write(:capub) do |f|
- f.puts @cert.public_key
- end
- cert
+ # This creates the cakey file
+ Puppet::Util::SUIDManager.asuser(Puppet[:user], Puppet[:group]) do
+ @cert = cert.mkselfsigned
end
-
- def removeclientcsr(host)
- csrfile = host2csrfile(host)
- raise Puppet::Error, "No certificate request for #{host}" unless File.exists?(csrfile)
-
- File.unlink(csrfile)
+ Puppet.settings.write(:cacert) do |f|
+ f.puts @cert.to_pem
end
-
- # Revoke the certificate with serial number SERIAL issued by this
- # CA. The REASON must be one of the OpenSSL::OCSP::REVOKED_* reasons
- def revoke(serial, reason = OpenSSL::OCSP::REVOKED_STATUS_KEYCOMPROMISE)
- time = Time.now
- revoked = OpenSSL::X509::Revoked.new
- revoked.serial = serial
- revoked.time = time
- enum = OpenSSL::ASN1::Enumerated(reason)
- ext = OpenSSL::X509::Extension.new("CRLReason", enum)
- revoked.add_extension(ext)
- @crl.add_revoked(revoked)
- store_crl
+ Puppet.settings.write(:capub) do |f|
+ f.puts @cert.public_key
+ end
+ cert
+ end
+
+ def removeclientcsr(host)
+ csrfile = host2csrfile(host)
+ raise Puppet::Error, "No certificate request for #{host}" unless File.exists?(csrfile)
+
+ File.unlink(csrfile)
+ end
+
+ # Revoke the certificate with serial number SERIAL issued by this
+ # CA. The REASON must be one of the OpenSSL::OCSP::REVOKED_* reasons
+ def revoke(serial, reason = OpenSSL::OCSP::REVOKED_STATUS_KEYCOMPROMISE)
+ time = Time.now
+ revoked = OpenSSL::X509::Revoked.new
+ revoked.serial = serial
+ revoked.time = time
+ enum = OpenSSL::ASN1::Enumerated(reason)
+ ext = OpenSSL::X509::Extension.new("CRLReason", enum)
+ revoked.add_extension(ext)
+ @crl.add_revoked(revoked)
+ store_crl
+ end
+
+ # Take the Puppet config and store it locally.
+ def setconfig(hash)
+ @config = {}
+ Puppet.settings.params("ca").each { |param|
+ param = param.intern if param.is_a? String
+ if hash.include?(param)
+ @config[param] = hash[param]
+ Puppet[param] = hash[param]
+ hash.delete(param)
+ else
+ @config[param] = Puppet[param]
+ end
+ }
+
+ if hash.include?(:password)
+ @config[:password] = hash[:password]
+ hash.delete(:password)
end
- # Take the Puppet config and store it locally.
- def setconfig(hash)
- @config = {}
- Puppet.settings.params("ca").each { |param|
- param = param.intern if param.is_a? String
- if hash.include?(param)
- @config[param] = hash[param]
- Puppet[param] = hash[param]
- hash.delete(param)
- else
- @config[param] = Puppet[param]
- end
- }
-
- if hash.include?(:password)
- @config[:password] = hash[:password]
- hash.delete(:password)
- end
+ raise ArgumentError, "Unknown parameters #{hash.keys.join(",")}" if hash.length > 0
- raise ArgumentError, "Unknown parameters #{hash.keys.join(",")}" if hash.length > 0
+ [:cadir, :csrdir, :signeddir].each { |dir|
+ raise Puppet::DevError, "#{dir} is undefined" unless @config[dir]
+ }
+ end
- [:cadir, :csrdir, :signeddir].each { |dir|
- raise Puppet::DevError, "#{dir} is undefined" unless @config[dir]
- }
+ # Sign a given certificate request.
+ def sign(csr)
+ unless csr.is_a?(OpenSSL::X509::Request)
+ raise Puppet::Error,
+ "CA#sign only accepts OpenSSL::X509::Request objects, not #{csr.class}"
end
- # Sign a given certificate request.
- def sign(csr)
- unless csr.is_a?(OpenSSL::X509::Request)
- raise Puppet::Error,
- "CA#sign only accepts OpenSSL::X509::Request objects, not #{csr.class}"
- end
-
- raise Puppet::Error, "CSR sign verification failed" unless csr.verify(csr.public_key)
+ raise Puppet::Error, "CSR sign verification failed" unless csr.verify(csr.public_key)
- serial = nil
- Puppet.settings.readwritelock(:serial) { |f|
- serial = File.read(@config[:serial]).chomp.hex
- # increment the serial
- f << "%04X" % (serial + 1)
- }
+ serial = nil
+ Puppet.settings.readwritelock(:serial) { |f|
+ serial = File.read(@config[:serial]).chomp.hex
+ # increment the serial
+ f << "%04X" % (serial + 1)
+ }
- newcert = Puppet::SSLCertificates.mkcert(
+ newcert = Puppet::SSLCertificates.mkcert(
- :type => :server,
- :name => csr.subject,
- :ttl => ttl,
- :issuer => @cert,
- :serial => serial,
+ :type => :server,
+ :name => csr.subject,
+ :ttl => ttl,
+ :issuer => @cert,
+ :serial => serial,
- :publickey => csr.public_key
- )
+ :publickey => csr.public_key
+ )
- sign_with_key(newcert)
+ sign_with_key(newcert)
- self.storeclientcert(newcert)
+ self.storeclientcert(newcert)
- [newcert, @cert]
- end
+ [newcert, @cert]
+ end
- # Store the client's CSR for later signing. This is called from
- # server/ca.rb, and the CSRs are deleted once the certificate is actually
- # signed.
- def storeclientcsr(csr)
- host = thing2name(csr)
+ # Store the client's CSR for later signing. This is called from
+ # server/ca.rb, and the CSRs are deleted once the certificate is actually
+ # signed.
+ def storeclientcsr(csr)
+ host = thing2name(csr)
- csrfile = host2csrfile(host)
- raise Puppet::Error, "Certificate request for #{host} already exists" if File.exists?(csrfile)
+ csrfile = host2csrfile(host)
+ raise Puppet::Error, "Certificate request for #{host} already exists" if File.exists?(csrfile)
- Puppet.settings.writesub(:csrdir, csrfile) do |f|
- f.print csr.to_pem
- end
+ Puppet.settings.writesub(:csrdir, csrfile) do |f|
+ f.print csr.to_pem
end
+ end
- # Store the certificate that we generate.
- def storeclientcert(cert)
- host = thing2name(cert)
+ # Store the certificate that we generate.
+ def storeclientcert(cert)
+ host = thing2name(cert)
- certfile = host2certfile(host)
- Puppet.notice "Overwriting signed certificate #{certfile} for #{host}" if File.exists?(certfile)
+ certfile = host2certfile(host)
+ Puppet.notice "Overwriting signed certificate #{certfile} for #{host}" if File.exists?(certfile)
- Puppet::SSLCertificates::Inventory::add(cert)
- Puppet.settings.writesub(:signeddir, certfile) do |f|
- f.print cert.to_pem
- end
+ Puppet::SSLCertificates::Inventory::add(cert)
+ Puppet.settings.writesub(:signeddir, certfile) do |f|
+ f.print cert.to_pem
end
-
- # TTL for new certificates in seconds. If config param :ca_ttl is set,
- # use that, otherwise use :ca_days for backwards compatibility
- def ttl
- days = @config[:ca_days]
- if days && days.size > 0
- warnonce "Parameter ca_ttl is not set. Using depecated ca_days instead."
- return @config[:ca_days] * 24 * 60 * 60
- else
- ttl = @config[:ca_ttl]
- if ttl.is_a?(String)
- unless ttl =~ /^(\d+)(y|d|h|s)$/
- raise ArgumentError, "Invalid ca_ttl #{ttl}"
- end
- case $2
- when 'y'
- unit = 365 * 24 * 60 * 60
- when 'd'
- unit = 24 * 60 * 60
- when 'h'
- unit = 60 * 60
- when 's'
- unit = 1
- else
- raise ArgumentError, "Invalid unit for ca_ttl #{ttl}"
- end
- return $1.to_i * unit
- else
- return ttl
- end
+ end
+
+ # TTL for new certificates in seconds. If config param :ca_ttl is set,
+ # use that, otherwise use :ca_days for backwards compatibility
+ def ttl
+ days = @config[:ca_days]
+ if days && days.size > 0
+ warnonce "Parameter ca_ttl is not set. Using depecated ca_days instead."
+ return @config[:ca_days] * 24 * 60 * 60
+ else
+ ttl = @config[:ca_ttl]
+ if ttl.is_a?(String)
+ unless ttl =~ /^(\d+)(y|d|h|s)$/
+ raise ArgumentError, "Invalid ca_ttl #{ttl}"
end
- end
-
- private
- def init_crl
- if FileTest.exists?(@config[:cacrl])
- @crl = OpenSSL::X509::CRL.new(
- File.read(@config[:cacrl])
- )
+ case $2
+ when 'y'
+ unit = 365 * 24 * 60 * 60
+ when 'd'
+ unit = 24 * 60 * 60
+ when 'h'
+ unit = 60 * 60
+ when 's'
+ unit = 1
else
- # Create new CRL
- @crl = OpenSSL::X509::CRL.new
- @crl.issuer = @cert.subject
- @crl.version = 1
- store_crl
- @crl
+ raise ArgumentError, "Invalid unit for ca_ttl #{ttl}"
end
+ return $1.to_i * unit
+ else
+ return ttl
+ end
end
-
- def store_crl
- # Increment the crlNumber
- e = @crl.extensions.find { |e| e.oid == 'crlNumber' }
- ext = @crl.extensions.reject { |e| e.oid == 'crlNumber' }
- crlNum = OpenSSL::ASN1::Integer(e ? e.value.to_i + 1 : 0)
- ext << OpenSSL::X509::Extension.new("crlNumber", crlNum)
- @crl.extensions = ext
-
- # Set last/next update
- now = Time.now
- @crl.last_update = now
- # Keep CRL valid for 5 years
- @crl.next_update = now + 5 * 365*24*60*60
-
- sign_with_key(@crl)
- Puppet.settings.write(:cacrl) do |f|
- f.puts @crl.to_pem
- end
+ end
+
+ private
+ def init_crl
+ if FileTest.exists?(@config[:cacrl])
+ @crl = OpenSSL::X509::CRL.new(
+ File.read(@config[:cacrl])
+ )
+ else
+ # Create new CRL
+ @crl = OpenSSL::X509::CRL.new
+ @crl.issuer = @cert.subject
+ @crl.version = 1
+ store_crl
+ @crl
+ end
+ end
+
+ def store_crl
+ # Increment the crlNumber
+ e = @crl.extensions.find { |e| e.oid == 'crlNumber' }
+ ext = @crl.extensions.reject { |e| e.oid == 'crlNumber' }
+ crlNum = OpenSSL::ASN1::Integer(e ? e.value.to_i + 1 : 0)
+ ext << OpenSSL::X509::Extension.new("crlNumber", crlNum)
+ @crl.extensions = ext
+
+ # Set last/next update
+ now = Time.now
+ @crl.last_update = now
+ # Keep CRL valid for 5 years
+ @crl.next_update = now + 5 * 365*24*60*60
+
+ sign_with_key(@crl)
+ Puppet.settings.write(:cacrl) do |f|
+ f.puts @crl.to_pem
+ end
+ end
+
+ def sign_with_key(signable, digest = OpenSSL::Digest::SHA1.new)
+ cakey = nil
+ if @config[:password]
+ begin
+ cakey = OpenSSL::PKey::RSA.new(
+ File.read(@config[:cakey]), @config[:password]
+ )
+ rescue
+ raise Puppet::Error,
+ "Decrypt of CA private key with password stored in @config[:capass] not possible"
+ end
+ else
+ cakey = OpenSSL::PKey::RSA.new(
+ File.read(@config[:cakey])
+ )
end
- def sign_with_key(signable, digest = OpenSSL::Digest::SHA1.new)
- cakey = nil
- if @config[:password]
- begin
- cakey = OpenSSL::PKey::RSA.new(
- File.read(@config[:cakey]), @config[:password]
- )
- rescue
- raise Puppet::Error,
- "Decrypt of CA private key with password stored in @config[:capass] not possible"
- end
- else
- cakey = OpenSSL::PKey::RSA.new(
- File.read(@config[:cakey])
- )
- end
-
- raise Puppet::Error, "CA Certificate is invalid" unless @cert.check_private_key(cakey)
+ raise Puppet::Error, "CA Certificate is invalid" unless @cert.check_private_key(cakey)
- signable.sign(cakey, digest)
- end
+ signable.sign(cakey, digest)
+ end
end
diff --git a/lib/puppet/sslcertificates/certificate.rb b/lib/puppet/sslcertificates/certificate.rb
index a9d1dd4..2d30bb0 100644
--- a/lib/puppet/sslcertificates/certificate.rb
+++ b/lib/puppet/sslcertificates/certificate.rb
@@ -1,148 +1,148 @@
class Puppet::SSLCertificates::Certificate
- SSLCertificates = Puppet::SSLCertificates
-
- attr_accessor :certfile, :keyfile, :name, :dir, :hash, :type
- attr_accessor :key, :cert, :csr, :cacert
-
- @@params2names = {
- :name => "CN",
- :state => "ST",
- :country => "C",
- :email => "emailAddress",
- :org => "O",
- :city => "L",
- :ou => "OU"
+ SSLCertificates = Puppet::SSLCertificates
+
+ attr_accessor :certfile, :keyfile, :name, :dir, :hash, :type
+ attr_accessor :key, :cert, :csr, :cacert
+
+ @@params2names = {
+ :name => "CN",
+ :state => "ST",
+ :country => "C",
+ :email => "emailAddress",
+ :org => "O",
+ :city => "L",
+ :ou => "OU"
+ }
+
+ def certname
+ OpenSSL::X509::Name.new self.subject
+ end
+
+ def delete
+ [@certfile, at keyfile].each { |file|
+ File.unlink(file) if FileTest.exists?(file)
}
- def certname
- OpenSSL::X509::Name.new self.subject
+ if @hash
+ File.unlink(@hash) if FileTest.symlink?(@hash)
end
+ end
- def delete
- [@certfile, at keyfile].each { |file|
- File.unlink(file) if FileTest.exists?(file)
- }
-
- if @hash
- File.unlink(@hash) if FileTest.symlink?(@hash)
- end
- end
+ def exists?
+ FileTest.exists?(@certfile)
+ end
- def exists?
- FileTest.exists?(@certfile)
- end
-
- def getkey
- self.mkkey unless FileTest.exists?(@keyfile)
- if @password
+ def getkey
+ self.mkkey unless FileTest.exists?(@keyfile)
+ if @password
- @key = OpenSSL::PKey::RSA.new(
+ @key = OpenSSL::PKey::RSA.new(
- File.read(@keyfile),
+ File.read(@keyfile),
- @password
- )
- else
- @key = OpenSSL::PKey::RSA.new(
- File.read(@keyfile)
- )
- end
+ @password
+ )
+ else
+ @key = OpenSSL::PKey::RSA.new(
+ File.read(@keyfile)
+ )
end
+ end
- def initialize(hash)
- raise Puppet::Error, "You must specify the common name for the certificate" unless hash.include?(:name)
- @name = hash[:name]
-
- # init a few variables
- @cert = @key = @csr = nil
+ def initialize(hash)
+ raise Puppet::Error, "You must specify the common name for the certificate" unless hash.include?(:name)
+ @name = hash[:name]
- if hash.include?(:cert)
- @certfile = hash[:cert]
- @dir = File.dirname(@certfile)
- else
- @dir = hash[:dir] || Puppet[:certdir]
- @certfile = File.join(@dir, @name)
- end
+ # init a few variables
+ @cert = @key = @csr = nil
- @cacertfile ||= File.join(Puppet[:certdir], "ca.pem")
+ if hash.include?(:cert)
+ @certfile = hash[:cert]
+ @dir = File.dirname(@certfile)
+ else
+ @dir = hash[:dir] || Puppet[:certdir]
+ @certfile = File.join(@dir, @name)
+ end
- Puppet.recmkdir(@dir) unless FileTest.directory?(@dir)
+ @cacertfile ||= File.join(Puppet[:certdir], "ca.pem")
- unless @certfile =~ /\.pem$/
- @certfile += ".pem"
- end
- @keyfile = hash[:key] || File.join(
- Puppet[:privatekeydir], [@name,"pem"].join(".")
- )
- Puppet.recmkdir(@dir) unless FileTest.directory?(@dir)
+ Puppet.recmkdir(@dir) unless FileTest.directory?(@dir)
- [@keyfile].each { |file|
- dir = File.dirname(file)
+ unless @certfile =~ /\.pem$/
+ @certfile += ".pem"
+ end
+ @keyfile = hash[:key] || File.join(
+ Puppet[:privatekeydir], [@name,"pem"].join(".")
+ )
+ Puppet.recmkdir(@dir) unless FileTest.directory?(@dir)
- Puppet.recmkdir(dir) unless FileTest.directory?(dir)
- }
+ [@keyfile].each { |file|
+ dir = File.dirname(file)
- @ttl = hash[:ttl] || 365 * 24 * 60 * 60
- @selfsign = hash[:selfsign] || false
- @encrypt = hash[:encrypt] || false
- @replace = hash[:replace] || false
- @issuer = hash[:issuer] || nil
-
- if hash.include?(:type)
- case hash[:type]
- when :ca, :client, :server; @type = hash[:type]
- else
- raise "Invalid Cert type #{hash[:type]}"
- end
- else
- @type = :client
- end
+ Puppet.recmkdir(dir) unless FileTest.directory?(dir)
+ }
- @params = {:name => @name}
- [:state, :country, :email, :org, :ou].each { |param|
- @params[param] = hash[param] if hash.include?(param)
- }
+ @ttl = hash[:ttl] || 365 * 24 * 60 * 60
+ @selfsign = hash[:selfsign] || false
+ @encrypt = hash[:encrypt] || false
+ @replace = hash[:replace] || false
+ @issuer = hash[:issuer] || nil
+
+ if hash.include?(:type)
+ case hash[:type]
+ when :ca, :client, :server; @type = hash[:type]
+ else
+ raise "Invalid Cert type #{hash[:type]}"
+ end
+ else
+ @type = :client
+ end
- if @encrypt
- if @encrypt =~ /^\//
- File.open(@encrypt) { |f|
- @password = f.read.chomp
- }
- else
- raise Puppet::Error, ":encrypt must be a path to a pass phrase file"
- end
- else
- @password = nil
- end
+ @params = {:name => @name}
+ [:state, :country, :email, :org, :ou].each { |param|
+ @params[param] = hash[param] if hash.include?(param)
+ }
- @selfsign = hash.include?(:selfsign) && hash[:selfsign]
+ if @encrypt
+ if @encrypt =~ /^\//
+ File.open(@encrypt) { |f|
+ @password = f.read.chomp
+ }
+ else
+ raise Puppet::Error, ":encrypt must be a path to a pass phrase file"
+ end
+ else
+ @password = nil
end
- # this only works for servers, not for users
- def mkcsr
- self.getkey unless @key
+ @selfsign = hash.include?(:selfsign) && hash[:selfsign]
+ end
- name = OpenSSL::X509::Name.new self.subject
+ # this only works for servers, not for users
+ def mkcsr
+ self.getkey unless @key
- @csr = OpenSSL::X509::Request.new
- @csr.version = 0
- @csr.subject = name
- @csr.public_key = @key.public_key
- @csr.sign(@key, OpenSSL::Digest::SHA1.new)
+ name = OpenSSL::X509::Name.new self.subject
- #File.open(@csrfile, "w") { |f|
- # f << @csr.to_pem
- #}
+ @csr = OpenSSL::X509::Request.new
+ @csr.version = 0
+ @csr.subject = name
+ @csr.public_key = @key.public_key
+ @csr.sign(@key, OpenSSL::Digest::SHA1.new)
- raise Puppet::Error, "CSR sign verification failed" unless @csr.verify(@key.public_key)
+ #File.open(@csrfile, "w") { |f|
+ # f << @csr.to_pem
+ #}
- @csr
- end
+ raise Puppet::Error, "CSR sign verification failed" unless @csr.verify(@key.public_key)
- def mkkey
- # @key is the file
+ @csr
+ end
- @key = OpenSSL::PKey::RSA.new(1024)
+ def mkkey
+ # @key is the file
+
+ @key = OpenSSL::PKey::RSA.new(1024)
# { |p,n|
# case p
# when 0; Puppet.info "key info: ." # BN_generate_prime
@@ -156,100 +156,100 @@ class Puppet::SSLCertificates::Certificate
# end
# }
- if @password
- # passwdproc = proc { @password }
-
- keytext = @key.export(
+ if @password
+ # passwdproc = proc { @password }
- OpenSSL::Cipher::DES.new(:EDE3, :CBC),
+ keytext = @key.export(
- @password
- )
- File.open(@keyfile, "w", 0400) { |f|
- f << keytext
- }
- else
- File.open(@keyfile, "w", 0400) { |f|
- f << @key.to_pem
- }
- end
+ OpenSSL::Cipher::DES.new(:EDE3, :CBC),
- #cmd = "#{ossl} genrsa -out #{@key} 1024"
+ @password
+ )
+ File.open(@keyfile, "w", 0400) { |f|
+ f << keytext
+ }
+ else
+ File.open(@keyfile, "w", 0400) { |f|
+ f << @key.to_pem
+ }
end
- def mkselfsigned
- self.getkey unless @key
+ #cmd = "#{ossl} genrsa -out #{@key} 1024"
+ end
- raise Puppet::Error, "Cannot replace existing certificate" if @cert
+ def mkselfsigned
+ self.getkey unless @key
- args = {
- :name => self.certname,
- :ttl => @ttl,
- :issuer => nil,
- :serial => 0x0,
- :publickey => @key.public_key
- }
- if @type
- args[:type] = @type
- else
- args[:type] = :server
- end
- @cert = SSLCertificates.mkcert(args)
+ raise Puppet::Error, "Cannot replace existing certificate" if @cert
- @cert.sign(@key, OpenSSL::Digest::SHA1.new) if @selfsign
-
- @cert
+ args = {
+ :name => self.certname,
+ :ttl => @ttl,
+ :issuer => nil,
+ :serial => 0x0,
+ :publickey => @key.public_key
+ }
+ if @type
+ args[:type] = @type
+ else
+ args[:type] = :server
end
+ @cert = SSLCertificates.mkcert(args)
- def subject(string = false)
- subj = @@params2names.collect { |param, name|
- [name, @params[param]] if @params.include?(param)
- }.reject { |ary| ary.nil? }
+ @cert.sign(@key, OpenSSL::Digest::SHA1.new) if @selfsign
- if string
- return "/" + subj.collect { |ary|
- "%s=%s" % ary
- }.join("/") + "/"
- else
- return subj
- end
- end
+ @cert
+ end
- # verify that we can track down the cert chain or whatever
- def verify
- "openssl verify -verbose -CAfile /home/luke/.puppet/ssl/certs/ca.pem -purpose sslserver culain.madstop.com.pem"
+ def subject(string = false)
+ subj = @@params2names.collect { |param, name|
+ [name, @params[param]] if @params.include?(param)
+ }.reject { |ary| ary.nil? }
+
+ if string
+ return "/" + subj.collect { |ary|
+ "%s=%s" % ary
+ }.join("/") + "/"
+ else
+ return subj
end
+ end
- def write
- files = {
- @certfile => @cert,
- @keyfile => @key,
- }
- files[@cacertfile] = @cacert if defined?(@cacert)
+ # verify that we can track down the cert chain or whatever
+ def verify
+ "openssl verify -verbose -CAfile /home/luke/.puppet/ssl/certs/ca.pem -purpose sslserver culain.madstop.com.pem"
+ end
- files.each { |file,thing|
- if thing
- next if FileTest.exists?(file)
+ def write
+ files = {
+ @certfile => @cert,
+ @keyfile => @key,
+ }
+ files[@cacertfile] = @cacert if defined?(@cacert)
- text = nil
+ files.each { |file,thing|
+ if thing
+ next if FileTest.exists?(file)
- if thing.is_a?(OpenSSL::PKey::RSA) and @password
+ text = nil
- text = thing.export(
+ if thing.is_a?(OpenSSL::PKey::RSA) and @password
- OpenSSL::Cipher::DES.new(:EDE3, :CBC),
+ text = thing.export(
- @password
- )
- else
- text = thing.to_pem
- end
+ OpenSSL::Cipher::DES.new(:EDE3, :CBC),
- File.open(file, "w", 0660) { |f| f.print text }
- end
- }
+ @password
+ )
+ else
+ text = thing.to_pem
+ end
- SSLCertificates.mkhash(Puppet[:certdir], @cacert, @cacertfile) if defined?(@cacert)
- end
+ File.open(file, "w", 0660) { |f| f.print text }
+ end
+ }
+
+ SSLCertificates.mkhash(Puppet[:certdir], @cacert, @cacertfile) if defined?(@cacert)
+ end
end
diff --git a/lib/puppet/sslcertificates/inventory.rb b/lib/puppet/sslcertificates/inventory.rb
index c3f79ee..1075c13 100644
--- a/lib/puppet/sslcertificates/inventory.rb
+++ b/lib/puppet/sslcertificates/inventory.rb
@@ -1,38 +1,38 @@
# A module for keeping track of all the certificates issued by the CA, ever
# Maintains the file "$cadir/inventory.txt"
module Puppet::SSLCertificates
- module Inventory
+ module Inventory
- # Add CERT to the inventory of issued certs in '$cadir/inventory.txt'
- # If no inventory exists yet, build an inventory and list all the
- # certificates that have been signed so far
- def self.add(cert)
- inited = false
- inited = true if FileTest.exists?(Puppet[:cert_inventory])
+ # Add CERT to the inventory of issued certs in '$cadir/inventory.txt'
+ # If no inventory exists yet, build an inventory and list all the
+ # certificates that have been signed so far
+ def self.add(cert)
+ inited = false
+ inited = true if FileTest.exists?(Puppet[:cert_inventory])
- Puppet.settings.write(:cert_inventory, "a") do |f|
- f.puts((inited ? nil : self.init).to_s + format(cert))
- end
- end
+ Puppet.settings.write(:cert_inventory, "a") do |f|
+ f.puts((inited ? nil : self.init).to_s + format(cert))
+ end
+ end
- private
+ private
- def self.init
- inv = "# Inventory of signed certificates\n"
- inv += "# SERIAL NOT_BEFORE NOT_AFTER SUBJECT\n"
- Dir.glob(File::join(Puppet[:signeddir], "*.pem")) do |f|
- inv += format(OpenSSL::X509::Certificate.new(File::read(f))) + "\n"
- end
- inv
- end
+ def self.init
+ inv = "# Inventory of signed certificates\n"
+ inv += "# SERIAL NOT_BEFORE NOT_AFTER SUBJECT\n"
+ Dir.glob(File::join(Puppet[:signeddir], "*.pem")) do |f|
+ inv += format(OpenSSL::X509::Certificate.new(File::read(f))) + "\n"
+ end
+ inv
+ end
- def self.format(cert)
- iso = '%Y-%m-%dT%H:%M:%S%Z'
- return "0x%04x %s %s %s" % [cert.serial,
- cert.not_before.strftime(iso),
- cert.not_after.strftime(iso),
- cert.subject]
- end
+ def self.format(cert)
+ iso = '%Y-%m-%dT%H:%M:%S%Z'
+ return "0x%04x %s %s %s" % [cert.serial,
+ cert.not_before.strftime(iso),
+ cert.not_after.strftime(iso),
+ cert.subject]
end
+ end
end
diff --git a/lib/puppet/sslcertificates/support.rb b/lib/puppet/sslcertificates/support.rb
index 919d686..7d67081 100644
--- a/lib/puppet/sslcertificates/support.rb
+++ b/lib/puppet/sslcertificates/support.rb
@@ -2,145 +2,145 @@ require 'puppet/sslcertificates'
# A module to handle reading of certificates.
module Puppet::SSLCertificates::Support
- class MissingCertificate < Puppet::Error; end
- class InvalidCertificate < Puppet::Error; end
+ class MissingCertificate < Puppet::Error; end
+ class InvalidCertificate < Puppet::Error; end
- attr_reader :cacert
+ attr_reader :cacert
- # Some metaprogramming to create methods for retrieving and creating keys.
- # This probably isn't fewer lines than defining each separately...
- def self.keytype(name, options, &block)
- var = "@#{name}"
+ # Some metaprogramming to create methods for retrieving and creating keys.
+ # This probably isn't fewer lines than defining each separately...
+ def self.keytype(name, options, &block)
+ var = "@#{name}"
- maker = "mk_#{name}"
- reader = "read_#{name}"
+ maker = "mk_#{name}"
+ reader = "read_#{name}"
- unless param = options[:param]
- raise ArgumentError, "You must specify the parameter for the key"
- end
-
- unless klass = options[:class]
- raise ArgumentError, "You must specify the class for the key"
- end
+ unless param = options[:param]
+ raise ArgumentError, "You must specify the parameter for the key"
+ end
- # Define the method that creates it.
- define_method(maker, &block)
+ unless klass = options[:class]
+ raise ArgumentError, "You must specify the class for the key"
+ end
- # Define the reading method.
- define_method(reader) do
- return nil unless FileTest.exists?(Puppet[param]) or rename_files_with_uppercase(Puppet[param])
+ # Define the method that creates it.
+ define_method(maker, &block)
- begin
- instance_variable_set(var, klass.new(File.read(Puppet[param])))
- rescue => detail
- raise InvalidCertificate, "Could not read #{param}: #{detail}"
- end
- end
+ # Define the reading method.
+ define_method(reader) do
+ return nil unless FileTest.exists?(Puppet[param]) or rename_files_with_uppercase(Puppet[param])
- # Define the overall method, which just calls the reader and maker
- # as appropriate.
- define_method(name) do
- unless cert = instance_variable_get(var)
- unless cert = send(reader)
- cert = send(maker)
- Puppet.settings.write(param) { |f| f.puts cert.to_pem }
- end
- instance_variable_set(var, cert)
- end
- cert
- end
+ begin
+ instance_variable_set(var, klass.new(File.read(Puppet[param])))
+ rescue => detail
+ raise InvalidCertificate, "Could not read #{param}: #{detail}"
+ end
end
- # The key pair.
- keytype :key, :param => :hostprivkey, :class => OpenSSL::PKey::RSA do
- Puppet.info "Creating a new SSL key at #{Puppet[:hostprivkey]}"
- key = OpenSSL::PKey::RSA.new(Puppet[:keylength])
-
- # Our key meta programming can only handle one file, so we have
- # to separately write out the public key.
- Puppet.settings.write(:hostpubkey) do |f|
- f.print key.public_key.to_pem
+ # Define the overall method, which just calls the reader and maker
+ # as appropriate.
+ define_method(name) do
+ unless cert = instance_variable_get(var)
+ unless cert = send(reader)
+ cert = send(maker)
+ Puppet.settings.write(param) { |f| f.puts cert.to_pem }
end
- return key
+ instance_variable_set(var, cert)
+ end
+ cert
end
+ end
- # Our certificate request
- keytype :csr, :param => :hostcsr, :class => OpenSSL::X509::Request do
- Puppet.info "Creating a new certificate request for #{Puppet[:certname]}"
+ # The key pair.
+ keytype :key, :param => :hostprivkey, :class => OpenSSL::PKey::RSA do
+ Puppet.info "Creating a new SSL key at #{Puppet[:hostprivkey]}"
+ key = OpenSSL::PKey::RSA.new(Puppet[:keylength])
- csr = OpenSSL::X509::Request.new
- csr.version = 0
- csr.subject = OpenSSL::X509::Name.new([["CN", Puppet[:certname]]])
- csr.public_key = key.public_key
- csr.sign(key, OpenSSL::Digest::MD5.new)
-
- return csr
+ # Our key meta programming can only handle one file, so we have
+ # to separately write out the public key.
+ Puppet.settings.write(:hostpubkey) do |f|
+ f.print key.public_key.to_pem
end
-
- keytype :cert, :param => :hostcert, :class => OpenSSL::X509::Certificate do
- raise MissingCertificate, "No host certificate"
+ return key
+ end
+
+ # Our certificate request
+ keytype :csr, :param => :hostcsr, :class => OpenSSL::X509::Request do
+ Puppet.info "Creating a new certificate request for #{Puppet[:certname]}"
+
+ csr = OpenSSL::X509::Request.new
+ csr.version = 0
+ csr.subject = OpenSSL::X509::Name.new([["CN", Puppet[:certname]]])
+ csr.public_key = key.public_key
+ csr.sign(key, OpenSSL::Digest::MD5.new)
+
+ return csr
+ end
+
+ keytype :cert, :param => :hostcert, :class => OpenSSL::X509::Certificate do
+ raise MissingCertificate, "No host certificate"
+ end
+
+ keytype :ca_cert, :param => :localcacert, :class => OpenSSL::X509::Certificate do
+ raise MissingCertificate, "No CA certificate"
+ end
+
+ # Request a certificate from the remote system. This does all of the work
+ # of creating the cert request, contacting the remote system, and
+ # storing the cert locally.
+ def requestcert
+ begin
+ cert, cacert = caclient.getcert(@csr.to_pem)
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ raise Puppet::Error.new("Certificate retrieval failed: #{detail}")
end
- keytype :ca_cert, :param => :localcacert, :class => OpenSSL::X509::Certificate do
- raise MissingCertificate, "No CA certificate"
+ if cert.nil? or cert == ""
+ return nil
end
-
- # Request a certificate from the remote system. This does all of the work
- # of creating the cert request, contacting the remote system, and
- # storing the cert locally.
- def requestcert
- begin
- cert, cacert = caclient.getcert(@csr.to_pem)
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- raise Puppet::Error.new("Certificate retrieval failed: #{detail}")
- end
-
- if cert.nil? or cert == ""
- return nil
- end
- Puppet.settings.write(:hostcert) do |f| f.print cert end
- Puppet.settings.write(:localcacert) do |f| f.print cacert end
- #File.open(@certfile, "w", 0644) { |f| f.print cert }
- #File.open(@cacertfile, "w", 0644) { |f| f.print cacert }
- begin
- @cert = OpenSSL::X509::Certificate.new(cert)
- @cacert = OpenSSL::X509::Certificate.new(cacert)
- retrieved = true
- rescue => detail
- raise Puppet::Error.new(
- "Invalid certificate: #{detail}"
- )
- end
-
- raise Puppet::DevError, "Received invalid certificate" unless @cert.check_private_key(@key)
- retrieved
+ Puppet.settings.write(:hostcert) do |f| f.print cert end
+ Puppet.settings.write(:localcacert) do |f| f.print cacert end
+ #File.open(@certfile, "w", 0644) { |f| f.print cert }
+ #File.open(@cacertfile, "w", 0644) { |f| f.print cacert }
+ begin
+ @cert = OpenSSL::X509::Certificate.new(cert)
+ @cacert = OpenSSL::X509::Certificate.new(cacert)
+ retrieved = true
+ rescue => detail
+ raise Puppet::Error.new(
+ "Invalid certificate: #{detail}"
+ )
end
- # A hack method to deal with files that exist with a different case.
- # Just renames it; doesn't read it in or anything.
- def rename_files_with_uppercase(file)
- dir = File.dirname(file)
- short = File.basename(file)
+ raise Puppet::DevError, "Received invalid certificate" unless @cert.check_private_key(@key)
+ retrieved
+ end
- # If the dir isn't present, we clearly don't have the file.
- #return nil unless FileTest.directory?(dir)
+ # A hack method to deal with files that exist with a different case.
+ # Just renames it; doesn't read it in or anything.
+ def rename_files_with_uppercase(file)
+ dir = File.dirname(file)
+ short = File.basename(file)
- raise ArgumentError, "Tried to fix SSL files to a file containing uppercase" unless short.downcase == short
+ # If the dir isn't present, we clearly don't have the file.
+ #return nil unless FileTest.directory?(dir)
- return false unless File.directory?(dir)
+ raise ArgumentError, "Tried to fix SSL files to a file containing uppercase" unless short.downcase == short
- real_file = Dir.entries(dir).reject { |f| f =~ /^\./ }.find do |other|
- other.downcase == short
- end
+ return false unless File.directory?(dir)
- return nil unless real_file
+ real_file = Dir.entries(dir).reject { |f| f =~ /^\./ }.find do |other|
+ other.downcase == short
+ end
- full_file = File.join(dir, real_file)
+ return nil unless real_file
- Puppet.notice "Fixing case in #{full_file}; renaming to #{file}"
- File.rename(full_file, file)
+ full_file = File.join(dir, real_file)
- true
- end
+ Puppet.notice "Fixing case in #{full_file}; renaming to #{file}"
+ File.rename(full_file, file)
+
+ true
+ end
end
diff --git a/lib/puppet/status.rb b/lib/puppet/status.rb
index aaec5d3..eecd0e1 100644
--- a/lib/puppet/status.rb
+++ b/lib/puppet/status.rb
@@ -1,28 +1,28 @@
require 'puppet/indirector'
class Puppet::Status
- extend Puppet::Indirector
- indirects :status, :terminus_class => :local
+ extend Puppet::Indirector
+ indirects :status, :terminus_class => :local
- attr :status, true
+ attr :status, true
- def initialize( status = nil )
- @status = status || {"is_alive" => true}
- end
+ def initialize( status = nil )
+ @status = status || {"is_alive" => true}
+ end
- def to_pson
- @status.to_pson
- end
+ def to_pson
+ @status.to_pson
+ end
- def self.from_pson( pson )
- self.new( pson )
- end
+ def self.from_pson( pson )
+ self.new( pson )
+ end
- def name
- "status"
- end
+ def name
+ "status"
+ end
- def name=(name)
- # NOOP
- end
+ def name=(name)
+ # NOOP
+ end
end
diff --git a/lib/puppet/transaction.rb b/lib/puppet/transaction.rb
index d70e06c..dcd9aad 100644
--- a/lib/puppet/transaction.rb
+++ b/lib/puppet/transaction.rb
@@ -6,355 +6,355 @@ require 'puppet/util/tagging'
require 'puppet/application'
class Puppet::Transaction
- require 'puppet/transaction/change'
- require 'puppet/transaction/event'
- require 'puppet/transaction/event_manager'
- require 'puppet/transaction/resource_harness'
- require 'puppet/resource/status'
+ require 'puppet/transaction/change'
+ require 'puppet/transaction/event'
+ require 'puppet/transaction/event_manager'
+ require 'puppet/transaction/resource_harness'
+ require 'puppet/resource/status'
- attr_accessor :component, :catalog, :ignoreschedules
- attr_accessor :sorted_resources, :configurator
+ attr_accessor :component, :catalog, :ignoreschedules
+ attr_accessor :sorted_resources, :configurator
- # The report, once generated.
- attr_accessor :report
+ # The report, once generated.
+ attr_accessor :report
- # Routes and stores any events and subscriptions.
- attr_reader :event_manager
+ # Routes and stores any events and subscriptions.
+ attr_reader :event_manager
- # Handles most of the actual interacting with resources
- attr_reader :resource_harness
+ # Handles most of the actual interacting with resources
+ attr_reader :resource_harness
- include Puppet::Util
- include Puppet::Util::Tagging
+ include Puppet::Util
+ include Puppet::Util::Tagging
- # Wraps application run state check to flag need to interrupt processing
- def stop_processing?
- Puppet::Application.stop_requested?
- end
-
- # Add some additional times for reporting
- def add_times(hash)
- hash.each do |name, num|
- report.add_times(name, num)
- end
- end
-
- # Are there any failed resources in this transaction?
- def any_failed?
- report.resource_statuses.values.detect { |status| status.failed? }
- end
-
- # Apply all changes for a resource
- def apply(resource, ancestor = nil)
- status = resource_harness.evaluate(resource)
- add_resource_status(status)
- event_manager.queue_events(ancestor || resource, status.events)
- rescue => detail
- resource.err "Could not evaluate: #{detail}"
- end
+ # Wraps application run state check to flag need to interrupt processing
+ def stop_processing?
+ Puppet::Application.stop_requested?
+ end
- # Find all of the changed resources.
- def changed?
- report.resource_statuses.values.find_all { |status| status.changed }.collect { |status| catalog.resource(status.resource) }
+ # Add some additional times for reporting
+ def add_times(hash)
+ hash.each do |name, num|
+ report.add_times(name, num)
end
-
- # Copy an important relationships from the parent to the newly-generated
- # child resource.
- def make_parent_child_relationship(resource, children)
- depthfirst = resource.depthfirst?
-
- children.each do |gen_child|
- if depthfirst
- edge = [gen_child, resource]
- else
- edge = [resource, gen_child]
- end
- relationship_graph.add_vertex(gen_child)
-
- unless relationship_graph.edge?(edge[1], edge[0])
- relationship_graph.add_edge(*edge)
- else
- resource.debug "Skipping automatic relationship to #{gen_child}"
- end
- end
+ end
+
+ # Are there any failed resources in this transaction?
+ def any_failed?
+ report.resource_statuses.values.detect { |status| status.failed? }
+ end
+
+ # Apply all changes for a resource
+ def apply(resource, ancestor = nil)
+ status = resource_harness.evaluate(resource)
+ add_resource_status(status)
+ event_manager.queue_events(ancestor || resource, status.events)
+ rescue => detail
+ resource.err "Could not evaluate: #{detail}"
+ end
+
+ # Find all of the changed resources.
+ def changed?
+ report.resource_statuses.values.find_all { |status| status.changed }.collect { |status| catalog.resource(status.resource) }
+ end
+
+ # Copy an important relationships from the parent to the newly-generated
+ # child resource.
+ def make_parent_child_relationship(resource, children)
+ depthfirst = resource.depthfirst?
+
+ children.each do |gen_child|
+ if depthfirst
+ edge = [gen_child, resource]
+ else
+ edge = [resource, gen_child]
+ end
+ relationship_graph.add_vertex(gen_child)
+
+ unless relationship_graph.edge?(edge[1], edge[0])
+ relationship_graph.add_edge(*edge)
+ else
+ resource.debug "Skipping automatic relationship to #{gen_child}"
+ end
end
-
- # See if the resource generates new resources at evaluation time.
- def eval_generate(resource)
- generate_additional_resources(resource, :eval_generate)
- end
-
- # Evaluate a single resource.
- def eval_resource(resource, ancestor = nil)
- if skip?(resource)
- resource_status(resource).skipped = true
- else
- eval_children_and_apply_resource(resource, ancestor)
- end
-
- # Check to see if there are any events queued for this resource
- event_manager.process_events(resource)
+ end
+
+ # See if the resource generates new resources at evaluation time.
+ def eval_generate(resource)
+ generate_additional_resources(resource, :eval_generate)
+ end
+
+ # Evaluate a single resource.
+ def eval_resource(resource, ancestor = nil)
+ if skip?(resource)
+ resource_status(resource).skipped = true
+ else
+ eval_children_and_apply_resource(resource, ancestor)
end
- def eval_children_and_apply_resource(resource, ancestor = nil)
- resource_status(resource).scheduled = true
+ # Check to see if there are any events queued for this resource
+ event_manager.process_events(resource)
+ end
- # We need to generate first regardless, because the recursive
- # actions sometimes change how the top resource is applied.
- children = eval_generate(resource)
-
- if ! children.empty? and resource.depthfirst?
- children.each do |child|
- # The child will never be skipped when the parent isn't
- eval_resource(child, ancestor || resource)
- end
- end
+ def eval_children_and_apply_resource(resource, ancestor = nil)
+ resource_status(resource).scheduled = true
- # Perform the actual changes
- apply(resource, ancestor)
+ # We need to generate first regardless, because the recursive
+ # actions sometimes change how the top resource is applied.
+ children = eval_generate(resource)
- if ! children.empty? and ! resource.depthfirst?
- children.each do |child|
- eval_resource(child, ancestor || resource)
- end
- end
+ if ! children.empty? and resource.depthfirst?
+ children.each do |child|
+ # The child will never be skipped when the parent isn't
+ eval_resource(child, ancestor || resource)
+ end
end
- # This method does all the actual work of running a transaction. It
- # collects all of the changes, executes them, and responds to any
- # necessary events.
- def evaluate
- # Start logging.
- Puppet::Util::Log.newdestination(@report)
-
- prepare
-
- Puppet.info "Applying configuration version '#{catalog.version}'" if catalog.version
-
- begin
- @sorted_resources.each do |resource|
- next if stop_processing?
- if resource.is_a?(Puppet::Type::Component)
- Puppet.warning "Somehow left a component in the relationship graph"
- next
- end
- ret = nil
- seconds = thinmark do
- ret = eval_resource(resource)
- end
-
- resource.info "Evaluated in %0.2f seconds" % seconds if Puppet[:evaltrace] and @catalog.host_config?
- ret
- end
- ensure
- # And then close the transaction log.
- Puppet::Util::Log.close(@report)
- end
-
- Puppet.debug "Finishing transaction #{object_id}"
- end
+ # Perform the actual changes
+ apply(resource, ancestor)
- def events
- event_manager.events
+ if ! children.empty? and ! resource.depthfirst?
+ children.each do |child|
+ eval_resource(child, ancestor || resource)
+ end
end
+ end
- def failed?(resource)
- s = resource_status(resource) and s.failed?
- end
+ # This method does all the actual work of running a transaction. It
+ # collects all of the changes, executes them, and responds to any
+ # necessary events.
+ def evaluate
+ # Start logging.
+ Puppet::Util::Log.newdestination(@report)
- # Does this resource have any failed dependencies?
- def failed_dependencies?(resource)
- # First make sure there are no failed dependencies. To do this,
- # we check for failures in any of the vertexes above us. It's not
- # enough to check the immediate dependencies, which is why we use
- # a tree from the reversed graph.
- found_failed = false
- relationship_graph.dependencies(resource).each do |dep|
- next unless failed?(dep)
- resource.notice "Dependency #{dep} has failures: #{resource_status(dep).failed}"
- found_failed = true
- end
+ prepare
- found_failed
- end
+ Puppet.info "Applying configuration version '#{catalog.version}'" if catalog.version
- # A general method for recursively generating new resources from a
- # resource.
- def generate_additional_resources(resource, method)
- return [] unless resource.respond_to?(method)
- begin
- made = resource.send(method)
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- resource.err "Failed to generate additional resources using '#{method}': #{detail}"
+ begin
+ @sorted_resources.each do |resource|
+ next if stop_processing?
+ if resource.is_a?(Puppet::Type::Component)
+ Puppet.warning "Somehow left a component in the relationship graph"
+ next
end
- return [] unless made
- made = [made] unless made.is_a?(Array)
- made.uniq.find_all do |res|
- begin
- res.tag(*resource.tags)
- @catalog.add_resource(res) do |r|
- r.finish
- make_parent_child_relationship(resource, [r])
-
- # Call 'generate' recursively
- generate_additional_resources(r, method)
- end
- true
- rescue Puppet::Resource::Catalog::DuplicateResourceError
- res.info "Duplicate generated resource; skipping"
- false
- end
+ ret = nil
+ seconds = thinmark do
+ ret = eval_resource(resource)
end
- end
- # Collect any dynamically generated resources. This method is called
- # before the transaction starts.
- def generate
- list = @catalog.vertices
- newlist = []
- while ! list.empty?
- list.each do |resource|
- newlist += generate_additional_resources(resource, :generate)
- end
- list = newlist
- newlist = []
- end
+ resource.info "Evaluated in %0.2f seconds" % seconds if Puppet[:evaltrace] and @catalog.host_config?
+ ret
+ end
+ ensure
+ # And then close the transaction log.
+ Puppet::Util::Log.close(@report)
end
- # Generate a transaction report.
- def generate_report
- @report.calculate_metrics
- @report
+ Puppet.debug "Finishing transaction #{object_id}"
+ end
+
+ def events
+ event_manager.events
+ end
+
+ def failed?(resource)
+ s = resource_status(resource) and s.failed?
+ end
+
+ # Does this resource have any failed dependencies?
+ def failed_dependencies?(resource)
+ # First make sure there are no failed dependencies. To do this,
+ # we check for failures in any of the vertexes above us. It's not
+ # enough to check the immediate dependencies, which is why we use
+ # a tree from the reversed graph.
+ found_failed = false
+ relationship_graph.dependencies(resource).each do |dep|
+ next unless failed?(dep)
+ resource.notice "Dependency #{dep} has failures: #{resource_status(dep).failed}"
+ found_failed = true
end
- # Should we ignore tags?
- def ignore_tags?
- ! (@catalog.host_config? or Puppet[:name] == "puppet")
- end
+ found_failed
+ end
- # this should only be called by a Puppet::Type::Component resource now
- # and it should only receive an array
- def initialize(catalog)
- @catalog = catalog
-
- @report = Report.new
-
- @event_manager = Puppet::Transaction::EventManager.new(self)
-
- @resource_harness = Puppet::Transaction::ResourceHarness.new(self)
+ # A general method for recursively generating new resources from a
+ # resource.
+ def generate_additional_resources(resource, method)
+ return [] unless resource.respond_to?(method)
+ begin
+ made = resource.send(method)
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ resource.err "Failed to generate additional resources using '#{method}': #{detail}"
end
-
- # Prefetch any providers that support it. We don't support prefetching
- # types, just providers.
- def prefetch
- prefetchers = {}
- @catalog.vertices.each do |resource|
- if provider = resource.provider and provider.class.respond_to?(:prefetch)
- prefetchers[provider.class] ||= {}
- prefetchers[provider.class][resource.name] = resource
- end
- end
-
- # Now call prefetch, passing in the resources so that the provider instances can be replaced.
- prefetchers.each do |provider, resources|
- Puppet.debug "Prefetching #{provider.name} resources for #{provider.resource_type.name}"
- begin
- provider.prefetch(resources)
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Could not prefetch #{provider.resource_type.name} provider '#{provider.name}': #{detail}"
- end
+ return [] unless made
+ made = [made] unless made.is_a?(Array)
+ made.uniq.find_all do |res|
+ begin
+ res.tag(*resource.tags)
+ @catalog.add_resource(res) do |r|
+ r.finish
+ make_parent_child_relationship(resource, [r])
+
+ # Call 'generate' recursively
+ generate_additional_resources(r, method)
end
+ true
+ rescue Puppet::Resource::Catalog::DuplicateResourceError
+ res.info "Duplicate generated resource; skipping"
+ false
+ end
end
-
- # Prepare to evaluate the resources in a transaction.
- def prepare
- # Now add any dynamically generated resources
- generate
-
- # Then prefetch. It's important that we generate and then prefetch,
- # so that any generated resources also get prefetched.
- prefetch
-
- # This will throw an error if there are cycles in the graph.
- @sorted_resources = relationship_graph.topsort
+ end
+
+ # Collect any dynamically generated resources. This method is called
+ # before the transaction starts.
+ def generate
+ list = @catalog.vertices
+ newlist = []
+ while ! list.empty?
+ list.each do |resource|
+ newlist += generate_additional_resources(resource, :generate)
+ end
+ list = newlist
+ newlist = []
end
-
- def relationship_graph
- catalog.relationship_graph
+ end
+
+ # Generate a transaction report.
+ def generate_report
+ @report.calculate_metrics
+ @report
+ end
+
+ # Should we ignore tags?
+ def ignore_tags?
+ ! (@catalog.host_config? or Puppet[:name] == "puppet")
+ end
+
+ # this should only be called by a Puppet::Type::Component resource now
+ # and it should only receive an array
+ def initialize(catalog)
+ @catalog = catalog
+
+ @report = Report.new
+
+ @event_manager = Puppet::Transaction::EventManager.new(self)
+
+ @resource_harness = Puppet::Transaction::ResourceHarness.new(self)
+ end
+
+ # Prefetch any providers that support it. We don't support prefetching
+ # types, just providers.
+ def prefetch
+ prefetchers = {}
+ @catalog.vertices.each do |resource|
+ if provider = resource.provider and provider.class.respond_to?(:prefetch)
+ prefetchers[provider.class] ||= {}
+ prefetchers[provider.class][resource.name] = resource
+ end
end
- # Send off the transaction report.
- def send_report
- begin
- report = generate_report
- rescue => detail
- Puppet.err "Could not generate report: #{detail}"
- return
- end
-
- puts report.summary if Puppet[:summarize]
-
- if Puppet[:report]
- begin
- report.save
- rescue => detail
- Puppet.err "Reporting failed: #{detail}"
- end
- end
+ # Now call prefetch, passing in the resources so that the provider instances can be replaced.
+ prefetchers.each do |provider, resources|
+ Puppet.debug "Prefetching #{provider.name} resources for #{provider.resource_type.name}"
+ begin
+ provider.prefetch(resources)
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Could not prefetch #{provider.resource_type.name} provider '#{provider.name}': #{detail}"
+ end
end
+ end
- def add_resource_status(status)
- report.add_resource_status status
- end
+ # Prepare to evaluate the resources in a transaction.
+ def prepare
+ # Now add any dynamically generated resources
+ generate
- def resource_status(resource)
- report.resource_statuses[resource.to_s] || add_resource_status(Puppet::Resource::Status.new(resource))
- end
+ # Then prefetch. It's important that we generate and then prefetch,
+ # so that any generated resources also get prefetched.
+ prefetch
- # Is the resource currently scheduled?
- def scheduled?(resource)
- self.ignoreschedules or resource_harness.scheduled?(resource_status(resource), resource)
- end
+ # This will throw an error if there are cycles in the graph.
+ @sorted_resources = relationship_graph.topsort
+ end
- # Should this resource be skipped?
- def skip?(resource)
- if missing_tags?(resource)
- resource.debug "Not tagged with #{tags.join(", ")}"
- elsif ! scheduled?(resource)
- resource.debug "Not scheduled"
- elsif failed_dependencies?(resource)
- resource.warning "Skipping because of failed dependencies"
- elsif resource.virtual?
- resource.debug "Skipping because virtual"
- else
- return false
- end
- true
- end
-
- # The tags we should be checking.
- def tags
- self.tags = Puppet[:tags] unless defined?(@tags)
-
- super
- end
+ def relationship_graph
+ catalog.relationship_graph
+ end
- def handle_qualified_tags( qualified )
- # The default behavior of Puppet::Util::Tagging is
- # to split qualified tags into parts. That would cause
- # qualified tags to match too broadly here.
- return
+ # Send off the transaction report.
+ def send_report
+ begin
+ report = generate_report
+ rescue => detail
+ Puppet.err "Could not generate report: #{detail}"
+ return
end
- # Is this resource tagged appropriately?
- def missing_tags?(resource)
- return false if ignore_tags?
- return false if tags.empty?
+ puts report.summary if Puppet[:summarize]
- not resource.tagged?(*tags)
+ if Puppet[:report]
+ begin
+ report.save
+ rescue => detail
+ Puppet.err "Reporting failed: #{detail}"
+ end
+ end
+ end
+
+ def add_resource_status(status)
+ report.add_resource_status status
+ end
+
+ def resource_status(resource)
+ report.resource_statuses[resource.to_s] || add_resource_status(Puppet::Resource::Status.new(resource))
+ end
+
+ # Is the resource currently scheduled?
+ def scheduled?(resource)
+ self.ignoreschedules or resource_harness.scheduled?(resource_status(resource), resource)
+ end
+
+ # Should this resource be skipped?
+ def skip?(resource)
+ if missing_tags?(resource)
+ resource.debug "Not tagged with #{tags.join(", ")}"
+ elsif ! scheduled?(resource)
+ resource.debug "Not scheduled"
+ elsif failed_dependencies?(resource)
+ resource.warning "Skipping because of failed dependencies"
+ elsif resource.virtual?
+ resource.debug "Skipping because virtual"
+ else
+ return false
end
+ true
+ end
+
+ # The tags we should be checking.
+ def tags
+ self.tags = Puppet[:tags] unless defined?(@tags)
+
+ super
+ end
+
+ def handle_qualified_tags( qualified )
+ # The default behavior of Puppet::Util::Tagging is
+ # to split qualified tags into parts. That would cause
+ # qualified tags to match too broadly here.
+ return
+ end
+
+ # Is this resource tagged appropriately?
+ def missing_tags?(resource)
+ return false if ignore_tags?
+ return false if tags.empty?
+
+ not resource.tagged?(*tags)
+ end
end
require 'puppet/transaction/report'
diff --git a/lib/puppet/transaction/change.rb b/lib/puppet/transaction/change.rb
index c8acec8..ecc3b5a 100644
--- a/lib/puppet/transaction/change.rb
+++ b/lib/puppet/transaction/change.rb
@@ -4,84 +4,84 @@ require 'puppet/transaction/event'
# Handle all of the work around performing an actual change,
# including calling 'sync' on the properties and producing events.
class Puppet::Transaction::Change
- attr_accessor :is, :should, :property, :proxy, :auditing
-
- def auditing?
- auditing
- end
-
- # Create our event object.
- def event
- result = property.event
- result.previous_value = is
- result.desired_value = should
- result
- end
-
- def initialize(property, currentvalue)
- @property = property
- @is = currentvalue
-
- @should = property.should
-
- @changed = false
- end
-
- def apply
- return audit_event if auditing?
- return noop_event if noop?
-
- property.sync
-
- result = event
- result.message = property.change_to_s(is, should)
- result.status = "success"
- result.send_log
- result
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- result = event
- result.status = "failure"
-
- result.message = "change from #{property.is_to_s(is)} to #{property.should_to_s(should)} failed: #{detail}"
- result.send_log
- result
- end
-
- # Is our property noop? This is used for generating special events.
- def noop?
- @property.noop
- end
-
- # The resource that generated this change. This is used for handling events,
- # and the proxy resource is used for generated resources, since we can't
- # send an event to a resource we don't have a direct relationship with. If we
- # have a proxy resource, then the events will be considered to be from
- # that resource, rather than us, so the graph resolution will still work.
- def resource
- self.proxy || @property.resource
- end
-
- def to_s
- "change #{@property.change_to_s(@is, @should)}"
- end
-
- private
-
- def audit_event
- # This needs to store the appropriate value, and then produce a new event
- result = event
- result.message = "audit change: previously recorded value #{property.should_to_s(should)} has been changed to #{property.is_to_s(is)}"
- result.status = "audit"
- result.send_log
- result
- end
-
- def noop_event
- result = event
- result.message = "is #{property.is_to_s(is)}, should be #{property.should_to_s(should)} (noop)"
- result.status = "noop"
- result.send_log
- result
- end
+ attr_accessor :is, :should, :property, :proxy, :auditing
+
+ def auditing?
+ auditing
+ end
+
+ # Create our event object.
+ def event
+ result = property.event
+ result.previous_value = is
+ result.desired_value = should
+ result
+ end
+
+ def initialize(property, currentvalue)
+ @property = property
+ @is = currentvalue
+
+ @should = property.should
+
+ @changed = false
+ end
+
+ def apply
+ return audit_event if auditing?
+ return noop_event if noop?
+
+ property.sync
+
+ result = event
+ result.message = property.change_to_s(is, should)
+ result.status = "success"
+ result.send_log
+ result
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ result = event
+ result.status = "failure"
+
+ result.message = "change from #{property.is_to_s(is)} to #{property.should_to_s(should)} failed: #{detail}"
+ result.send_log
+ result
+ end
+
+ # Is our property noop? This is used for generating special events.
+ def noop?
+ @property.noop
+ end
+
+ # The resource that generated this change. This is used for handling events,
+ # and the proxy resource is used for generated resources, since we can't
+ # send an event to a resource we don't have a direct relationship with. If we
+ # have a proxy resource, then the events will be considered to be from
+ # that resource, rather than us, so the graph resolution will still work.
+ def resource
+ self.proxy || @property.resource
+ end
+
+ def to_s
+ "change #{@property.change_to_s(@is, @should)}"
+ end
+
+ private
+
+ def audit_event
+ # This needs to store the appropriate value, and then produce a new event
+ result = event
+ result.message = "audit change: previously recorded value #{property.should_to_s(should)} has been changed to #{property.is_to_s(is)}"
+ result.status = "audit"
+ result.send_log
+ result
+ end
+
+ def noop_event
+ result = event
+ result.message = "is #{property.is_to_s(is)}, should be #{property.should_to_s(should)} (noop)"
+ result.status = "noop"
+ result.send_log
+ result
+ end
end
diff --git a/lib/puppet/transaction/event.rb b/lib/puppet/transaction/event.rb
index cb6c24e..e5e5793 100644
--- a/lib/puppet/transaction/event.rb
+++ b/lib/puppet/transaction/event.rb
@@ -4,58 +4,58 @@ require 'puppet/util/logging'
# A simple struct for storing what happens on the system.
class Puppet::Transaction::Event
- include Puppet::Util::Tagging
- include Puppet::Util::Logging
+ include Puppet::Util::Tagging
+ include Puppet::Util::Logging
- ATTRIBUTES = [:name, :resource, :property, :previous_value, :desired_value, :status, :message, :node, :version, :file, :line, :source_description]
- attr_accessor *ATTRIBUTES
- attr_writer :tags
- attr_accessor :time
- attr_reader :default_log_level
+ ATTRIBUTES = [:name, :resource, :property, :previous_value, :desired_value, :status, :message, :node, :version, :file, :line, :source_description]
+ attr_accessor *ATTRIBUTES
+ attr_writer :tags
+ attr_accessor :time
+ attr_reader :default_log_level
- EVENT_STATUSES = %w{noop success failure audit}
+ EVENT_STATUSES = %w{noop success failure audit}
- def initialize(*args)
- options = args.last.is_a?(Hash) ? args.pop : ATTRIBUTES.inject({}) { |hash, attr| hash[attr] = args.pop; hash }
- options.each { |attr, value| send(attr.to_s + "=", value) unless value.nil? }
+ def initialize(*args)
+ options = args.last.is_a?(Hash) ? args.pop : ATTRIBUTES.inject({}) { |hash, attr| hash[attr] = args.pop; hash }
+ options.each { |attr, value| send(attr.to_s + "=", value) unless value.nil? }
- @time = Time.now
- end
+ @time = Time.now
+ end
- def property=(prop)
- @property = prop.to_s
- end
+ def property=(prop)
+ @property = prop.to_s
+ end
- def resource=(res)
- if res.respond_to?(:[]) and level = res[:loglevel]
- @default_log_level = level
- end
- @resource = res.to_s
+ def resource=(res)
+ if res.respond_to?(:[]) and level = res[:loglevel]
+ @default_log_level = level
end
+ @resource = res.to_s
+ end
- def send_log
- super(log_level, message)
- end
+ def send_log
+ super(log_level, message)
+ end
- def status=(value)
- raise ArgumentError, "Event status can only be #{EVENT_STATUSES.join(', ')}" unless EVENT_STATUSES.include?(value)
- @status = value
- end
+ def status=(value)
+ raise ArgumentError, "Event status can only be #{EVENT_STATUSES.join(', ')}" unless EVENT_STATUSES.include?(value)
+ @status = value
+ end
- def to_s
- message
- end
+ def to_s
+ message
+ end
- private
+ private
- # If it's a failure, use 'err', else use either the resource's log level (if available)
- # or 'notice'.
- def log_level
- status == "failure" ? :err : (@default_log_level || :notice)
- end
+ # If it's a failure, use 'err', else use either the resource's log level (if available)
+ # or 'notice'.
+ def log_level
+ status == "failure" ? :err : (@default_log_level || :notice)
+ end
- # Used by the Logging module
- def log_source
- source_description || property || resource
- end
+ # Used by the Logging module
+ def log_source
+ source_description || property || resource
+ end
end
diff --git a/lib/puppet/transaction/event_manager.rb b/lib/puppet/transaction/event_manager.rb
index 34a4342..3ebb0a9 100644
--- a/lib/puppet/transaction/event_manager.rb
+++ b/lib/puppet/transaction/event_manager.rb
@@ -1,99 +1,99 @@
require 'puppet/transaction'
class Puppet::Transaction::EventManager
- attr_reader :transaction, :events
-
- def initialize(transaction)
- @transaction = transaction
- @event_queues = {}
- @events = []
- end
-
- def relationship_graph
- transaction.relationship_graph
+ attr_reader :transaction, :events
+
+ def initialize(transaction)
+ @transaction = transaction
+ @event_queues = {}
+ @events = []
+ end
+
+ def relationship_graph
+ transaction.relationship_graph
+ end
+
+ # Respond to any queued events for this resource.
+ def process_events(resource)
+ restarted = false
+ queued_events(resource) do |callback, events|
+ r = process_callback(resource, callback, events)
+ restarted ||= r
end
- # Respond to any queued events for this resource.
- def process_events(resource)
- restarted = false
- queued_events(resource) do |callback, events|
- r = process_callback(resource, callback, events)
- restarted ||= r
- end
-
- if restarted
- queue_events(resource, [resource.event(:name => :restarted, :status => "success")])
+ if restarted
+ queue_events(resource, [resource.event(:name => :restarted, :status => "success")])
- transaction.resource_status(resource).restarted = true
- end
+ transaction.resource_status(resource).restarted = true
end
-
- # Queue events for other resources to respond to. All of these events have
- # to be from the same resource.
- def queue_events(resource, events)
- @events += events
-
- # Do some basic normalization so we're not doing so many
- # graph queries for large sets of events.
- events.inject({}) do |collection, event|
- collection[event.name] ||= []
- collection[event.name] << event
- collection
- end.collect do |name, list|
- # It doesn't matter which event we use - they all have the same source
- # and name here.
- event = list[0]
-
- # Collect the targets of any subscriptions to those events. We pass
- # the parent resource in so it will override the source in the events,
- # since eval_generated children can't have direct relationships.
- relationship_graph.matching_edges(event, resource).each do |edge|
- next unless method = edge.callback
- next unless edge.target.respond_to?(method)
-
- queue_events_for_resource(resource, edge.target, method, list)
- end
-
- queue_events_for_resource(resource, resource, :refresh, [event]) if resource.self_refresh? and ! resource.deleting?
- end
+ end
+
+ # Queue events for other resources to respond to. All of these events have
+ # to be from the same resource.
+ def queue_events(resource, events)
+ @events += events
+
+ # Do some basic normalization so we're not doing so many
+ # graph queries for large sets of events.
+ events.inject({}) do |collection, event|
+ collection[event.name] ||= []
+ collection[event.name] << event
+ collection
+ end.collect do |name, list|
+ # It doesn't matter which event we use - they all have the same source
+ # and name here.
+ event = list[0]
+
+ # Collect the targets of any subscriptions to those events. We pass
+ # the parent resource in so it will override the source in the events,
+ # since eval_generated children can't have direct relationships.
+ relationship_graph.matching_edges(event, resource).each do |edge|
+ next unless method = edge.callback
+ next unless edge.target.respond_to?(method)
+
+ queue_events_for_resource(resource, edge.target, method, list)
+ end
+
+ queue_events_for_resource(resource, resource, :refresh, [event]) if resource.self_refresh? and ! resource.deleting?
end
+ end
- def queue_events_for_resource(source, target, callback, events)
- source.info "Scheduling #{callback} of #{target}"
+ def queue_events_for_resource(source, target, callback, events)
+ source.info "Scheduling #{callback} of #{target}"
- @event_queues[target] ||= {}
- @event_queues[target][callback] ||= []
- @event_queues[target][callback] += events
- end
+ @event_queues[target] ||= {}
+ @event_queues[target][callback] ||= []
+ @event_queues[target][callback] += events
+ end
- def queued_events(resource)
- return unless callbacks = @event_queues[resource]
- callbacks.each do |callback, events|
- yield callback, events
- end
+ def queued_events(resource)
+ return unless callbacks = @event_queues[resource]
+ callbacks.each do |callback, events|
+ yield callback, events
end
+ end
- private
+ private
- def process_callback(resource, callback, events)
- process_noop_events(resource, callback, events) and return false unless events.detect { |e| e.status != "noop" }
- resource.send(callback)
+ def process_callback(resource, callback, events)
+ process_noop_events(resource, callback, events) and return false unless events.detect { |e| e.status != "noop" }
+ resource.send(callback)
- resource.notice "Triggered '#{callback}' from #{events.length} events"
- return true
- rescue => detail
- resource.err "Failed to call #{callback}: #{detail}"
+ resource.notice "Triggered '#{callback}' from #{events.length} events"
+ return true
+ rescue => detail
+ resource.err "Failed to call #{callback}: #{detail}"
- transaction.resource_status(resource).failed_to_restart = true
- puts detail.backtrace if Puppet[:trace]
- return false
- end
+ transaction.resource_status(resource).failed_to_restart = true
+ puts detail.backtrace if Puppet[:trace]
+ return false
+ end
- def process_noop_events(resource, callback, events)
- resource.notice "Would have triggered '#{callback}' from #{events.length} events"
+ def process_noop_events(resource, callback, events)
+ resource.notice "Would have triggered '#{callback}' from #{events.length} events"
- # And then add an event for it.
- queue_events(resource, [resource.event(:status => "noop", :name => :noop_restart)])
- true # so the 'and if' works
- end
+ # And then add an event for it.
+ queue_events(resource, [resource.event(:status => "noop", :name => :noop_restart)])
+ true # so the 'and if' works
+ end
end
diff --git a/lib/puppet/transaction/report.rb b/lib/puppet/transaction/report.rb
index 021c020..e6d1e05 100644
--- a/lib/puppet/transaction/report.rb
+++ b/lib/puppet/transaction/report.rb
@@ -6,144 +6,144 @@ require 'puppet/indirector'
# change produces, and Metrics are all of the numerical data involved
# in the transaction.
class Puppet::Transaction::Report
- extend Puppet::Indirector
+ extend Puppet::Indirector
- indirects :report, :terminus_class => :processor
+ indirects :report, :terminus_class => :processor
- attr_reader :resource_statuses, :logs, :metrics, :host, :time
+ attr_reader :resource_statuses, :logs, :metrics, :host, :time
- # This is necessary since Marshall doesn't know how to
- # dump hash with default proc (see below @records)
- def self.default_format
- :yaml
- end
-
- def <<(msg)
- @logs << msg
- self
- end
+ # This is necessary since Marshall doesn't know how to
+ # dump hash with default proc (see below @records)
+ def self.default_format
+ :yaml
+ end
- def add_times(name, value)
- @external_times[name] = value
- end
+ def <<(msg)
+ @logs << msg
+ self
+ end
- def add_metric(name, hash)
- metric = Puppet::Util::Metric.new(name)
+ def add_times(name, value)
+ @external_times[name] = value
+ end
- hash.each do |name, value|
- metric.newvalue(name, value)
- end
+ def add_metric(name, hash)
+ metric = Puppet::Util::Metric.new(name)
- @metrics[metric.name] = metric
- metric
+ hash.each do |name, value|
+ metric.newvalue(name, value)
end
- def add_resource_status(status)
- @resource_statuses[status.resource] = status
+ @metrics[metric.name] = metric
+ metric
+ end
+
+ def add_resource_status(status)
+ @resource_statuses[status.resource] = status
+ end
+
+ def calculate_metrics
+ calculate_resource_metrics
+ calculate_time_metrics
+ calculate_change_metrics
+ calculate_event_metrics
+ end
+
+ def initialize
+ @metrics = {}
+ @logs = []
+ @resource_statuses = {}
+ @external_times ||= {}
+ @host = Puppet[:certname]
+ @time = Time.now
+ end
+
+ def name
+ host
+ end
+
+ # Provide a summary of this report.
+ def summary
+ ret = ""
+
+ @metrics.sort { |a,b| a[1].label <=> b[1].label }.each do |name, metric|
+ ret += "#{metric.label}:\n"
+ metric.values.sort { |a,b|
+ # sort by label
+ if a[0] == :total
+ 1
+ elsif b[0] == :total
+ -1
+ else
+ a[1] <=> b[1]
+ end
+ }.each do |name, label, value|
+ next if value == 0
+ value = "%0.2f" % value if value.is_a?(Float)
+ ret += " %15s %s\n" % [label + ":", value]
+ end
end
-
- def calculate_metrics
- calculate_resource_metrics
- calculate_time_metrics
- calculate_change_metrics
- calculate_event_metrics
+ ret
+ end
+
+ # Based on the contents of this report's metrics, compute a single number
+ # that represents the report. The resulting number is a bitmask where
+ # individual bits represent the presence of different metrics.
+ def exit_status
+ status = 0
+ status |= 2 if @metrics["changes"][:total] > 0
+ status |= 4 if @metrics["resources"][:failed] > 0
+ status
+ end
+
+ private
+
+ def calculate_change_metrics
+ metrics = Hash.new(0)
+ resource_statuses.each do |name, status|
+ metrics[:total] += status.change_count if status.change_count
end
- def initialize
- @metrics = {}
- @logs = []
- @resource_statuses = {}
- @external_times ||= {}
- @host = Puppet[:certname]
- @time = Time.now
- end
+ add_metric(:changes, metrics)
+ end
- def name
- host
+ def calculate_event_metrics
+ metrics = Hash.new(0)
+ resource_statuses.each do |name, status|
+ metrics[:total] += status.events.length
+ status.events.each do |event|
+ metrics[event.status] += 1
+ end
end
- # Provide a summary of this report.
- def summary
- ret = ""
-
- @metrics.sort { |a,b| a[1].label <=> b[1].label }.each do |name, metric|
- ret += "#{metric.label}:\n"
- metric.values.sort { |a,b|
- # sort by label
- if a[0] == :total
- 1
- elsif b[0] == :total
- -1
- else
- a[1] <=> b[1]
- end
- }.each do |name, label, value|
- next if value == 0
- value = "%0.2f" % value if value.is_a?(Float)
- ret += " %15s %s\n" % [label + ":", value]
- end
- end
- ret
- end
+ add_metric(:events, metrics)
+ end
- # Based on the contents of this report's metrics, compute a single number
- # that represents the report. The resulting number is a bitmask where
- # individual bits represent the presence of different metrics.
- def exit_status
- status = 0
- status |= 2 if @metrics["changes"][:total] > 0
- status |= 4 if @metrics["resources"][:failed] > 0
- status
- end
+ def calculate_resource_metrics
+ metrics = Hash.new(0)
+ metrics[:total] = resource_statuses.length
- private
+ resource_statuses.each do |name, status|
- def calculate_change_metrics
- metrics = Hash.new(0)
- resource_statuses.each do |name, status|
- metrics[:total] += status.change_count if status.change_count
- end
-
- add_metric(:changes, metrics)
+ Puppet::Resource::Status::STATES.each do |state|
+ metrics[state] += 1 if status.send(state)
+ end
end
- def calculate_event_metrics
- metrics = Hash.new(0)
- resource_statuses.each do |name, status|
- metrics[:total] += status.events.length
- status.events.each do |event|
- metrics[event.status] += 1
- end
- end
+ add_metric(:resources, metrics)
+ end
- add_metric(:events, metrics)
+ def calculate_time_metrics
+ metrics = Hash.new(0)
+ resource_statuses.each do |name, status|
+ type = Puppet::Resource.new(name).type
+ metrics[type.to_s.downcase] += status.evaluation_time if status.evaluation_time
end
- def calculate_resource_metrics
- metrics = Hash.new(0)
- metrics[:total] = resource_statuses.length
-
- resource_statuses.each do |name, status|
-
- Puppet::Resource::Status::STATES.each do |state|
- metrics[state] += 1 if status.send(state)
- end
- end
-
- add_metric(:resources, metrics)
+ @external_times.each do |name, value|
+ metrics[name.to_s.downcase] = value
end
- def calculate_time_metrics
- metrics = Hash.new(0)
- resource_statuses.each do |name, status|
- type = Puppet::Resource.new(name).type
- metrics[type.to_s.downcase] += status.evaluation_time if status.evaluation_time
- end
-
- @external_times.each do |name, value|
- metrics[name.to_s.downcase] = value
- end
-
- add_metric(:time, metrics)
- end
+ add_metric(:time, metrics)
+ end
end
diff --git a/lib/puppet/transaction/resource_harness.rb b/lib/puppet/transaction/resource_harness.rb
index 5f90df5..aace6a3 100644
--- a/lib/puppet/transaction/resource_harness.rb
+++ b/lib/puppet/transaction/resource_harness.rb
@@ -1,150 +1,150 @@
require 'puppet/resource/status'
class Puppet::Transaction::ResourceHarness
- extend Forwardable
- def_delegators :@transaction, :relationship_graph
+ extend Forwardable
+ def_delegators :@transaction, :relationship_graph
- attr_reader :transaction
+ attr_reader :transaction
- def allow_changes?(resource)
- return true unless resource.purging? and resource.deleting?
- return true unless deps = relationship_graph.dependents(resource) and ! deps.empty? and deps.detect { |d| ! d.deleting? }
+ def allow_changes?(resource)
+ return true unless resource.purging? and resource.deleting?
+ return true unless deps = relationship_graph.dependents(resource) and ! deps.empty? and deps.detect { |d| ! d.deleting? }
- deplabel = deps.collect { |r| r.ref }.join(",")
- plurality = deps.length > 1 ? "":"s"
- resource.warning "#{deplabel} still depend#{plurality} on me -- not purging"
- false
- end
-
- def apply_changes(status, changes)
- changes.each do |change|
- status << change.apply
+ deplabel = deps.collect { |r| r.ref }.join(",")
+ plurality = deps.length > 1 ? "":"s"
+ resource.warning "#{deplabel} still depend#{plurality} on me -- not purging"
+ false
+ end
- cache(change.property.resource, change.property.name, change.is) if change.auditing?
- end
- status.changed = true
- end
+ def apply_changes(status, changes)
+ changes.each do |change|
+ status << change.apply
- # Used mostly for scheduling at this point.
- def cached(resource, name)
- Puppet::Util::Storage.cache(resource)[name]
+ cache(change.property.resource, change.property.name, change.is) if change.auditing?
end
+ status.changed = true
+ end
- # Used mostly for scheduling at this point.
- def cache(resource, name, value)
- Puppet::Util::Storage.cache(resource)[name] = value
- end
+ # Used mostly for scheduling at this point.
+ def cached(resource, name)
+ Puppet::Util::Storage.cache(resource)[name]
+ end
- def changes_to_perform(status, resource)
- current = resource.retrieve_resource
+ # Used mostly for scheduling at this point.
+ def cache(resource, name, value)
+ Puppet::Util::Storage.cache(resource)[name] = value
+ end
- cache resource, :checked, Time.now
+ def changes_to_perform(status, resource)
+ current = resource.retrieve_resource
- return [] if ! allow_changes?(resource)
+ cache resource, :checked, Time.now
- audited = copy_audited_parameters(resource, current)
+ return [] if ! allow_changes?(resource)
- if param = resource.parameter(:ensure)
- return [] if absent_and_not_being_created?(current, param)
- return [Puppet::Transaction::Change.new(param, current[:ensure])] unless ensure_is_insync?(current, param)
- return [] if ensure_should_be_absent?(current, param)
- end
+ audited = copy_audited_parameters(resource, current)
- resource.properties.reject { |p| p.name == :ensure }.reject do |param|
- param.should.nil?
- end.reject do |param|
- param_is_insync?(current, param)
- end.collect do |param|
- change = Puppet::Transaction::Change.new(param, current[param.name])
- change.auditing = true if audited.include?(param.name)
- change
- end
+ if param = resource.parameter(:ensure)
+ return [] if absent_and_not_being_created?(current, param)
+ return [Puppet::Transaction::Change.new(param, current[:ensure])] unless ensure_is_insync?(current, param)
+ return [] if ensure_should_be_absent?(current, param)
end
- def copy_audited_parameters(resource, current)
- return [] unless audit = resource[:audit]
- audit = Array(audit).collect { |p| p.to_sym }
- audited = []
- audit.find_all do |param|
- next if resource[param]
-
- if value = cached(resource, param)
- resource[param] = value
- audited << param
- else
- resource.info "Storing newly-audited value #{current[param]} for #{param}"
- cache(resource, param, current[param])
- end
- end
-
- audited
+ resource.properties.reject { |p| p.name == :ensure }.reject do |param|
+ param.should.nil?
+ end.reject do |param|
+ param_is_insync?(current, param)
+ end.collect do |param|
+ change = Puppet::Transaction::Change.new(param, current[param.name])
+ change.auditing = true if audited.include?(param.name)
+ change
end
-
- def evaluate(resource)
- start = Time.now
- status = Puppet::Resource::Status.new(resource)
-
- if changes = changes_to_perform(status, resource) and ! changes.empty?
- status.out_of_sync = true
- status.change_count = changes.length
- apply_changes(status, changes)
- if ! resource.noop?
- cache(resource, :synced, Time.now)
- resource.flush if resource.respond_to?(:flush)
- end
- end
- return status
- rescue => detail
- resource.fail "Could not create resource status: #{detail}" unless status
- puts detail.backtrace if Puppet[:trace]
- resource.err "Could not evaluate: #{detail}"
- status.failed = true
- return status
- ensure
- (status.evaluation_time = Time.now - start) if status
+ end
+
+ def copy_audited_parameters(resource, current)
+ return [] unless audit = resource[:audit]
+ audit = Array(audit).collect { |p| p.to_sym }
+ audited = []
+ audit.find_all do |param|
+ next if resource[param]
+
+ if value = cached(resource, param)
+ resource[param] = value
+ audited << param
+ else
+ resource.info "Storing newly-audited value #{current[param]} for #{param}"
+ cache(resource, param, current[param])
+ end
end
- def initialize(transaction)
- @transaction = transaction
+ audited
+ end
+
+ def evaluate(resource)
+ start = Time.now
+ status = Puppet::Resource::Status.new(resource)
+
+ if changes = changes_to_perform(status, resource) and ! changes.empty?
+ status.out_of_sync = true
+ status.change_count = changes.length
+ apply_changes(status, changes)
+ if ! resource.noop?
+ cache(resource, :synced, Time.now)
+ resource.flush if resource.respond_to?(:flush)
+ end
end
-
- def scheduled?(status, resource)
- return true if Puppet[:ignoreschedules]
- return true unless schedule = schedule(resource)
-
- # We use 'checked' here instead of 'synced' because otherwise we'll
- # end up checking most resources most times, because they will generally
- # have been synced a long time ago (e.g., a file only gets updated
- # once a month on the server and its schedule is daily; the last sync time
- # will have been a month ago, so we'd end up checking every run).
- schedule.match?(cached(resource, :checked).to_i)
+ return status
+ rescue => detail
+ resource.fail "Could not create resource status: #{detail}" unless status
+ puts detail.backtrace if Puppet[:trace]
+ resource.err "Could not evaluate: #{detail}"
+ status.failed = true
+ return status
+ ensure
+ (status.evaluation_time = Time.now - start) if status
+ end
+
+ def initialize(transaction)
+ @transaction = transaction
+ end
+
+ def scheduled?(status, resource)
+ return true if Puppet[:ignoreschedules]
+ return true unless schedule = schedule(resource)
+
+ # We use 'checked' here instead of 'synced' because otherwise we'll
+ # end up checking most resources most times, because they will generally
+ # have been synced a long time ago (e.g., a file only gets updated
+ # once a month on the server and its schedule is daily; the last sync time
+ # will have been a month ago, so we'd end up checking every run).
+ schedule.match?(cached(resource, :checked).to_i)
+ end
+
+ def schedule(resource)
+ unless resource.catalog
+ resource.warning "Cannot schedule without a schedule-containing catalog"
+ return nil
end
- def schedule(resource)
- unless resource.catalog
- resource.warning "Cannot schedule without a schedule-containing catalog"
- return nil
- end
+ return nil unless name = resource[:schedule]
+ resource.catalog.resource(:schedule, name) || resource.fail("Could not find schedule #{name}")
+ end
- return nil unless name = resource[:schedule]
- resource.catalog.resource(:schedule, name) || resource.fail("Could not find schedule #{name}")
- end
-
- private
+ private
- def absent_and_not_being_created?(current, param)
- current[:ensure] == :absent and param.should.nil?
- end
+ def absent_and_not_being_created?(current, param)
+ current[:ensure] == :absent and param.should.nil?
+ end
- def ensure_is_insync?(current, param)
- param.insync?(current[:ensure])
- end
+ def ensure_is_insync?(current, param)
+ param.insync?(current[:ensure])
+ end
- def ensure_should_be_absent?(current, param)
- param.should == :absent
- end
+ def ensure_should_be_absent?(current, param)
+ param.should == :absent
+ end
- def param_is_insync?(current, param)
- param.insync?(current[param.name])
- end
+ def param_is_insync?(current, param)
+ param.insync?(current[param.name])
+ end
end
diff --git a/lib/puppet/transportable.rb b/lib/puppet/transportable.rb
index 74c1bbf..f7b839c 100644
--- a/lib/puppet/transportable.rb
+++ b/lib/puppet/transportable.rb
@@ -2,247 +2,247 @@ require 'puppet'
require 'yaml'
module Puppet
- # The transportable objects themselves. Basically just a hash with some
- # metadata and a few extra methods. I used to have the object actually
- # be a subclass of Hash, but I could never correctly dump them using
- # YAML.
- class TransObject
- include Enumerable
- attr_accessor :type, :name, :file, :line, :catalog
-
- attr_writer :tags
-
- %w{has_key? include? length delete empty? << [] []=}.each { |method|
- define_method(method) do |*args|
- @params.send(method, *args)
- end
- }
-
- def each
- @params.each { |p,v| yield p, v }
- end
-
- def initialize(name,type)
- @type = type.to_s.downcase
- @name = name
- @params = {}
- @tags = []
- end
-
- def longname
- [@type, at name].join('--')
- end
+ # The transportable objects themselves. Basically just a hash with some
+ # metadata and a few extra methods. I used to have the object actually
+ # be a subclass of Hash, but I could never correctly dump them using
+ # YAML.
+ class TransObject
+ include Enumerable
+ attr_accessor :type, :name, :file, :line, :catalog
+
+ attr_writer :tags
+
+ %w{has_key? include? length delete empty? << [] []=}.each { |method|
+ define_method(method) do |*args|
+ @params.send(method, *args)
+ end
+ }
+
+ def each
+ @params.each { |p,v| yield p, v }
+ end
- def ref
- @ref ||= Puppet::Resource.new(@type, @name)
- @ref.to_s
- end
+ def initialize(name,type)
+ @type = type.to_s.downcase
+ @name = name
+ @params = {}
+ @tags = []
+ end
- def tags
- @tags
- end
+ def longname
+ [@type, at name].join('--')
+ end
- # Convert a defined type into a component.
- def to_component
- trans = TransObject.new(ref, :component)
- @params.each { |param,value|
- next unless Puppet::Type::Component.valid_parameter?(param)
- Puppet.debug "Defining #{param} on #{ref}"
- trans[param] = value
- }
- trans.catalog = self.catalog
- Puppet::Type::Component.create(trans)
- end
+ def ref
+ @ref ||= Puppet::Resource.new(@type, @name)
+ @ref.to_s
+ end
- def to_hash
- @params.dup
- end
+ def tags
+ @tags
+ end
- def to_s
- "#{@type}(#{@name}) => #{super}"
- end
+ # Convert a defined type into a component.
+ def to_component
+ trans = TransObject.new(ref, :component)
+ @params.each { |param,value|
+ next unless Puppet::Type::Component.valid_parameter?(param)
+ Puppet.debug "Defining #{param} on #{ref}"
+ trans[param] = value
+ }
+ trans.catalog = self.catalog
+ Puppet::Type::Component.create(trans)
+ end
- def to_manifest
- "%s { '%s':\n%s\n}" % [self.type.to_s, self.name,
- @params.collect { |p, v|
- if v.is_a? Array
- " #{p} => [\'#{v.join("','")}\']"
- else
- " #{p} => \'#{v}\'"
- end
- }.join(",\n")
- ]
- end
+ def to_hash
+ @params.dup
+ end
- # Create a normalized resource from our TransObject.
- def to_resource
- result = Puppet::Resource.new(type, name, :parameters => @params.dup)
- result.tag(*tags)
+ def to_s
+ "#{@type}(#{@name}) => #{super}"
+ end
- result
- end
+ def to_manifest
+ "%s { '%s':\n%s\n}" % [self.type.to_s, self.name,
+ @params.collect { |p, v|
+ if v.is_a? Array
+ " #{p} => [\'#{v.join("','")}\']"
+ else
+ " #{p} => \'#{v}\'"
+ end
+ }.join(",\n")
+ ]
+ end
- def to_yaml_properties
- instance_variables.reject { |v| %w{@ref}.include?(v) }
- end
+ # Create a normalized resource from our TransObject.
+ def to_resource
+ result = Puppet::Resource.new(type, name, :parameters => @params.dup)
+ result.tag(*tags)
- def to_ref
- ref
- end
+ result
+ end
- def to_ral
- to_resource.to_ral
- end
+ def to_yaml_properties
+ instance_variables.reject { |v| %w{@ref}.include?(v) }
end
- # Just a linear container for objects. Behaves mostly like an array, except
- # that YAML will correctly dump them even with their instance variables.
- class TransBucket
- include Enumerable
-
- attr_accessor :name, :type, :file, :line, :classes, :keyword, :top, :catalog
-
- %w{delete shift include? length empty? << []}.each { |method|
- define_method(method) do |*args|
- #Puppet.warning "Calling #{method} with #{args.inspect}"
- @children.send(method, *args)
- #Puppet.warning @params.inspect
- end
- }
-
- # Recursively yield everything.
- def delve(&block)
- @children.each do |obj|
- block.call(obj)
- if obj.is_a? self.class
- obj.delve(&block)
- else
- obj
- end
- end
- end
+ def to_ref
+ ref
+ end
- def each
- @children.each { |c| yield c }
- end
+ def to_ral
+ to_resource.to_ral
+ end
+ end
+
+ # Just a linear container for objects. Behaves mostly like an array, except
+ # that YAML will correctly dump them even with their instance variables.
+ class TransBucket
+ include Enumerable
+
+ attr_accessor :name, :type, :file, :line, :classes, :keyword, :top, :catalog
+
+ %w{delete shift include? length empty? << []}.each { |method|
+ define_method(method) do |*args|
+ #Puppet.warning "Calling #{method} with #{args.inspect}"
+ @children.send(method, *args)
+ #Puppet.warning @params.inspect
+ end
+ }
+
+ # Recursively yield everything.
+ def delve(&block)
+ @children.each do |obj|
+ block.call(obj)
+ if obj.is_a? self.class
+ obj.delve(&block)
+ else
+ obj
+ end
+ end
+ end
- # Turn our heirarchy into a flat list
- def flatten
- @children.collect do |obj|
- if obj.is_a? Puppet::TransBucket
- obj.flatten
- else
- obj
- end
- end.flatten
- end
+ def each
+ @children.each { |c| yield c }
+ end
- def initialize(children = [])
- @children = children
+ # Turn our heirarchy into a flat list
+ def flatten
+ @children.collect do |obj|
+ if obj.is_a? Puppet::TransBucket
+ obj.flatten
+ else
+ obj
end
+ end.flatten
+ end
- def push(*args)
- args.each { |arg|
- case arg
- when Puppet::TransBucket, Puppet::TransObject
- # nada
- else
- raise Puppet::DevError,
- "TransBuckets cannot handle objects of type #{arg.class}"
- end
- }
- @children += args
- end
+ def initialize(children = [])
+ @children = children
+ end
- # Convert to a parseable manifest
- def to_manifest
- unless self.top
- raise Puppet::DevError, "No keyword; cannot convert to manifest" unless @keyword
- end
-
- str = "#{@keyword} #{@name} {\n%s\n}"
- str % @children.collect { |child|
- child.to_manifest
- }.collect { |str|
- if self.top
- str
- else
- str.gsub(/^/, " ") # indent everything once
- end
- }.join("\n\n") # and throw in a blank line
- end
+ def push(*args)
+ args.each { |arg|
+ case arg
+ when Puppet::TransBucket, Puppet::TransObject
+ # nada
+ else
+ raise Puppet::DevError,
+ "TransBuckets cannot handle objects of type #{arg.class}"
+ end
+ }
+ @children += args
+ end
- def to_yaml_properties
- instance_variables
- end
+ # Convert to a parseable manifest
+ def to_manifest
+ unless self.top
+ raise Puppet::DevError, "No keyword; cannot convert to manifest" unless @keyword
+ end
+
+ str = "#{@keyword} #{@name} {\n%s\n}"
+ str % @children.collect { |child|
+ child.to_manifest
+ }.collect { |str|
+ if self.top
+ str
+ else
+ str.gsub(/^/, " ") # indent everything once
+ end
+ }.join("\n\n") # and throw in a blank line
+ end
- # Create a resource graph from our structure.
- def to_catalog(clear_on_failure = true)
- catalog = Puppet::Resource::Catalog.new(Facter.value("hostname"))
-
- # This should really use the 'delve' method, but this
- # whole class is going away relatively soon, hopefully,
- # so it's not worth it.
- delver = proc do |obj|
- obj.catalog = catalog
- unless container = catalog.resource(obj.to_ref)
- container = obj.to_ral
- catalog.add_resource container
- end
- obj.each do |child|
- child.catalog = catalog
- unless resource = catalog.resource(child.to_ref)
- resource = child.to_ral
- catalog.add_resource resource
- end
-
- catalog.add_edge(container, resource)
- delver.call(child) if child.is_a?(self.class)
- end
- end
-
- begin
- delver.call(self)
- catalog.finalize
- rescue => detail
- # This is important until we lose the global resource references.
- catalog.clear if (clear_on_failure)
- raise
- end
-
- catalog
- end
+ def to_yaml_properties
+ instance_variables
+ end
- def to_ref
- unless defined?(@ref)
- if self.type and self.name
- @ref = Puppet::Resource.new(self.type, self.name)
- elsif self.type and ! self.name # This is old-school node types
- @ref = Puppet::Resource.new("node", self.type)
- elsif ! self.type and self.name
- @ref = Puppet::Resource.new("component", self.name)
- else
- @ref = nil
- end
- end
- @ref.to_s if @ref
- end
+ # Create a resource graph from our structure.
+ def to_catalog(clear_on_failure = true)
+ catalog = Puppet::Resource::Catalog.new(Facter.value("hostname"))
+
+ # This should really use the 'delve' method, but this
+ # whole class is going away relatively soon, hopefully,
+ # so it's not worth it.
+ delver = proc do |obj|
+ obj.catalog = catalog
+ unless container = catalog.resource(obj.to_ref)
+ container = obj.to_ral
+ catalog.add_resource container
+ end
+ obj.each do |child|
+ child.catalog = catalog
+ unless resource = catalog.resource(child.to_ref)
+ resource = child.to_ral
+ catalog.add_resource resource
+ end
+
+ catalog.add_edge(container, resource)
+ delver.call(child) if child.is_a?(self.class)
+ end
+ end
+
+ begin
+ delver.call(self)
+ catalog.finalize
+ rescue => detail
+ # This is important until we lose the global resource references.
+ catalog.clear if (clear_on_failure)
+ raise
+ end
+
+ catalog
+ end
- def to_ral
- to_resource.to_ral
- end
+ def to_ref
+ unless defined?(@ref)
+ if self.type and self.name
+ @ref = Puppet::Resource.new(self.type, self.name)
+ elsif self.type and ! self.name # This is old-school node types
+ @ref = Puppet::Resource.new("node", self.type)
+ elsif ! self.type and self.name
+ @ref = Puppet::Resource.new("component", self.name)
+ else
+ @ref = nil
+ end
+ end
+ @ref.to_s if @ref
+ end
- # Create a normalized resource from our TransObject.
- def to_resource
- params = defined?(@parameters) ? @parameters.dup : {}
- Puppet::Resource.new(type, name, :parameters => params)
- end
+ def to_ral
+ to_resource.to_ral
+ end
- def param(param,value)
- @parameters ||= {}
- @parameters[param] = value
- end
+ # Create a normalized resource from our TransObject.
+ def to_resource
+ params = defined?(@parameters) ? @parameters.dup : {}
+ Puppet::Resource.new(type, name, :parameters => params)
+ end
+ def param(param,value)
+ @parameters ||= {}
+ @parameters[param] = value
end
+
+ end
end
diff --git a/lib/puppet/type.rb b/lib/puppet/type.rb
index 1e0bde5..d0fea97 100644
--- a/lib/puppet/type.rb
+++ b/lib/puppet/type.rb
@@ -17,1868 +17,1868 @@ require 'puppet/util/tagging'
module Puppet
class Type
- include Puppet::Util
- include Puppet::Util::Errors
- include Puppet::Util::LogPaths
- include Puppet::Util::Logging
- include Puppet::Util::Cacher
- include Puppet::FileCollection::Lookup
- include Puppet::Util::Tagging
-
- ###############################
- # Code related to resource type attributes.
- class << self
- include Puppet::Util::ClassGen
- include Puppet::Util::Warnings
- attr_reader :properties
- end
-
- def self.states
- warnonce "The states method is deprecated; use properties"
- properties
- end
-
- # All parameters, in the appropriate order. The key_attributes come first, then
- # the provider, then the properties, and finally the params and metaparams
- # in the order they were specified in the files.
- def self.allattrs
- key_attributes | (parameters & [:provider]) | properties.collect { |property| property.name } | parameters | metaparams
- end
-
- # Retrieve an attribute alias, if there is one.
- def self.attr_alias(param)
- @attr_aliases[symbolize(param)]
- end
-
- # Create an alias to an existing attribute. This will cause the aliased
- # attribute to be valid when setting and retrieving values on the instance.
- def self.set_attr_alias(hash)
- hash.each do |new, old|
- @attr_aliases[symbolize(new)] = symbolize(old)
- end
- end
-
- # Find the class associated with any given attribute.
- def self.attrclass(name)
- @attrclasses ||= {}
-
- # We cache the value, since this method gets called such a huge number
- # of times (as in, hundreds of thousands in a given run).
- unless @attrclasses.include?(name)
- @attrclasses[name] = case self.attrtype(name)
- when :property; @validproperties[name]
- when :meta; @@metaparamhash[name]
- when :param; @paramhash[name]
- end
- end
- @attrclasses[name]
- end
-
- # What type of parameter are we dealing with? Cache the results, because
- # this method gets called so many times.
- def self.attrtype(attr)
- @attrtypes ||= {}
- unless @attrtypes.include?(attr)
- @attrtypes[attr] = case
- when @validproperties.include?(attr); :property
- when @paramhash.include?(attr); :param
- when @@metaparamhash.include?(attr); :meta
- end
- end
-
- @attrtypes[attr]
- end
-
- def self.eachmetaparam
- @@metaparams.each { |p| yield p.name }
- end
+ include Puppet::Util
+ include Puppet::Util::Errors
+ include Puppet::Util::LogPaths
+ include Puppet::Util::Logging
+ include Puppet::Util::Cacher
+ include Puppet::FileCollection::Lookup
+ include Puppet::Util::Tagging
+
+ ###############################
+ # Code related to resource type attributes.
+ class << self
+ include Puppet::Util::ClassGen
+ include Puppet::Util::Warnings
+ attr_reader :properties
+ end
+
+ def self.states
+ warnonce "The states method is deprecated; use properties"
+ properties
+ end
+
+ # All parameters, in the appropriate order. The key_attributes come first, then
+ # the provider, then the properties, and finally the params and metaparams
+ # in the order they were specified in the files.
+ def self.allattrs
+ key_attributes | (parameters & [:provider]) | properties.collect { |property| property.name } | parameters | metaparams
+ end
+
+ # Retrieve an attribute alias, if there is one.
+ def self.attr_alias(param)
+ @attr_aliases[symbolize(param)]
+ end
+
+ # Create an alias to an existing attribute. This will cause the aliased
+ # attribute to be valid when setting and retrieving values on the instance.
+ def self.set_attr_alias(hash)
+ hash.each do |new, old|
+ @attr_aliases[symbolize(new)] = symbolize(old)
+ end
+ end
+
+ # Find the class associated with any given attribute.
+ def self.attrclass(name)
+ @attrclasses ||= {}
+
+ # We cache the value, since this method gets called such a huge number
+ # of times (as in, hundreds of thousands in a given run).
+ unless @attrclasses.include?(name)
+ @attrclasses[name] = case self.attrtype(name)
+ when :property; @validproperties[name]
+ when :meta; @@metaparamhash[name]
+ when :param; @paramhash[name]
+ end
+ end
+ @attrclasses[name]
+ end
+
+ # What type of parameter are we dealing with? Cache the results, because
+ # this method gets called so many times.
+ def self.attrtype(attr)
+ @attrtypes ||= {}
+ unless @attrtypes.include?(attr)
+ @attrtypes[attr] = case
+ when @validproperties.include?(attr); :property
+ when @paramhash.include?(attr); :param
+ when @@metaparamhash.include?(attr); :meta
+ end
+ end
+
+ @attrtypes[attr]
+ end
+
+ def self.eachmetaparam
+ @@metaparams.each { |p| yield p.name }
+ end
+
+ # Create the 'ensure' class. This is a separate method so other types
+ # can easily call it and create their own 'ensure' values.
+ def self.ensurable(&block)
+ if block_given?
+ self.newproperty(:ensure, :parent => Puppet::Property::Ensure, &block)
+ else
+ self.newproperty(:ensure, :parent => Puppet::Property::Ensure) do
+ self.defaultvalues
+ end
+ end
+ end
+
+ # Should we add the 'ensure' property to this class?
+ def self.ensurable?
+ # If the class has all three of these methods defined, then it's
+ # ensurable.
+ ens = [:exists?, :create, :destroy].inject { |set, method|
+ set &&= self.public_method_defined?(method)
+ }
+
+ ens
+ end
+
+ # Deal with any options passed into parameters.
+ def self.handle_param_options(name, options)
+ # If it's a boolean parameter, create a method to test the value easily
+ if options[:boolean]
+ define_method(name.to_s + "?") do
+ val = self[name]
+ if val == :true or val == true
+ return true
+ end
+ end
+ end
+ end
+
+ # Is the parameter in question a meta-parameter?
+ def self.metaparam?(param)
+ @@metaparamhash.include?(symbolize(param))
+ end
+
+ # Find the metaparameter class associated with a given metaparameter name.
+ def self.metaparamclass(name)
+ @@metaparamhash[symbolize(name)]
+ end
+
+ def self.metaparams
+ @@metaparams.collect { |param| param.name }
+ end
+
+ def self.metaparamdoc(metaparam)
+ @@metaparamhash[metaparam].doc
+ end
+
+ # Create a new metaparam. Requires a block and a name, stores it in the
+ # @parameters array, and does some basic checking on it.
+ def self.newmetaparam(name, options = {}, &block)
+ @@metaparams ||= []
+ @@metaparamhash ||= {}
+ name = symbolize(name)
+
+
+ param = genclass(
+ name,
+ :parent => options[:parent] || Puppet::Parameter,
+ :prefix => "MetaParam",
+ :hash => @@metaparamhash,
+ :array => @@metaparams,
+ :attributes => options[:attributes],
+
+ &block
+ )
+
+ # Grr.
+ param.required_features = options[:required_features] if options[:required_features]
+
+ handle_param_options(name, options)
+
+ param.metaparam = true
+
+ param
+ end
+
+ def self.key_attribute_parameters
+ @key_attribute_parameters ||= (
+ params = @parameters.find_all { |param|
+ param.isnamevar? or param.name == :name
+ }
+ )
+ end
- # Create the 'ensure' class. This is a separate method so other types
- # can easily call it and create their own 'ensure' values.
- def self.ensurable(&block)
- if block_given?
- self.newproperty(:ensure, :parent => Puppet::Property::Ensure, &block)
- else
- self.newproperty(:ensure, :parent => Puppet::Property::Ensure) do
- self.defaultvalues
- end
- end
- end
+ def self.key_attributes
+ key_attribute_parameters.collect { |p| p.name }
+ end
+
+ def self.title_patterns
+ case key_attributes.length
+ when 0; []
+ when 1;
+ identity = lambda {|x| x}
+ [ [ /(.*)/, [ [key_attributes.first, identity ] ] ] ]
+ else
+ raise Puppet::DevError,"you must specify title patterns when there are two or more key attributes"
+ end
+ end
+
+ def uniqueness_key
+ to_resource.uniqueness_key
+ end
+
+ # Create a new parameter. Requires a block and a name, stores it in the
+ # @parameters array, and does some basic checking on it.
+ def self.newparam(name, options = {}, &block)
+ options[:attributes] ||= {}
+
+ param = genclass(
+ name,
+ :parent => options[:parent] || Puppet::Parameter,
+ :attributes => options[:attributes],
+ :block => block,
+ :prefix => "Parameter",
+ :array => @parameters,
- # Should we add the 'ensure' property to this class?
- def self.ensurable?
- # If the class has all three of these methods defined, then it's
- # ensurable.
- ens = [:exists?, :create, :destroy].inject { |set, method|
- set &&= self.public_method_defined?(method)
- }
+ :hash => @paramhash
+ )
+
+ handle_param_options(name, options)
- ens
- end
+ # Grr.
+ param.required_features = options[:required_features] if options[:required_features]
- # Deal with any options passed into parameters.
- def self.handle_param_options(name, options)
- # If it's a boolean parameter, create a method to test the value easily
- if options[:boolean]
- define_method(name.to_s + "?") do
- val = self[name]
- if val == :true or val == true
- return true
- end
- end
- end
- end
+ param.isnamevar if options[:namevar]
- # Is the parameter in question a meta-parameter?
- def self.metaparam?(param)
- @@metaparamhash.include?(symbolize(param))
- end
+ param
+ end
- # Find the metaparameter class associated with a given metaparameter name.
- def self.metaparamclass(name)
- @@metaparamhash[symbolize(name)]
- end
+ def self.newstate(name, options = {}, &block)
+ Puppet.warning "newstate() has been deprecrated; use newproperty(#{name})"
+ newproperty(name, options, &block)
+ end
- def self.metaparams
- @@metaparams.collect { |param| param.name }
- end
+ # Create a new property. The first parameter must be the name of the property;
+ # this is how users will refer to the property when creating new instances.
+ # The second parameter is a hash of options; the options are:
+ # * <tt>:parent</tt>: The parent class for the property. Defaults to Puppet::Property.
+ # * <tt>:retrieve</tt>: The method to call on the provider or @parent object (if
+ # the provider is not set) to retrieve the current value.
+ def self.newproperty(name, options = {}, &block)
+ name = symbolize(name)
+
+ # This is here for types that might still have the old method of defining
+ # a parent class.
+ unless options.is_a? Hash
+ raise Puppet::DevError,
+ "Options must be a hash, not #{options.inspect}"
+ end
+
+ raise Puppet::DevError, "Class #{self.name} already has a property named #{name}" if @validproperties.include?(name)
+
+ if parent = options[:parent]
+ options.delete(:parent)
+ else
+ parent = Puppet::Property
+ end
+
+ # We have to create our own, new block here because we want to define
+ # an initial :retrieve method, if told to, and then eval the passed
+ # block if available.
+ prop = genclass(name, :parent => parent, :hash => @validproperties, :attributes => options) do
+ # If they've passed a retrieve method, then override the retrieve
+ # method on the class.
+ if options[:retrieve]
+ define_method(:retrieve) do
+ provider.send(options[:retrieve])
+ end
+ end
+
+ class_eval(&block) if block
+ end
+
+ # If it's the 'ensure' property, always put it first.
+ if name == :ensure
+ @properties.unshift prop
+ else
+ @properties << prop
+ end
+
+ prop
+ end
+
+ def self.paramdoc(param)
+ @paramhash[param].doc
+ end
+
+ # Return the parameter names
+ def self.parameters
+ return [] unless defined?(@parameters)
+ @parameters.collect { |klass| klass.name }
+ end
+
+ # Find the parameter class associated with a given parameter name.
+ def self.paramclass(name)
+ @paramhash[name]
+ end
+
+ # Return the property class associated with a name
+ def self.propertybyname(name)
+ @validproperties[name]
+ end
+
+ def self.validattr?(name)
+ name = symbolize(name)
+ return true if name == :name
+ @validattrs ||= {}
- def self.metaparamdoc(metaparam)
- @@metaparamhash[metaparam].doc
+ unless @validattrs.include?(name)
+ @validattrs[name] = !!(self.validproperty?(name) or self.validparameter?(name) or self.metaparam?(name))
end
- # Create a new metaparam. Requires a block and a name, stores it in the
- # @parameters array, and does some basic checking on it.
- def self.newmetaparam(name, options = {}, &block)
- @@metaparams ||= []
- @@metaparamhash ||= {}
- name = symbolize(name)
-
+ @validattrs[name]
+ end
- param = genclass(
- name,
- :parent => options[:parent] || Puppet::Parameter,
- :prefix => "MetaParam",
- :hash => @@metaparamhash,
- :array => @@metaparams,
- :attributes => options[:attributes],
+ # does the name reflect a valid property?
+ def self.validproperty?(name)
+ name = symbolize(name)
+ @validproperties.include?(name) && @validproperties[name]
+ end
- &block
- )
-
- # Grr.
- param.required_features = options[:required_features] if options[:required_features]
-
- handle_param_options(name, options)
-
- param.metaparam = true
-
- param
- end
-
- def self.key_attribute_parameters
- @key_attribute_parameters ||= (
- params = @parameters.find_all { |param|
- param.isnamevar? or param.name == :name
- }
- )
- end
-
- def self.key_attributes
- key_attribute_parameters.collect { |p| p.name }
- end
-
- def self.title_patterns
- case key_attributes.length
- when 0; []
- when 1;
- identity = lambda {|x| x}
- [ [ /(.*)/, [ [key_attributes.first, identity ] ] ] ]
+ # Return the list of validproperties
+ def self.validproperties
+ return {} unless defined?(@parameters)
+
+ @validproperties.keys
+ end
+
+ # does the name reflect a valid parameter?
+ def self.validparameter?(name)
+ raise Puppet::DevError, "Class #{self} has not defined parameters" unless defined?(@parameters)
+ !!(@paramhash.include?(name) or @@metaparamhash.include?(name))
+ end
+
+ # This is a forward-compatibility method - it's the validity interface we'll use in Puppet::Resource.
+ def self.valid_parameter?(name)
+ validattr?(name)
+ end
+
+ # Return either the attribute alias or the attribute.
+ def attr_alias(name)
+ name = symbolize(name)
+ if synonym = self.class.attr_alias(name)
+ return synonym
+ else
+ return name
+ end
+ end
+
+ # Are we deleting this resource?
+ def deleting?
+ obj = @parameters[:ensure] and obj.should == :absent
+ end
+
+ # Create a new property if it is valid but doesn't exist
+ # Returns: true if a new parameter was added, false otherwise
+ def add_property_parameter(prop_name)
+ if self.class.validproperty?(prop_name) && !@parameters[prop_name]
+ self.newattr(prop_name)
+ return true
+ end
+ false
+ end
+
+ #
+ # The name_var is the key_attribute in the case that there is only one.
+ #
+ def name_var
+ key_attributes = self.class.key_attributes
+ (key_attributes.length == 1) && key_attributes.first
+ end
+
+ # abstract accessing parameters and properties, and normalize
+ # access to always be symbols, not strings
+ # This returns a value, not an object. It returns the 'is'
+ # value, but you can also specifically return 'is' and 'should'
+ # values using 'object.is(:property)' or 'object.should(:property)'.
+ def [](name)
+ name = attr_alias(name)
+
+ fail("Invalid parameter #{name}(#{name.inspect})") unless self.class.validattr?(name)
+
+ if name == :name
+ name = name_var
+ end
+
+ if obj = @parameters[name]
+ # Note that if this is a property, then the value is the "should" value,
+ # not the current value.
+ obj.value
+ else
+ return nil
+ end
+ end
+
+ # Abstract setting parameters and properties, and normalize
+ # access to always be symbols, not strings. This sets the 'should'
+ # value on properties, and otherwise just sets the appropriate parameter.
+ def []=(name,value)
+ name = attr_alias(name)
+
+ fail("Invalid parameter #{name}") unless self.class.validattr?(name)
+
+ if name == :name
+ name = name_var
+ end
+ raise Puppet::Error.new("Got nil value for #{name}") if value.nil?
+
+ property = self.newattr(name)
+
+ begin
+ # make sure the parameter doesn't have any errors
+ property.value = value
+ rescue => detail
+ error = Puppet::Error.new("Parameter #{name} failed: #{detail}")
+ error.set_backtrace(detail.backtrace)
+ raise error
+ end
+
+ nil
+ end
+
+ # remove a property from the object; useful in testing or in cleanup
+ # when an error has been encountered
+ def delete(attr)
+ attr = symbolize(attr)
+ if @parameters.has_key?(attr)
+ @parameters.delete(attr)
+ else
+ raise Puppet::DevError.new("Undefined attribute '#{attr}' in #{self}")
+ end
+ end
+
+ # iterate across the existing properties
+ def eachproperty
+ # properties is a private method
+ properties.each { |property|
+ yield property
+ }
+ end
+
+ # Create a transaction event. Called by Transaction or by
+ # a property.
+ def event(options = {})
+ Puppet::Transaction::Event.new({:resource => self, :file => file, :line => line, :tags => tags, :version => version}.merge(options))
+ end
+
+ # Let the catalog determine whether a given cached value is
+ # still valid or has expired.
+ def expirer
+ catalog
+ end
+
+ # retrieve the 'should' value for a specified property
+ def should(name)
+ name = attr_alias(name)
+ (prop = @parameters[name] and prop.is_a?(Puppet::Property)) ? prop.should : nil
+ end
+
+ # Create the actual attribute instance. Requires either the attribute
+ # name or class as the first argument, then an optional hash of
+ # attributes to set during initialization.
+ def newattr(name)
+ if name.is_a?(Class)
+ klass = name
+ name = klass.name
+ end
+
+ unless klass = self.class.attrclass(name)
+ raise Puppet::Error, "Resource type #{self.class.name} does not support parameter #{name}"
+ end
+
+ return @parameters[name] if @parameters.include?(name)
+
+ @parameters[name] = klass.new(:resource => self)
+ end
+
+ # return the value of a parameter
+ def parameter(name)
+ @parameters[name.to_sym]
+ end
+
+ def parameters
+ @parameters.dup
+ end
+
+ # Is the named property defined?
+ def propertydefined?(name)
+ name = name.intern unless name.is_a? Symbol
+ @parameters.include?(name)
+ end
+
+ # Return an actual property instance by name; to return the value, use 'resource[param]'
+ # LAK:NOTE(20081028) Since the 'parameter' method is now a superset of this method,
+ # this one should probably go away at some point.
+ def property(name)
+ (obj = @parameters[symbolize(name)] and obj.is_a?(Puppet::Property)) ? obj : nil
+ end
+
+ # For any parameters or properties that have defaults and have not yet been
+ # set, set them now. This method can be handed a list of attributes,
+ # and if so it will only set defaults for those attributes.
+ def set_default(attr)
+ return unless klass = self.class.attrclass(attr)
+ return unless klass.method_defined?(:default)
+ return if @parameters.include?(klass.name)
+
+ return unless parameter = newattr(klass.name)
+
+ if value = parameter.default and ! value.nil?
+ parameter.value = value
+ else
+ @parameters.delete(parameter.name)
+ end
+ end
+
+ # Convert our object to a hash. This just includes properties.
+ def to_hash
+ rethash = {}
+
+ @parameters.each do |name, obj|
+ rethash[name] = obj.value
+ end
+
+ rethash
+ end
+
+ def type
+ self.class.name
+ end
+
+ # Return a specific value for an attribute.
+ def value(name)
+ name = attr_alias(name)
+
+ (obj = @parameters[name] and obj.respond_to?(:value)) ? obj.value : nil
+ end
+
+ def version
+ return 0 unless catalog
+ catalog.version
+ end
+
+ # Return all of the property objects, in the order specified in the
+ # class.
+ def properties
+ self.class.properties.collect { |prop| @parameters[prop.name] }.compact
+ end
+
+ # Is this type's name isomorphic with the object? That is, if the
+ # name conflicts, does it necessarily mean that the objects conflict?
+ # Defaults to true.
+ def self.isomorphic?
+ if defined?(@isomorphic)
+ return @isomorphic
+ else
+ return true
+ end
+ end
+
+ def isomorphic?
+ self.class.isomorphic?
+ end
+
+ # is the instance a managed instance? A 'yes' here means that
+ # the instance was created from the language, vs. being created
+ # in order resolve other questions, such as finding a package
+ # in a list
+ def managed?
+ # Once an object is managed, it always stays managed; but an object
+ # that is listed as unmanaged might become managed later in the process,
+ # so we have to check that every time
+ if @managed
+ return @managed
+ else
+ @managed = false
+ properties.each { |property|
+ s = property.should
+ if s and ! property.class.unmanaged
+ @managed = true
+ break
+ end
+ }
+ return @managed
+ end
+ end
+
+ ###############################
+ # Code related to the container behaviour.
+
+ # this is a retarded hack method to get around the difference between
+ # component children and file children
+ def self.depthfirst?
+ @depthfirst
+ end
+
+ def depthfirst?
+ self.class.depthfirst?
+ end
+
+ # Remove an object. The argument determines whether the object's
+ # subscriptions get eliminated, too.
+ def remove(rmdeps = true)
+ # This is hackish (mmm, cut and paste), but it works for now, and it's
+ # better than warnings.
+ @parameters.each do |name, obj|
+ obj.remove
+ end
+ @parameters.clear
+
+ @parent = nil
+
+ # Remove the reference to the provider.
+ if self.provider
+ @provider.clear
+ @provider = nil
+ end
+ end
+
+ ###############################
+ # Code related to evaluating the resources.
+
+ # Flush the provider, if it supports it. This is called by the
+ # transaction.
+ def flush
+ self.provider.flush if self.provider and self.provider.respond_to?(:flush)
+ end
+
+ # if all contained objects are in sync, then we're in sync
+ # FIXME I don't think this is used on the type instances any more,
+ # it's really only used for testing
+ def insync?(is)
+ insync = true
+
+ if property = @parameters[:ensure]
+ unless is.include? property
+ raise Puppet::DevError,
+ "The is value is not in the is array for '#{property.name}'"
+ end
+ ensureis = is[property]
+ if property.insync?(ensureis) and property.should == :absent
+ return true
+ end
+ end
+
+ properties.each { |property|
+ unless is.include? property
+ raise Puppet::DevError,
+ "The is value is not in the is array for '#{property.name}'"
+ end
+
+ propis = is[property]
+ unless property.insync?(propis)
+ property.debug("Not in sync: #{propis.inspect} vs #{property.should.inspect}")
+ insync = false
+ #else
+ # property.debug("In sync")
+ end
+ }
+
+ #self.debug("#{self} sync status is #{insync}")
+ insync
+ end
+
+ # retrieve the current value of all contained properties
+ def retrieve
+ fail "Provider #{provider.class.name} is not functional on this host" if self.provider.is_a?(Puppet::Provider) and ! provider.class.suitable?
+
+ result = Puppet::Resource.new(type, title)
+
+ # Provide the name, so we know we'll always refer to a real thing
+ result[:name] = self[:name] unless self[:name] == title
+
+ if ensure_prop = property(:ensure) or (self.class.validattr?(:ensure) and ensure_prop = newattr(:ensure))
+ result[:ensure] = ensure_state = ensure_prop.retrieve
+ else
+ ensure_state = nil
+ end
+
+ properties.each do |property|
+ next if property.name == :ensure
+ if ensure_state == :absent
+ result[property] = :absent
+ else
+ result[property] = property.retrieve
+ end
+ end
+
+ result
+ end
+
+ def retrieve_resource
+ resource = retrieve
+ resource = Resource.new(type, title, :parameters => resource) if resource.is_a? Hash
+ resource
+ end
+
+ # Get a hash of the current properties. Returns a hash with
+ # the actual property instance as the key and the current value
+ # as the, um, value.
+ def currentpropvalues
+ # It's important to use the 'properties' method here, as it follows the order
+ # in which they're defined in the class. It also guarantees that 'ensure'
+ # is the first property, which is important for skipping 'retrieve' on
+ # all the properties if the resource is absent.
+ ensure_state = false
+ return properties.inject({}) do | prophash, property|
+ if property.name == :ensure
+ ensure_state = property.retrieve
+ prophash[property] = ensure_state
+ else
+ if ensure_state == :absent
+ prophash[property] = :absent
else
- raise Puppet::DevError,"you must specify title patterns when there are two or more key attributes"
- end
- end
-
- def uniqueness_key
- to_resource.uniqueness_key
- end
-
- # Create a new parameter. Requires a block and a name, stores it in the
- # @parameters array, and does some basic checking on it.
- def self.newparam(name, options = {}, &block)
- options[:attributes] ||= {}
-
- param = genclass(
- name,
- :parent => options[:parent] || Puppet::Parameter,
- :attributes => options[:attributes],
- :block => block,
- :prefix => "Parameter",
- :array => @parameters,
-
- :hash => @paramhash
+ prophash[property] = property.retrieve
+ end
+ end
+ prophash
+ end
+ end
+
+ # Are we running in noop mode?
+ def noop?
+ if defined?(@noop)
+ @noop
+ else
+ Puppet[:noop]
+ end
+ end
+
+ def noop
+ noop?
+ end
+
+ ###############################
+ # Code related to managing resource instances.
+ require 'puppet/transportable'
+
+ # retrieve a named instance of the current type
+ def self.[](name)
+ raise "Global resource access is deprecated"
+ @objects[name] || @aliases[name]
+ end
+
+ # add an instance by name to the class list of instances
+ def self.[]=(name,object)
+ raise "Global resource storage is deprecated"
+ newobj = nil
+ if object.is_a?(Puppet::Type)
+ newobj = object
+ else
+ raise Puppet::DevError, "must pass a Puppet::Type object"
+ end
+
+ if exobj = @objects[name] and self.isomorphic?
+ msg = "Object '#{newobj.class.name}[#{name}]' already exists"
+
+ msg += ("in file #{object.file} at line #{object.line}") if exobj.file and exobj.line
+ msg += ("and cannot be redefined in file #{object.file} at line #{object.line}") if object.file and object.line
+ error = Puppet::Error.new(msg)
+ raise error
+ else
+ #Puppet.info("adding %s of type %s to class list" %
+ # [name,object.class])
+ @objects[name] = newobj
+ end
+ end
+
+ # Create an alias. We keep these in a separate hash so that we don't encounter
+ # the objects multiple times when iterating over them.
+ def self.alias(name, obj)
+ raise "Global resource aliasing is deprecated"
+ if @objects.include?(name)
+ unless @objects[name] == obj
+ raise Puppet::Error.new(
+ "Cannot create alias #{name}: object already exists"
)
-
- handle_param_options(name, options)
-
- # Grr.
- param.required_features = options[:required_features] if options[:required_features]
-
- param.isnamevar if options[:namevar]
-
- param
- end
-
- def self.newstate(name, options = {}, &block)
- Puppet.warning "newstate() has been deprecrated; use newproperty(#{name})"
- newproperty(name, options, &block)
+ end
end
- # Create a new property. The first parameter must be the name of the property;
- # this is how users will refer to the property when creating new instances.
- # The second parameter is a hash of options; the options are:
- # * <tt>:parent</tt>: The parent class for the property. Defaults to Puppet::Property.
- # * <tt>:retrieve</tt>: The method to call on the provider or @parent object (if
- # the provider is not set) to retrieve the current value.
- def self.newproperty(name, options = {}, &block)
- name = symbolize(name)
-
- # This is here for types that might still have the old method of defining
- # a parent class.
- unless options.is_a? Hash
- raise Puppet::DevError,
- "Options must be a hash, not #{options.inspect}"
- end
-
- raise Puppet::DevError, "Class #{self.name} already has a property named #{name}" if @validproperties.include?(name)
-
- if parent = options[:parent]
- options.delete(:parent)
- else
- parent = Puppet::Property
- end
-
- # We have to create our own, new block here because we want to define
- # an initial :retrieve method, if told to, and then eval the passed
- # block if available.
- prop = genclass(name, :parent => parent, :hash => @validproperties, :attributes => options) do
- # If they've passed a retrieve method, then override the retrieve
- # method on the class.
- if options[:retrieve]
- define_method(:retrieve) do
- provider.send(options[:retrieve])
- end
- end
-
- class_eval(&block) if block
- end
-
- # If it's the 'ensure' property, always put it first.
- if name == :ensure
- @properties.unshift prop
- else
- @properties << prop
- end
-
- prop
- end
-
- def self.paramdoc(param)
- @paramhash[param].doc
- end
-
- # Return the parameter names
- def self.parameters
- return [] unless defined?(@parameters)
- @parameters.collect { |klass| klass.name }
- end
-
- # Find the parameter class associated with a given parameter name.
- def self.paramclass(name)
- @paramhash[name]
- end
-
- # Return the property class associated with a name
- def self.propertybyname(name)
- @validproperties[name]
- end
-
- def self.validattr?(name)
- name = symbolize(name)
- return true if name == :name
- @validattrs ||= {}
-
- unless @validattrs.include?(name)
- @validattrs[name] = !!(self.validproperty?(name) or self.validparameter?(name) or self.metaparam?(name))
- end
-
- @validattrs[name]
- end
-
- # does the name reflect a valid property?
- def self.validproperty?(name)
- name = symbolize(name)
- @validproperties.include?(name) && @validproperties[name]
- end
+ if @aliases.include?(name)
+ unless @aliases[name] == obj
+ raise Puppet::Error.new(
+ "Object #{@aliases[name].name} already has alias #{name}"
+ )
+ end
+ end
+
+ @aliases[name] = obj
+ end
+
+ # remove all of the instances of a single type
+ def self.clear
+ raise "Global resource removal is deprecated"
+ if defined?(@objects)
+ @objects.each do |name, obj|
+ obj.remove(true)
+ end
+ @objects.clear
+ end
+ @aliases.clear if defined?(@aliases)
+ end
+
+ # Force users to call this, so that we can merge objects if
+ # necessary.
+ def self.create(args)
+ # LAK:DEP Deprecation notice added 12/17/2008
+ Puppet.warning "Puppet::Type.create is deprecated; use Puppet::Type.new"
+ new(args)
+ end
+
+ # remove a specified object
+ def self.delete(resource)
+ raise "Global resource removal is deprecated"
+ return unless defined?(@objects)
+ @objects.delete(resource.title) if @objects.include?(resource.title)
+ @aliases.delete(resource.title) if @aliases.include?(resource.title)
+ if @aliases.has_value?(resource)
+ names = []
+ @aliases.each do |name, otherres|
+ if otherres == resource
+ names << name
+ end
+ end
+ names.each { |name| @aliases.delete(name) }
+ end
+ end
+
+ # iterate across each of the type's instances
+ def self.each
+ raise "Global resource iteration is deprecated"
+ return unless defined?(@objects)
+ @objects.each { |name,instance|
+ yield instance
+ }
+ end
+
+ # does the type have an object with the given name?
+ def self.has_key?(name)
+ raise "Global resource access is deprecated"
+ @objects.has_key?(name)
+ end
+
+ # Retrieve all known instances. Either requires providers or must be overridden.
+ def self.instances
+ raise Puppet::DevError, "#{self.name} has no providers and has not overridden 'instances'" if provider_hash.empty?
+
+ # Put the default provider first, then the rest of the suitable providers.
+ provider_instances = {}
+ providers_by_source.collect do |provider|
+ provider.instances.collect do |instance|
+ # We always want to use the "first" provider instance we find, unless the resource
+ # is already managed and has a different provider set
+ if other = provider_instances[instance.name]
+ Puppet.warning "%s %s found in both %s and %s; skipping the %s version" %
+ [self.name.to_s.capitalize, instance.name, other.class.name, instance.class.name, instance.class.name]
+ next
+ end
+ provider_instances[instance.name] = instance
+
+ new(:name => instance.name, :provider => instance, :audit => :all)
+ end
+ end.flatten.compact
+ end
+
+ # Return a list of one suitable provider per source, with the default provider first.
+ def self.providers_by_source
+ # Put the default provider first, then the rest of the suitable providers.
+ sources = []
+ [defaultprovider, suitableprovider].flatten.uniq.collect do |provider|
+ next if sources.include?(provider.source)
+
+ sources << provider.source
+ provider
+ end.compact
+ end
+
+ # Convert a simple hash into a Resource instance.
+ def self.hash2resource(hash)
+ hash = hash.inject({}) { |result, ary| result[ary[0].to_sym] = ary[1]; result }
+
+ title = hash.delete(:title)
+ title ||= hash[:name]
+ title ||= hash[key_attributes.first] if key_attributes.length == 1
+
+ raise Puppet::Error, "Title or name must be provided" unless title
+
+ # Now create our resource.
+ resource = Puppet::Resource.new(self.name, title)
+ [:catalog].each do |attribute|
+ if value = hash[attribute]
+ hash.delete(attribute)
+ resource.send(attribute.to_s + "=", value)
+ end
+ end
+
+ hash.each do |param, value|
+ resource[param] = value
+ end
+ resource
+ end
+
+ # Create the path for logging and such.
+ def pathbuilder
+ if p = parent
+ [p.pathbuilder, self.ref].flatten
+ else
+ [self.ref]
+ end
+ end
+
+ ###############################
+ # Add all of the meta parameters.
+ newmetaparam(:noop) do
+ desc "Boolean flag indicating whether work should actually
+ be done."
+
+ newvalues(:true, :false)
+ munge do |value|
+ case value
+ when true, :true, "true"; @resource.noop = true
+ when false, :false, "false"; @resource.noop = false
+ end
+ end
+ end
+
+ newmetaparam(:schedule) do
+ desc "On what schedule the object should be managed. You must create a
+ schedule object, and then reference the name of that object to use
+ that for your schedule::
+
+ schedule { daily:
+ period => daily,
+ range => \"2-4\"
+ }
- # Return the list of validproperties
- def self.validproperties
- return {} unless defined?(@parameters)
+ exec { \"/usr/bin/apt-get update\":
+ schedule => daily
+ }
- @validproperties.keys
- end
+ The creation of the schedule object does not need to appear in the
+ configuration before objects that use it."
+ end
- # does the name reflect a valid parameter?
- def self.validparameter?(name)
- raise Puppet::DevError, "Class #{self} has not defined parameters" unless defined?(@parameters)
- !!(@paramhash.include?(name) or @@metaparamhash.include?(name))
- end
+ newmetaparam(:audit) do
+ desc "Audit specified attributes of resources over time, and report if any have changed.
+ This attribute can be used to track changes to any resource over time, and can
+ provide an audit trail of every change that happens on any given machine.
- # This is a forward-compatibility method - it's the validity interface we'll use in Puppet::Resource.
- def self.valid_parameter?(name)
- validattr?(name)
- end
+ Note that you cannot both audit and manage an attribute - managing it guarantees
+ the value, and any changes already get logged."
- # Return either the attribute alias or the attribute.
- def attr_alias(name)
- name = symbolize(name)
- if synonym = self.class.attr_alias(name)
- return synonym
- else
- return name
+ validate do |list|
+ list = Array(list)
+ unless list == [:all]
+ list.each do |param|
+ next if @resource.class.validattr?(param)
+ fail "Cannot audit #{param}: not a valid attribute for #{resource}"
end
+ end
end
- # Are we deleting this resource?
- def deleting?
- obj = @parameters[:ensure] and obj.should == :absent
+ munge do |args|
+ properties_to_audit(args).each do |param|
+ next unless resource.class.validproperty?(param)
+ resource.newattr(param)
+ end
end
- # Create a new property if it is valid but doesn't exist
- # Returns: true if a new parameter was added, false otherwise
- def add_property_parameter(prop_name)
- if self.class.validproperty?(prop_name) && !@parameters[prop_name]
- self.newattr(prop_name)
- return true
- end
- false
+ def all_properties
+ resource.class.properties.find_all do |property|
+ resource.provider.nil? or resource.provider.class.supports_parameter?(property)
+ end.collect do |property|
+ property.name
+ end
end
- #
- # The name_var is the key_attribute in the case that there is only one.
- #
- def name_var
- key_attributes = self.class.key_attributes
- (key_attributes.length == 1) && key_attributes.first
+ def properties_to_audit(list)
+ if list == :all
+ list = all_properties if list == :all
+ else
+ list = Array(list).collect { |p| p.to_sym }
+ end
end
+ end
- # abstract accessing parameters and properties, and normalize
- # access to always be symbols, not strings
- # This returns a value, not an object. It returns the 'is'
- # value, but you can also specifically return 'is' and 'should'
- # values using 'object.is(:property)' or 'object.should(:property)'.
- def [](name)
- name = attr_alias(name)
-
- fail("Invalid parameter #{name}(#{name.inspect})") unless self.class.validattr?(name)
+ newmetaparam(:check) do
+ desc "Audit specified attributes of resources over time, and report if any have changed.
+ This parameter has been deprecated in favor of 'audit'."
- if name == :name
- name = name_var
- end
-
- if obj = @parameters[name]
- # Note that if this is a property, then the value is the "should" value,
- # not the current value.
- obj.value
- else
- return nil
- end
+ munge do |args|
+ resource.warning "'check' attribute is deprecated; use 'audit' instead"
+ resource[:audit] = args
end
+ end
- # Abstract setting parameters and properties, and normalize
- # access to always be symbols, not strings. This sets the 'should'
- # value on properties, and otherwise just sets the appropriate parameter.
- def []=(name,value)
- name = attr_alias(name)
-
- fail("Invalid parameter #{name}") unless self.class.validattr?(name)
-
- if name == :name
- name = name_var
- end
- raise Puppet::Error.new("Got nil value for #{name}") if value.nil?
-
- property = self.newattr(name)
+ newmetaparam(:loglevel) do
+ desc "Sets the level that information will be logged.
+ The log levels have the biggest impact when logs are sent to
+ syslog (which is currently the default)."
+ defaultto :notice
- begin
- # make sure the parameter doesn't have any errors
- property.value = value
- rescue => detail
- error = Puppet::Error.new("Parameter #{name} failed: #{detail}")
- error.set_backtrace(detail.backtrace)
- raise error
- end
+ newvalues(*Puppet::Util::Log.levels)
+ newvalues(:verbose)
- nil
+ munge do |loglevel|
+ val = super(loglevel)
+ if val == :verbose
+ val = :info
+ end
+ val
end
+ end
- # remove a property from the object; useful in testing or in cleanup
- # when an error has been encountered
- def delete(attr)
- attr = symbolize(attr)
- if @parameters.has_key?(attr)
- @parameters.delete(attr)
- else
- raise Puppet::DevError.new("Undefined attribute '#{attr}' in #{self}")
- end
- end
+ newmetaparam(:alias) do
+ desc "Creates an alias for the object. Puppet uses this internally when you
+ provide a symbolic name::
- # iterate across the existing properties
- def eachproperty
- # properties is a private method
- properties.each { |property|
- yield property
+ file { sshdconfig:
+ path => $operatingsystem ? {
+ solaris => \"/usr/local/etc/ssh/sshd_config\",
+ default => \"/etc/ssh/sshd_config\"
+ },
+ source => \"...\"
}
- end
- # Create a transaction event. Called by Transaction or by
- # a property.
- def event(options = {})
- Puppet::Transaction::Event.new({:resource => self, :file => file, :line => line, :tags => tags, :version => version}.merge(options))
- end
-
- # Let the catalog determine whether a given cached value is
- # still valid or has expired.
- def expirer
- catalog
- end
-
- # retrieve the 'should' value for a specified property
- def should(name)
- name = attr_alias(name)
- (prop = @parameters[name] and prop.is_a?(Puppet::Property)) ? prop.should : nil
- end
-
- # Create the actual attribute instance. Requires either the attribute
- # name or class as the first argument, then an optional hash of
- # attributes to set during initialization.
- def newattr(name)
- if name.is_a?(Class)
- klass = name
- name = klass.name
- end
-
- unless klass = self.class.attrclass(name)
- raise Puppet::Error, "Resource type #{self.class.name} does not support parameter #{name}"
- end
+ service { sshd:
+ subscribe => file[sshdconfig]
+ }
- return @parameters[name] if @parameters.include?(name)
+ When you use this feature, the parser sets ``sshdconfig`` as the name,
+ and the library sets that as an alias for the file so the dependency
+ lookup for ``sshd`` works. You can use this parameter yourself,
+ but note that only the library can use these aliases; for instance,
+ the following code will not work::
- @parameters[name] = klass.new(:resource => self)
- end
+ file { \"/etc/ssh/sshd_config\":
+ owner => root,
+ group => root,
+ alias => sshdconfig
+ }
- # return the value of a parameter
- def parameter(name)
- @parameters[name.to_sym]
- end
+ file { sshdconfig:
+ mode => 644
+ }
- def parameters
- @parameters.dup
- end
+ There's no way here for the Puppet parser to know that these two stanzas
+ should be affecting the same file.
- # Is the named property defined?
- def propertydefined?(name)
- name = name.intern unless name.is_a? Symbol
- @parameters.include?(name)
- end
+ See the `LanguageTutorial language tutorial`:trac: for more information.
- # Return an actual property instance by name; to return the value, use 'resource[param]'
- # LAK:NOTE(20081028) Since the 'parameter' method is now a superset of this method,
- # this one should probably go away at some point.
- def property(name)
- (obj = @parameters[symbolize(name)] and obj.is_a?(Puppet::Property)) ? obj : nil
- end
+ "
- # For any parameters or properties that have defaults and have not yet been
- # set, set them now. This method can be handed a list of attributes,
- # and if so it will only set defaults for those attributes.
- def set_default(attr)
- return unless klass = self.class.attrclass(attr)
- return unless klass.method_defined?(:default)
- return if @parameters.include?(klass.name)
+ munge do |aliases|
+ aliases = [aliases] unless aliases.is_a?(Array)
- return unless parameter = newattr(klass.name)
+ raise(ArgumentError, "Cannot add aliases without a catalog") unless @resource.catalog
- if value = parameter.default and ! value.nil?
- parameter.value = value
- else
- @parameters.delete(parameter.name)
+ aliases.each do |other|
+ if obj = @resource.catalog.resource(@resource.class.name, other)
+ unless obj.object_id == @resource.object_id
+ self.fail("#{@resource.title} can not create alias #{other}: object already exists")
+ end
+ next
end
+
+ # Newschool, add it to the catalog.
+ @resource.catalog.alias(@resource, other)
+ end
end
+ end
- # Convert our object to a hash. This just includes properties.
- def to_hash
- rethash = {}
+ newmetaparam(:tag) do
+ desc "Add the specified tags to the associated resource. While all resources
+ are automatically tagged with as much information as possible
+ (e.g., each class and definition containing the resource), it can
+ be useful to add your own tags to a given resource.
- @parameters.each do |name, obj|
- rethash[name] = obj.value
- end
-
- rethash
- end
+ Tags are currently useful for things like applying a subset of a
+ host's configuration::
- def type
- self.class.name
- end
+ puppet agent --test --tags mytag
- # Return a specific value for an attribute.
- def value(name)
- name = attr_alias(name)
+ This way, when you're testing a configuration you can run just the
+ portion you're testing."
- (obj = @parameters[name] and obj.respond_to?(:value)) ? obj.value : nil
- end
+ munge do |tags|
+ tags = [tags] unless tags.is_a? Array
- def version
- return 0 unless catalog
- catalog.version
+ tags.each do |tag|
+ @resource.tag(tag)
+ end
end
+ end
- # Return all of the property objects, in the order specified in the
- # class.
- def properties
- self.class.properties.collect { |prop| @parameters[prop.name] }.compact
+ class RelationshipMetaparam < Puppet::Parameter
+ class << self
+ attr_accessor :direction, :events, :callback, :subclasses
end
- # Is this type's name isomorphic with the object? That is, if the
- # name conflicts, does it necessarily mean that the objects conflict?
- # Defaults to true.
- def self.isomorphic?
- if defined?(@isomorphic)
- return @isomorphic
- else
- return true
- end
- end
+ @subclasses = []
- def isomorphic?
- self.class.isomorphic?
+ def self.inherited(sub)
+ @subclasses << sub
end
- # is the instance a managed instance? A 'yes' here means that
- # the instance was created from the language, vs. being created
- # in order resolve other questions, such as finding a package
- # in a list
- def managed?
- # Once an object is managed, it always stays managed; but an object
- # that is listed as unmanaged might become managed later in the process,
- # so we have to check that every time
- if @managed
- return @managed
+ def munge(references)
+ references = [references] unless references.is_a?(Array)
+ references.collect do |ref|
+ if ref.is_a?(Puppet::Resource)
+ ref
else
- @managed = false
- properties.each { |property|
- s = property.should
- if s and ! property.class.unmanaged
- @managed = true
- break
- end
- }
- return @managed
+ Puppet::Resource.new(ref)
end
+ end
end
- ###############################
- # Code related to the container behaviour.
-
- # this is a retarded hack method to get around the difference between
- # component children and file children
- def self.depthfirst?
- @depthfirst
- end
-
- def depthfirst?
- self.class.depthfirst?
- end
-
- # Remove an object. The argument determines whether the object's
- # subscriptions get eliminated, too.
- def remove(rmdeps = true)
- # This is hackish (mmm, cut and paste), but it works for now, and it's
- # better than warnings.
- @parameters.each do |name, obj|
- obj.remove
- end
- @parameters.clear
-
- @parent = nil
-
- # Remove the reference to the provider.
- if self.provider
- @provider.clear
- @provider = nil
+ def validate_relationship
+ @value.each do |ref|
+ unless @resource.catalog.resource(ref.to_s)
+ description = self.class.direction == :in ? "dependency" : "dependent"
+ fail "Could not find #{description} #{ref} for #{resource.ref}"
end
+ end
end
- ###############################
- # Code related to evaluating the resources.
-
- # Flush the provider, if it supports it. This is called by the
- # transaction.
- def flush
- self.provider.flush if self.provider and self.provider.respond_to?(:flush)
- end
+ # Create edges from each of our relationships. :in
+ # relationships are specified by the event-receivers, and :out
+ # relationships are specified by the event generator. This
+ # way 'source' and 'target' are consistent terms in both edges
+ # and events -- that is, an event targets edges whose source matches
+ # the event's source. The direction of the relationship determines
+ # which resource is applied first and which resource is considered
+ # to be the event generator.
+ def to_edges
+ @value.collect do |reference|
+ reference.catalog = resource.catalog
- # if all contained objects are in sync, then we're in sync
- # FIXME I don't think this is used on the type instances any more,
- # it's really only used for testing
- def insync?(is)
- insync = true
-
- if property = @parameters[:ensure]
- unless is.include? property
- raise Puppet::DevError,
- "The is value is not in the is array for '#{property.name}'"
- end
- ensureis = is[property]
- if property.insync?(ensureis) and property.should == :absent
- return true
- end
+ # Either of the two retrieval attempts could have returned
+ # nil.
+ unless related_resource = reference.resolve
+ self.fail "Could not retrieve dependency '#{reference}' of #{@resource.ref}"
end
- properties.each { |property|
- unless is.include? property
- raise Puppet::DevError,
- "The is value is not in the is array for '#{property.name}'"
- end
-
- propis = is[property]
- unless property.insync?(propis)
- property.debug("Not in sync: #{propis.inspect} vs #{property.should.inspect}")
- insync = false
- #else
- # property.debug("In sync")
- end
- }
-
- #self.debug("#{self} sync status is #{insync}")
- insync
- end
-
- # retrieve the current value of all contained properties
- def retrieve
- fail "Provider #{provider.class.name} is not functional on this host" if self.provider.is_a?(Puppet::Provider) and ! provider.class.suitable?
-
- result = Puppet::Resource.new(type, title)
-
- # Provide the name, so we know we'll always refer to a real thing
- result[:name] = self[:name] unless self[:name] == title
-
- if ensure_prop = property(:ensure) or (self.class.validattr?(:ensure) and ensure_prop = newattr(:ensure))
- result[:ensure] = ensure_state = ensure_prop.retrieve
+ # Are we requiring them, or vice versa? See the method docs
+ # for futher info on this.
+ if self.class.direction == :in
+ source = related_resource
+ target = @resource
else
- ensure_state = nil
+ source = @resource
+ target = related_resource
end
- properties.each do |property|
- next if property.name == :ensure
- if ensure_state == :absent
- result[property] = :absent
- else
- result[property] = property.retrieve
- end
- end
-
- result
- end
-
- def retrieve_resource
- resource = retrieve
- resource = Resource.new(type, title, :parameters => resource) if resource.is_a? Hash
- resource
- end
-
- # Get a hash of the current properties. Returns a hash with
- # the actual property instance as the key and the current value
- # as the, um, value.
- def currentpropvalues
- # It's important to use the 'properties' method here, as it follows the order
- # in which they're defined in the class. It also guarantees that 'ensure'
- # is the first property, which is important for skipping 'retrieve' on
- # all the properties if the resource is absent.
- ensure_state = false
- return properties.inject({}) do | prophash, property|
- if property.name == :ensure
- ensure_state = property.retrieve
- prophash[property] = ensure_state
- else
- if ensure_state == :absent
- prophash[property] = :absent
- else
- prophash[property] = property.retrieve
- end
- end
- prophash
- end
- end
-
- # Are we running in noop mode?
- def noop?
- if defined?(@noop)
- @noop
+ if method = self.class.callback
+ subargs = {
+ :event => self.class.events,
+ :callback => method
+ }
+ self.debug("subscribes to #{related_resource.ref}")
else
- Puppet[:noop]
+ # If there's no callback, there's no point in even adding
+ # a label.
+ subargs = nil
+ self.debug("requires #{related_resource.ref}")
end
- end
- def noop
- noop?
+ rel = Puppet::Relationship.new(source, target, subargs)
+ end
end
+ end
- ###############################
- # Code related to managing resource instances.
- require 'puppet/transportable'
+ def self.relationship_params
+ RelationshipMetaparam.subclasses
+ end
- # retrieve a named instance of the current type
- def self.[](name)
- raise "Global resource access is deprecated"
- @objects[name] || @aliases[name]
- end
- # add an instance by name to the class list of instances
- def self.[]=(name,object)
- raise "Global resource storage is deprecated"
- newobj = nil
- if object.is_a?(Puppet::Type)
- newobj = object
- else
- raise Puppet::DevError, "must pass a Puppet::Type object"
- end
-
- if exobj = @objects[name] and self.isomorphic?
- msg = "Object '#{newobj.class.name}[#{name}]' already exists"
-
- msg += ("in file #{object.file} at line #{object.line}") if exobj.file and exobj.line
- msg += ("and cannot be redefined in file #{object.file} at line #{object.line}") if object.file and object.line
- error = Puppet::Error.new(msg)
- raise error
- else
- #Puppet.info("adding %s of type %s to class list" %
- # [name,object.class])
- @objects[name] = newobj
- end
- end
+ # Note that the order in which the relationships params is defined
+ # matters. The labelled params (notify and subcribe) must be later,
+ # so that if both params are used, those ones win. It's a hackish
+ # solution, but it works.
- # Create an alias. We keep these in a separate hash so that we don't encounter
- # the objects multiple times when iterating over them.
- def self.alias(name, obj)
- raise "Global resource aliasing is deprecated"
- if @objects.include?(name)
- unless @objects[name] == obj
- raise Puppet::Error.new(
- "Cannot create alias #{name}: object already exists"
- )
- end
- end
+ newmetaparam(:require, :parent => RelationshipMetaparam, :attributes => {:direction => :in, :events => :NONE}) do
+ desc "One or more objects that this object depends on.
+ This is used purely for guaranteeing that changes to required objects
+ happen before the dependent object. For instance::
- if @aliases.include?(name)
- unless @aliases[name] == obj
- raise Puppet::Error.new(
- "Object #{@aliases[name].name} already has alias #{name}"
- )
- end
- end
-
- @aliases[name] = obj
- end
+ # Create the destination directory before you copy things down
+ file { \"/usr/local/scripts\":
+ ensure => directory
+ }
- # remove all of the instances of a single type
- def self.clear
- raise "Global resource removal is deprecated"
- if defined?(@objects)
- @objects.each do |name, obj|
- obj.remove(true)
- end
- @objects.clear
- end
- @aliases.clear if defined?(@aliases)
- end
-
- # Force users to call this, so that we can merge objects if
- # necessary.
- def self.create(args)
- # LAK:DEP Deprecation notice added 12/17/2008
- Puppet.warning "Puppet::Type.create is deprecated; use Puppet::Type.new"
- new(args)
- end
-
- # remove a specified object
- def self.delete(resource)
- raise "Global resource removal is deprecated"
- return unless defined?(@objects)
- @objects.delete(resource.title) if @objects.include?(resource.title)
- @aliases.delete(resource.title) if @aliases.include?(resource.title)
- if @aliases.has_value?(resource)
- names = []
- @aliases.each do |name, otherres|
- if otherres == resource
- names << name
- end
- end
- names.each { |name| @aliases.delete(name) }
- end
- end
+ file { \"/usr/local/scripts/myscript\":
+ source => \"puppet://server/module/myscript\",
+ mode => 755,
+ require => File[\"/usr/local/scripts\"]
+ }
- # iterate across each of the type's instances
- def self.each
- raise "Global resource iteration is deprecated"
- return unless defined?(@objects)
- @objects.each { |name,instance|
- yield instance
+ Multiple dependencies can be specified by providing a comma-seperated list
+ of resources, enclosed in square brackets::
+
+ require => [ File[\"/usr/local\"], File[\"/usr/local/scripts\"] ]
+
+ Note that Puppet will autorequire everything that it can, and
+ there are hooks in place so that it's easy for resources to add new
+ ways to autorequire objects, so if you think Puppet could be
+ smarter here, let us know.
+
+ In fact, the above code was redundant -- Puppet will autorequire
+ any parent directories that are being managed; it will
+ automatically realize that the parent directory should be created
+ before the script is pulled down.
+
+ Currently, exec resources will autorequire their CWD (if it is
+ specified) plus any fully qualified paths that appear in the
+ command. For instance, if you had an ``exec`` command that ran
+ the ``myscript`` mentioned above, the above code that pulls the
+ file down would be automatically listed as a requirement to the
+ ``exec`` code, so that you would always be running againts the
+ most recent version.
+ "
+ end
+
+ newmetaparam(:subscribe, :parent => RelationshipMetaparam, :attributes => {:direction => :in, :events => :ALL_EVENTS, :callback => :refresh}) do
+ desc "One or more objects that this object depends on. Changes in the
+ subscribed to objects result in the dependent objects being
+ refreshed (e.g., a service will get restarted). For instance::
+
+ class nagios {
+ file { \"/etc/nagios/nagios.conf\":
+ source => \"puppet://server/module/nagios.conf\",
+ alias => nagconf # just to make things easier for me
+ }
+ service { nagios:
+ ensure => running,
+ subscribe => File[nagconf]
+ }
}
- end
- # does the type have an object with the given name?
- def self.has_key?(name)
- raise "Global resource access is deprecated"
- @objects.has_key?(name)
- end
+ Currently the ``exec``, ``mount`` and ``service`` type support
+ refreshing.
+ "
+ end
- # Retrieve all known instances. Either requires providers or must be overridden.
- def self.instances
- raise Puppet::DevError, "#{self.name} has no providers and has not overridden 'instances'" if provider_hash.empty?
+ newmetaparam(:before, :parent => RelationshipMetaparam, :attributes => {:direction => :out, :events => :NONE}) do
+ desc %{This parameter is the opposite of **require** -- it guarantees
+ that the specified object is applied later than the specifying
+ object::
- # Put the default provider first, then the rest of the suitable providers.
- provider_instances = {}
- providers_by_source.collect do |provider|
- provider.instances.collect do |instance|
- # We always want to use the "first" provider instance we find, unless the resource
- # is already managed and has a different provider set
- if other = provider_instances[instance.name]
- Puppet.warning "%s %s found in both %s and %s; skipping the %s version" %
- [self.name.to_s.capitalize, instance.name, other.class.name, instance.class.name, instance.class.name]
- next
- end
- provider_instances[instance.name] = instance
+ file { "/var/nagios/configuration":
+ source => "...",
+ recurse => true,
+ before => Exec["nagios-rebuid"]
+ }
- new(:name => instance.name, :provider => instance, :audit => :all)
- end
- end.flatten.compact
- end
+ exec { "nagios-rebuild":
+ command => "/usr/bin/make",
+ cwd => "/var/nagios/configuration"
+ }
- # Return a list of one suitable provider per source, with the default provider first.
- def self.providers_by_source
- # Put the default provider first, then the rest of the suitable providers.
- sources = []
- [defaultprovider, suitableprovider].flatten.uniq.collect do |provider|
- next if sources.include?(provider.source)
+ This will make sure all of the files are up to date before the
+ make command is run.}
+ end
- sources << provider.source
- provider
- end.compact
- end
+ newmetaparam(:notify, :parent => RelationshipMetaparam, :attributes => {:direction => :out, :events => :ALL_EVENTS, :callback => :refresh}) do
+ desc %{This parameter is the opposite of **subscribe** -- it sends events
+ to the specified object::
- # Convert a simple hash into a Resource instance.
- def self.hash2resource(hash)
- hash = hash.inject({}) { |result, ary| result[ary[0].to_sym] = ary[1]; result }
+ file { "/etc/sshd_config":
+ source => "....",
+ notify => Service[sshd]
+ }
- title = hash.delete(:title)
- title ||= hash[:name]
- title ||= hash[key_attributes.first] if key_attributes.length == 1
+ service { sshd:
+ ensure => running
+ }
- raise Puppet::Error, "Title or name must be provided" unless title
+ This will restart the sshd service if the sshd config file changes.}
+ end
- # Now create our resource.
- resource = Puppet::Resource.new(self.name, title)
- [:catalog].each do |attribute|
- if value = hash[attribute]
- hash.delete(attribute)
- resource.send(attribute.to_s + "=", value)
- end
- end
+ newmetaparam(:stage) do
+ desc %{Which run stage a given resource should reside in. This just creates
+ a dependency on or from the named milestone. For instance, saying that
+ this is in the 'bootstrap' stage creates a dependency on the 'bootstrap'
+ milestone.
- hash.each do |param, value|
- resource[param] = value
- end
- resource
- end
+ By default, all classes get directly added to the
+ 'main' stage. You can create new stages as resources:
- # Create the path for logging and such.
- def pathbuilder
- if p = parent
- [p.pathbuilder, self.ref].flatten
- else
- [self.ref]
- end
- end
+ stage { [pre, post]: }
- ###############################
- # Add all of the meta parameters.
- newmetaparam(:noop) do
- desc "Boolean flag indicating whether work should actually
- be done."
+ To order stages, use standard relationships:
- newvalues(:true, :false)
- munge do |value|
- case value
- when true, :true, "true"; @resource.noop = true
- when false, :false, "false"; @resource.noop = false
- end
- end
- end
+ stage { pre: before => Stage[main] }
- newmetaparam(:schedule) do
- desc "On what schedule the object should be managed. You must create a
- schedule object, and then reference the name of that object to use
- that for your schedule::
+ Or use the new relationship syntax:
- schedule { daily:
- period => daily,
- range => \"2-4\"
- }
+ Stage[pre] -> Stage[main] -> Stage[post]
- exec { \"/usr/bin/apt-get update\":
- schedule => daily
- }
+ Then use the new class parameters to specify a stage:
- The creation of the schedule object does not need to appear in the
- configuration before objects that use it."
- end
+ class { foo: stage => pre }
- newmetaparam(:audit) do
- desc "Audit specified attributes of resources over time, and report if any have changed.
- This attribute can be used to track changes to any resource over time, and can
- provide an audit trail of every change that happens on any given machine.
+ Stages can only be set on classes, not individual resources. This will
+ fail::
- Note that you cannot both audit and manage an attribute - managing it guarantees
- the value, and any changes already get logged."
+ file { '/foo': stage => pre, ensure => file }
+ }
+ end
- validate do |list|
- list = Array(list)
- unless list == [:all]
- list.each do |param|
- next if @resource.class.validattr?(param)
- fail "Cannot audit #{param}: not a valid attribute for #{resource}"
- end
- end
- end
+ ###############################
+ # All of the provider plumbing for the resource types.
+ require 'puppet/provider'
+ require 'puppet/util/provider_features'
- munge do |args|
- properties_to_audit(args).each do |param|
- next unless resource.class.validproperty?(param)
- resource.newattr(param)
- end
- end
+ # Add the feature handling module.
+ extend Puppet::Util::ProviderFeatures
- def all_properties
- resource.class.properties.find_all do |property|
- resource.provider.nil? or resource.provider.class.supports_parameter?(property)
- end.collect do |property|
- property.name
- end
- end
+ attr_reader :provider
- def properties_to_audit(list)
- if list == :all
- list = all_properties if list == :all
- else
- list = Array(list).collect { |p| p.to_sym }
- end
- end
- end
+ # the Type class attribute accessors
+ class << self
+ attr_accessor :providerloader
+ attr_writer :defaultprovider
+ end
- newmetaparam(:check) do
- desc "Audit specified attributes of resources over time, and report if any have changed.
- This parameter has been deprecated in favor of 'audit'."
+ # Find the default provider.
+ def self.defaultprovider
+ unless @defaultprovider
+ suitable = suitableprovider
- munge do |args|
- resource.warning "'check' attribute is deprecated; use 'audit' instead"
- resource[:audit] = args
- end
- end
+ # Find which providers are a default for this system.
+ defaults = suitable.find_all { |provider| provider.default? }
- newmetaparam(:loglevel) do
- desc "Sets the level that information will be logged.
- The log levels have the biggest impact when logs are sent to
- syslog (which is currently the default)."
- defaultto :notice
+ # If we don't have any default we use suitable providers
+ defaults = suitable if defaults.empty?
+ max = defaults.collect { |provider| provider.specificity }.max
+ defaults = defaults.find_all { |provider| provider.specificity == max }
- newvalues(*Puppet::Util::Log.levels)
- newvalues(:verbose)
+ retval = nil
+ if defaults.length > 1
+ Puppet.warning(
+ "Found multiple default providers for #{self.name}: #{defaults.collect { |i| i.name.to_s }.join(", ")}; using #{defaults[0].name}"
+ )
+ retval = defaults.shift
+ elsif defaults.length == 1
+ retval = defaults.shift
+ else
+ raise Puppet::DevError, "Could not find a default provider for #{self.name}"
+ end
- munge do |loglevel|
- val = super(loglevel)
- if val == :verbose
- val = :info
- end
- val
- end
+ @defaultprovider = retval
end
- newmetaparam(:alias) do
- desc "Creates an alias for the object. Puppet uses this internally when you
- provide a symbolic name::
-
- file { sshdconfig:
- path => $operatingsystem ? {
- solaris => \"/usr/local/etc/ssh/sshd_config\",
- default => \"/etc/ssh/sshd_config\"
- },
- source => \"...\"
- }
-
- service { sshd:
- subscribe => file[sshdconfig]
- }
+ @defaultprovider
+ end
- When you use this feature, the parser sets ``sshdconfig`` as the name,
- and the library sets that as an alias for the file so the dependency
- lookup for ``sshd`` works. You can use this parameter yourself,
- but note that only the library can use these aliases; for instance,
- the following code will not work::
+ def self.provider_hash_by_type(type)
+ @provider_hashes ||= {}
+ @provider_hashes[type] ||= {}
+ end
- file { \"/etc/ssh/sshd_config\":
- owner => root,
- group => root,
- alias => sshdconfig
- }
+ def self.provider_hash
+ Puppet::Type.provider_hash_by_type(self.name)
+ end
- file { sshdconfig:
- mode => 644
- }
+ # Retrieve a provider by name.
+ def self.provider(name)
+ name = Puppet::Util.symbolize(name)
- There's no way here for the Puppet parser to know that these two stanzas
- should be affecting the same file.
+ # If we don't have it yet, try loading it.
+ @providerloader.load(name) unless provider_hash.has_key?(name)
+ provider_hash[name]
+ end
- See the `LanguageTutorial language tutorial`:trac: for more information.
+ # Just list all of the providers.
+ def self.providers
+ provider_hash.keys
+ end
- "
+ def self.validprovider?(name)
+ name = Puppet::Util.symbolize(name)
- munge do |aliases|
- aliases = [aliases] unless aliases.is_a?(Array)
+ (provider_hash.has_key?(name) && provider_hash[name].suitable?)
+ end
- raise(ArgumentError, "Cannot add aliases without a catalog") unless @resource.catalog
+ # Create a new provider of a type. This method must be called
+ # directly on the type that it's implementing.
+ def self.provide(name, options = {}, &block)
+ name = Puppet::Util.symbolize(name)
- aliases.each do |other|
- if obj = @resource.catalog.resource(@resource.class.name, other)
- unless obj.object_id == @resource.object_id
- self.fail("#{@resource.title} can not create alias #{other}: object already exists")
- end
- next
- end
-
- # Newschool, add it to the catalog.
- @resource.catalog.alias(@resource, other)
- end
- end
- end
-
- newmetaparam(:tag) do
- desc "Add the specified tags to the associated resource. While all resources
- are automatically tagged with as much information as possible
- (e.g., each class and definition containing the resource), it can
- be useful to add your own tags to a given resource.
-
- Tags are currently useful for things like applying a subset of a
- host's configuration::
-
- puppet agent --test --tags mytag
-
- This way, when you're testing a configuration you can run just the
- portion you're testing."
-
- munge do |tags|
- tags = [tags] unless tags.is_a? Array
-
- tags.each do |tag|
- @resource.tag(tag)
- end
- end
+ if obj = provider_hash[name]
+ Puppet.debug "Reloading #{name} #{self.name} provider"
+ unprovide(name)
end
- class RelationshipMetaparam < Puppet::Parameter
- class << self
- attr_accessor :direction, :events, :callback, :subclasses
- end
-
- @subclasses = []
-
- def self.inherited(sub)
- @subclasses << sub
- end
-
- def munge(references)
- references = [references] unless references.is_a?(Array)
- references.collect do |ref|
- if ref.is_a?(Puppet::Resource)
- ref
- else
- Puppet::Resource.new(ref)
- end
- end
- end
-
- def validate_relationship
- @value.each do |ref|
- unless @resource.catalog.resource(ref.to_s)
- description = self.class.direction == :in ? "dependency" : "dependent"
- fail "Could not find #{description} #{ref} for #{resource.ref}"
- end
- end
- end
-
- # Create edges from each of our relationships. :in
- # relationships are specified by the event-receivers, and :out
- # relationships are specified by the event generator. This
- # way 'source' and 'target' are consistent terms in both edges
- # and events -- that is, an event targets edges whose source matches
- # the event's source. The direction of the relationship determines
- # which resource is applied first and which resource is considered
- # to be the event generator.
- def to_edges
- @value.collect do |reference|
- reference.catalog = resource.catalog
-
- # Either of the two retrieval attempts could have returned
- # nil.
- unless related_resource = reference.resolve
- self.fail "Could not retrieve dependency '#{reference}' of #{@resource.ref}"
- end
-
- # Are we requiring them, or vice versa? See the method docs
- # for futher info on this.
- if self.class.direction == :in
- source = related_resource
- target = @resource
- else
- source = @resource
- target = related_resource
- end
-
- if method = self.class.callback
- subargs = {
- :event => self.class.events,
- :callback => method
- }
- self.debug("subscribes to #{related_resource.ref}")
- else
- # If there's no callback, there's no point in even adding
- # a label.
- subargs = nil
- self.debug("requires #{related_resource.ref}")
- end
-
- rel = Puppet::Relationship.new(source, target, subargs)
- end
+ parent = if pname = options[:parent]
+ options.delete(:parent)
+ if pname.is_a? Class
+ pname
+ else
+ if provider = self.provider(pname)
+ provider
+ else
+ raise Puppet::DevError,
+ "Could not find parent provider #{pname} of #{name}"
end
+ end
+ else
+ Puppet::Provider
end
- def self.relationship_params
- RelationshipMetaparam.subclasses
- end
-
-
- # Note that the order in which the relationships params is defined
- # matters. The labelled params (notify and subcribe) must be later,
- # so that if both params are used, those ones win. It's a hackish
- # solution, but it works.
-
- newmetaparam(:require, :parent => RelationshipMetaparam, :attributes => {:direction => :in, :events => :NONE}) do
- desc "One or more objects that this object depends on.
- This is used purely for guaranteeing that changes to required objects
- happen before the dependent object. For instance::
+ options[:resource_type] ||= self
- # Create the destination directory before you copy things down
- file { \"/usr/local/scripts\":
- ensure => directory
- }
+ self.providify
- file { \"/usr/local/scripts/myscript\":
- source => \"puppet://server/module/myscript\",
- mode => 755,
- require => File[\"/usr/local/scripts\"]
- }
- Multiple dependencies can be specified by providing a comma-seperated list
- of resources, enclosed in square brackets::
+ provider = genclass(
+ name,
+ :parent => parent,
+ :hash => provider_hash,
+ :prefix => "Provider",
+ :block => block,
+ :include => feature_module,
+ :extend => feature_module,
- require => [ File[\"/usr/local\"], File[\"/usr/local/scripts\"] ]
+ :attributes => options
+ )
- Note that Puppet will autorequire everything that it can, and
- there are hooks in place so that it's easy for resources to add new
- ways to autorequire objects, so if you think Puppet could be
- smarter here, let us know.
+ provider
+ end
- In fact, the above code was redundant -- Puppet will autorequire
- any parent directories that are being managed; it will
- automatically realize that the parent directory should be created
- before the script is pulled down.
+ # Make sure we have a :provider parameter defined. Only gets called if there
+ # are providers.
+ def self.providify
+ return if @paramhash.has_key? :provider
- Currently, exec resources will autorequire their CWD (if it is
- specified) plus any fully qualified paths that appear in the
- command. For instance, if you had an ``exec`` command that ran
- the ``myscript`` mentioned above, the above code that pulls the
- file down would be automatically listed as a requirement to the
- ``exec`` code, so that you would always be running againts the
- most recent version.
- "
- end
-
- newmetaparam(:subscribe, :parent => RelationshipMetaparam, :attributes => {:direction => :in, :events => :ALL_EVENTS, :callback => :refresh}) do
- desc "One or more objects that this object depends on. Changes in the
- subscribed to objects result in the dependent objects being
- refreshed (e.g., a service will get restarted). For instance::
+ newparam(:provider) do
+ desc "The specific backend for #{self.name.to_s} to use. You will
+ seldom need to specify this -- Puppet will usually discover the
+ appropriate provider for your platform."
- class nagios {
- file { \"/etc/nagios/nagios.conf\":
- source => \"puppet://server/module/nagios.conf\",
- alias => nagconf # just to make things easier for me
- }
- service { nagios:
- ensure => running,
- subscribe => File[nagconf]
- }
- }
+ # This is so we can refer back to the type to get a list of
+ # providers for documentation.
+ class << self
+ attr_accessor :parenttype
+ end
- Currently the ``exec``, ``mount`` and ``service`` type support
- refreshing.
- "
- end
-
- newmetaparam(:before, :parent => RelationshipMetaparam, :attributes => {:direction => :out, :events => :NONE}) do
- desc %{This parameter is the opposite of **require** -- it guarantees
- that the specified object is applied later than the specifying
- object::
-
- file { "/var/nagios/configuration":
- source => "...",
- recurse => true,
- before => Exec["nagios-rebuid"]
- }
-
- exec { "nagios-rebuild":
- command => "/usr/bin/make",
- cwd => "/var/nagios/configuration"
- }
-
- This will make sure all of the files are up to date before the
- make command is run.}
- end
+ # We need to add documentation for each provider.
+ def self.doc
+ @doc + " Available providers are:\n\n" + parenttype.providers.sort { |a,b|
+ a.to_s <=> b.to_s
+ }.collect { |i|
+ "* **#{i}**: #{parenttype().provider(i).doc}"
+ }.join("\n")
+ end
- newmetaparam(:notify, :parent => RelationshipMetaparam, :attributes => {:direction => :out, :events => :ALL_EVENTS, :callback => :refresh}) do
- desc %{This parameter is the opposite of **subscribe** -- it sends events
- to the specified object::
+ defaultto {
+ @resource.class.defaultprovider.name
+ }
- file { "/etc/sshd_config":
- source => "....",
- notify => Service[sshd]
- }
+ validate do |provider_class|
+ provider_class = provider_class[0] if provider_class.is_a? Array
+ provider_class = provider_class.class.name if provider_class.is_a?(Puppet::Provider)
- service { sshd:
- ensure => running
- }
-
- This will restart the sshd service if the sshd config file changes.}
- end
-
- newmetaparam(:stage) do
- desc %{Which run stage a given resource should reside in. This just creates
- a dependency on or from the named milestone. For instance, saying that
- this is in the 'bootstrap' stage creates a dependency on the 'bootstrap'
- milestone.
-
- By default, all classes get directly added to the
- 'main' stage. You can create new stages as resources:
-
- stage { [pre, post]: }
-
- To order stages, use standard relationships:
-
- stage { pre: before => Stage[main] }
-
- Or use the new relationship syntax:
-
- Stage[pre] -> Stage[main] -> Stage[post]
-
- Then use the new class parameters to specify a stage:
-
- class { foo: stage => pre }
-
- Stages can only be set on classes, not individual resources. This will
- fail::
-
- file { '/foo': stage => pre, ensure => file }
- }
- end
-
- ###############################
- # All of the provider plumbing for the resource types.
- require 'puppet/provider'
- require 'puppet/util/provider_features'
-
- # Add the feature handling module.
- extend Puppet::Util::ProviderFeatures
-
- attr_reader :provider
-
- # the Type class attribute accessors
- class << self
- attr_accessor :providerloader
- attr_writer :defaultprovider
- end
-
- # Find the default provider.
- def self.defaultprovider
- unless @defaultprovider
- suitable = suitableprovider
-
- # Find which providers are a default for this system.
- defaults = suitable.find_all { |provider| provider.default? }
-
- # If we don't have any default we use suitable providers
- defaults = suitable if defaults.empty?
- max = defaults.collect { |provider| provider.specificity }.max
- defaults = defaults.find_all { |provider| provider.specificity == max }
-
- retval = nil
- if defaults.length > 1
- Puppet.warning(
- "Found multiple default providers for #{self.name}: #{defaults.collect { |i| i.name.to_s }.join(", ")}; using #{defaults[0].name}"
- )
- retval = defaults.shift
- elsif defaults.length == 1
- retval = defaults.shift
- else
- raise Puppet::DevError, "Could not find a default provider for #{self.name}"
- end
-
- @defaultprovider = retval
+ unless provider = @resource.class.provider(provider_class)
+ raise ArgumentError, "Invalid #{@resource.class.name} provider '#{provider_class}'"
end
+ end
- @defaultprovider
- end
-
- def self.provider_hash_by_type(type)
- @provider_hashes ||= {}
- @provider_hashes[type] ||= {}
- end
-
- def self.provider_hash
- Puppet::Type.provider_hash_by_type(self.name)
- end
-
- # Retrieve a provider by name.
- def self.provider(name)
- name = Puppet::Util.symbolize(name)
-
- # If we don't have it yet, try loading it.
- @providerloader.load(name) unless provider_hash.has_key?(name)
- provider_hash[name]
- end
-
- # Just list all of the providers.
- def self.providers
- provider_hash.keys
- end
-
- def self.validprovider?(name)
- name = Puppet::Util.symbolize(name)
-
- (provider_hash.has_key?(name) && provider_hash[name].suitable?)
- end
-
- # Create a new provider of a type. This method must be called
- # directly on the type that it's implementing.
- def self.provide(name, options = {}, &block)
- name = Puppet::Util.symbolize(name)
-
- if obj = provider_hash[name]
- Puppet.debug "Reloading #{name} #{self.name} provider"
- unprovide(name)
- end
+ munge do |provider|
+ provider = provider[0] if provider.is_a? Array
+ provider = provider.intern if provider.is_a? String
+ @resource.provider = provider
- parent = if pname = options[:parent]
- options.delete(:parent)
- if pname.is_a? Class
- pname
- else
- if provider = self.provider(pname)
- provider
- else
- raise Puppet::DevError,
- "Could not find parent provider #{pname} of #{name}"
- end
- end
+ if provider.is_a?(Puppet::Provider)
+ provider.class.name
else
- Puppet::Provider
- end
-
- options[:resource_type] ||= self
-
- self.providify
-
-
- provider = genclass(
- name,
- :parent => parent,
- :hash => provider_hash,
- :prefix => "Provider",
- :block => block,
- :include => feature_module,
- :extend => feature_module,
-
- :attributes => options
- )
+ provider
+ end
+ end
+ end.parenttype = self
+ end
+
+ def self.unprovide(name)
+ if provider_hash.has_key? name
+
+ rmclass(
+ name,
+ :hash => provider_hash,
+
+ :prefix => "Provider"
+ )
+ if @defaultprovider and @defaultprovider.name == name
+ @defaultprovider = nil
+ end
+ end
+ end
+
+ # Return an array of all of the suitable providers.
+ def self.suitableprovider
+ providerloader.loadall if provider_hash.empty?
+ provider_hash.find_all { |name, provider|
+ provider.suitable?
+ }.collect { |name, provider|
+ provider
+ }.reject { |p| p.name == :fake } # For testing
+ end
+
+ def provider=(name)
+ if name.is_a?(Puppet::Provider)
+ @provider = name
+ @provider.resource = self
+ elsif klass = self.class.provider(name)
+ @provider = klass.new(self)
+ else
+ raise ArgumentError, "Could not find #{name} provider of #{self.class.name}"
+ end
+ end
+
+ ###############################
+ # All of the relationship code.
+
+ # Specify a block for generating a list of objects to autorequire. This
+ # makes it so that you don't have to manually specify things that you clearly
+ # require.
+ def self.autorequire(name, &block)
+ @autorequires ||= {}
+ @autorequires[name] = block
+ end
+
+ # Yield each of those autorequires in turn, yo.
+ def self.eachautorequire
+ @autorequires ||= {}
+ @autorequires.each { |type, block|
+ yield(type, block)
+ }
+ end
+
+ # Figure out of there are any objects we can automatically add as
+ # dependencies.
+ def autorequire(rel_catalog = nil)
+ rel_catalog ||= catalog
+ raise(Puppet::DevError, "You cannot add relationships without a catalog") unless rel_catalog
+
+ reqs = []
+ self.class.eachautorequire { |type, block|
+ # Ignore any types we can't find, although that would be a bit odd.
+ next unless typeobj = Puppet::Type.type(type)
+
+ # Retrieve the list of names from the block.
+ next unless list = self.instance_eval(&block)
+ list = [list] unless list.is_a?(Array)
+
+ # Collect the current prereqs
+ list.each { |dep|
+ obj = nil
+ # Support them passing objects directly, to save some effort.
+ unless dep.is_a? Puppet::Type
+ # Skip autorequires that we aren't managing
+ unless dep = rel_catalog.resource(type, dep)
+ next
+ end
+ end
+
+ reqs << Puppet::Relationship.new(dep, self)
+ }
+ }
+
+ reqs
+ end
+
+ # Build the dependencies associated with an individual object.
+ def builddepends
+ # Handle the requires
+ self.class.relationship_params.collect do |klass|
+ if param = @parameters[klass.name]
+ param.to_edges
+ end
+ end.flatten.reject { |r| r.nil? }
+ end
+
+ # Define the initial list of tags.
+ def tags=(list)
+ tag(self.class.name)
+ tag(*list)
+ end
+
+ # Types (which map to resources in the languages) are entirely composed of
+ # attribute value pairs. Generally, Puppet calls any of these things an
+ # 'attribute', but these attributes always take one of three specific
+ # forms: parameters, metaparams, or properties.
+
+ # In naming methods, I have tried to consistently name the method so
+ # that it is clear whether it operates on all attributes (thus has 'attr' in
+ # the method name, or whether it operates on a specific type of attributes.
+ attr_writer :title
+ attr_writer :noop
+
+ include Enumerable
+
+ # class methods dealing with Type management
+
+ public
+
+ # the Type class attribute accessors
+ class << self
+ attr_reader :name
+ attr_accessor :self_refresh
+ include Enumerable, Puppet::Util::ClassGen
+ include Puppet::MetaType::Manager
- provider
- end
-
- # Make sure we have a :provider parameter defined. Only gets called if there
- # are providers.
- def self.providify
- return if @paramhash.has_key? :provider
-
- newparam(:provider) do
- desc "The specific backend for #{self.name.to_s} to use. You will
- seldom need to specify this -- Puppet will usually discover the
- appropriate provider for your platform."
-
- # This is so we can refer back to the type to get a list of
- # providers for documentation.
- class << self
- attr_accessor :parenttype
- end
-
- # We need to add documentation for each provider.
- def self.doc
- @doc + " Available providers are:\n\n" + parenttype.providers.sort { |a,b|
- a.to_s <=> b.to_s
- }.collect { |i|
- "* **#{i}**: #{parenttype().provider(i).doc}"
- }.join("\n")
- end
-
- defaultto {
- @resource.class.defaultprovider.name
- }
-
- validate do |provider_class|
- provider_class = provider_class[0] if provider_class.is_a? Array
- provider_class = provider_class.class.name if provider_class.is_a?(Puppet::Provider)
-
- unless provider = @resource.class.provider(provider_class)
- raise ArgumentError, "Invalid #{@resource.class.name} provider '#{provider_class}'"
- end
- end
-
- munge do |provider|
- provider = provider[0] if provider.is_a? Array
- provider = provider.intern if provider.is_a? String
- @resource.provider = provider
-
- if provider.is_a?(Puppet::Provider)
- provider.class.name
- else
- provider
- end
- end
- end.parenttype = self
- end
-
- def self.unprovide(name)
- if provider_hash.has_key? name
-
- rmclass(
- name,
- :hash => provider_hash,
-
- :prefix => "Provider"
- )
- if @defaultprovider and @defaultprovider.name == name
- @defaultprovider = nil
- end
- end
- end
+ include Puppet::Util
+ include Puppet::Util::Logging
+ end
- # Return an array of all of the suitable providers.
- def self.suitableprovider
- providerloader.loadall if provider_hash.empty?
- provider_hash.find_all { |name, provider|
- provider.suitable?
- }.collect { |name, provider|
- provider
- }.reject { |p| p.name == :fake } # For testing
- end
+ # all of the variables that must be initialized for each subclass
+ def self.initvars
+ # all of the instances of this class
+ @objects = Hash.new
+ @aliases = Hash.new
- def provider=(name)
- if name.is_a?(Puppet::Provider)
- @provider = name
- @provider.resource = self
- elsif klass = self.class.provider(name)
- @provider = klass.new(self)
- else
- raise ArgumentError, "Could not find #{name} provider of #{self.class.name}"
- end
- end
+ @defaults = {}
- ###############################
- # All of the relationship code.
+ @parameters ||= []
- # Specify a block for generating a list of objects to autorequire. This
- # makes it so that you don't have to manually specify things that you clearly
- # require.
- def self.autorequire(name, &block)
- @autorequires ||= {}
- @autorequires[name] = block
- end
+ @validproperties = {}
+ @properties = []
+ @parameters = []
+ @paramhash = {}
- # Yield each of those autorequires in turn, yo.
- def self.eachautorequire
- @autorequires ||= {}
- @autorequires.each { |type, block|
- yield(type, block)
- }
- end
+ @attr_aliases = {}
- # Figure out of there are any objects we can automatically add as
- # dependencies.
- def autorequire(rel_catalog = nil)
- rel_catalog ||= catalog
- raise(Puppet::DevError, "You cannot add relationships without a catalog") unless rel_catalog
-
- reqs = []
- self.class.eachautorequire { |type, block|
- # Ignore any types we can't find, although that would be a bit odd.
- next unless typeobj = Puppet::Type.type(type)
-
- # Retrieve the list of names from the block.
- next unless list = self.instance_eval(&block)
- list = [list] unless list.is_a?(Array)
-
- # Collect the current prereqs
- list.each { |dep|
- obj = nil
- # Support them passing objects directly, to save some effort.
- unless dep.is_a? Puppet::Type
- # Skip autorequires that we aren't managing
- unless dep = rel_catalog.resource(type, dep)
- next
- end
- end
-
- reqs << Puppet::Relationship.new(dep, self)
- }
- }
+ @paramdoc = Hash.new { |hash,key|
+ key = key.intern if key.is_a?(String)
+ if hash.include?(key)
+ hash[key]
+ else
+ "Param Documentation for #{key} not found"
+ end
+ }
- reqs
- end
+ @doc ||= ""
- # Build the dependencies associated with an individual object.
- def builddepends
- # Handle the requires
- self.class.relationship_params.collect do |klass|
- if param = @parameters[klass.name]
- param.to_edges
- end
- end.flatten.reject { |r| r.nil? }
- end
+ end
- # Define the initial list of tags.
- def tags=(list)
- tag(self.class.name)
- tag(*list)
+ def self.to_s
+ if defined?(@name)
+ "Puppet::Type::#{@name.to_s.capitalize}"
+ else
+ super
end
+ end
- # Types (which map to resources in the languages) are entirely composed of
- # attribute value pairs. Generally, Puppet calls any of these things an
- # 'attribute', but these attributes always take one of three specific
- # forms: parameters, metaparams, or properties.
+ # Create a block to validate that our object is set up entirely. This will
+ # be run before the object is operated on.
+ def self.validate(&block)
+ define_method(:validate, &block)
+ #@validate = block
+ end
- # In naming methods, I have tried to consistently name the method so
- # that it is clear whether it operates on all attributes (thus has 'attr' in
- # the method name, or whether it operates on a specific type of attributes.
- attr_writer :title
- attr_writer :noop
+ # The catalog that this resource is stored in.
+ attr_accessor :catalog
- include Enumerable
+ # is the resource exported
+ attr_accessor :exported
- # class methods dealing with Type management
+ # is the resource virtual (it should not :-))
+ attr_accessor :virtual
- public
-
- # the Type class attribute accessors
- class << self
- attr_reader :name
- attr_accessor :self_refresh
- include Enumerable, Puppet::Util::ClassGen
- include Puppet::MetaType::Manager
+ # create a log at specified level
+ def log(msg)
- include Puppet::Util
- include Puppet::Util::Logging
- end
+ Puppet::Util::Log.create(
- # all of the variables that must be initialized for each subclass
- def self.initvars
- # all of the instances of this class
- @objects = Hash.new
- @aliases = Hash.new
+ :level => @parameters[:loglevel].value,
+ :message => msg,
- @defaults = {}
+ :source => self
+ )
+ end
- @parameters ||= []
- @validproperties = {}
- @properties = []
- @parameters = []
- @paramhash = {}
+ # instance methods related to instance intrinsics
+ # e.g., initialize and name
- @attr_aliases = {}
+ public
- @paramdoc = Hash.new { |hash,key|
- key = key.intern if key.is_a?(String)
- if hash.include?(key)
- hash[key]
- else
- "Param Documentation for #{key} not found"
- end
- }
+ attr_reader :original_parameters
- @doc ||= ""
+ # initialize the type instance
+ def initialize(resource)
+ raise Puppet::DevError, "Got TransObject instead of Resource or hash" if resource.is_a?(Puppet::TransObject)
+ resource = self.class.hash2resource(resource) unless resource.is_a?(Puppet::Resource)
- end
+ # The list of parameter/property instances.
+ @parameters = {}
- def self.to_s
- if defined?(@name)
- "Puppet::Type::#{@name.to_s.capitalize}"
- else
- super
- end
+ # Set the title first, so any failures print correctly.
+ if resource.type.to_s.downcase.to_sym == self.class.name
+ self.title = resource.title
+ else
+ # This should only ever happen for components
+ self.title = resource.ref
end
- # Create a block to validate that our object is set up entirely. This will
- # be run before the object is operated on.
- def self.validate(&block)
- define_method(:validate, &block)
- #@validate = block
+ [:file, :line, :catalog, :exported, :virtual].each do |getter|
+ setter = getter.to_s + "="
+ if val = resource.send(getter)
+ self.send(setter, val)
+ end
end
- # The catalog that this resource is stored in.
- attr_accessor :catalog
+ @tags = resource.tags
- # is the resource exported
- attr_accessor :exported
+ @original_parameters = resource.to_hash
- # is the resource virtual (it should not :-))
- attr_accessor :virtual
+ set_name(@original_parameters)
- # create a log at specified level
- def log(msg)
+ set_default(:provider)
- Puppet::Util::Log.create(
+ set_parameters(@original_parameters)
- :level => @parameters[:loglevel].value,
- :message => msg,
+ self.validate if self.respond_to?(:validate)
+ end
- :source => self
- )
- end
-
-
- # instance methods related to instance intrinsics
- # e.g., initialize and name
-
- public
-
- attr_reader :original_parameters
+ private
- # initialize the type instance
- def initialize(resource)
- raise Puppet::DevError, "Got TransObject instead of Resource or hash" if resource.is_a?(Puppet::TransObject)
- resource = self.class.hash2resource(resource) unless resource.is_a?(Puppet::Resource)
+ # Set our resource's name.
+ def set_name(hash)
+ self[name_var] = hash.delete(name_var) if name_var
+ end
- # The list of parameter/property instances.
- @parameters = {}
-
- # Set the title first, so any failures print correctly.
- if resource.type.to_s.downcase.to_sym == self.class.name
- self.title = resource.title
+ # Set all of the parameters from a hash, in the appropriate order.
+ def set_parameters(hash)
+ # Use the order provided by allattrs, but add in any
+ # extra attributes from the resource so we get failures
+ # on invalid attributes.
+ no_values = []
+ (self.class.allattrs + hash.keys).uniq.each do |attr|
+ begin
+ # Set any defaults immediately. This is mostly done so
+ # that the default provider is available for any other
+ # property validation.
+ if hash.has_key?(attr)
+ self[attr] = hash[attr]
else
- # This should only ever happen for components
- self.title = resource.ref
- end
-
- [:file, :line, :catalog, :exported, :virtual].each do |getter|
- setter = getter.to_s + "="
- if val = resource.send(getter)
- self.send(setter, val)
- end
- end
-
- @tags = resource.tags
-
- @original_parameters = resource.to_hash
-
- set_name(@original_parameters)
-
- set_default(:provider)
-
- set_parameters(@original_parameters)
-
- self.validate if self.respond_to?(:validate)
+ no_values << attr
+ end
+ rescue ArgumentError, Puppet::Error, TypeError
+ raise
+ rescue => detail
+ error = Puppet::DevError.new( "Could not set #{attr} on #{self.class.name}: #{detail}")
+ error.set_backtrace(detail.backtrace)
+ raise error
+ end
+ end
+ no_values.each do |attr|
+ set_default(attr)
+ end
+ end
+
+ public
+
+ # Set up all of our autorequires.
+ def finish
+ # Make sure all of our relationships are valid. Again, must be done
+ # when the entire catalog is instantiated.
+ self.class.relationship_params.collect do |klass|
+ if param = @parameters[klass.name]
+ param.validate_relationship
+ end
+ end.flatten.reject { |r| r.nil? }
+ end
+
+ # For now, leave the 'name' method functioning like it used to. Once 'title'
+ # works everywhere, I'll switch it.
+ def name
+ self[:name]
+ end
+
+ # Look up our parent in the catalog, if we have one.
+ def parent
+ return nil unless catalog
+
+ unless defined?(@parent)
+ if parents = catalog.adjacent(self, :direction => :in)
+ # We should never have more than one parent, so let's just ignore
+ # it if we happen to.
+ @parent = parents.shift
+ else
+ @parent = nil
+ end
end
+ @parent
+ end
- private
+ # Return the "type[name]" style reference.
+ def ref
+ "#{self.class.name.to_s.capitalize}[#{self.title}]"
+ end
- # Set our resource's name.
- def set_name(hash)
- self[name_var] = hash.delete(name_var) if name_var
- end
-
- # Set all of the parameters from a hash, in the appropriate order.
- def set_parameters(hash)
- # Use the order provided by allattrs, but add in any
- # extra attributes from the resource so we get failures
- # on invalid attributes.
- no_values = []
- (self.class.allattrs + hash.keys).uniq.each do |attr|
- begin
- # Set any defaults immediately. This is mostly done so
- # that the default provider is available for any other
- # property validation.
- if hash.has_key?(attr)
- self[attr] = hash[attr]
- else
- no_values << attr
- end
- rescue ArgumentError, Puppet::Error, TypeError
- raise
- rescue => detail
- error = Puppet::DevError.new( "Could not set #{attr} on #{self.class.name}: #{detail}")
- error.set_backtrace(detail.backtrace)
- raise error
- end
- end
- no_values.each do |attr|
- set_default(attr)
- end
- end
+ def self_refresh?
+ self.class.self_refresh
+ end
- public
+ # Mark that we're purging.
+ def purging
+ @purging = true
+ end
- # Set up all of our autorequires.
- def finish
- # Make sure all of our relationships are valid. Again, must be done
- # when the entire catalog is instantiated.
- self.class.relationship_params.collect do |klass|
- if param = @parameters[klass.name]
- param.validate_relationship
- end
- end.flatten.reject { |r| r.nil? }
+ # Is this resource being purged? Used by transactions to forbid
+ # deletion when there are dependencies.
+ def purging?
+ if defined?(@purging)
+ @purging
+ else
+ false
end
+ end
- # For now, leave the 'name' method functioning like it used to. Once 'title'
- # works everywhere, I'll switch it.
- def name
- self[:name]
+ # Retrieve the title of an object. If no title was set separately,
+ # then use the object's name.
+ def title
+ unless @title
+ if self.class.validparameter?(name_var)
+ @title = self[:name]
+ elsif self.class.validproperty?(name_var)
+ @title = self.should(name_var)
+ else
+ self.devfail "Could not find namevar #{name_var} for #{self.class.name}"
+ end
end
- # Look up our parent in the catalog, if we have one.
- def parent
- return nil unless catalog
+ @title
+ end
- unless defined?(@parent)
- if parents = catalog.adjacent(self, :direction => :in)
- # We should never have more than one parent, so let's just ignore
- # it if we happen to.
- @parent = parents.shift
- else
- @parent = nil
- end
- end
- @parent
- end
+ # convert to a string
+ def to_s
+ self.ref
+ end
- # Return the "type[name]" style reference.
- def ref
- "#{self.class.name.to_s.capitalize}[#{self.title}]"
- end
+ # Convert to a transportable object
+ def to_trans(ret = true)
+ trans = TransObject.new(self.title, self.class.name)
- def self_refresh?
- self.class.self_refresh
+ values = retrieve_resource
+ values.each do |name, value|
+ name = name.name if name.respond_to? :name
+ trans[name] = value
end
- # Mark that we're purging.
- def purging
- @purging = true
- end
+ @parameters.each do |name, param|
+ # Avoid adding each instance name twice
+ next if param.class.isnamevar? and param.value == self.title
- # Is this resource being purged? Used by transactions to forbid
- # deletion when there are dependencies.
- def purging?
- if defined?(@purging)
- @purging
- else
- false
- end
+ # We've already got property values
+ next if param.is_a?(Puppet::Property)
+ trans[name] = param.value
end
- # Retrieve the title of an object. If no title was set separately,
- # then use the object's name.
- def title
- unless @title
- if self.class.validparameter?(name_var)
- @title = self[:name]
- elsif self.class.validproperty?(name_var)
- @title = self.should(name_var)
- else
- self.devfail "Could not find namevar #{name_var} for #{self.class.name}"
- end
- end
+ trans.tags = self.tags
- @title
- end
+ # FIXME I'm currently ignoring 'parent' and 'path'
- # convert to a string
- def to_s
- self.ref
- end
+ trans
+ end
- # Convert to a transportable object
- def to_trans(ret = true)
- trans = TransObject.new(self.title, self.class.name)
-
- values = retrieve_resource
- values.each do |name, value|
- name = name.name if name.respond_to? :name
- trans[name] = value
- end
+ def to_resource
+ # this 'type instance' versus 'resource' distinction seems artificial
+ # I'd like to see it collapsed someday ~JW
+ self.to_trans.to_resource
+ end
- @parameters.each do |name, param|
- # Avoid adding each instance name twice
- next if param.class.isnamevar? and param.value == self.title
-
- # We've already got property values
- next if param.is_a?(Puppet::Property)
- trans[name] = param.value
- end
-
- trans.tags = self.tags
-
- # FIXME I'm currently ignoring 'parent' and 'path'
-
- trans
- end
-
- def to_resource
- # this 'type instance' versus 'resource' distinction seems artificial
- # I'd like to see it collapsed someday ~JW
- self.to_trans.to_resource
- end
-
- %w{exported virtual}.each do |m|
- define_method(m+"?") do
- self.send(m)
- end
+ %w{exported virtual}.each do |m|
+ define_method(m+"?") do
+ self.send(m)
end
+ end
end
end
diff --git a/lib/puppet/type/augeas.rb b/lib/puppet/type/augeas.rb
index 5a6fb54..7fcfdd7 100644
--- a/lib/puppet/type/augeas.rb
+++ b/lib/puppet/type/augeas.rb
@@ -18,166 +18,166 @@
# Author: Bryan Kearney <bkearney at redhat.com>
Puppet::Type.newtype(:augeas) do
- include Puppet::Util
-
- feature :parse_commands, "Parse the command string"
- feature :need_to_run?, "If the command should run"
- feature :execute_changes, "Actually make the changes"
-
- @doc = "Apply the changes (single or array of changes) to the filesystem
- via the augeas tool.
-
- Requires:
- - augeas to be installed (http://www.augeas.net)
- - ruby-augeas bindings
-
- Sample usage with a string::
-
- augeas{\"test1\" :
- context => \"/files/etc/sysconfig/firstboot\",
- changes => \"set RUN_FIRSTBOOT YES\",
- onlyif => \"match other_value size > 0\",
- }
-
- Sample usage with an array and custom lenses::
-
- augeas{\"jboss_conf\":
- context => \"/files\",
- changes => [
- \"set /etc/jbossas/jbossas.conf/JBOSS_IP $ipaddress\",
- \"set /etc/jbossas/jbossas.conf/JAVA_HOME /usr\"
- ],
- load_path => \"$/usr/share/jbossas/lenses\",
- }
-
- "
-
- newparam (:name) do
- desc "The name of this task. Used for uniqueness"
- isnamevar
- end
-
- newparam (:context) do
- desc "Optional context path. This value is prepended to the paths of all changes if the path is relative. If INCL is set, defaults to '/files' + INCL, otherwise the empty string"
- defaultto ""
- munge do |value|
- if value.empty? and resource[:incl]
- "/files" + resource[:incl]
- else
- value
- end
- end
- end
-
- newparam (:onlyif) do
- desc "Optional augeas command and comparisons to control the execution of this type.
- Supported onlyif syntax::
-
- get [AUGEAS_PATH] [COMPARATOR] [STRING]
- match [MATCH_PATH] size [COMPARATOR] [INT]
- match [MATCH_PATH] include [STRING]
- match [MATCH_PATH] not_include [STRING]
- match [MATCH_PATH] == [AN_ARRAY]
- match [MATCH_PATH] != [AN_ARRAY]
-
- where::
-
- AUGEAS_PATH is a valid path scoped by the context
- MATCH_PATH is a valid match synatx scoped by the context
- COMPARATOR is in the set [> >= != == <= <]
- STRING is a string
- INT is a number
- AN_ARRAY is in the form ['a string', 'another']"
- defaultto ""
- end
-
-
- newparam(:changes) do
- desc "The changes which should be applied to the filesystem. This
- can be either a string which contains a command or an array of commands.
- Commands supported are::
-
- set [PATH] [VALUE] Sets the value VALUE at loction PATH
- rm [PATH] Removes the node at location PATH
- remove [PATH] Synonym for rm
- clear [PATH] Keeps the node at PATH, but removes the value.
- ins [LABEL] [WHERE] [PATH]
- Inserts an empty node LABEL either [WHERE={before|after}] PATH.
- insert [LABEL] [WHERE] [PATH]
- Synonym for ins
-
- If the parameter 'context' is set that value is prepended to PATH"
- end
-
-
- newparam(:root) do
- desc "A file system path; all files loaded by Augeas are loaded underneath ROOT"
- defaultto "/"
- end
-
- newparam(:load_path) do
- desc "Optional colon separated list of directories; these directories are searched for schema definitions"
- defaultto ""
- end
-
- newparam(:force) do
- desc "Optional command to force the augeas type to execute even if it thinks changes
- will not be made. This does not overide the only setting. If onlyif is set, then the
- foce setting will not override that result"
-
- defaultto false
- end
-
- newparam(:type_check) do
- desc "Set to true if augeas should perform typechecking. Optional, defaults to false"
- newvalues(:true, :false)
-
- defaultto :false
+ include Puppet::Util
+
+ feature :parse_commands, "Parse the command string"
+ feature :need_to_run?, "If the command should run"
+ feature :execute_changes, "Actually make the changes"
+
+ @doc = "Apply the changes (single or array of changes) to the filesystem
+ via the augeas tool.
+
+ Requires:
+ - augeas to be installed (http://www.augeas.net)
+ - ruby-augeas bindings
+
+ Sample usage with a string::
+
+ augeas{\"test1\" :
+ context => \"/files/etc/sysconfig/firstboot\",
+ changes => \"set RUN_FIRSTBOOT YES\",
+ onlyif => \"match other_value size > 0\",
+ }
+
+ Sample usage with an array and custom lenses::
+
+ augeas{\"jboss_conf\":
+ context => \"/files\",
+ changes => [
+ \"set /etc/jbossas/jbossas.conf/JBOSS_IP $ipaddress\",
+ \"set /etc/jbossas/jbossas.conf/JAVA_HOME /usr\"
+ ],
+ load_path => \"$/usr/share/jbossas/lenses\",
+ }
+
+ "
+
+ newparam (:name) do
+ desc "The name of this task. Used for uniqueness"
+ isnamevar
+ end
+
+ newparam (:context) do
+ desc "Optional context path. This value is prepended to the paths of all changes if the path is relative. If INCL is set, defaults to '/files' + INCL, otherwise the empty string"
+ defaultto ""
+ munge do |value|
+ if value.empty? and resource[:incl]
+ "/files" + resource[:incl]
+ else
+ value
+ end
end
+ end
+
+ newparam (:onlyif) do
+ desc "Optional augeas command and comparisons to control the execution of this type.
+ Supported onlyif syntax::
+
+ get [AUGEAS_PATH] [COMPARATOR] [STRING]
+ match [MATCH_PATH] size [COMPARATOR] [INT]
+ match [MATCH_PATH] include [STRING]
+ match [MATCH_PATH] not_include [STRING]
+ match [MATCH_PATH] == [AN_ARRAY]
+ match [MATCH_PATH] != [AN_ARRAY]
+
+ where::
+
+ AUGEAS_PATH is a valid path scoped by the context
+ MATCH_PATH is a valid match synatx scoped by the context
+ COMPARATOR is in the set [> >= != == <= <]
+ STRING is a string
+ INT is a number
+ AN_ARRAY is in the form ['a string', 'another']"
+ defaultto ""
+ end
+
+
+ newparam(:changes) do
+ desc "The changes which should be applied to the filesystem. This
+ can be either a string which contains a command or an array of commands.
+ Commands supported are::
+
+ set [PATH] [VALUE] Sets the value VALUE at loction PATH
+ rm [PATH] Removes the node at location PATH
+ remove [PATH] Synonym for rm
+ clear [PATH] Keeps the node at PATH, but removes the value.
+ ins [LABEL] [WHERE] [PATH]
+ Inserts an empty node LABEL either [WHERE={before|after}] PATH.
+ insert [LABEL] [WHERE] [PATH]
+ Synonym for ins
+
+ If the parameter 'context' is set that value is prepended to PATH"
+ end
+
+
+ newparam(:root) do
+ desc "A file system path; all files loaded by Augeas are loaded underneath ROOT"
+ defaultto "/"
+ end
+
+ newparam(:load_path) do
+ desc "Optional colon separated list of directories; these directories are searched for schema definitions"
+ defaultto ""
+ end
+
+ newparam(:force) do
+ desc "Optional command to force the augeas type to execute even if it thinks changes
+ will not be made. This does not overide the only setting. If onlyif is set, then the
+ foce setting will not override that result"
+
+ defaultto false
+ end
+
+ newparam(:type_check) do
+ desc "Set to true if augeas should perform typechecking. Optional, defaults to false"
+ newvalues(:true, :false)
+
+ defaultto :false
+ end
+
+ newparam(:lens) do
+ desc "Use a specific lens, e.g. 'Hosts.lns'. When this parameter is set, you must also set the incl parameter to indicate which file to load. Only that file will be loaded, which greatly speeds up execution of the type"
+ end
+
+ newparam(:incl) do
+ desc "Load only a specific file, e.g. '/etc/hosts'. When this parameter is set, you must also set the lens parameter to indicate which lens to use."
+ end
+
+ validate do
+ has_lens = !self[:lens].nil?
+ has_incl = !self[:incl].nil?
+ self.fail "You must specify both the lens and incl parameters, or neither" if has_lens != has_incl
+ end
+
+ # This is the acutal meat of the code. It forces
+ # augeas to be run and fails or not based on the augeas return
+ # code.
+ newproperty(:returns) do |property|
+ include Puppet::Util
+ desc "The expected return code from the augeas command. Should not be set"
- newparam(:lens) do
- desc "Use a specific lens, e.g. 'Hosts.lns'. When this parameter is set, you must also set the incl parameter to indicate which file to load. Only that file will be loaded, which greatly speeds up execution of the type"
- end
+ defaultto 0
- newparam(:incl) do
- desc "Load only a specific file, e.g. '/etc/hosts'. When this parameter is set, you must also set the lens parameter to indicate which lens to use."
+ # Make output a bit prettier
+ def change_to_s(currentvalue, newvalue)
+ "executed successfully"
end
- validate do
- has_lens = !self[:lens].nil?
- has_incl = !self[:incl].nil?
- self.fail "You must specify both the lens and incl parameters, or neither" if has_lens != has_incl
+ # if the onlyif resource is provided, then the value is parsed.
+ # a return value of 0 will stop exection because it matches the
+ # default value.
+ def retrieve
+ if @resource.provider.need_to_run?()
+ :need_to_run
+ else
+ 0
+ end
end
- # This is the acutal meat of the code. It forces
- # augeas to be run and fails or not based on the augeas return
- # code.
- newproperty(:returns) do |property|
- include Puppet::Util
- desc "The expected return code from the augeas command. Should not be set"
-
- defaultto 0
-
- # Make output a bit prettier
- def change_to_s(currentvalue, newvalue)
- "executed successfully"
- end
-
- # if the onlyif resource is provided, then the value is parsed.
- # a return value of 0 will stop exection because it matches the
- # default value.
- def retrieve
- if @resource.provider.need_to_run?()
- :need_to_run
- else
- 0
- end
- end
-
- # Actually execute the command.
- def sync
- @resource.provider.execute_changes
- end
+ # Actually execute the command.
+ def sync
+ @resource.provider.execute_changes
end
+ end
end
diff --git a/lib/puppet/type/component.rb b/lib/puppet/type/component.rb
index 9e88523..c8c0940 100644
--- a/lib/puppet/type/component.rb
+++ b/lib/puppet/type/component.rb
@@ -4,82 +4,82 @@ require 'puppet/type'
require 'puppet/transaction'
Puppet::Type.newtype(:component) do
- include Enumerable
+ include Enumerable
- newparam(:name) do
- desc "The name of the component. Generally optional."
- isnamevar
- end
+ newparam(:name) do
+ desc "The name of the component. Generally optional."
+ isnamevar
+ end
- # Override how parameters are handled so that we support the extra
- # parameters that are used with defined resource types.
- def [](param)
- return super if self.class.valid_parameter?(param)
- @extra_parameters[param.to_sym]
- end
+ # Override how parameters are handled so that we support the extra
+ # parameters that are used with defined resource types.
+ def [](param)
+ return super if self.class.valid_parameter?(param)
+ @extra_parameters[param.to_sym]
+ end
- # Override how parameters are handled so that we support the extra
- # parameters that are used with defined resource types.
- def []=(param, value)
- return super if self.class.valid_parameter?(param)
- @extra_parameters[param.to_sym] = value
- end
+ # Override how parameters are handled so that we support the extra
+ # parameters that are used with defined resource types.
+ def []=(param, value)
+ return super if self.class.valid_parameter?(param)
+ @extra_parameters[param.to_sym] = value
+ end
- # Initialize a new component
- def initialize(*args)
- @extra_parameters = {}
- super
+ # Initialize a new component
+ def initialize(*args)
+ @extra_parameters = {}
+ super
- catalog.alias(self, ref) if catalog and ! catalog.resource(ref)
- end
+ catalog.alias(self, ref) if catalog and ! catalog.resource(ref)
+ end
- # Component paths are special because they function as containers.
- def pathbuilder
- if reference.type == "Class"
- # 'main' is the top class, so we want to see '//' instead of
- # its name.
- if reference.title.to_s.downcase == "main"
- myname = ""
- else
- myname = reference.title
- end
- else
- myname = reference.to_s
- end
- if p = self.parent
- return [p.pathbuilder, myname]
- else
- return [myname]
- end
+ # Component paths are special because they function as containers.
+ def pathbuilder
+ if reference.type == "Class"
+ # 'main' is the top class, so we want to see '//' instead of
+ # its name.
+ if reference.title.to_s.downcase == "main"
+ myname = ""
+ else
+ myname = reference.title
+ end
+ else
+ myname = reference.to_s
end
-
- def ref
- reference.to_s
+ if p = self.parent
+ return [p.pathbuilder, myname]
+ else
+ return [myname]
end
+ end
- # We want our title to just be the whole reference, rather than @title.
- def title
- ref
- end
+ def ref
+ reference.to_s
+ end
- def title=(str)
- @reference = Puppet::Resource.new(str)
- end
+ # We want our title to just be the whole reference, rather than @title.
+ def title
+ ref
+ end
- def refresh
- catalog.adjacent(self).each do |child|
- if child.respond_to?(:refresh)
- child.refresh
- child.log "triggering #{:refresh}"
- end
- end
- end
+ def title=(str)
+ @reference = Puppet::Resource.new(str)
+ end
- def to_s
- reference.to_s
+ def refresh
+ catalog.adjacent(self).each do |child|
+ if child.respond_to?(:refresh)
+ child.refresh
+ child.log "triggering #{:refresh}"
+ end
end
+ end
+
+ def to_s
+ reference.to_s
+ end
- private
+ private
- attr_reader :reference
+ attr_reader :reference
end
diff --git a/lib/puppet/type/computer.rb b/lib/puppet/type/computer.rb
index b27d8a4..86a30be 100644
--- a/lib/puppet/type/computer.rb
+++ b/lib/puppet/type/computer.rb
@@ -1,62 +1,62 @@
Puppet::Type.newtype(:computer) do
- @doc = "Computer object management using DirectoryService
- on OS X.
+ @doc = "Computer object management using DirectoryService
+ on OS X.
- Note that these are distinctly different kinds of objects to 'hosts',
- as they require a MAC address and can have all sorts of policy attached to
- them.
+ Note that these are distinctly different kinds of objects to 'hosts',
+ as they require a MAC address and can have all sorts of policy attached to
+ them.
- This provider only manages Computer objects in the local directory service
- domain, not in remote directories.
+ This provider only manages Computer objects in the local directory service
+ domain, not in remote directories.
- If you wish to manage /etc/hosts on Mac OS X, then simply use the host
- type as per other platforms.
+ If you wish to manage /etc/hosts on Mac OS X, then simply use the host
+ type as per other platforms.
- This type primarily exists to create localhost Computer objects that MCX
- policy can then be attached to."
+ This type primarily exists to create localhost Computer objects that MCX
+ policy can then be attached to."
- # ensurable
+ # ensurable
- # We autorequire the computer object in case it is being managed at the
- # file level by Puppet.
+ # We autorequire the computer object in case it is being managed at the
+ # file level by Puppet.
- autorequire(:file) do
- if self[:name]
- "/var/db/dslocal/nodes/Default/computers/#{self[:name]}.plist"
- else
- nil
- end
+ autorequire(:file) do
+ if self[:name]
+ "/var/db/dslocal/nodes/Default/computers/#{self[:name]}.plist"
+ else
+ nil
end
-
- newproperty(:ensure, :parent => Puppet::Property::Ensure) do
- desc "Control the existences of this computer record. Set this attribute to
- ``present`` to ensure the computer record exists. Set it to ``absent``
- to delete any computer records with this name"
- newvalue(:present) do
- provider.create
- end
-
- newvalue(:absent) do
- provider.delete
- end
+ end
+
+ newproperty(:ensure, :parent => Puppet::Property::Ensure) do
+ desc "Control the existences of this computer record. Set this attribute to
+ ``present`` to ensure the computer record exists. Set it to ``absent``
+ to delete any computer records with this name"
+ newvalue(:present) do
+ provider.create
end
- newparam(:name) do
- desc "The authoritative 'short' name of the computer record."
- isnamevar
+ newvalue(:absent) do
+ provider.delete
end
+ end
- newparam(:realname) do
- desc "The 'long' name of the computer record."
- end
+ newparam(:name) do
+ desc "The authoritative 'short' name of the computer record."
+ isnamevar
+ end
- newproperty(:en_address) do
- desc "The MAC address of the primary network interface. Must match en0."
- end
+ newparam(:realname) do
+ desc "The 'long' name of the computer record."
+ end
- newproperty(:ip_address) do
- desc "The IP Address of the Computer object."
- end
+ newproperty(:en_address) do
+ desc "The MAC address of the primary network interface. Must match en0."
+ end
+
+ newproperty(:ip_address) do
+ desc "The IP Address of the Computer object."
+ end
end
diff --git a/lib/puppet/type/cron.rb b/lib/puppet/type/cron.rb
index 5a25332..b3f5e60 100755
--- a/lib/puppet/type/cron.rb
+++ b/lib/puppet/type/cron.rb
@@ -3,411 +3,411 @@ require 'facter'
require 'puppet/util/filetype'
Puppet::Type.newtype(:cron) do
- @doc = "Installs and manages cron jobs. All fields except the command
- and the user are optional, although specifying no periodic
- fields would result in the command being executed every
- minute. While the name of the cron job is not part of the actual
- job, it is used by Puppet to store and retrieve it.
-
- If you specify a cron job that matches an existing job in every way
- except name, then the jobs will be considered equivalent and the
- new name will be permanently associated with that job. Once this
- association is made and synced to disk, you can then manage the job
- normally (e.g., change the schedule of the job).
-
- Example::
-
- cron { logrotate:
- command => \"/usr/sbin/logrotate\",
- user => root,
- hour => 2,
- minute => 0
- }
-
- Note that all cron values can be specified as an array of values::
-
- cron { logrotate:
- command => \"/usr/sbin/logrotate\",
- user => root,
- hour => [2, 4]
- }
-
- Or using ranges, or the step syntax ``*/2`` (although there's no guarantee that
- your ``cron`` daemon supports it)::
-
- cron { logrotate:
- command => \"/usr/sbin/logrotate\",
- user => root,
- hour => ['2-4'],
- minute => '*/10'
- }
- "
- ensurable
-
- # A base class for all of the Cron parameters, since they all have
- # similar argument checking going on.
- class CronParam < Puppet::Property
- class << self
- attr_accessor :boundaries, :default
- end
-
- # We have to override the parent method, because we consume the entire
- # "should" array
- def insync?(is)
- if @should
- self.is_to_s(is) == self.should_to_s
- else
- true
- end
- end
-
- # A method used to do parameter input handling. Converts integers
- # in string form to actual integers, and returns the value if it's
- # an integer or false if it's just a normal string.
- def numfix(num)
- if num =~ /^\d+$/
- return num.to_i
- elsif num.is_a?(Integer)
- return num
- else
- return false
- end
- end
-
- # Verify that a number is within the specified limits. Return the
- # number if it is, or false if it is not.
- def limitcheck(num, lower, upper)
- (num >= lower and num <= upper) && num
- end
-
- # Verify that a value falls within the specified array. Does case
- # insensitive matching, and supports matching either the entire word
- # or the first three letters of the word.
- def alphacheck(value, ary)
- tmp = value.downcase
-
- # If they specified a shortened version of the name, then see
- # if we can lengthen it (e.g., mon => monday).
- if tmp.length == 3
- ary.each_with_index { |name, index|
- if name =~ /#{tmp}/i
- return index
- end
- }
- else
- return ary.index(tmp) if ary.include?(tmp)
- end
-
- false
- end
+ @doc = "Installs and manages cron jobs. All fields except the command
+ and the user are optional, although specifying no periodic
+ fields would result in the command being executed every
+ minute. While the name of the cron job is not part of the actual
+ job, it is used by Puppet to store and retrieve it.
+
+ If you specify a cron job that matches an existing job in every way
+ except name, then the jobs will be considered equivalent and the
+ new name will be permanently associated with that job. Once this
+ association is made and synced to disk, you can then manage the job
+ normally (e.g., change the schedule of the job).
+
+ Example::
+
+ cron { logrotate:
+ command => \"/usr/sbin/logrotate\",
+ user => root,
+ hour => 2,
+ minute => 0
+ }
+
+ Note that all cron values can be specified as an array of values::
+
+ cron { logrotate:
+ command => \"/usr/sbin/logrotate\",
+ user => root,
+ hour => [2, 4]
+ }
+
+ Or using ranges, or the step syntax ``*/2`` (although there's no guarantee that
+ your ``cron`` daemon supports it)::
+
+ cron { logrotate:
+ command => \"/usr/sbin/logrotate\",
+ user => root,
+ hour => ['2-4'],
+ minute => '*/10'
+ }
+ "
+ ensurable
+
+ # A base class for all of the Cron parameters, since they all have
+ # similar argument checking going on.
+ class CronParam < Puppet::Property
+ class << self
+ attr_accessor :boundaries, :default
+ end
- def should_to_s(newvalue = @should)
- if newvalue
- newvalue = [newvalue] unless newvalue.is_a?(Array)
- if self.name == :command or newvalue[0].is_a? Symbol
- newvalue[0]
- else
- newvalue.join(",")
- end
- else
- nil
- end
- end
+ # We have to override the parent method, because we consume the entire
+ # "should" array
+ def insync?(is)
+ if @should
+ self.is_to_s(is) == self.should_to_s
+ else
+ true
+ end
+ end
- def is_to_s(currentvalue = @is)
- if currentvalue
- return currentvalue unless currentvalue.is_a?(Array)
-
- if self.name == :command or currentvalue[0].is_a? Symbol
- currentvalue[0]
- else
- currentvalue.join(",")
- end
- else
- nil
- end
- end
+ # A method used to do parameter input handling. Converts integers
+ # in string form to actual integers, and returns the value if it's
+ # an integer or false if it's just a normal string.
+ def numfix(num)
+ if num =~ /^\d+$/
+ return num.to_i
+ elsif num.is_a?(Integer)
+ return num
+ else
+ return false
+ end
+ end
- def should
- if @should and @should[0] == :absent
- :absent
- else
- @should
- end
- end
+ # Verify that a number is within the specified limits. Return the
+ # number if it is, or false if it is not.
+ def limitcheck(num, lower, upper)
+ (num >= lower and num <= upper) && num
+ end
- def should=(ary)
- super
- @should.flatten!
- end
+ # Verify that a value falls within the specified array. Does case
+ # insensitive matching, and supports matching either the entire word
+ # or the first three letters of the word.
+ def alphacheck(value, ary)
+ tmp = value.downcase
+
+ # If they specified a shortened version of the name, then see
+ # if we can lengthen it (e.g., mon => monday).
+ if tmp.length == 3
+ ary.each_with_index { |name, index|
+ if name =~ /#{tmp}/i
+ return index
+ end
+ }
+ else
+ return ary.index(tmp) if ary.include?(tmp)
+ end
- # The method that does all of the actual parameter value
- # checking; called by all of the +param<name>=+ methods.
- # Requires the value, type, and bounds, and optionally supports
- # a boolean of whether to do alpha checking, and if so requires
- # the ary against which to do the checking.
- munge do |value|
- # Support 'absent' as a value, so that they can remove
- # a value
- if value == "absent" or value == :absent
- return :absent
- end
-
- # Allow the */2 syntax
- if value =~ /^\*\/[0-9]+$/
- return value
- end
-
- # Allow ranges
- if value =~ /^[0-9]+-[0-9]+$/
- return value
- end
-
- # Allow ranges + */2
- if value =~ /^[0-9]+-[0-9]+\/[0-9]+$/
- return value
- end
-
- if value == "*"
- return value
- end
-
- return value unless self.class.boundaries
- lower, upper = self.class.boundaries
- retval = nil
- if num = numfix(value)
- retval = limitcheck(num, lower, upper)
- elsif respond_to?(:alpha)
- # If it has an alpha method defined, then we check
- # to see if our value is in that list and if so we turn
- # it into a number
- retval = alphacheck(value, alpha)
- end
-
- if retval
- return retval.to_s
- else
- self.fail "#{value} is not a valid #{self.class.name}"
- end
- end
+ false
end
- # Somewhat uniquely, this property does not actually change anything -- it
- # just calls + at resource.sync+, which writes out the whole cron tab for
- # the user in question. There is no real way to change individual cron
- # jobs without rewriting the entire cron file.
- #
- # Note that this means that managing many cron jobs for a given user
- # could currently result in multiple write sessions for that user.
- newproperty(:command, :parent => CronParam) do
- desc "The command to execute in the cron job. The environment
- provided to the command varies by local system rules, and it is
- best to always provide a fully qualified command. The user's
- profile is not sourced when the command is run, so if the
- user's environment is desired it should be sourced manually.
-
- All cron parameters support ``absent`` as a value; this will
- remove any existing values for that field."
-
- def retrieve
- return_value = super
- return_value = return_value[0] if return_value && return_value.is_a?(Array)
-
- return_value
- end
-
- def should
- if @should
- if @should.is_a? Array
- @should[0]
- else
- devfail "command is not an array"
- end
- else
- nil
- end
+ def should_to_s(newvalue = @should)
+ if newvalue
+ newvalue = [newvalue] unless newvalue.is_a?(Array)
+ if self.name == :command or newvalue[0].is_a? Symbol
+ newvalue[0]
+ else
+ newvalue.join(",")
end
+ else
+ nil
+ end
end
- newproperty(:special) do
- desc "Special schedules only supported on FreeBSD."
+ def is_to_s(currentvalue = @is)
+ if currentvalue
+ return currentvalue unless currentvalue.is_a?(Array)
- def specials
- %w{reboot yearly annually monthly weekly daily midnight hourly}
- end
-
- validate do |value|
- raise ArgumentError, "Invalid special schedule #{value.inspect}" unless specials.include?(value)
+ if self.name == :command or currentvalue[0].is_a? Symbol
+ currentvalue[0]
+ else
+ currentvalue.join(",")
end
+ else
+ nil
+ end
end
- newproperty(:minute, :parent => CronParam) do
- self.boundaries = [0, 59]
- desc "The minute at which to run the cron job.
- Optional; if specified, must be between 0 and 59, inclusive."
+ def should
+ if @should and @should[0] == :absent
+ :absent
+ else
+ @should
+ end
end
- newproperty(:hour, :parent => CronParam) do
- self.boundaries = [0, 23]
- desc "The hour at which to run the cron job. Optional;
- if specified, must be between 0 and 23, inclusive."
+ def should=(ary)
+ super
+ @should.flatten!
end
- newproperty(:weekday, :parent => CronParam) do
- def alpha
- %w{sunday monday tuesday wednesday thursday friday saturday}
- end
- self.boundaries = [0, 7]
- desc "The weekday on which to run the command.
- Optional; if specified, must be between 0 and 7, inclusive, with
- 0 (or 7) being Sunday, or must be the name of the day (e.g., Tuesday)."
+ # The method that does all of the actual parameter value
+ # checking; called by all of the +param<name>=+ methods.
+ # Requires the value, type, and bounds, and optionally supports
+ # a boolean of whether to do alpha checking, and if so requires
+ # the ary against which to do the checking.
+ munge do |value|
+ # Support 'absent' as a value, so that they can remove
+ # a value
+ if value == "absent" or value == :absent
+ return :absent
+ end
+
+ # Allow the */2 syntax
+ if value =~ /^\*\/[0-9]+$/
+ return value
+ end
+
+ # Allow ranges
+ if value =~ /^[0-9]+-[0-9]+$/
+ return value
+ end
+
+ # Allow ranges + */2
+ if value =~ /^[0-9]+-[0-9]+\/[0-9]+$/
+ return value
+ end
+
+ if value == "*"
+ return value
+ end
+
+ return value unless self.class.boundaries
+ lower, upper = self.class.boundaries
+ retval = nil
+ if num = numfix(value)
+ retval = limitcheck(num, lower, upper)
+ elsif respond_to?(:alpha)
+ # If it has an alpha method defined, then we check
+ # to see if our value is in that list and if so we turn
+ # it into a number
+ retval = alphacheck(value, alpha)
+ end
+
+ if retval
+ return retval.to_s
+ else
+ self.fail "#{value} is not a valid #{self.class.name}"
+ end
end
-
- newproperty(:month, :parent => CronParam) do
- def alpha
- %w{january february march april may june july
- august september october november december}
- end
- self.boundaries = [1, 12]
- desc "The month of the year. Optional; if specified
- must be between 1 and 12 or the month name (e.g., December)."
- end
-
- newproperty(:monthday, :parent => CronParam) do
- self.boundaries = [1, 31]
- desc "The day of the month on which to run the
- command. Optional; if specified, must be between 1 and 31."
+ end
+
+ # Somewhat uniquely, this property does not actually change anything -- it
+ # just calls + at resource.sync+, which writes out the whole cron tab for
+ # the user in question. There is no real way to change individual cron
+ # jobs without rewriting the entire cron file.
+ #
+ # Note that this means that managing many cron jobs for a given user
+ # could currently result in multiple write sessions for that user.
+ newproperty(:command, :parent => CronParam) do
+ desc "The command to execute in the cron job. The environment
+ provided to the command varies by local system rules, and it is
+ best to always provide a fully qualified command. The user's
+ profile is not sourced when the command is run, so if the
+ user's environment is desired it should be sourced manually.
+
+ All cron parameters support ``absent`` as a value; this will
+ remove any existing values for that field."
+
+ def retrieve
+ return_value = super
+ return_value = return_value[0] if return_value && return_value.is_a?(Array)
+
+ return_value
end
- newproperty(:environment) do
- desc "Any environment settings associated with this cron job. They
- will be stored between the header and the job in the crontab. There
- can be no guarantees that other, earlier settings will not also
- affect a given cron job.
-
-
- Also, Puppet cannot automatically determine whether an existing,
- unmanaged environment setting is associated with a given cron
- job. If you already have cron jobs with environment settings,
- then Puppet will keep those settings in the same place in the file,
- but will not associate them with a specific job.
-
- Settings should be specified exactly as they should appear in
- the crontab, e.g., ``PATH=/bin:/usr/bin:/usr/sbin``."
-
- validate do |value|
- unless value =~ /^\s*(\w+)\s*=\s*(.*)\s*$/ or value == :absent or value == "absent"
- raise ArgumentError, "Invalid environment setting #{value.inspect}"
- end
- end
-
- def insync?(is)
- if is.is_a? Array
- return is.sort == @should.sort
- else
- return is == @should
- end
- end
-
- def is_to_s(newvalue)
- if newvalue
- if newvalue.is_a?(Array)
- newvalue.join(",")
- else
- newvalue
- end
- else
- nil
- end
- end
-
- def should
- @should
- end
-
- def should_to_s(newvalue = @should)
- if newvalue
- newvalue.join(",")
- else
- nil
- end
+ def should
+ if @should
+ if @should.is_a? Array
+ @should[0]
+ else
+ devfail "command is not an array"
end
+ else
+ nil
+ end
end
+ end
- newparam(:name) do
- desc "The symbolic name of the cron job. This name
- is used for human reference only and is generated automatically
- for cron jobs found on the system. This generally won't
- matter, as Puppet will do its best to match existing cron jobs
- against specified jobs (and Puppet adds a comment to cron jobs it adds), but it is at least possible that converting from
- unmanaged jobs to managed jobs might require manual
- intervention."
+ newproperty(:special) do
+ desc "Special schedules only supported on FreeBSD."
- isnamevar
+ def specials
+ %w{reboot yearly annually monthly weekly daily midnight hourly}
end
- newproperty(:user) do
- desc "The user to run the command as. This user must
- be allowed to run cron jobs, which is not currently checked by
- Puppet.
+ validate do |value|
+ raise ArgumentError, "Invalid special schedule #{value.inspect}" unless specials.include?(value)
+ end
+ end
+
+ newproperty(:minute, :parent => CronParam) do
+ self.boundaries = [0, 59]
+ desc "The minute at which to run the cron job.
+ Optional; if specified, must be between 0 and 59, inclusive."
+ end
+
+ newproperty(:hour, :parent => CronParam) do
+ self.boundaries = [0, 23]
+ desc "The hour at which to run the cron job. Optional;
+ if specified, must be between 0 and 23, inclusive."
+ end
+
+ newproperty(:weekday, :parent => CronParam) do
+ def alpha
+ %w{sunday monday tuesday wednesday thursday friday saturday}
+ end
+ self.boundaries = [0, 7]
+ desc "The weekday on which to run the command.
+ Optional; if specified, must be between 0 and 7, inclusive, with
+ 0 (or 7) being Sunday, or must be the name of the day (e.g., Tuesday)."
+ end
+
+ newproperty(:month, :parent => CronParam) do
+ def alpha
+ %w{january february march april may june july
+ august september october november december}
+ end
+ self.boundaries = [1, 12]
+ desc "The month of the year. Optional; if specified
+ must be between 1 and 12 or the month name (e.g., December)."
+ end
+
+ newproperty(:monthday, :parent => CronParam) do
+ self.boundaries = [1, 31]
+ desc "The day of the month on which to run the
+ command. Optional; if specified, must be between 1 and 31."
+ end
+
+ newproperty(:environment) do
+ desc "Any environment settings associated with this cron job. They
+ will be stored between the header and the job in the crontab. There
+ can be no guarantees that other, earlier settings will not also
+ affect a given cron job.
+
+
+ Also, Puppet cannot automatically determine whether an existing,
+ unmanaged environment setting is associated with a given cron
+ job. If you already have cron jobs with environment settings,
+ then Puppet will keep those settings in the same place in the file,
+ but will not associate them with a specific job.
+
+ Settings should be specified exactly as they should appear in
+ the crontab, e.g., ``PATH=/bin:/usr/bin:/usr/sbin``."
+
+ validate do |value|
+ unless value =~ /^\s*(\w+)\s*=\s*(.*)\s*$/ or value == :absent or value == "absent"
+ raise ArgumentError, "Invalid environment setting #{value.inspect}"
+ end
+ end
- The user defaults to whomever Puppet is running as."
+ def insync?(is)
+ if is.is_a? Array
+ return is.sort == @should.sort
+ else
+ return is == @should
+ end
+ end
- defaultto { Etc.getpwuid(Process.uid).name || "root" }
+ def is_to_s(newvalue)
+ if newvalue
+ if newvalue.is_a?(Array)
+ newvalue.join(",")
+ else
+ newvalue
+ end
+ else
+ nil
+ end
end
- newproperty(:target) do
- desc "Where the cron job should be stored. For crontab-style
- entries this is the same as the user and defaults that way.
- Other providers default accordingly."
-
- defaultto {
- if provider.is_a?(@resource.class.provider(:crontab))
- if val = @resource.should(:user)
- val
- else
- raise ArgumentError,
- "You must provide a user with crontab entries"
- end
- elsif provider.class.ancestors.include?(Puppet::Provider::ParsedFile)
- provider.class.default_target
- else
- nil
- end
- }
+ def should
+ @should
end
- # We have to reorder things so that :provide is before :target
+ def should_to_s(newvalue = @should)
+ if newvalue
+ newvalue.join(",")
+ else
+ nil
+ end
+ end
+ end
+
+ newparam(:name) do
+ desc "The symbolic name of the cron job. This name
+ is used for human reference only and is generated automatically
+ for cron jobs found on the system. This generally won't
+ matter, as Puppet will do its best to match existing cron jobs
+ against specified jobs (and Puppet adds a comment to cron jobs it adds), but it is at least possible that converting from
+ unmanaged jobs to managed jobs might require manual
+ intervention."
+
+ isnamevar
+ end
+
+ newproperty(:user) do
+ desc "The user to run the command as. This user must
+ be allowed to run cron jobs, which is not currently checked by
+ Puppet.
+
+ The user defaults to whomever Puppet is running as."
+
+ defaultto { Etc.getpwuid(Process.uid).name || "root" }
+ end
+
+ newproperty(:target) do
+ desc "Where the cron job should be stored. For crontab-style
+ entries this is the same as the user and defaults that way.
+ Other providers default accordingly."
+
+ defaultto {
+ if provider.is_a?(@resource.class.provider(:crontab))
+ if val = @resource.should(:user)
+ val
+ else
+ raise ArgumentError,
+ "You must provide a user with crontab entries"
+ end
+ elsif provider.class.ancestors.include?(Puppet::Provider::ParsedFile)
+ provider.class.default_target
+ else
+ nil
+ end
+ }
+ end
- attr_accessor :uid
+ # We have to reorder things so that :provide is before :target
- def value(name)
- name = symbolize(name)
- ret = nil
- if obj = @parameters[name]
- ret = obj.should
+ attr_accessor :uid
- ret ||= obj.retrieve
+ def value(name)
+ name = symbolize(name)
+ ret = nil
+ if obj = @parameters[name]
+ ret = obj.should
- if ret == :absent
- ret = nil
- end
- end
+ ret ||= obj.retrieve
- unless ret
- case name
- when :command
- devfail "No command, somehow"
- when :special
- # nothing
- else
- #ret = (self.class.validproperty?(name).default || "*").to_s
- ret = "*"
- end
- end
+ if ret == :absent
+ ret = nil
+ end
+ end
- ret
+ unless ret
+ case name
+ when :command
+ devfail "No command, somehow"
+ when :special
+ # nothing
+ else
+ #ret = (self.class.validproperty?(name).default || "*").to_s
+ ret = "*"
+ end
end
+
+ ret
+ end
end
diff --git a/lib/puppet/type/exec.rb b/lib/puppet/type/exec.rb
index a60cdb4..bfeaaad 100755
--- a/lib/puppet/type/exec.rb
+++ b/lib/puppet/type/exec.rb
@@ -1,686 +1,686 @@
module Puppet
- newtype(:exec) do
- include Puppet::Util::Execution
- require 'timeout'
-
- @doc = "Executes external commands. It is critical that all commands
- executed using this mechanism can be run multiple times without
- harm, i.e., they are *idempotent*. One useful way to create idempotent
- commands is to use the checks like ``creates`` to avoid running the
- command unless some condition is met.
-
- Note also that you can restrict an ``exec`` to only run when it receives
- events by using the ``refreshonly`` parameter; this is a useful way to
- have your configuration respond to events with arbitrary commands.
-
- It is worth noting that ``exec`` is special, in that it is not
- currently considered an error to have multiple ``exec`` instances
- with the same name. This was done purely because it had to be this
- way in order to get certain functionality, but it complicates things.
- In particular, you will not be able to use ``exec`` instances that
- share their commands with other instances as a dependency, since
- Puppet has no way of knowing which instance you mean.
-
- For example::
-
- # defined in the production class
- exec { \"make\":
- cwd => \"/prod/build/dir\",
- path => \"/usr/bin:/usr/sbin:/bin\"
- }
-
- . etc. .
-
- # defined in the test class
- exec { \"make\":
- cwd => \"/test/build/dir\",
- path => \"/usr/bin:/usr/sbin:/bin\"
- }
-
- Any other type would throw an error, complaining that you had
- the same instance being managed in multiple places, but these are
- obviously different images, so ``exec`` had to be treated specially.
-
- It is recommended to avoid duplicate names whenever possible.
-
- Note that if an ``exec`` receives an event from another resource,
- it will get executed again (or execute the command specified in ``refresh``, if there is one).
-
- There is a strong tendency to use ``exec`` to do whatever work Puppet
- can't already do; while this is obviously acceptable (and unavoidable)
- in the short term, it is highly recommended to migrate work from ``exec``
- to native Puppet types as quickly as possible. If you find that
- you are doing a lot of work with ``exec``, please at least notify
- us at Puppet Labs what you are doing, and hopefully we can work with
- you to get a native resource type for the work you are doing."
-
- require 'open3'
-
- # Create a new check mechanism. It's basically just a parameter that
- # provides one extra 'check' method.
- def self.newcheck(name, &block)
- @checks ||= {}
-
- check = newparam(name, &block)
- @checks[name] = check
- end
-
- def self.checks
- @checks.keys
- end
-
- newproperty(:returns, :array_matching => :all, :event => :executed_command) do |property|
- include Puppet::Util::Execution
- munge do |value|
- value.to_s
- end
-
- def event_name
- :executed_command
- end
-
- defaultto "0"
+ newtype(:exec) do
+ include Puppet::Util::Execution
+ require 'timeout'
+
+ @doc = "Executes external commands. It is critical that all commands
+ executed using this mechanism can be run multiple times without
+ harm, i.e., they are *idempotent*. One useful way to create idempotent
+ commands is to use the checks like ``creates`` to avoid running the
+ command unless some condition is met.
+
+ Note also that you can restrict an ``exec`` to only run when it receives
+ events by using the ``refreshonly`` parameter; this is a useful way to
+ have your configuration respond to events with arbitrary commands.
+
+ It is worth noting that ``exec`` is special, in that it is not
+ currently considered an error to have multiple ``exec`` instances
+ with the same name. This was done purely because it had to be this
+ way in order to get certain functionality, but it complicates things.
+ In particular, you will not be able to use ``exec`` instances that
+ share their commands with other instances as a dependency, since
+ Puppet has no way of knowing which instance you mean.
+
+ For example::
+
+ # defined in the production class
+ exec { \"make\":
+ cwd => \"/prod/build/dir\",
+ path => \"/usr/bin:/usr/sbin:/bin\"
+ }
+
+ . etc. .
+
+ # defined in the test class
+ exec { \"make\":
+ cwd => \"/test/build/dir\",
+ path => \"/usr/bin:/usr/sbin:/bin\"
+ }
+
+ Any other type would throw an error, complaining that you had
+ the same instance being managed in multiple places, but these are
+ obviously different images, so ``exec`` had to be treated specially.
+
+ It is recommended to avoid duplicate names whenever possible.
+
+ Note that if an ``exec`` receives an event from another resource,
+ it will get executed again (or execute the command specified in ``refresh``, if there is one).
+
+ There is a strong tendency to use ``exec`` to do whatever work Puppet
+ can't already do; while this is obviously acceptable (and unavoidable)
+ in the short term, it is highly recommended to migrate work from ``exec``
+ to native Puppet types as quickly as possible. If you find that
+ you are doing a lot of work with ``exec``, please at least notify
+ us at Puppet Labs what you are doing, and hopefully we can work with
+ you to get a native resource type for the work you are doing."
+
+ require 'open3'
+
+ # Create a new check mechanism. It's basically just a parameter that
+ # provides one extra 'check' method.
+ def self.newcheck(name, &block)
+ @checks ||= {}
+
+ check = newparam(name, &block)
+ @checks[name] = check
+ end
- attr_reader :output
- desc "The expected return code(s). An error will be returned if the
- executed command returns something else. Defaults to 0. Can be
- specified as an array of acceptable return codes or a single value."
+ def self.checks
+ @checks.keys
+ end
- # Make output a bit prettier
- def change_to_s(currentvalue, newvalue)
- "executed successfully"
- end
+ newproperty(:returns, :array_matching => :all, :event => :executed_command) do |property|
+ include Puppet::Util::Execution
+ munge do |value|
+ value.to_s
+ end
- # First verify that all of our checks pass.
- def retrieve
- # Default to somethinng
+ def event_name
+ :executed_command
+ end
- if @resource.check
- return :notrun
- else
- return self.should
- end
- end
+ defaultto "0"
- # Actually execute the command.
- def sync
- olddir = nil
-
- # We need a dir to change to, even if it's just the cwd
- dir = self.resource[:cwd] || Dir.pwd
-
- event = :executed_command
- tries = self.resource[:tries]
- try_sleep = self.resource[:try_sleep]
-
- begin
- tries.times do |try|
- # Only add debug messages for tries > 1 to reduce log spam.
- debug("Exec try #{try+1}/#{tries}") if tries > 1
- @output, @status = @resource.run(self.resource[:command])
- break if self.should.include?(@status.exitstatus.to_s)
- if try_sleep > 0 and tries > 1
- debug("Sleeping for #{try_sleep} seconds between tries")
- sleep try_sleep
- end
- end
- rescue Timeout::Error
- self.fail "Command exceeded timeout" % value.inspect
- end
+ attr_reader :output
+ desc "The expected return code(s). An error will be returned if the
+ executed command returns something else. Defaults to 0. Can be
+ specified as an array of acceptable return codes or a single value."
- if log = @resource[:logoutput]
- case log
- when :true
- log = @resource[:loglevel]
- when :on_failure
- unless self.should.include?(@status.exitstatus.to_s)
- log = @resource[:loglevel]
- else
- log = :false
- end
- end
- unless log == :false
- @output.split(/\n/).each { |line|
- self.send(log, line)
- }
- end
- end
+ # Make output a bit prettier
+ def change_to_s(currentvalue, newvalue)
+ "executed successfully"
+ end
- unless self.should.include?(@status.exitstatus.to_s)
- self.fail("#{self.resource[:command]} returned #{@status.exitstatus} instead of one of [#{self.should.join(",")}]")
- end
+ # First verify that all of our checks pass.
+ def retrieve
+ # Default to somethinng
- event
+ if @resource.check
+ return :notrun
+ else
+ return self.should
+ end
+ end
+
+ # Actually execute the command.
+ def sync
+ olddir = nil
+
+ # We need a dir to change to, even if it's just the cwd
+ dir = self.resource[:cwd] || Dir.pwd
+
+ event = :executed_command
+ tries = self.resource[:tries]
+ try_sleep = self.resource[:try_sleep]
+
+ begin
+ tries.times do |try|
+ # Only add debug messages for tries > 1 to reduce log spam.
+ debug("Exec try #{try+1}/#{tries}") if tries > 1
+ @output, @status = @resource.run(self.resource[:command])
+ break if self.should.include?(@status.exitstatus.to_s)
+ if try_sleep > 0 and tries > 1
+ debug("Sleeping for #{try_sleep} seconds between tries")
+ sleep try_sleep
end
+ end
+ rescue Timeout::Error
+ self.fail "Command exceeded timeout" % value.inspect
end
- newparam(:command) do
- isnamevar
- desc "The actual command to execute. Must either be fully qualified
- or a search path for the command must be provided. If the command
- succeeds, any output produced will be logged at the instance's
- normal log level (usually ``notice``), but if the command fails
- (meaning its return code does not match the specified code) then
- any output is logged at the ``err`` log level."
+ if log = @resource[:logoutput]
+ case log
+ when :true
+ log = @resource[:loglevel]
+ when :on_failure
+ unless self.should.include?(@status.exitstatus.to_s)
+ log = @resource[:loglevel]
+ else
+ log = :false
+ end
+ end
+ unless log == :false
+ @output.split(/\n/).each { |line|
+ self.send(log, line)
+ }
+ end
end
- newparam(:path) do
- desc "The search path used for command execution.
- Commands must be fully qualified if no path is specified. Paths
- can be specified as an array or as a colon-separated list."
-
- # Support both arrays and colon-separated fields.
- def value=(*values)
- @value = values.flatten.collect { |val|
- if val =~ /;/ # recognize semi-colon separated paths
- val.split(";")
- elsif val =~ /^\w:[^:]*$/ # heuristic to avoid splitting a driveletter away
- val
- else
- val.split(":")
- end
- }.flatten
- end
+ unless self.should.include?(@status.exitstatus.to_s)
+ self.fail("#{self.resource[:command]} returned #{@status.exitstatus} instead of one of [#{self.should.join(",")}]")
end
- newparam(:user) do
- desc "The user to run the command as. Note that if you
- use this then any error output is not currently captured. This
- is because of a bug within Ruby. If you are using Puppet to
- create this user, the exec will automatically require the user,
- as long as it is specified by name."
+ event
+ end
+ end
- # Most validation is handled by the SUIDManager class.
- validate do |user|
- self.fail "Only root can execute commands as other users" unless Puppet.features.root?
- end
- end
+ newparam(:command) do
+ isnamevar
+ desc "The actual command to execute. Must either be fully qualified
+ or a search path for the command must be provided. If the command
+ succeeds, any output produced will be logged at the instance's
+ normal log level (usually ``notice``), but if the command fails
+ (meaning its return code does not match the specified code) then
+ any output is logged at the ``err`` log level."
+ end
- newparam(:group) do
- desc "The group to run the command as. This seems to work quite
- haphazardly on different platforms -- it is a platform issue
- not a Ruby or Puppet one, since the same variety exists when
- running commnands as different users in the shell."
- # Validation is handled by the SUIDManager class.
- end
+ newparam(:path) do
+ desc "The search path used for command execution.
+ Commands must be fully qualified if no path is specified. Paths
+ can be specified as an array or as a colon-separated list."
+
+ # Support both arrays and colon-separated fields.
+ def value=(*values)
+ @value = values.flatten.collect { |val|
+ if val =~ /;/ # recognize semi-colon separated paths
+ val.split(";")
+ elsif val =~ /^\w:[^:]*$/ # heuristic to avoid splitting a driveletter away
+ val
+ else
+ val.split(":")
+ end
+ }.flatten
+ end
+ end
- newparam(:cwd) do
- desc "The directory from which to run the command. If
- this directory does not exist, the command will fail."
+ newparam(:user) do
+ desc "The user to run the command as. Note that if you
+ use this then any error output is not currently captured. This
+ is because of a bug within Ruby. If you are using Puppet to
+ create this user, the exec will automatically require the user,
+ as long as it is specified by name."
+
+ # Most validation is handled by the SUIDManager class.
+ validate do |user|
+ self.fail "Only root can execute commands as other users" unless Puppet.features.root?
+ end
+ end
- validate do |dir|
- unless dir =~ /^#{File::SEPARATOR}/
- self.fail("CWD must be a fully qualified path")
- end
- end
+ newparam(:group) do
+ desc "The group to run the command as. This seems to work quite
+ haphazardly on different platforms -- it is a platform issue
+ not a Ruby or Puppet one, since the same variety exists when
+ running commnands as different users in the shell."
+ # Validation is handled by the SUIDManager class.
+ end
- munge do |dir|
- dir = dir[0] if dir.is_a?(Array)
+ newparam(:cwd) do
+ desc "The directory from which to run the command. If
+ this directory does not exist, the command will fail."
- dir
- end
+ validate do |dir|
+ unless dir =~ /^#{File::SEPARATOR}/
+ self.fail("CWD must be a fully qualified path")
end
+ end
- newparam(:logoutput) do
- desc "Whether to log output. Defaults to logging output at the
- loglevel for the ``exec`` resource. Use *on_failure* to only
- log the output when the command reports an error. Values are
- **true**, *false*, *on_failure*, and any legal log level."
+ munge do |dir|
+ dir = dir[0] if dir.is_a?(Array)
- newvalues(:true, :false, :on_failure)
- end
+ dir
+ end
+ end
- newparam(:refresh) do
- desc "How to refresh this command. By default, the exec is just
- called again when it receives an event from another resource,
- but this parameter allows you to define a different command
- for refreshing."
+ newparam(:logoutput) do
+ desc "Whether to log output. Defaults to logging output at the
+ loglevel for the ``exec`` resource. Use *on_failure* to only
+ log the output when the command reports an error. Values are
+ **true**, *false*, *on_failure*, and any legal log level."
- validate do |command|
- @resource.validatecmd(command)
- end
- end
+ newvalues(:true, :false, :on_failure)
+ end
- newparam(:env) do
- desc "This parameter is deprecated. Use 'environment' instead."
+ newparam(:refresh) do
+ desc "How to refresh this command. By default, the exec is just
+ called again when it receives an event from another resource,
+ but this parameter allows you to define a different command
+ for refreshing."
- munge do |value|
- warning "'env' is deprecated on exec; use 'environment' instead."
- resource[:environment] = value
- end
- end
+ validate do |command|
+ @resource.validatecmd(command)
+ end
+ end
- newparam(:environment) do
- desc "Any additional environment variables you want to set for a
- command. Note that if you use this to set PATH, it will override
- the ``path`` attribute. Multiple environment variables should be
- specified as an array."
-
- validate do |values|
- values = [values] unless values.is_a? Array
- values.each do |value|
- unless value =~ /\w+=/
- raise ArgumentError, "Invalid environment setting '#{value}'"
- end
- end
- end
- end
+ newparam(:env) do
+ desc "This parameter is deprecated. Use 'environment' instead."
- newparam(:timeout) do
- desc "The maximum time the command should take. If the command takes
- longer than the timeout, the command is considered to have failed
- and will be stopped. Use any negative number to disable the timeout.
- The time is specified in seconds."
-
- munge do |value|
- value = value.shift if value.is_a?(Array)
- if value.is_a?(String)
- unless value =~ /^[-\d.]+$/
- raise ArgumentError, "The timeout must be a number."
- end
- Float(value)
- else
- value
- end
- end
+ munge do |value|
+ warning "'env' is deprecated on exec; use 'environment' instead."
+ resource[:environment] = value
+ end
+ end
- defaultto 300
+ newparam(:environment) do
+ desc "Any additional environment variables you want to set for a
+ command. Note that if you use this to set PATH, it will override
+ the ``path`` attribute. Multiple environment variables should be
+ specified as an array."
+
+ validate do |values|
+ values = [values] unless values.is_a? Array
+ values.each do |value|
+ unless value =~ /\w+=/
+ raise ArgumentError, "Invalid environment setting '#{value}'"
+ end
end
+ end
+ end
- newparam(:tries) do
- desc "The number of times execution of the command should be tried.
- Defaults to '1'. This many attempts will be made to execute
- the command until an acceptable return code is returned.
- Note that the timeout paramater applies to each try rather than
- to the complete set of tries."
-
- munge do |value|
- if value.is_a?(String)
- unless value =~ /^[\d]+$/
- raise ArgumentError, "Tries must be an integer"
- end
- value = Integer(value)
- end
- raise ArgumentError, "Tries must be an integer >= 1" if value < 1
- value
- end
+ newparam(:timeout) do
+ desc "The maximum time the command should take. If the command takes
+ longer than the timeout, the command is considered to have failed
+ and will be stopped. Use any negative number to disable the timeout.
+ The time is specified in seconds."
+
+ munge do |value|
+ value = value.shift if value.is_a?(Array)
+ if value.is_a?(String)
+ unless value =~ /^[-\d.]+$/
+ raise ArgumentError, "The timeout must be a number."
+ end
+ Float(value)
+ else
+ value
+ end
+ end
- defaultto 1
+ defaultto 300
+ end
+
+ newparam(:tries) do
+ desc "The number of times execution of the command should be tried.
+ Defaults to '1'. This many attempts will be made to execute
+ the command until an acceptable return code is returned.
+ Note that the timeout paramater applies to each try rather than
+ to the complete set of tries."
+
+ munge do |value|
+ if value.is_a?(String)
+ unless value =~ /^[\d]+$/
+ raise ArgumentError, "Tries must be an integer"
+ end
+ value = Integer(value)
end
+ raise ArgumentError, "Tries must be an integer >= 1" if value < 1
+ value
+ end
- newparam(:try_sleep) do
- desc "The time to sleep in seconds between 'tries'."
+ defaultto 1
+ end
- munge do |value|
- if value.is_a?(String)
- unless value =~ /^[-\d.]+$/
- raise ArgumentError, "try_sleep must be a number"
- end
- value = Float(value)
- end
- raise ArgumentError, "try_sleep cannot be a negative number" if value < 0
- value
- end
+ newparam(:try_sleep) do
+ desc "The time to sleep in seconds between 'tries'."
- defaultto 0
+ munge do |value|
+ if value.is_a?(String)
+ unless value =~ /^[-\d.]+$/
+ raise ArgumentError, "try_sleep must be a number"
+ end
+ value = Float(value)
end
+ raise ArgumentError, "try_sleep cannot be a negative number" if value < 0
+ value
+ end
+ defaultto 0
+ end
- newcheck(:refreshonly) do
- desc "The command should only be run as a
- refresh mechanism for when a dependent object is changed. It only
- makes sense to use this option when this command depends on some
- other object; it is useful for triggering an action::
-
- # Pull down the main aliases file
- file { \"/etc/aliases\":
- source => \"puppet://server/module/aliases\"
- }
-
- # Rebuild the database, but only when the file changes
- exec { newaliases:
- path => [\"/usr/bin\", \"/usr/sbin\"],
- subscribe => File[\"/etc/aliases\"],
- refreshonly => true
- }
-
- Note that only ``subscribe`` and ``notify`` can trigger actions, not ``require``,
- so it only makes sense to use ``refreshonly`` with ``subscribe`` or ``notify``."
-
- newvalues(:true, :false)
-
- # We always fail this test, because we're only supposed to run
- # on refresh.
- def check(value)
- # We have to invert the values.
- if value == :true
- false
- else
- true
- end
- end
+
+ newcheck(:refreshonly) do
+ desc "The command should only be run as a
+ refresh mechanism for when a dependent object is changed. It only
+ makes sense to use this option when this command depends on some
+ other object; it is useful for triggering an action::
+
+ # Pull down the main aliases file
+ file { \"/etc/aliases\":
+ source => \"puppet://server/module/aliases\"
+ }
+
+ # Rebuild the database, but only when the file changes
+ exec { newaliases:
+ path => [\"/usr/bin\", \"/usr/sbin\"],
+ subscribe => File[\"/etc/aliases\"],
+ refreshonly => true
+ }
+
+ Note that only ``subscribe`` and ``notify`` can trigger actions, not ``require``,
+ so it only makes sense to use ``refreshonly`` with ``subscribe`` or ``notify``."
+
+ newvalues(:true, :false)
+
+ # We always fail this test, because we're only supposed to run
+ # on refresh.
+ def check(value)
+ # We have to invert the values.
+ if value == :true
+ false
+ else
+ true
end
+ end
+ end
- newcheck(:creates) do
- desc "A file that this command creates. If this
- parameter is provided, then the command will only be run
- if the specified file does not exist::
+ newcheck(:creates) do
+ desc "A file that this command creates. If this
+ parameter is provided, then the command will only be run
+ if the specified file does not exist::
- exec { \"tar xf /my/tar/file.tar\":
- cwd => \"/var/tmp\",
- creates => \"/var/tmp/myfile\",
- path => [\"/usr/bin\", \"/usr/sbin\"]
- }
+ exec { \"tar xf /my/tar/file.tar\":
+ cwd => \"/var/tmp\",
+ creates => \"/var/tmp/myfile\",
+ path => [\"/usr/bin\", \"/usr/sbin\"]
+ }
- "
+ "
- # FIXME if they try to set this and fail, then we should probably
- # fail the entire exec, right?
- validate do |files|
- files = [files] unless files.is_a? Array
+ # FIXME if they try to set this and fail, then we should probably
+ # fail the entire exec, right?
+ validate do |files|
+ files = [files] unless files.is_a? Array
- files.each do |file|
- self.fail("'creates' must be set to a fully qualified path") unless file
+ files.each do |file|
+ self.fail("'creates' must be set to a fully qualified path") unless file
- unless file =~ %r{^#{File::SEPARATOR}}
- self.fail "'creates' files must be fully qualified."
- end
- end
- end
-
- # If the file exists, return false (i.e., don't run the command),
- # else return true
- def check(value)
- ! FileTest.exists?(value)
- end
+ unless file =~ %r{^#{File::SEPARATOR}}
+ self.fail "'creates' files must be fully qualified."
+ end
end
+ end
- newcheck(:unless) do
- desc "If this parameter is set, then this ``exec`` will run unless
- the command returns 0. For example::
-
- exec { \"/bin/echo root >> /usr/lib/cron/cron.allow\":
- path => \"/usr/bin:/usr/sbin:/bin\",
- unless => \"grep root /usr/lib/cron/cron.allow 2>/dev/null\"
- }
+ # If the file exists, return false (i.e., don't run the command),
+ # else return true
+ def check(value)
+ ! FileTest.exists?(value)
+ end
+ end
- This would add ``root`` to the cron.allow file (on Solaris) unless
- ``grep`` determines it's already there.
+ newcheck(:unless) do
+ desc "If this parameter is set, then this ``exec`` will run unless
+ the command returns 0. For example::
- Note that this command follows the same rules as the main command,
- which is to say that it must be fully qualified if the path is not set.
- "
+ exec { \"/bin/echo root >> /usr/lib/cron/cron.allow\":
+ path => \"/usr/bin:/usr/sbin:/bin\",
+ unless => \"grep root /usr/lib/cron/cron.allow 2>/dev/null\"
+ }
- validate do |cmds|
- cmds = [cmds] unless cmds.is_a? Array
+ This would add ``root`` to the cron.allow file (on Solaris) unless
+ ``grep`` determines it's already there.
- cmds.each do |cmd|
- @resource.validatecmd(cmd)
- end
- end
+ Note that this command follows the same rules as the main command,
+ which is to say that it must be fully qualified if the path is not set.
+ "
- # Return true if the command does not return 0.
- def check(value)
- begin
- output, status = @resource.run(value, true)
- rescue Timeout::Error
- err "Check #{value.inspect} exceeded timeout"
- return false
- end
+ validate do |cmds|
+ cmds = [cmds] unless cmds.is_a? Array
- status.exitstatus != 0
- end
+ cmds.each do |cmd|
+ @resource.validatecmd(cmd)
+ end
+ end
+
+ # Return true if the command does not return 0.
+ def check(value)
+ begin
+ output, status = @resource.run(value, true)
+ rescue Timeout::Error
+ err "Check #{value.inspect} exceeded timeout"
+ return false
end
- newcheck(:onlyif) do
- desc "If this parameter is set, then this ``exec`` will only run if
- the command returns 0. For example::
+ status.exitstatus != 0
+ end
+ end
- exec { \"logrotate\":
- path => \"/usr/bin:/usr/sbin:/bin\",
- onlyif => \"test `du /var/log/messages | cut -f1` -gt 100000\"
- }
+ newcheck(:onlyif) do
+ desc "If this parameter is set, then this ``exec`` will only run if
+ the command returns 0. For example::
- This would run ``logrotate`` only if that test returned true.
+ exec { \"logrotate\":
+ path => \"/usr/bin:/usr/sbin:/bin\",
+ onlyif => \"test `du /var/log/messages | cut -f1` -gt 100000\"
+ }
- Note that this command follows the same rules as the main command,
- which is to say that it must be fully qualified if the path is not set.
+ This would run ``logrotate`` only if that test returned true.
- Also note that onlyif can take an array as its value, eg::
+ Note that this command follows the same rules as the main command,
+ which is to say that it must be fully qualified if the path is not set.
- onlyif => [\"test -f /tmp/file1\", \"test -f /tmp/file2\"]
+ Also note that onlyif can take an array as its value, eg::
- This will only run the exec if /all/ conditions in the array return true.
- "
+ onlyif => [\"test -f /tmp/file1\", \"test -f /tmp/file2\"]
- validate do |cmds|
- cmds = [cmds] unless cmds.is_a? Array
+ This will only run the exec if /all/ conditions in the array return true.
+ "
- cmds.each do |cmd|
- @resource.validatecmd(cmd)
- end
- end
-
- # Return true if the command returns 0.
- def check(value)
- begin
- output, status = @resource.run(value, true)
- rescue Timeout::Error
- err "Check #{value.inspect} exceeded timeout"
- return false
- end
+ validate do |cmds|
+ cmds = [cmds] unless cmds.is_a? Array
- status.exitstatus == 0
- end
+ cmds.each do |cmd|
+ @resource.validatecmd(cmd)
end
-
- # Exec names are not isomorphic with the objects.
- @isomorphic = false
-
- validate do
- validatecmd(self[:command])
+ end
+
+ # Return true if the command returns 0.
+ def check(value)
+ begin
+ output, status = @resource.run(value, true)
+ rescue Timeout::Error
+ err "Check #{value.inspect} exceeded timeout"
+ return false
end
- # FIXME exec should autorequire any exec that 'creates' our cwd
- autorequire(:file) do
- reqs = []
+ status.exitstatus == 0
+ end
+ end
- # Stick the cwd in there if we have it
- reqs << self[:cwd] if self[:cwd]
+ # Exec names are not isomorphic with the objects.
+ @isomorphic = false
- self[:command].scan(/^(#{File::SEPARATOR}\S+)/) { |str|
- reqs << str
- }
+ validate do
+ validatecmd(self[:command])
+ end
- self[:command].scan(/^"([^"]+)"/) { |str|
- reqs << str
- }
+ # FIXME exec should autorequire any exec that 'creates' our cwd
+ autorequire(:file) do
+ reqs = []
- [:onlyif, :unless].each { |param|
- next unless tmp = self[param]
+ # Stick the cwd in there if we have it
+ reqs << self[:cwd] if self[:cwd]
- tmp = [tmp] unless tmp.is_a? Array
+ self[:command].scan(/^(#{File::SEPARATOR}\S+)/) { |str|
+ reqs << str
+ }
- tmp.each do |line|
- # And search the command line for files, adding any we
- # find. This will also catch the command itself if it's
- # fully qualified. It might not be a bad idea to add
- # unqualified files, but, well, that's a bit more annoying
- # to do.
- reqs += line.scan(%r{(#{File::SEPARATOR}\S+)})
- end
- }
+ self[:command].scan(/^"([^"]+)"/) { |str|
+ reqs << str
+ }
- # For some reason, the += isn't causing a flattening
- reqs.flatten!
+ [:onlyif, :unless].each { |param|
+ next unless tmp = self[param]
- reqs
- end
+ tmp = [tmp] unless tmp.is_a? Array
- autorequire(:user) do
- # Autorequire users if they are specified by name
- if user = self[:user] and user !~ /^\d+$/
- user
- end
+ tmp.each do |line|
+ # And search the command line for files, adding any we
+ # find. This will also catch the command itself if it's
+ # fully qualified. It might not be a bad idea to add
+ # unqualified files, but, well, that's a bit more annoying
+ # to do.
+ reqs += line.scan(%r{(#{File::SEPARATOR}\S+)})
end
+ }
- def self.instances
- []
- end
+ # For some reason, the += isn't causing a flattening
+ reqs.flatten!
- # Verify that we pass all of the checks. The argument determines whether
- # we skip the :refreshonly check, which is necessary because we now check
- # within refresh
- def check(refreshing = false)
- self.class.checks.each { |check|
- next if refreshing and check == :refreshonly
- if @parameters.include?(check)
- val = @parameters[check].value
- val = [val] unless val.is_a? Array
- val.each do |value|
- return false unless @parameters[check].check(value)
- end
- end
- }
+ reqs
+ end
- true
- end
+ autorequire(:user) do
+ # Autorequire users if they are specified by name
+ if user = self[:user] and user !~ /^\d+$/
+ user
+ end
+ end
- # Verify that we have the executable
- def checkexe(cmd)
- exe = extractexe(cmd)
-
- if self[:path]
- if Puppet.features.posix? and !File.exists?(exe)
- withenv :PATH => self[:path].join(File::PATH_SEPARATOR) do
- path = %x{which #{exe}}.chomp
- if path == ""
- raise ArgumentError,
- "Could not find command '#{exe}'"
- else
- exe = path
- end
- end
- elsif Puppet.features.microsoft_windows? and !File.exists?(exe)
- self[:path].each do |path|
- [".exe", ".ps1", ".bat", ".com", ""].each do |extension|
- file = File.join(path, exe+extension)
- return if File.exists?(file)
- end
- end
- end
- end
+ def self.instances
+ []
+ end
- raise ArgumentError, "Could not find executable '#{exe}'" unless FileTest.exists?(exe)
- unless FileTest.executable?(exe)
- raise ArgumentError,
- "'#{exe}' is not executable"
- end
+ # Verify that we pass all of the checks. The argument determines whether
+ # we skip the :refreshonly check, which is necessary because we now check
+ # within refresh
+ def check(refreshing = false)
+ self.class.checks.each { |check|
+ next if refreshing and check == :refreshonly
+ if @parameters.include?(check)
+ val = @parameters[check].value
+ val = [val] unless val.is_a? Array
+ val.each do |value|
+ return false unless @parameters[check].check(value)
+ end
end
+ }
+
+ true
+ end
- def output
- if self.property(:returns).nil?
- return nil
+ # Verify that we have the executable
+ def checkexe(cmd)
+ exe = extractexe(cmd)
+
+ if self[:path]
+ if Puppet.features.posix? and !File.exists?(exe)
+ withenv :PATH => self[:path].join(File::PATH_SEPARATOR) do
+ path = %x{which #{exe}}.chomp
+ if path == ""
+ raise ArgumentError,
+ "Could not find command '#{exe}'"
else
- return self.property(:returns).output
+ exe = path
end
+ end
+ elsif Puppet.features.microsoft_windows? and !File.exists?(exe)
+ self[:path].each do |path|
+ [".exe", ".ps1", ".bat", ".com", ""].each do |extension|
+ file = File.join(path, exe+extension)
+ return if File.exists?(file)
+ end
+ end
end
+ end
- # Run the command, or optionally run a separately-specified command.
- def refresh
- if self.check(true)
- if cmd = self[:refresh]
- self.run(cmd)
- else
- self.property(:returns).sync
- end
- end
+ raise ArgumentError, "Could not find executable '#{exe}'" unless FileTest.exists?(exe)
+ unless FileTest.executable?(exe)
+ raise ArgumentError,
+ "'#{exe}' is not executable"
+ end
+ end
+
+ def output
+ if self.property(:returns).nil?
+ return nil
+ else
+ return self.property(:returns).output
+ end
+ end
+
+ # Run the command, or optionally run a separately-specified command.
+ def refresh
+ if self.check(true)
+ if cmd = self[:refresh]
+ self.run(cmd)
+ else
+ self.property(:returns).sync
end
+ end
+ end
- # Run a command.
- def run(command, check = false)
- output = nil
- status = nil
+ # Run a command.
+ def run(command, check = false)
+ output = nil
+ status = nil
- dir = nil
+ dir = nil
- checkexe(command)
+ checkexe(command)
- if dir = self[:cwd]
- unless File.directory?(dir)
- if check
- dir = nil
- else
- self.fail "Working directory '#{dir}' does not exist"
- end
+ if dir = self[:cwd]
+ unless File.directory?(dir)
+ if check
+ dir = nil
+ else
+ self.fail "Working directory '#{dir}' does not exist"
+ end
+ end
+ end
+
+ dir ||= Dir.pwd
+
+ if check
+ debug "Executing check '#{command}'"
+ else
+ debug "Executing '#{command}'"
+ end
+ begin
+ # Do our chdir
+ Dir.chdir(dir) do
+ environment = {}
+
+ environment[:PATH] = self[:path].join(":") if self[:path]
+
+ if envlist = self[:environment]
+ envlist = [envlist] unless envlist.is_a? Array
+ envlist.each do |setting|
+ if setting =~ /^(\w+)=((.|\n)+)$/
+ name = $1
+ value = $2
+ if environment.include? name
+ warning(
+ "Overriding environment setting '#{name}' with '#{value}'"
+ )
end
+ environment[name] = value
+ else
+ warning "Cannot understand environment setting #{setting.inspect}"
+ end
end
+ end
- dir ||= Dir.pwd
-
- if check
- debug "Executing check '#{command}'"
- else
- debug "Executing '#{command}'"
+ withenv environment do
+ Timeout::timeout(self[:timeout]) do
+ output, status = Puppet::Util::SUIDManager.run_and_capture(
+ [command], self[:user], self[:group]
+ )
end
- begin
- # Do our chdir
- Dir.chdir(dir) do
- environment = {}
-
- environment[:PATH] = self[:path].join(":") if self[:path]
-
- if envlist = self[:environment]
- envlist = [envlist] unless envlist.is_a? Array
- envlist.each do |setting|
- if setting =~ /^(\w+)=((.|\n)+)$/
- name = $1
- value = $2
- if environment.include? name
- warning(
- "Overriding environment setting '#{name}' with '#{value}'"
- )
- end
- environment[name] = value
- else
- warning "Cannot understand environment setting #{setting.inspect}"
- end
- end
- end
-
- withenv environment do
- Timeout::timeout(self[:timeout]) do
- output, status = Puppet::Util::SUIDManager.run_and_capture(
- [command], self[:user], self[:group]
- )
- end
- # The shell returns 127 if the command is missing.
- if status.exitstatus == 127
- raise ArgumentError, output
- end
- end
- end
- rescue Errno::ENOENT => detail
- self.fail detail.to_s
+ # The shell returns 127 if the command is missing.
+ if status.exitstatus == 127
+ raise ArgumentError, output
end
-
- return output, status
+ end
end
+ rescue Errno::ENOENT => detail
+ self.fail detail.to_s
+ end
- def validatecmd(cmd)
- exe = extractexe(cmd)
- # if we're not fully qualified, require a path
- self.fail "'#{cmd}' is both unqualifed and specified no search path" if File.expand_path(exe) != exe and self[:path].nil?
- end
+ return output, status
+ end
- def extractexe(cmd)
- # easy case: command was quoted
- if cmd =~ /^"([^"]+)"/
- $1
- else
- cmd.split(/ /)[0]
- end
- end
+ def validatecmd(cmd)
+ exe = extractexe(cmd)
+ # if we're not fully qualified, require a path
+ self.fail "'#{cmd}' is both unqualifed and specified no search path" if File.expand_path(exe) != exe and self[:path].nil?
+ end
+
+ def extractexe(cmd)
+ # easy case: command was quoted
+ if cmd =~ /^"([^"]+)"/
+ $1
+ else
+ cmd.split(/ /)[0]
+ end
end
+ end
end
diff --git a/lib/puppet/type/file.rb b/lib/puppet/type/file.rb
index afa990d..195e8c8 100644
--- a/lib/puppet/type/file.rb
+++ b/lib/puppet/type/file.rb
@@ -10,777 +10,777 @@ require 'puppet/network/client'
require 'puppet/util/backups'
Puppet::Type.newtype(:file) do
- include Puppet::Util::MethodHelper
- include Puppet::Util::Checksums
- include Puppet::Util::Backups
- @doc = "Manages local files, including setting ownership and
- permissions, creation of both files and directories, and
- retrieving entire files from remote servers. As Puppet matures, it
- expected that the ``file`` resource will be used less and less to
- manage content, and instead native resources will be used to do so.
-
- If you find that you are often copying files in from a central
- location, rather than using native resources, please contact
- Puppet Labs and we can hopefully work with you to develop a
- native resource to support what you are doing."
-
- def self.title_patterns
- [ [ /^(.*?)\/?$/, [ [ :path, lambda{|x| x} ] ] ] ]
- end
-
- newparam(:path) do
- desc "The path to the file to manage. Must be fully qualified."
- isnamevar
-
- validate do |value|
- # accept various path syntaxes: lone slash, posix, win32, unc
- unless (Puppet.features.posix? and (value =~ /^\/$/ or value =~ /^\/[^\/]/)) or (Puppet.features.microsoft_windows? and (value =~ /^.:\// or value =~ /^\/\/[^\/]+\/[^\/]+/))
- fail Puppet::Error, "File paths must be fully qualified, not '#{value}'"
- end
- end
-
- # convert the current path in an index into the collection and the last
- # path name. The aim is to use less storage for all common paths in a hierarchy
- munge do |value|
- path, name = File.split(value.gsub(/\/+/,'/'))
- { :index => Puppet::FileCollection.collection.index(path), :name => name }
- end
-
- # and the reverse
- unmunge do |value|
- basedir = Puppet::FileCollection.collection.path(value[:index])
- # a lone slash as :name indicates a root dir on windows
- if value[:name] == '/'
- basedir
- else
- File.join( basedir, value[:name] )
- end
- end
- end
-
- newparam(:backup) do
- desc "Whether files should be backed up before
- being replaced. The preferred method of backing files up is via
- a ``filebucket``, which stores files by their MD5 sums and allows
- easy retrieval without littering directories with backups. You
- can specify a local filebucket or a network-accessible
- server-based filebucket by setting ``backup => bucket-name``.
- Alternatively, if you specify any value that begins with a ``.``
- (e.g., ``.puppet-bak``), then Puppet will use copy the file in
- the same directory with that value as the extension of the
- backup. Setting ``backup => false`` disables all backups of the
- file in question.
-
- Puppet automatically creates a local filebucket named ``puppet`` and
- defaults to backing up there. To use a server-based filebucket,
- you must specify one in your configuration::
-
- filebucket { main:
- server => puppet
- }
-
- The ``puppet master`` daemon creates a filebucket by default,
- so you can usually back up to your main server with this
- configuration. Once you've described the bucket in your
- configuration, you can use it in any file::
-
- file { \"/my/file\":
- source => \"/path/in/nfs/or/something\",
- backup => main
- }
-
- This will back the file up to the central server.
-
- At this point, the benefits of using a filebucket are that you do not
- have backup files lying around on each of your machines, a given
- version of a file is only backed up once, and you can restore
- any given file manually, no matter how old. Eventually,
- transactional support will be able to automatically restore
- filebucketed files.
- "
-
- defaultto "puppet"
-
- munge do |value|
- # I don't really know how this is happening.
- value = value.shift if value.is_a?(Array)
-
- case value
- when false, "false", :false
- false
- when true, "true", ".puppet-bak", :true
- ".puppet-bak"
- when String
- value
- else
- self.fail "Invalid backup type #{value.inspect}"
- end
- end
- end
-
- newparam(:recurse) do
- desc "Whether and how deeply to do recursive
- management."
-
- newvalues(:true, :false, :inf, :remote, /^[0-9]+$/)
-
- # Replace the validation so that we allow numbers in
- # addition to string representations of them.
- validate { |arg| }
- munge do |value|
- newval = super(value)
- case newval
- when :true, :inf; true
- when :false; false
- when :remote; :remote
- when Integer, Fixnum, Bignum
- self.warning "Setting recursion depth with the recurse parameter is now deprecated, please use recurselimit"
-
- # recurse == 0 means no recursion
- return false if value == 0
-
- resource[:recurselimit] = value
- true
- when /^\d+$/
- self.warning "Setting recursion depth with the recurse parameter is now deprecated, please use recurselimit"
- value = Integer(value)
-
- # recurse == 0 means no recursion
- return false if value == 0
-
- resource[:recurselimit] = value
- true
- else
- self.fail "Invalid recurse value #{value.inspect}"
- end
- end
- end
-
- newparam(:recurselimit) do
- desc "How deeply to do recursive management."
-
- newvalues(/^[0-9]+$/)
-
- munge do |value|
- newval = super(value)
- case newval
- when Integer, Fixnum, Bignum; value
- when /^\d+$/; Integer(value)
- else
- self.fail "Invalid recurselimit value #{value.inspect}"
- end
- end
- end
-
- newparam(:replace, :boolean => true) do
- desc "Whether or not to replace a file that is
- sourced but exists. This is useful for using file sources
- purely for initialization."
- newvalues(:true, :false)
- aliasvalue(:yes, :true)
- aliasvalue(:no, :false)
- defaultto :true
- end
-
- newparam(:force, :boolean => true) do
- desc "Force the file operation. Currently only used when replacing
- directories with links."
- newvalues(:true, :false)
- defaultto false
- end
-
- newparam(:ignore) do
- desc "A parameter which omits action on files matching
- specified patterns during recursion. Uses Ruby's builtin globbing
- engine, so shell metacharacters are fully supported, e.g. ``[a-z]*``.
- Matches that would descend into the directory structure are ignored,
- e.g., ``*/*``."
-
- validate do |value|
- unless value.is_a?(Array) or value.is_a?(String) or value == false
- self.devfail "Ignore must be a string or an Array"
- end
- end
- end
-
- newparam(:links) do
- desc "How to handle links during file actions. During file copying,
- ``follow`` will copy the target file instead of the link, ``manage``
- will copy the link itself, and ``ignore`` will just pass it by.
- When not copying, ``manage`` and ``ignore`` behave equivalently
- (because you cannot really ignore links entirely during local recursion), and ``follow`` will manage the file to which the
- link points."
-
- newvalues(:follow, :manage)
-
- defaultto :manage
- end
-
- newparam(:purge, :boolean => true) do
- desc "Whether unmanaged files should be purged. If you have a filebucket
- configured the purged files will be uploaded, but if you do not,
- this will destroy data. Only use this option for generated
- files unless you really know what you are doing. This option only
- makes sense when recursively managing directories.
-
- Note that when using ``purge`` with ``source``, Puppet will purge any files
- that are not on the remote system."
-
- defaultto :false
-
- newvalues(:true, :false)
- end
-
- newparam(:sourceselect) do
- desc "Whether to copy all valid sources, or just the first one. This parameter
- is only used in recursive copies; by default, the first valid source is the
- only one used as a recursive source, but if this parameter is set to ``all``,
- then all valid sources will have all of their contents copied to the local host,
- and for sources that have the same file, the source earlier in the list will
- be used."
-
- defaultto :first
-
- newvalues(:first, :all)
- end
-
- # Autorequire any parent directories.
- autorequire(:file) do
- basedir = File.dirname(self[:path])
- if basedir != self[:path]
- basedir
- else
- nil
- end
- end
-
- # Autorequire the owner and group of the file.
- {:user => :owner, :group => :group}.each do |type, property|
- autorequire(type) do
- if @parameters.include?(property)
- # The user/group property automatically converts to IDs
- next unless should = @parameters[property].shouldorig
- val = should[0]
- if val.is_a?(Integer) or val =~ /^\d+$/
- nil
- else
- val
- end
- end
- end
- end
-
- CREATORS = [:content, :source, :target]
-
- validate do
- count = 0
- CREATORS.each do |param|
- count += 1 if self.should(param)
- end
- count += 1 if @parameters.include?(:source)
- self.fail "You cannot specify more than one of #{CREATORS.collect { |p| p.to_s}.join(", ")}" if count > 1
-
- self.fail "You cannot specify a remote recursion without a source" if !self[:source] and self[:recurse] == :remote
-
- self.warning "Possible error: recurselimit is set but not recurse, no recursion will happen" if !self[:recurse] and self[:recurselimit]
- end
-
- def self.[](path)
- return nil unless path
- super(path.gsub(/\/+/, '/').sub(/\/$/, ''))
- end
-
- # List files, but only one level deep.
- def self.instances(base = "/")
- return [] unless FileTest.directory?(base)
-
- files = []
- Dir.entries(base).reject { |e|
- e == "." or e == ".."
- }.each do |name|
- path = File.join(base, name)
- if obj = self[path]
- obj[:audit] = :all
- files << obj
- else
- files << self.new(
- :name => path, :audit => :all
- )
- end
- end
- files
- end
-
- @depthfirst = false
-
- # Determine the user to write files as.
- def asuser
- if self.should(:owner) and ! self.should(:owner).is_a?(Symbol)
- writeable = Puppet::Util::SUIDManager.asuser(self.should(:owner)) {
- FileTest.writable?(File.dirname(self[:path]))
- }
-
- # If the parent directory is writeable, then we execute
- # as the user in question. Otherwise we'll rely on
- # the 'owner' property to do things.
- asuser = self.should(:owner) if writeable
- end
-
- asuser
- end
-
- def bucket
- return @bucket if @bucket
-
- backup = self[:backup]
- return nil unless backup
- return nil if backup =~ /^\./
-
- unless catalog or backup == "puppet"
- fail "Can not find filebucket for backups without a catalog"
- end
-
- unless catalog and filebucket = catalog.resource(:filebucket, backup) or backup == "puppet"
- fail "Could not find filebucket #{backup} specified in backup"
- end
-
- return default_bucket unless filebucket
-
- @bucket = filebucket.bucket
-
- @bucket
- end
-
- def default_bucket
- Puppet::Type.type(:filebucket).mkdefaultbucket.bucket
- end
-
- # Does the file currently exist? Just checks for whether
- # we have a stat
- def exist?
- stat ? true : false
- end
-
- # We have to do some extra finishing, to retrieve our bucket if
- # there is one.
- def finish
- # Look up our bucket, if there is one
- bucket
- super
- end
-
- # Create any children via recursion or whatever.
- def eval_generate
- return [] unless self.recurse?
-
- recurse
- #recurse.reject do |resource|
- # catalog.resource(:file, resource[:path])
- #end.each do |child|
- # catalog.add_resource child
- # catalog.relationship_graph.add_edge self, child
- #end
- end
-
- def flush
- # We want to make sure we retrieve metadata anew on each transaction.
- @parameters.each do |name, param|
- param.flush if param.respond_to?(:flush)
- end
- @stat = nil
- end
-
- def initialize(hash)
- # Used for caching clients
- @clients = {}
-
- super
-
- # If they've specified a source, we get our 'should' values
- # from it.
- unless self[:ensure]
- if self[:target]
- self[:ensure] = :symlink
- elsif self[:content]
- self[:ensure] = :file
- end
- end
-
- @stat = nil
- end
-
- # Configure discovered resources to be purged.
- def mark_children_for_purging(children)
- children.each do |name, child|
- next if child[:source]
- child[:ensure] = :absent
- end
- end
-
- # Create a new file or directory object as a child to the current
- # object.
- def newchild(path)
- full_path = File.join(self[:path], path)
-
- # Add some new values to our original arguments -- these are the ones
- # set at initialization. We specifically want to exclude any param
- # values set by the :source property or any default values.
- # LAK:NOTE This is kind of silly, because the whole point here is that
- # the values set at initialization should live as long as the resource
- # but values set by default or by :source should only live for the transaction
- # or so. Unfortunately, we don't have a straightforward way to manage
- # the different lifetimes of this data, so we kludge it like this.
- # The right-side hash wins in the merge.
- options = @original_parameters.merge(:path => full_path).reject { |param, value| value.nil? }
-
- # These should never be passed to our children.
- [:parent, :ensure, :recurse, :recurselimit, :target, :alias, :source].each do |param|
- options.delete(param) if options.include?(param)
- end
-
- self.class.new(options)
- end
-
- # Files handle paths specially, because they just lengthen their
- # path names, rather than including the full parent's title each
- # time.
- def pathbuilder
- # We specifically need to call the method here, so it looks
- # up our parent in the catalog graph.
- if parent = parent()
- # We only need to behave specially when our parent is also
- # a file
- if parent.is_a?(self.class)
- # Remove the parent file name
- list = parent.pathbuilder
- list.pop # remove the parent's path info
- return list << self.ref
- else
- return super
- end
+ include Puppet::Util::MethodHelper
+ include Puppet::Util::Checksums
+ include Puppet::Util::Backups
+ @doc = "Manages local files, including setting ownership and
+ permissions, creation of both files and directories, and
+ retrieving entire files from remote servers. As Puppet matures, it
+ expected that the ``file`` resource will be used less and less to
+ manage content, and instead native resources will be used to do so.
+
+ If you find that you are often copying files in from a central
+ location, rather than using native resources, please contact
+ Puppet Labs and we can hopefully work with you to develop a
+ native resource to support what you are doing."
+
+ def self.title_patterns
+ [ [ /^(.*?)\/?$/, [ [ :path, lambda{|x| x} ] ] ] ]
+ end
+
+ newparam(:path) do
+ desc "The path to the file to manage. Must be fully qualified."
+ isnamevar
+
+ validate do |value|
+ # accept various path syntaxes: lone slash, posix, win32, unc
+ unless (Puppet.features.posix? and (value =~ /^\/$/ or value =~ /^\/[^\/]/)) or (Puppet.features.microsoft_windows? and (value =~ /^.:\// or value =~ /^\/\/[^\/]+\/[^\/]+/))
+ fail Puppet::Error, "File paths must be fully qualified, not '#{value}'"
+ end
+ end
+
+ # convert the current path in an index into the collection and the last
+ # path name. The aim is to use less storage for all common paths in a hierarchy
+ munge do |value|
+ path, name = File.split(value.gsub(/\/+/,'/'))
+ { :index => Puppet::FileCollection.collection.index(path), :name => name }
+ end
+
+ # and the reverse
+ unmunge do |value|
+ basedir = Puppet::FileCollection.collection.path(value[:index])
+ # a lone slash as :name indicates a root dir on windows
+ if value[:name] == '/'
+ basedir
+ else
+ File.join( basedir, value[:name] )
+ end
+ end
+ end
+
+ newparam(:backup) do
+ desc "Whether files should be backed up before
+ being replaced. The preferred method of backing files up is via
+ a ``filebucket``, which stores files by their MD5 sums and allows
+ easy retrieval without littering directories with backups. You
+ can specify a local filebucket or a network-accessible
+ server-based filebucket by setting ``backup => bucket-name``.
+ Alternatively, if you specify any value that begins with a ``.``
+ (e.g., ``.puppet-bak``), then Puppet will use copy the file in
+ the same directory with that value as the extension of the
+ backup. Setting ``backup => false`` disables all backups of the
+ file in question.
+
+ Puppet automatically creates a local filebucket named ``puppet`` and
+ defaults to backing up there. To use a server-based filebucket,
+ you must specify one in your configuration::
+
+ filebucket { main:
+ server => puppet
+ }
+
+ The ``puppet master`` daemon creates a filebucket by default,
+ so you can usually back up to your main server with this
+ configuration. Once you've described the bucket in your
+ configuration, you can use it in any file::
+
+ file { \"/my/file\":
+ source => \"/path/in/nfs/or/something\",
+ backup => main
+ }
+
+ This will back the file up to the central server.
+
+ At this point, the benefits of using a filebucket are that you do not
+ have backup files lying around on each of your machines, a given
+ version of a file is only backed up once, and you can restore
+ any given file manually, no matter how old. Eventually,
+ transactional support will be able to automatically restore
+ filebucketed files.
+ "
+
+ defaultto "puppet"
+
+ munge do |value|
+ # I don't really know how this is happening.
+ value = value.shift if value.is_a?(Array)
+
+ case value
+ when false, "false", :false
+ false
+ when true, "true", ".puppet-bak", :true
+ ".puppet-bak"
+ when String
+ value
+ else
+ self.fail "Invalid backup type #{value.inspect}"
+ end
+ end
+ end
+
+ newparam(:recurse) do
+ desc "Whether and how deeply to do recursive
+ management."
+
+ newvalues(:true, :false, :inf, :remote, /^[0-9]+$/)
+
+ # Replace the validation so that we allow numbers in
+ # addition to string representations of them.
+ validate { |arg| }
+ munge do |value|
+ newval = super(value)
+ case newval
+ when :true, :inf; true
+ when :false; false
+ when :remote; :remote
+ when Integer, Fixnum, Bignum
+ self.warning "Setting recursion depth with the recurse parameter is now deprecated, please use recurselimit"
+
+ # recurse == 0 means no recursion
+ return false if value == 0
+
+ resource[:recurselimit] = value
+ true
+ when /^\d+$/
+ self.warning "Setting recursion depth with the recurse parameter is now deprecated, please use recurselimit"
+ value = Integer(value)
+
+ # recurse == 0 means no recursion
+ return false if value == 0
+
+ resource[:recurselimit] = value
+ true
+ else
+ self.fail "Invalid recurse value #{value.inspect}"
+ end
+ end
+ end
+
+ newparam(:recurselimit) do
+ desc "How deeply to do recursive management."
+
+ newvalues(/^[0-9]+$/)
+
+ munge do |value|
+ newval = super(value)
+ case newval
+ when Integer, Fixnum, Bignum; value
+ when /^\d+$/; Integer(value)
+ else
+ self.fail "Invalid recurselimit value #{value.inspect}"
+ end
+ end
+ end
+
+ newparam(:replace, :boolean => true) do
+ desc "Whether or not to replace a file that is
+ sourced but exists. This is useful for using file sources
+ purely for initialization."
+ newvalues(:true, :false)
+ aliasvalue(:yes, :true)
+ aliasvalue(:no, :false)
+ defaultto :true
+ end
+
+ newparam(:force, :boolean => true) do
+ desc "Force the file operation. Currently only used when replacing
+ directories with links."
+ newvalues(:true, :false)
+ defaultto false
+ end
+
+ newparam(:ignore) do
+ desc "A parameter which omits action on files matching
+ specified patterns during recursion. Uses Ruby's builtin globbing
+ engine, so shell metacharacters are fully supported, e.g. ``[a-z]*``.
+ Matches that would descend into the directory structure are ignored,
+ e.g., ``*/*``."
+
+ validate do |value|
+ unless value.is_a?(Array) or value.is_a?(String) or value == false
+ self.devfail "Ignore must be a string or an Array"
+ end
+ end
+ end
+
+ newparam(:links) do
+ desc "How to handle links during file actions. During file copying,
+ ``follow`` will copy the target file instead of the link, ``manage``
+ will copy the link itself, and ``ignore`` will just pass it by.
+ When not copying, ``manage`` and ``ignore`` behave equivalently
+ (because you cannot really ignore links entirely during local recursion), and ``follow`` will manage the file to which the
+ link points."
+
+ newvalues(:follow, :manage)
+
+ defaultto :manage
+ end
+
+ newparam(:purge, :boolean => true) do
+ desc "Whether unmanaged files should be purged. If you have a filebucket
+ configured the purged files will be uploaded, but if you do not,
+ this will destroy data. Only use this option for generated
+ files unless you really know what you are doing. This option only
+ makes sense when recursively managing directories.
+
+ Note that when using ``purge`` with ``source``, Puppet will purge any files
+ that are not on the remote system."
+
+ defaultto :false
+
+ newvalues(:true, :false)
+ end
+
+ newparam(:sourceselect) do
+ desc "Whether to copy all valid sources, or just the first one. This parameter
+ is only used in recursive copies; by default, the first valid source is the
+ only one used as a recursive source, but if this parameter is set to ``all``,
+ then all valid sources will have all of their contents copied to the local host,
+ and for sources that have the same file, the source earlier in the list will
+ be used."
+
+ defaultto :first
+
+ newvalues(:first, :all)
+ end
+
+ # Autorequire any parent directories.
+ autorequire(:file) do
+ basedir = File.dirname(self[:path])
+ if basedir != self[:path]
+ basedir
+ else
+ nil
+ end
+ end
+
+ # Autorequire the owner and group of the file.
+ {:user => :owner, :group => :group}.each do |type, property|
+ autorequire(type) do
+ if @parameters.include?(property)
+ # The user/group property automatically converts to IDs
+ next unless should = @parameters[property].shouldorig
+ val = should[0]
+ if val.is_a?(Integer) or val =~ /^\d+$/
+ nil
else
- return [self.ref]
- end
- end
-
- # Should we be purging?
- def purge?
- @parameters.include?(:purge) and (self[:purge] == :true or self[:purge] == "true")
- end
-
- # Recursively generate a list of file resources, which will
- # be used to copy remote files, manage local files, and/or make links
- # to map to another directory.
- def recurse
- children = {}
- children = recurse_local if self[:recurse] != :remote
-
- if self[:target]
- recurse_link(children)
- elsif self[:source]
- recurse_remote(children)
- end
-
- # If we're purging resources, then delete any resource that isn't on the
- # remote system.
- mark_children_for_purging(children) if self.purge?
-
- result = children.values.sort { |a, b| a[:path] <=> b[:path] }
- remove_less_specific_files(result)
- end
-
- # This is to fix bug #2296, where two files recurse over the same
- # set of files. It's a rare case, and when it does happen you're
- # not likely to have many actual conflicts, which is good, because
- # this is a pretty inefficient implementation.
- def remove_less_specific_files(files)
- mypath = self[:path].split(File::Separator)
- other_paths = catalog.vertices.
- select { |r| r.is_a?(self.class) and r[:path] != self[:path] }.
- collect { |r| r[:path].split(File::Separator) }.
- select { |p| p[0,mypath.length] == mypath }
-
- return files if other_paths.empty?
-
- files.reject { |file|
- path = file[:path].split(File::Separator)
- other_paths.any? { |p| path[0,p.length] == p }
- }
- end
-
- # A simple method for determining whether we should be recursing.
- def recurse?
- return false unless @parameters.include?(:recurse)
-
- val = @parameters[:recurse].value
-
- !!(val and (val == true or val == :remote))
- end
-
- # Recurse the target of the link.
- def recurse_link(children)
- perform_recursion(self[:target]).each do |meta|
- if meta.relative_path == "."
- self[:ensure] = :directory
- next
- end
-
- children[meta.relative_path] ||= newchild(meta.relative_path)
- if meta.ftype == "directory"
- children[meta.relative_path][:ensure] = :directory
- else
- children[meta.relative_path][:ensure] = :link
- children[meta.relative_path][:target] = meta.full_path
- end
+ val
end
- children
+ end
end
+ end
- # Recurse the file itself, returning a Metadata instance for every found file.
- def recurse_local
- result = perform_recursion(self[:path])
- return {} unless result
- result.inject({}) do |hash, meta|
- next hash if meta.relative_path == "."
+ CREATORS = [:content, :source, :target]
- hash[meta.relative_path] = newchild(meta.relative_path)
- hash
- end
+ validate do
+ count = 0
+ CREATORS.each do |param|
+ count += 1 if self.should(param)
end
+ count += 1 if @parameters.include?(:source)
+ self.fail "You cannot specify more than one of #{CREATORS.collect { |p| p.to_s}.join(", ")}" if count > 1
- # Recurse against our remote file.
- def recurse_remote(children)
- sourceselect = self[:sourceselect]
-
- total = self[:source].collect do |source|
- next unless result = perform_recursion(source)
- return if top = result.find { |r| r.relative_path == "." } and top.ftype != "directory"
- result.each { |data| data.source = "#{source}/#{data.relative_path}" }
- break result if result and ! result.empty? and sourceselect == :first
- result
- end.flatten
-
- # This only happens if we have sourceselect == :all
- unless sourceselect == :first
- found = []
- total.reject! do |data|
- result = found.include?(data.relative_path)
- found << data.relative_path unless found.include?(data.relative_path)
- result
- end
- end
-
- total.each do |meta|
- if meta.relative_path == "."
- parameter(:source).metadata = meta
- next
- end
- children[meta.relative_path] ||= newchild(meta.relative_path)
- children[meta.relative_path][:source] = meta.source
- children[meta.relative_path][:checksum] = :md5 if meta.ftype == "file"
+ self.fail "You cannot specify a remote recursion without a source" if !self[:source] and self[:recurse] == :remote
- children[meta.relative_path].parameter(:source).metadata = meta
- end
-
- children
- end
+ self.warning "Possible error: recurselimit is set but not recurse, no recursion will happen" if !self[:recurse] and self[:recurselimit]
+ end
- def perform_recursion(path)
+ def self.[](path)
+ return nil unless path
+ super(path.gsub(/\/+/, '/').sub(/\/$/, ''))
+ end
- Puppet::FileServing::Metadata.search(
+ # List files, but only one level deep.
+ def self.instances(base = "/")
+ return [] unless FileTest.directory?(base)
- path,
- :links => self[:links],
- :recurse => (self[:recurse] == :remote ? true : self[:recurse]),
-
- :recurselimit => self[:recurselimit],
- :ignore => self[:ignore],
- :checksum_type => (self[:source] || self[:content]) ? self[:checksum] : :none
+ files = []
+ Dir.entries(base).reject { |e|
+ e == "." or e == ".."
+ }.each do |name|
+ path = File.join(base, name)
+ if obj = self[path]
+ obj[:audit] = :all
+ files << obj
+ else
+ files << self.new(
+ :name => path, :audit => :all
)
+ end
end
+ files
+ end
- # Remove any existing data. This is only used when dealing with
- # links or directories.
- def remove_existing(should)
- return unless s = stat
-
- self.fail "Could not back up; will not replace" unless perform_backup
-
- unless should.to_s == "link"
- return if s.ftype.to_s == should.to_s
- end
-
- case s.ftype
- when "directory"
- if self[:force] == :true
- debug "Removing existing directory for replacement with #{should}"
- FileUtils.rmtree(self[:path])
- else
- notice "Not removing directory; use 'force' to override"
- end
- when "link", "file"
- debug "Removing existing #{s.ftype} for replacement with #{should}"
- File.unlink(self[:path])
- else
- self.fail "Could not back up files of type #{s.ftype}"
- end
- expire
- end
-
- def retrieve
- if source = parameter(:source)
- source.copy_source_values
- end
- super
- end
-
- # Set the checksum, from another property. There are multiple
- # properties that modify the contents of a file, and they need the
- # ability to make sure that the checksum value is in sync.
- def setchecksum(sum = nil)
- if @parameters.include? :checksum
- if sum
- @parameters[:checksum].checksum = sum
- else
- # If they didn't pass in a sum, then tell checksum to
- # figure it out.
- currentvalue = @parameters[:checksum].retrieve
- @parameters[:checksum].checksum = currentvalue
- end
- end
- end
-
- # Should this thing be a normal file? This is a relatively complex
- # way of determining whether we're trying to create a normal file,
- # and it's here so that the logic isn't visible in the content property.
- def should_be_file?
- return true if self[:ensure] == :file
-
- # I.e., it's set to something like "directory"
- return false if e = self[:ensure] and e != :present
-
- # The user doesn't really care, apparently
- if self[:ensure] == :present
- return true unless s = stat
- return(s.ftype == "file" ? true : false)
- end
-
- # If we've gotten here, then :ensure isn't set
- return true if self[:content]
- return true if stat and stat.ftype == "file"
- false
- end
-
- # Stat our file. Depending on the value of the 'links' attribute, we
- # use either 'stat' or 'lstat', and we expect the properties to use the
- # resulting stat object accordingly (mostly by testing the 'ftype'
- # value).
- cached_attr(:stat) do
- method = :stat
-
- # Files are the only types that support links
- if (self.class.name == :file and self[:links] != :follow) or self.class.name == :tidy
- method = :lstat
- end
- path = self[:path]
-
- begin
- File.send(method, self[:path])
- rescue Errno::ENOENT => error
- return nil
- rescue Errno::EACCES => error
- warning "Could not stat; permission denied"
- return nil
- end
- end
-
- # We have to hack this just a little bit, because otherwise we'll get
- # an error when the target and the contents are created as properties on
- # the far side.
- def to_trans(retrieve = true)
- obj = super
- obj.delete(:target) if obj[:target] == :notlink
- obj
- end
-
- # Write out the file. Requires the property name for logging.
- # Write will be done by the content property, along with checksum computation
- def write(property)
- remove_existing(:file)
+ @depthfirst = false
- use_temporary_file = write_temporary_file?
- if use_temporary_file
- path = "#{self[:path]}.puppettmp_#{rand(10000)}"
- path = "#{self[:path]}.puppettmp_#{rand(10000)}" while File.exists?(path) or File.symlink?(path)
- else
- path = self[:path]
- end
-
- mode = self.should(:mode) # might be nil
- umask = mode ? 000 : 022
-
- content_checksum = Puppet::Util.withumask(umask) { File.open(path, 'w', mode) { |f| write_content(f) } }
-
- # And put our new file in place
- if use_temporary_file # This is only not true when our file is empty.
- begin
- fail_if_checksum_is_wrong(path, content_checksum) if validate_checksum?
- File.rename(path, self[:path])
- rescue => detail
- fail "Could not rename temporary file #{path} to #{self[:path]}: #{detail}"
- ensure
- # Make sure the created file gets removed
- File.unlink(path) if FileTest.exists?(path)
- end
- end
-
- # make sure all of the modes are actually correct
- property_fix
+ # Determine the user to write files as.
+ def asuser
+ if self.should(:owner) and ! self.should(:owner).is_a?(Symbol)
+ writeable = Puppet::Util::SUIDManager.asuser(self.should(:owner)) {
+ FileTest.writable?(File.dirname(self[:path]))
+ }
+ # If the parent directory is writeable, then we execute
+ # as the user in question. Otherwise we'll rely on
+ # the 'owner' property to do things.
+ asuser = self.should(:owner) if writeable
end
- private
+ asuser
+ end
- # Should we validate the checksum of the file we're writing?
- def validate_checksum?
- self[:checksum] !~ /time/
- end
+ def bucket
+ return @bucket if @bucket
- # Make sure the file we wrote out is what we think it is.
- def fail_if_checksum_is_wrong(path, content_checksum)
- newsum = parameter(:checksum).sum_file(path)
- return if [:absent, nil, content_checksum].include?(newsum)
+ backup = self[:backup]
+ return nil unless backup
+ return nil if backup =~ /^\./
- self.fail "File written to disk did not match checksum; discarding changes (#{content_checksum} vs #{newsum})"
+ unless catalog or backup == "puppet"
+ fail "Can not find filebucket for backups without a catalog"
end
- # write the current content. Note that if there is no content property
- # simply opening the file with 'w' as done in write is enough to truncate
- # or write an empty length file.
- def write_content(file)
- (content = property(:content)) && content.write(file)
+ unless catalog and filebucket = catalog.resource(:filebucket, backup) or backup == "puppet"
+ fail "Could not find filebucket #{backup} specified in backup"
end
- private
-
- def write_temporary_file?
- # unfortunately we don't know the source file size before fetching it
- # so let's assume the file won't be empty
- (c = property(:content) and c.length) || (s = @parameters[:source] and 1)
- end
+ return default_bucket unless filebucket
- # There are some cases where all of the work does not get done on
- # file creation/modification, so we have to do some extra checking.
- def property_fix
- properties.each do |thing|
- next unless [:mode, :owner, :group, :seluser, :selrole, :seltype, :selrange].include?(thing.name)
+ @bucket = filebucket.bucket
- # Make sure we get a new stat objct
- expire
- currentvalue = thing.retrieve
- thing.sync unless thing.insync?(currentvalue)
- end
- end
+ @bucket
+ end
+
+ def default_bucket
+ Puppet::Type.type(:filebucket).mkdefaultbucket.bucket
+ end
+
+ # Does the file currently exist? Just checks for whether
+ # we have a stat
+ def exist?
+ stat ? true : false
+ end
+
+ # We have to do some extra finishing, to retrieve our bucket if
+ # there is one.
+ def finish
+ # Look up our bucket, if there is one
+ bucket
+ super
+ end
+
+ # Create any children via recursion or whatever.
+ def eval_generate
+ return [] unless self.recurse?
+
+ recurse
+ #recurse.reject do |resource|
+ # catalog.resource(:file, resource[:path])
+ #end.each do |child|
+ # catalog.add_resource child
+ # catalog.relationship_graph.add_edge self, child
+ #end
+ end
+
+ def flush
+ # We want to make sure we retrieve metadata anew on each transaction.
+ @parameters.each do |name, param|
+ param.flush if param.respond_to?(:flush)
+ end
+ @stat = nil
+ end
+
+ def initialize(hash)
+ # Used for caching clients
+ @clients = {}
+
+ super
+
+ # If they've specified a source, we get our 'should' values
+ # from it.
+ unless self[:ensure]
+ if self[:target]
+ self[:ensure] = :symlink
+ elsif self[:content]
+ self[:ensure] = :file
+ end
+ end
+
+ @stat = nil
+ end
+
+ # Configure discovered resources to be purged.
+ def mark_children_for_purging(children)
+ children.each do |name, child|
+ next if child[:source]
+ child[:ensure] = :absent
+ end
+ end
+
+ # Create a new file or directory object as a child to the current
+ # object.
+ def newchild(path)
+ full_path = File.join(self[:path], path)
+
+ # Add some new values to our original arguments -- these are the ones
+ # set at initialization. We specifically want to exclude any param
+ # values set by the :source property or any default values.
+ # LAK:NOTE This is kind of silly, because the whole point here is that
+ # the values set at initialization should live as long as the resource
+ # but values set by default or by :source should only live for the transaction
+ # or so. Unfortunately, we don't have a straightforward way to manage
+ # the different lifetimes of this data, so we kludge it like this.
+ # The right-side hash wins in the merge.
+ options = @original_parameters.merge(:path => full_path).reject { |param, value| value.nil? }
+
+ # These should never be passed to our children.
+ [:parent, :ensure, :recurse, :recurselimit, :target, :alias, :source].each do |param|
+ options.delete(param) if options.include?(param)
+ end
+
+ self.class.new(options)
+ end
+
+ # Files handle paths specially, because they just lengthen their
+ # path names, rather than including the full parent's title each
+ # time.
+ def pathbuilder
+ # We specifically need to call the method here, so it looks
+ # up our parent in the catalog graph.
+ if parent = parent()
+ # We only need to behave specially when our parent is also
+ # a file
+ if parent.is_a?(self.class)
+ # Remove the parent file name
+ list = parent.pathbuilder
+ list.pop # remove the parent's path info
+ return list << self.ref
+ else
+ return super
+ end
+ else
+ return [self.ref]
+ end
+ end
+
+ # Should we be purging?
+ def purge?
+ @parameters.include?(:purge) and (self[:purge] == :true or self[:purge] == "true")
+ end
+
+ # Recursively generate a list of file resources, which will
+ # be used to copy remote files, manage local files, and/or make links
+ # to map to another directory.
+ def recurse
+ children = {}
+ children = recurse_local if self[:recurse] != :remote
+
+ if self[:target]
+ recurse_link(children)
+ elsif self[:source]
+ recurse_remote(children)
+ end
+
+ # If we're purging resources, then delete any resource that isn't on the
+ # remote system.
+ mark_children_for_purging(children) if self.purge?
+
+ result = children.values.sort { |a, b| a[:path] <=> b[:path] }
+ remove_less_specific_files(result)
+ end
+
+ # This is to fix bug #2296, where two files recurse over the same
+ # set of files. It's a rare case, and when it does happen you're
+ # not likely to have many actual conflicts, which is good, because
+ # this is a pretty inefficient implementation.
+ def remove_less_specific_files(files)
+ mypath = self[:path].split(File::Separator)
+ other_paths = catalog.vertices.
+ select { |r| r.is_a?(self.class) and r[:path] != self[:path] }.
+ collect { |r| r[:path].split(File::Separator) }.
+ select { |p| p[0,mypath.length] == mypath }
+
+ return files if other_paths.empty?
+
+ files.reject { |file|
+ path = file[:path].split(File::Separator)
+ other_paths.any? { |p| path[0,p.length] == p }
+ }
+ end
+
+ # A simple method for determining whether we should be recursing.
+ def recurse?
+ return false unless @parameters.include?(:recurse)
+
+ val = @parameters[:recurse].value
+
+ !!(val and (val == true or val == :remote))
+ end
+
+ # Recurse the target of the link.
+ def recurse_link(children)
+ perform_recursion(self[:target]).each do |meta|
+ if meta.relative_path == "."
+ self[:ensure] = :directory
+ next
+ end
+
+ children[meta.relative_path] ||= newchild(meta.relative_path)
+ if meta.ftype == "directory"
+ children[meta.relative_path][:ensure] = :directory
+ else
+ children[meta.relative_path][:ensure] = :link
+ children[meta.relative_path][:target] = meta.full_path
+ end
+ end
+ children
+ end
+
+ # Recurse the file itself, returning a Metadata instance for every found file.
+ def recurse_local
+ result = perform_recursion(self[:path])
+ return {} unless result
+ result.inject({}) do |hash, meta|
+ next hash if meta.relative_path == "."
+
+ hash[meta.relative_path] = newchild(meta.relative_path)
+ hash
+ end
+ end
+
+ # Recurse against our remote file.
+ def recurse_remote(children)
+ sourceselect = self[:sourceselect]
+
+ total = self[:source].collect do |source|
+ next unless result = perform_recursion(source)
+ return if top = result.find { |r| r.relative_path == "." } and top.ftype != "directory"
+ result.each { |data| data.source = "#{source}/#{data.relative_path}" }
+ break result if result and ! result.empty? and sourceselect == :first
+ result
+ end.flatten
+
+ # This only happens if we have sourceselect == :all
+ unless sourceselect == :first
+ found = []
+ total.reject! do |data|
+ result = found.include?(data.relative_path)
+ found << data.relative_path unless found.include?(data.relative_path)
+ result
+ end
+ end
+
+ total.each do |meta|
+ if meta.relative_path == "."
+ parameter(:source).metadata = meta
+ next
+ end
+ children[meta.relative_path] ||= newchild(meta.relative_path)
+ children[meta.relative_path][:source] = meta.source
+ children[meta.relative_path][:checksum] = :md5 if meta.ftype == "file"
+
+ children[meta.relative_path].parameter(:source).metadata = meta
+ end
+
+ children
+ end
+
+ def perform_recursion(path)
+
+ Puppet::FileServing::Metadata.search(
+
+ path,
+ :links => self[:links],
+ :recurse => (self[:recurse] == :remote ? true : self[:recurse]),
+
+ :recurselimit => self[:recurselimit],
+ :ignore => self[:ignore],
+ :checksum_type => (self[:source] || self[:content]) ? self[:checksum] : :none
+ )
+ end
+
+ # Remove any existing data. This is only used when dealing with
+ # links or directories.
+ def remove_existing(should)
+ return unless s = stat
+
+ self.fail "Could not back up; will not replace" unless perform_backup
+
+ unless should.to_s == "link"
+ return if s.ftype.to_s == should.to_s
+ end
+
+ case s.ftype
+ when "directory"
+ if self[:force] == :true
+ debug "Removing existing directory for replacement with #{should}"
+ FileUtils.rmtree(self[:path])
+ else
+ notice "Not removing directory; use 'force' to override"
+ end
+ when "link", "file"
+ debug "Removing existing #{s.ftype} for replacement with #{should}"
+ File.unlink(self[:path])
+ else
+ self.fail "Could not back up files of type #{s.ftype}"
+ end
+ expire
+ end
+
+ def retrieve
+ if source = parameter(:source)
+ source.copy_source_values
+ end
+ super
+ end
+
+ # Set the checksum, from another property. There are multiple
+ # properties that modify the contents of a file, and they need the
+ # ability to make sure that the checksum value is in sync.
+ def setchecksum(sum = nil)
+ if @parameters.include? :checksum
+ if sum
+ @parameters[:checksum].checksum = sum
+ else
+ # If they didn't pass in a sum, then tell checksum to
+ # figure it out.
+ currentvalue = @parameters[:checksum].retrieve
+ @parameters[:checksum].checksum = currentvalue
+ end
+ end
+ end
+
+ # Should this thing be a normal file? This is a relatively complex
+ # way of determining whether we're trying to create a normal file,
+ # and it's here so that the logic isn't visible in the content property.
+ def should_be_file?
+ return true if self[:ensure] == :file
+
+ # I.e., it's set to something like "directory"
+ return false if e = self[:ensure] and e != :present
+
+ # The user doesn't really care, apparently
+ if self[:ensure] == :present
+ return true unless s = stat
+ return(s.ftype == "file" ? true : false)
+ end
+
+ # If we've gotten here, then :ensure isn't set
+ return true if self[:content]
+ return true if stat and stat.ftype == "file"
+ false
+ end
+
+ # Stat our file. Depending on the value of the 'links' attribute, we
+ # use either 'stat' or 'lstat', and we expect the properties to use the
+ # resulting stat object accordingly (mostly by testing the 'ftype'
+ # value).
+ cached_attr(:stat) do
+ method = :stat
+
+ # Files are the only types that support links
+ if (self.class.name == :file and self[:links] != :follow) or self.class.name == :tidy
+ method = :lstat
+ end
+ path = self[:path]
+
+ begin
+ File.send(method, self[:path])
+ rescue Errno::ENOENT => error
+ return nil
+ rescue Errno::EACCES => error
+ warning "Could not stat; permission denied"
+ return nil
+ end
+ end
+
+ # We have to hack this just a little bit, because otherwise we'll get
+ # an error when the target and the contents are created as properties on
+ # the far side.
+ def to_trans(retrieve = true)
+ obj = super
+ obj.delete(:target) if obj[:target] == :notlink
+ obj
+ end
+
+ # Write out the file. Requires the property name for logging.
+ # Write will be done by the content property, along with checksum computation
+ def write(property)
+ remove_existing(:file)
+
+ use_temporary_file = write_temporary_file?
+ if use_temporary_file
+ path = "#{self[:path]}.puppettmp_#{rand(10000)}"
+ path = "#{self[:path]}.puppettmp_#{rand(10000)}" while File.exists?(path) or File.symlink?(path)
+ else
+ path = self[:path]
+ end
+
+ mode = self.should(:mode) # might be nil
+ umask = mode ? 000 : 022
+
+ content_checksum = Puppet::Util.withumask(umask) { File.open(path, 'w', mode) { |f| write_content(f) } }
+
+ # And put our new file in place
+ if use_temporary_file # This is only not true when our file is empty.
+ begin
+ fail_if_checksum_is_wrong(path, content_checksum) if validate_checksum?
+ File.rename(path, self[:path])
+ rescue => detail
+ fail "Could not rename temporary file #{path} to #{self[:path]}: #{detail}"
+ ensure
+ # Make sure the created file gets removed
+ File.unlink(path) if FileTest.exists?(path)
+ end
+ end
+
+ # make sure all of the modes are actually correct
+ property_fix
+
+ end
+
+ private
+
+ # Should we validate the checksum of the file we're writing?
+ def validate_checksum?
+ self[:checksum] !~ /time/
+ end
+
+ # Make sure the file we wrote out is what we think it is.
+ def fail_if_checksum_is_wrong(path, content_checksum)
+ newsum = parameter(:checksum).sum_file(path)
+ return if [:absent, nil, content_checksum].include?(newsum)
+
+ self.fail "File written to disk did not match checksum; discarding changes (#{content_checksum} vs #{newsum})"
+ end
+
+ # write the current content. Note that if there is no content property
+ # simply opening the file with 'w' as done in write is enough to truncate
+ # or write an empty length file.
+ def write_content(file)
+ (content = property(:content)) && content.write(file)
+ end
+
+ private
+
+ def write_temporary_file?
+ # unfortunately we don't know the source file size before fetching it
+ # so let's assume the file won't be empty
+ (c = property(:content) and c.length) || (s = @parameters[:source] and 1)
+ end
+
+ # There are some cases where all of the work does not get done on
+ # file creation/modification, so we have to do some extra checking.
+ def property_fix
+ properties.each do |thing|
+ next unless [:mode, :owner, :group, :seluser, :selrole, :seltype, :selrange].include?(thing.name)
+
+ # Make sure we get a new stat objct
+ expire
+ currentvalue = thing.retrieve
+ thing.sync unless thing.insync?(currentvalue)
+ end
+ end
end
# We put all of the properties in separate files, because there are so many
diff --git a/lib/puppet/type/file/checksum.rb b/lib/puppet/type/file/checksum.rb
index 3e2fdbf..7324607 100755
--- a/lib/puppet/type/file/checksum.rb
+++ b/lib/puppet/type/file/checksum.rb
@@ -3,31 +3,31 @@ require 'puppet/util/checksums'
# Specify which checksum algorithm to use when checksumming
# files.
Puppet::Type.type(:file).newparam(:checksum) do
- include Puppet::Util::Checksums
+ include Puppet::Util::Checksums
- desc "The checksum type to use when checksumming a file.
+ desc "The checksum type to use when checksumming a file.
- The default checksum parameter, if checksums are enabled, is md5."
+ The default checksum parameter, if checksums are enabled, is md5."
- newvalues "md5", "md5lite", "timestamp", "mtime", "time", "none"
+ newvalues "md5", "md5lite", "timestamp", "mtime", "time", "none"
- defaultto :md5
+ defaultto :md5
- def sum(content)
- type = value || :md5 # because this might be called before defaults are set
- "{#{type}}" + send(type, content)
- end
+ def sum(content)
+ type = value || :md5 # because this might be called before defaults are set
+ "{#{type}}" + send(type, content)
+ end
- def sum_file(path)
- type = value || :md5 # because this might be called before defaults are set
- method = type.to_s + "_file"
- "{#{type}}" + send(method, path).to_s
- end
+ def sum_file(path)
+ type = value || :md5 # because this might be called before defaults are set
+ method = type.to_s + "_file"
+ "{#{type}}" + send(method, path).to_s
+ end
- def sum_stream(&block)
- type = value || :md5 # same comment as above
- method = type.to_s + "_stream"
- checksum = send(method, &block)
- "{#{type}}#{checksum}"
- end
+ def sum_stream(&block)
+ type = value || :md5 # same comment as above
+ method = type.to_s + "_stream"
+ checksum = send(method, &block)
+ "{#{type}}#{checksum}"
+ end
end
diff --git a/lib/puppet/type/file/content.rb b/lib/puppet/type/file/content.rb
index 472fdb4..74b380f 100755
--- a/lib/puppet/type/file/content.rb
+++ b/lib/puppet/type/file/content.rb
@@ -7,204 +7,204 @@ require 'puppet/network/http/api/v1'
require 'puppet/network/http/compression'
module Puppet
- Puppet::Type.type(:file).newproperty(:content) do
- include Puppet::Util::Diff
- include Puppet::Util::Checksums
- include Puppet::Network::HTTP::API::V1
- include Puppet::Network::HTTP::Compression.module
-
- attr_reader :actual_content
-
- desc "Specify the contents of a file as a string. Newlines, tabs, and
- spaces can be specified using the escaped syntax (e.g., \\n for a newline). The primary purpose of this parameter is to provide a
- kind of limited templating::
-
- define resolve(nameserver1, nameserver2, domain, search) {
- $str = \"search $search
- domain $domain
- nameserver $nameserver1
- nameserver $nameserver2
- \"
-
- file { \"/etc/resolv.conf\":
- content => $str
- }
- }
-
- This attribute is especially useful when used with
- `PuppetTemplating templating`:trac:."
-
- # Store a checksum as the value, rather than the actual content.
- # Simplifies everything.
- munge do |value|
- if value == :absent
- value
- elsif checksum?(value)
- # XXX This is potentially dangerous because it means users can't write a file whose
- # entire contents are a plain checksum
- value
- else
- @actual_content = value
- resource.parameter(:checksum).sum(value)
- end
- end
+ Puppet::Type.type(:file).newproperty(:content) do
+ include Puppet::Util::Diff
+ include Puppet::Util::Checksums
+ include Puppet::Network::HTTP::API::V1
+ include Puppet::Network::HTTP::Compression.module
+
+ attr_reader :actual_content
+
+ desc "Specify the contents of a file as a string. Newlines, tabs, and
+ spaces can be specified using the escaped syntax (e.g., \\n for a newline). The primary purpose of this parameter is to provide a
+ kind of limited templating::
+
+ define resolve(nameserver1, nameserver2, domain, search) {
+ $str = \"search $search
+ domain $domain
+ nameserver $nameserver1
+ nameserver $nameserver2
+ \"
+
+ file { \"/etc/resolv.conf\":
+ content => $str
+ }
+ }
+
+ This attribute is especially useful when used with
+ `PuppetTemplating templating`:trac:."
+
+ # Store a checksum as the value, rather than the actual content.
+ # Simplifies everything.
+ munge do |value|
+ if value == :absent
+ value
+ elsif checksum?(value)
+ # XXX This is potentially dangerous because it means users can't write a file whose
+ # entire contents are a plain checksum
+ value
+ else
+ @actual_content = value
+ resource.parameter(:checksum).sum(value)
+ end
+ end
- # Checksums need to invert how changes are printed.
- def change_to_s(currentvalue, newvalue)
- # Our "new" checksum value is provided by the source.
- if source = resource.parameter(:source) and tmp = source.checksum
- newvalue = tmp
- end
- if currentvalue == :absent
- return "defined content as '#{newvalue}'"
- elsif newvalue == :absent
- return "undefined content from '#{currentvalue}'"
- else
- return "content changed '#{currentvalue}' to '#{newvalue}'"
- end
- end
+ # Checksums need to invert how changes are printed.
+ def change_to_s(currentvalue, newvalue)
+ # Our "new" checksum value is provided by the source.
+ if source = resource.parameter(:source) and tmp = source.checksum
+ newvalue = tmp
+ end
+ if currentvalue == :absent
+ return "defined content as '#{newvalue}'"
+ elsif newvalue == :absent
+ return "undefined content from '#{currentvalue}'"
+ else
+ return "content changed '#{currentvalue}' to '#{newvalue}'"
+ end
+ end
- def checksum_type
- if source = resource.parameter(:source)
- result = source.checksum
- else checksum = resource.parameter(:checksum)
- result = resource[:checksum]
- end
- if result =~ /^\{(\w+)\}.+/
- return $1.to_sym
- else
- return result
- end
- end
+ def checksum_type
+ if source = resource.parameter(:source)
+ result = source.checksum
+ else checksum = resource.parameter(:checksum)
+ result = resource[:checksum]
+ end
+ if result =~ /^\{(\w+)\}.+/
+ return $1.to_sym
+ else
+ return result
+ end
+ end
- def length
- (actual_content and actual_content.length) || 0
- end
+ def length
+ (actual_content and actual_content.length) || 0
+ end
- def content
- self.should
- end
+ def content
+ self.should
+ end
- # Override this method to provide diffs if asked for.
- # Also, fix #872: when content is used, and replace is true, the file
- # should be insync when it exists
- def insync?(is)
- if resource.should_be_file?
- return false if is == :absent
- else
- return true
- end
-
- return true if ! @resource.replace?
- return true unless self.should
-
- result = super
-
- if ! result and Puppet[:show_diff]
- write_temporarily do |path|
- print diff(@resource[:path], path)
- end
- end
- result
- end
+ # Override this method to provide diffs if asked for.
+ # Also, fix #872: when content is used, and replace is true, the file
+ # should be insync when it exists
+ def insync?(is)
+ if resource.should_be_file?
+ return false if is == :absent
+ else
+ return true
+ end
- def retrieve
- return :absent unless stat = @resource.stat
- ftype = stat.ftype
- # Don't even try to manage the content on directories or links
- return nil if ["directory","link"].include?(ftype)
-
- begin
- resource.parameter(:checksum).sum_file(resource[:path])
- rescue => detail
- raise Puppet::Error, "Could not read #{ftype} #{@resource.title}: #{detail}"
- end
- end
+ return true if ! @resource.replace?
+ return true unless self.should
- # Make sure we're also managing the checksum property.
- def should=(value)
- @resource.newattr(:checksum) unless @resource.parameter(:checksum)
- super
+ result = super
+
+ if ! result and Puppet[:show_diff]
+ write_temporarily do |path|
+ print diff(@resource[:path], path)
end
+ end
+ result
+ end
- # Just write our content out to disk.
- def sync
- return_event = @resource.stat ? :file_changed : :file_created
+ def retrieve
+ return :absent unless stat = @resource.stat
+ ftype = stat.ftype
+ # Don't even try to manage the content on directories or links
+ return nil if ["directory","link"].include?(ftype)
+
+ begin
+ resource.parameter(:checksum).sum_file(resource[:path])
+ rescue => detail
+ raise Puppet::Error, "Could not read #{ftype} #{@resource.title}: #{detail}"
+ end
+ end
- # We're safe not testing for the 'source' if there's no 'should'
- # because we wouldn't have gotten this far if there weren't at least
- # one valid value somewhere.
- @resource.write(:content)
+ # Make sure we're also managing the checksum property.
+ def should=(value)
+ @resource.newattr(:checksum) unless @resource.parameter(:checksum)
+ super
+ end
- return_event
- end
+ # Just write our content out to disk.
+ def sync
+ return_event = @resource.stat ? :file_changed : :file_created
- def write_temporarily
- tempfile = Tempfile.new("puppet-file")
- tempfile.open
+ # We're safe not testing for the 'source' if there's no 'should'
+ # because we wouldn't have gotten this far if there weren't at least
+ # one valid value somewhere.
+ @resource.write(:content)
- write(tempfile)
+ return_event
+ end
- tempfile.close
+ def write_temporarily
+ tempfile = Tempfile.new("puppet-file")
+ tempfile.open
- yield tempfile.path
+ write(tempfile)
- tempfile.delete
- end
+ tempfile.close
- def write(file)
- resource.parameter(:checksum).sum_stream { |sum|
- each_chunk_from(actual_content || resource.parameter(:source)) { |chunk|
- sum << chunk
- file.print chunk
- }
- }
- end
+ yield tempfile.path
- def each_chunk_from(source_or_content)
- if source_or_content.is_a?(String)
- yield source_or_content
- elsif source_or_content.nil?
- yield read_file_from_filebucket
- elsif source_or_content.local?
- chunk_file_from_disk(source_or_content) { |chunk| yield chunk }
- else
- chunk_file_from_source(source_or_content) { |chunk| yield chunk }
- end
- end
+ tempfile.delete
+ end
- private
+ def write(file)
+ resource.parameter(:checksum).sum_stream { |sum|
+ each_chunk_from(actual_content || resource.parameter(:source)) { |chunk|
+ sum << chunk
+ file.print chunk
+ }
+ }
+ end
+
+ def each_chunk_from(source_or_content)
+ if source_or_content.is_a?(String)
+ yield source_or_content
+ elsif source_or_content.nil?
+ yield read_file_from_filebucket
+ elsif source_or_content.local?
+ chunk_file_from_disk(source_or_content) { |chunk| yield chunk }
+ else
+ chunk_file_from_source(source_or_content) { |chunk| yield chunk }
+ end
+ end
+
+ private
- def chunk_file_from_disk(source_or_content)
- File.open(source_or_content.full_path, "r") do |src|
- while chunk = src.read(8192)
- yield chunk
- end
- end
+ def chunk_file_from_disk(source_or_content)
+ File.open(source_or_content.full_path, "r") do |src|
+ while chunk = src.read(8192)
+ yield chunk
end
+ end
+ end
- def chunk_file_from_source(source_or_content)
- request = Puppet::Indirector::Request.new(:file_content, :find, source_or_content.full_path)
- connection = Puppet::Network::HttpPool.http_instance(source_or_content.server, source_or_content.port)
- connection.request_get(indirection2uri(request), add_accept_encoding({"Accept" => "raw"})) do |response|
- case response.code
- when "404"; nil
- when /^2/; uncompress(response) { |uncompressor| response.read_body { |chunk| yield uncompressor.uncompress(chunk) } }
- else
- # Raise the http error if we didn't get a 'success' of some kind.
- message = "Error #{response.code} on SERVER: #{(response.body||'').empty? ? response.message : uncompress_body(response)}"
- raise Net::HTTPError.new(message, response)
- end
- end
+ def chunk_file_from_source(source_or_content)
+ request = Puppet::Indirector::Request.new(:file_content, :find, source_or_content.full_path)
+ connection = Puppet::Network::HttpPool.http_instance(source_or_content.server, source_or_content.port)
+ connection.request_get(indirection2uri(request), add_accept_encoding({"Accept" => "raw"})) do |response|
+ case response.code
+ when "404"; nil
+ when /^2/; uncompress(response) { |uncompressor| response.read_body { |chunk| yield uncompressor.uncompress(chunk) } }
+ else
+ # Raise the http error if we didn't get a 'success' of some kind.
+ message = "Error #{response.code} on SERVER: #{(response.body||'').empty? ? response.message : uncompress_body(response)}"
+ raise Net::HTTPError.new(message, response)
end
+ end
+ end
- def read_file_from_filebucket
- raise "Could not get filebucket from file" unless dipper = resource.bucket
- sum = should.sub(/\{\w+\}/, '')
+ def read_file_from_filebucket
+ raise "Could not get filebucket from file" unless dipper = resource.bucket
+ sum = should.sub(/\{\w+\}/, '')
- dipper.getfile(sum)
- rescue => detail
- fail "Could not retrieve content for #{should} from filebucket: #{detail}"
- end
+ dipper.getfile(sum)
+ rescue => detail
+ fail "Could not retrieve content for #{should} from filebucket: #{detail}"
end
+ end
end
diff --git a/lib/puppet/type/file/ensure.rb b/lib/puppet/type/file/ensure.rb
index a6eed8a..c74a1d4 100755
--- a/lib/puppet/type/file/ensure.rb
+++ b/lib/puppet/type/file/ensure.rb
@@ -1,170 +1,170 @@
module Puppet
- Puppet::Type.type(:file).ensurable do
- require 'etc'
- desc "Whether to create files that don't currently exist.
- Possible values are *absent*, *present*, *file*, and *directory*.
- Specifying ``present`` will match any form of file existence, and
- if the file is missing will create an empty file. Specifying
- ``absent`` will delete the file (and directory if recurse => true).
-
- Anything other than those values will be considered to be a symlink.
- For instance, the following text creates a link::
-
- # Useful on solaris
- file { \"/etc/inetd.conf\":
- ensure => \"/etc/inet/inetd.conf\"
- }
-
- You can make relative links::
-
- # Useful on solaris
- file { \"/etc/inetd.conf\":
- ensure => \"inet/inetd.conf\"
- }
-
- If you need to make a relative link to a file named the same
- as one of the valid values, you must prefix it with ``./`` or
- something similar.
-
- You can also make recursive symlinks, which will create a
- directory structure that maps to the target directory,
- with directories corresponding to each directory
- and links corresponding to each file."
-
- # Most 'ensure' properties have a default, but with files we, um, don't.
- nodefault
-
- newvalue(:absent) do
- File.unlink(@resource[:path])
- end
+ Puppet::Type.type(:file).ensurable do
+ require 'etc'
+ desc "Whether to create files that don't currently exist.
+ Possible values are *absent*, *present*, *file*, and *directory*.
+ Specifying ``present`` will match any form of file existence, and
+ if the file is missing will create an empty file. Specifying
+ ``absent`` will delete the file (and directory if recurse => true).
+
+ Anything other than those values will be considered to be a symlink.
+ For instance, the following text creates a link::
+
+ # Useful on solaris
+ file { \"/etc/inetd.conf\":
+ ensure => \"/etc/inet/inetd.conf\"
+ }
+
+ You can make relative links::
+
+ # Useful on solaris
+ file { \"/etc/inetd.conf\":
+ ensure => \"inet/inetd.conf\"
+ }
+
+ If you need to make a relative link to a file named the same
+ as one of the valid values, you must prefix it with ``./`` or
+ something similar.
+
+ You can also make recursive symlinks, which will create a
+ directory structure that maps to the target directory,
+ with directories corresponding to each directory
+ and links corresponding to each file."
+
+ # Most 'ensure' properties have a default, but with files we, um, don't.
+ nodefault
+
+ newvalue(:absent) do
+ File.unlink(@resource[:path])
+ end
- aliasvalue(:false, :absent)
+ aliasvalue(:false, :absent)
- newvalue(:file, :event => :file_created) do
- # Make sure we're not managing the content some other way
- if property = @resource.property(:content)
- property.sync
- else
- @resource.write(:ensure)
- mode = @resource.should(:mode)
- end
- end
+ newvalue(:file, :event => :file_created) do
+ # Make sure we're not managing the content some other way
+ if property = @resource.property(:content)
+ property.sync
+ else
+ @resource.write(:ensure)
+ mode = @resource.should(:mode)
+ end
+ end
- #aliasvalue(:present, :file)
- newvalue(:present, :event => :file_created) do
- # Make a file if they want something, but this will match almost
- # anything.
- set_file
- end
+ #aliasvalue(:present, :file)
+ newvalue(:present, :event => :file_created) do
+ # Make a file if they want something, but this will match almost
+ # anything.
+ set_file
+ end
- newvalue(:directory, :event => :directory_created) do
- mode = @resource.should(:mode)
- parent = File.dirname(@resource[:path])
- unless FileTest.exists? parent
- raise Puppet::Error,
- "Cannot create #{@resource[:path]}; parent directory #{parent} does not exist"
- end
- if mode
- Puppet::Util.withumask(000) do
- Dir.mkdir(@resource[:path],mode)
- end
- else
- Dir.mkdir(@resource[:path])
- end
- @resource.send(:property_fix)
- return :directory_created
+ newvalue(:directory, :event => :directory_created) do
+ mode = @resource.should(:mode)
+ parent = File.dirname(@resource[:path])
+ unless FileTest.exists? parent
+ raise Puppet::Error,
+ "Cannot create #{@resource[:path]}; parent directory #{parent} does not exist"
+ end
+ if mode
+ Puppet::Util.withumask(000) do
+ Dir.mkdir(@resource[:path],mode)
end
+ else
+ Dir.mkdir(@resource[:path])
+ end
+ @resource.send(:property_fix)
+ return :directory_created
+ end
- newvalue(:link, :event => :link_created) do
- fail "Cannot create a symlink without a target" unless property = resource.property(:target)
- property.retrieve
- property.mklink
- end
+ newvalue(:link, :event => :link_created) do
+ fail "Cannot create a symlink without a target" unless property = resource.property(:target)
+ property.retrieve
+ property.mklink
+ end
- # Symlinks.
- newvalue(/./) do
- # This code never gets executed. We need the regex to support
- # specifying it, but the work is done in the 'symlink' code block.
- end
+ # Symlinks.
+ newvalue(/./) do
+ # This code never gets executed. We need the regex to support
+ # specifying it, but the work is done in the 'symlink' code block.
+ end
- munge do |value|
- value = super(value)
- value,resource[:target] = :link,value unless value.is_a? Symbol
- resource[:links] = :manage if value == :link and resource[:links] != :follow
- value
- end
+ munge do |value|
+ value = super(value)
+ value,resource[:target] = :link,value unless value.is_a? Symbol
+ resource[:links] = :manage if value == :link and resource[:links] != :follow
+ value
+ end
- def change_to_s(currentvalue, newvalue)
- return super unless newvalue.to_s == "file"
-
- return super unless property = @resource.property(:content)
-
- # We know that content is out of sync if we're here, because
- # it's essentially equivalent to 'ensure' in the transaction.
- if source = @resource.parameter(:source)
- should = source.checksum
- else
- should = property.should
- end
- if should == :absent
- is = property.retrieve
- else
- is = :absent
- end
-
- property.change_to_s(is, should)
- end
+ def change_to_s(currentvalue, newvalue)
+ return super unless newvalue.to_s == "file"
+
+ return super unless property = @resource.property(:content)
+
+ # We know that content is out of sync if we're here, because
+ # it's essentially equivalent to 'ensure' in the transaction.
+ if source = @resource.parameter(:source)
+ should = source.checksum
+ else
+ should = property.should
+ end
+ if should == :absent
+ is = property.retrieve
+ else
+ is = :absent
+ end
+
+ property.change_to_s(is, should)
+ end
- # Check that we can actually create anything
- def check
- basedir = File.dirname(@resource[:path])
-
- if ! FileTest.exists?(basedir)
- raise Puppet::Error,
- "Can not create #{@resource.title}; parent directory does not exist"
- elsif ! FileTest.directory?(basedir)
- raise Puppet::Error,
- "Can not create #{@resource.title}; #{dirname} is not a directory"
- end
- end
+ # Check that we can actually create anything
+ def check
+ basedir = File.dirname(@resource[:path])
+
+ if ! FileTest.exists?(basedir)
+ raise Puppet::Error,
+ "Can not create #{@resource.title}; parent directory does not exist"
+ elsif ! FileTest.directory?(basedir)
+ raise Puppet::Error,
+ "Can not create #{@resource.title}; #{dirname} is not a directory"
+ end
+ end
- # We have to treat :present specially, because it works with any
- # type of file.
- def insync?(currentvalue)
- unless currentvalue == :absent or resource.replace?
- return true
- end
-
- if self.should == :present
- return !(currentvalue.nil? or currentvalue == :absent)
- else
- return super(currentvalue)
- end
- end
+ # We have to treat :present specially, because it works with any
+ # type of file.
+ def insync?(currentvalue)
+ unless currentvalue == :absent or resource.replace?
+ return true
+ end
+
+ if self.should == :present
+ return !(currentvalue.nil? or currentvalue == :absent)
+ else
+ return super(currentvalue)
+ end
+ end
- def retrieve
- if stat = @resource.stat(false)
- return stat.ftype.intern
- else
- if self.should == :false
- return :false
- else
- return :absent
- end
- end
+ def retrieve
+ if stat = @resource.stat(false)
+ return stat.ftype.intern
+ else
+ if self.should == :false
+ return :false
+ else
+ return :absent
end
+ end
+ end
- def sync
- @resource.remove_existing(self.should)
- if self.should == :absent
- return :file_removed
- end
+ def sync
+ @resource.remove_existing(self.should)
+ if self.should == :absent
+ return :file_removed
+ end
- event = super
+ event = super
- event
- end
+ event
end
+ end
end
diff --git a/lib/puppet/type/file/group.rb b/lib/puppet/type/file/group.rb
index b00eb23..5ed5166 100755
--- a/lib/puppet/type/file/group.rb
+++ b/lib/puppet/type/file/group.rb
@@ -2,112 +2,112 @@ require 'puppet/util/posix'
# Manage file group ownership.
module Puppet
- Puppet::Type.type(:file).newproperty(:group) do
- include Puppet::Util::POSIX
+ Puppet::Type.type(:file).newproperty(:group) do
+ include Puppet::Util::POSIX
- require 'etc'
- desc "Which group should own the file. Argument can be either group
- name or group ID."
- @event = :file_changed
+ require 'etc'
+ desc "Which group should own the file. Argument can be either group
+ name or group ID."
+ @event = :file_changed
- validate do |group|
- raise(Puppet::Error, "Invalid group name '#{group.inspect}'") unless group and group != ""
- end
+ validate do |group|
+ raise(Puppet::Error, "Invalid group name '#{group.inspect}'") unless group and group != ""
+ end
- def id2name(id)
- return id.to_s if id.is_a?(Symbol)
- return nil if id > Puppet[:maximum_uid].to_i
- begin
- group = Etc.getgrgid(id)
- rescue ArgumentError
- return nil
- end
- if group.gid == ""
- return nil
- else
- return group.name
- end
- end
+ def id2name(id)
+ return id.to_s if id.is_a?(Symbol)
+ return nil if id > Puppet[:maximum_uid].to_i
+ begin
+ group = Etc.getgrgid(id)
+ rescue ArgumentError
+ return nil
+ end
+ if group.gid == ""
+ return nil
+ else
+ return group.name
+ end
+ end
- # We want to print names, not numbers
- def is_to_s(currentvalue)
- if currentvalue.is_a? Integer
- id2name(currentvalue) || currentvalue
- else
- return currentvalue.to_s
- end
- end
+ # We want to print names, not numbers
+ def is_to_s(currentvalue)
+ if currentvalue.is_a? Integer
+ id2name(currentvalue) || currentvalue
+ else
+ return currentvalue.to_s
+ end
+ end
- def should_to_s(newvalue = @should)
- if newvalue.is_a? Integer
- id2name(newvalue) || newvalue
- else
- return newvalue.to_s
- end
- end
+ def should_to_s(newvalue = @should)
+ if newvalue.is_a? Integer
+ id2name(newvalue) || newvalue
+ else
+ return newvalue.to_s
+ end
+ end
- def insync?(current)
- @should.each do |value|
- if value =~ /^\d+$/
- gid = Integer(value)
- elsif value.is_a?(String)
- fail "Could not find group #{value}" unless gid = gid(value)
- else
- gid = value
- end
-
- return true if gid == current
- end
- false
+ def insync?(current)
+ @should.each do |value|
+ if value =~ /^\d+$/
+ gid = Integer(value)
+ elsif value.is_a?(String)
+ fail "Could not find group #{value}" unless gid = gid(value)
+ else
+ gid = value
end
- def retrieve
- return :absent unless stat = resource.stat(false)
+ return true if gid == current
+ end
+ false
+ end
- currentvalue = stat.gid
+ def retrieve
+ return :absent unless stat = resource.stat(false)
- # On OS X, files that are owned by -2 get returned as really
- # large GIDs instead of negative ones. This isn't a Ruby bug,
- # it's an OS X bug, since it shows up in perl, too.
- if currentvalue > Puppet[:maximum_uid].to_i
- self.warning "Apparently using negative GID (#{currentvalue}) on a platform that does not consistently handle them"
- currentvalue = :silly
- end
+ currentvalue = stat.gid
- currentvalue
- end
+ # On OS X, files that are owned by -2 get returned as really
+ # large GIDs instead of negative ones. This isn't a Ruby bug,
+ # it's an OS X bug, since it shows up in perl, too.
+ if currentvalue > Puppet[:maximum_uid].to_i
+ self.warning "Apparently using negative GID (#{currentvalue}) on a platform that does not consistently handle them"
+ currentvalue = :silly
+ end
- # Determine if the group is valid, and if so, return the GID
- def validgroup?(value)
- Integer(value) rescue gid(value) || false
- end
+ currentvalue
+ end
- # Normal users will only be able to manage certain groups. Right now,
- # we'll just let it fail, but we should probably set things up so
- # that users get warned if they try to change to an unacceptable group.
- def sync
- # Set our method appropriately, depending on links.
- if resource[:links] == :manage
- method = :lchown
- else
- method = :chown
- end
-
- gid = nil
- @should.each do |group|
- break if gid = validgroup?(group)
- end
-
- raise Puppet::Error, "Could not find group(s) #{@should.join(",")}" unless gid
-
- begin
- # set owner to nil so it's ignored
- File.send(method, nil, gid, resource[:path])
- rescue => detail
- error = Puppet::Error.new( "failed to chgrp #{resource[:path]} to #{gid}: #{detail.message}")
- raise error
- end
- :file_changed
- end
+ # Determine if the group is valid, and if so, return the GID
+ def validgroup?(value)
+ Integer(value) rescue gid(value) || false
+ end
+
+ # Normal users will only be able to manage certain groups. Right now,
+ # we'll just let it fail, but we should probably set things up so
+ # that users get warned if they try to change to an unacceptable group.
+ def sync
+ # Set our method appropriately, depending on links.
+ if resource[:links] == :manage
+ method = :lchown
+ else
+ method = :chown
+ end
+
+ gid = nil
+ @should.each do |group|
+ break if gid = validgroup?(group)
+ end
+
+ raise Puppet::Error, "Could not find group(s) #{@should.join(",")}" unless gid
+
+ begin
+ # set owner to nil so it's ignored
+ File.send(method, nil, gid, resource[:path])
+ rescue => detail
+ error = Puppet::Error.new( "failed to chgrp #{resource[:path]} to #{gid}: #{detail.message}")
+ raise error
+ end
+ :file_changed
end
+ end
end
diff --git a/lib/puppet/type/file/mode.rb b/lib/puppet/type/file/mode.rb
index 31209f4..9abf56d 100755
--- a/lib/puppet/type/file/mode.rb
+++ b/lib/puppet/type/file/mode.rb
@@ -2,123 +2,123 @@
# for specification (e.g., u+rwx, or -0011), but for now only supports
# specifying the full mode.
module Puppet
- Puppet::Type.type(:file).newproperty(:mode) do
- require 'etc'
- desc "Mode the file should be. Currently relatively limited:
- you must specify the exact mode the file should be.
-
- Note that when you set the mode of a directory, Puppet always
- sets the search/traverse (1) bit anywhere the read (4) bit is set.
- This is almost always what you want: read allows you to list the
- entries in a directory, and search/traverse allows you to access
- (read/write/execute) those entries.) Because of this feature, you
- can recursively make a directory and all of the files in it
- world-readable by setting e.g.::
-
- file { '/some/dir':
- mode => 644,
- recurse => true,
- }
-
- In this case all of the files underneath ``/some/dir`` will have
- mode 644, and all of the directories will have mode 755."
-
- @event = :file_changed
-
- # Our modes are octal, so make sure they print correctly. Other
- # valid values are symbols, basically
- def is_to_s(currentvalue)
- case currentvalue
- when Integer
- return "%o" % currentvalue
- when Symbol
- return currentvalue
- else
- raise Puppet::DevError, "Invalid current value for mode: #{currentvalue.inspect}"
- end
- end
+ Puppet::Type.type(:file).newproperty(:mode) do
+ require 'etc'
+ desc "Mode the file should be. Currently relatively limited:
+ you must specify the exact mode the file should be.
+
+ Note that when you set the mode of a directory, Puppet always
+ sets the search/traverse (1) bit anywhere the read (4) bit is set.
+ This is almost always what you want: read allows you to list the
+ entries in a directory, and search/traverse allows you to access
+ (read/write/execute) those entries.) Because of this feature, you
+ can recursively make a directory and all of the files in it
+ world-readable by setting e.g.::
+
+ file { '/some/dir':
+ mode => 644,
+ recurse => true,
+ }
+
+ In this case all of the files underneath ``/some/dir`` will have
+ mode 644, and all of the directories will have mode 755."
+
+ @event = :file_changed
+
+ # Our modes are octal, so make sure they print correctly. Other
+ # valid values are symbols, basically
+ def is_to_s(currentvalue)
+ case currentvalue
+ when Integer
+ return "%o" % currentvalue
+ when Symbol
+ return currentvalue
+ else
+ raise Puppet::DevError, "Invalid current value for mode: #{currentvalue.inspect}"
+ end
+ end
- def should_to_s(newvalue = @should)
- case newvalue
- when Integer
- return "%o" % newvalue
- when Symbol
- return newvalue
- else
- raise Puppet::DevError, "Invalid 'should' value for mode: #{newvalue.inspect}"
- end
- end
+ def should_to_s(newvalue = @should)
+ case newvalue
+ when Integer
+ return "%o" % newvalue
+ when Symbol
+ return newvalue
+ else
+ raise Puppet::DevError, "Invalid 'should' value for mode: #{newvalue.inspect}"
+ end
+ end
- munge do |should|
- # this is pretty hackish, but i need to make sure the number is in
- # octal, yet the number can only be specified as a string right now
- value = should
- if value.is_a?(String)
- unless value =~ /^\d+$/
- raise Puppet::Error, "File modes can only be numbers, not #{value.inspect}"
- end
- # Make sure our number looks like octal.
- unless value =~ /^0/
- value = "0#{value}"
- end
- old = value
- begin
- value = Integer(value)
- rescue ArgumentError => detail
- raise Puppet::DevError, "Could not convert #{old.inspect} to integer"
- end
- end
-
- return value
+ munge do |should|
+ # this is pretty hackish, but i need to make sure the number is in
+ # octal, yet the number can only be specified as a string right now
+ value = should
+ if value.is_a?(String)
+ unless value =~ /^\d+$/
+ raise Puppet::Error, "File modes can only be numbers, not #{value.inspect}"
end
+ # Make sure our number looks like octal.
+ unless value =~ /^0/
+ value = "0#{value}"
+ end
+ old = value
+ begin
+ value = Integer(value)
+ rescue ArgumentError => detail
+ raise Puppet::DevError, "Could not convert #{old.inspect} to integer"
+ end
+ end
- # If we're a directory, we need to be executable for all cases
- # that are readable. This should probably be selectable, but eh.
- def dirmask(value)
- if FileTest.directory?(@resource[:path])
- value |= 0100 if value & 0400 != 0
- value |= 010 if value & 040 != 0
- value |= 01 if value & 04 != 0
- end
+ return value
+ end
- value
- end
+ # If we're a directory, we need to be executable for all cases
+ # that are readable. This should probably be selectable, but eh.
+ def dirmask(value)
+ if FileTest.directory?(@resource[:path])
+ value |= 0100 if value & 0400 != 0
+ value |= 010 if value & 040 != 0
+ value |= 01 if value & 04 != 0
+ end
- def insync?(currentvalue)
- if stat = @resource.stat and stat.ftype == "link" and @resource[:links] != :follow
- self.debug "Not managing symlink mode"
- return true
- else
- return super(currentvalue)
- end
- end
+ value
+ end
- def retrieve
- # If we're not following links and we're a link, then we just turn
- # off mode management entirely.
-
- if stat = @resource.stat(false)
- unless defined?(@fixed)
- @should &&= @should.collect { |s| self.dirmask(s) }
- end
- return stat.mode & 007777
- else
- return :absent
- end
- end
+ def insync?(currentvalue)
+ if stat = @resource.stat and stat.ftype == "link" and @resource[:links] != :follow
+ self.debug "Not managing symlink mode"
+ return true
+ else
+ return super(currentvalue)
+ end
+ end
- def sync
- mode = self.should
-
- begin
- File.chmod(mode, @resource[:path])
- rescue => detail
- error = Puppet::Error.new("failed to chmod #{@resource[:path]}: #{detail.message}")
- error.set_backtrace detail.backtrace
- raise error
- end
- :file_changed
+ def retrieve
+ # If we're not following links and we're a link, then we just turn
+ # off mode management entirely.
+
+ if stat = @resource.stat(false)
+ unless defined?(@fixed)
+ @should &&= @should.collect { |s| self.dirmask(s) }
end
+ return stat.mode & 007777
+ else
+ return :absent
+ end
+ end
+
+ def sync
+ mode = self.should
+
+ begin
+ File.chmod(mode, @resource[:path])
+ rescue => detail
+ error = Puppet::Error.new("failed to chmod #{@resource[:path]}: #{detail.message}")
+ error.set_backtrace detail.backtrace
+ raise error
+ end
+ :file_changed
end
+ end
end
diff --git a/lib/puppet/type/file/owner.rb b/lib/puppet/type/file/owner.rb
index 01c0923..d473da2 100755
--- a/lib/puppet/type/file/owner.rb
+++ b/lib/puppet/type/file/owner.rb
@@ -1,52 +1,52 @@
module Puppet
- Puppet::Type.type(:file).newproperty(:owner) do
+ Puppet::Type.type(:file).newproperty(:owner) do
- desc "To whom the file should belong. Argument can be user name or
- user ID."
- @event = :file_changed
+ desc "To whom the file should belong. Argument can be user name or
+ user ID."
+ @event = :file_changed
- def insync?(current)
- provider.insync?(current, @should)
- end
+ def insync?(current)
+ provider.insync?(current, @should)
+ end
- # We want to print names, not numbers
- def is_to_s(currentvalue)
- provider.id2name(currentvalue) || currentvalue
- end
+ # We want to print names, not numbers
+ def is_to_s(currentvalue)
+ provider.id2name(currentvalue) || currentvalue
+ end
- def should_to_s(newvalue = @should)
- case newvalue
- when Symbol
- newvalue.to_s
- when Integer
- provider.id2name(newvalue) || newvalue
- when String
- newvalue
- else
- raise Puppet::DevError, "Invalid uid type #{newvalue.class}(#{newvalue})"
- end
- end
+ def should_to_s(newvalue = @should)
+ case newvalue
+ when Symbol
+ newvalue.to_s
+ when Integer
+ provider.id2name(newvalue) || newvalue
+ when String
+ newvalue
+ else
+ raise Puppet::DevError, "Invalid uid type #{newvalue.class}(#{newvalue})"
+ end
+ end
- def retrieve
- if self.should
- @should = @should.collect do |val|
- unless val.is_a?(Integer)
- if tmp = provider.validuser?(val)
- val = tmp
- else
- raise "Could not find user #{val}"
- end
- else
- val
- end
- end
+ def retrieve
+ if self.should
+ @should = @should.collect do |val|
+ unless val.is_a?(Integer)
+ if tmp = provider.validuser?(val)
+ val = tmp
+ else
+ raise "Could not find user #{val}"
end
- provider.retrieve(@resource)
+ else
+ val
+ end
end
+ end
+ provider.retrieve(@resource)
+ end
- def sync
- provider.sync(resource[:path], resource[:links], @should)
- end
+ def sync
+ provider.sync(resource[:path], resource[:links], @should)
end
+ end
end
diff --git a/lib/puppet/type/file/selcontext.rb b/lib/puppet/type/file/selcontext.rb
index 0a889fc..edcfb83 100644
--- a/lib/puppet/type/file/selcontext.rb
+++ b/lib/puppet/type/file/selcontext.rb
@@ -20,84 +20,84 @@
# See http://www.nsa.gov/selinux/ for complete docs on SELinux.
module Puppet
- require 'puppet/util/selinux'
-
- class SELFileContext < Puppet::Property
- include Puppet::Util::SELinux
-
- def retrieve
- return :absent unless @resource.stat(false)
- context = self.get_selinux_current_context(@resource[:path])
- parse_selinux_context(name, context)
- end
-
- def retrieve_default_context(property)
- unless context = self.get_selinux_default_context(@resource[:path])
- return nil
- end
- property_default = self.parse_selinux_context(property, context)
- self.debug "Found #{property} default '#{property_default}' for #{@resource[:path]}" if not property_default.nil?
- property_default
- end
-
- def insync?(value)
- if not selinux_support?
- debug("SELinux bindings not found. Ignoring parameter.")
- return true
- end
- super
- end
-
- def sync
- self.set_selinux_context(@resource[:path], @should, name)
- :file_changed
- end
- end
+ require 'puppet/util/selinux'
- Puppet::Type.type(:file).newproperty(:seluser, :parent => Puppet::SELFileContext) do
- desc "What the SELinux user component of the context of the file should be.
- Any valid SELinux user component is accepted. For example ``user_u``.
- If not specified it defaults to the value returned by matchpathcon for
- the file, if any exists. Only valid on systems with SELinux support
- enabled."
+ class SELFileContext < Puppet::Property
+ include Puppet::Util::SELinux
- @event = :file_changed
- defaultto { self.retrieve_default_context(:seluser) }
+ def retrieve
+ return :absent unless @resource.stat(false)
+ context = self.get_selinux_current_context(@resource[:path])
+ parse_selinux_context(name, context)
end
- Puppet::Type.type(:file).newproperty(:selrole, :parent => Puppet::SELFileContext) do
- desc "What the SELinux role component of the context of the file should be.
- Any valid SELinux role component is accepted. For example ``role_r``.
- If not specified it defaults to the value returned by matchpathcon for
- the file, if any exists. Only valid on systems with SELinux support
- enabled."
-
- @event = :file_changed
- defaultto { self.retrieve_default_context(:selrole) }
+ def retrieve_default_context(property)
+ unless context = self.get_selinux_default_context(@resource[:path])
+ return nil
+ end
+ property_default = self.parse_selinux_context(property, context)
+ self.debug "Found #{property} default '#{property_default}' for #{@resource[:path]}" if not property_default.nil?
+ property_default
end
- Puppet::Type.type(:file).newproperty(:seltype, :parent => Puppet::SELFileContext) do
- desc "What the SELinux type component of the context of the file should be.
- Any valid SELinux type component is accepted. For example ``tmp_t``.
- If not specified it defaults to the value returned by matchpathcon for
- the file, if any exists. Only valid on systems with SELinux support
- enabled."
-
- @event = :file_changed
- defaultto { self.retrieve_default_context(:seltype) }
+ def insync?(value)
+ if not selinux_support?
+ debug("SELinux bindings not found. Ignoring parameter.")
+ return true
+ end
+ super
end
- Puppet::Type.type(:file).newproperty(:selrange, :parent => Puppet::SELFileContext) do
- desc "What the SELinux range component of the context of the file should be.
- Any valid SELinux range component is accepted. For example ``s0`` or
- ``SystemHigh``. If not specified it defaults to the value returned by
- matchpathcon for the file, if any exists. Only valid on systems with
- SELinux support enabled and that have support for MCS (Multi-Category
- Security)."
-
- @event = :file_changed
- defaultto { self.retrieve_default_context(:selrange) }
+ def sync
+ self.set_selinux_context(@resource[:path], @should, name)
+ :file_changed
end
+ end
+
+ Puppet::Type.type(:file).newproperty(:seluser, :parent => Puppet::SELFileContext) do
+ desc "What the SELinux user component of the context of the file should be.
+ Any valid SELinux user component is accepted. For example ``user_u``.
+ If not specified it defaults to the value returned by matchpathcon for
+ the file, if any exists. Only valid on systems with SELinux support
+ enabled."
+
+ @event = :file_changed
+ defaultto { self.retrieve_default_context(:seluser) }
+ end
+
+ Puppet::Type.type(:file).newproperty(:selrole, :parent => Puppet::SELFileContext) do
+ desc "What the SELinux role component of the context of the file should be.
+ Any valid SELinux role component is accepted. For example ``role_r``.
+ If not specified it defaults to the value returned by matchpathcon for
+ the file, if any exists. Only valid on systems with SELinux support
+ enabled."
+
+ @event = :file_changed
+ defaultto { self.retrieve_default_context(:selrole) }
+ end
+
+ Puppet::Type.type(:file).newproperty(:seltype, :parent => Puppet::SELFileContext) do
+ desc "What the SELinux type component of the context of the file should be.
+ Any valid SELinux type component is accepted. For example ``tmp_t``.
+ If not specified it defaults to the value returned by matchpathcon for
+ the file, if any exists. Only valid on systems with SELinux support
+ enabled."
+
+ @event = :file_changed
+ defaultto { self.retrieve_default_context(:seltype) }
+ end
+
+ Puppet::Type.type(:file).newproperty(:selrange, :parent => Puppet::SELFileContext) do
+ desc "What the SELinux range component of the context of the file should be.
+ Any valid SELinux range component is accepted. For example ``s0`` or
+ ``SystemHigh``. If not specified it defaults to the value returned by
+ matchpathcon for the file, if any exists. Only valid on systems with
+ SELinux support enabled and that have support for MCS (Multi-Category
+ Security)."
+
+ @event = :file_changed
+ defaultto { self.retrieve_default_context(:selrange) }
+ end
end
diff --git a/lib/puppet/type/file/source.rb b/lib/puppet/type/file/source.rb
index 0053693..05da79b 100755
--- a/lib/puppet/type/file/source.rb
+++ b/lib/puppet/type/file/source.rb
@@ -3,187 +3,187 @@ require 'puppet/file_serving/content'
require 'puppet/file_serving/metadata'
module Puppet
- # Copy files from a local or remote source. This state *only* does any work
- # when the remote file is an actual file; in that case, this state copies
- # the file down. If the remote file is a dir or a link or whatever, then
- # this state, during retrieval, modifies the appropriate other states
- # so that things get taken care of appropriately.
- Puppet::Type.type(:file).newparam(:source) do
- include Puppet::Util::Diff
-
- attr_accessor :source, :local
- desc "Copy a file over the current file. Uses ``checksum`` to
- determine when a file should be copied. Valid values are either
- fully qualified paths to files, or URIs. Currently supported URI
- types are *puppet* and *file*.
-
- This is one of the primary mechanisms for getting content into
- applications that Puppet does not directly support and is very
- useful for those configuration files that don't change much across
- sytems. For instance::
-
- class sendmail {
- file { \"/etc/mail/sendmail.cf\":
- source => \"puppet://server/modules/module_name/sendmail.cf\"
- }
- }
-
- You can also leave out the server name, in which case ``puppet agent``
- will fill in the name of its configuration server and ``puppet apply``
- will use the local filesystem. This makes it easy to use the same
- configuration in both local and centralized forms.
-
- Currently, only the ``puppet`` scheme is supported for source
- URL's. Puppet will connect to the file server running on
- ``server`` to retrieve the contents of the file. If the
- ``server`` part is empty, the behavior of the command-line
- interpreter (``puppet apply``) and the client demon (``puppet agent``) differs
- slightly: ``apply`` will look such a file up on the module path
- on the local host, whereas ``agent`` will connect to the
- puppet server that it received the manifest from.
-
- See the `FileServingConfiguration fileserver configuration documentation`:trac: for information on how to configure
- and use file services within Puppet.
-
- If you specify multiple file sources for a file, then the first
- source that exists will be used. This allows you to specify
- what amount to search paths for files::
-
- file { \"/path/to/my/file\":
- source => [
- \"/modules/nfs/files/file.$host\",
- \"/modules/nfs/files/file.$operatingsystem\",
- \"/modules/nfs/files/file\"
- ]
- }
-
- This will use the first found file as the source.
-
- You cannot currently copy links using this mechanism; set ``links``
- to ``follow`` if any remote sources are links.
- "
-
- validate do |sources|
- sources = [sources] unless sources.is_a?(Array)
- sources.each do |source|
- begin
- uri = URI.parse(URI.escape(source))
- rescue => detail
- self.fail "Could not understand source #{source}: #{detail}"
- end
-
- self.fail "Cannot use URLs of type '#{uri.scheme}' as source for fileserving" unless uri.scheme.nil? or %w{file puppet}.include?(uri.scheme)
- end
+ # Copy files from a local or remote source. This state *only* does any work
+ # when the remote file is an actual file; in that case, this state copies
+ # the file down. If the remote file is a dir or a link or whatever, then
+ # this state, during retrieval, modifies the appropriate other states
+ # so that things get taken care of appropriately.
+ Puppet::Type.type(:file).newparam(:source) do
+ include Puppet::Util::Diff
+
+ attr_accessor :source, :local
+ desc "Copy a file over the current file. Uses ``checksum`` to
+ determine when a file should be copied. Valid values are either
+ fully qualified paths to files, or URIs. Currently supported URI
+ types are *puppet* and *file*.
+
+ This is one of the primary mechanisms for getting content into
+ applications that Puppet does not directly support and is very
+ useful for those configuration files that don't change much across
+ sytems. For instance::
+
+ class sendmail {
+ file { \"/etc/mail/sendmail.cf\":
+ source => \"puppet://server/modules/module_name/sendmail.cf\"
+ }
+ }
+
+ You can also leave out the server name, in which case ``puppet agent``
+ will fill in the name of its configuration server and ``puppet apply``
+ will use the local filesystem. This makes it easy to use the same
+ configuration in both local and centralized forms.
+
+ Currently, only the ``puppet`` scheme is supported for source
+ URL's. Puppet will connect to the file server running on
+ ``server`` to retrieve the contents of the file. If the
+ ``server`` part is empty, the behavior of the command-line
+ interpreter (``puppet apply``) and the client demon (``puppet agent``) differs
+ slightly: ``apply`` will look such a file up on the module path
+ on the local host, whereas ``agent`` will connect to the
+ puppet server that it received the manifest from.
+
+ See the `FileServingConfiguration fileserver configuration documentation`:trac: for information on how to configure
+ and use file services within Puppet.
+
+ If you specify multiple file sources for a file, then the first
+ source that exists will be used. This allows you to specify
+ what amount to search paths for files::
+
+ file { \"/path/to/my/file\":
+ source => [
+ \"/modules/nfs/files/file.$host\",
+ \"/modules/nfs/files/file.$operatingsystem\",
+ \"/modules/nfs/files/file\"
+ ]
+ }
+
+ This will use the first found file as the source.
+
+ You cannot currently copy links using this mechanism; set ``links``
+ to ``follow`` if any remote sources are links.
+ "
+
+ validate do |sources|
+ sources = [sources] unless sources.is_a?(Array)
+ sources.each do |source|
+ begin
+ uri = URI.parse(URI.escape(source))
+ rescue => detail
+ self.fail "Could not understand source #{source}: #{detail}"
end
- munge do |sources|
- sources = [sources] unless sources.is_a?(Array)
- sources.collect { |source| source.sub(/\/$/, '') }
- end
+ self.fail "Cannot use URLs of type '#{uri.scheme}' as source for fileserving" unless uri.scheme.nil? or %w{file puppet}.include?(uri.scheme)
+ end
+ end
- def change_to_s(currentvalue, newvalue)
- # newvalue = "{md5}#{@metadata.checksum}"
- if @resource.property(:ensure).retrieve == :absent
- return "creating from source #{metadata.source} with contents #{metadata.checksum}"
- else
- return "replacing from source #{metadata.source} with contents #{metadata.checksum}"
- end
- end
+ munge do |sources|
+ sources = [sources] unless sources.is_a?(Array)
+ sources.collect { |source| source.sub(/\/$/, '') }
+ end
- def checksum
- metadata && metadata.checksum
- end
+ def change_to_s(currentvalue, newvalue)
+ # newvalue = "{md5}#{@metadata.checksum}"
+ if @resource.property(:ensure).retrieve == :absent
+ return "creating from source #{metadata.source} with contents #{metadata.checksum}"
+ else
+ return "replacing from source #{metadata.source} with contents #{metadata.checksum}"
+ end
+ end
- # Copy the values from the source to the resource. Yay.
- def copy_source_values
- devfail "Somehow got asked to copy source values without any metadata" unless metadata
-
- # Take each of the stats and set them as states on the local file
- # if a value has not already been provided.
- [:owner, :mode, :group, :checksum].each do |metadata_method|
- param_name = (metadata_method == :checksum) ? :content : metadata_method
- next if metadata_method == :owner and !Puppet.features.root?
- next if metadata_method == :checksum and metadata.ftype == "directory"
-
- if resource[param_name].nil? or resource[param_name] == :absent
- v = metadata.send(metadata_method)
- resource.info "Setting #{param_name} to #{v}"
- resource[param_name] = metadata.send(metadata_method)
- end
- end
-
- if resource[:ensure] == :absent
- # We know all we need to
- elsif metadata.ftype != "link"
- resource[:ensure] = metadata.ftype
- elsif @resource[:links] == :follow
- resource[:ensure] = :present
- else
- resource[:ensure] = "link"
- resource[:target] = metadata.destination
- end
- end
+ def checksum
+ metadata && metadata.checksum
+ end
- def pinparams
- [:mode, :type, :owner, :group, :content]
+ # Copy the values from the source to the resource. Yay.
+ def copy_source_values
+ devfail "Somehow got asked to copy source values without any metadata" unless metadata
+
+ # Take each of the stats and set them as states on the local file
+ # if a value has not already been provided.
+ [:owner, :mode, :group, :checksum].each do |metadata_method|
+ param_name = (metadata_method == :checksum) ? :content : metadata_method
+ next if metadata_method == :owner and !Puppet.features.root?
+ next if metadata_method == :checksum and metadata.ftype == "directory"
+
+ if resource[param_name].nil? or resource[param_name] == :absent
+ v = metadata.send(metadata_method)
+ resource.info "Setting #{param_name} to #{v}"
+ resource[param_name] = metadata.send(metadata_method)
end
+ end
+
+ if resource[:ensure] == :absent
+ # We know all we need to
+ elsif metadata.ftype != "link"
+ resource[:ensure] = metadata.ftype
+ elsif @resource[:links] == :follow
+ resource[:ensure] = :present
+ else
+ resource[:ensure] = "link"
+ resource[:target] = metadata.destination
+ end
+ end
- def found?
- ! (metadata.nil? or metadata.ftype.nil?)
- end
+ def pinparams
+ [:mode, :type, :owner, :group, :content]
+ end
+
+ def found?
+ ! (metadata.nil? or metadata.ftype.nil?)
+ end
- # Provide, and retrieve if necessary, the metadata for this file. Fail
- # if we can't find data about this host, and fail if there are any
- # problems in our query.
- cached_attr(:metadata) do
- return nil unless value
- result = nil
- value.each do |source|
- begin
- if data = Puppet::FileServing::Metadata.find(source)
- result = data
- result.source = source
- break
- end
- rescue => detail
- fail detail, "Could not retrieve file metadata for #{source}: #{detail}"
- end
- end
- fail "Could not retrieve information from source(s) #{value.join(", ")}" unless result
- result
+ # Provide, and retrieve if necessary, the metadata for this file. Fail
+ # if we can't find data about this host, and fail if there are any
+ # problems in our query.
+ cached_attr(:metadata) do
+ return nil unless value
+ result = nil
+ value.each do |source|
+ begin
+ if data = Puppet::FileServing::Metadata.find(source)
+ result = data
+ result.source = source
+ break
+ end
+ rescue => detail
+ fail detail, "Could not retrieve file metadata for #{source}: #{detail}"
end
+ end
+ fail "Could not retrieve information from source(s) #{value.join(", ")}" unless result
+ result
+ end
- # Make sure we're also checking the checksum
- def value=(value)
- super
+ # Make sure we're also checking the checksum
+ def value=(value)
+ super
- checks = (pinparams + [:ensure])
- checks.delete(:checksum)
+ checks = (pinparams + [:ensure])
+ checks.delete(:checksum)
- resource[:audit] = checks
- resource[:checksum] = :md5 unless resource.property(:checksum)
- end
+ resource[:audit] = checks
+ resource[:checksum] = :md5 unless resource.property(:checksum)
+ end
- def local?
- found? and uri and (uri.scheme || "file") == "file"
- end
+ def local?
+ found? and uri and (uri.scheme || "file") == "file"
+ end
- def full_path
- URI.unescape(uri.path) if found? and uri
- end
+ def full_path
+ URI.unescape(uri.path) if found? and uri
+ end
- def server
- (uri and uri.host) or Puppet.settings[:server]
- end
+ def server
+ (uri and uri.host) or Puppet.settings[:server]
+ end
- def port
- (uri and uri.port) or Puppet.settings[:masterport]
- end
+ def port
+ (uri and uri.port) or Puppet.settings[:masterport]
+ end
- private
+ private
- def uri
- @uri ||= URI.parse(URI.escape(metadata.source))
- end
+ def uri
+ @uri ||= URI.parse(URI.escape(metadata.source))
end
+ end
end
diff --git a/lib/puppet/type/file/target.rb b/lib/puppet/type/file/target.rb
index 59f1e59..9e7229d 100644
--- a/lib/puppet/type/file/target.rb
+++ b/lib/puppet/type/file/target.rb
@@ -1,74 +1,74 @@
module Puppet
- Puppet::Type.type(:file).newproperty(:target) do
- desc "The target for creating a link. Currently, symlinks are the
- only type supported."
+ Puppet::Type.type(:file).newproperty(:target) do
+ desc "The target for creating a link. Currently, symlinks are the
+ only type supported."
- newvalue(:notlink) do
- # We do nothing if the value is absent
- return :nochange
- end
-
- # Anything else, basically
- newvalue(/./) do
- @resource[:ensure] = :link if ! @resource.should(:ensure)
-
- # Only call mklink if ensure didn't call us in the first place.
- currentensure = @resource.property(:ensure).retrieve
- mklink if @resource.property(:ensure).insync?(currentensure)
- end
+ newvalue(:notlink) do
+ # We do nothing if the value is absent
+ return :nochange
+ end
- # Create our link.
- def mklink
- raise Puppet::Error, "Cannot symlink on Microsoft Windows" if Puppet.features.microsoft_windows?
+ # Anything else, basically
+ newvalue(/./) do
+ @resource[:ensure] = :link if ! @resource.should(:ensure)
- target = self.should
+ # Only call mklink if ensure didn't call us in the first place.
+ currentensure = @resource.property(:ensure).retrieve
+ mklink if @resource.property(:ensure).insync?(currentensure)
+ end
- # Clean up any existing objects. The argument is just for logging,
- # it doesn't determine what's removed.
- @resource.remove_existing(target)
+ # Create our link.
+ def mklink
+ raise Puppet::Error, "Cannot symlink on Microsoft Windows" if Puppet.features.microsoft_windows?
- raise Puppet::Error, "Could not remove existing file" if FileTest.exists?(@resource[:path])
+ target = self.should
- Dir.chdir(File.dirname(@resource[:path])) do
- Puppet::Util::SUIDManager.asuser(@resource.asuser) do
- mode = @resource.should(:mode)
- if mode
- Puppet::Util.withumask(000) do
- File.symlink(target, @resource[:path])
- end
- else
- File.symlink(target, @resource[:path])
- end
- end
+ # Clean up any existing objects. The argument is just for logging,
+ # it doesn't determine what's removed.
+ @resource.remove_existing(target)
- @resource.send(:property_fix)
+ raise Puppet::Error, "Could not remove existing file" if FileTest.exists?(@resource[:path])
- :link_created
+ Dir.chdir(File.dirname(@resource[:path])) do
+ Puppet::Util::SUIDManager.asuser(@resource.asuser) do
+ mode = @resource.should(:mode)
+ if mode
+ Puppet::Util.withumask(000) do
+ File.symlink(target, @resource[:path])
end
+ else
+ File.symlink(target, @resource[:path])
+ end
end
- def insync?(currentvalue)
- if [:nochange, :notlink].include?(self.should) or @resource.recurse?
- return true
- elsif ! @resource.replace? and File.exists?(@resource[:path])
- return true
- else
- return super(currentvalue)
- end
- end
+ @resource.send(:property_fix)
+ :link_created
+ end
+ end
- def retrieve
- if stat = @resource.stat
- if stat.ftype == "link"
- return File.readlink(@resource[:path])
- else
- return :notlink
- end
- else
- return :absent
- end
+ def insync?(currentvalue)
+ if [:nochange, :notlink].include?(self.should) or @resource.recurse?
+ return true
+ elsif ! @resource.replace? and File.exists?(@resource[:path])
+ return true
+ else
+ return super(currentvalue)
+ end
+ end
+
+
+ def retrieve
+ if stat = @resource.stat
+ if stat.ftype == "link"
+ return File.readlink(@resource[:path])
+ else
+ return :notlink
end
+ else
+ return :absent
+ end
end
+ end
end
diff --git a/lib/puppet/type/file/type.rb b/lib/puppet/type/file/type.rb
index 95470bb..eb50b81 100755
--- a/lib/puppet/type/file/type.rb
+++ b/lib/puppet/type/file/type.rb
@@ -1,26 +1,26 @@
module Puppet
- Puppet::Type.type(:file).newproperty(:type) do
- require 'etc'
- desc "A read-only state to check the file type."
+ Puppet::Type.type(:file).newproperty(:type) do
+ require 'etc'
+ desc "A read-only state to check the file type."
- #munge do |value|
- # raise Puppet::Error, ":type is read-only"
- #end
+ #munge do |value|
+ # raise Puppet::Error, ":type is read-only"
+ #end
- def retrieve
- currentvalue = :absent
- if stat = @resource.stat(false)
- currentvalue = stat.ftype
- end
- # so this state is never marked out of sync
- @should = [currentvalue]
- currentvalue
- end
+ def retrieve
+ currentvalue = :absent
+ if stat = @resource.stat(false)
+ currentvalue = stat.ftype
+ end
+ # so this state is never marked out of sync
+ @should = [currentvalue]
+ currentvalue
+ end
- def sync
- raise Puppet::Error, ":type is read-only"
- end
+ def sync
+ raise Puppet::Error, ":type is read-only"
end
+ end
end
diff --git a/lib/puppet/type/filebucket.rb b/lib/puppet/type/filebucket.rb
index 37ebd2d..65ff884 100755
--- a/lib/puppet/type/filebucket.rb
+++ b/lib/puppet/type/filebucket.rb
@@ -1,95 +1,95 @@
module Puppet
- require 'puppet/file_bucket/dipper'
-
- newtype(:filebucket) do
- @doc = "A repository for backing up files. If no filebucket is
- defined, then files will be backed up in their current directory,
- but the filebucket can be either a host- or site-global repository
- for backing up. It stores files and returns the MD5 sum, which
- can later be used to retrieve the file if restoration becomes
- necessary. A filebucket does not do any work itself; instead,
- it can be specified as the value of *backup* in a **file** object.
-
- Currently, filebuckets are only useful for manual retrieval of
- accidentally removed files (e.g., you look in the log for the md5 sum and retrieve the file with that sum from the filebucket), but
- when transactions are fully supported filebuckets will be used to
- undo transactions.
-
- You will normally want to define a single filebucket for your
- whole network and then use that as the default backup location::
-
- # Define the bucket
- filebucket { main: server => puppet }
-
- # Specify it as the default target
- File { backup => main }
-
- Puppetmaster servers create a filebucket by default, so this will
- work in a default configuration."
-
- newparam(:name) do
- desc "The name of the filebucket."
- isnamevar
- end
-
- newparam(:server) do
- desc "The server providing the remote filebucket. If this is not
- specified then *path* is checked. If it is set, then the
- bucket is local. Otherwise the puppetmaster server specified
- in the config or at the commandline is used."
- defaultto { Puppet[:server] }
- end
-
- newparam(:port) do
- desc "The port on which the remote server is listening.
- Defaults to the normal Puppet port, %s." % Puppet[:masterport]
-
- defaultto { Puppet[:masterport] }
- end
-
- newparam(:path) do
- desc "The path to the local filebucket. If this is
- unset, then the bucket is remote. The parameter *server* must
- can be specified to set the remote server."
-
- defaultto { Puppet[:clientbucketdir] }
- end
-
- # Create a default filebucket.
- def self.mkdefaultbucket
- new(:name => "puppet", :path => Puppet[:clientbucketdir])
- end
-
- def bucket
- mkbucket unless defined?(@bucket)
- @bucket
- end
-
- private
-
- def mkbucket
- # Default is a local filebucket, if no server is given.
- # If the default path has been removed, too, then
- # the puppetmaster is used as default server
-
- type = "local"
- args = {}
- if self[:path]
- args[:Path] = self[:path]
- else
- args[:Server] = self[:server]
- args[:Port] = self[:port]
- end
-
- begin
- @bucket = Puppet::FileBucket::Dipper.new(args)
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- self.fail("Could not create #{type} filebucket: #{detail}")
- end
-
- @bucket.name = self.name
- end
+ require 'puppet/file_bucket/dipper'
+
+ newtype(:filebucket) do
+ @doc = "A repository for backing up files. If no filebucket is
+ defined, then files will be backed up in their current directory,
+ but the filebucket can be either a host- or site-global repository
+ for backing up. It stores files and returns the MD5 sum, which
+ can later be used to retrieve the file if restoration becomes
+ necessary. A filebucket does not do any work itself; instead,
+ it can be specified as the value of *backup* in a **file** object.
+
+ Currently, filebuckets are only useful for manual retrieval of
+ accidentally removed files (e.g., you look in the log for the md5 sum and retrieve the file with that sum from the filebucket), but
+ when transactions are fully supported filebuckets will be used to
+ undo transactions.
+
+ You will normally want to define a single filebucket for your
+ whole network and then use that as the default backup location::
+
+ # Define the bucket
+ filebucket { main: server => puppet }
+
+ # Specify it as the default target
+ File { backup => main }
+
+ Puppetmaster servers create a filebucket by default, so this will
+ work in a default configuration."
+
+ newparam(:name) do
+ desc "The name of the filebucket."
+ isnamevar
+ end
+
+ newparam(:server) do
+ desc "The server providing the remote filebucket. If this is not
+ specified then *path* is checked. If it is set, then the
+ bucket is local. Otherwise the puppetmaster server specified
+ in the config or at the commandline is used."
+ defaultto { Puppet[:server] }
+ end
+
+ newparam(:port) do
+ desc "The port on which the remote server is listening.
+ Defaults to the normal Puppet port, %s." % Puppet[:masterport]
+
+ defaultto { Puppet[:masterport] }
+ end
+
+ newparam(:path) do
+ desc "The path to the local filebucket. If this is
+ unset, then the bucket is remote. The parameter *server* must
+ can be specified to set the remote server."
+
+ defaultto { Puppet[:clientbucketdir] }
+ end
+
+ # Create a default filebucket.
+ def self.mkdefaultbucket
+ new(:name => "puppet", :path => Puppet[:clientbucketdir])
+ end
+
+ def bucket
+ mkbucket unless defined?(@bucket)
+ @bucket
+ end
+
+ private
+
+ def mkbucket
+ # Default is a local filebucket, if no server is given.
+ # If the default path has been removed, too, then
+ # the puppetmaster is used as default server
+
+ type = "local"
+ args = {}
+ if self[:path]
+ args[:Path] = self[:path]
+ else
+ args[:Server] = self[:server]
+ args[:Port] = self[:port]
+ end
+
+ begin
+ @bucket = Puppet::FileBucket::Dipper.new(args)
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ self.fail("Could not create #{type} filebucket: #{detail}")
+ end
+
+ @bucket.name = self.name
end
+ end
end
diff --git a/lib/puppet/type/group.rb b/lib/puppet/type/group.rb
index 7cf031a..9f26d22 100755
--- a/lib/puppet/type/group.rb
+++ b/lib/puppet/type/group.rb
@@ -3,98 +3,98 @@ require 'etc'
require 'facter'
module Puppet
- newtype(:group) do
- @doc = "Manage groups. On most platforms this can only create groups.
- Group membership must be managed on individual users.
+ newtype(:group) do
+ @doc = "Manage groups. On most platforms this can only create groups.
+ Group membership must be managed on individual users.
- On some platforms such as OS X, group membership is managed as an
- attribute of the group, not the user record. Providers must have
- the feature 'manages_members' to manage the 'members' property of
- a group record."
+ On some platforms such as OS X, group membership is managed as an
+ attribute of the group, not the user record. Providers must have
+ the feature 'manages_members' to manage the 'members' property of
+ a group record."
- feature :manages_members,
- "For directories where membership is an attribute of groups not users."
+ feature :manages_members,
+ "For directories where membership is an attribute of groups not users."
- ensurable do
- desc "Create or remove the group."
+ ensurable do
+ desc "Create or remove the group."
- newvalue(:present) do
- provider.create
- end
+ newvalue(:present) do
+ provider.create
+ end
- newvalue(:absent) do
- provider.delete
- end
- end
+ newvalue(:absent) do
+ provider.delete
+ end
+ end
- newproperty(:gid) do
- desc "The group ID. Must be specified numerically. If not
- specified, a number will be picked, which can result in ID
- differences across systems and thus is not recommended. The
- GID is picked according to local system standards."
-
- def retrieve
- provider.gid
- end
-
- def sync
- if self.should == :absent
- raise Puppet::DevError, "GID cannot be deleted"
- else
- provider.gid = self.should
- end
- end
-
- munge do |gid|
- case gid
- when String
- if gid =~ /^[-0-9]+$/
- gid = Integer(gid)
- else
- self.fail "Invalid GID #{gid}"
- end
- when Symbol
- unless gid == :absent
- self.devfail "Invalid GID #{gid}"
- end
- end
-
- return gid
- end
+ newproperty(:gid) do
+ desc "The group ID. Must be specified numerically. If not
+ specified, a number will be picked, which can result in ID
+ differences across systems and thus is not recommended. The
+ GID is picked according to local system standards."
+
+ def retrieve
+ provider.gid
+ end
+
+ def sync
+ if self.should == :absent
+ raise Puppet::DevError, "GID cannot be deleted"
+ else
+ provider.gid = self.should
+ end
+ end
+
+ munge do |gid|
+ case gid
+ when String
+ if gid =~ /^[-0-9]+$/
+ gid = Integer(gid)
+ else
+ self.fail "Invalid GID #{gid}"
+ end
+ when Symbol
+ unless gid == :absent
+ self.devfail "Invalid GID #{gid}"
+ end
end
- newproperty(:members, :array_matching => :all, :required_features => :manages_members) do
- desc "The members of the group. For directory services where group
- membership is stored in the group objects, not the users."
+ return gid
+ end
+ end
- def change_to_s(currentvalue, newvalue)
- currentvalue = currentvalue.join(",") if currentvalue != :absent
- newvalue = newvalue.join(",")
- super(currentvalue, newvalue)
- end
- end
+ newproperty(:members, :array_matching => :all, :required_features => :manages_members) do
+ desc "The members of the group. For directory services where group
+ membership is stored in the group objects, not the users."
- newparam(:auth_membership) do
- desc "whether the provider is authoritative for group membership."
- defaultto true
- end
+ def change_to_s(currentvalue, newvalue)
+ currentvalue = currentvalue.join(",") if currentvalue != :absent
+ newvalue = newvalue.join(",")
+ super(currentvalue, newvalue)
+ end
+ end
- newparam(:name) do
- desc "The group name. While naming limitations vary by
- system, it is advisable to keep the name to the degenerate
- limitations, which is a maximum of 8 characters beginning with
- a letter."
- isnamevar
- end
+ newparam(:auth_membership) do
+ desc "whether the provider is authoritative for group membership."
+ defaultto true
+ end
- newparam(:allowdupe, :boolean => true) do
- desc "Whether to allow duplicate GIDs. This option does not work on
- FreeBSD (contract to the ``pw`` man page)."
+ newparam(:name) do
+ desc "The group name. While naming limitations vary by
+ system, it is advisable to keep the name to the degenerate
+ limitations, which is a maximum of 8 characters beginning with
+ a letter."
+ isnamevar
+ end
- newvalues(:true, :false)
+ newparam(:allowdupe, :boolean => true) do
+ desc "Whether to allow duplicate GIDs. This option does not work on
+ FreeBSD (contract to the ``pw`` man page)."
- defaultto false
- end
+ newvalues(:true, :false)
+
+ defaultto false
end
+ end
end
diff --git a/lib/puppet/type/host.rb b/lib/puppet/type/host.rb
index bd7d4bd..929542d 100755
--- a/lib/puppet/type/host.rb
+++ b/lib/puppet/type/host.rb
@@ -1,101 +1,101 @@
module Puppet
- newtype(:host) do
- ensurable
+ newtype(:host) do
+ ensurable
- newproperty(:ip) do
- desc "The host's IP address, IPv4 or IPv6."
+ newproperty(:ip) do
+ desc "The host's IP address, IPv4 or IPv6."
- validate do |value|
- unless value =~ /((([0-9a-fA-F]+:){7}[0-9a-fA-F]+)|(([0-9a-fA-F]+:)*[0-9a-fA-F]+)?::(([0-9a-fA-F]+:)*[0-9a-fA-F]+)?)|((25[0-5]|2[0-4][\d]|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})/
- raise Puppet::Error, "Invalid IP address"
- end
- end
+ validate do |value|
+ unless value =~ /((([0-9a-fA-F]+:){7}[0-9a-fA-F]+)|(([0-9a-fA-F]+:)*[0-9a-fA-F]+)?::(([0-9a-fA-F]+:)*[0-9a-fA-F]+)?)|((25[0-5]|2[0-4][\d]|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})/
+ raise Puppet::Error, "Invalid IP address"
+ end
+ end
- end
+ end
- newproperty(:host_aliases) do
- desc 'Any aliases the host might have. Multiple values must be
- specified as an array. Note that this property is not the same as
- the "alias" metaparam; use this property to add aliases to a host
- on disk, and "alias" to aliases for use in your Puppet scripts.'
-
- def insync?(is)
- is == @should
- end
-
- def is_to_s(currentvalue = @is)
- currentvalue = [currentvalue] unless currentvalue.is_a? Array
- currentvalue.join(" ")
- end
-
- def retrieve
- is = super
- case is
- when String
- is = is.split(/\s*,\s*/)
- when Symbol
- is = [is]
- when Array
- # nothing
- else
- raise Puppet::DevError, "Invalid @is type #{is.class}"
- end
- is
- end
-
- # We actually want to return the whole array here, not just the first
- # value.
- def should
- if defined?(@should)
- if @should == [:absent]
- return :absent
- else
- return @should
- end
- else
- return nil
- end
- end
-
- def should_to_s(newvalue = @should)
- newvalue.join(" ")
- end
-
- validate do |value|
- raise Puppet::Error, "Host aliases cannot include whitespace" if value =~ /\s/
- end
+ newproperty(:host_aliases) do
+ desc 'Any aliases the host might have. Multiple values must be
+ specified as an array. Note that this property is not the same as
+ the "alias" metaparam; use this property to add aliases to a host
+ on disk, and "alias" to aliases for use in your Puppet scripts.'
+
+ def insync?(is)
+ is == @should
+ end
+
+ def is_to_s(currentvalue = @is)
+ currentvalue = [currentvalue] unless currentvalue.is_a? Array
+ currentvalue.join(" ")
+ end
+
+ def retrieve
+ is = super
+ case is
+ when String
+ is = is.split(/\s*,\s*/)
+ when Symbol
+ is = [is]
+ when Array
+ # nothing
+ else
+ raise Puppet::DevError, "Invalid @is type #{is.class}"
+ end
+ is
+ end
+
+ # We actually want to return the whole array here, not just the first
+ # value.
+ def should
+ if defined?(@should)
+ if @should == [:absent]
+ return :absent
+ else
+ return @should
+ end
+ else
+ return nil
end
+ end
- newproperty(:target) do
- desc "The file in which to store service information. Only used by
- those providers that write to disk."
+ def should_to_s(newvalue = @should)
+ newvalue.join(" ")
+ end
- defaultto { if @resource.class.defaultprovider.ancestors.include?(Puppet::Provider::ParsedFile)
- @resource.class.defaultprovider.default_target
- else
- nil
- end
- }
+ validate do |value|
+ raise Puppet::Error, "Host aliases cannot include whitespace" if value =~ /\s/
+ end
+ end
+
+ newproperty(:target) do
+ desc "The file in which to store service information. Only used by
+ those providers that write to disk."
+
+ defaultto { if @resource.class.defaultprovider.ancestors.include?(Puppet::Provider::ParsedFile)
+ @resource.class.defaultprovider.default_target
+ else
+ nil
end
+ }
+ end
- newparam(:name) do
- desc "The host name."
+ newparam(:name) do
+ desc "The host name."
- isnamevar
+ isnamevar
- validate do |value|
- # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
- x = value.split('.').each do |hostpart|
- unless hostpart =~ /^([\d\w]+|[\d\w][\d\w\-]+[\d\w])$/
- raise Puppet::Error, "Invalid host name"
- end
- end
- end
+ validate do |value|
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = value.split('.').each do |hostpart|
+ unless hostpart =~ /^([\d\w]+|[\d\w][\d\w\-]+[\d\w])$/
+ raise Puppet::Error, "Invalid host name"
+ end
end
-
- @doc = "Installs and manages host entries. For most systems, these
- entries will just be in ``/etc/hosts``, but some systems (notably OS X)
- will have different solutions."
+ end
end
+
+ @doc = "Installs and manages host entries. For most systems, these
+ entries will just be in ``/etc/hosts``, but some systems (notably OS X)
+ will have different solutions."
+ end
end
diff --git a/lib/puppet/type/k5login.rb b/lib/puppet/type/k5login.rb
index e192ce4..850e377 100644
--- a/lib/puppet/type/k5login.rb
+++ b/lib/puppet/type/k5login.rb
@@ -3,85 +3,85 @@
# Plug-in type for handling k5login files
Puppet::Type.newtype(:k5login) do
- @doc = "Manage the .k5login file for a user. Specify the full path to
- the .k5login file as the name and an array of principals as the
- property principals."
+ @doc = "Manage the .k5login file for a user. Specify the full path to
+ the .k5login file as the name and an array of principals as the
+ property principals."
- ensurable
+ ensurable
- # Principals that should exist in the file
- newproperty(:principals, :array_matching => :all) do
- desc "The principals present in the .k5login file."
- end
+ # Principals that should exist in the file
+ newproperty(:principals, :array_matching => :all) do
+ desc "The principals present in the .k5login file."
+ end
- # The path/name of the k5login file
- newparam(:path) do
- isnamevar
- desc "The path to the file to manage. Must be fully qualified."
+ # The path/name of the k5login file
+ newparam(:path) do
+ isnamevar
+ desc "The path to the file to manage. Must be fully qualified."
- validate do |value|
- unless value =~ /^#{File::SEPARATOR}/
- raise Puppet::Error, "File paths must be fully qualified"
- end
- end
+ validate do |value|
+ unless value =~ /^#{File::SEPARATOR}/
+ raise Puppet::Error, "File paths must be fully qualified"
+ end
end
+ end
- # To manage the mode of the file
- newproperty(:mode) do
- desc "Manage the k5login file's mode"
- defaultto { "644" }
- end
+ # To manage the mode of the file
+ newproperty(:mode) do
+ desc "Manage the k5login file's mode"
+ defaultto { "644" }
+ end
- provide(:k5login) do
- desc "The k5login provider is the only provider for the k5login
- type."
+ provide(:k5login) do
+ desc "The k5login provider is the only provider for the k5login
+ type."
- # Does this file exist?
- def exists?
- File.exists?(@resource[:name])
- end
+ # Does this file exist?
+ def exists?
+ File.exists?(@resource[:name])
+ end
- # create the file
- def create
- write(@resource.should(:principals))
- should_mode = @resource.should(:mode)
- unless self.mode == should_mode
- self.mode = should_mode
- end
- end
+ # create the file
+ def create
+ write(@resource.should(:principals))
+ should_mode = @resource.should(:mode)
+ unless self.mode == should_mode
+ self.mode = should_mode
+ end
+ end
- # remove the file
- def destroy
- File.unlink(@resource[:name])
- end
+ # remove the file
+ def destroy
+ File.unlink(@resource[:name])
+ end
- # Return the principals
- def principals(dummy_argument=:work_arround_for_ruby_GC_bug)
- if File.exists?(@resource[:name])
- File.readlines(@resource[:name]).collect { |line| line.chomp }
- else
- :absent
- end
- end
+ # Return the principals
+ def principals(dummy_argument=:work_arround_for_ruby_GC_bug)
+ if File.exists?(@resource[:name])
+ File.readlines(@resource[:name]).collect { |line| line.chomp }
+ else
+ :absent
+ end
+ end
- # Write the principals out to the k5login file
- def principals=(value)
- write(value)
- end
+ # Write the principals out to the k5login file
+ def principals=(value)
+ write(value)
+ end
- # Return the mode as an octal string, not as an integer
- def mode
- "%o" % (File.stat(@resource[:name]).mode & 007777)
- end
+ # Return the mode as an octal string, not as an integer
+ def mode
+ "%o" % (File.stat(@resource[:name]).mode & 007777)
+ end
- # Set the file mode, converting from a string to an integer.
- def mode=(value)
- File.chmod(Integer("0#{value}"), @resource[:name])
- end
+ # Set the file mode, converting from a string to an integer.
+ def mode=(value)
+ File.chmod(Integer("0#{value}"), @resource[:name])
+ end
- private
- def write(value)
- File.open(@resource[:name], "w") { |f| f.puts value.join("\n") }
- end
+ private
+ def write(value)
+ File.open(@resource[:name], "w") { |f| f.puts value.join("\n") }
end
+ end
end
diff --git a/lib/puppet/type/macauthorization.rb b/lib/puppet/type/macauthorization.rb
index 5fe64fa..9b17c27 100644
--- a/lib/puppet/type/macauthorization.rb
+++ b/lib/puppet/type/macauthorization.rb
@@ -1,164 +1,164 @@
Puppet::Type.newtype(:macauthorization) do
- @doc = "Manage the Mac OS X authorization database.
- See:
- http://developer.apple.com/documentation/Security/Conceptual/Security_Overview/Security_Services/chapter_4_section_5.html for more information."
+ @doc = "Manage the Mac OS X authorization database.
+ See:
+ http://developer.apple.com/documentation/Security/Conceptual/Security_Overview/Security_Services/chapter_4_section_5.html for more information."
+
+ ensurable
+
+ autorequire(:file) do
+ ["/etc/authorization"]
+ end
+
+ def munge_boolean(value)
+ case value
+ when true, "true", :true
+ :true
+ when false, "false", :false
+ :false
+ else
+ fail("munge_boolean only takes booleans")
+ end
+ end
+
+ def munge_integer(value)
+ Integer(value)
+ rescue ArgumentError
+ fail("munge_integer only takes integers")
+ end
- ensurable
+ newparam(:name) do
+ desc "The name of the right or rule to be managed.
+ Corresponds to 'key' in Authorization Services. The key is the name
+ of a rule. A key uses the same naming conventions as a right. The
+ Security Server uses a ruleâs key to match the rule with a right.
+ Wildcard keys end with a â.â. The generic rule has an empty key value.
+ Any rights that do not match a specific rule use the generic rule."
+
+ isnamevar
+ end
+
+ newproperty(:auth_type) do
+ desc "type - can be a 'right' or a 'rule'. 'comment' has not yet been
+ implemented."
- autorequire(:file) do
- ["/etc/authorization"]
- end
-
- def munge_boolean(value)
- case value
- when true, "true", :true
- :true
- when false, "false", :false
- :false
- else
- fail("munge_boolean only takes booleans")
- end
- end
-
- def munge_integer(value)
- Integer(value)
- rescue ArgumentError
- fail("munge_integer only takes integers")
- end
-
- newparam(:name) do
- desc "The name of the right or rule to be managed.
- Corresponds to 'key' in Authorization Services. The key is the name
- of a rule. A key uses the same naming conventions as a right. The
- Security Server uses a ruleâs key to match the rule with a right.
- Wildcard keys end with a â.â. The generic rule has an empty key value.
- Any rights that do not match a specific rule use the generic rule."
+ newvalue(:right)
+ newvalue(:rule)
+ # newvalue(:comment) # not yet implemented.
+ end
+
+ newproperty(:allow_root, :boolean => true) do
+ desc "Corresponds to 'allow-root' in the authorization store, renamed
+ due to hyphens being problematic. Specifies whether a right should be
+ allowed automatically if the requesting process is running with
+ uid == 0. AuthorizationServices defaults this attribute to false if
+ not specified"
- isnamevar
+ newvalue(:true)
+ newvalue(:false)
+
+ munge do |value|
+ @resource.munge_boolean(value)
+ end
+ end
+
+ newproperty(:authenticate_user, :boolean => true) do
+ desc "Corresponds to 'authenticate-user' in the authorization store,
+ renamed due to hyphens being problematic."
+
+ newvalue(:true)
+ newvalue(:false)
+
+ munge do |value|
+ @resource.munge_boolean(value)
+ end
+ end
+
+ newproperty(:auth_class) do
+ desc "Corresponds to 'class' in the authorization store, renamed due
+ to 'class' being a reserved word."
+
+ newvalue(:user)
+ newvalue(:'evaluate-mechanisms')
+ newvalue(:allow)
+ newvalue(:deny)
+ newvalue(:rule)
+ end
+
+ newproperty(:comment) do
+ desc "The 'comment' attribute for authorization resources."
+ end
+
+ newproperty(:group) do
+ desc "The user must authenticate as a member of this group. This
+ attribute can be set to any one group."
+ end
+
+ newproperty(:k_of_n) do
+ desc "k-of-n describes how large a subset of rule mechanisms must
+ succeed for successful authentication. If there are 'n' mechanisms,
+ then 'k' (the integer value of this parameter) mechanisms must succeed.
+ The most common setting for this parameter is '1'. If k-of-n is not
+ set, then 'n-of-n' mechanisms must succeed."
+
+ munge do |value|
+ @resource.munge_integer(value)
end
+ end
- newproperty(:auth_type) do
- desc "type - can be a 'right' or a 'rule'. 'comment' has not yet been
- implemented."
-
- newvalue(:right)
- newvalue(:rule)
- # newvalue(:comment) # not yet implemented.
- end
+ newproperty(:mechanisms, :array_matching => :all) do
+ desc "an array of suitable mechanisms."
+ end
- newproperty(:allow_root, :boolean => true) do
- desc "Corresponds to 'allow-root' in the authorization store, renamed
- due to hyphens being problematic. Specifies whether a right should be
- allowed automatically if the requesting process is running with
- uid == 0. AuthorizationServices defaults this attribute to false if
- not specified"
-
- newvalue(:true)
- newvalue(:false)
-
- munge do |value|
- @resource.munge_boolean(value)
- end
- end
-
- newproperty(:authenticate_user, :boolean => true) do
- desc "Corresponds to 'authenticate-user' in the authorization store,
- renamed due to hyphens being problematic."
-
- newvalue(:true)
- newvalue(:false)
-
- munge do |value|
- @resource.munge_boolean(value)
- end
- end
-
- newproperty(:auth_class) do
- desc "Corresponds to 'class' in the authorization store, renamed due
- to 'class' being a reserved word."
-
- newvalue(:user)
- newvalue(:'evaluate-mechanisms')
- newvalue(:allow)
- newvalue(:deny)
- newvalue(:rule)
- end
-
- newproperty(:comment) do
- desc "The 'comment' attribute for authorization resources."
- end
-
- newproperty(:group) do
- desc "The user must authenticate as a member of this group. This
- attribute can be set to any one group."
- end
-
- newproperty(:k_of_n) do
- desc "k-of-n describes how large a subset of rule mechanisms must
- succeed for successful authentication. If there are 'n' mechanisms,
- then 'k' (the integer value of this parameter) mechanisms must succeed.
- The most common setting for this parameter is '1'. If k-of-n is not
- set, then 'n-of-n' mechanisms must succeed."
-
- munge do |value|
- @resource.munge_integer(value)
- end
- end
-
- newproperty(:mechanisms, :array_matching => :all) do
- desc "an array of suitable mechanisms."
- end
-
- newproperty(:rule, :array_matching => :all) do
- desc "The rule(s) that this right refers to."
- end
+ newproperty(:rule, :array_matching => :all) do
+ desc "The rule(s) that this right refers to."
+ end
- newproperty(:session_owner, :boolean => true) do
- desc "Corresponds to 'session-owner' in the authorization store,
- renamed due to hyphens being problematic. Whether the session owner
- automatically matches this rule or right."
+ newproperty(:session_owner, :boolean => true) do
+ desc "Corresponds to 'session-owner' in the authorization store,
+ renamed due to hyphens being problematic. Whether the session owner
+ automatically matches this rule or right."
- newvalue(:true)
- newvalue(:false)
+ newvalue(:true)
+ newvalue(:false)
- munge do |value|
- @resource.munge_boolean(value)
- end
+ munge do |value|
+ @resource.munge_boolean(value)
end
+ end
- newproperty(:shared, :boolean => true) do
- desc "If this is set to true, then the Security Server marks the
- credentials used to gain this right as shared. The Security Server
- may use any shared credentials to authorize this right. For maximum
- security, set sharing to false so credentials stored by the Security
- Server for one application may not be used by another application."
+ newproperty(:shared, :boolean => true) do
+ desc "If this is set to true, then the Security Server marks the
+ credentials used to gain this right as shared. The Security Server
+ may use any shared credentials to authorize this right. For maximum
+ security, set sharing to false so credentials stored by the Security
+ Server for one application may not be used by another application."
- newvalue(:true)
- newvalue(:false)
+ newvalue(:true)
+ newvalue(:false)
- munge do |value|
- @resource.munge_boolean(value)
- end
+ munge do |value|
+ @resource.munge_boolean(value)
end
+ end
- newproperty(:timeout) do
- desc "The credential used by this rule expires in the specified
- number of seconds. For maximum security where the user must
- authenticate every time, set the timeout to 0. For minimum security,
- remove the timeout attribute so the user authenticates only once per
- session."
+ newproperty(:timeout) do
+ desc "The credential used by this rule expires in the specified
+ number of seconds. For maximum security where the user must
+ authenticate every time, set the timeout to 0. For minimum security,
+ remove the timeout attribute so the user authenticates only once per
+ session."
- munge do |value|
- @resource.munge_integer(value)
- end
+ munge do |value|
+ @resource.munge_integer(value)
end
+ end
- newproperty(:tries) do
- desc "The number of tries allowed."
- munge do |value|
- @resource.munge_integer(value)
- end
+ newproperty(:tries) do
+ desc "The number of tries allowed."
+ munge do |value|
+ @resource.munge_integer(value)
end
+ end
end
diff --git a/lib/puppet/type/mailalias.rb b/lib/puppet/type/mailalias.rb
index 1044374..5534fdf 100755
--- a/lib/puppet/type/mailalias.rb
+++ b/lib/puppet/type/mailalias.rb
@@ -1,49 +1,49 @@
module Puppet
- newtype(:mailalias) do
- @doc = "Creates an email alias in the local alias database."
+ newtype(:mailalias) do
+ @doc = "Creates an email alias in the local alias database."
- ensurable
+ ensurable
- newparam(:name, :namevar => true) do
- desc "The alias name."
+ newparam(:name, :namevar => true) do
+ desc "The alias name."
+ end
+
+ newproperty(:recipient, :array_matching => :all) do
+ desc "Where email should be sent. Multiple values
+ should be specified as an array."
+
+ def is_to_s(value)
+ if value.include?(:absent)
+ super
+ else
+ value.join(",")
end
+ end
- newproperty(:recipient, :array_matching => :all) do
- desc "Where email should be sent. Multiple values
- should be specified as an array."
-
- def is_to_s(value)
- if value.include?(:absent)
- super
- else
- value.join(",")
- end
- end
-
- def should
- @should
- end
-
- def should_to_s(value)
- if value.include?(:absent)
- super
- else
- value.join(",")
- end
- end
+ def should
+ @should
+ end
+
+ def should_to_s(value)
+ if value.include?(:absent)
+ super
+ else
+ value.join(",")
end
+ end
+ end
- newproperty(:target) do
- desc "The file in which to store the aliases. Only used by
- those providers that write to disk."
+ newproperty(:target) do
+ desc "The file in which to store the aliases. Only used by
+ those providers that write to disk."
- defaultto { if @resource.class.defaultprovider.ancestors.include?(Puppet::Provider::ParsedFile)
- @resource.class.defaultprovider.default_target
- else
- nil
- end
- }
+ defaultto { if @resource.class.defaultprovider.ancestors.include?(Puppet::Provider::ParsedFile)
+ @resource.class.defaultprovider.default_target
+ else
+ nil
end
+ }
end
+ end
end
diff --git a/lib/puppet/type/maillist.rb b/lib/puppet/type/maillist.rb
index af5ed51..7ac0e4e 100755
--- a/lib/puppet/type/maillist.rb
+++ b/lib/puppet/type/maillist.rb
@@ -1,63 +1,63 @@
module Puppet
- newtype(:maillist) do
- @doc = "Manage email lists. This resource type currently can only create
- and remove lists, it cannot reconfigure them."
-
- ensurable do
- defaultvalues
-
- newvalue(:purged) do
- provider.purge
- end
-
- def change_to_s(current_value, newvalue)
- return "Purged #{resource}" if newvalue == :purged
- super
- end
-
- def insync?(is)
- return true if is == :absent && should == :purged
- super
- end
- end
+ newtype(:maillist) do
+ @doc = "Manage email lists. This resource type currently can only create
+ and remove lists, it cannot reconfigure them."
+
+ ensurable do
+ defaultvalues
+
+ newvalue(:purged) do
+ provider.purge
+ end
+
+ def change_to_s(current_value, newvalue)
+ return "Purged #{resource}" if newvalue == :purged
+ super
+ end
+
+ def insync?(is)
+ return true if is == :absent && should == :purged
+ super
+ end
+ end
- newparam(:name, :namevar => true) do
- desc "The name of the email list."
- end
+ newparam(:name, :namevar => true) do
+ desc "The name of the email list."
+ end
- newparam(:description) do
- desc "The description of the mailing list."
- end
+ newparam(:description) do
+ desc "The description of the mailing list."
+ end
- newparam(:password) do
- desc "The admin password."
- end
+ newparam(:password) do
+ desc "The admin password."
+ end
- newparam(:webserver) do
- desc "The name of the host providing web archives and the administrative interface."
- end
+ newparam(:webserver) do
+ desc "The name of the host providing web archives and the administrative interface."
+ end
- newparam(:mailserver) do
- desc "The name of the host handling email for the list."
- end
+ newparam(:mailserver) do
+ desc "The name of the host handling email for the list."
+ end
- newparam(:admin) do
- desc "The email address of the administrator."
- end
+ newparam(:admin) do
+ desc "The email address of the administrator."
+ end
- def generate
- if provider.respond_to?(:aliases)
- should = self.should(:ensure) || :present
- if should == :purged
- should = :absent
- end
- atype = Puppet::Type.type(:mailalias)
-
- provider.aliases.
- reject { |name,recipient| catalog.resource(:mailalias, name) }.
- collect { |name,recipient| atype.new(:name => name, :recipient => recipient, :ensure => should) }
- end
+ def generate
+ if provider.respond_to?(:aliases)
+ should = self.should(:ensure) || :present
+ if should == :purged
+ should = :absent
end
+ atype = Puppet::Type.type(:mailalias)
+
+ provider.aliases.
+ reject { |name,recipient| catalog.resource(:mailalias, name) }.
+ collect { |name,recipient| atype.new(:name => name, :recipient => recipient, :ensure => should) }
+ end
end
+ end
end
diff --git a/lib/puppet/type/mcx.rb b/lib/puppet/type/mcx.rb
index 6e02669..e56b119 100644
--- a/lib/puppet/type/mcx.rb
+++ b/lib/puppet/type/mcx.rb
@@ -19,7 +19,7 @@
Puppet::Type.newtype(:mcx) do
- @doc = "MCX object management using DirectoryService on OS X.
+ @doc = "MCX object management using DirectoryService on OS X.
Original Author: Jeff McCune <mccune.jeff at gmail.com>
@@ -32,84 +32,84 @@ to manage users and groups on the local computer, record the resulting
puppet manifest using the command 'ralsh mcx' then deploying this
to other machines.
"
- feature :manages_content, \
- "The provider can manage MCXSettings as a string.",
- :methods => [:content, :content=]
+ feature :manages_content, \
+ "The provider can manage MCXSettings as a string.",
+ :methods => [:content, :content=]
- ensurable do
- desc "Create or remove the MCX setting."
+ ensurable do
+ desc "Create or remove the MCX setting."
- newvalue(:present) do
- provider.create
- end
-
- newvalue(:absent) do
- provider.destroy
- end
+ newvalue(:present) do
+ provider.create
+ end
+ newvalue(:absent) do
+ provider.destroy
end
- newparam(:name) do
- desc "The name of the resource being managed.
- The default naming convention follows Directory Service paths::
+ end
- /Computers/localhost
- /Groups/admin
- /Users/localadmin
+ newparam(:name) do
+ desc "The name of the resource being managed.
+ The default naming convention follows Directory Service paths::
- The ds_type and ds_name type parameters are not necessary if the
- default naming convention is followed."
- isnamevar
- end
+ /Computers/localhost
+ /Groups/admin
+ /Users/localadmin
- newparam(:ds_type) do
+ The ds_type and ds_name type parameters are not necessary if the
+ default naming convention is followed."
+ isnamevar
+ end
- desc "The DirectoryService type this MCX setting attaches to."
+ newparam(:ds_type) do
- newvalues(:user, :group, :computer, :computerlist)
+ desc "The DirectoryService type this MCX setting attaches to."
- end
+ newvalues(:user, :group, :computer, :computerlist)
- newparam(:ds_name) do
- desc "The name to attach the MCX Setting to.
- e.g. 'localhost' when ds_type => computer. This setting is not
- required, as it may be parsed so long as the resource name is
- parseable. e.g. /Groups/admin where 'group' is the dstype."
- end
+ end
- newproperty(:content, :required_features => :manages_content) do
- desc "The XML Plist. The value of MCXSettings in DirectoryService.
- This is the standard output from the system command:
- dscl localhost -mcxexport /Local/Default/<ds_type>/ds_name
- Note that ds_type is capitalized and plural in the dscl command."
- end
+ newparam(:ds_name) do
+ desc "The name to attach the MCX Setting to.
+ e.g. 'localhost' when ds_type => computer. This setting is not
+ required, as it may be parsed so long as the resource name is
+ parseable. e.g. /Groups/admin where 'group' is the dstype."
+ end
- # JJM Yes, this is not DRY at all. Because of the code blocks
- # autorequire must be done this way. I think.
-
- def setup_autorequire(type)
- # value returns a Symbol
- name = value(:name)
- ds_type = value(:ds_type)
- ds_name = value(:ds_name)
- if ds_type == type
- rval = [ ds_name.to_s ]
- else
- rval = [ ]
- end
- rval
- end
+ newproperty(:content, :required_features => :manages_content) do
+ desc "The XML Plist. The value of MCXSettings in DirectoryService.
+ This is the standard output from the system command:
+ dscl localhost -mcxexport /Local/Default/<ds_type>/ds_name
+ Note that ds_type is capitalized and plural in the dscl command."
+ end
- autorequire(:user) do
- setup_autorequire(:user)
- end
+ # JJM Yes, this is not DRY at all. Because of the code blocks
+ # autorequire must be done this way. I think.
- autorequire(:group) do
- setup_autorequire(:group)
+ def setup_autorequire(type)
+ # value returns a Symbol
+ name = value(:name)
+ ds_type = value(:ds_type)
+ ds_name = value(:ds_name)
+ if ds_type == type
+ rval = [ ds_name.to_s ]
+ else
+ rval = [ ]
end
+ rval
+ end
- autorequire(:computer) do
- setup_autorequire(:computer)
- end
+ autorequire(:user) do
+ setup_autorequire(:user)
+ end
+
+ autorequire(:group) do
+ setup_autorequire(:group)
+ end
+
+ autorequire(:computer) do
+ setup_autorequire(:computer)
+ end
end
diff --git a/lib/puppet/type/mount.rb b/lib/puppet/type/mount.rb
index cf9b408..6ee5dd1 100755
--- a/lib/puppet/type/mount.rb
+++ b/lib/puppet/type/mount.rb
@@ -1,225 +1,225 @@
module Puppet
- # We want the mount to refresh when it changes.
- newtype(:mount, :self_refresh => true) do
- @doc = "Manages mounted filesystems, including putting mount
- information into the mount table. The actual behavior depends
- on the value of the 'ensure' parameter.
-
- Note that if a ``mount`` receives an event from another resource,
- it will try to remount the filesystems if ``ensure`` is set to ``mounted``."
-
- feature :refreshable, "The provider can remount the filesystem.",
- :methods => [:remount]
-
- # Use the normal parent class, because we actually want to
- # call code when sync is called.
- newproperty(:ensure) do
- desc "Control what to do with this mount. Set this attribute to
- ``umounted`` to make sure the filesystem is in the filesystem table
- but not mounted (if the filesystem is currently mounted, it will be unmounted). Set it to ``absent`` to unmount (if necessary) and remove
- the filesystem from the fstab. Set to ``mounted`` to add it to the
- fstab and mount it. Set to ``present`` to add to fstab but not change
- mount/unmount status"
-
- newvalue(:defined) do
- provider.create
- return :mount_created
- end
-
- aliasvalue :present, :defined
-
- newvalue(:unmounted) do
- if provider.mounted?
- syncothers
- provider.unmount
- return :mount_unmounted
- else
- provider.create
- return :mount_created
- end
- end
-
- newvalue(:absent, :event => :mount_deleted) do
- provider.unmount if provider.mounted?
-
- provider.destroy
- end
-
- newvalue(:mounted, :event => :mount_mounted) do
- # Create the mount point if it does not already exist.
- current_value = self.retrieve
- provider.create if current_value.nil? or current_value == :absent
-
- syncothers
-
- # The fs can be already mounted if it was absent but mounted
- provider.mount unless provider.mounted?
- end
-
- def insync?(is)
- if should == :defined and is != :absent
- true
- else
- super
- end
- end
-
- def retrieve
- # We need to special case :mounted; if we're absent, we still
- # want
- curval = super()
- if curval == :absent
- return :absent
- elsif provider.mounted?
- return :mounted
- else
- return :unmounted
- end
- end
-
- def syncothers
- # We have to flush any changes to disk.
- currentvalues = @resource.retrieve_resource
-
- # Determine if there are any out-of-sync properties.
- oos = @resource.send(:properties).find_all do |prop|
- unless currentvalues.include?(prop)
- raise Puppet::DevError, "Parent has property %s but it doesn't appear in the current values", [prop.name]
- end
- if prop.name == :ensure
- false
- else
- ! prop.insync?(currentvalues[prop])
- end
- end.each { |prop| prop.sync }.length
- @resource.flush if oos > 0
- end
+ # We want the mount to refresh when it changes.
+ newtype(:mount, :self_refresh => true) do
+ @doc = "Manages mounted filesystems, including putting mount
+ information into the mount table. The actual behavior depends
+ on the value of the 'ensure' parameter.
+
+ Note that if a ``mount`` receives an event from another resource,
+ it will try to remount the filesystems if ``ensure`` is set to ``mounted``."
+
+ feature :refreshable, "The provider can remount the filesystem.",
+ :methods => [:remount]
+
+ # Use the normal parent class, because we actually want to
+ # call code when sync is called.
+ newproperty(:ensure) do
+ desc "Control what to do with this mount. Set this attribute to
+ ``umounted`` to make sure the filesystem is in the filesystem table
+ but not mounted (if the filesystem is currently mounted, it will be unmounted). Set it to ``absent`` to unmount (if necessary) and remove
+ the filesystem from the fstab. Set to ``mounted`` to add it to the
+ fstab and mount it. Set to ``present`` to add to fstab but not change
+ mount/unmount status"
+
+ newvalue(:defined) do
+ provider.create
+ return :mount_created
+ end
+
+ aliasvalue :present, :defined
+
+ newvalue(:unmounted) do
+ if provider.mounted?
+ syncothers
+ provider.unmount
+ return :mount_unmounted
+ else
+ provider.create
+ return :mount_created
end
+ end
- newproperty(:device) do
- desc "The device providing the mount. This can be whatever
- device is supporting by the mount, including network
- devices or devices specified by UUID rather than device
- path, depending on the operating system."
- end
+ newvalue(:absent, :event => :mount_deleted) do
+ provider.unmount if provider.mounted?
- # Solaris specifies two devices, not just one.
- newproperty(:blockdevice) do
- desc "The device to fsck. This is property is only valid
- on Solaris, and in most cases will default to the correct
- value."
-
- # Default to the device but with "dsk" replaced with "rdsk".
- defaultto do
- if Facter["operatingsystem"].value == "Solaris"
- device = @resource.value(:device)
- if device =~ %r{/dsk/}
- device.sub(%r{/dsk/}, "/rdsk/")
- else
- nil
- end
- else
- nil
- end
- end
- end
+ provider.destroy
+ end
- newproperty(:fstype) do
- desc "The mount type. Valid values depend on the
- operating system. This is a required option."
- end
+ newvalue(:mounted, :event => :mount_mounted) do
+ # Create the mount point if it does not already exist.
+ current_value = self.retrieve
+ provider.create if current_value.nil? or current_value == :absent
- newproperty(:options) do
- desc "Mount options for the mounts, as they would
- appear in the fstab."
- end
+ syncothers
- newproperty(:pass) do
- desc "The pass in which the mount is checked."
+ # The fs can be already mounted if it was absent but mounted
+ provider.mount unless provider.mounted?
+ end
- defaultto {
- 0 if @resource.managed?
- }
+ def insync?(is)
+ if should == :defined and is != :absent
+ true
+ else
+ super
end
+ end
+
+ def retrieve
+ # We need to special case :mounted; if we're absent, we still
+ # want
+ curval = super()
+ if curval == :absent
+ return :absent
+ elsif provider.mounted?
+ return :mounted
+ else
+ return :unmounted
+ end
+ end
+
+ def syncothers
+ # We have to flush any changes to disk.
+ currentvalues = @resource.retrieve_resource
+
+ # Determine if there are any out-of-sync properties.
+ oos = @resource.send(:properties).find_all do |prop|
+ unless currentvalues.include?(prop)
+ raise Puppet::DevError, "Parent has property %s but it doesn't appear in the current values", [prop.name]
+ end
+ if prop.name == :ensure
+ false
+ else
+ ! prop.insync?(currentvalues[prop])
+ end
+ end.each { |prop| prop.sync }.length
+ @resource.flush if oos > 0
+ end
+ end
+
+ newproperty(:device) do
+ desc "The device providing the mount. This can be whatever
+ device is supporting by the mount, including network
+ devices or devices specified by UUID rather than device
+ path, depending on the operating system."
+ end
- newproperty(:atboot) do
- desc "Whether to mount the mount at boot. Not all platforms
- support this."
+ # Solaris specifies two devices, not just one.
+ newproperty(:blockdevice) do
+ desc "The device to fsck. This is property is only valid
+ on Solaris, and in most cases will default to the correct
+ value."
+
+ # Default to the device but with "dsk" replaced with "rdsk".
+ defaultto do
+ if Facter["operatingsystem"].value == "Solaris"
+ device = @resource.value(:device)
+ if device =~ %r{/dsk/}
+ device.sub(%r{/dsk/}, "/rdsk/")
+ else
+ nil
+ end
+ else
+ nil
end
+ end
+ end
- newproperty(:dump) do
- desc "Whether to dump the mount. Not all platform support this.
- Valid values are ``1`` or ``0``. or ``2`` on FreeBSD, Default is ``0``."
+ newproperty(:fstype) do
+ desc "The mount type. Valid values depend on the
+ operating system. This is a required option."
+ end
- if Facter["operatingsystem"].value == "FreeBSD"
- newvalue(%r{(0|1|2)})
- else
- newvalue(%r{(0|1)})
- end
+ newproperty(:options) do
+ desc "Mount options for the mounts, as they would
+ appear in the fstab."
+ end
- newvalue(%r{(0|1)})
+ newproperty(:pass) do
+ desc "The pass in which the mount is checked."
- defaultto {
- 0 if @resource.managed?
- }
- end
+ defaultto {
+ 0 if @resource.managed?
+ }
+ end
- newproperty(:target) do
- desc "The file in which to store the mount table. Only used by
- those providers that write to disk."
+ newproperty(:atboot) do
+ desc "Whether to mount the mount at boot. Not all platforms
+ support this."
+ end
- defaultto { if @resource.class.defaultprovider.ancestors.include?(Puppet::Provider::ParsedFile)
- @resource.class.defaultprovider.default_target
- else
- nil
- end
- }
- end
+ newproperty(:dump) do
+ desc "Whether to dump the mount. Not all platform support this.
+ Valid values are ``1`` or ``0``. or ``2`` on FreeBSD, Default is ``0``."
- newparam(:name) do
- desc "The mount path for the mount."
+ if Facter["operatingsystem"].value == "FreeBSD"
+ newvalue(%r{(0|1|2)})
+ else
+ newvalue(%r{(0|1)})
+ end
- isnamevar
- end
+ newvalue(%r{(0|1)})
- newparam(:path) do
- desc "The deprecated name for the mount point. Please use ``name`` now."
+ defaultto {
+ 0 if @resource.managed?
+ }
+ end
- def value=(value)
- warning "'path' is deprecated for mounts. Please use 'name'."
- @resource[:name] = value
- super
- end
- end
+ newproperty(:target) do
+ desc "The file in which to store the mount table. Only used by
+ those providers that write to disk."
- newparam(:remounts) do
- desc "Whether the mount can be remounted ``mount -o remount``. If
- this is false, then the filesystem will be unmounted and remounted
- manually, which is prone to failure."
-
- newvalues(:true, :false)
- defaultto do
- case Facter.value(:operatingsystem)
- when "FreeBSD", "Darwin"
- false
- else
- true
- end
- end
+ defaultto { if @resource.class.defaultprovider.ancestors.include?(Puppet::Provider::ParsedFile)
+ @resource.class.defaultprovider.default_target
+ else
+ nil
end
+ }
+ end
- def refresh
- # Only remount if we're supposed to be mounted.
- provider.remount if self.should(:fstype) != "swap" and provider.mounted?
- end
+ newparam(:name) do
+ desc "The mount path for the mount."
+
+ isnamevar
+ end
- def value(name)
- name = symbolize(name)
- ret = nil
- if property = @parameters[name]
- return property.value
- end
+ newparam(:path) do
+ desc "The deprecated name for the mount point. Please use ``name`` now."
+
+ def value=(value)
+ warning "'path' is deprecated for mounts. Please use 'name'."
+ @resource[:name] = value
+ super
+ end
+ end
+
+ newparam(:remounts) do
+ desc "Whether the mount can be remounted ``mount -o remount``. If
+ this is false, then the filesystem will be unmounted and remounted
+ manually, which is prone to failure."
+
+ newvalues(:true, :false)
+ defaultto do
+ case Facter.value(:operatingsystem)
+ when "FreeBSD", "Darwin"
+ false
+ else
+ true
end
+ end
+ end
+
+ def refresh
+ # Only remount if we're supposed to be mounted.
+ provider.remount if self.should(:fstype) != "swap" and provider.mounted?
+ end
+
+ def value(name)
+ name = symbolize(name)
+ ret = nil
+ if property = @parameters[name]
+ return property.value
+ end
end
+ end
end
diff --git a/lib/puppet/type/notify.rb b/lib/puppet/type/notify.rb
index d46ade7..97935e2 100644
--- a/lib/puppet/type/notify.rb
+++ b/lib/puppet/type/notify.rb
@@ -3,43 +3,43 @@
#
module Puppet
- newtype(:notify) do
- @doc = "Sends an arbitrary message to the agent run-time log."
-
- newproperty(:message) do
- desc "The message to be sent to the log."
- def sync
- case @resource["withpath"]
- when :true
- send(@resource[:loglevel], self.should)
- else
- Puppet.send(@resource[:loglevel], self.should)
- end
- return
- end
-
- def retrieve
- :absent
- end
-
- def insync?(is)
- false
- end
-
- defaultto { @resource[:name] }
+ newtype(:notify) do
+ @doc = "Sends an arbitrary message to the agent run-time log."
+
+ newproperty(:message) do
+ desc "The message to be sent to the log."
+ def sync
+ case @resource["withpath"]
+ when :true
+ send(@resource[:loglevel], self.should)
+ else
+ Puppet.send(@resource[:loglevel], self.should)
end
+ return
+ end
- newparam(:withpath) do
- desc "Whether to not to show the full object path."
- defaultto :false
+ def retrieve
+ :absent
+ end
- newvalues(:true, :false)
- end
+ def insync?(is)
+ false
+ end
- newparam(:name) do
- desc "An arbitrary tag for your own reference; the name of the message."
- isnamevar
- end
+ defaultto { @resource[:name] }
+ end
+
+ newparam(:withpath) do
+ desc "Whether to not to show the full object path."
+ defaultto :false
+
+ newvalues(:true, :false)
+ end
+
+ newparam(:name) do
+ desc "An arbitrary tag for your own reference; the name of the message."
+ isnamevar
end
+ end
end
diff --git a/lib/puppet/type/package.rb b/lib/puppet/type/package.rb
index 658901e..f25464d 100644
--- a/lib/puppet/type/package.rb
+++ b/lib/puppet/type/package.rb
@@ -4,320 +4,320 @@
# systems.
module Puppet
- newtype(:package) do
- @doc = "Manage packages. There is a basic dichotomy in package
- support right now: Some package types (e.g., yum and apt) can
- retrieve their own package files, while others (e.g., rpm and sun) cannot. For those package formats that cannot retrieve
- their own files, you can use the ``source`` parameter to point to
- the correct file.
-
- Puppet will automatically guess the packaging format that you are
- using based on the platform you are on, but you can override it
- using the ``provider`` parameter; each provider defines what it
- requires in order to function, and you must meet those requirements
- to use a given provider."
-
- feature :installable, "The provider can install packages.",
- :methods => [:install]
- feature :uninstallable, "The provider can uninstall packages.",
- :methods => [:uninstall]
- feature :upgradeable, "The provider can upgrade to the latest version of a
- package. This feature is used by specifying ``latest`` as the
- desired value for the package.",
- :methods => [:update, :latest]
- feature :purgeable, "The provider can purge packages. This generally means
- that all traces of the package are removed, including
- existing configuration files. This feature is thus destructive
- and should be used with the utmost care.",
- :methods => [:purge]
- feature :versionable, "The provider is capable of interrogating the
- package database for installed version(s), and can select
- which out of a set of available versions of a package to
- install if asked."
- feature :holdable, "The provider is capable of placing packages on hold
- such that they are not automatically upgraded as a result of
- other package dependencies unless explicit action is taken by
- a user or another package. Held is considered a superset of
- installed.",
- :methods => [:hold]
-
- ensurable do
- desc "What state the package should be in.
- *latest* only makes sense for those packaging formats that can
- retrieve new packages on their own and will throw an error on
- those that cannot. For those packaging systems that allow you
- to specify package versions, specify them here. Similarly,
- *purged* is only useful for packaging systems that support
- the notion of managing configuration files separately from
- 'normal' system files."
-
- attr_accessor :latest
-
- newvalue(:present, :event => :package_installed) do
- provider.install
- end
-
- newvalue(:absent, :event => :package_removed) do
- provider.uninstall
- end
-
- newvalue(:purged, :event => :package_purged, :required_features => :purgeable) do
- provider.purge
- end
-
- newvalue(:held, :event => :package_held, :required_features => :holdable) do
- provider.hold
- end
-
- # Alias the 'present' value.
- aliasvalue(:installed, :present)
-
- newvalue(:latest, :required_features => :upgradeable) do
- # Because yum always exits with a 0 exit code, there's a retrieve
- # in the "install" method. So, check the current state now,
- # to compare against later.
- current = self.retrieve
- begin
- provider.update
- rescue => detail
- self.fail "Could not update: #{detail}"
- end
-
- if current == :absent
- :package_installed
- else
- :package_changed
- end
- end
-
- newvalue(/./, :required_features => :versionable) do
- begin
- provider.install
- rescue => detail
- self.fail "Could not update: #{detail}"
- end
-
- if self.retrieve == :absent
- :package_installed
- else
- :package_changed
- end
- end
+ newtype(:package) do
+ @doc = "Manage packages. There is a basic dichotomy in package
+ support right now: Some package types (e.g., yum and apt) can
+ retrieve their own package files, while others (e.g., rpm and sun) cannot. For those package formats that cannot retrieve
+ their own files, you can use the ``source`` parameter to point to
+ the correct file.
+
+ Puppet will automatically guess the packaging format that you are
+ using based on the platform you are on, but you can override it
+ using the ``provider`` parameter; each provider defines what it
+ requires in order to function, and you must meet those requirements
+ to use a given provider."
+
+ feature :installable, "The provider can install packages.",
+ :methods => [:install]
+ feature :uninstallable, "The provider can uninstall packages.",
+ :methods => [:uninstall]
+ feature :upgradeable, "The provider can upgrade to the latest version of a
+ package. This feature is used by specifying ``latest`` as the
+ desired value for the package.",
+ :methods => [:update, :latest]
+ feature :purgeable, "The provider can purge packages. This generally means
+ that all traces of the package are removed, including
+ existing configuration files. This feature is thus destructive
+ and should be used with the utmost care.",
+ :methods => [:purge]
+ feature :versionable, "The provider is capable of interrogating the
+ package database for installed version(s), and can select
+ which out of a set of available versions of a package to
+ install if asked."
+ feature :holdable, "The provider is capable of placing packages on hold
+ such that they are not automatically upgraded as a result of
+ other package dependencies unless explicit action is taken by
+ a user or another package. Held is considered a superset of
+ installed.",
+ :methods => [:hold]
+
+ ensurable do
+ desc "What state the package should be in.
+ *latest* only makes sense for those packaging formats that can
+ retrieve new packages on their own and will throw an error on
+ those that cannot. For those packaging systems that allow you
+ to specify package versions, specify them here. Similarly,
+ *purged* is only useful for packaging systems that support
+ the notion of managing configuration files separately from
+ 'normal' system files."
+
+ attr_accessor :latest
+
+ newvalue(:present, :event => :package_installed) do
+ provider.install
+ end
+
+ newvalue(:absent, :event => :package_removed) do
+ provider.uninstall
+ end
+
+ newvalue(:purged, :event => :package_purged, :required_features => :purgeable) do
+ provider.purge
+ end
+
+ newvalue(:held, :event => :package_held, :required_features => :holdable) do
+ provider.hold
+ end
+
+ # Alias the 'present' value.
+ aliasvalue(:installed, :present)
+
+ newvalue(:latest, :required_features => :upgradeable) do
+ # Because yum always exits with a 0 exit code, there's a retrieve
+ # in the "install" method. So, check the current state now,
+ # to compare against later.
+ current = self.retrieve
+ begin
+ provider.update
+ rescue => detail
+ self.fail "Could not update: #{detail}"
+ end
+ if current == :absent
+ :package_installed
+ else
+ :package_changed
+ end
+ end
- defaultto :installed
-
- # Override the parent method, because we've got all kinds of
- # funky definitions of 'in sync'.
- def insync?(is)
- @should ||= []
-
- @latest ||= nil
- @lateststamp ||= (Time.now.to_i - 1000)
- # Iterate across all of the should values, and see how they
- # turn out.
-
- @should.each { |should|
- case should
- when :present
- return true unless [:absent, :purged, :held].include?(is)
- when :latest
- # Short-circuit packages that are not present
- return false if is == :absent or is == :purged
-
- # Don't run 'latest' more than about every 5 minutes
- if @latest and ((Time.now.to_i - @lateststamp) / 60) < 5
- #self.debug "Skipping latest check"
- else
- begin
- @latest = provider.latest
- @lateststamp = Time.now.to_i
- rescue => detail
- error = Puppet::Error.new("Could not get latest version: #{detail}")
- error.set_backtrace(detail.backtrace)
- raise error
- end
- end
-
- case is
- when @latest
- return true
- when :present
- # This will only happen on retarded packaging systems
- # that can't query versions.
- return true
- else
- self.debug "#{@resource.name} #{is.inspect} is installed, latest is #{@latest.inspect}"
- end
- when :absent
- return true if is == :absent or is == :purged
- when :purged
- return true if is == :purged
- when is
- return true
- end
- }
-
- false
- end
+ newvalue(/./, :required_features => :versionable) do
+ begin
+ provider.install
+ rescue => detail
+ self.fail "Could not update: #{detail}"
+ end
- # This retrieves the current state. LAK: I think this method is unused.
- def retrieve
- provider.properties[:ensure]
+ if self.retrieve == :absent
+ :package_installed
+ else
+ :package_changed
+ end
+ end
+
+
+ defaultto :installed
+
+ # Override the parent method, because we've got all kinds of
+ # funky definitions of 'in sync'.
+ def insync?(is)
+ @should ||= []
+
+ @latest ||= nil
+ @lateststamp ||= (Time.now.to_i - 1000)
+ # Iterate across all of the should values, and see how they
+ # turn out.
+
+ @should.each { |should|
+ case should
+ when :present
+ return true unless [:absent, :purged, :held].include?(is)
+ when :latest
+ # Short-circuit packages that are not present
+ return false if is == :absent or is == :purged
+
+ # Don't run 'latest' more than about every 5 minutes
+ if @latest and ((Time.now.to_i - @lateststamp) / 60) < 5
+ #self.debug "Skipping latest check"
+ else
+ begin
+ @latest = provider.latest
+ @lateststamp = Time.now.to_i
+ rescue => detail
+ error = Puppet::Error.new("Could not get latest version: #{detail}")
+ error.set_backtrace(detail.backtrace)
+ raise error
+ end
end
- # Provide a bit more information when logging upgrades.
- def should_to_s(newvalue = @should)
- if @latest
- @latest.to_s
- else
- super(newvalue)
- end
+ case is
+ when @latest
+ return true
+ when :present
+ # This will only happen on retarded packaging systems
+ # that can't query versions.
+ return true
+ else
+ self.debug "#{@resource.name} #{is.inspect} is installed, latest is #{@latest.inspect}"
end
+ when :absent
+ return true if is == :absent or is == :purged
+ when :purged
+ return true if is == :purged
+ when is
+ return true
+ end
+ }
+
+ false
+ end
+
+ # This retrieves the current state. LAK: I think this method is unused.
+ def retrieve
+ provider.properties[:ensure]
+ end
+
+ # Provide a bit more information when logging upgrades.
+ def should_to_s(newvalue = @should)
+ if @latest
+ @latest.to_s
+ else
+ super(newvalue)
end
+ end
+ end
- newparam(:name) do
- desc "The package name. This is the name that the packaging
- system uses internally, which is sometimes (especially on Solaris)
- a name that is basically useless to humans. If you want to
- abstract package installation, then you can use aliases to provide
- a common name to packages::
-
- # In the 'openssl' class
- $ssl = $operatingsystem ? {
- solaris => SMCossl,
- default => openssl
- }
-
- # It is not an error to set an alias to the same value as the
- # object name.
- package { $ssl:
- ensure => installed,
- alias => openssl
- }
-
- . etc. .
-
- $ssh = $operatingsystem ? {
- solaris => SMCossh,
- default => openssh
- }
-
- # Use the alias to specify a dependency, rather than
- # having another selector to figure it out again.
- package { $ssh:
- ensure => installed,
- alias => openssh,
- require => Package[openssl]
- }
-
- "
- isnamevar
- end
+ newparam(:name) do
+ desc "The package name. This is the name that the packaging
+ system uses internally, which is sometimes (especially on Solaris)
+ a name that is basically useless to humans. If you want to
+ abstract package installation, then you can use aliases to provide
+ a common name to packages::
+
+ # In the 'openssl' class
+ $ssl = $operatingsystem ? {
+ solaris => SMCossl,
+ default => openssl
+ }
+
+ # It is not an error to set an alias to the same value as the
+ # object name.
+ package { $ssl:
+ ensure => installed,
+ alias => openssl
+ }
+
+ . etc. .
+
+ $ssh = $operatingsystem ? {
+ solaris => SMCossh,
+ default => openssh
+ }
+
+ # Use the alias to specify a dependency, rather than
+ # having another selector to figure it out again.
+ package { $ssh:
+ ensure => installed,
+ alias => openssh,
+ require => Package[openssl]
+ }
+
+ "
+ isnamevar
+ end
- newparam(:source) do
- desc "Where to find the actual package. This must be a local file
- (or on a network file system) or a URL that your specific
- packaging type understands; Puppet will not retrieve files for you."
- end
- newparam(:instance) do
- desc "A read-only parameter set by the package."
- end
- newparam(:status) do
- desc "A read-only parameter set by the package."
- end
+ newparam(:source) do
+ desc "Where to find the actual package. This must be a local file
+ (or on a network file system) or a URL that your specific
+ packaging type understands; Puppet will not retrieve files for you."
+ end
+ newparam(:instance) do
+ desc "A read-only parameter set by the package."
+ end
+ newparam(:status) do
+ desc "A read-only parameter set by the package."
+ end
- newparam(:type) do
- desc "Deprecated form of ``provider``."
+ newparam(:type) do
+ desc "Deprecated form of ``provider``."
- munge do |value|
- warning "'type' is deprecated; use 'provider' instead"
- @resource[:provider] = value
+ munge do |value|
+ warning "'type' is deprecated; use 'provider' instead"
+ @resource[:provider] = value
- @resource[:provider]
- end
- end
+ @resource[:provider]
+ end
+ end
- newparam(:adminfile) do
- desc "A file containing package defaults for installing packages.
- This is currently only used on Solaris. The value will be
- validated according to system rules, which in the case of
- Solaris means that it should either be a fully qualified path
- or it should be in /var/sadm/install/admin."
- end
+ newparam(:adminfile) do
+ desc "A file containing package defaults for installing packages.
+ This is currently only used on Solaris. The value will be
+ validated according to system rules, which in the case of
+ Solaris means that it should either be a fully qualified path
+ or it should be in /var/sadm/install/admin."
+ end
- newparam(:responsefile) do
- desc "A file containing any necessary answers to questions asked by
- the package. This is currently used on Solaris and Debian. The
- value will be validated according to system rules, but it should
- generally be a fully qualified path."
- end
+ newparam(:responsefile) do
+ desc "A file containing any necessary answers to questions asked by
+ the package. This is currently used on Solaris and Debian. The
+ value will be validated according to system rules, but it should
+ generally be a fully qualified path."
+ end
- newparam(:configfiles) do
- desc "Whether configfiles should be kept or replaced. Most packages
- types do not support this parameter."
+ newparam(:configfiles) do
+ desc "Whether configfiles should be kept or replaced. Most packages
+ types do not support this parameter."
- defaultto :keep
+ defaultto :keep
- newvalues(:keep, :replace)
- end
+ newvalues(:keep, :replace)
+ end
- newparam(:category) do
- desc "A read-only parameter set by the package."
- end
- newparam(:platform) do
- desc "A read-only parameter set by the package."
- end
- newparam(:root) do
- desc "A read-only parameter set by the package."
- end
- newparam(:vendor) do
- desc "A read-only parameter set by the package."
- end
- newparam(:description) do
- desc "A read-only parameter set by the package."
- end
+ newparam(:category) do
+ desc "A read-only parameter set by the package."
+ end
+ newparam(:platform) do
+ desc "A read-only parameter set by the package."
+ end
+ newparam(:root) do
+ desc "A read-only parameter set by the package."
+ end
+ newparam(:vendor) do
+ desc "A read-only parameter set by the package."
+ end
+ newparam(:description) do
+ desc "A read-only parameter set by the package."
+ end
- newparam(:allowcdrom) do
- desc "Tells apt to allow cdrom sources in the sources.list file.
- Normally apt will bail if you try this."
+ newparam(:allowcdrom) do
+ desc "Tells apt to allow cdrom sources in the sources.list file.
+ Normally apt will bail if you try this."
- newvalues(:true, :false)
- end
+ newvalues(:true, :false)
+ end
- newparam(:flavor) do
- desc "Newer versions of OpenBSD support 'flavors', which are
- further specifications for which type of package you want."
- end
+ newparam(:flavor) do
+ desc "Newer versions of OpenBSD support 'flavors', which are
+ further specifications for which type of package you want."
+ end
- autorequire(:file) do
- autos = []
- [:responsefile, :adminfile].each { |param|
- if val = self[param]
- autos << val
- end
- }
-
- if source = self[:source]
- if source =~ /^#{File::SEPARATOR}/
- autos << source
- end
- end
- autos
+ autorequire(:file) do
+ autos = []
+ [:responsefile, :adminfile].each { |param|
+ if val = self[param]
+ autos << val
end
+ }
- # This only exists for testing.
- def clear
- if obj = @parameters[:ensure]
- obj.latest = nil
- end
+ if source = self[:source]
+ if source =~ /^#{File::SEPARATOR}/
+ autos << source
end
+ end
+ autos
+ end
- # The 'query' method returns a hash of info if the package
- # exists and returns nil if it does not.
- def exists?
- @provider.get(:ensure) != :absent
- end
+ # This only exists for testing.
+ def clear
+ if obj = @parameters[:ensure]
+ obj.latest = nil
+ end
+ end
+
+ # The 'query' method returns a hash of info if the package
+ # exists and returns nil if it does not.
+ def exists?
+ @provider.get(:ensure) != :absent
end
+ end
end
diff --git a/lib/puppet/type/resources.rb b/lib/puppet/type/resources.rb
index 6e351f8..34382e0 100644
--- a/lib/puppet/type/resources.rb
+++ b/lib/puppet/type/resources.rb
@@ -4,132 +4,132 @@
require 'puppet'
Puppet::Type.newtype(:resources) do
- @doc = "This is a metatype that can manage other resource types. Any
- metaparams specified here will be passed on to any generated resources,
- so you can purge umanaged resources but set ``noop`` to true so the
- purging is only logged and does not actually happen."
+ @doc = "This is a metatype that can manage other resource types. Any
+ metaparams specified here will be passed on to any generated resources,
+ so you can purge umanaged resources but set ``noop`` to true so the
+ purging is only logged and does not actually happen."
- newparam(:name) do
- desc "The name of the type to be managed."
+ newparam(:name) do
+ desc "The name of the type to be managed."
- validate do |name|
- raise ArgumentError, "Could not find resource type '#{name}'" unless Puppet::Type.type(name)
- end
-
- munge { |v| v.to_s }
+ validate do |name|
+ raise ArgumentError, "Could not find resource type '#{name}'" unless Puppet::Type.type(name)
end
- newparam(:purge, :boolean => true) do
- desc "Purge unmanaged resources. This will delete any resource
- that is not specified in your configuration
- and is not required by any specified resources."
+ munge { |v| v.to_s }
+ end
- newvalues(:true, :false)
+ newparam(:purge, :boolean => true) do
+ desc "Purge unmanaged resources. This will delete any resource
+ that is not specified in your configuration
+ and is not required by any specified resources."
- validate do |value|
- if [:true, true, "true"].include?(value)
- unless @resource.resource_type.respond_to?(:instances)
- raise ArgumentError, "Purging resources of type #{@resource[:name]} is not supported, since they cannot be queried from the system"
- end
- raise ArgumentError, "Purging is only supported on types that accept 'ensure'" unless @resource.resource_type.validproperty?(:ensure)
- end
- end
- end
+ newvalues(:true, :false)
- newparam(:unless_system_user) do
- desc "This keeps system users from being purged. By default, it
- does not purge users whose UIDs are less than or equal to 500, but you can specify
- a different UID as the inclusive limit."
-
- newvalues(:true, :false, /^\d+$/)
-
- munge do |value|
- case value
- when /^\d+/
- Integer(value)
- when :true, true
- 500
- when :false, false
- false
- when Integer; value
- else
- raise ArgumentError, "Invalid value #{value.inspect}"
- end
+ validate do |value|
+ if [:true, true, "true"].include?(value)
+ unless @resource.resource_type.respond_to?(:instances)
+ raise ArgumentError, "Purging resources of type #{@resource[:name]} is not supported, since they cannot be queried from the system"
end
-
- defaultto {
- if @resource[:name] == "user"
- 500
- else
- nil
- end
- }
+ raise ArgumentError, "Purging is only supported on types that accept 'ensure'" unless @resource.resource_type.validproperty?(:ensure)
+ end
end
-
- def check(resource)
- @checkmethod ||= "#{self[:name]}_check"
- @hascheck ||= respond_to?(@checkmethod)
- if @hascheck
- return send(@checkmethod, resource)
- else
- return true
- end
+ end
+
+ newparam(:unless_system_user) do
+ desc "This keeps system users from being purged. By default, it
+ does not purge users whose UIDs are less than or equal to 500, but you can specify
+ a different UID as the inclusive limit."
+
+ newvalues(:true, :false, /^\d+$/)
+
+ munge do |value|
+ case value
+ when /^\d+/
+ Integer(value)
+ when :true, true
+ 500
+ when :false, false
+ false
+ when Integer; value
+ else
+ raise ArgumentError, "Invalid value #{value.inspect}"
+ end
end
- def able_to_ensure_absent?(resource)
- resource[:ensure] = :absent
- rescue ArgumentError, Puppet::Error => detail
- err "The 'ensure' attribute on #{self[:name]} resources does not accept 'absent' as a value"
- false
+ defaultto {
+ if @resource[:name] == "user"
+ 500
+ else
+ nil
+ end
+ }
+ end
+
+ def check(resource)
+ @checkmethod ||= "#{self[:name]}_check"
+ @hascheck ||= respond_to?(@checkmethod)
+ if @hascheck
+ return send(@checkmethod, resource)
+ else
+ return true
end
-
- # Generate any new resources we need to manage. This is pretty hackish
- # right now, because it only supports purging.
- def generate
- return [] unless self.purge?
- resource_type.instances.
- reject { |r| catalog.resource_refs.include? r.ref }.
- select { |r| check(r) }.
- select { |r| r.class.validproperty?(:ensure) }.
- select { |r| able_to_ensure_absent?(r) }.
- each { |resource|
- @parameters.each do |name, param|
- resource[name] = param.value if param.metaparam?
- end
-
- # Mark that we're purging, so transactions can handle relationships
- # correctly
- resource.purging
- }
- end
-
- def resource_type
- unless defined?(@resource_type)
- unless type = Puppet::Type.type(self[:name])
- raise Puppet::DevError, "Could not find resource type"
- end
- @resource_type = type
+ end
+
+ def able_to_ensure_absent?(resource)
+ resource[:ensure] = :absent
+ rescue ArgumentError, Puppet::Error => detail
+ err "The 'ensure' attribute on #{self[:name]} resources does not accept 'absent' as a value"
+ false
+ end
+
+ # Generate any new resources we need to manage. This is pretty hackish
+ # right now, because it only supports purging.
+ def generate
+ return [] unless self.purge?
+ resource_type.instances.
+ reject { |r| catalog.resource_refs.include? r.ref }.
+ select { |r| check(r) }.
+ select { |r| r.class.validproperty?(:ensure) }.
+ select { |r| able_to_ensure_absent?(r) }.
+ each { |resource|
+ @parameters.each do |name, param|
+ resource[name] = param.value if param.metaparam?
end
- @resource_type
+
+ # Mark that we're purging, so transactions can handle relationships
+ # correctly
+ resource.purging
+ }
+ end
+
+ def resource_type
+ unless defined?(@resource_type)
+ unless type = Puppet::Type.type(self[:name])
+ raise Puppet::DevError, "Could not find resource type"
+ end
+ @resource_type = type
end
+ @resource_type
+ end
- # Make sure we don't purge users below a certain uid, if the check
- # is enabled.
- def user_check(resource)
- return true unless self[:name] == "user"
- return true unless self[:unless_system_user]
+ # Make sure we don't purge users below a certain uid, if the check
+ # is enabled.
+ def user_check(resource)
+ return true unless self[:name] == "user"
+ return true unless self[:unless_system_user]
- resource[:audit] = :uid
- current_values = resource.retrieve_resource
+ resource[:audit] = :uid
+ current_values = resource.retrieve_resource
- return false if system_users.include?(resource[:name])
+ return false if system_users.include?(resource[:name])
- current_values[resource.property(:uid)] > self[:unless_system_user]
- end
+ current_values[resource.property(:uid)] > self[:unless_system_user]
+ end
- def system_users
- %w{root nobody bin noaccess daemon sys}
- end
+ def system_users
+ %w{root nobody bin noaccess daemon sys}
+ end
end
diff --git a/lib/puppet/type/schedule.rb b/lib/puppet/type/schedule.rb
index bcc62ce..bedf1e5 100755
--- a/lib/puppet/type/schedule.rb
+++ b/lib/puppet/type/schedule.rb
@@ -1,352 +1,352 @@
module Puppet
- newtype(:schedule) do
- @doc = "Defined schedules for Puppet. The important thing to understand
- about how schedules are currently implemented in Puppet is that they
- can only be used to stop a resource from being applied, they never
- guarantee that it is applied.
-
- Every time Puppet applies its configuration, it will collect the
- list of resources whose schedule does not eliminate them from
- running right then, but there is currently no system in place to
- guarantee that a given resource runs at a given time. If you
- specify a very restrictive schedule and Puppet happens to run at a
- time within that schedule, then the resources will get applied;
- otherwise, that work may never get done.
-
- Thus, it behooves you to use wider scheduling (e.g., over a couple of
- hours) combined with periods and repetitions. For instance, if you
- wanted to restrict certain resources to only running once, between
- the hours of two and 4 AM, then you would use this schedule::
-
- schedule { maint:
- range => \"2 - 4\",
- period => daily,
- repeat => 1
- }
-
- With this schedule, the first time that Puppet runs between 2 and 4 AM,
- all resources with this schedule will get applied, but they won't
- get applied again between 2 and 4 because they will have already
- run once that day, and they won't get applied outside that schedule
- because they will be outside the scheduled range.
-
- Puppet automatically creates a schedule for each valid period with the
- same name as that period (e.g., hourly and daily). Additionally,
- a schedule named *puppet* is created and used as the default,
- with the following attributes::
-
- schedule { puppet:
- period => hourly,
- repeat => 2
- }
-
- This will cause resources to be applied every 30 minutes by default.
- "
-
- newparam(:name) do
- desc "The name of the schedule. This name is used to retrieve the
- schedule when assigning it to an object::
-
- schedule { daily:
- period => daily,
- range => [2, 4]
- }
-
- exec { \"/usr/bin/apt-get update\":
- schedule => daily
- }
-
- "
- isnamevar
- end
+ newtype(:schedule) do
+ @doc = "Defined schedules for Puppet. The important thing to understand
+ about how schedules are currently implemented in Puppet is that they
+ can only be used to stop a resource from being applied, they never
+ guarantee that it is applied.
+
+ Every time Puppet applies its configuration, it will collect the
+ list of resources whose schedule does not eliminate them from
+ running right then, but there is currently no system in place to
+ guarantee that a given resource runs at a given time. If you
+ specify a very restrictive schedule and Puppet happens to run at a
+ time within that schedule, then the resources will get applied;
+ otherwise, that work may never get done.
+
+ Thus, it behooves you to use wider scheduling (e.g., over a couple of
+ hours) combined with periods and repetitions. For instance, if you
+ wanted to restrict certain resources to only running once, between
+ the hours of two and 4 AM, then you would use this schedule::
+
+ schedule { maint:
+ range => \"2 - 4\",
+ period => daily,
+ repeat => 1
+ }
+
+ With this schedule, the first time that Puppet runs between 2 and 4 AM,
+ all resources with this schedule will get applied, but they won't
+ get applied again between 2 and 4 because they will have already
+ run once that day, and they won't get applied outside that schedule
+ because they will be outside the scheduled range.
+
+ Puppet automatically creates a schedule for each valid period with the
+ same name as that period (e.g., hourly and daily). Additionally,
+ a schedule named *puppet* is created and used as the default,
+ with the following attributes::
+
+ schedule { puppet:
+ period => hourly,
+ repeat => 2
+ }
+
+ This will cause resources to be applied every 30 minutes by default.
+ "
+
+ newparam(:name) do
+ desc "The name of the schedule. This name is used to retrieve the
+ schedule when assigning it to an object::
+
+ schedule { daily:
+ period => daily,
+ range => [2, 4]
+ }
+
+ exec { \"/usr/bin/apt-get update\":
+ schedule => daily
+ }
+
+ "
+ isnamevar
+ end
- newparam(:range) do
- desc "The earliest and latest that a resource can be applied. This
- is always a range within a 24 hour period, and hours must be
- specified in numbers between 0 and 23, inclusive. Minutes and
- seconds can be provided, using the normal colon as a separator.
- For instance::
-
- schedule { maintenance:
- range => \"1:30 - 4:30\"
- }
-
- This is mostly useful for restricting certain resources to being
- applied in maintenance windows or during off-peak hours."
-
- # This is lame; properties all use arrays as values, but parameters don't.
- # That's going to hurt eventually.
- validate do |values|
- values = [values] unless values.is_a?(Array)
- values.each { |value|
- unless value.is_a?(String) and
- value =~ /\d+(:\d+){0,2}\s*-\s*\d+(:\d+){0,2}/
- self.fail "Invalid range value '#{value}'"
- end
- }
+ newparam(:range) do
+ desc "The earliest and latest that a resource can be applied. This
+ is always a range within a 24 hour period, and hours must be
+ specified in numbers between 0 and 23, inclusive. Minutes and
+ seconds can be provided, using the normal colon as a separator.
+ For instance::
+
+ schedule { maintenance:
+ range => \"1:30 - 4:30\"
+ }
+
+ This is mostly useful for restricting certain resources to being
+ applied in maintenance windows or during off-peak hours."
+
+ # This is lame; properties all use arrays as values, but parameters don't.
+ # That's going to hurt eventually.
+ validate do |values|
+ values = [values] unless values.is_a?(Array)
+ values.each { |value|
+ unless value.is_a?(String) and
+ value =~ /\d+(:\d+){0,2}\s*-\s*\d+(:\d+){0,2}/
+ self.fail "Invalid range value '#{value}'"
+ end
+ }
+ end
+
+ munge do |values|
+ values = [values] unless values.is_a?(Array)
+ ret = []
+
+ values.each { |value|
+ range = []
+ # Split each range value into a hour, minute, second triad
+ value.split(/\s*-\s*/).each { |val|
+ # Add the values as an array.
+ range << val.split(":").collect { |n| n.to_i }
+ }
+
+ self.fail "Invalid range #{value}" if range.length != 2
+
+ # Make sure the hours are valid
+ [range[0][0], range[1][0]].each do |n|
+ raise ArgumentError, "Invalid hour '#{n}'" if n < 0 or n > 23
+ end
+
+ [range[0][1], range[1][1]].each do |n|
+ raise ArgumentError, "Invalid minute '#{n}'" if n and (n < 0 or n > 59)
+ end
+ if range[0][0] > range[1][0]
+ self.fail(("Invalid range #{value}; ") +
+ "ranges cannot span days."
+ )
+ end
+ ret << range
+ }
+
+ # Now our array of arrays
+ ret
+ end
+
+ def match?(previous, now)
+ # The lowest-level array is of the hour, minute, second triad
+ # then it's an array of two of those, to present the limits
+ # then it's array of those ranges
+ @value = [@value] unless @value[0][0].is_a?(Array)
+
+ @value.each do |value|
+ limits = value.collect do |range|
+ ary = [now.year, now.month, now.day, range[0]]
+ if range[1]
+ ary << range[1]
+ else
+ ary << now.min
end
- munge do |values|
- values = [values] unless values.is_a?(Array)
- ret = []
-
- values.each { |value|
- range = []
- # Split each range value into a hour, minute, second triad
- value.split(/\s*-\s*/).each { |val|
- # Add the values as an array.
- range << val.split(":").collect { |n| n.to_i }
- }
-
- self.fail "Invalid range #{value}" if range.length != 2
-
- # Make sure the hours are valid
- [range[0][0], range[1][0]].each do |n|
- raise ArgumentError, "Invalid hour '#{n}'" if n < 0 or n > 23
- end
-
- [range[0][1], range[1][1]].each do |n|
- raise ArgumentError, "Invalid minute '#{n}'" if n and (n < 0 or n > 59)
- end
- if range[0][0] > range[1][0]
- self.fail(("Invalid range #{value}; ") +
- "ranges cannot span days."
- )
- end
- ret << range
- }
-
- # Now our array of arrays
- ret
+ if range[2]
+ ary << range[2]
+ else
+ ary << now.sec
end
- def match?(previous, now)
- # The lowest-level array is of the hour, minute, second triad
- # then it's an array of two of those, to present the limits
- # then it's array of those ranges
- @value = [@value] unless @value[0][0].is_a?(Array)
-
- @value.each do |value|
- limits = value.collect do |range|
- ary = [now.year, now.month, now.day, range[0]]
- if range[1]
- ary << range[1]
- else
- ary << now.min
- end
-
- if range[2]
- ary << range[2]
- else
- ary << now.sec
- end
-
- time = Time.local(*ary)
-
- unless time.hour == range[0]
- self.devfail(
- "Incorrectly converted time: #{time}: #{time.hour} vs #{range[0]}"
- )
- end
-
- time
- end
-
- unless limits[0] < limits[1]
- self.info(
- "Assuming upper limit should be that time the next day"
- )
-
- ary = limits[1].to_a
- ary[3] += 1
- limits[1] = Time.local(*ary)
-
- #self.devfail("Lower limit is above higher limit: %s" %
- # limits.inspect
- #)
- end
-
- #self.info limits.inspect
- #self.notice now
- return now.between?(*limits)
- end
-
- # Else, return false, since our current time isn't between
- # any valid times
- false
+ time = Time.local(*ary)
+
+ unless time.hour == range[0]
+ self.devfail(
+ "Incorrectly converted time: #{time}: #{time.hour} vs #{range[0]}"
+ )
end
- end
- newparam(:periodmatch) do
- desc "Whether periods should be matched by number (e.g., the two times
- are in the same hour) or by distance (e.g., the two times are
- 60 minutes apart)."
+ time
+ end
- newvalues(:number, :distance)
+ unless limits[0] < limits[1]
+ self.info(
+ "Assuming upper limit should be that time the next day"
+ )
- defaultto :distance
- end
+ ary = limits[1].to_a
+ ary[3] += 1
+ limits[1] = Time.local(*ary)
- newparam(:period) do
- desc "The period of repetition for a resource. Choose from among
- a fixed list of *hourly*, *daily*, *weekly*, and *monthly*.
- The default is for a resource to get applied every time that
- Puppet runs, whatever that period is.
-
- Note that the period defines how often a given resource will get
- applied but not when; if you would like to restrict the hours
- that a given resource can be applied (e.g., only at night during
- a maintenance window) then use the ``range`` attribute.
-
- If the provided periods are not sufficient, you can provide a
- value to the *repeat* attribute, which will cause Puppet to
- schedule the affected resources evenly in the period the
- specified number of times. Take this schedule::
-
- schedule { veryoften:
- period => hourly,
- repeat => 6
- }
-
- This can cause Puppet to apply that resource up to every 10 minutes.
-
- At the moment, Puppet cannot guarantee that level of
- repetition; that is, it can run up to every 10 minutes, but
- internal factors might prevent it from actually running that
- often (e.g., long-running Puppet runs will squash conflictingly scheduled runs).
-
- See the ``periodmatch`` attribute for tuning whether to match
- times by their distance apart or by their specific value."
-
- newvalues(:hourly, :daily, :weekly, :monthly, :never)
-
- @@scale = {
- :hourly => 3600,
- :daily => 86400,
- :weekly => 604800,
- :monthly => 2592000
- }
- @@methods = {
- :hourly => :hour,
- :daily => :day,
- :monthly => :month,
- :weekly => proc do |prev, now|
- # Run the resource if the previous day was after this weekday (e.g., prev is wed, current is tue)
- # or if it's been more than a week since we ran
- prev.wday > now.wday or (now - prev) > (24 * 3600 * 7)
- end
- }
-
- def match?(previous, now)
- return false if value == :never
-
- value = self.value
- case @resource[:periodmatch]
- when :number
- method = @@methods[value]
- if method.is_a?(Proc)
- return method.call(previous, now)
- else
- # We negate it, because if they're equal we don't run
- return now.send(method) != previous.send(method)
- end
- when :distance
- scale = @@scale[value]
-
- # If the number of seconds between the two times is greater
- # than the unit of time, we match. We divide the scale
- # by the repeat, so that we'll repeat that often within
- # the scale.
- diff = (now.to_i - previous.to_i)
- comparison = (scale / @resource[:repeat])
-
- return (now.to_i - previous.to_i) >= (scale / @resource[:repeat])
- end
- end
+ #self.devfail("Lower limit is above higher limit: %s" %
+ # limits.inspect
+ #)
+ end
+
+ #self.info limits.inspect
+ #self.notice now
+ return now.between?(*limits)
end
- newparam(:repeat) do
- desc "How often the application gets repeated in a given period.
- Defaults to 1. Must be an integer."
+ # Else, return false, since our current time isn't between
+ # any valid times
+ false
+ end
+ end
- defaultto 1
+ newparam(:periodmatch) do
+ desc "Whether periods should be matched by number (e.g., the two times
+ are in the same hour) or by distance (e.g., the two times are
+ 60 minutes apart)."
- validate do |value|
- unless value.is_a?(Integer) or value =~ /^\d+$/
- raise Puppet::Error,
- "Repeat must be a number"
- end
+ newvalues(:number, :distance)
- # This implicitly assumes that 'periodmatch' is distance -- that
- # is, if there's no value, we assume it's a valid value.
- return unless @resource[:periodmatch]
+ defaultto :distance
+ end
- if value != 1 and @resource[:periodmatch] != :distance
- raise Puppet::Error,
- "Repeat must be 1 unless periodmatch is 'distance', not '#{@resource[:periodmatch]}'"
- end
- end
+ newparam(:period) do
+ desc "The period of repetition for a resource. Choose from among
+ a fixed list of *hourly*, *daily*, *weekly*, and *monthly*.
+ The default is for a resource to get applied every time that
+ Puppet runs, whatever that period is.
+
+ Note that the period defines how often a given resource will get
+ applied but not when; if you would like to restrict the hours
+ that a given resource can be applied (e.g., only at night during
+ a maintenance window) then use the ``range`` attribute.
+
+ If the provided periods are not sufficient, you can provide a
+ value to the *repeat* attribute, which will cause Puppet to
+ schedule the affected resources evenly in the period the
+ specified number of times. Take this schedule::
+
+ schedule { veryoften:
+ period => hourly,
+ repeat => 6
+ }
+
+ This can cause Puppet to apply that resource up to every 10 minutes.
+
+ At the moment, Puppet cannot guarantee that level of
+ repetition; that is, it can run up to every 10 minutes, but
+ internal factors might prevent it from actually running that
+ often (e.g., long-running Puppet runs will squash conflictingly scheduled runs).
+
+ See the ``periodmatch`` attribute for tuning whether to match
+ times by their distance apart or by their specific value."
+
+ newvalues(:hourly, :daily, :weekly, :monthly, :never)
+
+ @@scale = {
+ :hourly => 3600,
+ :daily => 86400,
+ :weekly => 604800,
+ :monthly => 2592000
+ }
+ @@methods = {
+ :hourly => :hour,
+ :daily => :day,
+ :monthly => :month,
+ :weekly => proc do |prev, now|
+ # Run the resource if the previous day was after this weekday (e.g., prev is wed, current is tue)
+ # or if it's been more than a week since we ran
+ prev.wday > now.wday or (now - prev) > (24 * 3600 * 7)
+ end
+ }
+
+ def match?(previous, now)
+ return false if value == :never
+
+ value = self.value
+ case @resource[:periodmatch]
+ when :number
+ method = @@methods[value]
+ if method.is_a?(Proc)
+ return method.call(previous, now)
+ else
+ # We negate it, because if they're equal we don't run
+ return now.send(method) != previous.send(method)
+ end
+ when :distance
+ scale = @@scale[value]
+
+ # If the number of seconds between the two times is greater
+ # than the unit of time, we match. We divide the scale
+ # by the repeat, so that we'll repeat that often within
+ # the scale.
+ diff = (now.to_i - previous.to_i)
+ comparison = (scale / @resource[:repeat])
+
+ return (now.to_i - previous.to_i) >= (scale / @resource[:repeat])
+ end
+ end
+ end
- munge do |value|
- value = Integer(value) unless value.is_a?(Integer)
+ newparam(:repeat) do
+ desc "How often the application gets repeated in a given period.
+ Defaults to 1. Must be an integer."
- value
- end
+ defaultto 1
- def match?(previous, now)
- true
- end
+ validate do |value|
+ unless value.is_a?(Integer) or value =~ /^\d+$/
+ raise Puppet::Error,
+ "Repeat must be a number"
end
- def self.instances
- []
+ # This implicitly assumes that 'periodmatch' is distance -- that
+ # is, if there's no value, we assume it's a valid value.
+ return unless @resource[:periodmatch]
+
+ if value != 1 and @resource[:periodmatch] != :distance
+ raise Puppet::Error,
+ "Repeat must be 1 unless periodmatch is 'distance', not '#{@resource[:periodmatch]}'"
end
+ end
+
+ munge do |value|
+ value = Integer(value) unless value.is_a?(Integer)
+
+ value
+ end
+
+ def match?(previous, now)
+ true
+ end
+ end
- def self.mkdefaultschedules
- result = []
- Puppet.debug "Creating default schedules"
+ def self.instances
+ []
+ end
+
+ def self.mkdefaultschedules
+ result = []
+ Puppet.debug "Creating default schedules"
- result << self.new(
+ result << self.new(
- :name => "puppet",
- :period => :hourly,
+ :name => "puppet",
+ :period => :hourly,
- :repeat => "2"
- )
+ :repeat => "2"
+ )
- # And then one for every period
- @parameters.find { |p| p.name == :period }.value_collection.values.each { |value|
+ # And then one for every period
+ @parameters.find { |p| p.name == :period }.value_collection.values.each { |value|
- result << self.new(
+ result << self.new(
- :name => value.to_s,
+ :name => value.to_s,
- :period => value
- )
- }
+ :period => value
+ )
+ }
- result
- end
-
- def match?(previous = nil, now = nil)
+ result
+ end
- # If we've got a value, then convert it to a Time instance
- previous &&= Time.at(previous)
+ def match?(previous = nil, now = nil)
- now ||= Time.now
+ # If we've got a value, then convert it to a Time instance
+ previous &&= Time.at(previous)
- # Pull them in order
- self.class.allattrs.each { |param|
- if @parameters.include?(param) and
- @parameters[param].respond_to?(:match?)
- return false unless @parameters[param].match?(previous, now)
- end
- }
+ now ||= Time.now
- # If we haven't returned false, then return true; in other words,
- # any provided schedules need to all match
- true
+ # Pull them in order
+ self.class.allattrs.each { |param|
+ if @parameters.include?(param) and
+ @parameters[param].respond_to?(:match?)
+ return false unless @parameters[param].match?(previous, now)
end
+ }
+
+ # If we haven't returned false, then return true; in other words,
+ # any provided schedules need to all match
+ true
end
+ end
end
diff --git a/lib/puppet/type/selboolean.rb b/lib/puppet/type/selboolean.rb
index b1f12ca..cf873e9 100644
--- a/lib/puppet/type/selboolean.rb
+++ b/lib/puppet/type/selboolean.rb
@@ -3,29 +3,29 @@
#
module Puppet
- newtype(:selboolean) do
- @doc = "Manages SELinux booleans on systems with SELinux support. The supported booleans
- are any of the ones found in /selinux/booleans/."
+ newtype(:selboolean) do
+ @doc = "Manages SELinux booleans on systems with SELinux support. The supported booleans
+ are any of the ones found in /selinux/booleans/."
- newparam(:name) do
- desc "The name of the SELinux boolean to be managed."
- isnamevar
- end
-
- newproperty(:value) do
- desc "Whether the the SELinux boolean should be enabled or disabled."
- newvalue(:on)
- newvalue(:off)
- end
+ newparam(:name) do
+ desc "The name of the SELinux boolean to be managed."
+ isnamevar
+ end
- newparam(:persistent) do
- desc "If set true, SELinux booleans will be written to disk and persist accross reboots.
- The default is ``false``."
+ newproperty(:value) do
+ desc "Whether the the SELinux boolean should be enabled or disabled."
+ newvalue(:on)
+ newvalue(:off)
+ end
- defaultto :false
- newvalues(:true, :false)
- end
+ newparam(:persistent) do
+ desc "If set true, SELinux booleans will be written to disk and persist accross reboots.
+ The default is ``false``."
+ defaultto :false
+ newvalues(:true, :false)
end
+
+ end
end
diff --git a/lib/puppet/type/selmodule.rb b/lib/puppet/type/selmodule.rb
index 90b28b0..240d6e6 100644
--- a/lib/puppet/type/selmodule.rb
+++ b/lib/puppet/type/selmodule.rb
@@ -3,52 +3,52 @@
#
Puppet::Type.newtype(:selmodule) do
- @doc = "Manages loading and unloading of SELinux policy modules
- on the system. Requires SELinux support. See man semodule(8)
- for more information on SELinux policy modules."
+ @doc = "Manages loading and unloading of SELinux policy modules
+ on the system. Requires SELinux support. See man semodule(8)
+ for more information on SELinux policy modules."
- ensurable
+ ensurable
- newparam(:name) do
- desc "The name of the SELinux policy to be managed. You should not
- include the customary trailing .pp extension."
- isnamevar
- end
+ newparam(:name) do
+ desc "The name of the SELinux policy to be managed. You should not
+ include the customary trailing .pp extension."
+ isnamevar
+ end
- newparam(:selmoduledir) do
+ newparam(:selmoduledir) do
- desc "The directory to look for the compiled pp module file in.
- Currently defaults to /usr/share/selinux/targeted. If selmodulepath
- is not specified the module will be looked for in this directory in a
- in a file called NAME.pp, where NAME is the value of the name parameter."
+ desc "The directory to look for the compiled pp module file in.
+ Currently defaults to /usr/share/selinux/targeted. If selmodulepath
+ is not specified the module will be looked for in this directory in a
+ in a file called NAME.pp, where NAME is the value of the name parameter."
- defaultto "/usr/share/selinux/targeted"
- end
+ defaultto "/usr/share/selinux/targeted"
+ end
- newparam(:selmodulepath) do
+ newparam(:selmodulepath) do
- desc "The full path to the compiled .pp policy module. You only need to use
- this if the module file is not in the directory pointed at by selmoduledir."
+ desc "The full path to the compiled .pp policy module. You only need to use
+ this if the module file is not in the directory pointed at by selmoduledir."
- end
+ end
- newproperty(:syncversion) do
+ newproperty(:syncversion) do
- desc "If set to ``true``, the policy will be reloaded if the
- version found in the on-disk file differs from the loaded
- version. If set to ``false`` (the default) the the only check
- that will be made is if the policy is loaded at all or not."
+ desc "If set to ``true``, the policy will be reloaded if the
+ version found in the on-disk file differs from the loaded
+ version. If set to ``false`` (the default) the the only check
+ that will be made is if the policy is loaded at all or not."
- newvalue(:true)
- newvalue(:false)
- end
+ newvalue(:true)
+ newvalue(:false)
+ end
- autorequire(:file) do
- if self[:selmodulepath]
- [self[:selmodulepath]]
- else
- ["#{self[:selmoduledir]}/#{self[:name]}.pp"]
- end
+ autorequire(:file) do
+ if self[:selmodulepath]
+ [self[:selmodulepath]]
+ else
+ ["#{self[:selmoduledir]}/#{self[:name]}.pp"]
end
+ end
end
diff --git a/lib/puppet/type/service.rb b/lib/puppet/type/service.rb
index e1a2685..8f5c6ee 100644
--- a/lib/puppet/type/service.rb
+++ b/lib/puppet/type/service.rb
@@ -6,180 +6,180 @@
module Puppet
- newtype(:service) do
- @doc = "Manage running services. Service support unfortunately varies
- widely by platform -- some platforms have very little if any
- concept of a running service, and some have a very codified and
- powerful concept. Puppet's service support will generally be able
- to make up for any inherent shortcomings (e.g., if there is no
- 'status' command, then Puppet will look in the process table for a
- command matching the service name), but the more information you
- can provide the better behaviour you will get. Or, you can just
- use a platform that has very good service support.
-
- Note that if a ``service`` receives an event from another resource,
- the service will get restarted. The actual command to restart the
- service depends on the platform. You can provide a special command
- for restarting with the ``restart`` attribute."
-
- feature :refreshable, "The provider can restart the service.",
- :methods => [:restart]
-
- feature :enableable, "The provider can enable and disable the service",
- :methods => [:disable, :enable, :enabled?]
-
- feature :controllable, "The provider uses a control variable."
-
- newproperty(:enable, :required_features => :enableable) do
- desc "Whether a service should be enabled to start at boot.
- This property behaves quite differently depending on the platform;
- wherever possible, it relies on local tools to enable or disable
- a given service."
-
- newvalue(:true, :event => :service_enabled) do
- provider.enable
- end
-
- newvalue(:false, :event => :service_disabled) do
- provider.disable
- end
-
- def retrieve
- provider.enabled?
- end
- end
-
- # Handle whether the service should actually be running right now.
- newproperty(:ensure) do
- desc "Whether a service should be running."
+ newtype(:service) do
+ @doc = "Manage running services. Service support unfortunately varies
+ widely by platform -- some platforms have very little if any
+ concept of a running service, and some have a very codified and
+ powerful concept. Puppet's service support will generally be able
+ to make up for any inherent shortcomings (e.g., if there is no
+ 'status' command, then Puppet will look in the process table for a
+ command matching the service name), but the more information you
+ can provide the better behaviour you will get. Or, you can just
+ use a platform that has very good service support.
+
+ Note that if a ``service`` receives an event from another resource,
+ the service will get restarted. The actual command to restart the
+ service depends on the platform. You can provide a special command
+ for restarting with the ``restart`` attribute."
+
+ feature :refreshable, "The provider can restart the service.",
+ :methods => [:restart]
+
+ feature :enableable, "The provider can enable and disable the service",
+ :methods => [:disable, :enable, :enabled?]
+
+ feature :controllable, "The provider uses a control variable."
+
+ newproperty(:enable, :required_features => :enableable) do
+ desc "Whether a service should be enabled to start at boot.
+ This property behaves quite differently depending on the platform;
+ wherever possible, it relies on local tools to enable or disable
+ a given service."
+
+ newvalue(:true, :event => :service_enabled) do
+ provider.enable
+ end
+
+ newvalue(:false, :event => :service_disabled) do
+ provider.disable
+ end
+
+ def retrieve
+ provider.enabled?
+ end
+ end
- newvalue(:stopped, :event => :service_stopped) do
- provider.stop
- end
+ # Handle whether the service should actually be running right now.
+ newproperty(:ensure) do
+ desc "Whether a service should be running."
- newvalue(:running, :event => :service_started) do
- provider.start
- end
+ newvalue(:stopped, :event => :service_stopped) do
+ provider.stop
+ end
- aliasvalue(:false, :stopped)
- aliasvalue(:true, :running)
+ newvalue(:running, :event => :service_started) do
+ provider.start
+ end
- def retrieve
- provider.status
- end
+ aliasvalue(:false, :stopped)
+ aliasvalue(:true, :running)
- def sync
- event = super()
+ def retrieve
+ provider.status
+ end
- if property = @resource.property(:enable)
- val = property.retrieve
- property.sync unless property.insync?(val)
- end
+ def sync
+ event = super()
- event
- end
+ if property = @resource.property(:enable)
+ val = property.retrieve
+ property.sync unless property.insync?(val)
end
- newparam(:binary) do
- desc "The path to the daemon. This is only used for
- systems that do not support init scripts. This binary will be
- used to start the service if no ``start`` parameter is
- provided."
- end
+ event
+ end
+ end
- newparam(:hasstatus) do
- desc "Declare the the service's init script has a
- functional status command. Based on testing, it was found
- that a large number of init scripts on different platforms do
- not support any kind of status command; thus, you must specify
- manually whether the service you are running has such a
- command (or you can specify a specific command using the
- ``status`` parameter).
+ newparam(:binary) do
+ desc "The path to the daemon. This is only used for
+ systems that do not support init scripts. This binary will be
+ used to start the service if no ``start`` parameter is
+ provided."
+ end
- If you do not specify anything, then the service name will be
- looked for in the process table."
+ newparam(:hasstatus) do
+ desc "Declare the the service's init script has a
+ functional status command. Based on testing, it was found
+ that a large number of init scripts on different platforms do
+ not support any kind of status command; thus, you must specify
+ manually whether the service you are running has such a
+ command (or you can specify a specific command using the
+ ``status`` parameter).
- newvalues(:true, :false)
- end
- newparam(:name) do
- desc "The name of the service to run. This name is used to find
- the service in whatever service subsystem it is in."
- isnamevar
- end
+ If you do not specify anything, then the service name will be
+ looked for in the process table."
- newparam(:path) do
- desc "The search path for finding init scripts. Multiple values should
- be separated by colons or provided as an array."
+ newvalues(:true, :false)
+ end
+ newparam(:name) do
+ desc "The name of the service to run. This name is used to find
+ the service in whatever service subsystem it is in."
+ isnamevar
+ end
- munge do |value|
- value = [value] unless value.is_a?(Array)
- # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
- # It affects stand-alone blocks, too.
- paths = value.flatten.collect { |p| x = p.split(":") }.flatten
- end
+ newparam(:path) do
+ desc "The search path for finding init scripts. Multiple values should
+ be separated by colons or provided as an array."
- defaultto { provider.class.defpath if provider.class.respond_to?(:defpath) }
- end
- newparam(:pattern) do
- desc "The pattern to search for in the process table.
- This is used for stopping services on platforms that do not
- support init scripts, and is also used for determining service
- status on those service whose init scripts do not include a status
- command.
+ munge do |value|
+ value = [value] unless value.is_a?(Array)
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ # It affects stand-alone blocks, too.
+ paths = value.flatten.collect { |p| x = p.split(":") }.flatten
+ end
- If this is left unspecified and is needed to check the status
- of a service, then the service name will be used instead.
+ defaultto { provider.class.defpath if provider.class.respond_to?(:defpath) }
+ end
+ newparam(:pattern) do
+ desc "The pattern to search for in the process table.
+ This is used for stopping services on platforms that do not
+ support init scripts, and is also used for determining service
+ status on those service whose init scripts do not include a status
+ command.
- The pattern can be a simple string or any legal Ruby pattern."
+ If this is left unspecified and is needed to check the status
+ of a service, then the service name will be used instead.
- defaultto { @resource[:binary] || @resource[:name] }
- end
- newparam(:restart) do
- desc "Specify a *restart* command manually. If left
- unspecified, the service will be stopped and then started."
- end
- newparam(:start) do
- desc "Specify a *start* command manually. Most service subsystems
- support a ``start`` command, so this will not need to be
- specified."
- end
- newparam(:status) do
- desc "Specify a *status* command manually. If left
- unspecified, the status method will be determined
- automatically, usually by looking for the service in the
- process table."
- end
+ The pattern can be a simple string or any legal Ruby pattern."
- newparam(:stop) do
- desc "Specify a *stop* command manually."
- end
+ defaultto { @resource[:binary] || @resource[:name] }
+ end
+ newparam(:restart) do
+ desc "Specify a *restart* command manually. If left
+ unspecified, the service will be stopped and then started."
+ end
+ newparam(:start) do
+ desc "Specify a *start* command manually. Most service subsystems
+ support a ``start`` command, so this will not need to be
+ specified."
+ end
+ newparam(:status) do
+ desc "Specify a *status* command manually. If left
+ unspecified, the status method will be determined
+ automatically, usually by looking for the service in the
+ process table."
+ end
- newparam(:control) do
- desc "The control variable used to manage services (originally for HP-UX).
- Defaults to the upcased service name plus ``START`` replacing dots with
- underscores, for those providers that support the ``controllable`` feature."
- defaultto { resource.name.gsub(".","_").upcase + "_START" if resource.provider.controllable? }
- end
+ newparam(:stop) do
+ desc "Specify a *stop* command manually."
+ end
- newparam :hasrestart do
- desc "Specify that an init script has a ``restart`` option. Otherwise,
- the init script's ``stop`` and ``start`` methods are used."
- newvalues(:true, :false)
- end
+ newparam(:control) do
+ desc "The control variable used to manage services (originally for HP-UX).
+ Defaults to the upcased service name plus ``START`` replacing dots with
+ underscores, for those providers that support the ``controllable`` feature."
+ defaultto { resource.name.gsub(".","_").upcase + "_START" if resource.provider.controllable? }
+ end
- newparam(:manifest) do
- desc "Specify a command to config a service, or a path to a manifest to do so."
- end
+ newparam :hasrestart do
+ desc "Specify that an init script has a ``restart`` option. Otherwise,
+ the init script's ``stop`` and ``start`` methods are used."
+ newvalues(:true, :false)
+ end
- # Basically just a synonym for restarting. Used to respond
- # to events.
- def refresh
- # Only restart if we're actually running
- if (@parameters[:ensure] || newattr(:ensure)).retrieve == :running
- provider.restart
- else
- debug "Skipping restart; service is not running"
- end
- end
+ newparam(:manifest) do
+ desc "Specify a command to config a service, or a path to a manifest to do so."
+ end
+
+ # Basically just a synonym for restarting. Used to respond
+ # to events.
+ def refresh
+ # Only restart if we're actually running
+ if (@parameters[:ensure] || newattr(:ensure)).retrieve == :running
+ provider.restart
+ else
+ debug "Skipping restart; service is not running"
+ end
end
+ end
end
diff --git a/lib/puppet/type/ssh_authorized_key.rb b/lib/puppet/type/ssh_authorized_key.rb
index 306af89..2bfa87b 100644
--- a/lib/puppet/type/ssh_authorized_key.rb
+++ b/lib/puppet/type/ssh_authorized_key.rb
@@ -1,99 +1,99 @@
module Puppet
- newtype(:ssh_authorized_key) do
- @doc = "Manages SSH authorized keys. Currently only type 2 keys are
- supported."
+ newtype(:ssh_authorized_key) do
+ @doc = "Manages SSH authorized keys. Currently only type 2 keys are
+ supported."
- ensurable
+ ensurable
- newparam(:name) do
- desc "The SSH key comment. This attribute is currently used as a
- system-wide primary key and therefore has to be unique."
+ newparam(:name) do
+ desc "The SSH key comment. This attribute is currently used as a
+ system-wide primary key and therefore has to be unique."
- isnamevar
- end
+ isnamevar
+ end
- newproperty(:type) do
- desc "The encryption type used: ssh-dss or ssh-rsa."
+ newproperty(:type) do
+ desc "The encryption type used: ssh-dss or ssh-rsa."
- newvalue("ssh-dss")
- newvalue("ssh-rsa")
+ newvalue("ssh-dss")
+ newvalue("ssh-rsa")
- aliasvalue(:dsa, "ssh-dss")
- aliasvalue(:rsa, "ssh-rsa")
- end
-
- newproperty(:key) do
- desc "The key itself; generally a long string of hex digits."
- end
+ aliasvalue(:dsa, "ssh-dss")
+ aliasvalue(:rsa, "ssh-rsa")
+ end
- newproperty(:user) do
- desc "The user account in which the SSH key should be installed.
- The resource will automatically depend on this user."
- end
+ newproperty(:key) do
+ desc "The key itself; generally a long string of hex digits."
+ end
- newproperty(:target) do
- desc "The absolute filename in which to store the SSH key. This
- property is optional and should only be used in cases where keys
- are stored in a non-standard location (ie not in
- ~user/.ssh/authorized_keys)."
+ newproperty(:user) do
+ desc "The user account in which the SSH key should be installed.
+ The resource will automatically depend on this user."
+ end
- defaultto :absent
+ newproperty(:target) do
+ desc "The absolute filename in which to store the SSH key. This
+ property is optional and should only be used in cases where keys
+ are stored in a non-standard location (ie not in
+ ~user/.ssh/authorized_keys)."
- def should
- return super if defined?(@should) and @should[0] != :absent
+ defaultto :absent
- return nil unless user = resource[:user]
+ def should
+ return super if defined?(@should) and @should[0] != :absent
- begin
- return File.expand_path("~#{user}/.ssh/authorized_keys")
- rescue
- Puppet.debug "The required user is not yet present on the system"
- return nil
- end
- end
+ return nil unless user = resource[:user]
- def insync?(is)
- is == should
- end
+ begin
+ return File.expand_path("~#{user}/.ssh/authorized_keys")
+ rescue
+ Puppet.debug "The required user is not yet present on the system"
+ return nil
end
+ end
- newproperty(:options, :array_matching => :all) do
- desc "Key options, see sshd(8) for possible values. Multiple values
- should be specified as an array."
-
- defaultto do :absent end
-
- def is_to_s(value)
- if value == :absent or value.include?(:absent)
- super
- else
- value.join(",")
- end
- end
-
- def should_to_s(value)
- if value == :absent or value.include?(:absent)
- super
- else
- value.join(",")
- end
- end
+ def insync?(is)
+ is == should
+ end
+ end
+
+ newproperty(:options, :array_matching => :all) do
+ desc "Key options, see sshd(8) for possible values. Multiple values
+ should be specified as an array."
+
+ defaultto do :absent end
+
+ def is_to_s(value)
+ if value == :absent or value.include?(:absent)
+ super
+ else
+ value.join(",")
end
+ end
- autorequire(:user) do
- should(:user) if should(:user)
+ def should_to_s(value)
+ if value == :absent or value.include?(:absent)
+ super
+ else
+ value.join(",")
end
+ end
+ end
+
+ autorequire(:user) do
+ should(:user) if should(:user)
+ end
- validate do
- # Go ahead if target attribute is defined
- return if @parameters[:target].shouldorig[0] != :absent
+ validate do
+ # Go ahead if target attribute is defined
+ return if @parameters[:target].shouldorig[0] != :absent
- # Go ahead if user attribute is defined
- return if @parameters.include?(:user)
+ # Go ahead if user attribute is defined
+ return if @parameters.include?(:user)
- # If neither target nor user is defined, this is an error
- raise Puppet::Error, "Attribute 'user' or 'target' is mandatory"
- end
+ # If neither target nor user is defined, this is an error
+ raise Puppet::Error, "Attribute 'user' or 'target' is mandatory"
end
+ end
end
diff --git a/lib/puppet/type/sshkey.rb b/lib/puppet/type/sshkey.rb
index 6051a52..e1adc71 100755
--- a/lib/puppet/type/sshkey.rb
+++ b/lib/puppet/type/sshkey.rb
@@ -1,70 +1,70 @@
module Puppet
- newtype(:sshkey) do
- @doc = "Installs and manages ssh host keys. At this point, this type
- only knows how to install keys into /etc/ssh/ssh_known_hosts, and
- it cannot manage user authorized keys yet."
+ newtype(:sshkey) do
+ @doc = "Installs and manages ssh host keys. At this point, this type
+ only knows how to install keys into /etc/ssh/ssh_known_hosts, and
+ it cannot manage user authorized keys yet."
- ensurable
+ ensurable
- newproperty(:type) do
- desc "The encryption type used. Probably ssh-dss or ssh-rsa."
+ newproperty(:type) do
+ desc "The encryption type used. Probably ssh-dss or ssh-rsa."
- newvalue("ssh-dss")
- newvalue("ssh-rsa")
- aliasvalue(:dsa, "ssh-dss")
- aliasvalue(:rsa, "ssh-rsa")
- end
+ newvalue("ssh-dss")
+ newvalue("ssh-rsa")
+ aliasvalue(:dsa, "ssh-dss")
+ aliasvalue(:rsa, "ssh-rsa")
+ end
- newproperty(:key) do
- desc "The key itself; generally a long string of hex digits."
- end
+ newproperty(:key) do
+ desc "The key itself; generally a long string of hex digits."
+ end
- # FIXME This should automagically check for aliases to the hosts, just
- # to see if we can automatically glean any aliases.
- newproperty(:host_aliases) do
- desc 'Any aliases the host might have. Multiple values must be
- specified as an array. Note that this property is not the same as
- the "alias" metaparam; use this property to add aliases to a host
- on disk, and "alias" to aliases for use in your Puppet scripts.'
+ # FIXME This should automagically check for aliases to the hosts, just
+ # to see if we can automatically glean any aliases.
+ newproperty(:host_aliases) do
+ desc 'Any aliases the host might have. Multiple values must be
+ specified as an array. Note that this property is not the same as
+ the "alias" metaparam; use this property to add aliases to a host
+ on disk, and "alias" to aliases for use in your Puppet scripts.'
- attr_accessor :meta
+ attr_accessor :meta
- def insync?(is)
- is == @should
- end
- # We actually want to return the whole array here, not just the first
- # value.
- def should
- defined?(@should) ? @should : nil
- end
+ def insync?(is)
+ is == @should
+ end
+ # We actually want to return the whole array here, not just the first
+ # value.
+ def should
+ defined?(@should) ? @should : nil
+ end
- validate do |value|
- if value =~ /\s/
- raise Puppet::Error, "Aliases cannot include whitespace"
- end
- if value =~ /,/
- raise Puppet::Error, "Aliases cannot include whitespace"
- end
- end
+ validate do |value|
+ if value =~ /\s/
+ raise Puppet::Error, "Aliases cannot include whitespace"
end
+ if value =~ /,/
+ raise Puppet::Error, "Aliases cannot include whitespace"
+ end
+ end
+ end
- newparam(:name) do
- desc "The host name that the key is associated with."
+ newparam(:name) do
+ desc "The host name that the key is associated with."
- isnamevar
- end
+ isnamevar
+ end
- newproperty(:target) do
- desc "The file in which to store the ssh key. Only used by
- the ``parsed`` provider."
+ newproperty(:target) do
+ desc "The file in which to store the ssh key. Only used by
+ the ``parsed`` provider."
- defaultto { if @resource.class.defaultprovider.ancestors.include?(Puppet::Provider::ParsedFile)
- @resource.class.defaultprovider.default_target
- else
- nil
- end
- }
+ defaultto { if @resource.class.defaultprovider.ancestors.include?(Puppet::Provider::ParsedFile)
+ @resource.class.defaultprovider.default_target
+ else
+ nil
end
+ }
end
+ end
end
diff --git a/lib/puppet/type/stage.rb b/lib/puppet/type/stage.rb
index c11acdc..d22cd7b 100644
--- a/lib/puppet/type/stage.rb
+++ b/lib/puppet/type/stage.rb
@@ -1,18 +1,18 @@
Puppet::Type.newtype(:stage) do
- desc "A resource type for specifying run stages. The actual stage should
- be specified on resources::
- class { foo: stage => pre }
+ desc "A resource type for specifying run stages. The actual stage should
+ be specified on resources::
+ class { foo: stage => pre }
- And you must manually control stage order::
+ And you must manually control stage order::
- stage { pre: before => Stage[main] }
+ stage { pre: before => Stage[main] }
- You automatically get a 'main' stage created, and by default all resources
- get inserted into that stage.
+ You automatically get a 'main' stage created, and by default all resources
+ get inserted into that stage.
- You can only set stages on class resources, not normal builtin resources."
+ You can only set stages on class resources, not normal builtin resources."
- newparam :name do
- desc "The name of the stage. This will be used as the 'stage' for each resource."
- end
+ newparam :name do
+ desc "The name of the stage. This will be used as the 'stage' for each resource."
+ end
end
diff --git a/lib/puppet/type/tidy.rb b/lib/puppet/type/tidy.rb
index 6923b45..a660521 100755
--- a/lib/puppet/type/tidy.rb
+++ b/lib/puppet/type/tidy.rb
@@ -1,330 +1,330 @@
Puppet::Type.newtype(:tidy) do
- require 'puppet/file_serving/fileset'
-
- @doc = "Remove unwanted files based on specific criteria. Multiple
- criteria are OR'd together, so a file that is too large but is not
- old enough will still get tidied.
-
- If you don't specify either 'age' or 'size', then all files will
- be removed.
-
- This resource type works by generating a file resource for every file
- that should be deleted and then letting that resource perform the
- actual deletion.
- "
-
- newparam(:path) do
- desc "The path to the file or directory to manage. Must be fully
- qualified."
- isnamevar
+ require 'puppet/file_serving/fileset'
+
+ @doc = "Remove unwanted files based on specific criteria. Multiple
+ criteria are OR'd together, so a file that is too large but is not
+ old enough will still get tidied.
+
+ If you don't specify either 'age' or 'size', then all files will
+ be removed.
+
+ This resource type works by generating a file resource for every file
+ that should be deleted and then letting that resource perform the
+ actual deletion.
+ "
+
+ newparam(:path) do
+ desc "The path to the file or directory to manage. Must be fully
+ qualified."
+ isnamevar
+ end
+
+ newparam(:recurse) do
+ desc "If target is a directory, recursively descend
+ into the directory looking for files to tidy."
+
+ newvalues(:true, :false, :inf, /^[0-9]+$/)
+
+ # Replace the validation so that we allow numbers in
+ # addition to string representations of them.
+ validate { |arg| }
+ munge do |value|
+ newval = super(value)
+ case newval
+ when :true, :inf; true
+ when :false; false
+ when Integer, Fixnum, Bignum; value
+ when /^\d+$/; Integer(value)
+ else
+ raise ArgumentError, "Invalid recurse value #{value.inspect}"
+ end
+ end
+ end
+
+ newparam(:matches) do
+ desc "One or more (shell type) file glob patterns, which restrict
+ the list of files to be tidied to those whose basenames match
+ at least one of the patterns specified. Multiple patterns can
+ be specified using an array.
+
+ Example::
+
+ tidy { \"/tmp\":
+ age => \"1w\",
+ recurse => 1,
+ matches => [ \"[0-9]pub*.tmp\", \"*.temp\", \"tmpfile?\" ]
+ }
+
+ This removes files from \/tmp if they are one week old or older,
+ are not in a subdirectory and match one of the shell globs given.
+
+ Note that the patterns are matched against the basename of each
+ file -- that is, your glob patterns should not have any '/'
+ characters in them, since you are only specifying against the last
+ bit of the file.
+
+ Finally, note that you must now specify a non-zero/non-false value
+ for recurse if matches is used, as matches only apply to files found
+ by recursion (there's no reason to use static patterns match against
+ a statically determined path). Requiering explicit recursion clears
+ up a common source of confusion."
+
+ # Make sure we convert to an array.
+ munge do |value|
+ fail "Tidy can't use matches with recurse 0, false, or undef" if "#{@resource[:recurse]}" =~ /^(0|false|)$/
+ [value].flatten
end
- newparam(:recurse) do
- desc "If target is a directory, recursively descend
- into the directory looking for files to tidy."
-
- newvalues(:true, :false, :inf, /^[0-9]+$/)
-
- # Replace the validation so that we allow numbers in
- # addition to string representations of them.
- validate { |arg| }
- munge do |value|
- newval = super(value)
- case newval
- when :true, :inf; true
- when :false; false
- when Integer, Fixnum, Bignum; value
- when /^\d+$/; Integer(value)
- else
- raise ArgumentError, "Invalid recurse value #{value.inspect}"
- end
- end
+ # Does a given path match our glob patterns, if any? Return true
+ # if no patterns have been provided.
+ def tidy?(path, stat)
+ basename = File.basename(path)
+ flags = File::FNM_DOTMATCH | File::FNM_PATHNAME
+ return(value.find {|pattern| File.fnmatch(pattern, basename, flags) } ? true : false)
+ end
+ end
+
+ newparam(:backup) do
+ desc "Whether tidied files should be backed up. Any values are passed
+ directly to the file resources used for actual file deletion, so use
+ its backup documentation to determine valid values."
+ end
+
+ newparam(:age) do
+ desc "Tidy files whose age is equal to or greater than
+ the specified time. You can choose seconds, minutes,
+ hours, days, or weeks by specifying the first letter of any
+ of those words (e.g., '1w').
+
+ Specifying 0 will remove all files."
+
+ @@ageconvertors = {
+ :s => 1,
+ :m => 60
+ }
+
+ @@ageconvertors[:h] = @@ageconvertors[:m] * 60
+ @@ageconvertors[:d] = @@ageconvertors[:h] * 24
+ @@ageconvertors[:w] = @@ageconvertors[:d] * 7
+
+ def convert(unit, multi)
+ if num = @@ageconvertors[unit]
+ return num * multi
+ else
+ self.fail "Invalid age unit '#{unit}'"
+ end
end
- newparam(:matches) do
- desc "One or more (shell type) file glob patterns, which restrict
- the list of files to be tidied to those whose basenames match
- at least one of the patterns specified. Multiple patterns can
- be specified using an array.
-
- Example::
-
- tidy { \"/tmp\":
- age => \"1w\",
- recurse => 1,
- matches => [ \"[0-9]pub*.tmp\", \"*.temp\", \"tmpfile?\" ]
- }
-
- This removes files from \/tmp if they are one week old or older,
- are not in a subdirectory and match one of the shell globs given.
-
- Note that the patterns are matched against the basename of each
- file -- that is, your glob patterns should not have any '/'
- characters in them, since you are only specifying against the last
- bit of the file.
-
- Finally, note that you must now specify a non-zero/non-false value
- for recurse if matches is used, as matches only apply to files found
- by recursion (there's no reason to use static patterns match against
- a statically determined path). Requiering explicit recursion clears
- up a common source of confusion."
-
- # Make sure we convert to an array.
- munge do |value|
- fail "Tidy can't use matches with recurse 0, false, or undef" if "#{@resource[:recurse]}" =~ /^(0|false|)$/
- [value].flatten
- end
-
- # Does a given path match our glob patterns, if any? Return true
- # if no patterns have been provided.
- def tidy?(path, stat)
- basename = File.basename(path)
- flags = File::FNM_DOTMATCH | File::FNM_PATHNAME
- return(value.find {|pattern| File.fnmatch(pattern, basename, flags) } ? true : false)
- end
+ def tidy?(path, stat)
+ # If the file's older than we allow, we should get rid of it.
+ (Time.now.to_i - stat.send(resource[:type]).to_i) > value
end
- newparam(:backup) do
- desc "Whether tidied files should be backed up. Any values are passed
- directly to the file resources used for actual file deletion, so use
- its backup documentation to determine valid values."
+ munge do |age|
+ unit = multi = nil
+ case age
+ when /^([0-9]+)(\w)\w*$/
+ multi = Integer($1)
+ unit = $2.downcase.intern
+ when /^([0-9]+)$/
+ multi = Integer($1)
+ unit = :d
+ else
+ self.fail "Invalid tidy age #{age}"
+ end
+
+ convert(unit, multi)
+ end
+ end
+
+ newparam(:size) do
+ desc "Tidy files whose size is equal to or greater than
+ the specified size. Unqualified values are in kilobytes, but
+ *b*, *k*, and *m* can be appended to specify *bytes*, *kilobytes*,
+ and *megabytes*, respectively. Only the first character is
+ significant, so the full word can also be used."
+
+ @@sizeconvertors = {
+ :b => 0,
+ :k => 1,
+ :m => 2,
+ :g => 3
+ }
+
+ def convert(unit, multi)
+ if num = @@sizeconvertors[unit]
+ result = multi
+ num.times do result *= 1024 end
+ return result
+ else
+ self.fail "Invalid size unit '#{unit}'"
+ end
end
- newparam(:age) do
- desc "Tidy files whose age is equal to or greater than
- the specified time. You can choose seconds, minutes,
- hours, days, or weeks by specifying the first letter of any
- of those words (e.g., '1w').
-
- Specifying 0 will remove all files."
-
- @@ageconvertors = {
- :s => 1,
- :m => 60
- }
-
- @@ageconvertors[:h] = @@ageconvertors[:m] * 60
- @@ageconvertors[:d] = @@ageconvertors[:h] * 24
- @@ageconvertors[:w] = @@ageconvertors[:d] * 7
-
- def convert(unit, multi)
- if num = @@ageconvertors[unit]
- return num * multi
- else
- self.fail "Invalid age unit '#{unit}'"
- end
- end
-
- def tidy?(path, stat)
- # If the file's older than we allow, we should get rid of it.
- (Time.now.to_i - stat.send(resource[:type]).to_i) > value
- end
-
- munge do |age|
- unit = multi = nil
- case age
- when /^([0-9]+)(\w)\w*$/
- multi = Integer($1)
- unit = $2.downcase.intern
- when /^([0-9]+)$/
- multi = Integer($1)
- unit = :d
- else
- self.fail "Invalid tidy age #{age}"
- end
-
- convert(unit, multi)
- end
+ def tidy?(path, stat)
+ stat.size >= value
end
- newparam(:size) do
- desc "Tidy files whose size is equal to or greater than
- the specified size. Unqualified values are in kilobytes, but
- *b*, *k*, and *m* can be appended to specify *bytes*, *kilobytes*,
- and *megabytes*, respectively. Only the first character is
- significant, so the full word can also be used."
-
- @@sizeconvertors = {
- :b => 0,
- :k => 1,
- :m => 2,
- :g => 3
- }
-
- def convert(unit, multi)
- if num = @@sizeconvertors[unit]
- result = multi
- num.times do result *= 1024 end
- return result
- else
- self.fail "Invalid size unit '#{unit}'"
- end
- end
-
- def tidy?(path, stat)
- stat.size >= value
- end
-
- munge do |size|
- case size
- when /^([0-9]+)(\w)\w*$/
- multi = Integer($1)
- unit = $2.downcase.intern
- when /^([0-9]+)$/
- multi = Integer($1)
- unit = :k
- else
- self.fail "Invalid tidy size #{age}"
- end
-
- convert(unit, multi)
- end
+ munge do |size|
+ case size
+ when /^([0-9]+)(\w)\w*$/
+ multi = Integer($1)
+ unit = $2.downcase.intern
+ when /^([0-9]+)$/
+ multi = Integer($1)
+ unit = :k
+ else
+ self.fail "Invalid tidy size #{age}"
+ end
+
+ convert(unit, multi)
end
+ end
- newparam(:type) do
- desc "Set the mechanism for determining age."
+ newparam(:type) do
+ desc "Set the mechanism for determining age."
- newvalues(:atime, :mtime, :ctime)
+ newvalues(:atime, :mtime, :ctime)
- defaultto :atime
- end
+ defaultto :atime
+ end
- newparam(:rmdirs, :boolean => true) do
- desc "Tidy directories in addition to files; that is, remove
- directories whose age is older than the specified criteria.
- This will only remove empty directories, so all contained
- files must also be tidied before a directory gets removed."
+ newparam(:rmdirs, :boolean => true) do
+ desc "Tidy directories in addition to files; that is, remove
+ directories whose age is older than the specified criteria.
+ This will only remove empty directories, so all contained
+ files must also be tidied before a directory gets removed."
- newvalues :true, :false
- end
+ newvalues :true, :false
+ end
- # Erase PFile's validate method
- validate do
- end
+ # Erase PFile's validate method
+ validate do
+ end
- def self.instances
- []
- end
+ def self.instances
+ []
+ end
- @depthfirst = true
+ @depthfirst = true
- def initialize(hash)
- super
+ def initialize(hash)
+ super
- # only allow backing up into filebuckets
- self[:backup] = false unless self[:backup].is_a? Puppet::FileBucket::Dipper
- end
+ # only allow backing up into filebuckets
+ self[:backup] = false unless self[:backup].is_a? Puppet::FileBucket::Dipper
+ end
- # Make a file resource to remove a given file.
- def mkfile(path)
- # Force deletion, so directories actually get deleted.
- Puppet::Type.type(:file).new :path => path, :backup => self[:backup], :ensure => :absent, :force => true
- end
+ # Make a file resource to remove a given file.
+ def mkfile(path)
+ # Force deletion, so directories actually get deleted.
+ Puppet::Type.type(:file).new :path => path, :backup => self[:backup], :ensure => :absent, :force => true
+ end
- def retrieve
- # Our ensure property knows how to retrieve everything for us.
- if obj = @parameters[:ensure]
- return obj.retrieve
- else
- return {}
- end
+ def retrieve
+ # Our ensure property knows how to retrieve everything for us.
+ if obj = @parameters[:ensure]
+ return obj.retrieve
+ else
+ return {}
end
+ end
- # Hack things a bit so we only ever check the ensure property.
- def properties
- []
- end
+ # Hack things a bit so we only ever check the ensure property.
+ def properties
+ []
+ end
- def eval_generate
- []
- end
+ def eval_generate
+ []
+ end
- def generate
- return [] unless stat(self[:path])
-
- case self[:recurse]
- when Integer, Fixnum, Bignum, /^\d+$/
- parameter = { :recurse => true, :recurselimit => self[:recurse] }
- when true, :true, :inf
- parameter = { :recurse => true }
- end
-
- if parameter
- files = Puppet::FileServing::Fileset.new(self[:path], parameter).files.collect do |f|
- f == "." ? self[:path] : File.join(self[:path], f)
- end
- else
- files = [self[:path]]
- end
- result = files.find_all { |path| tidy?(path) }.collect { |path| mkfile(path) }.each { |file| notice "Tidying #{file.ref}" }.sort { |a,b| b[:path] <=> a[:path] }
-
- # No need to worry about relationships if we don't have rmdirs; there won't be
- # any directories.
- return result unless rmdirs?
-
- # Now make sure that all directories require the files they contain, if all are available,
- # so that a directory is emptied before we try to remove it.
- files_by_name = result.inject({}) { |hash, file| hash[file[:path]] = file; hash }
-
- files_by_name.keys.sort { |a,b| b <=> b }.each do |path|
- dir = File.dirname(path)
- next unless resource = files_by_name[dir]
- if resource[:require]
- resource[:require] << Puppet::Resource.new(:file, path)
- else
- resource[:require] = [Puppet::Resource.new(:file, path)]
- end
- end
-
- result
+ def generate
+ return [] unless stat(self[:path])
+
+ case self[:recurse]
+ when Integer, Fixnum, Bignum, /^\d+$/
+ parameter = { :recurse => true, :recurselimit => self[:recurse] }
+ when true, :true, :inf
+ parameter = { :recurse => true }
end
- # Does a given path match our glob patterns, if any? Return true
- # if no patterns have been provided.
- def matches?(path)
- return true unless self[:matches]
-
- basename = File.basename(path)
- flags = File::FNM_DOTMATCH | File::FNM_PATHNAME
- if self[:matches].find {|pattern| File.fnmatch(pattern, basename, flags) }
- return true
- else
- debug "No specified patterns match #{path}, not tidying"
- return false
- end
+ if parameter
+ files = Puppet::FileServing::Fileset.new(self[:path], parameter).files.collect do |f|
+ f == "." ? self[:path] : File.join(self[:path], f)
+ end
+ else
+ files = [self[:path]]
+ end
+ result = files.find_all { |path| tidy?(path) }.collect { |path| mkfile(path) }.each { |file| notice "Tidying #{file.ref}" }.sort { |a,b| b[:path] <=> a[:path] }
+
+ # No need to worry about relationships if we don't have rmdirs; there won't be
+ # any directories.
+ return result unless rmdirs?
+
+ # Now make sure that all directories require the files they contain, if all are available,
+ # so that a directory is emptied before we try to remove it.
+ files_by_name = result.inject({}) { |hash, file| hash[file[:path]] = file; hash }
+
+ files_by_name.keys.sort { |a,b| b <=> b }.each do |path|
+ dir = File.dirname(path)
+ next unless resource = files_by_name[dir]
+ if resource[:require]
+ resource[:require] << Puppet::Resource.new(:file, path)
+ else
+ resource[:require] = [Puppet::Resource.new(:file, path)]
+ end
end
- # Should we remove the specified file?
- def tidy?(path)
- return false unless stat = self.stat(path)
+ result
+ end
+
+ # Does a given path match our glob patterns, if any? Return true
+ # if no patterns have been provided.
+ def matches?(path)
+ return true unless self[:matches]
+
+ basename = File.basename(path)
+ flags = File::FNM_DOTMATCH | File::FNM_PATHNAME
+ if self[:matches].find {|pattern| File.fnmatch(pattern, basename, flags) }
+ return true
+ else
+ debug "No specified patterns match #{path}, not tidying"
+ return false
+ end
+ end
- return false if stat.ftype == "directory" and ! rmdirs?
+ # Should we remove the specified file?
+ def tidy?(path)
+ return false unless stat = self.stat(path)
- # The 'matches' parameter isn't OR'ed with the other tests --
- # it's just used to reduce the list of files we can match.
- return false if param = parameter(:matches) and ! param.tidy?(path, stat)
+ return false if stat.ftype == "directory" and ! rmdirs?
- tested = false
- [:age, :size].each do |name|
- next unless param = parameter(name)
- tested = true
- return true if param.tidy?(path, stat)
- end
+ # The 'matches' parameter isn't OR'ed with the other tests --
+ # it's just used to reduce the list of files we can match.
+ return false if param = parameter(:matches) and ! param.tidy?(path, stat)
- # If they don't specify either, then the file should always be removed.
- return true unless tested
- false
+ tested = false
+ [:age, :size].each do |name|
+ next unless param = parameter(name)
+ tested = true
+ return true if param.tidy?(path, stat)
end
- def stat(path)
- begin
- File.lstat(path)
- rescue Errno::ENOENT => error
- info "File does not exist"
- return nil
- rescue Errno::EACCES => error
- warning "Could not stat; permission denied"
- return nil
- end
+ # If they don't specify either, then the file should always be removed.
+ return true unless tested
+ false
+ end
+
+ def stat(path)
+ begin
+ File.lstat(path)
+ rescue Errno::ENOENT => error
+ info "File does not exist"
+ return nil
+ rescue Errno::EACCES => error
+ warning "Could not stat; permission denied"
+ return nil
end
+ end
end
diff --git a/lib/puppet/type/user.rb b/lib/puppet/type/user.rb
index 4c47227..c7ac796 100755
--- a/lib/puppet/type/user.rb
+++ b/lib/puppet/type/user.rb
@@ -5,380 +5,380 @@ require 'puppet/property/ordered_list'
require 'puppet/property/keyvalue'
module Puppet
- newtype(:user) do
- @doc = "Manage users. This type is mostly built to manage system
- users, so it is lacking some features useful for managing normal
- users.
-
- This resource type uses the prescribed native tools for creating
- groups and generally uses POSIX APIs for retrieving information
- about them. It does not directly modify /etc/passwd or anything."
-
- feature :allows_duplicates,
- "The provider supports duplicate users with the same UID."
-
- feature :manages_homedir,
- "The provider can create and remove home directories."
-
- feature :manages_passwords,
- "The provider can modify user passwords, by accepting a password
- hash."
-
- feature :manages_solaris_rbac,
- "The provider can manage roles and normal users"
+ newtype(:user) do
+ @doc = "Manage users. This type is mostly built to manage system
+ users, so it is lacking some features useful for managing normal
+ users.
+
+ This resource type uses the prescribed native tools for creating
+ groups and generally uses POSIX APIs for retrieving information
+ about them. It does not directly modify /etc/passwd or anything."
+
+ feature :allows_duplicates,
+ "The provider supports duplicate users with the same UID."
+
+ feature :manages_homedir,
+ "The provider can create and remove home directories."
+
+ feature :manages_passwords,
+ "The provider can modify user passwords, by accepting a password
+ hash."
+
+ feature :manages_solaris_rbac,
+ "The provider can manage roles and normal users"
+
+ newproperty(:ensure, :parent => Puppet::Property::Ensure) do
+ newvalue(:present, :event => :user_created) do
+ provider.create
+ end
+
+ newvalue(:absent, :event => :user_removed) do
+ provider.delete
+ end
+
+ newvalue(:role, :event => :role_created, :required_features => :manages_solaris_rbac) do
+ provider.create_role
+ end
+
+ desc "The basic state that the object should be in."
+
+ # If they're talking about the thing at all, they generally want to
+ # say it should exist.
+ defaultto do
+ if @resource.managed?
+ :present
+ else
+ nil
+ end
+ end
+
+ def retrieve
+ if provider.exists?
+ if provider.respond_to?(:is_role?) and provider.is_role?
+ return :role
+ else
+ return :present
+ end
+ else
+ return :absent
+ end
+ end
+ end
- newproperty(:ensure, :parent => Puppet::Property::Ensure) do
- newvalue(:present, :event => :user_created) do
- provider.create
- end
+ newproperty(:uid) do
+ desc "The user ID. Must be specified numerically. For new users
+ being created, if no user ID is specified then one will be
+ chosen automatically, which will likely result in the same user
+ having different IDs on different systems, which is not
+ recommended. This is especially noteworthy if you use Puppet
+ to manage the same user on both Darwin and other platforms,
+ since Puppet does the ID generation for you on Darwin, but the
+ tools do so on other platforms."
+
+ munge do |value|
+ case value
+ when String
+ if value =~ /^[-0-9]+$/
+ value = Integer(value)
+ end
+ end
- newvalue(:absent, :event => :user_removed) do
- provider.delete
- end
+ return value
+ end
+ end
- newvalue(:role, :event => :role_created, :required_features => :manages_solaris_rbac) do
- provider.create_role
- end
+ newproperty(:gid) do
+ desc "The user's primary group. Can be specified numerically or
+ by name."
- desc "The basic state that the object should be in."
+ munge do |value|
+ if value.is_a?(String) and value =~ /^[-0-9]+$/
+ Integer(value)
+ else
+ value
+ end
+ end
- # If they're talking about the thing at all, they generally want to
- # say it should exist.
- defaultto do
- if @resource.managed?
- :present
- else
- nil
- end
- end
+ def insync?(is)
+ return true unless self.should
- def retrieve
- if provider.exists?
- if provider.respond_to?(:is_role?) and provider.is_role?
- return :role
- else
- return :present
- end
- else
- return :absent
- end
- end
+ # We know the 'is' is a number, so we need to convert the 'should' to a number,
+ # too.
+ @should.each do |value|
+ return true if number = Puppet::Util.gid(value) and is == number
end
- newproperty(:uid) do
- desc "The user ID. Must be specified numerically. For new users
- being created, if no user ID is specified then one will be
- chosen automatically, which will likely result in the same user
- having different IDs on different systems, which is not
- recommended. This is especially noteworthy if you use Puppet
- to manage the same user on both Darwin and other platforms,
- since Puppet does the ID generation for you on Darwin, but the
- tools do so on other platforms."
-
- munge do |value|
- case value
- when String
- if value =~ /^[-0-9]+$/
- value = Integer(value)
- end
- end
-
- return value
- end
+ false
+ end
+
+ def sync
+ found = false
+ @should.each do |value|
+ if number = Puppet::Util.gid(value)
+ provider.gid = number
+ found = true
+ break
+ end
end
- newproperty(:gid) do
- desc "The user's primary group. Can be specified numerically or
- by name."
+ fail "Could not find group(s) #{@should.join(",")}" unless found
- munge do |value|
- if value.is_a?(String) and value =~ /^[-0-9]+$/
- Integer(value)
- else
- value
- end
- end
+ # Use the default event.
+ end
+ end
- def insync?(is)
- return true unless self.should
+ newproperty(:comment) do
+ desc "A description of the user. Generally is a user's full name."
+ end
- # We know the 'is' is a number, so we need to convert the 'should' to a number,
- # too.
- @should.each do |value|
- return true if number = Puppet::Util.gid(value) and is == number
- end
+ newproperty(:home) do
+ desc "The home directory of the user. The directory must be created
+ separately and is not currently checked for existence."
+ end
- false
- end
+ newproperty(:shell) do
+ desc "The user's login shell. The shell must exist and be
+ executable."
+ end
- def sync
- found = false
- @should.each do |value|
- if number = Puppet::Util.gid(value)
- provider.gid = number
- found = true
- break
- end
- end
+ newproperty(:password, :required_features => :manages_passwords) do
+ desc "The user's password, in whatever encrypted format the local machine requires. Be sure to enclose any value that includes a dollar sign ($) in single quotes (\')."
- fail "Could not find group(s) #{@should.join(",")}" unless found
+ validate do |value|
+ raise ArgumentError, "Passwords cannot include ':'" if value.is_a?(String) and value.include?(":")
+ end
- # Use the default event.
- end
+ def change_to_s(currentvalue, newvalue)
+ if currentvalue == :absent
+ return "created password"
+ else
+ return "changed password"
end
+ end
+ end
- newproperty(:comment) do
- desc "A description of the user. Generally is a user's full name."
- end
- newproperty(:home) do
- desc "The home directory of the user. The directory must be created
- separately and is not currently checked for existence."
- end
+ newproperty(:groups, :parent => Puppet::Property::List) do
+ desc "The groups of which the user is a member. The primary
+ group should not be listed. Multiple groups should be
+ specified as an array."
- newproperty(:shell) do
- desc "The user's login shell. The shell must exist and be
- executable."
+ validate do |value|
+ if value =~ /^\d+$/
+ raise ArgumentError, "Group names must be provided, not numbers"
end
+ raise ArgumentError, "Group names must be provided as an array, not a comma-separated list" if value.include?(",")
+ end
+ end
- newproperty(:password, :required_features => :manages_passwords) do
- desc "The user's password, in whatever encrypted format the local machine requires. Be sure to enclose any value that includes a dollar sign ($) in single quotes (\')."
-
- validate do |value|
- raise ArgumentError, "Passwords cannot include ':'" if value.is_a?(String) and value.include?(":")
- end
+ newparam(:name) do
+ desc "User name. While limitations are determined for
+ each operating system, it is generally a good idea to keep to
+ the degenerate 8 characters, beginning with a letter."
+ isnamevar
+ end
- def change_to_s(currentvalue, newvalue)
- if currentvalue == :absent
- return "created password"
- else
- return "changed password"
- end
- end
- end
+ newparam(:membership) do
+ desc "Whether specified groups should be treated as the only groups
+ of which the user is a member or whether they should merely
+ be treated as the minimum membership list."
+ newvalues(:inclusive, :minimum)
- newproperty(:groups, :parent => Puppet::Property::List) do
- desc "The groups of which the user is a member. The primary
- group should not be listed. Multiple groups should be
- specified as an array."
+ defaultto :minimum
+ end
- validate do |value|
- if value =~ /^\d+$/
- raise ArgumentError, "Group names must be provided, not numbers"
- end
- raise ArgumentError, "Group names must be provided as an array, not a comma-separated list" if value.include?(",")
- end
- end
+ newparam(:allowdupe, :boolean => true) do
+ desc "Whether to allow duplicate UIDs."
- newparam(:name) do
- desc "User name. While limitations are determined for
- each operating system, it is generally a good idea to keep to
- the degenerate 8 characters, beginning with a letter."
- isnamevar
- end
+ newvalues(:true, :false)
- newparam(:membership) do
- desc "Whether specified groups should be treated as the only groups
- of which the user is a member or whether they should merely
- be treated as the minimum membership list."
+ defaultto false
+ end
- newvalues(:inclusive, :minimum)
+ newparam(:managehome, :boolean => true) do
+ desc "Whether to manage the home directory when managing the user."
- defaultto :minimum
- end
+ newvalues(:true, :false)
- newparam(:allowdupe, :boolean => true) do
- desc "Whether to allow duplicate UIDs."
+ defaultto false
- newvalues(:true, :false)
-
- defaultto false
+ validate do |val|
+ if val.to_s == "true"
+ raise ArgumentError, "User provider #{provider.class.name} can not manage home directories" unless provider.class.manages_homedir?
end
+ end
+ end
- newparam(:managehome, :boolean => true) do
- desc "Whether to manage the home directory when managing the user."
-
- newvalues(:true, :false)
-
- defaultto false
-
- validate do |val|
- if val.to_s == "true"
- raise ArgumentError, "User provider #{provider.class.name} can not manage home directories" unless provider.class.manages_homedir?
- end
+ # Autorequire the group, if it's around
+ autorequire(:group) do
+ autos = []
+
+ if obj = @parameters[:gid] and groups = obj.shouldorig
+ groups = groups.collect { |group|
+ if group =~ /^\d+$/
+ Integer(group)
+ else
+ group
+ end
+ }
+ groups.each { |group|
+ case group
+ when Integer
+ if resource = catalog.resources.find { |r| r.is_a?(Puppet::Type.type(:group)) and r.should(:gid) == group }
+ autos << resource
end
- end
+ else
+ autos << group
+ end
+ }
+ end
- # Autorequire the group, if it's around
- autorequire(:group) do
- autos = []
-
- if obj = @parameters[:gid] and groups = obj.shouldorig
- groups = groups.collect { |group|
- if group =~ /^\d+$/
- Integer(group)
- else
- group
- end
- }
- groups.each { |group|
- case group
- when Integer
- if resource = catalog.resources.find { |r| r.is_a?(Puppet::Type.type(:group)) and r.should(:gid) == group }
- autos << resource
- end
- else
- autos << group
- end
- }
- end
+ if obj = @parameters[:groups] and groups = obj.should
+ autos += groups.split(",")
+ end
- if obj = @parameters[:groups] and groups = obj.should
- autos += groups.split(",")
- end
+ autos
+ end
- autos
- end
+ # Provide an external hook. Yay breaking out of APIs.
+ def exists?
+ provider.exists?
+ end
+
+ def retrieve
+ absent = false
+ properties.inject({}) { |prophash, property|
+ current_value = :absent
- # Provide an external hook. Yay breaking out of APIs.
- def exists?
- provider.exists?
+ if absent
+ prophash[property] = :absent
+ else
+ current_value = property.retrieve
+ prophash[property] = current_value
end
- def retrieve
- absent = false
- properties.inject({}) { |prophash, property|
- current_value = :absent
-
- if absent
- prophash[property] = :absent
- else
- current_value = property.retrieve
- prophash[property] = current_value
- end
-
- if property.name == :ensure and current_value == :absent
- absent = true
- end
- prophash
- }
+ if property.name == :ensure and current_value == :absent
+ absent = true
end
+ prophash
+ }
+ end
- newproperty(:roles, :parent => Puppet::Property::List, :required_features => :manages_solaris_rbac) do
- desc "The roles the user has. Multiple roles should be
- specified as an array."
+ newproperty(:roles, :parent => Puppet::Property::List, :required_features => :manages_solaris_rbac) do
+ desc "The roles the user has. Multiple roles should be
+ specified as an array."
- def membership
- :role_membership
- end
+ def membership
+ :role_membership
+ end
- validate do |value|
- if value =~ /^\d+$/
- raise ArgumentError, "Role names must be provided, not numbers"
- end
- raise ArgumentError, "Role names must be provided as an array, not a comma-separated list" if value.include?(",")
- end
+ validate do |value|
+ if value =~ /^\d+$/
+ raise ArgumentError, "Role names must be provided, not numbers"
end
+ raise ArgumentError, "Role names must be provided as an array, not a comma-separated list" if value.include?(",")
+ end
+ end
- #autorequire the roles that the user has
- autorequire(:user) do
- reqs = []
+ #autorequire the roles that the user has
+ autorequire(:user) do
+ reqs = []
- if roles_property = @parameters[:roles] and roles = roles_property.should
- reqs += roles.split(',')
- end
+ if roles_property = @parameters[:roles] and roles = roles_property.should
+ reqs += roles.split(',')
+ end
- reqs
- end
+ reqs
+ end
- newparam(:role_membership) do
- desc "Whether specified roles should be treated as the only roles
- of which the user is a member or whether they should merely
- be treated as the minimum membership list."
+ newparam(:role_membership) do
+ desc "Whether specified roles should be treated as the only roles
+ of which the user is a member or whether they should merely
+ be treated as the minimum membership list."
- newvalues(:inclusive, :minimum)
+ newvalues(:inclusive, :minimum)
- defaultto :minimum
- end
+ defaultto :minimum
+ end
- newproperty(:auths, :parent => Puppet::Property::List, :required_features => :manages_solaris_rbac) do
- desc "The auths the user has. Multiple auths should be
- specified as an array."
+ newproperty(:auths, :parent => Puppet::Property::List, :required_features => :manages_solaris_rbac) do
+ desc "The auths the user has. Multiple auths should be
+ specified as an array."
- def membership
- :auth_membership
- end
+ def membership
+ :auth_membership
+ end
- validate do |value|
- if value =~ /^\d+$/
- raise ArgumentError, "Auth names must be provided, not numbers"
- end
- raise ArgumentError, "Auth names must be provided as an array, not a comma-separated list" if value.include?(",")
- end
+ validate do |value|
+ if value =~ /^\d+$/
+ raise ArgumentError, "Auth names must be provided, not numbers"
end
+ raise ArgumentError, "Auth names must be provided as an array, not a comma-separated list" if value.include?(",")
+ end
+ end
- newparam(:auth_membership) do
- desc "Whether specified auths should be treated as the only auths
- of which the user is a member or whether they should merely
- be treated as the minimum membership list."
+ newparam(:auth_membership) do
+ desc "Whether specified auths should be treated as the only auths
+ of which the user is a member or whether they should merely
+ be treated as the minimum membership list."
- newvalues(:inclusive, :minimum)
+ newvalues(:inclusive, :minimum)
- defaultto :minimum
- end
+ defaultto :minimum
+ end
- newproperty(:profiles, :parent => Puppet::Property::OrderedList, :required_features => :manages_solaris_rbac) do
- desc "The profiles the user has. Multiple profiles should be
- specified as an array."
+ newproperty(:profiles, :parent => Puppet::Property::OrderedList, :required_features => :manages_solaris_rbac) do
+ desc "The profiles the user has. Multiple profiles should be
+ specified as an array."
- def membership
- :profile_membership
- end
+ def membership
+ :profile_membership
+ end
- validate do |value|
- if value =~ /^\d+$/
- raise ArgumentError, "Profile names must be provided, not numbers"
- end
- raise ArgumentError, "Profile names must be provided as an array, not a comma-separated list" if value.include?(",")
- end
+ validate do |value|
+ if value =~ /^\d+$/
+ raise ArgumentError, "Profile names must be provided, not numbers"
end
+ raise ArgumentError, "Profile names must be provided as an array, not a comma-separated list" if value.include?(",")
+ end
+ end
- newparam(:profile_membership) do
- desc "Whether specified roles should be treated as the only roles
- of which the user is a member or whether they should merely
- be treated as the minimum membership list."
+ newparam(:profile_membership) do
+ desc "Whether specified roles should be treated as the only roles
+ of which the user is a member or whether they should merely
+ be treated as the minimum membership list."
- newvalues(:inclusive, :minimum)
+ newvalues(:inclusive, :minimum)
- defaultto :minimum
- end
+ defaultto :minimum
+ end
- newproperty(:keys, :parent => Puppet::Property::KeyValue, :required_features => :manages_solaris_rbac) do
- desc "Specify user attributes in an array of keyvalue pairs"
+ newproperty(:keys, :parent => Puppet::Property::KeyValue, :required_features => :manages_solaris_rbac) do
+ desc "Specify user attributes in an array of keyvalue pairs"
- def membership
- :key_membership
- end
+ def membership
+ :key_membership
+ end
- validate do |value|
- raise ArgumentError, "key value pairs must be seperated by an =" unless value.include?("=")
- end
- end
+ validate do |value|
+ raise ArgumentError, "key value pairs must be seperated by an =" unless value.include?("=")
+ end
+ end
- newparam(:key_membership) do
- desc "Whether specified key value pairs should be treated as the only attributes
- of the user or whether they should merely
- be treated as the minimum list."
+ newparam(:key_membership) do
+ desc "Whether specified key value pairs should be treated as the only attributes
+ of the user or whether they should merely
+ be treated as the minimum list."
- newvalues(:inclusive, :minimum)
+ newvalues(:inclusive, :minimum)
- defaultto :minimum
- end
+ defaultto :minimum
+ end
- newproperty(:project, :required_features => :manages_solaris_rbac) do
- desc "The name of the project associated with a user"
- end
+ newproperty(:project, :required_features => :manages_solaris_rbac) do
+ desc "The name of the project associated with a user"
end
+ end
end
diff --git a/lib/puppet/type/yumrepo.rb b/lib/puppet/type/yumrepo.rb
index d37da02..e0ed3ad 100644
--- a/lib/puppet/type/yumrepo.rb
+++ b/lib/puppet/type/yumrepo.rb
@@ -3,344 +3,344 @@
require 'puppet/util/inifile'
module Puppet
- # A property for one entry in a .ini-style file
- class IniProperty < Puppet::Property
- def insync?(is)
- # A should property of :absent is the same as nil
- if is.nil? && (should.nil? || should == :absent)
- return true
- end
- super(is)
- end
-
- def sync
- if insync?(retrieve)
- result = nil
- else
- result = set(self.should)
- if should == :absent
- resource.section[inikey] = nil
- else
- resource.section[inikey] = should
- end
- end
- result
- end
+ # A property for one entry in a .ini-style file
+ class IniProperty < Puppet::Property
+ def insync?(is)
+ # A should property of :absent is the same as nil
+ if is.nil? && (should.nil? || should == :absent)
+ return true
+ end
+ super(is)
+ end
- def retrieve
- resource.section[inikey]
- end
+ def sync
+ if insync?(retrieve)
+ result = nil
+ else
+ result = set(self.should)
+ if should == :absent
+ resource.section[inikey] = nil
+ else
+ resource.section[inikey] = should
+ end
+ end
+ result
+ end
- def inikey
- name.to_s
- end
+ def retrieve
+ resource.section[inikey]
+ end
- # Set the key associated with this property to KEY, instead
- # of using the property's NAME
- def self.inikey(key)
- # Override the inikey instance method
- # Is there a way to do this without resorting to strings ?
- # Using a block fails because the block can't access
- # the variable 'key' in the outer scope
- self.class_eval("def inikey ; \"#{key.to_s}\" ; end")
- end
+ def inikey
+ name.to_s
+ end
+ # Set the key associated with this property to KEY, instead
+ # of using the property's NAME
+ def self.inikey(key)
+ # Override the inikey instance method
+ # Is there a way to do this without resorting to strings ?
+ # Using a block fails because the block can't access
+ # the variable 'key' in the outer scope
+ self.class_eval("def inikey ; \"#{key.to_s}\" ; end")
end
- # Doc string for properties that can be made 'absent'
- ABSENT_DOC="Set this to 'absent' to remove it from the file completely"
+ end
- newtype(:yumrepo) do
- @doc = "The client-side description of a yum repository. Repository
- configurations are found by parsing /etc/yum.conf and
- the files indicated by reposdir in that file (see yum.conf(5) for details)
+ # Doc string for properties that can be made 'absent'
+ ABSENT_DOC="Set this to 'absent' to remove it from the file completely"
- Most parameters are identical to the ones documented
- in yum.conf(5)
+ newtype(:yumrepo) do
+ @doc = "The client-side description of a yum repository. Repository
+ configurations are found by parsing /etc/yum.conf and
+ the files indicated by reposdir in that file (see yum.conf(5) for details)
- Continuation lines that yum supports for example for the
- baseurl are not supported. No attempt is made to access
- files included with the **include** directive"
+ Most parameters are identical to the ones documented
+ in yum.conf(5)
- class << self
- attr_accessor :filetype
- # The writer is only used for testing, there should be no need
- # to change yumconf or inifile in any other context
- attr_accessor :yumconf
- attr_writer :inifile
- end
+ Continuation lines that yum supports for example for the
+ baseurl are not supported. No attempt is made to access
+ files included with the **include** directive"
- self.filetype = Puppet::Util::FileType.filetype(:flat)
-
- @inifile = nil
-
- @yumconf = "/etc/yum.conf"
-
- # Where to put files for brand new sections
- @defaultrepodir = nil
-
- def self.instances
- l = []
- check = validproperties
- clear
- inifile.each_section do |s|
- next if s.name == "main"
- obj = create(:name => s.name, :audit => check)
- current_values = obj.retrieve
- obj.eachproperty do |property|
- if current_values[property].nil?
- obj.delete(property.name)
- else
- property.should = current_values[property]
- end
- end
- obj.delete(:audit)
- l << obj
- end
- l
- end
+ class << self
+ attr_accessor :filetype
+ # The writer is only used for testing, there should be no need
+ # to change yumconf or inifile in any other context
+ attr_accessor :yumconf
+ attr_writer :inifile
+ end
- # Return the Puppet::Util::IniConfig::File for the whole yum config
- def self.inifile
- if @inifile.nil?
- @inifile = read
- main = @inifile['main']
- raise Puppet::Error, "File #{yumconf} does not contain a main section" if main.nil?
- reposdir = main['reposdir']
- reposdir ||= "/etc/yum.repos.d, /etc/yum/repos.d"
- reposdir.gsub!(/[\n,]/, " ")
- reposdir.split.each do |dir|
- Dir::glob("#{dir}/*.repo").each do |file|
- @inifile.read(file) if File.file?(file)
- end
- end
- reposdir.split.each do |dir|
- if File::directory?(dir) && File::writable?(dir)
- @defaultrepodir = dir
- break
- end
- end
- end
- @inifile
- end
+ self.filetype = Puppet::Util::FileType.filetype(:flat)
+
+ @inifile = nil
+
+ @yumconf = "/etc/yum.conf"
+
+ # Where to put files for brand new sections
+ @defaultrepodir = nil
+
+ def self.instances
+ l = []
+ check = validproperties
+ clear
+ inifile.each_section do |s|
+ next if s.name == "main"
+ obj = create(:name => s.name, :audit => check)
+ current_values = obj.retrieve
+ obj.eachproperty do |property|
+ if current_values[property].nil?
+ obj.delete(property.name)
+ else
+ property.should = current_values[property]
+ end
+ end
+ obj.delete(:audit)
+ l << obj
+ end
+ l
+ end
- # Parse the yum config files. Only exposed for the tests
- # Non-test code should use self.inifile to get at the
- # underlying file
- def self.read
- result = Puppet::Util::IniConfig::File.new
- result.read(yumconf)
- main = result['main']
- raise Puppet::Error, "File #{yumconf} does not contain a main section" if main.nil?
- reposdir = main['reposdir']
- reposdir ||= "/etc/yum.repos.d, /etc/yum/repos.d"
- reposdir.gsub!(/[\n,]/, " ")
- reposdir.split.each do |dir|
- Dir::glob("#{dir}/*.repo").each do |file|
- result.read(file) if File.file?(file)
- end
- end
- if @defaultrepodir.nil?
- reposdir.split.each do |dir|
- if File::directory?(dir) && File::writable?(dir)
- @defaultrepodir = dir
- break
- end
- end
- end
- result
- end
+ # Return the Puppet::Util::IniConfig::File for the whole yum config
+ def self.inifile
+ if @inifile.nil?
+ @inifile = read
+ main = @inifile['main']
+ raise Puppet::Error, "File #{yumconf} does not contain a main section" if main.nil?
+ reposdir = main['reposdir']
+ reposdir ||= "/etc/yum.repos.d, /etc/yum/repos.d"
+ reposdir.gsub!(/[\n,]/, " ")
+ reposdir.split.each do |dir|
+ Dir::glob("#{dir}/*.repo").each do |file|
+ @inifile.read(file) if File.file?(file)
+ end
+ end
+ reposdir.split.each do |dir|
+ if File::directory?(dir) && File::writable?(dir)
+ @defaultrepodir = dir
+ break
+ end
+ end
+ end
+ @inifile
+ end
- # Return the Puppet::Util::IniConfig::Section with name NAME
- # from the yum config
- def self.section(name)
- result = inifile[name]
- if result.nil?
- # Brand new section
- path = yumconf
- path = File::join(@defaultrepodir, "#{name}.repo") unless @defaultrepodir.nil?
- Puppet::info "create new repo #{name} in file #{path}"
- result = inifile.add_section(name, path)
- end
- result
- end
+ # Parse the yum config files. Only exposed for the tests
+ # Non-test code should use self.inifile to get at the
+ # underlying file
+ def self.read
+ result = Puppet::Util::IniConfig::File.new
+ result.read(yumconf)
+ main = result['main']
+ raise Puppet::Error, "File #{yumconf} does not contain a main section" if main.nil?
+ reposdir = main['reposdir']
+ reposdir ||= "/etc/yum.repos.d, /etc/yum/repos.d"
+ reposdir.gsub!(/[\n,]/, " ")
+ reposdir.split.each do |dir|
+ Dir::glob("#{dir}/*.repo").each do |file|
+ result.read(file) if File.file?(file)
+ end
+ end
+ if @defaultrepodir.nil?
+ reposdir.split.each do |dir|
+ if File::directory?(dir) && File::writable?(dir)
+ @defaultrepodir = dir
+ break
+ end
+ end
+ end
+ result
+ end
- # Store all modifications back to disk
- def self.store
- inifile.store
- unless Puppet[:noop]
- target_mode = 0644 # FIXME: should be configurable
- inifile.each_file do |file|
- current_mode = File.stat(file).mode & 0777
- unless current_mode == target_mode
- Puppet::info "changing mode of #{file} from %03o to %03o" % [current_mode, target_mode]
- File.chmod(target_mode, file)
- end
- end
- end
- end
+ # Return the Puppet::Util::IniConfig::Section with name NAME
+ # from the yum config
+ def self.section(name)
+ result = inifile[name]
+ if result.nil?
+ # Brand new section
+ path = yumconf
+ path = File::join(@defaultrepodir, "#{name}.repo") unless @defaultrepodir.nil?
+ Puppet::info "create new repo #{name} in file #{path}"
+ result = inifile.add_section(name, path)
+ end
+ result
+ end
- # This is only used during testing.
- def self.clear
- @inifile = nil
- @yumconf = "/etc/yum.conf"
- @defaultrepodir = nil
- end
+ # Store all modifications back to disk
+ def self.store
+ inifile.store
+ unless Puppet[:noop]
+ target_mode = 0644 # FIXME: should be configurable
+ inifile.each_file do |file|
+ current_mode = File.stat(file).mode & 0777
+ unless current_mode == target_mode
+ Puppet::info "changing mode of #{file} from %03o to %03o" % [current_mode, target_mode]
+ File.chmod(target_mode, file)
+ end
+ end
+ end
+ end
- # Return the Puppet::Util::IniConfig::Section for this yumrepo resource
- def section
- self.class.section(self[:name])
- end
+ # This is only used during testing.
+ def self.clear
+ @inifile = nil
+ @yumconf = "/etc/yum.conf"
+ @defaultrepodir = nil
+ end
- # Store modifications to this yumrepo resource back to disk
- def flush
- self.class.store
- end
+ # Return the Puppet::Util::IniConfig::Section for this yumrepo resource
+ def section
+ self.class.section(self[:name])
+ end
- newparam(:name) do
- desc "The name of the repository. This corresponds to the
- repositoryid parameter in yum.conf(5)."
- isnamevar
- end
+ # Store modifications to this yumrepo resource back to disk
+ def flush
+ self.class.store
+ end
- newproperty(:descr, :parent => Puppet::IniProperty) do
- desc "A human readable description of the repository.
- This corresponds to the name parameter in yum.conf(5).
- #{ABSENT_DOC}"
- newvalue(:absent) { self.should = :absent }
- newvalue(/.*/) { }
- inikey "name"
- end
+ newparam(:name) do
+ desc "The name of the repository. This corresponds to the
+ repositoryid parameter in yum.conf(5)."
+ isnamevar
+ end
- newproperty(:mirrorlist, :parent => Puppet::IniProperty) do
- desc "The URL that holds the list of mirrors for this repository.
- #{ABSENT_DOC}"
- newvalue(:absent) { self.should = :absent }
- # Should really check that it's a valid URL
- newvalue(/.*/) { }
- end
+ newproperty(:descr, :parent => Puppet::IniProperty) do
+ desc "A human readable description of the repository.
+ This corresponds to the name parameter in yum.conf(5).
+ #{ABSENT_DOC}"
+ newvalue(:absent) { self.should = :absent }
+ newvalue(/.*/) { }
+ inikey "name"
+ end
- newproperty(:baseurl, :parent => Puppet::IniProperty) do
- desc "The URL for this repository.\n#{ABSENT_DOC}"
- newvalue(:absent) { self.should = :absent }
- # Should really check that it's a valid URL
- newvalue(/.*/) { }
- end
+ newproperty(:mirrorlist, :parent => Puppet::IniProperty) do
+ desc "The URL that holds the list of mirrors for this repository.
+ #{ABSENT_DOC}"
+ newvalue(:absent) { self.should = :absent }
+ # Should really check that it's a valid URL
+ newvalue(/.*/) { }
+ end
- newproperty(:enabled, :parent => Puppet::IniProperty) do
- desc "Whether this repository is enabled or disabled. Possible
- values are '0', and '1'.\n#{ABSENT_DOC}"
- newvalue(:absent) { self.should = :absent }
- newvalue(%r{(0|1)}) { }
- end
+ newproperty(:baseurl, :parent => Puppet::IniProperty) do
+ desc "The URL for this repository.\n#{ABSENT_DOC}"
+ newvalue(:absent) { self.should = :absent }
+ # Should really check that it's a valid URL
+ newvalue(/.*/) { }
+ end
- newproperty(:gpgcheck, :parent => Puppet::IniProperty) do
- desc "Whether to check the GPG signature on packages installed
- from this repository. Possible values are '0', and '1'.
- \n#{ABSENT_DOC}"
- newvalue(:absent) { self.should = :absent }
- newvalue(%r{(0|1)}) { }
- end
+ newproperty(:enabled, :parent => Puppet::IniProperty) do
+ desc "Whether this repository is enabled or disabled. Possible
+ values are '0', and '1'.\n#{ABSENT_DOC}"
+ newvalue(:absent) { self.should = :absent }
+ newvalue(%r{(0|1)}) { }
+ end
- newproperty(:gpgkey, :parent => Puppet::IniProperty) do
- desc "The URL for the GPG key with which packages from this
- repository are signed.\n#{ABSENT_DOC}"
- newvalue(:absent) { self.should = :absent }
- # Should really check that it's a valid URL
- newvalue(/.*/) { }
- end
+ newproperty(:gpgcheck, :parent => Puppet::IniProperty) do
+ desc "Whether to check the GPG signature on packages installed
+ from this repository. Possible values are '0', and '1'.
+ \n#{ABSENT_DOC}"
+ newvalue(:absent) { self.should = :absent }
+ newvalue(%r{(0|1)}) { }
+ end
- newproperty(:include, :parent => Puppet::IniProperty) do
- desc "A URL from which to include the config.\n#{ABSENT_DOC}"
- newvalue(:absent) { self.should = :absent }
- # Should really check that it's a valid URL
- newvalue(/.*/) { }
- end
+ newproperty(:gpgkey, :parent => Puppet::IniProperty) do
+ desc "The URL for the GPG key with which packages from this
+ repository are signed.\n#{ABSENT_DOC}"
+ newvalue(:absent) { self.should = :absent }
+ # Should really check that it's a valid URL
+ newvalue(/.*/) { }
+ end
- newproperty(:exclude, :parent => Puppet::IniProperty) do
- desc "List of shell globs. Matching packages will never be
- considered in updates or installs for this repo.
- #{ABSENT_DOC}"
- newvalue(:absent) { self.should = :absent }
- newvalue(/.*/) { }
- end
+ newproperty(:include, :parent => Puppet::IniProperty) do
+ desc "A URL from which to include the config.\n#{ABSENT_DOC}"
+ newvalue(:absent) { self.should = :absent }
+ # Should really check that it's a valid URL
+ newvalue(/.*/) { }
+ end
- newproperty(:includepkgs, :parent => Puppet::IniProperty) do
- desc "List of shell globs. If this is set, only packages
- matching one of the globs will be considered for
- update or install.\n#{ABSENT_DOC}"
- newvalue(:absent) { self.should = :absent }
- newvalue(/.*/) { }
- end
+ newproperty(:exclude, :parent => Puppet::IniProperty) do
+ desc "List of shell globs. Matching packages will never be
+ considered in updates or installs for this repo.
+ #{ABSENT_DOC}"
+ newvalue(:absent) { self.should = :absent }
+ newvalue(/.*/) { }
+ end
- newproperty(:enablegroups, :parent => Puppet::IniProperty) do
- desc "Determines whether yum will allow the use of
- package groups for this repository. Possible
- values are '0', and '1'.\n#{ABSENT_DOC}"
- newvalue(:absent) { self.should = :absent }
- newvalue(%r{(0|1)}) { }
- end
+ newproperty(:includepkgs, :parent => Puppet::IniProperty) do
+ desc "List of shell globs. If this is set, only packages
+ matching one of the globs will be considered for
+ update or install.\n#{ABSENT_DOC}"
+ newvalue(:absent) { self.should = :absent }
+ newvalue(/.*/) { }
+ end
- newproperty(:failovermethod, :parent => Puppet::IniProperty) do
- desc "Either 'roundrobin' or 'priority'.\n#{ABSENT_DOC}"
- newvalue(:absent) { self.should = :absent }
- newvalue(%r{roundrobin|priority}) { }
- end
+ newproperty(:enablegroups, :parent => Puppet::IniProperty) do
+ desc "Determines whether yum will allow the use of
+ package groups for this repository. Possible
+ values are '0', and '1'.\n#{ABSENT_DOC}"
+ newvalue(:absent) { self.should = :absent }
+ newvalue(%r{(0|1)}) { }
+ end
- newproperty(:keepalive, :parent => Puppet::IniProperty) do
- desc "Either '1' or '0'. This tells yum whether or not HTTP/1.1
- keepalive should be used with this repository.\n#{ABSENT_DOC}"
- newvalue(:absent) { self.should = :absent }
- newvalue(%r{(0|1)}) { }
- end
+ newproperty(:failovermethod, :parent => Puppet::IniProperty) do
+ desc "Either 'roundrobin' or 'priority'.\n#{ABSENT_DOC}"
+ newvalue(:absent) { self.should = :absent }
+ newvalue(%r{roundrobin|priority}) { }
+ end
- newproperty(:timeout, :parent => Puppet::IniProperty) do
- desc "Number of seconds to wait for a connection before timing
- out.\n#{ABSENT_DOC}"
- newvalue(:absent) { self.should = :absent }
- newvalue(%r{[0-9]+}) { }
- end
+ newproperty(:keepalive, :parent => Puppet::IniProperty) do
+ desc "Either '1' or '0'. This tells yum whether or not HTTP/1.1
+ keepalive should be used with this repository.\n#{ABSENT_DOC}"
+ newvalue(:absent) { self.should = :absent }
+ newvalue(%r{(0|1)}) { }
+ end
- newproperty(:metadata_expire, :parent => Puppet::IniProperty) do
- desc "Number of seconds after which the metadata will expire.
- #{ABSENT_DOC}"
- newvalue(:absent) { self.should = :absent }
- newvalue(%r{[0-9]+}) { }
- end
+ newproperty(:timeout, :parent => Puppet::IniProperty) do
+ desc "Number of seconds to wait for a connection before timing
+ out.\n#{ABSENT_DOC}"
+ newvalue(:absent) { self.should = :absent }
+ newvalue(%r{[0-9]+}) { }
+ end
- newproperty(:protect, :parent => Puppet::IniProperty) do
- desc "Enable or disable protection for this repository. Requires
- that the protectbase plugin is installed and enabled.
- #{ABSENT_DOC}"
- newvalue(:absent) { self.should = :absent }
- newvalue(%r{(0|1)}) { }
- end
+ newproperty(:metadata_expire, :parent => Puppet::IniProperty) do
+ desc "Number of seconds after which the metadata will expire.
+ #{ABSENT_DOC}"
+ newvalue(:absent) { self.should = :absent }
+ newvalue(%r{[0-9]+}) { }
+ end
- newproperty(:priority, :parent => Puppet::IniProperty) do
- desc "Priority of this repository from 1-99. Requires that
- the priorities plugin is installed and enabled.
- #{ABSENT_DOC}"
- newvalue(:absent) { self.should = :absent }
- newvalue(%r{[1-9][0-9]?}) { }
- end
+ newproperty(:protect, :parent => Puppet::IniProperty) do
+ desc "Enable or disable protection for this repository. Requires
+ that the protectbase plugin is installed and enabled.
+ #{ABSENT_DOC}"
+ newvalue(:absent) { self.should = :absent }
+ newvalue(%r{(0|1)}) { }
+ end
- newproperty(:proxy, :parent => Puppet::IniProperty) do
- desc "URL to the proxy server for this repository.\n#{ABSENT_DOC}"
- newvalue(:absent) { self.should = :absent }
- # Should really check that it's a valid URL
- newvalue(/.*/) { }
- end
+ newproperty(:priority, :parent => Puppet::IniProperty) do
+ desc "Priority of this repository from 1-99. Requires that
+ the priorities plugin is installed and enabled.
+ #{ABSENT_DOC}"
+ newvalue(:absent) { self.should = :absent }
+ newvalue(%r{[1-9][0-9]?}) { }
+ end
- newproperty(:proxy_username, :parent => Puppet::IniProperty) do
- desc "Username for this proxy.\n#{ABSENT_DOC}"
- newvalue(:absent) { self.should = :absent }
- newvalue(/.*/) { }
- end
+ newproperty(:proxy, :parent => Puppet::IniProperty) do
+ desc "URL to the proxy server for this repository.\n#{ABSENT_DOC}"
+ newvalue(:absent) { self.should = :absent }
+ # Should really check that it's a valid URL
+ newvalue(/.*/) { }
+ end
- newproperty(:proxy_password, :parent => Puppet::IniProperty) do
- desc "Password for this proxy.\n#{ABSENT_DOC}"
- newvalue(:absent) { self.should = :absent }
- newvalue(/.*/) { }
- end
+ newproperty(:proxy_username, :parent => Puppet::IniProperty) do
+ desc "Username for this proxy.\n#{ABSENT_DOC}"
+ newvalue(:absent) { self.should = :absent }
+ newvalue(/.*/) { }
+ end
+
+ newproperty(:proxy_password, :parent => Puppet::IniProperty) do
+ desc "Password for this proxy.\n#{ABSENT_DOC}"
+ newvalue(:absent) { self.should = :absent }
+ newvalue(/.*/) { }
end
+ end
end
diff --git a/lib/puppet/type/zfs.rb b/lib/puppet/type/zfs.rb
index 3a8806a..e1a972d 100755
--- a/lib/puppet/type/zfs.rb
+++ b/lib/puppet/type/zfs.rb
@@ -1,51 +1,51 @@
module Puppet
- newtype(:zfs) do
- @doc = "Manage zfs. Create destroy and set properties on zfs instances."
+ newtype(:zfs) do
+ @doc = "Manage zfs. Create destroy and set properties on zfs instances."
- ensurable
+ ensurable
- newparam(:name) do
- desc "The full name for this filesystem. (including the zpool)"
- end
+ newparam(:name) do
+ desc "The full name for this filesystem. (including the zpool)"
+ end
- newproperty(:mountpoint) do
- desc "The mountpoint property."
- end
+ newproperty(:mountpoint) do
+ desc "The mountpoint property."
+ end
- newproperty(:compression) do
- desc "The compression property."
- end
+ newproperty(:compression) do
+ desc "The compression property."
+ end
- newproperty(:copies) do
- desc "The copies property."
- end
+ newproperty(:copies) do
+ desc "The copies property."
+ end
- newproperty(:quota) do
- desc "The quota property."
- end
+ newproperty(:quota) do
+ desc "The quota property."
+ end
- newproperty(:reservation) do
- desc "The reservation property."
- end
+ newproperty(:reservation) do
+ desc "The reservation property."
+ end
- newproperty(:sharenfs) do
- desc "The sharenfs property."
- end
+ newproperty(:sharenfs) do
+ desc "The sharenfs property."
+ end
- newproperty(:snapdir) do
- desc "The sharenfs property."
- end
+ newproperty(:snapdir) do
+ desc "The sharenfs property."
+ end
- autorequire(:zpool) do
- #strip the zpool off the zfs name and autorequire it
- [@parameters[:name].value.split('/')[0]]
- end
+ autorequire(:zpool) do
+ #strip the zpool off the zfs name and autorequire it
+ [@parameters[:name].value.split('/')[0]]
+ end
- autorequire(:zfs) do
- #slice and dice, we want all the zfs before this one
- names = @parameters[:name].value.split('/')
- names.slice(1..-2).inject([]) { |a,v| a << "#{a.last}/#{v}" }.collect { |fs| names[0] + fs }
- end
+ autorequire(:zfs) do
+ #slice and dice, we want all the zfs before this one
+ names = @parameters[:name].value.split('/')
+ names.slice(1..-2).inject([]) { |a,v| a << "#{a.last}/#{v}" }.collect { |fs| names[0] + fs }
end
+ end
end
diff --git a/lib/puppet/type/zone.rb b/lib/puppet/type/zone.rb
index 9d972a1..d523c46 100644
--- a/lib/puppet/type/zone.rb
+++ b/lib/puppet/type/zone.rb
@@ -1,444 +1,444 @@
Puppet::Type.newtype(:zone) do
- @doc = "Solaris zones."
-
- # These properties modify the zone configuration, and they need to provide
- # the text separately from syncing it, so all config statements can be rolled
- # into a single creation statement.
- class ZoneConfigProperty < Puppet::Property
- # Perform the config operation.
- def sync
- provider.setconfig self.configtext
- end
+ @doc = "Solaris zones."
+
+ # These properties modify the zone configuration, and they need to provide
+ # the text separately from syncing it, so all config statements can be rolled
+ # into a single creation statement.
+ class ZoneConfigProperty < Puppet::Property
+ # Perform the config operation.
+ def sync
+ provider.setconfig self.configtext
end
+ end
- # Those properties that can have multiple instances.
- class ZoneMultiConfigProperty < ZoneConfigProperty
- def configtext
- list = @should
-
- current_value = self.retrieve
-
- unless current_value.is_a? Symbol
- if current_value.is_a? Array
- list += current_value
- else
- list << current_value if current_value
- end
- end
-
- # Some hackery so we can test whether current_value is an array or a symbol
- if current_value.is_a? Array
- tmpis = current_value
- else
- if current_value
- tmpis = [current_value]
- else
- tmpis = []
- end
- end
+ # Those properties that can have multiple instances.
+ class ZoneMultiConfigProperty < ZoneConfigProperty
+ def configtext
+ list = @should
- rms = []
- adds = []
+ current_value = self.retrieve
- # Collect the modifications to make
- list.sort.uniq.collect do |obj|
- # Skip objectories that are configured and should be
- next if tmpis.include?(obj) and @should.include?(obj)
-
- if tmpis.include?(obj)
- rms << obj
- else
- adds << obj
- end
- end
-
-
- # And then perform all of the removals before any of the adds.
- (rms.collect { |o| rm(o) } + adds.collect { |o| add(o) }).join("\n")
+ unless current_value.is_a? Symbol
+ if current_value.is_a? Array
+ list += current_value
+ else
+ list << current_value if current_value
end
-
- # We want all specified directories to be included.
- def insync?(current_value)
- if current_value.is_a? Array and @should.is_a? Array
- current_value.sort == @should.sort
- else
- current_value == @should
- end
+ end
+
+ # Some hackery so we can test whether current_value is an array or a symbol
+ if current_value.is_a? Array
+ tmpis = current_value
+ else
+ if current_value
+ tmpis = [current_value]
+ else
+ tmpis = []
end
- end
+ end
- ensurable do
- desc "The running state of the zone. The valid states directly reflect
- the states that ``zoneadm`` provides. The states are linear,
- in that a zone must be ``configured`` then ``installed``, and
- only then can be ``running``. Note also that ``halt`` is currently
- used to stop zones."
+ rms = []
+ adds = []
- @states = {}
- @parametervalues = []
+ # Collect the modifications to make
+ list.sort.uniq.collect do |obj|
+ # Skip objectories that are configured and should be
+ next if tmpis.include?(obj) and @should.include?(obj)
- def self.alias_state(values)
- @state_aliases ||= {}
- values.each do |nick, name|
- @state_aliases[nick] = name
- end
+ if tmpis.include?(obj)
+ rms << obj
+ else
+ adds << obj
end
+ end
- def self.newvalue(name, hash)
- @parametervalues = [] if @parametervalues.is_a? Hash
- @parametervalues << name
+ # And then perform all of the removals before any of the adds.
+ (rms.collect { |o| rm(o) } + adds.collect { |o| add(o) }).join("\n")
+ end
- @states[name] = hash
- hash[:name] = name
- end
+ # We want all specified directories to be included.
+ def insync?(current_value)
+ if current_value.is_a? Array and @should.is_a? Array
+ current_value.sort == @should.sort
+ else
+ current_value == @should
+ end
+ end
+ end
+
+ ensurable do
+ desc "The running state of the zone. The valid states directly reflect
+ the states that ``zoneadm`` provides. The states are linear,
+ in that a zone must be ``configured`` then ``installed``, and
+ only then can be ``running``. Note also that ``halt`` is currently
+ used to stop zones."
+
+ @states = {}
+ @parametervalues = []
+
+ def self.alias_state(values)
+ @state_aliases ||= {}
+ values.each do |nick, name|
+ @state_aliases[nick] = name
+ end
+ end
- def self.state_name(name)
- if other = @state_aliases[name]
- other
- else
- name
- end
- end
+ def self.newvalue(name, hash)
+ @parametervalues = [] if @parametervalues.is_a? Hash
- newvalue :absent, :down => :destroy
- newvalue :configured, :up => :configure, :down => :uninstall
- newvalue :installed, :up => :install, :down => :stop
- newvalue :running, :up => :start
+ @parametervalues << name
- alias_state :incomplete => :installed, :ready => :installed, :shutting_down => :running
+ @states[name] = hash
+ hash[:name] = name
+ end
- defaultto :running
+ def self.state_name(name)
+ if other = @state_aliases[name]
+ other
+ else
+ name
+ end
+ end
- def self.state_index(value)
- @parametervalues.index(state_name(value))
- end
+ newvalue :absent, :down => :destroy
+ newvalue :configured, :up => :configure, :down => :uninstall
+ newvalue :installed, :up => :install, :down => :stop
+ newvalue :running, :up => :start
- # Return all of the states between two listed values, exclusive
- # of the first item.
- def self.state_sequence(first, second)
- findex = sindex = nil
- unless findex = @parametervalues.index(state_name(first))
- raise ArgumentError, "'#{first}' is not a valid zone state"
- end
- unless sindex = @parametervalues.index(state_name(second))
- raise ArgumentError, "'#{first}' is not a valid zone state"
- end
- list = nil
-
- # Apparently ranges are unidirectional, so we have to reverse
- # the range op twice.
- if findex > sindex
- list = @parametervalues[sindex..findex].collect do |name|
- @states[name]
- end.reverse
- else
- list = @parametervalues[findex..sindex].collect do |name|
- @states[name]
- end
- end
+ alias_state :incomplete => :installed, :ready => :installed, :shutting_down => :running
- # The first result is the current state, so don't return it.
- list[1..-1]
- end
+ defaultto :running
- def retrieve
- provider.properties[:ensure]
+ def self.state_index(value)
+ @parametervalues.index(state_name(value))
+ end
+
+ # Return all of the states between two listed values, exclusive
+ # of the first item.
+ def self.state_sequence(first, second)
+ findex = sindex = nil
+ unless findex = @parametervalues.index(state_name(first))
+ raise ArgumentError, "'#{first}' is not a valid zone state"
+ end
+ unless sindex = @parametervalues.index(state_name(second))
+ raise ArgumentError, "'#{first}' is not a valid zone state"
+ end
+ list = nil
+
+ # Apparently ranges are unidirectional, so we have to reverse
+ # the range op twice.
+ if findex > sindex
+ list = @parametervalues[sindex..findex].collect do |name|
+ @states[name]
+ end.reverse
+ else
+ list = @parametervalues[findex..sindex].collect do |name|
+ @states[name]
end
+ end
- def sync
- method = nil
- if up?
- direction = :up
- else
- direction = :down
- end
+ # The first result is the current state, so don't return it.
+ list[1..-1]
+ end
- # We need to get the state we're currently in and just call
- # everything between it and us.
- self.class.state_sequence(self.retrieve, self.should).each do |state|
- if method = state[direction]
- warned = false
- while provider.processing?
- unless warned
- info "Waiting for zone to finish processing"
- warned = true
- end
- sleep 1
- end
- provider.send(method)
- else
- raise Puppet::DevError, "Cannot move #{direction} from #{st[:name]}"
- end
- end
+ def retrieve
+ provider.properties[:ensure]
+ end
- ("zone_#{self.should}").intern
+ def sync
+ method = nil
+ if up?
+ direction = :up
+ else
+ direction = :down
+ end
+
+ # We need to get the state we're currently in and just call
+ # everything between it and us.
+ self.class.state_sequence(self.retrieve, self.should).each do |state|
+ if method = state[direction]
+ warned = false
+ while provider.processing?
+ unless warned
+ info "Waiting for zone to finish processing"
+ warned = true
+ end
+ sleep 1
+ end
+ provider.send(method)
+ else
+ raise Puppet::DevError, "Cannot move #{direction} from #{st[:name]}"
end
+ end
- # Are we moving up the property tree?
- def up?
- current_value = self.retrieve
- self.class.state_index(current_value) < self.class.state_index(self.should)
- end
+ ("zone_#{self.should}").intern
end
- newparam(:name) do
- desc "The name of the zone."
-
- isnamevar
+ # Are we moving up the property tree?
+ def up?
+ current_value = self.retrieve
+ self.class.state_index(current_value) < self.class.state_index(self.should)
end
-
- newparam(:id) do
- desc "The numerical ID of the zone. This number is autogenerated
- and cannot be changed."
+ end
+
+ newparam(:name) do
+ desc "The name of the zone."
+
+ isnamevar
+ end
+
+ newparam(:id) do
+ desc "The numerical ID of the zone. This number is autogenerated
+ and cannot be changed."
+ end
+
+ newparam(:clone) do
+ desc "Instead of installing the zone, clone it from another zone.
+ If the zone root resides on a zfs file system, a snapshot will be
+ used to create the clone, is it redisides on ufs, a copy of the zone
+ will be used. The zone you clone from must not be running."
+ end
+
+ newproperty(:ip, :parent => ZoneMultiConfigProperty) do
+ require 'ipaddr'
+
+ desc "The IP address of the zone. IP addresses must be specified
+ with the interface, separated by a colon, e.g.: bge0:192.168.0.1.
+ For multiple interfaces, specify them in an array."
+
+ # Add an interface.
+ def add(str)
+ interface, ip, defrouter = ipsplit(str)
+ cmd = "add net\n"
+ cmd += "set physical=#{interface}\n" if interface
+ cmd += "set address=#{ip}\n" if ip
+ cmd += "set defrouter=#{defrouter}\n" if defrouter
+ #if @resource[:iptype] == :shared
+ cmd += "end\n"
end
- newparam(:clone) do
- desc "Instead of installing the zone, clone it from another zone.
- If the zone root resides on a zfs file system, a snapshot will be
- used to create the clone, is it redisides on ufs, a copy of the zone
- will be used. The zone you clone from must not be running."
+ # Convert a string into the component interface, address and defrouter
+ def ipsplit(str)
+ interface, address, defrouter = str.split(':')
+ return interface, address, defrouter
end
- newproperty(:ip, :parent => ZoneMultiConfigProperty) do
- require 'ipaddr'
-
- desc "The IP address of the zone. IP addresses must be specified
- with the interface, separated by a colon, e.g.: bge0:192.168.0.1.
- For multiple interfaces, specify them in an array."
-
- # Add an interface.
- def add(str)
- interface, ip, defrouter = ipsplit(str)
- cmd = "add net\n"
- cmd += "set physical=#{interface}\n" if interface
- cmd += "set address=#{ip}\n" if ip
- cmd += "set defrouter=#{defrouter}\n" if defrouter
- #if @resource[:iptype] == :shared
- cmd += "end\n"
- end
-
- # Convert a string into the component interface, address and defrouter
- def ipsplit(str)
- interface, address, defrouter = str.split(':')
- return interface, address, defrouter
- end
-
- # Remove an interface.
- def rm(str)
- interface, ip, defrouter = ipsplit(str)
- # Reality seems to disagree with the documentation here; the docs
- # specify that braces are required, but they're apparently only
- # required if you're specifying multiple values.
- if ip
- "remove net address=#{ip}"
- elsif interface
- "remove net interface=#{interface}"
- else
- raise ArgumentError, "can not remove network based on default router"
- end
- end
+ # Remove an interface.
+ def rm(str)
+ interface, ip, defrouter = ipsplit(str)
+ # Reality seems to disagree with the documentation here; the docs
+ # specify that braces are required, but they're apparently only
+ # required if you're specifying multiple values.
+ if ip
+ "remove net address=#{ip}"
+ elsif interface
+ "remove net interface=#{interface}"
+ else
+ raise ArgumentError, "can not remove network based on default router"
+ end
end
+ end
- newproperty(:iptype, :parent => ZoneConfigProperty) do
- desc "The IP stack type of the zone. Can either be 'shared' or 'exclusive'."
+ newproperty(:iptype, :parent => ZoneConfigProperty) do
+ desc "The IP stack type of the zone. Can either be 'shared' or 'exclusive'."
- defaultto :shared
+ defaultto :shared
- newvalue :shared
- newvalue :exclusive
+ newvalue :shared
+ newvalue :exclusive
- def configtext
- "set ip-type=#{self.should}"
- end
+ def configtext
+ "set ip-type=#{self.should}"
end
+ end
- newproperty(:autoboot, :parent => ZoneConfigProperty) do
- desc "Whether the zone should automatically boot."
+ newproperty(:autoboot, :parent => ZoneConfigProperty) do
+ desc "Whether the zone should automatically boot."
- defaultto true
+ defaultto true
- newvalue(:true) {}
- newvalue(:false) {}
+ newvalue(:true) {}
+ newvalue(:false) {}
- def configtext
- "set autoboot=#{self.should}"
- end
+ def configtext
+ "set autoboot=#{self.should}"
end
+ end
- newproperty(:pool, :parent => ZoneConfigProperty) do
- desc "The resource pool for this zone."
+ newproperty(:pool, :parent => ZoneConfigProperty) do
+ desc "The resource pool for this zone."
- def configtext
- "set pool=#{self.should}"
- end
+ def configtext
+ "set pool=#{self.should}"
end
+ end
- newproperty(:shares, :parent => ZoneConfigProperty) do
- desc "Number of FSS CPU shares allocated to the zone."
+ newproperty(:shares, :parent => ZoneConfigProperty) do
+ desc "Number of FSS CPU shares allocated to the zone."
- def configtext
- "add rctl\nset name=zone.cpu-shares\nadd value (priv=privileged,limit=#{self.should},action=none)\nend"
- end
+ def configtext
+ "add rctl\nset name=zone.cpu-shares\nadd value (priv=privileged,limit=#{self.should},action=none)\nend"
end
+ end
- newproperty(:inherit, :parent => ZoneMultiConfigProperty) do
- desc "The list of directories that the zone inherits from the global
- zone. All directories must be fully qualified."
+ newproperty(:inherit, :parent => ZoneMultiConfigProperty) do
+ desc "The list of directories that the zone inherits from the global
+ zone. All directories must be fully qualified."
- validate do |value|
- unless value =~ /^\//
- raise ArgumentError, "Inherited filesystems must be fully qualified"
- end
- end
-
- # Add a directory to our list of inherited directories.
- def add(dir)
- "add inherit-pkg-dir\nset dir=#{dir}\nend"
- end
-
- def rm(dir)
- # Reality seems to disagree with the documentation here; the docs
- # specify that braces are required, but they're apparently only
- # required if you're specifying multiple values.
- "remove inherit-pkg-dir dir=#{dir}"
- end
-
- def should
- @should
- end
- end
-
- # Specify the sysidcfg file. This is pretty hackish, because it's
- # only used to boot the zone the very first time.
- newparam(:sysidcfg) do
- desc %{The text to go into the sysidcfg file when the zone is first
- booted. The best way is to use a template::
-
- # $templatedir/sysidcfg
- system_locale=en_US
- timezone=GMT
- terminal=xterms
- security_policy=NONE
- root_password=<%= password %>
- timeserver=localhost
- name_service=DNS {domain_name=<%= domain %> name_server=<%= nameserver %>}
- network_interface=primary {hostname=<%= realhostname %>
- ip_address=<%= ip %>
- netmask=<%= netmask %>
- protocol_ipv6=no
- default_route=<%= defaultroute %>}
- nfs4_domain=dynamic
-
- And then call that::
-
- zone { myzone:
- ip => "bge0:192.168.0.23",
- sysidcfg => template(sysidcfg),
- path => "/opt/zones/myzone",
- realhostname => "fully.qualified.domain.name"
- }
-
- The sysidcfg only matters on the first booting of the zone,
- so Puppet only checks for it at that time.}
+ validate do |value|
+ unless value =~ /^\//
+ raise ArgumentError, "Inherited filesystems must be fully qualified"
+ end
end
- newparam(:path) do
- desc "The root of the zone's filesystem. Must be a fully qualified
- file name. If you include '%s' in the path, then it will be
- replaced with the zone's name. At this point, you cannot use
- Puppet to move a zone."
-
- validate do |value|
- unless value =~ /^\//
- raise ArgumentError, "The zone base must be fully qualified"
- end
- end
-
- munge do |value|
- if value =~ /%s/
- value % @resource[:name]
- else
- value
- end
- end
+ # Add a directory to our list of inherited directories.
+ def add(dir)
+ "add inherit-pkg-dir\nset dir=#{dir}\nend"
end
- newparam(:create_args) do
- desc "Arguments to the zonecfg create command. This can be used to create branded zones."
+ def rm(dir)
+ # Reality seems to disagree with the documentation here; the docs
+ # specify that braces are required, but they're apparently only
+ # required if you're specifying multiple values.
+ "remove inherit-pkg-dir dir=#{dir}"
end
- newparam(:install_args) do
- desc "Arguments to the zoneadm install command. This can be used to create branded zones."
+ def should
+ @should
end
-
- newparam(:realhostname) do
- desc "The actual hostname of the zone."
+ end
+
+ # Specify the sysidcfg file. This is pretty hackish, because it's
+ # only used to boot the zone the very first time.
+ newparam(:sysidcfg) do
+ desc %{The text to go into the sysidcfg file when the zone is first
+ booted. The best way is to use a template::
+
+ # $templatedir/sysidcfg
+ system_locale=en_US
+ timezone=GMT
+ terminal=xterms
+ security_policy=NONE
+ root_password=<%= password %>
+ timeserver=localhost
+ name_service=DNS {domain_name=<%= domain %> name_server=<%= nameserver %>}
+ network_interface=primary {hostname=<%= realhostname %>
+ ip_address=<%= ip %>
+ netmask=<%= netmask %>
+ protocol_ipv6=no
+ default_route=<%= defaultroute %>}
+ nfs4_domain=dynamic
+
+ And then call that::
+
+ zone { myzone:
+ ip => "bge0:192.168.0.23",
+ sysidcfg => template(sysidcfg),
+ path => "/opt/zones/myzone",
+ realhostname => "fully.qualified.domain.name"
+ }
+
+ The sysidcfg only matters on the first booting of the zone,
+ so Puppet only checks for it at that time.}
+ end
+
+ newparam(:path) do
+ desc "The root of the zone's filesystem. Must be a fully qualified
+ file name. If you include '%s' in the path, then it will be
+ replaced with the zone's name. At this point, you cannot use
+ Puppet to move a zone."
+
+ validate do |value|
+ unless value =~ /^\//
+ raise ArgumentError, "The zone base must be fully qualified"
+ end
end
- # If Puppet is also managing the base dir or its parent dir, list them
- # both as prerequisites.
- autorequire(:file) do
- if @parameters.include? :path
- [@parameters[:path].value, File.dirname(@parameters[:path].value)]
- else
- nil
- end
+ munge do |value|
+ if value =~ /%s/
+ value % @resource[:name]
+ else
+ value
+ end
end
-
- def validate_ip(ip, name)
- IPAddr.new(ip) if ip
- rescue ArgumentError
- self.fail "'#{ip}' is an invalid #{name}"
+ end
+
+ newparam(:create_args) do
+ desc "Arguments to the zonecfg create command. This can be used to create branded zones."
+ end
+
+ newparam(:install_args) do
+ desc "Arguments to the zoneadm install command. This can be used to create branded zones."
+ end
+
+ newparam(:realhostname) do
+ desc "The actual hostname of the zone."
+ end
+
+ # If Puppet is also managing the base dir or its parent dir, list them
+ # both as prerequisites.
+ autorequire(:file) do
+ if @parameters.include? :path
+ [@parameters[:path].value, File.dirname(@parameters[:path].value)]
+ else
+ nil
end
-
- validate do
- value = self[:ip]
- interface, address, defrouter = value.split(':')
- if self[:iptype] == :shared
- if (interface && address && defrouter.nil?) ||
- (interface && address && defrouter)
- validate_ip(address, "IP address")
- validate_ip(defrouter, "default router")
- else
- self.fail "ip must contain interface name and ip address separated by a \":\""
- end
- else
- self.fail "only interface may be specified when using exclusive IP stack: #{value}" unless interface && address.nil? && defrouter.nil?
- end
-
- self.fail "zone path is required" unless self[:path]
+ end
+
+ def validate_ip(ip, name)
+ IPAddr.new(ip) if ip
+ rescue ArgumentError
+ self.fail "'#{ip}' is an invalid #{name}"
+ end
+
+ validate do
+ value = self[:ip]
+ interface, address, defrouter = value.split(':')
+ if self[:iptype] == :shared
+ if (interface && address && defrouter.nil?) ||
+ (interface && address && defrouter)
+ validate_ip(address, "IP address")
+ validate_ip(defrouter, "default router")
+ else
+ self.fail "ip must contain interface name and ip address separated by a \":\""
+ end
+ else
+ self.fail "only interface may be specified when using exclusive IP stack: #{value}" unless interface && address.nil? && defrouter.nil?
end
- def retrieve
- provider.flush
- if hash = provider.properties and hash[:ensure] != :absent
- result = setstatus(hash)
- result
- else
- # Return all properties as absent.
- return properties.inject({}) do | prophash, property|
- prophash[property] = :absent
- prophash
- end
- end
+ self.fail "zone path is required" unless self[:path]
+ end
+
+ def retrieve
+ provider.flush
+ if hash = provider.properties and hash[:ensure] != :absent
+ result = setstatus(hash)
+ result
+ else
+ # Return all properties as absent.
+ return properties.inject({}) do | prophash, property|
+ prophash[property] = :absent
+ prophash
+ end
end
-
- # Take the results of a listing and set everything appropriately.
- def setstatus(hash)
- prophash = {}
- hash.each do |param, value|
- next if param == :name
- case self.class.attrtype(param)
- when :property
- # Only try to provide values for the properties we're managing
- if prop = self.property(param)
- prophash[prop] = value
- end
- else
- self[param] = value
- end
+ end
+
+ # Take the results of a listing and set everything appropriately.
+ def setstatus(hash)
+ prophash = {}
+ hash.each do |param, value|
+ next if param == :name
+ case self.class.attrtype(param)
+ when :property
+ # Only try to provide values for the properties we're managing
+ if prop = self.property(param)
+ prophash[prop] = value
end
- prophash
+ else
+ self[param] = value
+ end
end
+ prophash
+ end
end
diff --git a/lib/puppet/type/zpool.rb b/lib/puppet/type/zpool.rb
index e6dec62..80e6355 100755
--- a/lib/puppet/type/zpool.rb
+++ b/lib/puppet/type/zpool.rb
@@ -1,87 +1,87 @@
module Puppet
- class Property
+ class Property
- class VDev < Property
+ class VDev < Property
- def flatten_and_sort(array)
- array.collect { |a| a.split(' ') }.flatten.sort
- end
+ def flatten_and_sort(array)
+ array.collect { |a| a.split(' ') }.flatten.sort
+ end
- def insync?(is)
- return true unless self.should
+ def insync?(is)
+ return true unless self.should
- return @should == [:absent] if is == :absent
+ return @should == [:absent] if is == :absent
- flatten_and_sort(is) == flatten_and_sort(@should)
- end
- end
+ flatten_and_sort(is) == flatten_and_sort(@should)
+ end
+ end
- class MultiVDev < VDev
- def insync?(is)
- return true unless self.should
+ class MultiVDev < VDev
+ def insync?(is)
+ return true unless self.should
- return @should == [:absent] if is == :absent
+ return @should == [:absent] if is == :absent
- return false unless is.length == @should.length
+ return false unless is.length == @should.length
- is.each_with_index { |list, i| return false unless flatten_and_sort(list) == flatten_and_sort(@should[i]) }
+ is.each_with_index { |list, i| return false unless flatten_and_sort(list) == flatten_and_sort(@should[i]) }
- #if we made it this far we are in sync
- true
- end
- end
+ #if we made it this far we are in sync
+ true
+ end
end
+ end
- newtype(:zpool) do
- @doc = "Manage zpools. Create and delete zpools. The provider WILL NOT SYNC, only report differences.
+ newtype(:zpool) do
+ @doc = "Manage zpools. Create and delete zpools. The provider WILL NOT SYNC, only report differences.
- Supports vdevs with mirrors, raidz, logs and spares."
+ Supports vdevs with mirrors, raidz, logs and spares."
- ensurable
+ ensurable
- newproperty(:disk, :array_matching => :all, :parent => Puppet::Property::VDev) do
- desc "The disk(s) for this pool. Can be an array or space separated string"
- end
+ newproperty(:disk, :array_matching => :all, :parent => Puppet::Property::VDev) do
+ desc "The disk(s) for this pool. Can be an array or space separated string"
+ end
- newproperty(:mirror, :array_matching => :all, :parent => Puppet::Property::MultiVDev) do
- desc "List of all the devices to mirror for this pool. Each mirror should be a space separated string.
- mirror => [\"disk1 disk2\", \"disk3 disk4\"]"
+ newproperty(:mirror, :array_matching => :all, :parent => Puppet::Property::MultiVDev) do
+ desc "List of all the devices to mirror for this pool. Each mirror should be a space separated string.
+ mirror => [\"disk1 disk2\", \"disk3 disk4\"]"
- validate do |value|
- raise ArgumentError, "mirror names must be provided as string separated, not a comma-separated list" if value.include?(",")
- end
- end
+ validate do |value|
+ raise ArgumentError, "mirror names must be provided as string separated, not a comma-separated list" if value.include?(",")
+ end
+ end
- newproperty(:raidz, :array_matching => :all, :parent => Puppet::Property::MultiVDev) do
- desc "List of all the devices to raid for this pool. Should be an array of space separated strings.
- raidz => [\"disk1 disk2\", \"disk3 disk4\"]"
+ newproperty(:raidz, :array_matching => :all, :parent => Puppet::Property::MultiVDev) do
+ desc "List of all the devices to raid for this pool. Should be an array of space separated strings.
+ raidz => [\"disk1 disk2\", \"disk3 disk4\"]"
- validate do |value|
- raise ArgumentError, "raid names must be provided as string separated, not a comma-separated list" if value.include?(",")
- end
- end
+ validate do |value|
+ raise ArgumentError, "raid names must be provided as string separated, not a comma-separated list" if value.include?(",")
+ end
+ end
- newproperty(:spare, :array_matching => :all, :parent => Puppet::Property::VDev) do
- desc "Spare disk(s) for this pool."
- end
+ newproperty(:spare, :array_matching => :all, :parent => Puppet::Property::VDev) do
+ desc "Spare disk(s) for this pool."
+ end
- newproperty(:log, :array_matching => :all, :parent => Puppet::Property::VDev) do
- desc "Log disks for this pool. (doesn't support mirroring yet)"
- end
+ newproperty(:log, :array_matching => :all, :parent => Puppet::Property::VDev) do
+ desc "Log disks for this pool. (doesn't support mirroring yet)"
+ end
- newparam(:pool) do
- desc "The name for this pool."
- isnamevar
- end
+ newparam(:pool) do
+ desc "The name for this pool."
+ isnamevar
+ end
- newparam(:raid_parity) do
- desc "Determines parity when using raidz property."
- end
+ newparam(:raid_parity) do
+ desc "Determines parity when using raidz property."
+ end
- validate do
- has_should = [:disk, :mirror, :raidz].select { |prop| self.should(prop) }
- self.fail "You cannot specify #{has_should.join(" and ")} on this type (only one)" if has_should.length > 1
- end
+ validate do
+ has_should = [:disk, :mirror, :raidz].select { |prop| self.should(prop) }
+ self.fail "You cannot specify #{has_should.join(" and ")} on this type (only one)" if has_should.length > 1
end
+ end
end
diff --git a/lib/puppet/util.rb b/lib/puppet/util.rb
index 221365a..bb41270 100644
--- a/lib/puppet/util.rb
+++ b/lib/puppet/util.rb
@@ -5,441 +5,441 @@ require 'sync'
require 'puppet/external/lock'
module Puppet
- # A command failed to execute.
- require 'puppet/error'
- class ExecutionFailure < Puppet::Error
- end
+ # A command failed to execute.
+ require 'puppet/error'
+ class ExecutionFailure < Puppet::Error
+ end
module Util
- require 'benchmark'
-
- # These are all for backward compatibility -- these are methods that used
- # to be in Puppet::Util but have been moved into external modules.
- require 'puppet/util/posix'
- extend Puppet::Util::POSIX
-
- # Create a hash to store the different sync objects.
- @@syncresources = {}
-
- # Return the sync object associated with a given resource.
- def self.sync(resource)
- @@syncresources[resource] ||= Sync.new
- @@syncresources[resource]
- end
-
- # Change the process to a different user
- def self.chuser
- if group = Puppet[:group]
- group = self.gid(group)
- raise Puppet::Error, "No such group #{Puppet[:group]}" unless group
- unless Puppet::Util::SUIDManager.gid == group
- begin
- Puppet::Util::SUIDManager.egid = group
- Puppet::Util::SUIDManager.gid = group
- rescue => detail
- Puppet.warning "could not change to group #{group.inspect}: #{detail}"
- $stderr.puts "could not change to group #{group.inspect}"
-
- # Don't exit on failed group changes, since it's
- # not fatal
- #exit(74)
- end
- end
+ require 'benchmark'
+
+ # These are all for backward compatibility -- these are methods that used
+ # to be in Puppet::Util but have been moved into external modules.
+ require 'puppet/util/posix'
+ extend Puppet::Util::POSIX
+
+ # Create a hash to store the different sync objects.
+ @@syncresources = {}
+
+ # Return the sync object associated with a given resource.
+ def self.sync(resource)
+ @@syncresources[resource] ||= Sync.new
+ @@syncresources[resource]
+ end
+
+ # Change the process to a different user
+ def self.chuser
+ if group = Puppet[:group]
+ group = self.gid(group)
+ raise Puppet::Error, "No such group #{Puppet[:group]}" unless group
+ unless Puppet::Util::SUIDManager.gid == group
+ begin
+ Puppet::Util::SUIDManager.egid = group
+ Puppet::Util::SUIDManager.gid = group
+ rescue => detail
+ Puppet.warning "could not change to group #{group.inspect}: #{detail}"
+ $stderr.puts "could not change to group #{group.inspect}"
+
+ # Don't exit on failed group changes, since it's
+ # not fatal
+ #exit(74)
end
+ end
+ end
- if user = Puppet[:user]
- user = self.uid(user)
- raise Puppet::Error, "No such user #{Puppet[:user]}" unless user
- unless Puppet::Util::SUIDManager.uid == user
- begin
- Puppet::Util::SUIDManager.initgroups(user)
- Puppet::Util::SUIDManager.uid = user
- Puppet::Util::SUIDManager.euid = user
- rescue => detail
- $stderr.puts "Could not change to user #{user}: #{detail}"
- exit(74)
- end
- end
+ if user = Puppet[:user]
+ user = self.uid(user)
+ raise Puppet::Error, "No such user #{Puppet[:user]}" unless user
+ unless Puppet::Util::SUIDManager.uid == user
+ begin
+ Puppet::Util::SUIDManager.initgroups(user)
+ Puppet::Util::SUIDManager.uid = user
+ Puppet::Util::SUIDManager.euid = user
+ rescue => detail
+ $stderr.puts "Could not change to user #{user}: #{detail}"
+ exit(74)
end
+ end
end
+ end
- # Create instance methods for each of the log levels. This allows
- # the messages to be a little richer. Most classes will be calling this
- # method.
- def self.logmethods(klass, useself = true)
- Puppet::Util::Log.eachlevel { |level|
- klass.send(:define_method, level, proc { |args|
- args = args.join(" ") if args.is_a?(Array)
- if useself
+ # Create instance methods for each of the log levels. This allows
+ # the messages to be a little richer. Most classes will be calling this
+ # method.
+ def self.logmethods(klass, useself = true)
+ Puppet::Util::Log.eachlevel { |level|
+ klass.send(:define_method, level, proc { |args|
+ args = args.join(" ") if args.is_a?(Array)
+ if useself
- Puppet::Util::Log.create(
+ Puppet::Util::Log.create(
- :level => level,
- :source => self,
+ :level => level,
+ :source => self,
- :message => args
- )
- else
-
- Puppet::Util::Log.create(
+ :message => args
+ )
+ else
- :level => level,
+ Puppet::Util::Log.create(
- :message => args
- )
- end
- })
- }
- end
+ :level => level,
- # Proxy a bunch of methods to another object.
- def self.classproxy(klass, objmethod, *methods)
- classobj = class << klass; self; end
- methods.each do |method|
- classobj.send(:define_method, method) do |*args|
- obj = self.send(objmethod)
-
- obj.send(method, *args)
- end
+ :message => args
+ )
end
+ })
+ }
+ end
+
+ # Proxy a bunch of methods to another object.
+ def self.classproxy(klass, objmethod, *methods)
+ classobj = class << klass; self; end
+ methods.each do |method|
+ classobj.send(:define_method, method) do |*args|
+ obj = self.send(objmethod)
+
+ obj.send(method, *args)
+ end
end
+ end
- # Proxy a bunch of methods to another object.
- def self.proxy(klass, objmethod, *methods)
- methods.each do |method|
- klass.send(:define_method, method) do |*args|
- obj = self.send(objmethod)
+ # Proxy a bunch of methods to another object.
+ def self.proxy(klass, objmethod, *methods)
+ methods.each do |method|
+ klass.send(:define_method, method) do |*args|
+ obj = self.send(objmethod)
- obj.send(method, *args)
- end
- end
+ obj.send(method, *args)
+ end
end
-
- # XXX this should all be done using puppet objects, not using
- # normal mkdir
- def self.recmkdir(dir,mode = 0755)
- if FileTest.exist?(dir)
- return false
- else
- tmp = dir.sub(/^\//,'')
- path = [File::SEPARATOR]
- tmp.split(File::SEPARATOR).each { |dir|
- path.push dir
- if ! FileTest.exist?(File.join(path))
- Dir.mkdir(File.join(path), mode)
- elsif FileTest.directory?(File.join(path))
- next
- else FileTest.exist?(File.join(path))
- raise "Cannot create #{dir}: basedir #{File.join(path)} is a file"
- end
- }
- return true
+ end
+
+ # XXX this should all be done using puppet objects, not using
+ # normal mkdir
+ def self.recmkdir(dir,mode = 0755)
+ if FileTest.exist?(dir)
+ return false
+ else
+ tmp = dir.sub(/^\//,'')
+ path = [File::SEPARATOR]
+ tmp.split(File::SEPARATOR).each { |dir|
+ path.push dir
+ if ! FileTest.exist?(File.join(path))
+ Dir.mkdir(File.join(path), mode)
+ elsif FileTest.directory?(File.join(path))
+ next
+ else FileTest.exist?(File.join(path))
+ raise "Cannot create #{dir}: basedir #{File.join(path)} is a file"
end
+ }
+ return true
end
+ end
- # Execute a given chunk of code with a new umask.
- def self.withumask(mask)
- cur = File.umask(mask)
+ # Execute a given chunk of code with a new umask.
+ def self.withumask(mask)
+ cur = File.umask(mask)
- begin
- yield
- ensure
- File.umask(cur)
- end
+ begin
+ yield
+ ensure
+ File.umask(cur)
+ end
+ end
+
+ def benchmark(*args)
+ msg = args.pop
+ level = args.pop
+ object = nil
+
+ if args.empty?
+ if respond_to?(level)
+ object = self
+ else
+ object = Puppet
+ end
+ else
+ object = args.pop
end
- def benchmark(*args)
- msg = args.pop
- level = args.pop
- object = nil
-
- if args.empty?
- if respond_to?(level)
- object = self
- else
- object = Puppet
- end
- else
- object = args.pop
- end
-
- raise Puppet::DevError, "Failed to provide level to :benchmark" unless level
+ raise Puppet::DevError, "Failed to provide level to :benchmark" unless level
- unless level == :none or object.respond_to? level
- raise Puppet::DevError, "Benchmarked object does not respond to #{level}"
- end
-
- # Only benchmark if our log level is high enough
- if level != :none and Puppet::Util::Log.sendlevel?(level)
- result = nil
- seconds = Benchmark.realtime {
- yield
- }
- object.send(level, msg + (" in %0.2f seconds" % seconds))
- return seconds
- else
- yield
- end
+ unless level == :none or object.respond_to? level
+ raise Puppet::DevError, "Benchmarked object does not respond to #{level}"
end
- def binary(bin)
- if bin =~ /^\//
- return bin if FileTest.file? bin and FileTest.executable? bin
- else
- ENV['PATH'].split(File::PATH_SEPARATOR).each do |dir|
- dest=File.join(dir, bin)
- return dest if FileTest.file? dest and FileTest.executable? dest
- end
- end
- nil
+ # Only benchmark if our log level is high enough
+ if level != :none and Puppet::Util::Log.sendlevel?(level)
+ result = nil
+ seconds = Benchmark.realtime {
+ yield
+ }
+ object.send(level, msg + (" in %0.2f seconds" % seconds))
+ return seconds
+ else
+ yield
end
- module_function :binary
-
- # Execute the provided command in a pipe, yielding the pipe object.
- def execpipe(command, failonfail = true)
- if respond_to? :debug
- debug "Executing '#{command}'"
- else
- Puppet.debug "Executing '#{command}'"
- end
-
- output = open("| #{command} 2>&1") do |pipe|
- yield pipe
- end
-
- if failonfail
- unless $CHILD_STATUS == 0
- raise ExecutionFailure, output
- end
- end
-
- output
+ end
+
+ def binary(bin)
+ if bin =~ /^\//
+ return bin if FileTest.file? bin and FileTest.executable? bin
+ else
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |dir|
+ dest=File.join(dir, bin)
+ return dest if FileTest.file? dest and FileTest.executable? dest
+ end
+ end
+ nil
+ end
+ module_function :binary
+
+ # Execute the provided command in a pipe, yielding the pipe object.
+ def execpipe(command, failonfail = true)
+ if respond_to? :debug
+ debug "Executing '#{command}'"
+ else
+ Puppet.debug "Executing '#{command}'"
end
- def execfail(command, exception)
- output = execute(command)
- return output
- rescue ExecutionFailure
- raise exception, output
+ output = open("| #{command} 2>&1") do |pipe|
+ yield pipe
end
- # Execute the desired command, and return the status and output.
- # def execute(command, failonfail = true, uid = nil, gid = nil)
- # :combine sets whether or not to combine stdout/stderr in the output
- # :stdinfile sets a file that can be used for stdin. Passing a string
- # for stdin is not currently supported.
- def execute(command, arguments = {:failonfail => true, :combine => true})
- if command.is_a?(Array)
- command = command.flatten.collect { |i| i.to_s }
- str = command.join(" ")
- else
- # We require an array here so we know where we're incorrectly
- # using a string instead of an array. Once everything is
- # switched to an array, we might relax this requirement.
- raise ArgumentError, "Must pass an array to execute()"
- end
+ if failonfail
+ unless $CHILD_STATUS == 0
+ raise ExecutionFailure, output
+ end
+ end
- if respond_to? :debug
- debug "Executing '#{str}'"
- else
- Puppet.debug "Executing '#{str}'"
- end
+ output
+ end
+
+ def execfail(command, exception)
+ output = execute(command)
+ return output
+ rescue ExecutionFailure
+ raise exception, output
+ end
+
+ # Execute the desired command, and return the status and output.
+ # def execute(command, failonfail = true, uid = nil, gid = nil)
+ # :combine sets whether or not to combine stdout/stderr in the output
+ # :stdinfile sets a file that can be used for stdin. Passing a string
+ # for stdin is not currently supported.
+ def execute(command, arguments = {:failonfail => true, :combine => true})
+ if command.is_a?(Array)
+ command = command.flatten.collect { |i| i.to_s }
+ str = command.join(" ")
+ else
+ # We require an array here so we know where we're incorrectly
+ # using a string instead of an array. Once everything is
+ # switched to an array, we might relax this requirement.
+ raise ArgumentError, "Must pass an array to execute()"
+ end
- arguments[:uid] = Puppet::Util::SUIDManager.convert_xid(:uid, arguments[:uid]) if arguments[:uid]
- arguments[:gid] = Puppet::Util::SUIDManager.convert_xid(:gid, arguments[:gid]) if arguments[:gid]
-
- @@os ||= Facter.value(:operatingsystem)
- output = nil
- child_pid, child_status = nil
- # There are problems with read blocking with badly behaved children
- # read.partialread doesn't seem to capture either stdout or stderr
- # We hack around this using a temporary file
-
- # The idea here is to avoid IO#read whenever possible.
- output_file="/dev/null"
- error_file="/dev/null"
- if ! arguments[:squelch]
- require "tempfile"
- output_file = Tempfile.new("puppet")
- error_file=output_file if arguments[:combine]
- end
+ if respond_to? :debug
+ debug "Executing '#{str}'"
+ else
+ Puppet.debug "Executing '#{str}'"
+ end
- if Puppet.features.posix?
- oldverb = $VERBOSE
- $VERBOSE = nil
- child_pid = Kernel.fork
- $VERBOSE = oldverb
- if child_pid
- # Parent process executes this
- child_status = (Process.waitpid2(child_pid)[1]).to_i >> 8
- else
- # Child process executes this
- Process.setsid
- begin
- if arguments[:stdinfile]
- $stdin.reopen(arguments[:stdinfile])
- else
- $stdin.reopen("/dev/null")
- end
- $stdout.reopen(output_file)
- $stderr.reopen(error_file)
-
- 3.upto(256){|fd| IO::new(fd).close rescue nil}
- if arguments[:gid]
- Process.egid = arguments[:gid]
- Process.gid = arguments[:gid] unless @@os == "Darwin"
- end
- if arguments[:uid]
- Process.euid = arguments[:uid]
- Process.uid = arguments[:uid] unless @@os == "Darwin"
- end
- ENV['LANG'] = ENV['LC_ALL'] = ENV['LC_MESSAGES'] = ENV['LANGUAGE'] = 'C'
- if command.is_a?(Array)
- Kernel.exec(*command)
- else
- Kernel.exec(command)
- end
- rescue => detail
- puts detail.to_s
- exit!(1)
- end
- end
- elsif Puppet.features.microsoft_windows?
- command = command.collect {|part| '"' + part.gsub(/"/, '\\"') + '"'}.join(" ") if command.is_a?(Array)
- Puppet.debug "Creating process '#{command}'"
- processinfo = Process.create( :command_line => command )
- child_status = (Process.waitpid2(child_pid)[1]).to_i >> 8
- end
+ arguments[:uid] = Puppet::Util::SUIDManager.convert_xid(:uid, arguments[:uid]) if arguments[:uid]
+ arguments[:gid] = Puppet::Util::SUIDManager.convert_xid(:gid, arguments[:gid]) if arguments[:gid]
+
+ @@os ||= Facter.value(:operatingsystem)
+ output = nil
+ child_pid, child_status = nil
+ # There are problems with read blocking with badly behaved children
+ # read.partialread doesn't seem to capture either stdout or stderr
+ # We hack around this using a temporary file
+
+ # The idea here is to avoid IO#read whenever possible.
+ output_file="/dev/null"
+ error_file="/dev/null"
+ if ! arguments[:squelch]
+ require "tempfile"
+ output_file = Tempfile.new("puppet")
+ error_file=output_file if arguments[:combine]
+ end
- # read output in if required
- if ! arguments[:squelch]
-
- # Make sure the file's actually there. This is
- # basically a race condition, and is probably a horrible
- # way to handle it, but, well, oh well.
- unless FileTest.exists?(output_file.path)
- Puppet.warning "sleeping"
- sleep 0.5
- unless FileTest.exists?(output_file.path)
- Puppet.warning "sleeping 2"
- sleep 1
- unless FileTest.exists?(output_file.path)
- Puppet.warning "Could not get output"
- output = ""
- end
- end
- end
- unless output
- # We have to explicitly open here, so that it reopens
- # after the child writes.
- output = output_file.open.read
-
- # The 'true' causes the file to get unlinked right away.
- output_file.close(true)
- end
+ if Puppet.features.posix?
+ oldverb = $VERBOSE
+ $VERBOSE = nil
+ child_pid = Kernel.fork
+ $VERBOSE = oldverb
+ if child_pid
+ # Parent process executes this
+ child_status = (Process.waitpid2(child_pid)[1]).to_i >> 8
+ else
+ # Child process executes this
+ Process.setsid
+ begin
+ if arguments[:stdinfile]
+ $stdin.reopen(arguments[:stdinfile])
+ else
+ $stdin.reopen("/dev/null")
+ end
+ $stdout.reopen(output_file)
+ $stderr.reopen(error_file)
+
+ 3.upto(256){|fd| IO::new(fd).close rescue nil}
+ if arguments[:gid]
+ Process.egid = arguments[:gid]
+ Process.gid = arguments[:gid] unless @@os == "Darwin"
+ end
+ if arguments[:uid]
+ Process.euid = arguments[:uid]
+ Process.uid = arguments[:uid] unless @@os == "Darwin"
+ end
+ ENV['LANG'] = ENV['LC_ALL'] = ENV['LC_MESSAGES'] = ENV['LANGUAGE'] = 'C'
+ if command.is_a?(Array)
+ Kernel.exec(*command)
+ else
+ Kernel.exec(command)
+ end
+ rescue => detail
+ puts detail.to_s
+ exit!(1)
end
+ end
+ elsif Puppet.features.microsoft_windows?
+ command = command.collect {|part| '"' + part.gsub(/"/, '\\"') + '"'}.join(" ") if command.is_a?(Array)
+ Puppet.debug "Creating process '#{command}'"
+ processinfo = Process.create( :command_line => command )
+ child_status = (Process.waitpid2(child_pid)[1]).to_i >> 8
+ end
- if arguments[:failonfail]
- unless child_status == 0
- raise ExecutionFailure, "Execution of '#{str}' returned #{child_status}: #{output}"
- end
+ # read output in if required
+ if ! arguments[:squelch]
+
+ # Make sure the file's actually there. This is
+ # basically a race condition, and is probably a horrible
+ # way to handle it, but, well, oh well.
+ unless FileTest.exists?(output_file.path)
+ Puppet.warning "sleeping"
+ sleep 0.5
+ unless FileTest.exists?(output_file.path)
+ Puppet.warning "sleeping 2"
+ sleep 1
+ unless FileTest.exists?(output_file.path)
+ Puppet.warning "Could not get output"
+ output = ""
+ end
end
+ end
+ unless output
+ # We have to explicitly open here, so that it reopens
+ # after the child writes.
+ output = output_file.open.read
+
+ # The 'true' causes the file to get unlinked right away.
+ output_file.close(true)
+ end
+ end
- output
+ if arguments[:failonfail]
+ unless child_status == 0
+ raise ExecutionFailure, "Execution of '#{str}' returned #{child_status}: #{output}"
+ end
end
- module_function :execute
+ output
+ end
- # Create an exclusive lock.
- def threadlock(resource, type = Sync::EX)
- Puppet::Util.sync(resource).synchronize(type) do
- yield
- end
+ module_function :execute
+
+ # Create an exclusive lock.
+ def threadlock(resource, type = Sync::EX)
+ Puppet::Util.sync(resource).synchronize(type) do
+ yield
end
+ end
- # Because some modules provide their own version of this method.
- alias util_execute execute
+ # Because some modules provide their own version of this method.
+ alias util_execute execute
- module_function :benchmark
+ module_function :benchmark
- def memory
- unless defined?(@pmap)
- pmap = %x{which pmap 2>/dev/null}.chomp
- if $CHILD_STATUS != 0 or pmap =~ /^no/
- @pmap = nil
- else
- @pmap = pmap
- end
- end
- if @pmap
- return %x{pmap #{Process.pid}| grep total}.chomp.sub(/^\s*total\s+/, '').sub(/K$/, '').to_i
- else
- 0
- end
+ def memory
+ unless defined?(@pmap)
+ pmap = %x{which pmap 2>/dev/null}.chomp
+ if $CHILD_STATUS != 0 or pmap =~ /^no/
+ @pmap = nil
+ else
+ @pmap = pmap
+ end
end
-
- def symbolize(value)
- if value.respond_to? :intern
- value.intern
- else
- value
- end
+ if @pmap
+ return %x{pmap #{Process.pid}| grep total}.chomp.sub(/^\s*total\s+/, '').sub(/K$/, '').to_i
+ else
+ 0
end
+ end
- def symbolizehash(hash)
- newhash = {}
- hash.each do |name, val|
- if name.is_a? String
- newhash[name.intern] = val
- else
- newhash[name] = val
- end
- end
+ def symbolize(value)
+ if value.respond_to? :intern
+ value.intern
+ else
+ value
end
-
- def symbolizehash!(hash)
- hash.each do |name, val|
- if name.is_a? String
- hash[name.intern] = val
- hash.delete(name)
- end
- end
-
- hash
+ end
+
+ def symbolizehash(hash)
+ newhash = {}
+ hash.each do |name, val|
+ if name.is_a? String
+ newhash[name.intern] = val
+ else
+ newhash[name] = val
+ end
end
- module_function :symbolize, :symbolizehash, :symbolizehash!
-
- # Just benchmark, with no logging.
- def thinmark
- seconds = Benchmark.realtime {
- yield
- }
-
- seconds
+ end
+
+ def symbolizehash!(hash)
+ hash.each do |name, val|
+ if name.is_a? String
+ hash[name.intern] = val
+ hash.delete(name)
+ end
end
- module_function :memory, :thinmark
-
- def secure_open(file,must_be_w,&block)
- raise Puppet::DevError,"secure_open only works with mode 'w'" unless must_be_w == 'w'
- raise Puppet::DevError,"secure_open only requires a block" unless block_given?
- Puppet.warning "#{file} was a symlink to #{File.readlink(file)}" if File.symlink?(file)
- if File.exists?(file) or File.symlink?(file)
- wait = File.symlink?(file) ? 5.0 : 0.1
- File.delete(file)
- sleep wait # give it a chance to reappear, just in case someone is actively trying something.
- end
- begin
- File.open(file,File::CREAT|File::EXCL|File::TRUNC|File::WRONLY,&block)
- rescue Errno::EEXIST
- desc = File.symlink?(file) ? "symlink to #{File.readlink(file)}" : File.stat(file).ftype
- puts "Warning: #{file} was apparently created by another process (as"
- puts "a #{desc}) as soon as it was deleted by this process. Someone may be trying"
- puts "to do something objectionable (such as tricking you into overwriting system"
- puts "files if you are running as root)."
- raise
- end
+ hash
+ end
+ module_function :symbolize, :symbolizehash, :symbolizehash!
+
+ # Just benchmark, with no logging.
+ def thinmark
+ seconds = Benchmark.realtime {
+ yield
+ }
+
+ seconds
+ end
+
+ module_function :memory, :thinmark
+
+ def secure_open(file,must_be_w,&block)
+ raise Puppet::DevError,"secure_open only works with mode 'w'" unless must_be_w == 'w'
+ raise Puppet::DevError,"secure_open only requires a block" unless block_given?
+ Puppet.warning "#{file} was a symlink to #{File.readlink(file)}" if File.symlink?(file)
+ if File.exists?(file) or File.symlink?(file)
+ wait = File.symlink?(file) ? 5.0 : 0.1
+ File.delete(file)
+ sleep wait # give it a chance to reappear, just in case someone is actively trying something.
+ end
+ begin
+ File.open(file,File::CREAT|File::EXCL|File::TRUNC|File::WRONLY,&block)
+ rescue Errno::EEXIST
+ desc = File.symlink?(file) ? "symlink to #{File.readlink(file)}" : File.stat(file).ftype
+ puts "Warning: #{file} was apparently created by another process (as"
+ puts "a #{desc}) as soon as it was deleted by this process. Someone may be trying"
+ puts "to do something objectionable (such as tricking you into overwriting system"
+ puts "files if you are running as root)."
+ raise
end
- module_function :secure_open
+ end
+ module_function :secure_open
end
end
diff --git a/lib/puppet/util/autoload.rb b/lib/puppet/util/autoload.rb
index 21f99e4..c293ac1 100644
--- a/lib/puppet/util/autoload.rb
+++ b/lib/puppet/util/autoload.rb
@@ -3,142 +3,142 @@ require 'puppet/util/cacher'
# Autoload paths, either based on names or all at once.
class Puppet::Util::Autoload
- require 'puppet/util/autoload/file_cache'
+ require 'puppet/util/autoload/file_cache'
- include Puppet::Util
- include Puppet::Util::Warnings
- include Puppet::Util::Cacher
- include Puppet::Util::Autoload::FileCache
+ include Puppet::Util
+ include Puppet::Util::Warnings
+ include Puppet::Util::Cacher
+ include Puppet::Util::Autoload::FileCache
- @autoloaders = {}
- @loaded = []
+ @autoloaders = {}
+ @loaded = []
- class << self
- attr_reader :autoloaders
- private :autoloaders
- end
-
- # Send [], []=, and :clear to the @autloaders hash
- Puppet::Util.classproxy self, :autoloaders, "[]", "[]="
+ class << self
+ attr_reader :autoloaders
+ private :autoloaders
+ end
- # List all loaded files.
- def self.list_loaded
- @loaded.sort { |a,b| a[0] <=> b[0] }.collect do |path, hash|
- "#{path}: #{hash[:file]}"
- end
- end
+ # Send [], []=, and :clear to the @autloaders hash
+ Puppet::Util.classproxy self, :autoloaders, "[]", "[]="
- # Has a given path been loaded? This is used for testing whether a
- # changed file should be loaded or just ignored. This is only
- # used in network/client/master, when downloading plugins, to
- # see if a given plugin is currently loaded and thus should be
- # reloaded.
- def self.loaded?(path)
- path = path.to_s.sub(/\.rb$/, '')
- @loaded.include?(path)
+ # List all loaded files.
+ def self.list_loaded
+ @loaded.sort { |a,b| a[0] <=> b[0] }.collect do |path, hash|
+ "#{path}: #{hash[:file]}"
end
-
- # Save the fact that a given path has been loaded. This is so
- # we can load downloaded plugins if they've already been loaded
- # into memory.
- def self.loaded(file)
- $" << file + ".rb" unless $".include?(file)
- @loaded << file unless @loaded.include?(file)
+ end
+
+ # Has a given path been loaded? This is used for testing whether a
+ # changed file should be loaded or just ignored. This is only
+ # used in network/client/master, when downloading plugins, to
+ # see if a given plugin is currently loaded and thus should be
+ # reloaded.
+ def self.loaded?(path)
+ path = path.to_s.sub(/\.rb$/, '')
+ @loaded.include?(path)
+ end
+
+ # Save the fact that a given path has been loaded. This is so
+ # we can load downloaded plugins if they've already been loaded
+ # into memory.
+ def self.loaded(file)
+ $" << file + ".rb" unless $".include?(file)
+ @loaded << file unless @loaded.include?(file)
+ end
+
+ attr_accessor :object, :path, :objwarn, :wrap
+
+ def initialize(obj, path, options = {})
+ @path = path.to_s
+ raise ArgumentError, "Autoload paths cannot be fully qualified" if @path !~ /^\w/
+ @object = obj
+
+ self.class[obj] = self
+
+ options.each do |opt, value|
+ opt = opt.intern if opt.is_a? String
+ begin
+ self.send(opt.to_s + "=", value)
+ rescue NoMethodError
+ raise ArgumentError, "#{opt} is not a valid option"
+ end
end
- attr_accessor :object, :path, :objwarn, :wrap
-
- def initialize(obj, path, options = {})
- @path = path.to_s
- raise ArgumentError, "Autoload paths cannot be fully qualified" if @path !~ /^\w/
- @object = obj
-
- self.class[obj] = self
-
- options.each do |opt, value|
- opt = opt.intern if opt.is_a? String
- begin
- self.send(opt.to_s + "=", value)
- rescue NoMethodError
- raise ArgumentError, "#{opt} is not a valid option"
- end
- end
-
- @wrap = true unless defined?(@wrap)
+ @wrap = true unless defined?(@wrap)
+ end
+
+ # Load a single plugin by name. We use 'load' here so we can reload a
+ # given plugin.
+ def load(name,env=nil)
+ path = name.to_s + ".rb"
+
+ searchpath(env).each do |dir|
+ file = File.join(dir, path)
+ next unless file_exist?(file)
+ begin
+ Kernel.load file, @wrap
+ name = symbolize(name)
+ loaded name, file
+ return true
+ rescue SystemExit,NoMemoryError
+ raise
+ rescue Exception => detail
+ puts detail.backtrace if Puppet[:trace]
+ raise Puppet::Error, "Could not autoload #{name}: #{detail}"
+ end
end
-
- # Load a single plugin by name. We use 'load' here so we can reload a
- # given plugin.
- def load(name,env=nil)
- path = name.to_s + ".rb"
-
- searchpath(env).each do |dir|
- file = File.join(dir, path)
- next unless file_exist?(file)
- begin
- Kernel.load file, @wrap
- name = symbolize(name)
- loaded name, file
- return true
- rescue SystemExit,NoMemoryError
- raise
- rescue Exception => detail
- puts detail.backtrace if Puppet[:trace]
- raise Puppet::Error, "Could not autoload #{name}: #{detail}"
- end
+ false
+ end
+
+ # Mark the named object as loaded. Note that this supports unqualified
+ # queries, while we store the result as a qualified query in the class.
+ def loaded(name, file)
+ self.class.loaded(File.join(@path, name.to_s))
+ end
+
+ # Indicate whether the specfied plugin has been loaded.
+ def loaded?(name)
+ self.class.loaded?(File.join(@path, name.to_s))
+ end
+
+ # Load all instances that we can. This uses require, rather than load,
+ # so that already-loaded files don't get reloaded unnecessarily.
+ def loadall
+ # Load every instance of everything we can find.
+ searchpath.each do |dir|
+ Dir.glob("#{dir}/*.rb").each do |file|
+ name = File.basename(file).sub(".rb", '').intern
+ next if loaded?(name)
+ begin
+ Kernel.require file
+ loaded(name, file)
+ rescue SystemExit,NoMemoryError
+ raise
+ rescue Exception => detail
+ puts detail.backtrace if Puppet[:trace]
+ raise Puppet::Error, "Could not autoload #{file}: #{detail}"
end
- false
+ end
end
-
- # Mark the named object as loaded. Note that this supports unqualified
- # queries, while we store the result as a qualified query in the class.
- def loaded(name, file)
- self.class.loaded(File.join(@path, name.to_s))
+ end
+
+ # The list of directories to search through for loadable plugins.
+ def searchpath(env=nil)
+ search_directories(env).collect { |d| File.join(d, @path) }.find_all { |d| FileTest.directory?(d) }
+ end
+
+ def module_directories(env=nil)
+ # We have to require this late in the process because otherwise we might have
+ # load order issues.
+ require 'puppet/node/environment'
+ Puppet::Node::Environment.new(env).modulepath.collect do |dir|
+ Dir.entries(dir).reject { |f| f =~ /^\./ }.collect { |f| File.join(dir, f) }
+ end.flatten.collect { |d| [File.join(d, "plugins"), File.join(d, "lib")] }.flatten.find_all do |d|
+ FileTest.directory?(d)
end
+ end
- # Indicate whether the specfied plugin has been loaded.
- def loaded?(name)
- self.class.loaded?(File.join(@path, name.to_s))
- end
-
- # Load all instances that we can. This uses require, rather than load,
- # so that already-loaded files don't get reloaded unnecessarily.
- def loadall
- # Load every instance of everything we can find.
- searchpath.each do |dir|
- Dir.glob("#{dir}/*.rb").each do |file|
- name = File.basename(file).sub(".rb", '').intern
- next if loaded?(name)
- begin
- Kernel.require file
- loaded(name, file)
- rescue SystemExit,NoMemoryError
- raise
- rescue Exception => detail
- puts detail.backtrace if Puppet[:trace]
- raise Puppet::Error, "Could not autoload #{file}: #{detail}"
- end
- end
- end
- end
-
- # The list of directories to search through for loadable plugins.
- def searchpath(env=nil)
- search_directories(env).collect { |d| File.join(d, @path) }.find_all { |d| FileTest.directory?(d) }
- end
-
- def module_directories(env=nil)
- # We have to require this late in the process because otherwise we might have
- # load order issues.
- require 'puppet/node/environment'
- Puppet::Node::Environment.new(env).modulepath.collect do |dir|
- Dir.entries(dir).reject { |f| f =~ /^\./ }.collect { |f| File.join(dir, f) }
- end.flatten.collect { |d| [File.join(d, "plugins"), File.join(d, "lib")] }.flatten.find_all do |d|
- FileTest.directory?(d)
- end
- end
-
- def search_directories(env=nil)
- [module_directories(env), Puppet[:libdir].split(File::PATH_SEPARATOR), $LOAD_PATH].flatten
- end
+ def search_directories(env=nil)
+ [module_directories(env), Puppet[:libdir].split(File::PATH_SEPARATOR), $LOAD_PATH].flatten
+ end
end
diff --git a/lib/puppet/util/autoload/file_cache.rb b/lib/puppet/util/autoload/file_cache.rb
index ce30eed..b555473 100644
--- a/lib/puppet/util/autoload/file_cache.rb
+++ b/lib/puppet/util/autoload/file_cache.rb
@@ -1,92 +1,92 @@
module Puppet::Util::Autoload::FileCache
- @found_files = {}
- @missing_files = {}
- class << self
- attr_reader :found_files, :missing_files
- end
+ @found_files = {}
+ @missing_files = {}
+ class << self
+ attr_reader :found_files, :missing_files
+ end
- # Only used for testing.
- def self.clear
- @found_files.clear
- @missing_files.clear
- end
+ # Only used for testing.
+ def self.clear
+ @found_files.clear
+ @missing_files.clear
+ end
- def found_files
- Puppet::Util::Autoload::FileCache.found_files
- end
+ def found_files
+ Puppet::Util::Autoload::FileCache.found_files
+ end
- def missing_files
- Puppet::Util::Autoload::FileCache.missing_files
- end
+ def missing_files
+ Puppet::Util::Autoload::FileCache.missing_files
+ end
- def directory_exist?(path)
- cache = cached_data?(path, :directory?)
- return cache unless cache.nil?
+ def directory_exist?(path)
+ cache = cached_data?(path, :directory?)
+ return cache unless cache.nil?
- protect(path) do
- stat = File.lstat(path)
- if stat.directory?
- found_file(path, stat)
- return true
- else
- missing_file(path)
- return false
- end
- end
+ protect(path) do
+ stat = File.lstat(path)
+ if stat.directory?
+ found_file(path, stat)
+ return true
+ else
+ missing_file(path)
+ return false
+ end
end
+ end
- def file_exist?(path)
- cache = cached_data?(path)
- return cache unless cache.nil?
+ def file_exist?(path)
+ cache = cached_data?(path)
+ return cache unless cache.nil?
- protect(path) do
- stat = File.lstat(path)
- found_file(path, stat)
- return true
- end
+ protect(path) do
+ stat = File.lstat(path)
+ found_file(path, stat)
+ return true
end
+ end
- def found_file?(path, type = nil)
- if data = found_files[path] and ! data_expired?(data[:time])
- return(type and ! data[:stat].send(type)) ? false : true
- else
- return false
- end
+ def found_file?(path, type = nil)
+ if data = found_files[path] and ! data_expired?(data[:time])
+ return(type and ! data[:stat].send(type)) ? false : true
+ else
+ return false
end
+ end
- def found_file(path, stat)
- found_files[path] = {:stat => stat, :time => Time.now}
- end
+ def found_file(path, stat)
+ found_files[path] = {:stat => stat, :time => Time.now}
+ end
- def missing_file?(path)
- !!(time = missing_files[path] and ! data_expired?(time))
- end
+ def missing_file?(path)
+ !!(time = missing_files[path] and ! data_expired?(time))
+ end
- def missing_file(path)
- missing_files[path] = Time.now
- end
+ def missing_file(path)
+ missing_files[path] = Time.now
+ end
- private
+ private
- def cached_data?(path, type = nil)
- if found_file?(path, type)
- return true
- elsif missing_file?(path)
- return false
- else
- return nil
- end
+ def cached_data?(path, type = nil)
+ if found_file?(path, type)
+ return true
+ elsif missing_file?(path)
+ return false
+ else
+ return nil
end
+ end
- def data_expired?(time)
- Time.now - time > 15
- end
+ def data_expired?(time)
+ Time.now - time > 15
+ end
- def protect(path)
- yield
- rescue => detail
- raise unless detail.class.to_s.include?("Errno")
- missing_file(path)
- return false
- end
+ def protect(path)
+ yield
+ rescue => detail
+ raise unless detail.class.to_s.include?("Errno")
+ missing_file(path)
+ return false
+ end
end
diff --git a/lib/puppet/util/backups.rb b/lib/puppet/util/backups.rb
index 1e05149..c01bdd4 100644
--- a/lib/puppet/util/backups.rb
+++ b/lib/puppet/util/backups.rb
@@ -2,86 +2,86 @@ require 'find'
require 'fileutils'
module Puppet::Util::Backups
- # Deal with backups.
- def perform_backup(file = nil)
- # if they specifically don't want a backup, then just say
- # we're good
- return true unless self[:backup]
+ # Deal with backups.
+ def perform_backup(file = nil)
+ # if they specifically don't want a backup, then just say
+ # we're good
+ return true unless self[:backup]
- # let the path be specified
- file ||= self[:path]
- return true unless FileTest.exists?(file)
+ # let the path be specified
+ file ||= self[:path]
+ return true unless FileTest.exists?(file)
- return(self.bucket ? perform_backup_with_bucket(file) : perform_backup_with_backuplocal(file, self[:backup]))
- end
+ return(self.bucket ? perform_backup_with_bucket(file) : perform_backup_with_backuplocal(file, self[:backup]))
+ end
- private
+ private
- def perform_backup_with_bucket(fileobj)
- file = (fileobj.class == String) ? fileobj : fileobj.name
- case File.stat(file).ftype
- when "directory"
- # we don't need to backup directories when recurse is on
- return true if self[:recurse]
- info "Recursively backing up to filebucket"
- Find.find(self[:path]) { |f| backup_file_with_filebucket(f) if File.file?(f) }
- when "file"; backup_file_with_filebucket(file)
- when "link";
- end
- true
+ def perform_backup_with_bucket(fileobj)
+ file = (fileobj.class == String) ? fileobj : fileobj.name
+ case File.stat(file).ftype
+ when "directory"
+ # we don't need to backup directories when recurse is on
+ return true if self[:recurse]
+ info "Recursively backing up to filebucket"
+ Find.find(self[:path]) { |f| backup_file_with_filebucket(f) if File.file?(f) }
+ when "file"; backup_file_with_filebucket(file)
+ when "link";
end
+ true
+ end
- def perform_backup_with_backuplocal(fileobj, backup)
- file = (fileobj.class == String) ? fileobj : fileobj.name
- newfile = file + backup
+ def perform_backup_with_backuplocal(fileobj, backup)
+ file = (fileobj.class == String) ? fileobj : fileobj.name
+ newfile = file + backup
- remove_backup(newfile)
+ remove_backup(newfile)
- begin
- bfile = file + backup
+ begin
+ bfile = file + backup
- # Ruby 1.8.1 requires the 'preserve' addition, but
- # later versions do not appear to require it.
- # N.B. cp_r works on both files and directories
- FileUtils.cp_r(file, bfile, :preserve => true)
- return true
- rescue => detail
- # since they said they want a backup, let's error out
- # if we couldn't make one
- self.fail "Could not back #{file} up: #{detail.message}"
- end
+ # Ruby 1.8.1 requires the 'preserve' addition, but
+ # later versions do not appear to require it.
+ # N.B. cp_r works on both files and directories
+ FileUtils.cp_r(file, bfile, :preserve => true)
+ return true
+ rescue => detail
+ # since they said they want a backup, let's error out
+ # if we couldn't make one
+ self.fail "Could not back #{file} up: #{detail.message}"
end
+ end
- def remove_backup(newfile)
- if self.class.name == :file and self[:links] != :follow
- method = :lstat
- else
- method = :stat
- end
+ def remove_backup(newfile)
+ if self.class.name == :file and self[:links] != :follow
+ method = :lstat
+ else
+ method = :stat
+ end
- begin
- stat = File.send(method, newfile)
- rescue Errno::ENOENT
- return
- end
+ begin
+ stat = File.send(method, newfile)
+ rescue Errno::ENOENT
+ return
+ end
- if stat.ftype == "directory"
- raise Puppet::Error, "Will not remove directory backup #{newfile}; use a filebucket"
- end
+ if stat.ftype == "directory"
+ raise Puppet::Error, "Will not remove directory backup #{newfile}; use a filebucket"
+ end
- info "Removing old backup of type #{stat.ftype}"
+ info "Removing old backup of type #{stat.ftype}"
- begin
- File.unlink(newfile)
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- self.fail "Could not remove old backup: #{detail}"
- end
+ begin
+ File.unlink(newfile)
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ self.fail "Could not remove old backup: #{detail}"
end
+ end
- def backup_file_with_filebucket(f)
- sum = self.bucket.backup(f)
- self.info "Filebucketed #{f} to #{self.bucket.name} with sum #{sum}"
- return sum
- end
+ def backup_file_with_filebucket(f)
+ sum = self.bucket.backup(f)
+ self.info "Filebucketed #{f} to #{self.bucket.name} with sum #{sum}"
+ return sum
+ end
end
diff --git a/lib/puppet/util/cacher.rb b/lib/puppet/util/cacher.rb
index c87661a..8785c69 100644
--- a/lib/puppet/util/cacher.rb
+++ b/lib/puppet/util/cacher.rb
@@ -1,127 +1,127 @@
module Puppet::Util::Cacher
- module Expirer
- attr_reader :timestamp
+ module Expirer
+ attr_reader :timestamp
- # Cause all cached values to be considered expired.
- def expire
- @timestamp = Time.now
- end
+ # Cause all cached values to be considered expired.
+ def expire
+ @timestamp = Time.now
+ end
+
+ # Is the provided timestamp earlier than our expiration timestamp?
+ # If it is, then the associated value is expired.
+ def dependent_data_expired?(ts)
+ return false unless timestamp
+
+ timestamp > ts
+ end
+ end
+
+ extend Expirer
+
+ # Our module has been extended in a class; we can only add the Instance methods,
+ # which become *class* methods in the class.
+ def self.extended(other)
+ class << other
+ extend ClassMethods
+ include InstanceMethods
+ end
+ end
+
+ # Our module has been included in a class, which means the class gets the class methods
+ # and all of its instances get the instance methods.
+ def self.included(other)
+ other.extend(ClassMethods)
+ other.send(:include, InstanceMethods)
+ end
+
+ # Methods that can get added to a class.
+ module ClassMethods
+ # Provide a means of defining an attribute whose value will be cached.
+ # Must provide a block capable of defining the value if it's flushed..
+ def cached_attr(name, options = {}, &block)
+ init_method = "init_#{name}"
+ define_method(init_method, &block)
+
+ define_method(name) do
+ cached_value(name)
+ end
+
+ define_method(name.to_s + "=") do |value|
+ # Make sure the cache timestamp is set
+ cache_timestamp
+ value_cache[name] = value
+ end
+
+ if ttl = options[:ttl]
+ set_attr_ttl(name, ttl)
+ end
+ end
- # Is the provided timestamp earlier than our expiration timestamp?
- # If it is, then the associated value is expired.
- def dependent_data_expired?(ts)
- return false unless timestamp
+ def attr_ttl(name)
+ return nil unless @attr_ttls
+ @attr_ttls[name]
+ end
+
+ def set_attr_ttl(name, value)
+ @attr_ttls ||= {}
+ @attr_ttls[name] = Integer(value)
+ end
+ end
+
+ # Methods that get added to instances.
+ module InstanceMethods
+ def expire
+ # Only expire if we have an expirer. This is
+ # mostly so that we can comfortably handle cases
+ # like Puppet::Type instances, which use their
+ # catalog as their expirer, and they often don't
+ # have a catalog.
+ if e = expirer
+ e.expire
+ end
+ end
- timestamp > ts
- end
+ def expirer
+ Puppet::Util::Cacher
end
- extend Expirer
+ private
- # Our module has been extended in a class; we can only add the Instance methods,
- # which become *class* methods in the class.
- def self.extended(other)
- class << other
- extend ClassMethods
- include InstanceMethods
- end
+ def cache_timestamp
+ @cache_timestamp ||= Time.now
end
- # Our module has been included in a class, which means the class gets the class methods
- # and all of its instances get the instance methods.
- def self.included(other)
- other.extend(ClassMethods)
- other.send(:include, InstanceMethods)
+ def cached_value(name)
+ # Allow a nil expirer, in which case we regenerate the value every time.
+ if expired_by_expirer?(name)
+ value_cache.clear
+ @cache_timestamp = Time.now
+ elsif expired_by_ttl?(name)
+ value_cache.delete(name)
+ end
+ value_cache[name] = send("init_#{name}") unless value_cache.include?(name)
+ value_cache[name]
end
- # Methods that can get added to a class.
- module ClassMethods
- # Provide a means of defining an attribute whose value will be cached.
- # Must provide a block capable of defining the value if it's flushed..
- def cached_attr(name, options = {}, &block)
- init_method = "init_#{name}"
- define_method(init_method, &block)
-
- define_method(name) do
- cached_value(name)
- end
-
- define_method(name.to_s + "=") do |value|
- # Make sure the cache timestamp is set
- cache_timestamp
- value_cache[name] = value
- end
-
- if ttl = options[:ttl]
- set_attr_ttl(name, ttl)
- end
- end
-
- def attr_ttl(name)
- return nil unless @attr_ttls
- @attr_ttls[name]
- end
-
- def set_attr_ttl(name, value)
- @attr_ttls ||= {}
- @attr_ttls[name] = Integer(value)
- end
+ def expired_by_expirer?(name)
+ if expirer.nil?
+ return true unless self.class.attr_ttl(name)
+ end
+ expirer.dependent_data_expired?(cache_timestamp)
+ end
+
+ def expired_by_ttl?(name)
+ return false unless self.class.respond_to?(:attr_ttl)
+ return false unless ttl = self.class.attr_ttl(name)
+
+ @ttl_timestamps ||= {}
+ @ttl_timestamps[name] ||= Time.now
+
+ (Time.now - @ttl_timestamps[name]) > ttl
end
- # Methods that get added to instances.
- module InstanceMethods
- def expire
- # Only expire if we have an expirer. This is
- # mostly so that we can comfortably handle cases
- # like Puppet::Type instances, which use their
- # catalog as their expirer, and they often don't
- # have a catalog.
- if e = expirer
- e.expire
- end
- end
-
- def expirer
- Puppet::Util::Cacher
- end
-
- private
-
- def cache_timestamp
- @cache_timestamp ||= Time.now
- end
-
- def cached_value(name)
- # Allow a nil expirer, in which case we regenerate the value every time.
- if expired_by_expirer?(name)
- value_cache.clear
- @cache_timestamp = Time.now
- elsif expired_by_ttl?(name)
- value_cache.delete(name)
- end
- value_cache[name] = send("init_#{name}") unless value_cache.include?(name)
- value_cache[name]
- end
-
- def expired_by_expirer?(name)
- if expirer.nil?
- return true unless self.class.attr_ttl(name)
- end
- expirer.dependent_data_expired?(cache_timestamp)
- end
-
- def expired_by_ttl?(name)
- return false unless self.class.respond_to?(:attr_ttl)
- return false unless ttl = self.class.attr_ttl(name)
-
- @ttl_timestamps ||= {}
- @ttl_timestamps[name] ||= Time.now
-
- (Time.now - @ttl_timestamps[name]) > ttl
- end
-
- def value_cache
- @value_cache ||= {}
- end
+ def value_cache
+ @value_cache ||= {}
end
+ end
end
diff --git a/lib/puppet/util/checksums.rb b/lib/puppet/util/checksums.rb
index 102ee98..5aebd83 100644
--- a/lib/puppet/util/checksums.rb
+++ b/lib/puppet/util/checksums.rb
@@ -1,125 +1,125 @@
# A stand-alone module for calculating checksums
# in a generic way.
module Puppet::Util::Checksums
- # Is the provided string a checksum?
- def checksum?(string)
- string =~ /^\{(\w{3,5})\}\S+/
- end
-
- # Strip the checksum type from an existing checksum
- def sumdata(checksum)
- checksum =~ /^\{(\w+)\}(.+)/ ? $2 : nil
- end
-
- # Strip the checksum type from an existing checksum
- def sumtype(checksum)
- checksum =~ /^\{(\w+)\}/ ? $1 : nil
- end
-
- # Calculate a checksum using Digest::MD5.
- def md5(content)
- require 'digest/md5'
- Digest::MD5.hexdigest(content)
- end
-
- # Calculate a checksum of the first 500 chars of the content using Digest::MD5.
- def md5lite(content)
- md5(content[0..511])
- end
-
- # Calculate a checksum of a file's content using Digest::MD5.
- def md5_file(filename, lite = false)
- require 'digest/md5'
-
- digest = Digest::MD5.new
- checksum_file(digest, filename, lite)
- end
-
- # Calculate a checksum of the first 500 chars of a file's content using Digest::MD5.
- def md5lite_file(filename)
- md5_file(filename, true)
- end
-
- def md5_stream(&block)
- require 'digest/md5'
- digest = Digest::MD5.new
- yield digest
- digest.hexdigest
- end
-
- alias :md5lite_stream :md5_stream
-
- # Return the :mtime timestamp of a file.
- def mtime_file(filename)
- File.stat(filename).send(:mtime)
- end
-
- # by definition this doesn't exist
- def mtime_stream
- nil
- end
-
- alias :ctime_stream :mtime_stream
-
- # Calculate a checksum using Digest::SHA1.
- def sha1(content)
- require 'digest/sha1'
- Digest::SHA1.hexdigest(content)
- end
-
- # Calculate a checksum of the first 500 chars of the content using Digest::SHA1.
- def sha1lite(content)
- sha1(content[0..511])
- end
-
- # Calculate a checksum of a file's content using Digest::SHA1.
- def sha1_file(filename, lite = false)
- require 'digest/sha1'
-
- digest = Digest::SHA1.new
- checksum_file(digest, filename, lite)
- end
-
- # Calculate a checksum of the first 500 chars of a file's content using Digest::SHA1.
- def sha1lite_file(filename)
- sha1_file(filename, true)
- end
-
- def sha1_stream
- require 'digest/sha1'
- digest = Digest::SHA1.new
- yield digest
- digest.hexdigest
- end
-
- alias :sha1lite_stream :sha1_stream
-
- # Return the :ctime of a file.
- def ctime_file(filename)
- File.stat(filename).send(:ctime)
- end
-
- # Return a "no checksum"
- def none_file(filename)
- ""
- end
-
- def none_stream
- ""
- end
-
- private
-
- # Perform an incremental checksum on a file.
- def checksum_file(digest, filename, lite = false)
- buffer = lite ? 512 : 4096
- File.open(filename, 'r') do |file|
- while content = file.read(buffer)
- digest << content
- break if lite
- end
- end
-
- digest.hexdigest
- end
+ # Is the provided string a checksum?
+ def checksum?(string)
+ string =~ /^\{(\w{3,5})\}\S+/
+ end
+
+ # Strip the checksum type from an existing checksum
+ def sumdata(checksum)
+ checksum =~ /^\{(\w+)\}(.+)/ ? $2 : nil
+ end
+
+ # Strip the checksum type from an existing checksum
+ def sumtype(checksum)
+ checksum =~ /^\{(\w+)\}/ ? $1 : nil
+ end
+
+ # Calculate a checksum using Digest::MD5.
+ def md5(content)
+ require 'digest/md5'
+ Digest::MD5.hexdigest(content)
+ end
+
+ # Calculate a checksum of the first 500 chars of the content using Digest::MD5.
+ def md5lite(content)
+ md5(content[0..511])
+ end
+
+ # Calculate a checksum of a file's content using Digest::MD5.
+ def md5_file(filename, lite = false)
+ require 'digest/md5'
+
+ digest = Digest::MD5.new
+ checksum_file(digest, filename, lite)
+ end
+
+ # Calculate a checksum of the first 500 chars of a file's content using Digest::MD5.
+ def md5lite_file(filename)
+ md5_file(filename, true)
+ end
+
+ def md5_stream(&block)
+ require 'digest/md5'
+ digest = Digest::MD5.new
+ yield digest
+ digest.hexdigest
+ end
+
+ alias :md5lite_stream :md5_stream
+
+ # Return the :mtime timestamp of a file.
+ def mtime_file(filename)
+ File.stat(filename).send(:mtime)
+ end
+
+ # by definition this doesn't exist
+ def mtime_stream
+ nil
+ end
+
+ alias :ctime_stream :mtime_stream
+
+ # Calculate a checksum using Digest::SHA1.
+ def sha1(content)
+ require 'digest/sha1'
+ Digest::SHA1.hexdigest(content)
+ end
+
+ # Calculate a checksum of the first 500 chars of the content using Digest::SHA1.
+ def sha1lite(content)
+ sha1(content[0..511])
+ end
+
+ # Calculate a checksum of a file's content using Digest::SHA1.
+ def sha1_file(filename, lite = false)
+ require 'digest/sha1'
+
+ digest = Digest::SHA1.new
+ checksum_file(digest, filename, lite)
+ end
+
+ # Calculate a checksum of the first 500 chars of a file's content using Digest::SHA1.
+ def sha1lite_file(filename)
+ sha1_file(filename, true)
+ end
+
+ def sha1_stream
+ require 'digest/sha1'
+ digest = Digest::SHA1.new
+ yield digest
+ digest.hexdigest
+ end
+
+ alias :sha1lite_stream :sha1_stream
+
+ # Return the :ctime of a file.
+ def ctime_file(filename)
+ File.stat(filename).send(:ctime)
+ end
+
+ # Return a "no checksum"
+ def none_file(filename)
+ ""
+ end
+
+ def none_stream
+ ""
+ end
+
+ private
+
+ # Perform an incremental checksum on a file.
+ def checksum_file(digest, filename, lite = false)
+ buffer = lite ? 512 : 4096
+ File.open(filename, 'r') do |file|
+ while content = file.read(buffer)
+ digest << content
+ break if lite
+ end
+ end
+
+ digest.hexdigest
+ end
end
diff --git a/lib/puppet/util/classgen.rb b/lib/puppet/util/classgen.rb
index 92fcc67..ed69c58 100644
--- a/lib/puppet/util/classgen.rb
+++ b/lib/puppet/util/classgen.rb
@@ -1,197 +1,197 @@
module Puppet
- class ConstantAlreadyDefined < Error; end
- class SubclassAlreadyDefined < Error; end
+ class ConstantAlreadyDefined < Error; end
+ class SubclassAlreadyDefined < Error; end
end
module Puppet::Util::ClassGen
- include Puppet::Util::MethodHelper
- include Puppet::Util
-
- # Create a new subclass. Valid options are:
- # * <tt>:array</tt>: An array of existing classes. If specified, the new
- # class is added to this array.
- # * <tt>:attributes</tt>: A hash of attributes to set before the block is
- # evaluated.
- # * <tt>:block</tt>: The block to evaluate in the context of the class.
- # You can also just pass the block normally, but it will still be evaluated
- # with <tt>class_eval</tt>.
- # * <tt>:constant</tt>: What to set the constant as. Defaults to the
- # capitalized name.
- # * <tt>:hash</tt>: A hash of existing classes. If specified, the new
- # class is added to this hash, and it is also used for overwrite tests.
- # * <tt>:overwrite</tt>: Whether to overwrite an existing class.
- # * <tt>:parent</tt>: The parent class for the generated class. Defaults to
- # self.
- # * <tt>:prefix</tt>: The constant prefix. Default to nothing; if specified,
- # the capitalized name is appended and the result is set as the constant.
- def genclass(name, options = {}, &block)
- genthing(name, Class, options, block)
+ include Puppet::Util::MethodHelper
+ include Puppet::Util
+
+ # Create a new subclass. Valid options are:
+ # * <tt>:array</tt>: An array of existing classes. If specified, the new
+ # class is added to this array.
+ # * <tt>:attributes</tt>: A hash of attributes to set before the block is
+ # evaluated.
+ # * <tt>:block</tt>: The block to evaluate in the context of the class.
+ # You can also just pass the block normally, but it will still be evaluated
+ # with <tt>class_eval</tt>.
+ # * <tt>:constant</tt>: What to set the constant as. Defaults to the
+ # capitalized name.
+ # * <tt>:hash</tt>: A hash of existing classes. If specified, the new
+ # class is added to this hash, and it is also used for overwrite tests.
+ # * <tt>:overwrite</tt>: Whether to overwrite an existing class.
+ # * <tt>:parent</tt>: The parent class for the generated class. Defaults to
+ # self.
+ # * <tt>:prefix</tt>: The constant prefix. Default to nothing; if specified,
+ # the capitalized name is appended and the result is set as the constant.
+ def genclass(name, options = {}, &block)
+ genthing(name, Class, options, block)
+ end
+
+ # Create a new module. Valid options are:
+ # * <tt>:array</tt>: An array of existing classes. If specified, the new
+ # class is added to this array.
+ # * <tt>:attributes</tt>: A hash of attributes to set before the block is
+ # evaluated.
+ # * <tt>:block</tt>: The block to evaluate in the context of the class.
+ # You can also just pass the block normally, but it will still be evaluated
+ # with <tt>class_eval</tt>.
+ # * <tt>:constant</tt>: What to set the constant as. Defaults to the
+ # capitalized name.
+ # * <tt>:hash</tt>: A hash of existing classes. If specified, the new
+ # class is added to this hash, and it is also used for overwrite tests.
+ # * <tt>:overwrite</tt>: Whether to overwrite an existing class.
+ # * <tt>:prefix</tt>: The constant prefix. Default to nothing; if specified,
+ # the capitalized name is appended and the result is set as the constant.
+ def genmodule(name, options = {}, &block)
+ genthing(name, Module, options, block)
+ end
+
+ # Remove an existing class
+ def rmclass(name, options)
+ options = symbolize_options(options)
+ const = genconst_string(name, options)
+ retval = false
+ if const_defined?(const)
+ remove_const(const)
+ retval = true
end
- # Create a new module. Valid options are:
- # * <tt>:array</tt>: An array of existing classes. If specified, the new
- # class is added to this array.
- # * <tt>:attributes</tt>: A hash of attributes to set before the block is
- # evaluated.
- # * <tt>:block</tt>: The block to evaluate in the context of the class.
- # You can also just pass the block normally, but it will still be evaluated
- # with <tt>class_eval</tt>.
- # * <tt>:constant</tt>: What to set the constant as. Defaults to the
- # capitalized name.
- # * <tt>:hash</tt>: A hash of existing classes. If specified, the new
- # class is added to this hash, and it is also used for overwrite tests.
- # * <tt>:overwrite</tt>: Whether to overwrite an existing class.
- # * <tt>:prefix</tt>: The constant prefix. Default to nothing; if specified,
- # the capitalized name is appended and the result is set as the constant.
- def genmodule(name, options = {}, &block)
- genthing(name, Module, options, block)
+ if hash = options[:hash] and hash.include? name
+ hash.delete(name)
+ retval = true
end
- # Remove an existing class
- def rmclass(name, options)
- options = symbolize_options(options)
- const = genconst_string(name, options)
- retval = false
- if const_defined?(const)
- remove_const(const)
- retval = true
- end
+ # Let them know whether we did actually delete a subclass.
+ retval
+ end
- if hash = options[:hash] and hash.include? name
- hash.delete(name)
- retval = true
- end
+ private
- # Let them know whether we did actually delete a subclass.
- retval
+ # Generate the constant to create or remove.
+ def genconst_string(name, options)
+ unless const = options[:constant]
+ prefix = options[:prefix] || ""
+ const = prefix + name2const(name)
end
- private
+ const
+ end
- # Generate the constant to create or remove.
- def genconst_string(name, options)
- unless const = options[:constant]
- prefix = options[:prefix] || ""
- const = prefix + name2const(name)
- end
+ # This does the actual work of creating our class or module. It's just a
+ # slightly abstract version of genclass.
+ def genthing(name, type, options, block)
+ options = symbolize_options(options)
- const
- end
+ name = symbolize(name.to_s.downcase)
- # This does the actual work of creating our class or module. It's just a
- # slightly abstract version of genclass.
- def genthing(name, type, options, block)
- options = symbolize_options(options)
-
- name = symbolize(name.to_s.downcase)
-
- if type == Module
- #evalmethod = :module_eval
- evalmethod = :class_eval
- # Create the class, with the correct name.
- klass = Module.new do
- class << self
- attr_reader :name
- end
- @name = name
- end
- else
- options[:parent] ||= self
- evalmethod = :class_eval
- # Create the class, with the correct name.
- klass = Class.new(options[:parent]) do
- @name = name
- end
+ if type == Module
+ #evalmethod = :module_eval
+ evalmethod = :class_eval
+ # Create the class, with the correct name.
+ klass = Module.new do
+ class << self
+ attr_reader :name
end
+ @name = name
+ end
+ else
+ options[:parent] ||= self
+ evalmethod = :class_eval
+ # Create the class, with the correct name.
+ klass = Class.new(options[:parent]) do
+ @name = name
+ end
+ end
- # Create the constant as appropriation.
- handleclassconst(klass, name, options)
+ # Create the constant as appropriation.
+ handleclassconst(klass, name, options)
- # Initialize any necessary variables.
- initclass(klass, options)
+ # Initialize any necessary variables.
+ initclass(klass, options)
- block ||= options[:block]
+ block ||= options[:block]
- # Evaluate the passed block if there is one. This should usually
- # define all of the work.
- klass.send(evalmethod, &block) if block
+ # Evaluate the passed block if there is one. This should usually
+ # define all of the work.
+ klass.send(evalmethod, &block) if block
- klass.postinit if klass.respond_to? :postinit
+ klass.postinit if klass.respond_to? :postinit
- # Store the class in hashes or arrays or whatever.
- storeclass(klass, name, options)
+ # Store the class in hashes or arrays or whatever.
+ storeclass(klass, name, options)
- klass
- end
+ klass
+ end
- # Handle the setting and/or removing of the associated constant.
- def handleclassconst(klass, name, options)
- const = genconst_string(name, options)
-
- if const_defined?(const)
- if options[:overwrite]
- Puppet.info "Redefining #{name} in #{self}"
- remove_const(const)
- else
- raise Puppet::ConstantAlreadyDefined,
- "Class #{const} is already defined in #{self}"
- end
- end
- const_set(const, klass)
+ # Handle the setting and/or removing of the associated constant.
+ def handleclassconst(klass, name, options)
+ const = genconst_string(name, options)
- const
+ if const_defined?(const)
+ if options[:overwrite]
+ Puppet.info "Redefining #{name} in #{self}"
+ remove_const(const)
+ else
+ raise Puppet::ConstantAlreadyDefined,
+ "Class #{const} is already defined in #{self}"
+ end
end
+ const_set(const, klass)
- # Perform the initializations on the class.
- def initclass(klass, options)
- klass.initvars if klass.respond_to? :initvars
-
- if attrs = options[:attributes]
- attrs.each do |param, value|
- method = param.to_s + "="
- klass.send(method, value) if klass.respond_to? method
- end
- end
+ const
+ end
- [:include, :extend].each do |method|
- if set = options[method]
- set = [set] unless set.is_a?(Array)
- set.each do |mod|
- klass.send(method, mod)
- end
- end
- end
+ # Perform the initializations on the class.
+ def initclass(klass, options)
+ klass.initvars if klass.respond_to? :initvars
- klass.preinit if klass.respond_to? :preinit
+ if attrs = options[:attributes]
+ attrs.each do |param, value|
+ method = param.to_s + "="
+ klass.send(method, value) if klass.respond_to? method
+ end
end
- # Convert our name to a constant.
- def name2const(name)
- name.to_s.capitalize
+ [:include, :extend].each do |method|
+ if set = options[method]
+ set = [set] unless set.is_a?(Array)
+ set.each do |mod|
+ klass.send(method, mod)
+ end
+ end
end
- # Store the class in the appropriate places.
- def storeclass(klass, klassname, options)
- if hash = options[:hash]
- if hash.include? klassname and ! options[:overwrite]
- raise Puppet::SubclassAlreadyDefined,
- "Already a generated class named #{klassname}"
- end
+ klass.preinit if klass.respond_to? :preinit
+ end
- hash[klassname] = klass
- end
+ # Convert our name to a constant.
+ def name2const(name)
+ name.to_s.capitalize
+ end
- # If we were told to stick it in a hash, then do so
- if array = options[:array]
- if (klass.respond_to? :name and
- array.find { |c| c.name == klassname } and
- ! options[:overwrite])
- raise Puppet::SubclassAlreadyDefined,
- "Already a generated class named #{klassname}"
- end
+ # Store the class in the appropriate places.
+ def storeclass(klass, klassname, options)
+ if hash = options[:hash]
+ if hash.include? klassname and ! options[:overwrite]
+ raise Puppet::SubclassAlreadyDefined,
+ "Already a generated class named #{klassname}"
+ end
- array << klass
- end
+ hash[klassname] = klass
+ end
+
+ # If we were told to stick it in a hash, then do so
+ if array = options[:array]
+ if (klass.respond_to? :name and
+ array.find { |c| c.name == klassname } and
+ ! options[:overwrite])
+ raise Puppet::SubclassAlreadyDefined,
+ "Already a generated class named #{klassname}"
+ end
+
+ array << klass
end
+ end
end
diff --git a/lib/puppet/util/command_line.rb b/lib/puppet/util/command_line.rb
index 568d52c..2a97ee0 100644
--- a/lib/puppet/util/command_line.rb
+++ b/lib/puppet/util/command_line.rb
@@ -1,95 +1,95 @@
module Puppet
- module Util
- class CommandLine
-
- LegacyName = Hash.new{|h,k| k}.update(
- {
- 'agent' => 'puppetd',
- 'cert' => 'puppetca',
- 'doc' => 'puppetdoc',
- 'filebucket' => 'filebucket',
- 'apply' => 'puppet',
- 'describe' => 'pi',
- 'queue' => 'puppetqd',
- 'resource' => 'ralsh',
- 'kick' => 'puppetrun',
- 'master' => 'puppetmasterd',
+ module Util
+ class CommandLine
+
+ LegacyName = Hash.new{|h,k| k}.update(
+ {
+ 'agent' => 'puppetd',
+ 'cert' => 'puppetca',
+ 'doc' => 'puppetdoc',
+ 'filebucket' => 'filebucket',
+ 'apply' => 'puppet',
+ 'describe' => 'pi',
+ 'queue' => 'puppetqd',
+ 'resource' => 'ralsh',
+ 'kick' => 'puppetrun',
+ 'master' => 'puppetmasterd',
- })
-
- def initialize( zero = $0, argv = ARGV, stdin = STDIN )
- @zero = zero
- @argv = argv.dup
- @stdin = stdin
-
- @subcommand_name, @args = subcommand_and_args( @zero, @argv, @stdin )
- end
-
- attr :subcommand_name
- attr :args
-
- def appdir
- File.join('puppet', 'application')
- end
-
- def available_subcommands
- absolute_appdir = $LOAD_PATH.collect { |x| File.join(x,'puppet','application') }.detect{ |x| File.directory?(x) }
- Dir[File.join(absolute_appdir, '*.rb')].map{|fn| File.basename(fn, '.rb')}
- end
-
- def usage_message
- usage = "Usage: puppet command <space separated arguments>"
- available = "Available commands are: #{available_subcommands.sort.join(', ')}"
- [usage, available].join("\n")
- end
-
- def require_application(application)
- require File.join(appdir, application)
- end
-
- def execute
- if subcommand_name.nil?
- puts usage_message
- elsif available_subcommands.include?(subcommand_name) #subcommand
- require_application subcommand_name
- Puppet::Application.find(subcommand_name).new(self).run
- else
- abort "Error: Unknown command #{subcommand_name}.\n#{usage_message}" unless execute_external_subcommand
- end
- end
-
- def execute_external_subcommand
- external_command = "puppet-#{subcommand_name}"
-
- require 'puppet/util'
- path_to_subcommand = Puppet::Util.binary( external_command )
- return false unless path_to_subcommand
-
- system( path_to_subcommand, *args )
- true
- end
-
- def legacy_executable_name
- LegacyName[ subcommand_name ]
- end
-
- private
-
- def subcommand_and_args( zero, argv, stdin )
- zero = File.basename(zero, '.rb')
-
- if zero == 'puppet'
- case argv.first
- when nil; [ stdin.tty? ? nil : "apply", argv] # ttys get usage info
- when "--help"; [nil, argv] # help should give you usage, not the help for `puppet apply`
- when /^-|\.pp$|\.rb$/; ["apply", argv]
- else [ argv.first, argv[1..-1] ]
- end
- else
- [ zero, argv ]
- end
- end
+ })
+
+ def initialize( zero = $0, argv = ARGV, stdin = STDIN )
+ @zero = zero
+ @argv = argv.dup
+ @stdin = stdin
+
+ @subcommand_name, @args = subcommand_and_args( @zero, @argv, @stdin )
+ end
+
+ attr :subcommand_name
+ attr :args
+
+ def appdir
+ File.join('puppet', 'application')
+ end
+
+ def available_subcommands
+ absolute_appdir = $LOAD_PATH.collect { |x| File.join(x,'puppet','application') }.detect{ |x| File.directory?(x) }
+ Dir[File.join(absolute_appdir, '*.rb')].map{|fn| File.basename(fn, '.rb')}
+ end
+
+ def usage_message
+ usage = "Usage: puppet command <space separated arguments>"
+ available = "Available commands are: #{available_subcommands.sort.join(', ')}"
+ [usage, available].join("\n")
+ end
+
+ def require_application(application)
+ require File.join(appdir, application)
+ end
+
+ def execute
+ if subcommand_name.nil?
+ puts usage_message
+ elsif available_subcommands.include?(subcommand_name) #subcommand
+ require_application subcommand_name
+ Puppet::Application.find(subcommand_name).new(self).run
+ else
+ abort "Error: Unknown command #{subcommand_name}.\n#{usage_message}" unless execute_external_subcommand
+ end
+ end
+
+ def execute_external_subcommand
+ external_command = "puppet-#{subcommand_name}"
+
+ require 'puppet/util'
+ path_to_subcommand = Puppet::Util.binary( external_command )
+ return false unless path_to_subcommand
+
+ system( path_to_subcommand, *args )
+ true
+ end
+ def legacy_executable_name
+ LegacyName[ subcommand_name ]
+ end
+
+ private
+
+ def subcommand_and_args( zero, argv, stdin )
+ zero = File.basename(zero, '.rb')
+
+ if zero == 'puppet'
+ case argv.first
+ when nil; [ stdin.tty? ? nil : "apply", argv] # ttys get usage info
+ when "--help"; [nil, argv] # help should give you usage, not the help for `puppet apply`
+ when /^-|\.pp$|\.rb$/; ["apply", argv]
+ else [ argv.first, argv[1..-1] ]
+ end
+ else
+ [ zero, argv ]
end
+ end
+
end
+ end
end
diff --git a/lib/puppet/util/constant_inflector.rb b/lib/puppet/util/constant_inflector.rb
index 20ad384..8f93e32 100644
--- a/lib/puppet/util/constant_inflector.rb
+++ b/lib/puppet/util/constant_inflector.rb
@@ -4,12 +4,12 @@
# A common module for converting between constants and
# file names.
module Puppet::Util::ConstantInflector
- def file2constant(file)
- # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
- x = file.split("/").collect { |name| name.capitalize }.join("::").gsub(/_+(.)/) { |term| $1.capitalize }
- end
+ def file2constant(file)
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = file.split("/").collect { |name| name.capitalize }.join("::").gsub(/_+(.)/) { |term| $1.capitalize }
+ end
- def constant2file(constant)
- constant.to_s.gsub(/([a-z])([A-Z])/) { |term| $1 + "_#{$2}" }.gsub("::", "/").downcase
- end
+ def constant2file(constant)
+ constant.to_s.gsub(/([a-z])([A-Z])/) { |term| $1 + "_#{$2}" }.gsub("::", "/").downcase
+ end
end
diff --git a/lib/puppet/util/diff.rb b/lib/puppet/util/diff.rb
index 0e5deab..73e1bc0 100644
--- a/lib/puppet/util/diff.rb
+++ b/lib/puppet/util/diff.rb
@@ -1,74 +1,74 @@
# Provide a diff between two strings.
module Puppet::Util::Diff
- include Puppet::Util
- require 'tempfile'
+ include Puppet::Util
+ require 'tempfile'
- def diff(old, new)
- command = [Puppet[:diff]]
- if args = Puppet[:diff_args] and args != ""
- command << args
- end
- command << old << new
- execute(command, :failonfail => false)
+ def diff(old, new)
+ command = [Puppet[:diff]]
+ if args = Puppet[:diff_args] and args != ""
+ command << args
end
+ command << old << new
+ execute(command, :failonfail => false)
+ end
- module_function :diff
-
- # return diff string of two input strings
- # format defaults to unified
- # context defaults to 3 lines
- def lcs_diff(data_old, data_new, format=:unified, context_lines=3)
- unless Puppet.features.diff?
- Puppet.warning "Cannot provide diff without the diff/lcs Ruby library"
- return ""
- end
- data_old = data_old.split(/\n/).map! { |e| e.chomp }
- data_new = data_new.split(/\n/).map! { |e| e.chomp }
+ module_function :diff
- output = ""
+ # return diff string of two input strings
+ # format defaults to unified
+ # context defaults to 3 lines
+ def lcs_diff(data_old, data_new, format=:unified, context_lines=3)
+ unless Puppet.features.diff?
+ Puppet.warning "Cannot provide diff without the diff/lcs Ruby library"
+ return ""
+ end
+ data_old = data_old.split(/\n/).map! { |e| e.chomp }
+ data_new = data_new.split(/\n/).map! { |e| e.chomp }
- diffs = ::Diff::LCS.diff(data_old, data_new)
- return output if diffs.empty?
+ output = ""
- oldhunk = hunk = nil
- file_length_difference = 0
+ diffs = ::Diff::LCS.diff(data_old, data_new)
+ return output if diffs.empty?
- diffs.each do |piece|
- begin
+ oldhunk = hunk = nil
+ file_length_difference = 0
- hunk = ::Diff::LCS::Hunk.new(
- data_old, data_new, piece,
- context_lines,
+ diffs.each do |piece|
+ begin
- file_length_difference)
- file_length_difference = hunk.file_length_difference
- next unless oldhunk
- # Hunks may overlap, which is why we need to be careful when our
- # diff includes lines of context. Otherwise, we might print
- # redundant lines.
- if (context_lines > 0) and hunk.overlaps?(oldhunk)
- hunk.unshift(oldhunk)
- else
- output << oldhunk.diff(format)
- end
- ensure
- oldhunk = hunk
- output << "\n"
- end
- end
+ hunk = ::Diff::LCS::Hunk.new(
+ data_old, data_new, piece,
+ context_lines,
- # Handle the last remaining hunk
- output << oldhunk.diff(format) << "\n"
+ file_length_difference)
+ file_length_difference = hunk.file_length_difference
+ next unless oldhunk
+ # Hunks may overlap, which is why we need to be careful when our
+ # diff includes lines of context. Otherwise, we might print
+ # redundant lines.
+ if (context_lines > 0) and hunk.overlaps?(oldhunk)
+ hunk.unshift(oldhunk)
+ else
+ output << oldhunk.diff(format)
+ end
+ ensure
+ oldhunk = hunk
+ output << "\n"
+ end
end
- def string_file_diff(path, string)
- require 'tempfile'
- tempfile = Tempfile.new("puppet-diffing")
- tempfile.open
- tempfile.print string
- tempfile.close
- print diff(path, tempfile.path)
- tempfile.delete
- end
+ # Handle the last remaining hunk
+ output << oldhunk.diff(format) << "\n"
+ end
+
+ def string_file_diff(path, string)
+ require 'tempfile'
+ tempfile = Tempfile.new("puppet-diffing")
+ tempfile.open
+ tempfile.print string
+ tempfile.close
+ print diff(path, tempfile.path)
+ tempfile.delete
+ end
end
diff --git a/lib/puppet/util/docs.rb b/lib/puppet/util/docs.rb
index dc742d4..efd054d 100644
--- a/lib/puppet/util/docs.rb
+++ b/lib/puppet/util/docs.rb
@@ -1,114 +1,114 @@
# Some simple methods for helping manage automatic documentation generation.
module Puppet::Util::Docs
- # Specify the actual doc string.
- def desc(str)
- @doc = str
+ # Specify the actual doc string.
+ def desc(str)
+ @doc = str
+ end
+
+ # Add a new autodoc block. We have to define these as class methods,
+ # rather than just sticking them in a hash, because otherwise they're
+ # too difficult to do inheritance with.
+ def dochook(name, &block)
+ method = "dochook_#{name}"
+
+ meta_def method, &block
+ end
+
+ attr_writer :doc
+
+ # Generate the full doc string.
+ def doc
+ extra = methods.find_all { |m| m.to_s =~ /^dochook_.+/ }.sort.collect { |m|
+ self.send(m)
+ }.join(" ")
+
+ if @doc
+ @doc + extra
+ else
+ extra
end
-
- # Add a new autodoc block. We have to define these as class methods,
- # rather than just sticking them in a hash, because otherwise they're
- # too difficult to do inheritance with.
- def dochook(name, &block)
- method = "dochook_#{name}"
-
- meta_def method, &block
+ end
+
+ # Build a table
+ def doctable(headers, data)
+ str = "\n\n"
+
+ lengths = []
+ # Figure out the longest field for all columns
+ data.each do |name, values|
+ [name, values].flatten.each_with_index do |value, i|
+ lengths[i] ||= 0
+ lengths[i] = value.to_s.length if value.to_s.length > lengths[i]
+ end
end
- attr_writer :doc
-
- # Generate the full doc string.
- def doc
- extra = methods.find_all { |m| m.to_s =~ /^dochook_.+/ }.sort.collect { |m|
- self.send(m)
- }.join(" ")
-
- if @doc
- @doc + extra
- else
- extra
- end
+ # The headers could also be longest
+ headers.each_with_index do |value, i|
+ lengths[i] = value.to_s.length if value.to_s.length > lengths[i]
end
- # Build a table
- def doctable(headers, data)
- str = "\n\n"
-
- lengths = []
- # Figure out the longest field for all columns
- data.each do |name, values|
- [name, values].flatten.each_with_index do |value, i|
- lengths[i] ||= 0
- lengths[i] = value.to_s.length if value.to_s.length > lengths[i]
- end
- end
-
- # The headers could also be longest
- headers.each_with_index do |value, i|
- lengths[i] = value.to_s.length if value.to_s.length > lengths[i]
- end
-
- # Add the top header row
- str += lengths.collect { |num| "=" * num }.join(" ") + "\n"
+ # Add the top header row
+ str += lengths.collect { |num| "=" * num }.join(" ") + "\n"
- # And the header names
- str += headers.zip(lengths).collect { |value, num| pad(value, num) }.join(" ") + "\n"
+ # And the header names
+ str += headers.zip(lengths).collect { |value, num| pad(value, num) }.join(" ") + "\n"
- # And the second header row
- str += lengths.collect { |num| "=" * num }.join(" ") + "\n"
+ # And the second header row
+ str += lengths.collect { |num| "=" * num }.join(" ") + "\n"
- # Now each data row
- data.sort { |a, b| a[0].to_s <=> b[0].to_s }.each do |name, rows|
- str += [name, rows].flatten.zip(lengths).collect do |value, length|
- pad(value, length)
- end.join(" ") + "\n"
- end
-
- # And the bottom line row
- str += lengths.collect { |num| "=" * num }.join(" ") + "\n"
-
- str + "\n"
- end
-
- attr_reader :nodoc
- def nodoc?
- nodoc
+ # Now each data row
+ data.sort { |a, b| a[0].to_s <=> b[0].to_s }.each do |name, rows|
+ str += [name, rows].flatten.zip(lengths).collect do |value, length|
+ pad(value, length)
+ end.join(" ") + "\n"
end
- # Pad a field with spaces
- def pad(value, length)
- value.to_s + (" " * (length - value.to_s.length))
+ # And the bottom line row
+ str += lengths.collect { |num| "=" * num }.join(" ") + "\n"
+
+ str + "\n"
+ end
+
+ attr_reader :nodoc
+ def nodoc?
+ nodoc
+ end
+
+ # Pad a field with spaces
+ def pad(value, length)
+ value.to_s + (" " * (length - value.to_s.length))
+ end
+
+ # Handle the inline indentation in the docs.
+ def scrub(text)
+ # Stupid markdown
+ #text = text.gsub("<%=", "<%=")
+ # For text with no carriage returns, there's nothing to do.
+ return text if text !~ /\n/
+ indent = nil
+
+ # If we can match an indentation, then just remove that same level of
+ # indent from every line. However, ignore any indentation on the
+ # first line, since that can be inconsistent.
+ text = text.lstrip
+ text.gsub!(/^([\t]+)/) { |s| " "*8*s.length; } # Expand leading tabs
+ # Find first non-empty line after the first line:
+ line2start = (text =~ /(\n?\s*\n)/)
+ line2start += $1.length
+ if (text[line2start..-1] =~ /^([ ]+)\S/) == 0
+ indent = Regexp.quote($1)
+ begin
+ return text.gsub(/^#{indent}/,'')
+ rescue => detail
+ puts detail.backtrace
+ puts detail
+ end
+ else
+ return text
end
- # Handle the inline indentation in the docs.
- def scrub(text)
- # Stupid markdown
- #text = text.gsub("<%=", "<%=")
- # For text with no carriage returns, there's nothing to do.
- return text if text !~ /\n/
- indent = nil
-
- # If we can match an indentation, then just remove that same level of
- # indent from every line. However, ignore any indentation on the
- # first line, since that can be inconsistent.
- text = text.lstrip
- text.gsub!(/^([\t]+)/) { |s| " "*8*s.length; } # Expand leading tabs
- # Find first non-empty line after the first line:
- line2start = (text =~ /(\n?\s*\n)/)
- line2start += $1.length
- if (text[line2start..-1] =~ /^([ ]+)\S/) == 0
- indent = Regexp.quote($1)
- begin
- return text.gsub(/^#{indent}/,'')
- rescue => detail
- puts detail.backtrace
- puts detail
- end
- else
- return text
- end
-
- end
+ end
- module_function :scrub
+ module_function :scrub
end
diff --git a/lib/puppet/util/errors.rb b/lib/puppet/util/errors.rb
index 6fa14d3..5a7a763 100644
--- a/lib/puppet/util/errors.rb
+++ b/lib/puppet/util/errors.rb
@@ -1,63 +1,63 @@
# Some helper methods for throwing errors.
module Puppet::Util::Errors
- # Throw a dev error.
- def devfail(msg)
- self.fail(Puppet::DevError, msg)
+ # Throw a dev error.
+ def devfail(msg)
+ self.fail(Puppet::DevError, msg)
+ end
+
+ # Add line and file info if available and appropriate.
+ def adderrorcontext(error, other = nil)
+ error.line ||= self.line if self.respond_to?(:line) and self.line
+ error.file ||= self.file if self.respond_to?(:file) and self.file
+
+ error.set_backtrace other.backtrace if other and other.respond_to?(:backtrace)
+
+ error
+ end
+
+ def error_context
+ if file and line
+ " at #{file}:#{line}"
+ elsif line
+ " at line #{line}"
+ elsif file
+ " in #{file}"
+ else
+ ""
end
-
- # Add line and file info if available and appropriate.
- def adderrorcontext(error, other = nil)
- error.line ||= self.line if self.respond_to?(:line) and self.line
- error.file ||= self.file if self.respond_to?(:file) and self.file
-
- error.set_backtrace other.backtrace if other and other.respond_to?(:backtrace)
-
- error
+ end
+
+ # Wrap a call in such a way that we always throw the right exception and keep
+ # as much context as possible.
+ def exceptwrap(options = {})
+ options[:type] ||= Puppet::DevError
+ begin
+ return yield
+ rescue Puppet::Error => detail
+ raise adderrorcontext(detail)
+ rescue => detail
+ message = options[:message] || "#{self.class} failed with error #{detail.class}: #{detail}"
+
+ error = options[:type].new(message)
+ # We can't use self.fail here because it always expects strings,
+ # not exceptions.
+ raise adderrorcontext(error, detail)
end
- def error_context
- if file and line
- " at #{file}:#{line}"
- elsif line
- " at line #{line}"
- elsif file
- " in #{file}"
- else
- ""
- end
- end
+ retval
+ end
- # Wrap a call in such a way that we always throw the right exception and keep
- # as much context as possible.
- def exceptwrap(options = {})
- options[:type] ||= Puppet::DevError
- begin
- return yield
- rescue Puppet::Error => detail
- raise adderrorcontext(detail)
- rescue => detail
- message = options[:message] || "#{self.class} failed with error #{detail.class}: #{detail}"
-
- error = options[:type].new(message)
- # We can't use self.fail here because it always expects strings,
- # not exceptions.
- raise adderrorcontext(error, detail)
- end
-
- retval
+ # Throw an error, defaulting to a Puppet::Error.
+ def fail(*args)
+ if args[0].is_a?(Class)
+ type = args.shift
+ else
+ type = Puppet::Error
end
- # Throw an error, defaulting to a Puppet::Error.
- def fail(*args)
- if args[0].is_a?(Class)
- type = args.shift
- else
- type = Puppet::Error
- end
-
- error = adderrorcontext(type.new(args.join(" ")))
+ error = adderrorcontext(type.new(args.join(" ")))
- raise error
- end
+ raise error
+ end
end
diff --git a/lib/puppet/util/execution.rb b/lib/puppet/util/execution.rb
index 7db7137..dd820f8 100644
--- a/lib/puppet/util/execution.rb
+++ b/lib/puppet/util/execution.rb
@@ -1,21 +1,21 @@
module Puppet::Util::Execution
- module_function
+ module_function
- # Run some code with a specific environment. Resets the environment back to
- # what it was at the end of the code.
- def withenv(hash)
- oldvals = {}
- hash.each do |name, val|
- name = name.to_s
- oldvals[name] = ENV[name]
- ENV[name] = val
- end
+ # Run some code with a specific environment. Resets the environment back to
+ # what it was at the end of the code.
+ def withenv(hash)
+ oldvals = {}
+ hash.each do |name, val|
+ name = name.to_s
+ oldvals[name] = ENV[name]
+ ENV[name] = val
+ end
- yield
- ensure
- oldvals.each do |name, val|
- ENV[name] = val
- end
+ yield
+ ensure
+ oldvals.each do |name, val|
+ ENV[name] = val
end
+ end
end
diff --git a/lib/puppet/util/feature.rb b/lib/puppet/util/feature.rb
index 99587a0..2f70410 100644
--- a/lib/puppet/util/feature.rb
+++ b/lib/puppet/util/feature.rb
@@ -2,83 +2,83 @@
# Copyright (c) 2006. All rights reserved.
class Puppet::Util::Feature
- attr_reader :path
+ attr_reader :path
- # Create a new feature test. You have to pass the feature name,
- # and it must be unique. You can either provide a block that
- # will get executed immediately to determine if the feature
- # is present, or you can pass an option to determine it.
- # Currently, the only supported option is 'libs' (must be
- # passed as a symbol), which will make sure that each lib loads
- # successfully.
- def add(name, options = {})
- method = name.to_s + "?"
- raise ArgumentError, "Feature #{name} is already defined" if self.class.respond_to?(method)
+ # Create a new feature test. You have to pass the feature name,
+ # and it must be unique. You can either provide a block that
+ # will get executed immediately to determine if the feature
+ # is present, or you can pass an option to determine it.
+ # Currently, the only supported option is 'libs' (must be
+ # passed as a symbol), which will make sure that each lib loads
+ # successfully.
+ def add(name, options = {})
+ method = name.to_s + "?"
+ raise ArgumentError, "Feature #{name} is already defined" if self.class.respond_to?(method)
- if block_given?
- begin
- result = yield
- rescue Exception => detail
- warn "Failed to load feature test for #{name}: #{detail}"
- result = false
- end
- @results[name] = result
- end
-
- meta_def(method) do
- @results[name] = test(name, options) unless @results.include?(name)
- @results[name]
- end
+ if block_given?
+ begin
+ result = yield
+ rescue Exception => detail
+ warn "Failed to load feature test for #{name}: #{detail}"
+ result = false
+ end
+ @results[name] = result
end
- # Create a new feature collection.
- def initialize(path)
- @path = path
- @results = {}
- @loader = Puppet::Util::Autoload.new(self, @path)
+ meta_def(method) do
+ @results[name] = test(name, options) unless @results.include?(name)
+ @results[name]
end
+ end
- def load
- @loader.loadall
- end
+ # Create a new feature collection.
+ def initialize(path)
+ @path = path
+ @results = {}
+ @loader = Puppet::Util::Autoload.new(self, @path)
+ end
- def method_missing(method, *args)
- return super unless method.to_s =~ /\?$/
+ def load
+ @loader.loadall
+ end
- feature = method.to_s.sub(/\?$/, '')
- @loader.load(feature)
+ def method_missing(method, *args)
+ return super unless method.to_s =~ /\?$/
- respond_to?(method) && self.send(method)
- end
+ feature = method.to_s.sub(/\?$/, '')
+ @loader.load(feature)
- # Actually test whether the feature is present. We only want to test when
- # someone asks for the feature, so we don't unnecessarily load
- # files.
- def test(name, options)
- return true unless ary = options[:libs]
- ary = [ary] unless ary.is_a?(Array)
+ respond_to?(method) && self.send(method)
+ end
- ary.each do |lib|
- return false unless load_library(lib, name)
- end
+ # Actually test whether the feature is present. We only want to test when
+ # someone asks for the feature, so we don't unnecessarily load
+ # files.
+ def test(name, options)
+ return true unless ary = options[:libs]
+ ary = [ary] unless ary.is_a?(Array)
- # We loaded all of the required libraries
- true
+ ary.each do |lib|
+ return false unless load_library(lib, name)
end
- private
+ # We loaded all of the required libraries
+ true
+ end
+
+ private
- def load_library(lib, name)
- raise ArgumentError, "Libraries must be passed as strings not #{lib.class}" unless lib.is_a?(String)
+ def load_library(lib, name)
+ raise ArgumentError, "Libraries must be passed as strings not #{lib.class}" unless lib.is_a?(String)
- begin
- require lib
- rescue SystemExit,NoMemoryError
- raise
- rescue Exception
- Puppet.debug "Failed to load library '#{lib}' for feature '#{name}'"
- return false
- end
- true
+ begin
+ require lib
+ rescue SystemExit,NoMemoryError
+ raise
+ rescue Exception
+ Puppet.debug "Failed to load library '#{lib}' for feature '#{name}'"
+ return false
end
+ true
+ end
end
diff --git a/lib/puppet/util/file_locking.rb b/lib/puppet/util/file_locking.rb
index cfac5ba..8b194ed 100644
--- a/lib/puppet/util/file_locking.rb
+++ b/lib/puppet/util/file_locking.rb
@@ -1,44 +1,44 @@
require 'puppet/util'
module Puppet::Util::FileLocking
- module_function
+ module_function
- # Create a shared lock for reading
- def readlock(file)
- raise ArgumentError, "#{file} is not a file" unless !File.exists?(file) or File.file?(file)
- Puppet::Util.sync(file).synchronize(Sync::SH) do
- File.open(file) { |f|
- f.lock_shared { |lf| yield lf }
- }
- end
+ # Create a shared lock for reading
+ def readlock(file)
+ raise ArgumentError, "#{file} is not a file" unless !File.exists?(file) or File.file?(file)
+ Puppet::Util.sync(file).synchronize(Sync::SH) do
+ File.open(file) { |f|
+ f.lock_shared { |lf| yield lf }
+ }
end
+ end
- # Create an exclusive lock for writing, and do the writing in a
- # tmp file.
- def writelock(file, mode = nil)
- raise Puppet::DevError, "Cannot create #{file}; directory #{File.dirname(file)} does not exist" unless FileTest.directory?(File.dirname(file))
- raise ArgumentError, "#{file} is not a file" unless !File.exists?(file) or File.file?(file)
- tmpfile = file + ".tmp"
+ # Create an exclusive lock for writing, and do the writing in a
+ # tmp file.
+ def writelock(file, mode = nil)
+ raise Puppet::DevError, "Cannot create #{file}; directory #{File.dirname(file)} does not exist" unless FileTest.directory?(File.dirname(file))
+ raise ArgumentError, "#{file} is not a file" unless !File.exists?(file) or File.file?(file)
+ tmpfile = file + ".tmp"
- unless mode
- # It's far more likely that the file will be there than not, so it's
- # better to stat once to check for existence and mode.
- # If we can't stat, it's most likely because the file's not there,
- # but could also be because the directory isn't readable, in which case
- # we won't be able to write anyway.
- begin
- mode = File.stat(file).mode
- rescue
- mode = 0600
- end
- end
+ unless mode
+ # It's far more likely that the file will be there than not, so it's
+ # better to stat once to check for existence and mode.
+ # If we can't stat, it's most likely because the file's not there,
+ # but could also be because the directory isn't readable, in which case
+ # we won't be able to write anyway.
+ begin
+ mode = File.stat(file).mode
+ rescue
+ mode = 0600
+ end
+ end
- Puppet::Util.sync(file).synchronize(Sync::EX) do
- File.open(file, "w", mode) do |rf|
- rf.lock_exclusive do |lrf|
- yield lrf
- end
- end
+ Puppet::Util.sync(file).synchronize(Sync::EX) do
+ File.open(file, "w", mode) do |rf|
+ rf.lock_exclusive do |lrf|
+ yield lrf
end
+ end
end
+ end
end
diff --git a/lib/puppet/util/fileparsing.rb b/lib/puppet/util/fileparsing.rb
index bc35559..5c2a29c 100644
--- a/lib/puppet/util/fileparsing.rb
+++ b/lib/puppet/util/fileparsing.rb
@@ -27,347 +27,347 @@
require 'puppet/util/methodhelper'
module Puppet::Util::FileParsing
- include Puppet::Util
- attr_writer :line_separator, :trailing_separator
-
- class FileRecord
- include Puppet::Util
- include Puppet::Util::MethodHelper
- attr_accessor :absent, :joiner, :rts, :separator, :rollup, :name, :match, :block_eval
-
- attr_reader :fields, :optional, :type
+ include Puppet::Util
+ attr_writer :line_separator, :trailing_separator
- INVALID_FIELDS = [:record_type, :target, :on_disk]
+ class FileRecord
+ include Puppet::Util
+ include Puppet::Util::MethodHelper
+ attr_accessor :absent, :joiner, :rts, :separator, :rollup, :name, :match, :block_eval
- # Customize this so we can do a bit of validation.
- def fields=(fields)
- @fields = fields.collect do |field|
- r = symbolize(field)
- raise ArgumentError.new("Cannot have fields named #{r}") if INVALID_FIELDS.include?(r)
- r
- end
- end
+ attr_reader :fields, :optional, :type
- def initialize(type, options = {}, &block)
- @type = symbolize(type)
- raise ArgumentError, "Invalid record type #{@type}" unless [:record, :text].include?(@type)
-
- set_options(options)
-
- if self.type == :record
- # Now set defaults.
- self.absent ||= ""
- self.separator ||= /\s+/
- self.joiner ||= " "
- self.optional ||= []
- @rollup = true unless defined?(@rollup)
- end
-
- if block_given?
- @block_eval ||= :process
-
- # Allow the developer to specify that a block should be instance-eval'ed.
- if @block_eval == :instance
- instance_eval(&block)
- else
- meta_def(@block_eval, &block)
- end
- end
- end
+ INVALID_FIELDS = [:record_type, :target, :on_disk]
- # Convert a record into a line by joining the fields together appropriately.
- # This is pulled into a separate method so it can be called by the hooks.
- def join(details)
- joinchar = self.joiner
-
- fields.collect { |field|
- # If the field is marked absent, use the appropriate replacement
- if details[field] == :absent or details[field] == [:absent] or details[field].nil?
- if self.optional.include?(field)
- self.absent
- else
- raise ArgumentError, "Field '#{field}' is required"
- end
- else
- details[field].to_s
- end
- }.reject { |c| c.nil?}.join(joinchar)
- end
+ # Customize this so we can do a bit of validation.
+ def fields=(fields)
+ @fields = fields.collect do |field|
+ r = symbolize(field)
+ raise ArgumentError.new("Cannot have fields named #{r}") if INVALID_FIELDS.include?(r)
+ r
+ end
+ end
- # Customize this so we can do a bit of validation.
- def optional=(optional)
- @optional = optional.collect do |field|
- symbolize(field)
- end
- end
+ def initialize(type, options = {}, &block)
+ @type = symbolize(type)
+ raise ArgumentError, "Invalid record type #{@type}" unless [:record, :text].include?(@type)
- # Create a hook that modifies the hash resulting from parsing.
- def post_parse=(block)
- meta_def(:post_parse, &block)
- end
+ set_options(options)
- # Create a hook that modifies the hash just prior to generation.
- def pre_gen=(block)
- meta_def(:pre_gen, &block)
- end
+ if self.type == :record
+ # Now set defaults.
+ self.absent ||= ""
+ self.separator ||= /\s+/
+ self.joiner ||= " "
+ self.optional ||= []
+ @rollup = true unless defined?(@rollup)
+ end
- # Are we a text type?
- def text?
- type == :text
- end
+ if block_given?
+ @block_eval ||= :process
- def to_line=(block)
- meta_def(:to_line, &block)
+ # Allow the developer to specify that a block should be instance-eval'ed.
+ if @block_eval == :instance
+ instance_eval(&block)
+ else
+ meta_def(@block_eval, &block)
end
+ end
end
- # Clear all existing record definitions. Only used for testing.
- def clear_records
- @record_types.clear
- @record_order.clear
- end
-
- def fields(type)
- if record = record_type(type)
- record.fields.dup
+ # Convert a record into a line by joining the fields together appropriately.
+ # This is pulled into a separate method so it can be called by the hooks.
+ def join(details)
+ joinchar = self.joiner
+
+ fields.collect { |field|
+ # If the field is marked absent, use the appropriate replacement
+ if details[field] == :absent or details[field] == [:absent] or details[field].nil?
+ if self.optional.include?(field)
+ self.absent
+ else
+ raise ArgumentError, "Field '#{field}' is required"
+ end
else
- nil
+ details[field].to_s
end
+ }.reject { |c| c.nil?}.join(joinchar)
end
- # Try to match a specific text line.
- def handle_text_line(line, record)
- line =~ record.match ? {:record_type => record.name, :line => line} : nil
+ # Customize this so we can do a bit of validation.
+ def optional=(optional)
+ @optional = optional.collect do |field|
+ symbolize(field)
+ end
end
- # Try to match a record.
- def handle_record_line(line, record)
- ret = nil
- if record.respond_to?(:process)
- if ret = record.send(:process, line.dup)
- unless ret.is_a?(Hash)
- raise Puppet::DevError,
- "Process record type #{record.name} returned non-hash"
- end
- else
- return nil
- end
- elsif regex = record.match
- # In this case, we try to match the whole line and then use the
- # match captures to get our fields.
- if match = regex.match(line)
- fields = []
- ret = {}
- record.fields.zip(match.captures).each do |field, value|
- if value == record.absent
- ret[field] = :absent
- else
- ret[field] = value
- end
- end
- else
- nil
- end
- else
- ret = {}
- sep = record.separator
-
- # String "helpfully" replaces ' ' with /\s+/ in splitting, so we
- # have to work around it.
- if sep == " "
- sep = / /
- end
- line_fields = line.split(sep)
- record.fields.each do |param|
- value = line_fields.shift
- if value and value != record.absent
- ret[param] = value
- else
- ret[param] = :absent
- end
- end
-
- if record.rollup and ! line_fields.empty?
- last_field = record.fields[-1]
- val = ([ret[last_field]] + line_fields).join(record.joiner)
- ret[last_field] = val
- end
- end
-
- if ret
- ret[:record_type] = record.name
- return ret
- else
- return nil
- end
+ # Create a hook that modifies the hash resulting from parsing.
+ def post_parse=(block)
+ meta_def(:post_parse, &block)
end
- def line_separator
- @line_separator ||= "\n"
-
- @line_separator
+ # Create a hook that modifies the hash just prior to generation.
+ def pre_gen=(block)
+ meta_def(:pre_gen, &block)
end
- # Split text into separate lines using the record separator.
- def lines(text)
- # Remove any trailing separators, and then split based on them
- # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
- x = text.sub(/#{self.line_separator}\Q/,'').split(self.line_separator)
+ # Are we a text type?
+ def text?
+ type == :text
end
- # Split a bunch of text into lines and then parse them individually.
- def parse(text)
- count = 1
- lines(text).collect do |line|
- count += 1
- if val = parse_line(line)
- val
- else
- error = Puppet::Error.new("Could not parse line #{line.inspect}")
- error.line = count
- raise error
- end
- end
+ def to_line=(block)
+ meta_def(:to_line, &block)
end
-
- # Handle parsing a single line.
- def parse_line(line)
- raise Puppet::DevError, "No record types defined; cannot parse lines" unless records?
-
- @record_order.each do |record|
- # These are basically either text or record lines.
- method = "handle_#{record.type}_line"
- if respond_to?(method)
- if result = send(method, line, record)
- record.send(:post_parse, result) if record.respond_to?(:post_parse)
- return result
- end
- else
- raise Puppet::DevError,
- "Somehow got invalid line type #{record.type}"
- end
+ end
+
+ # Clear all existing record definitions. Only used for testing.
+ def clear_records
+ @record_types.clear
+ @record_order.clear
+ end
+
+ def fields(type)
+ if record = record_type(type)
+ record.fields.dup
+ else
+ nil
+ end
+ end
+
+ # Try to match a specific text line.
+ def handle_text_line(line, record)
+ line =~ record.match ? {:record_type => record.name, :line => line} : nil
+ end
+
+ # Try to match a record.
+ def handle_record_line(line, record)
+ ret = nil
+ if record.respond_to?(:process)
+ if ret = record.send(:process, line.dup)
+ unless ret.is_a?(Hash)
+ raise Puppet::DevError,
+ "Process record type #{record.name} returned non-hash"
end
-
+ else
+ return nil
+ end
+ elsif regex = record.match
+ # In this case, we try to match the whole line and then use the
+ # match captures to get our fields.
+ if match = regex.match(line)
+ fields = []
+ ret = {}
+ record.fields.zip(match.captures).each do |field, value|
+ if value == record.absent
+ ret[field] = :absent
+ else
+ ret[field] = value
+ end
+ end
+ else
nil
- end
+ end
+ else
+ ret = {}
+ sep = record.separator
+
+ # String "helpfully" replaces ' ' with /\s+/ in splitting, so we
+ # have to work around it.
+ if sep == " "
+ sep = / /
+ end
+ line_fields = line.split(sep)
+ record.fields.each do |param|
+ value = line_fields.shift
+ if value and value != record.absent
+ ret[param] = value
+ else
+ ret[param] = :absent
+ end
+ end
- # Define a new type of record. These lines get split into hashes. Valid
- # options are:
- # * <tt>:absent</tt>: What to use as value within a line, when a field is
- # absent. Note that in the record object, the literal :absent symbol is
- # used, and not this value. Defaults to "".
- # * <tt>:fields</tt>: The list of fields, as an array. By default, all
- # fields are considered required.
- # * <tt>:joiner</tt>: How to join fields together. Defaults to '\t'.
- # * <tt>:optional</tt>: Which fields are optional. If these are missing,
- # you'll just get the 'absent' value instead of an ArgumentError.
- # * <tt>:rts</tt>: Whether to remove trailing whitespace. Defaults to false.
- # If true, whitespace will be removed; if a regex, then whatever matches
- # the regex will be removed.
- # * <tt>:separator</tt>: The record separator. Defaults to /\s+/.
- def record_line(name, options, &block)
- raise ArgumentError, "Must include a list of fields" unless options.include?(:fields)
-
- record = FileRecord.new(:record, options, &block)
- record.name = symbolize(name)
-
- new_line_type(record)
+ if record.rollup and ! line_fields.empty?
+ last_field = record.fields[-1]
+ val = ([ret[last_field]] + line_fields).join(record.joiner)
+ ret[last_field] = val
+ end
end
- # Are there any record types defined?
- def records?
- defined?(@record_types) and ! @record_types.empty?
+ if ret
+ ret[:record_type] = record.name
+ return ret
+ else
+ return nil
end
-
- # Define a new type of text record.
- def text_line(name, options, &block)
- raise ArgumentError, "You must provide a :match regex for text lines" unless options.include?(:match)
-
- record = FileRecord.new(:text, options, &block)
- record.name = symbolize(name)
-
- new_line_type(record)
+ end
+
+ def line_separator
+ @line_separator ||= "\n"
+
+ @line_separator
+ end
+
+ # Split text into separate lines using the record separator.
+ def lines(text)
+ # Remove any trailing separators, and then split based on them
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = text.sub(/#{self.line_separator}\Q/,'').split(self.line_separator)
+ end
+
+ # Split a bunch of text into lines and then parse them individually.
+ def parse(text)
+ count = 1
+ lines(text).collect do |line|
+ count += 1
+ if val = parse_line(line)
+ val
+ else
+ error = Puppet::Error.new("Could not parse line #{line.inspect}")
+ error.line = count
+ raise error
+ end
+ end
+ end
+
+ # Handle parsing a single line.
+ def parse_line(line)
+ raise Puppet::DevError, "No record types defined; cannot parse lines" unless records?
+
+ @record_order.each do |record|
+ # These are basically either text or record lines.
+ method = "handle_#{record.type}_line"
+ if respond_to?(method)
+ if result = send(method, line, record)
+ record.send(:post_parse, result) if record.respond_to?(:post_parse)
+ return result
+ end
+ else
+ raise Puppet::DevError,
+ "Somehow got invalid line type #{record.type}"
+ end
end
- # Generate a file from a bunch of hash records.
- def to_file(records)
- text = records.collect { |record| to_line(record) }.join(line_separator)
-
- text += line_separator if trailing_separator
+ nil
+ end
+
+ # Define a new type of record. These lines get split into hashes. Valid
+ # options are:
+ # * <tt>:absent</tt>: What to use as value within a line, when a field is
+ # absent. Note that in the record object, the literal :absent symbol is
+ # used, and not this value. Defaults to "".
+ # * <tt>:fields</tt>: The list of fields, as an array. By default, all
+ # fields are considered required.
+ # * <tt>:joiner</tt>: How to join fields together. Defaults to '\t'.
+ # * <tt>:optional</tt>: Which fields are optional. If these are missing,
+ # you'll just get the 'absent' value instead of an ArgumentError.
+ # * <tt>:rts</tt>: Whether to remove trailing whitespace. Defaults to false.
+ # If true, whitespace will be removed; if a regex, then whatever matches
+ # the regex will be removed.
+ # * <tt>:separator</tt>: The record separator. Defaults to /\s+/.
+ def record_line(name, options, &block)
+ raise ArgumentError, "Must include a list of fields" unless options.include?(:fields)
+
+ record = FileRecord.new(:record, options, &block)
+ record.name = symbolize(name)
+
+ new_line_type(record)
+ end
+
+ # Are there any record types defined?
+ def records?
+ defined?(@record_types) and ! @record_types.empty?
+ end
+
+ # Define a new type of text record.
+ def text_line(name, options, &block)
+ raise ArgumentError, "You must provide a :match regex for text lines" unless options.include?(:match)
+
+ record = FileRecord.new(:text, options, &block)
+ record.name = symbolize(name)
+
+ new_line_type(record)
+ end
+
+ # Generate a file from a bunch of hash records.
+ def to_file(records)
+ text = records.collect { |record| to_line(record) }.join(line_separator)
+
+ text += line_separator if trailing_separator
+
+ text
+ end
+
+ # Convert our parsed record into a text record.
+ def to_line(details)
+ unless record = record_type(details[:record_type])
+ raise ArgumentError, "Invalid record type #{details[:record_type].inspect}"
+ end
- text
+ if record.respond_to?(:pre_gen)
+ details = details.dup
+ record.send(:pre_gen, details)
end
- # Convert our parsed record into a text record.
- def to_line(details)
- unless record = record_type(details[:record_type])
- raise ArgumentError, "Invalid record type #{details[:record_type].inspect}"
- end
+ case record.type
+ when :text; return details[:line]
+ else
+ return record.to_line(details) if record.respond_to?(:to_line)
- if record.respond_to?(:pre_gen)
- details = details.dup
- record.send(:pre_gen, details)
- end
+ line = record.join(details)
- case record.type
- when :text; return details[:line]
- else
- return record.to_line(details) if record.respond_to?(:to_line)
-
- line = record.join(details)
-
- if regex = record.rts
- # If they say true, then use whitespace; else, use their regex.
- if regex == true
- regex = /\s+$/
- end
- return line.sub(regex,'')
- else
- return line
- end
+ if regex = record.rts
+ # If they say true, then use whitespace; else, use their regex.
+ if regex == true
+ regex = /\s+$/
end
+ return line.sub(regex,'')
+ else
+ return line
+ end
end
-
- # Whether to add a trailing separator to the file. Defaults to true
- def trailing_separator
- if defined?(@trailing_separator)
- return @trailing_separator
- else
- return true
- end
+ end
+
+ # Whether to add a trailing separator to the file. Defaults to true
+ def trailing_separator
+ if defined?(@trailing_separator)
+ return @trailing_separator
+ else
+ return true
end
-
- def valid_attr?(type, attr)
- type = symbolize(type)
- if record = record_type(type) and record.fields.include?(symbolize(attr))
- return true
- else
- if symbolize(attr) == :ensure
- return true
- else
- false
- end
- end
+ end
+
+ def valid_attr?(type, attr)
+ type = symbolize(type)
+ if record = record_type(type) and record.fields.include?(symbolize(attr))
+ return true
+ else
+ if symbolize(attr) == :ensure
+ return true
+ else
+ false
+ end
end
+ end
- private
+ private
- # Define a new type of record.
- def new_line_type(record)
- @record_types ||= {}
- @record_order ||= []
+ # Define a new type of record.
+ def new_line_type(record)
+ @record_types ||= {}
+ @record_order ||= []
- raise ArgumentError, "Line type #{record.name} is already defined" if @record_types.include?(record.name)
+ raise ArgumentError, "Line type #{record.name} is already defined" if @record_types.include?(record.name)
- @record_types[record.name] = record
- @record_order << record
+ @record_types[record.name] = record
+ @record_order << record
- record
- end
+ record
+ end
- # Retrieve the record object.
- def record_type(type)
- @record_types[symbolize(type)]
- end
+ # Retrieve the record object.
+ def record_type(type)
+ @record_types[symbolize(type)]
+ end
end
diff --git a/lib/puppet/util/filetype.rb b/lib/puppet/util/filetype.rb
index bacc7d2..fdc6ccd 100755
--- a/lib/puppet/util/filetype.rb
+++ b/lib/puppet/util/filetype.rb
@@ -5,279 +5,279 @@ require 'puppet/util/selinux'
require 'fileutils'
class Puppet::Util::FileType
- attr_accessor :loaded, :path, :synced
+ attr_accessor :loaded, :path, :synced
- include Puppet::Util::SELinux
+ include Puppet::Util::SELinux
- class << self
- attr_accessor :name
- include Puppet::Util::ClassGen
- end
+ class << self
+ attr_accessor :name
+ include Puppet::Util::ClassGen
+ end
- # Create a new filetype.
- def self.newfiletype(name, &block)
- @filetypes ||= {}
+ # Create a new filetype.
+ def self.newfiletype(name, &block)
+ @filetypes ||= {}
- klass = genclass(
- name,
- :block => block,
- :prefix => "FileType",
+ klass = genclass(
+ name,
+ :block => block,
+ :prefix => "FileType",
- :hash => @filetypes
- )
-
- # Rename the read and write methods, so that we're sure they
- # maintain the stats.
- klass.class_eval do
- # Rename the read method
- define_method(:real_read, instance_method(:read))
- define_method(:read) do
- begin
- val = real_read
- @loaded = Time.now
- if val
- return val.gsub(/# HEADER.*\n/,'')
- else
- return ""
- end
- rescue Puppet::Error => detail
- raise
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- raise Puppet::Error, "#{self.class} could not read #{@path}: #{detail}"
- end
- end
-
- # And then the write method
- define_method(:real_write, instance_method(:write))
- define_method(:write) do |text|
- begin
- val = real_write(text)
- @synced = Time.now
- return val
- rescue Puppet::Error => detail
- raise
- rescue => detail
- puts detail.backtrace if Puppet[:debug]
- raise Puppet::Error, "#{self.class} could not write #{@path}: #{detail}"
- end
- end
+ :hash => @filetypes
+ )
+
+ # Rename the read and write methods, so that we're sure they
+ # maintain the stats.
+ klass.class_eval do
+ # Rename the read method
+ define_method(:real_read, instance_method(:read))
+ define_method(:read) do
+ begin
+ val = real_read
+ @loaded = Time.now
+ if val
+ return val.gsub(/# HEADER.*\n/,'')
+ else
+ return ""
+ end
+ rescue Puppet::Error => detail
+ raise
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ raise Puppet::Error, "#{self.class} could not read #{@path}: #{detail}"
+ end
+ end
+
+ # And then the write method
+ define_method(:real_write, instance_method(:write))
+ define_method(:write) do |text|
+ begin
+ val = real_write(text)
+ @synced = Time.now
+ return val
+ rescue Puppet::Error => detail
+ raise
+ rescue => detail
+ puts detail.backtrace if Puppet[:debug]
+ raise Puppet::Error, "#{self.class} could not write #{@path}: #{detail}"
end
+ end
end
-
- def self.filetype(type)
- @filetypes[type]
+ end
+
+ def self.filetype(type)
+ @filetypes[type]
+ end
+
+ # Pick or create a filebucket to use.
+ def bucket
+ @bucket ||= Puppet::Type.type(:filebucket).mkdefaultbucket.bucket
+ end
+
+ def initialize(path)
+ raise ArgumentError.new("Path is nil") if path.nil?
+ @path = path
+ end
+
+ # Operate on plain files.
+ newfiletype(:flat) do
+ # Back the file up before replacing it.
+ def backup
+ bucket.backup(@path) if File.exists?(@path)
end
- # Pick or create a filebucket to use.
- def bucket
- @bucket ||= Puppet::Type.type(:filebucket).mkdefaultbucket.bucket
+ # Read the file.
+ def read
+ if File.exist?(@path)
+ File.read(@path)
+ else
+ return nil
+ end
end
- def initialize(path)
- raise ArgumentError.new("Path is nil") if path.nil?
- @path = path
+ # Remove the file.
+ def remove
+ File.unlink(@path) if File.exist?(@path)
end
- # Operate on plain files.
- newfiletype(:flat) do
- # Back the file up before replacing it.
- def backup
- bucket.backup(@path) if File.exists?(@path)
- end
-
- # Read the file.
- def read
- if File.exist?(@path)
- File.read(@path)
- else
- return nil
- end
- end
-
- # Remove the file.
- def remove
- File.unlink(@path) if File.exist?(@path)
- end
-
- # Overwrite the file.
- def write(text)
- require "tempfile"
- tf = Tempfile.new("puppet")
- tf.print text; tf.flush
- FileUtils.cp(tf.path, @path)
- tf.close
- # If SELinux is present, we need to ensure the file has its expected context
- set_selinux_default_context(@path)
- end
+ # Overwrite the file.
+ def write(text)
+ require "tempfile"
+ tf = Tempfile.new("puppet")
+ tf.print text; tf.flush
+ FileUtils.cp(tf.path, @path)
+ tf.close
+ # If SELinux is present, we need to ensure the file has its expected context
+ set_selinux_default_context(@path)
end
+ end
- # Operate on plain files.
- newfiletype(:ram) do
- @@tabs = {}
+ # Operate on plain files.
+ newfiletype(:ram) do
+ @@tabs = {}
- def self.clear
- @@tabs.clear
- end
-
- def initialize(path)
- super
- @@tabs[@path] ||= ""
- end
-
- # Read the file.
- def read
- Puppet.info "Reading #{@path} from RAM"
- @@tabs[@path]
- end
+ def self.clear
+ @@tabs.clear
+ end
- # Remove the file.
- def remove
- Puppet.info "Removing #{@path} from RAM"
- @@tabs[@path] = ""
- end
+ def initialize(path)
+ super
+ @@tabs[@path] ||= ""
+ end
- # Overwrite the file.
- def write(text)
- Puppet.info "Writing #{@path} to RAM"
- @@tabs[@path] = text
- end
+ # Read the file.
+ def read
+ Puppet.info "Reading #{@path} from RAM"
+ @@tabs[@path]
end
- # Handle Linux-style cron tabs.
- newfiletype(:crontab) do
- def initialize(user)
- self.path = user
- end
+ # Remove the file.
+ def remove
+ Puppet.info "Removing #{@path} from RAM"
+ @@tabs[@path] = ""
+ end
- def path=(user)
- begin
- @uid = Puppet::Util.uid(user)
- rescue Puppet::Error => detail
- raise Puppet::Error, "Could not retrieve user #{user}"
- end
+ # Overwrite the file.
+ def write(text)
+ Puppet.info "Writing #{@path} to RAM"
+ @@tabs[@path] = text
+ end
+ end
- # XXX We have to have the user name, not the uid, because some
- # systems *cough*linux*cough* require it that way
- @path = user
- end
+ # Handle Linux-style cron tabs.
+ newfiletype(:crontab) do
+ def initialize(user)
+ self.path = user
+ end
- # Read a specific @path's cron tab.
- def read
- %x{#{cmdbase} -l 2>/dev/null}
- end
+ def path=(user)
+ begin
+ @uid = Puppet::Util.uid(user)
+ rescue Puppet::Error => detail
+ raise Puppet::Error, "Could not retrieve user #{user}"
+ end
- # Remove a specific @path's cron tab.
- def remove
- if %w{Darwin FreeBSD}.include?(Facter.value("operatingsystem"))
- %x{/bin/echo yes | #{cmdbase} -r 2>/dev/null}
- else
- %x{#{cmdbase} -r 2>/dev/null}
- end
- end
+ # XXX We have to have the user name, not the uid, because some
+ # systems *cough*linux*cough* require it that way
+ @path = user
+ end
- # Overwrite a specific @path's cron tab; must be passed the @path name
- # and the text with which to create the cron tab.
- def write(text)
- IO.popen("#{cmdbase()} -", "w") { |p|
- p.print text
- }
- end
+ # Read a specific @path's cron tab.
+ def read
+ %x{#{cmdbase} -l 2>/dev/null}
+ end
- private
-
- # Only add the -u flag when the @path is different. Fedora apparently
- # does not think I should be allowed to set the @path to my own user name
- def cmdbase
- cmd = nil
- if @uid == Puppet::Util::SUIDManager.uid || Facter.value(:operatingsystem) == "HP-UX"
- return "crontab"
- else
- return "crontab -u #{@path}"
- end
- end
+ # Remove a specific @path's cron tab.
+ def remove
+ if %w{Darwin FreeBSD}.include?(Facter.value("operatingsystem"))
+ %x{/bin/echo yes | #{cmdbase} -r 2>/dev/null}
+ else
+ %x{#{cmdbase} -r 2>/dev/null}
+ end
end
- # SunOS has completely different cron commands; this class implements
- # its versions.
- newfiletype(:suntab) do
- # Read a specific @path's cron tab.
- def read
- output = Puppet::Util.execute(%w{crontab -l}, :uid => @path)
- return "" if output.include?("can't open your crontab")
- raise Puppet::Error, "User #{@path} not authorized to use cron" if output.include?("you are not authorized to use cron")
- return output
- rescue => detail
- raise Puppet::Error, "Could not read crontab for #{@path}: #{detail}"
- end
+ # Overwrite a specific @path's cron tab; must be passed the @path name
+ # and the text with which to create the cron tab.
+ def write(text)
+ IO.popen("#{cmdbase()} -", "w") { |p|
+ p.print text
+ }
+ end
- # Remove a specific @path's cron tab.
- def remove
- Puppet::Util.execute(%w{crontab -r}, :uid => @path)
- rescue => detail
- raise Puppet::Error, "Could not remove crontab for #{@path}: #{detail}"
- end
+ private
+
+ # Only add the -u flag when the @path is different. Fedora apparently
+ # does not think I should be allowed to set the @path to my own user name
+ def cmdbase
+ cmd = nil
+ if @uid == Puppet::Util::SUIDManager.uid || Facter.value(:operatingsystem) == "HP-UX"
+ return "crontab"
+ else
+ return "crontab -u #{@path}"
+ end
+ end
+ end
+
+ # SunOS has completely different cron commands; this class implements
+ # its versions.
+ newfiletype(:suntab) do
+ # Read a specific @path's cron tab.
+ def read
+ output = Puppet::Util.execute(%w{crontab -l}, :uid => @path)
+ return "" if output.include?("can't open your crontab")
+ raise Puppet::Error, "User #{@path} not authorized to use cron" if output.include?("you are not authorized to use cron")
+ return output
+ rescue => detail
+ raise Puppet::Error, "Could not read crontab for #{@path}: #{detail}"
+ end
- # Overwrite a specific @path's cron tab; must be passed the @path name
- # and the text with which to create the cron tab.
- def write(text)
- puts text
- require "tempfile"
- output_file = Tempfile.new("puppet")
- fh = output_file.open
- fh.print text
- fh.close
-
- # We have to chown the stupid file to the user.
- File.chown(Puppet::Util.uid(@path), nil, output_file.path)
-
- begin
- Puppet::Util.execute(["crontab", output_file.path], :uid => @path)
- rescue => detail
- raise Puppet::Error, "Could not write crontab for #{@path}: #{detail}"
- end
- output_file.delete
- end
+ # Remove a specific @path's cron tab.
+ def remove
+ Puppet::Util.execute(%w{crontab -r}, :uid => @path)
+ rescue => detail
+ raise Puppet::Error, "Could not remove crontab for #{@path}: #{detail}"
end
- # Support for AIX crontab with output different than suntab's crontab command.
- newfiletype(:aixtab) do
- # Read a specific @path's cron tab.
- def read
- output = Puppet::Util.execute(%w{crontab -l}, :uid => @path)
- raise Puppet::Error, "User #{@path} not authorized to use cron" if output.include?("You are not authorized to use the cron command")
- return output
- rescue => detail
- raise Puppet::Error, "Could not read crontab for #{@path}: #{detail}"
- end
+ # Overwrite a specific @path's cron tab; must be passed the @path name
+ # and the text with which to create the cron tab.
+ def write(text)
+ puts text
+ require "tempfile"
+ output_file = Tempfile.new("puppet")
+ fh = output_file.open
+ fh.print text
+ fh.close
+
+ # We have to chown the stupid file to the user.
+ File.chown(Puppet::Util.uid(@path), nil, output_file.path)
+
+ begin
+ Puppet::Util.execute(["crontab", output_file.path], :uid => @path)
+ rescue => detail
+ raise Puppet::Error, "Could not write crontab for #{@path}: #{detail}"
+ end
+ output_file.delete
+ end
+ end
+
+ # Support for AIX crontab with output different than suntab's crontab command.
+ newfiletype(:aixtab) do
+ # Read a specific @path's cron tab.
+ def read
+ output = Puppet::Util.execute(%w{crontab -l}, :uid => @path)
+ raise Puppet::Error, "User #{@path} not authorized to use cron" if output.include?("You are not authorized to use the cron command")
+ return output
+ rescue => detail
+ raise Puppet::Error, "Could not read crontab for #{@path}: #{detail}"
+ end
- # Remove a specific @path's cron tab.
- def remove
- Puppet::Util.execute(%w{crontab -r}, :uid => @path)
- rescue => detail
- raise Puppet::Error, "Could not remove crontab for #{@path}: #{detail}"
- end
+ # Remove a specific @path's cron tab.
+ def remove
+ Puppet::Util.execute(%w{crontab -r}, :uid => @path)
+ rescue => detail
+ raise Puppet::Error, "Could not remove crontab for #{@path}: #{detail}"
+ end
- # Overwrite a specific @path's cron tab; must be passed the @path name
- # and the text with which to create the cron tab.
- def write(text)
- require "tempfile"
- output_file = Tempfile.new("puppet")
- fh = output_file.open
- fh.print text
- fh.close
-
- # We have to chown the stupid file to the user.
- File.chown(Puppet::Util.uid(@path), nil, output_file.path)
-
- begin
- Puppet::Util.execute(["crontab", output_file.path], :uid => @path)
- rescue => detail
- raise Puppet::Error, "Could not write crontab for #{@path}: #{detail}"
- ensure
- output_file.delete
- end
- end
+ # Overwrite a specific @path's cron tab; must be passed the @path name
+ # and the text with which to create the cron tab.
+ def write(text)
+ require "tempfile"
+ output_file = Tempfile.new("puppet")
+ fh = output_file.open
+ fh.print text
+ fh.close
+
+ # We have to chown the stupid file to the user.
+ File.chown(Puppet::Util.uid(@path), nil, output_file.path)
+
+ begin
+ Puppet::Util.execute(["crontab", output_file.path], :uid => @path)
+ rescue => detail
+ raise Puppet::Error, "Could not write crontab for #{@path}: #{detail}"
+ ensure
+ output_file.delete
+ end
end
+ end
end
diff --git a/lib/puppet/util/graph.rb b/lib/puppet/util/graph.rb
index 5dd55e9..9598d28 100644
--- a/lib/puppet/util/graph.rb
+++ b/lib/puppet/util/graph.rb
@@ -6,25 +6,25 @@ require 'puppet/simple_graph'
# A module that handles the small amount of graph stuff in Puppet.
module Puppet::Util::Graph
- # Make a graph where each of our children gets converted to
- # the receiving end of an edge. Call the same thing on all
- # of our children, optionally using a block
- def to_graph(graph = nil, &block)
- # Allow our calling function to send in a graph, so that we
- # can call this recursively with one graph.
- graph ||= Puppet::SimpleGraph.new
+ # Make a graph where each of our children gets converted to
+ # the receiving end of an edge. Call the same thing on all
+ # of our children, optionally using a block
+ def to_graph(graph = nil, &block)
+ # Allow our calling function to send in a graph, so that we
+ # can call this recursively with one graph.
+ graph ||= Puppet::SimpleGraph.new
- self.each do |child|
- unless block_given? and ! yield(child)
- graph.add_edge(self, child)
+ self.each do |child|
+ unless block_given? and ! yield(child)
+ graph.add_edge(self, child)
- child.to_graph(graph, &block) if child.respond_to?(:to_graph)
- end
- end
+ child.to_graph(graph, &block) if child.respond_to?(:to_graph)
+ end
+ end
- # Do a topsort, which will throw an exception if the graph is cyclic.
+ # Do a topsort, which will throw an exception if the graph is cyclic.
- graph
- end
+ graph
+ end
end
diff --git a/lib/puppet/util/inifile.rb b/lib/puppet/util/inifile.rb
index 276f741..82f074d 100644
--- a/lib/puppet/util/inifile.rb
+++ b/lib/puppet/util/inifile.rb
@@ -11,193 +11,193 @@
require 'puppet/util/filetype'
module Puppet::Util::IniConfig
- # A section in a .ini file
- class Section
- attr_reader :name, :file
-
- def initialize(name, file)
- @name = name
- @file = file
- @dirty = false
- @entries = []
- end
-
- # Has this section been modified since it's been read in
- # or written back to disk
- def dirty?
- @dirty
- end
+ # A section in a .ini file
+ class Section
+ attr_reader :name, :file
+
+ def initialize(name, file)
+ @name = name
+ @file = file
+ @dirty = false
+ @entries = []
+ end
- # Should only be used internally
- def mark_clean
- @dirty = false
- end
+ # Has this section been modified since it's been read in
+ # or written back to disk
+ def dirty?
+ @dirty
+ end
- # Add a line of text (e.g., a comment) Such lines
- # will be written back out in exactly the same
- # place they were read in
- def add_line(line)
- @entries << line
- end
+ # Should only be used internally
+ def mark_clean
+ @dirty = false
+ end
- # Set the entry 'key=value'. If no entry with the
- # given key exists, one is appended to teh end of the section
- def []=(key, value)
- entry = find_entry(key)
- @dirty = true
- if entry.nil?
- @entries << [key, value]
- else
- entry[1] = value
- end
- end
+ # Add a line of text (e.g., a comment) Such lines
+ # will be written back out in exactly the same
+ # place they were read in
+ def add_line(line)
+ @entries << line
+ end
- # Return the value associated with KEY. If no such entry
- # exists, return nil
- def [](key)
- entry = find_entry(key)
- return(entry.nil? ? nil : entry[1])
- end
+ # Set the entry 'key=value'. If no entry with the
+ # given key exists, one is appended to teh end of the section
+ def []=(key, value)
+ entry = find_entry(key)
+ @dirty = true
+ if entry.nil?
+ @entries << [key, value]
+ else
+ entry[1] = value
+ end
+ end
- # Format the section as text in the way it should be
- # written to file
- def format
- text = "[#{name}]\n"
- @entries.each do |entry|
- if entry.is_a?(Array)
- key, value = entry
- text << "#{key}=#{value}\n" unless value.nil?
- else
- text << entry
- end
- end
- text
- end
+ # Return the value associated with KEY. If no such entry
+ # exists, return nil
+ def [](key)
+ entry = find_entry(key)
+ return(entry.nil? ? nil : entry[1])
+ end
- private
- def find_entry(key)
- @entries.each do |entry|
- return entry if entry.is_a?(Array) && entry[0] == key
- end
- nil
- end
+ # Format the section as text in the way it should be
+ # written to file
+ def format
+ text = "[#{name}]\n"
+ @entries.each do |entry|
+ if entry.is_a?(Array)
+ key, value = entry
+ text << "#{key}=#{value}\n" unless value.nil?
+ else
+ text << entry
+ end
+ end
+ text
+ end
+ private
+ def find_entry(key)
+ @entries.each do |entry|
+ return entry if entry.is_a?(Array) && entry[0] == key
+ end
+ nil
end
- # A logical .ini-file that can be spread across several physical
- # files. For each physical file, call #read with the filename
- class File
- def initialize
- @files = {}
- end
+ end
- # Add the contents of the file with name FILE to the
- # already existing sections
- def read(file)
- text = Puppet::Util::FileType.filetype(:flat).new(file).read
- raise "Could not find #{file}" if text.nil?
-
- section = nil # The name of the current section
- optname = nil # The name of the last option in section
- line = 0
- @files[file] = []
- text.each_line do |l|
- line += 1
- if l.strip.empty? || "#;".include?(l[0,1]) ||
- (l.split(nil, 2)[0].downcase == "rem" && l[0,1].downcase == "r")
- # Whitespace or comment
- if section.nil?
- @files[file] << l
- else
- section.add_line(l)
- end
- elsif " \t\r\n\f".include?(l[0,1]) && section && optname
- # continuation line
- section[optname] += "\n#{l.chomp}"
- elsif l =~ /^\[([^\]]+)\]/
- # section heading
- section.mark_clean unless section.nil?
- section = add_section($1, file)
- optname = nil
- elsif l =~ /^\s*([^\s=]+)\s*\=(.*)$/
- # We allow space around the keys, but not the values
- # For the values, we don't know if space is significant
- if section.nil?
- raise "#{file}:#{line}:Key/value pair outside of a section for key #{$1}"
- else
- section[$1] = $2
- optname = $1
- end
- else
- raise "#{file}:#{line}: Can't parse '#{l.chomp}'"
- end
- end
- section.mark_clean unless section.nil?
- end
+ # A logical .ini-file that can be spread across several physical
+ # files. For each physical file, call #read with the filename
+ class File
+ def initialize
+ @files = {}
+ end
- # Store all modifications made to sections in this file back
- # to the physical files. If no modifications were made to
- # a physical file, nothing is written
- def store
- @files.each do |file, lines|
- text = ""
- dirty = false
- lines.each do |l|
- if l.is_a?(Section)
- dirty ||= l.dirty?
- text << l.format
- l.mark_clean
- else
- text << l
- end
- end
- if dirty
- Puppet::Util::FileType.filetype(:flat).new(file).write(text)
- return file
- end
- end
- end
+ # Add the contents of the file with name FILE to the
+ # already existing sections
+ def read(file)
+ text = Puppet::Util::FileType.filetype(:flat).new(file).read
+ raise "Could not find #{file}" if text.nil?
+
+ section = nil # The name of the current section
+ optname = nil # The name of the last option in section
+ line = 0
+ @files[file] = []
+ text.each_line do |l|
+ line += 1
+ if l.strip.empty? || "#;".include?(l[0,1]) ||
+ (l.split(nil, 2)[0].downcase == "rem" && l[0,1].downcase == "r")
+ # Whitespace or comment
+ if section.nil?
+ @files[file] << l
+ else
+ section.add_line(l)
+ end
+ elsif " \t\r\n\f".include?(l[0,1]) && section && optname
+ # continuation line
+ section[optname] += "\n#{l.chomp}"
+ elsif l =~ /^\[([^\]]+)\]/
+ # section heading
+ section.mark_clean unless section.nil?
+ section = add_section($1, file)
+ optname = nil
+ elsif l =~ /^\s*([^\s=]+)\s*\=(.*)$/
+ # We allow space around the keys, but not the values
+ # For the values, we don't know if space is significant
+ if section.nil?
+ raise "#{file}:#{line}:Key/value pair outside of a section for key #{$1}"
+ else
+ section[$1] = $2
+ optname = $1
+ end
+ else
+ raise "#{file}:#{line}: Can't parse '#{l.chomp}'"
+ end
+ end
+ section.mark_clean unless section.nil?
+ end
- # Execute BLOCK, passing each section in this file
- # as an argument
- def each_section(&block)
- @files.each do |file, list|
- list.each do |entry|
- yield(entry) if entry.is_a?(Section)
- end
- end
- end
+ # Store all modifications made to sections in this file back
+ # to the physical files. If no modifications were made to
+ # a physical file, nothing is written
+ def store
+ @files.each do |file, lines|
+ text = ""
+ dirty = false
+ lines.each do |l|
+ if l.is_a?(Section)
+ dirty ||= l.dirty?
+ text << l.format
+ l.mark_clean
+ else
+ text << l
+ end
+ end
+ if dirty
+ Puppet::Util::FileType.filetype(:flat).new(file).write(text)
+ return file
+ end
+ end
+ end
- # Execute BLOCK, passing each file constituting this inifile
- # as an argument
- def each_file(&block)
- @files.keys.each do |file|
- yield(file)
- end
+ # Execute BLOCK, passing each section in this file
+ # as an argument
+ def each_section(&block)
+ @files.each do |file, list|
+ list.each do |entry|
+ yield(entry) if entry.is_a?(Section)
end
+ end
+ end
- # Return the Section with the given name or nil
- def [](name)
- name = name.to_s
- each_section do |section|
- return section if section.name == name
- end
- nil
- end
+ # Execute BLOCK, passing each file constituting this inifile
+ # as an argument
+ def each_file(&block)
+ @files.keys.each do |file|
+ yield(file)
+ end
+ end
- # Return true if the file contains a section with name NAME
- def include?(name)
- ! self[name].nil?
- end
+ # Return the Section with the given name or nil
+ def [](name)
+ name = name.to_s
+ each_section do |section|
+ return section if section.name == name
+ end
+ nil
+ end
- # Add a section to be stored in FILE when store is called
- def add_section(name, file)
- raise "A section with name #{name} already exists" if include?(name)
- result = Section.new(name, file)
- @files[file] ||= []
- @files[file] << result
- result
- end
+ # Return true if the file contains a section with name NAME
+ def include?(name)
+ ! self[name].nil?
+ end
+
+ # Add a section to be stored in FILE when store is called
+ def add_section(name, file)
+ raise "A section with name #{name} already exists" if include?(name)
+ result = Section.new(name, file)
+ @files[file] ||= []
+ @files[file] << result
+ result
end
+ end
end
diff --git a/lib/puppet/util/inline_docs.rb b/lib/puppet/util/inline_docs.rb
index 1e54506..62818c1 100644
--- a/lib/puppet/util/inline_docs.rb
+++ b/lib/puppet/util/inline_docs.rb
@@ -1,26 +1,26 @@
module Puppet::Util::InlineDocs
- def self.included(klass)
- klass.send(:include, InstanceMethods)
- klass.extend ClassMethods
- end
+ def self.included(klass)
+ klass.send(:include, InstanceMethods)
+ klass.extend ClassMethods
+ end
- module ClassMethods
- attr_accessor :use_docs
- def associates_doc
- self.use_docs = true
- end
+ module ClassMethods
+ attr_accessor :use_docs
+ def associates_doc
+ self.use_docs = true
end
+ end
- module InstanceMethods
- attr_writer :doc
+ module InstanceMethods
+ attr_writer :doc
- def doc
- @doc ||= ""
- end
+ def doc
+ @doc ||= ""
+ end
- # don't fetch lexer comment by default
- def use_docs
- self.class.use_docs
- end
+ # don't fetch lexer comment by default
+ def use_docs
+ self.class.use_docs
end
+ end
end
diff --git a/lib/puppet/util/instance_loader.rb b/lib/puppet/util/instance_loader.rb
index 56d75b6..5e16bd7 100755
--- a/lib/puppet/util/instance_loader.rb
+++ b/lib/puppet/util/instance_loader.rb
@@ -4,78 +4,78 @@ require 'puppet/util'
# A module that can easily autoload things for us. Uses an instance
# of Puppet::Util::Autoload
module Puppet::Util::InstanceLoader
- include Puppet::Util
+ include Puppet::Util
- # Are we instance-loading this type?
- def instance_loading?(type)
- defined?(@autoloaders) and @autoloaders.include?(symbolize(type))
- end
-
- # Define a new type of autoloading.
- def instance_load(type, path, options = {})
- @autoloaders ||= {}
- @instances ||= {}
- type = symbolize(type)
- @instances[type] = {}
- @autoloaders[type] = Puppet::Util::Autoload.new(self, path, options)
+ # Are we instance-loading this type?
+ def instance_loading?(type)
+ defined?(@autoloaders) and @autoloaders.include?(symbolize(type))
+ end
- # Now define our new simple methods
- unless respond_to?(type)
- meta_def(type) do |name|
- loaded_instance(type, name)
- end
- end
- end
+ # Define a new type of autoloading.
+ def instance_load(type, path, options = {})
+ @autoloaders ||= {}
+ @instances ||= {}
+ type = symbolize(type)
+ @instances[type] = {}
+ @autoloaders[type] = Puppet::Util::Autoload.new(self, path, options)
- # Return a list of the names of all instances
- def loaded_instances(type)
- @instances[type].keys
+ # Now define our new simple methods
+ unless respond_to?(type)
+ meta_def(type) do |name|
+ loaded_instance(type, name)
+ end
end
+ end
- # Collect the docs for all of our instances.
- def instance_docs(type)
- docs = ""
+ # Return a list of the names of all instances
+ def loaded_instances(type)
+ @instances[type].keys
+ end
- # Load all instances.
- instance_loader(type).loadall
+ # Collect the docs for all of our instances.
+ def instance_docs(type)
+ docs = ""
- # Use this method so they all get loaded
- loaded_instances(type).sort { |a,b| a.to_s <=> b.to_s }.each do |name|
- mod = self.loaded_instance(name)
- docs += "#{name}\n#{"-" * name.to_s.length}\n"
+ # Load all instances.
+ instance_loader(type).loadall
- docs += Puppet::Util::Docs.scrub(mod.doc) + "\n\n"
- end
+ # Use this method so they all get loaded
+ loaded_instances(type).sort { |a,b| a.to_s <=> b.to_s }.each do |name|
+ mod = self.loaded_instance(name)
+ docs += "#{name}\n#{"-" * name.to_s.length}\n"
- docs
+ docs += Puppet::Util::Docs.scrub(mod.doc) + "\n\n"
end
- # Return the instance hash for our type.
- def instance_hash(type)
- @instances[symbolize(type)]
- end
+ docs
+ end
- # Return the Autoload object for a given type.
- def instance_loader(type)
- @autoloaders[symbolize(type)]
- end
+ # Return the instance hash for our type.
+ def instance_hash(type)
+ @instances[symbolize(type)]
+ end
+
+ # Return the Autoload object for a given type.
+ def instance_loader(type)
+ @autoloaders[symbolize(type)]
+ end
- # Retrieve an alread-loaded instance, or attempt to load our instance.
- def loaded_instance(type, name)
- name = symbolize(name)
- return nil unless instances = instance_hash(type)
+ # Retrieve an alread-loaded instance, or attempt to load our instance.
+ def loaded_instance(type, name)
+ name = symbolize(name)
+ return nil unless instances = instance_hash(type)
+ unless instances.include? name
+ if instance_loader(type).load(name)
unless instances.include? name
- if instance_loader(type).load(name)
- unless instances.include? name
- Puppet.warning(
- "Loaded #{type} file for #{name} but #{type} was not defined"
- )
- return nil
- end
- else
- return nil
- end
+ Puppet.warning(
+ "Loaded #{type} file for #{name} but #{type} was not defined"
+ )
+ return nil
end
- instances[name]
+ else
+ return nil
+ end
end
+ instances[name]
+ end
end
diff --git a/lib/puppet/util/ldap/connection.rb b/lib/puppet/util/ldap/connection.rb
index 624bc6f..03240ea 100644
--- a/lib/puppet/util/ldap/connection.rb
+++ b/lib/puppet/util/ldap/connection.rb
@@ -4,74 +4,74 @@
require 'puppet/util/ldap'
class Puppet::Util::Ldap::Connection
- attr_accessor :host, :port, :user, :password, :reset, :ssl
+ attr_accessor :host, :port, :user, :password, :reset, :ssl
- attr_reader :connection
+ attr_reader :connection
- # Return a default connection, using our default settings.
- def self.instance
- ssl = if Puppet[:ldaptls]
- :tls
- elsif Puppet[:ldapssl]
- true
- else
- false
- end
-
- options = {}
- options[:ssl] = ssl
- if user = Puppet.settings[:ldapuser] and user != ""
- options[:user] = user
- if pass = Puppet.settings[:ldappassword] and pass != ""
- options[:password] = pass
- end
+ # Return a default connection, using our default settings.
+ def self.instance
+ ssl = if Puppet[:ldaptls]
+ :tls
+ elsif Puppet[:ldapssl]
+ true
+ else
+ false
end
- new(Puppet[:ldapserver], Puppet[:ldapport], options)
+ options = {}
+ options[:ssl] = ssl
+ if user = Puppet.settings[:ldapuser] and user != ""
+ options[:user] = user
+ if pass = Puppet.settings[:ldappassword] and pass != ""
+ options[:password] = pass
+ end
end
- def close
- connection.unbind if connection.bound?
- end
+ new(Puppet[:ldapserver], Puppet[:ldapport], options)
+ end
- def initialize(host, port, options = {})
- raise Puppet::Error, "Could not set up LDAP Connection: Missing ruby/ldap libraries" unless Puppet.features.ldap?
+ def close
+ connection.unbind if connection.bound?
+ end
- @host, @port = host, port
+ def initialize(host, port, options = {})
+ raise Puppet::Error, "Could not set up LDAP Connection: Missing ruby/ldap libraries" unless Puppet.features.ldap?
- options.each do |param, value|
- begin
- send(param.to_s + "=", value)
- rescue
- raise ArgumentError, "LDAP connections do not support #{param} parameters"
- end
- end
- end
+ @host, @port = host, port
- # Create a per-connection unique name.
- def name
- [host, port, user, password, ssl].collect { |p| p.to_s }.join("/")
+ options.each do |param, value|
+ begin
+ send(param.to_s + "=", value)
+ rescue
+ raise ArgumentError, "LDAP connections do not support #{param} parameters"
+ end
end
+ end
- # Should we reset the connection?
- def reset?
- reset
- end
+ # Create a per-connection unique name.
+ def name
+ [host, port, user, password, ssl].collect { |p| p.to_s }.join("/")
+ end
- # Start our ldap connection.
- def start
- case ssl
- when :tls
- @connection = LDAP::SSLConn.new(host, port, true)
- when true
- @connection = LDAP::SSLConn.new(host, port)
- else
- @connection = LDAP::Conn.new(host, port)
- end
- @connection.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
- @connection.set_option(LDAP::LDAP_OPT_REFERRALS, LDAP::LDAP_OPT_ON)
- @connection.simple_bind(user, password)
- rescue => detail
- raise Puppet::Error, "Could not connect to LDAP: #{detail}"
- end
+ # Should we reset the connection?
+ def reset?
+ reset
+ end
+
+ # Start our ldap connection.
+ def start
+ case ssl
+ when :tls
+ @connection = LDAP::SSLConn.new(host, port, true)
+ when true
+ @connection = LDAP::SSLConn.new(host, port)
+ else
+ @connection = LDAP::Conn.new(host, port)
+ end
+ @connection.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
+ @connection.set_option(LDAP::LDAP_OPT_REFERRALS, LDAP::LDAP_OPT_ON)
+ @connection.simple_bind(user, password)
+ rescue => detail
+ raise Puppet::Error, "Could not connect to LDAP: #{detail}"
+ end
end
diff --git a/lib/puppet/util/ldap/generator.rb b/lib/puppet/util/ldap/generator.rb
index 2320c20..2aaa9c3 100644
--- a/lib/puppet/util/ldap/generator.rb
+++ b/lib/puppet/util/ldap/generator.rb
@@ -4,42 +4,42 @@
require 'puppet/util/ldap'
class Puppet::Util::Ldap::Generator
- # Declare the attribute we'll use to generate the value.
- def from(source)
- @source = source
- self
- end
+ # Declare the attribute we'll use to generate the value.
+ def from(source)
+ @source = source
+ self
+ end
- # Actually do the generation.
- def generate(value = nil)
- if value.nil?
- @generator.call
- else
- @generator.call(value)
- end
+ # Actually do the generation.
+ def generate(value = nil)
+ if value.nil?
+ @generator.call
+ else
+ @generator.call(value)
end
+ end
- # Initialize our generator with the name of the parameter
- # being generated.
- def initialize(name)
- @name = name
- end
+ # Initialize our generator with the name of the parameter
+ # being generated.
+ def initialize(name)
+ @name = name
+ end
- def name
- @name.to_s
- end
+ def name
+ @name.to_s
+ end
- def source
- if @source
- @source.to_s
- else
- nil
- end
+ def source
+ if @source
+ @source.to_s
+ else
+ nil
end
+ end
- # Provide the code that does the generation.
- def with(&block)
- @generator = block
- self
- end
+ # Provide the code that does the generation.
+ def with(&block)
+ @generator = block
+ self
+ end
end
diff --git a/lib/puppet/util/ldap/manager.rb b/lib/puppet/util/ldap/manager.rb
index 501a3cd..2ccd102 100644
--- a/lib/puppet/util/ldap/manager.rb
+++ b/lib/puppet/util/ldap/manager.rb
@@ -5,275 +5,275 @@ require 'puppet/util/ldap/generator'
# The configuration class for LDAP providers, plus
# connection handling for actually interacting with ldap.
class Puppet::Util::Ldap::Manager
- attr_reader :objectclasses, :puppet2ldap, :location, :rdn
-
- # A null-op that just returns the config.
- def and
- self
+ attr_reader :objectclasses, :puppet2ldap, :location, :rdn
+
+ # A null-op that just returns the config.
+ def and
+ self
+ end
+
+ # Set the offset from the search base and return the config.
+ def at(location)
+ @location = location
+ self
+ end
+
+ # The basic search base.
+ def base
+ [location, Puppet[:ldapbase]].join(",")
+ end
+
+ # Convert the name to a dn, then pass the args along to
+ # our connection.
+ def create(name, attributes)
+ attributes = attributes.dup
+
+ # Add the objectclasses
+ attributes["objectClass"] = objectclasses.collect { |o| o.to_s }
+ attributes["objectClass"] << "top" unless attributes["objectClass"].include?("top")
+
+ attributes[rdn.to_s] = [name]
+
+ # Generate any new values we might need.
+ generate(attributes)
+
+ # And create our resource.
+ connect { |conn| conn.add dn(name), attributes }
+ end
+
+ # Open, yield, and close the connection. Cannot be left
+ # open, at this point.
+ def connect
+ raise ArgumentError, "You must pass a block to #connect" unless block_given?
+
+ unless @connection
+ if Puppet[:ldaptls]
+ ssl = :tls
+ elsif Puppet[:ldapssl]
+ ssl = true
+ else
+ ssl = false
+ end
+ options = {:ssl => ssl}
+ if user = Puppet[:ldapuser] and user != ""
+ options[:user] = user
+ end
+ if password = Puppet[:ldappassword] and password != ""
+ options[:password] = password
+ end
+ @connection = Puppet::Util::Ldap::Connection.new(Puppet[:ldapserver], Puppet[:ldapport], options)
end
-
- # Set the offset from the search base and return the config.
- def at(location)
- @location = location
- self
+ @connection.start
+ begin
+ yield @connection.connection
+ ensure
+ @connection.close
end
+ nil
+ end
- # The basic search base.
- def base
- [location, Puppet[:ldapbase]].join(",")
- end
+ # Convert the name to a dn, then pass the args along to
+ # our connection.
+ def delete(name)
+ connect { |connection| connection.delete dn(name) }
+ end
- # Convert the name to a dn, then pass the args along to
- # our connection.
- def create(name, attributes)
- attributes = attributes.dup
+ # Calculate the dn for a given resource.
+ def dn(name)
+ ["#{rdn}=#{name}", base].join(",")
+ end
- # Add the objectclasses
- attributes["objectClass"] = objectclasses.collect { |o| o.to_s }
- attributes["objectClass"] << "top" unless attributes["objectClass"].include?("top")
+ # Convert an ldap-style entry hash to a provider-style hash.
+ def entry2provider(entry)
+ raise ArgumentError, "Could not get dn from ldap entry" unless entry["dn"]
- attributes[rdn.to_s] = [name]
+ # DN is always a single-entry array. Strip off the bits before the
+ # first comma, then the bits after the remaining equal sign. This is the
+ # name.
+ name = entry["dn"].dup.pop.split(",").shift.split("=").pop
- # Generate any new values we might need.
- generate(attributes)
+ result = {:name => name}
- # And create our resource.
- connect { |conn| conn.add dn(name), attributes }
+ @ldap2puppet.each do |ldap, puppet|
+ result[puppet] = entry[ldap.to_s] || :absent
end
- # Open, yield, and close the connection. Cannot be left
- # open, at this point.
- def connect
- raise ArgumentError, "You must pass a block to #connect" unless block_given?
-
- unless @connection
- if Puppet[:ldaptls]
- ssl = :tls
- elsif Puppet[:ldapssl]
- ssl = true
- else
- ssl = false
- end
- options = {:ssl => ssl}
- if user = Puppet[:ldapuser] and user != ""
- options[:user] = user
- end
- if password = Puppet[:ldappassword] and password != ""
- options[:password] = password
- end
- @connection = Puppet::Util::Ldap::Connection.new(Puppet[:ldapserver], Puppet[:ldapport], options)
+ result
+ end
+
+ # Create our normal search filter.
+ def filter
+ return(objectclasses.length == 1 ? "objectclass=#{objectclasses[0]}" : "(&(objectclass=" + objectclasses.join(")(objectclass=") + "))")
+ end
+
+ # Find the associated entry for a resource. Returns a hash, minus
+ # 'dn', or nil if the entry cannot be found.
+ def find(name)
+ result = nil
+ connect do |conn|
+ begin
+ conn.search2(dn(name), 0, "objectclass=*") do |result|
+ # Convert to puppet-appropriate attributes
+ return entry2provider(result)
end
- @connection.start
- begin
- yield @connection.connection
- ensure
- @connection.close
- end
- nil
+ rescue => detail
+ return nil
+ end
end
+ end
- # Convert the name to a dn, then pass the args along to
- # our connection.
- def delete(name)
- connect { |connection| connection.delete dn(name) }
- end
+ # Declare a new attribute generator.
+ def generates(parameter)
+ @generators << Puppet::Util::Ldap::Generator.new(parameter)
+ @generators[-1]
+ end
- # Calculate the dn for a given resource.
- def dn(name)
- ["#{rdn}=#{name}", base].join(",")
- end
+ # Generate any extra values we need to make the ldap entry work.
+ def generate(values)
+ return unless @generators.length > 0
- # Convert an ldap-style entry hash to a provider-style hash.
- def entry2provider(entry)
- raise ArgumentError, "Could not get dn from ldap entry" unless entry["dn"]
+ @generators.each do |generator|
+ # Don't override any values that might exist.
+ next if values[generator.name]
- # DN is always a single-entry array. Strip off the bits before the
- # first comma, then the bits after the remaining equal sign. This is the
- # name.
- name = entry["dn"].dup.pop.split(",").shift.split("=").pop
-
- result = {:name => name}
-
- @ldap2puppet.each do |ldap, puppet|
- result[puppet] = entry[ldap.to_s] || :absent
+ if generator.source
+ unless value = values[generator.source]
+ raise ArgumentError, "#{generator.source} must be defined to generate #{generator.name}"
end
+ result = generator.generate(value)
+ else
+ result = generator.generate
+ end
- result
- end
-
- # Create our normal search filter.
- def filter
- return(objectclasses.length == 1 ? "objectclass=#{objectclasses[0]}" : "(&(objectclass=" + objectclasses.join(")(objectclass=") + "))")
- end
-
- # Find the associated entry for a resource. Returns a hash, minus
- # 'dn', or nil if the entry cannot be found.
- def find(name)
- result = nil
- connect do |conn|
- begin
- conn.search2(dn(name), 0, "objectclass=*") do |result|
- # Convert to puppet-appropriate attributes
- return entry2provider(result)
- end
- rescue => detail
- return nil
- end
- end
- end
+ result = [result] unless result.is_a?(Array)
+ result = result.collect { |r| r.to_s }
- # Declare a new attribute generator.
- def generates(parameter)
- @generators << Puppet::Util::Ldap::Generator.new(parameter)
- @generators[-1]
+ values[generator.name] = result
end
-
- # Generate any extra values we need to make the ldap entry work.
- def generate(values)
- return unless @generators.length > 0
-
- @generators.each do |generator|
- # Don't override any values that might exist.
- next if values[generator.name]
-
- if generator.source
- unless value = values[generator.source]
- raise ArgumentError, "#{generator.source} must be defined to generate #{generator.name}"
- end
- result = generator.generate(value)
- else
- result = generator.generate
- end
-
- result = [result] unless result.is_a?(Array)
- result = result.collect { |r| r.to_s }
-
- values[generator.name] = result
- end
+ end
+
+ def initialize
+ @rdn = :cn
+ @generators = []
+ end
+
+ # Specify what classes this provider models.
+ def manages(*classes)
+ @objectclasses = classes
+ self
+ end
+
+ # Specify the attribute map. Assumes the keys are the puppet
+ # attributes, and the values are the ldap attributes, and creates a map
+ # for each direction.
+ def maps(attributes)
+ # The map with the puppet attributes as the keys
+ @puppet2ldap = attributes
+
+ # and the ldap attributes as the keys.
+ @ldap2puppet = attributes.inject({}) { |map, ary| map[ary[1]] = ary[0]; map }
+
+ self
+ end
+
+ # Return the ldap name for a puppet attribute.
+ def ldap_name(attribute)
+ @puppet2ldap[attribute].to_s
+ end
+
+ # Convert the name to a dn, then pass the args along to
+ # our connection.
+ def modify(name, mods)
+ connect { |connection| connection.modify dn(name), mods }
+ end
+
+ # Specify the rdn that we use to build up our dn.
+ def named_by(attribute)
+ @rdn = attribute
+ self
+ end
+
+ # Return the puppet name for an ldap attribute.
+ def puppet_name(attribute)
+ @ldap2puppet[attribute]
+ end
+
+ # Search for all entries at our base. A potentially expensive search.
+ def search(sfilter = nil)
+ sfilter ||= filter
+
+ result = []
+ connect do |conn|
+ conn.search2(base, 1, sfilter) do |entry|
+ result << entry2provider(entry)
+ end
end
-
- def initialize
- @rdn = :cn
- @generators = []
+ return(result.empty? ? nil : result)
+ end
+
+ # Update the ldap entry with the desired state.
+ def update(name, is, should)
+ if should[:ensure] == :absent
+ Puppet.info "Removing #{dn(name)} from ldap"
+ delete(name)
+ return
end
- # Specify what classes this provider models.
- def manages(*classes)
- @objectclasses = classes
- self
+ # We're creating a new entry
+ if is.empty? or is[:ensure] == :absent
+ Puppet.info "Creating #{dn(name)} in ldap"
+ # Remove any :absent params and :ensure, then convert the names to ldap names.
+ attrs = ldap_convert(should)
+ create(name, attrs)
+ return
end
- # Specify the attribute map. Assumes the keys are the puppet
- # attributes, and the values are the ldap attributes, and creates a map
- # for each direction.
- def maps(attributes)
- # The map with the puppet attributes as the keys
- @puppet2ldap = attributes
-
- # and the ldap attributes as the keys.
- @ldap2puppet = attributes.inject({}) { |map, ary| map[ary[1]] = ary[0]; map }
+ # We're modifying an existing entry. Yuck.
- self
- end
-
- # Return the ldap name for a puppet attribute.
- def ldap_name(attribute)
- @puppet2ldap[attribute].to_s
- end
+ mods = []
+ # For each attribute we're deleting that is present, create a
+ # modify instance for deletion.
+ [is.keys, should.keys].flatten.uniq.each do |property|
+ # They're equal, so do nothing.
+ next if is[property] == should[property]
- # Convert the name to a dn, then pass the args along to
- # our connection.
- def modify(name, mods)
- connect { |connection| connection.modify dn(name), mods }
- end
+ attributes = ldap_convert(should)
- # Specify the rdn that we use to build up our dn.
- def named_by(attribute)
- @rdn = attribute
- self
- end
+ prop_name = ldap_name(property).to_s
- # Return the puppet name for an ldap attribute.
- def puppet_name(attribute)
- @ldap2puppet[attribute]
- end
+ # We're creating it.
+ if is[property] == :absent or is[property].nil?
+ mods << LDAP::Mod.new(LDAP::LDAP_MOD_ADD, prop_name, attributes[prop_name])
+ next
+ end
- # Search for all entries at our base. A potentially expensive search.
- def search(sfilter = nil)
- sfilter ||= filter
+ # We're deleting it
+ if should[property] == :absent or should[property].nil?
+ mods << LDAP::Mod.new(LDAP::LDAP_MOD_DELETE, prop_name, [])
+ next
+ end
- result = []
- connect do |conn|
- conn.search2(base, 1, sfilter) do |entry|
- result << entry2provider(entry)
- end
- end
- return(result.empty? ? nil : result)
+ # We're replacing an existing value
+ mods << LDAP::Mod.new(LDAP::LDAP_MOD_REPLACE, prop_name, attributes[prop_name])
end
- # Update the ldap entry with the desired state.
- def update(name, is, should)
- if should[:ensure] == :absent
- Puppet.info "Removing #{dn(name)} from ldap"
- delete(name)
- return
- end
-
- # We're creating a new entry
- if is.empty? or is[:ensure] == :absent
- Puppet.info "Creating #{dn(name)} in ldap"
- # Remove any :absent params and :ensure, then convert the names to ldap names.
- attrs = ldap_convert(should)
- create(name, attrs)
- return
- end
-
- # We're modifying an existing entry. Yuck.
+ modify(name, mods)
+ end
- mods = []
- # For each attribute we're deleting that is present, create a
- # modify instance for deletion.
- [is.keys, should.keys].flatten.uniq.each do |property|
- # They're equal, so do nothing.
- next if is[property] == should[property]
+ # Is this a complete ldap configuration?
+ def valid?
+ location and objectclasses and ! objectclasses.empty? and puppet2ldap
+ end
- attributes = ldap_convert(should)
+ private
- prop_name = ldap_name(property).to_s
-
- # We're creating it.
- if is[property] == :absent or is[property].nil?
- mods << LDAP::Mod.new(LDAP::LDAP_MOD_ADD, prop_name, attributes[prop_name])
- next
- end
-
- # We're deleting it
- if should[property] == :absent or should[property].nil?
- mods << LDAP::Mod.new(LDAP::LDAP_MOD_DELETE, prop_name, [])
- next
- end
-
- # We're replacing an existing value
- mods << LDAP::Mod.new(LDAP::LDAP_MOD_REPLACE, prop_name, attributes[prop_name])
- end
-
- modify(name, mods)
- end
-
- # Is this a complete ldap configuration?
- def valid?
- location and objectclasses and ! objectclasses.empty? and puppet2ldap
- end
-
- private
-
- # Convert a hash of attributes to ldap-like forms. This mostly means
- # getting rid of :ensure and making sure everything's an array of strings.
- def ldap_convert(attributes)
- attributes.reject { |param, value| value == :absent or param == :ensure }.inject({}) do |result, ary|
- value = (ary[1].is_a?(Array) ? ary[1] : [ary[1]]).collect { |v| v.to_s }
- result[ldap_name(ary[0])] = value
- result
- end
+ # Convert a hash of attributes to ldap-like forms. This mostly means
+ # getting rid of :ensure and making sure everything's an array of strings.
+ def ldap_convert(attributes)
+ attributes.reject { |param, value| value == :absent or param == :ensure }.inject({}) do |result, ary|
+ value = (ary[1].is_a?(Array) ? ary[1] : [ary[1]]).collect { |v| v.to_s }
+ result[ldap_name(ary[0])] = value
+ result
end
+ end
end
diff --git a/lib/puppet/util/loadedfile.rb b/lib/puppet/util/loadedfile.rb
index 9eaca55..735dba4 100755
--- a/lib/puppet/util/loadedfile.rb
+++ b/lib/puppet/util/loadedfile.rb
@@ -4,62 +4,62 @@
require 'puppet'
module Puppet
- class NoSuchFile < Puppet::Error; end
- class Util::LoadedFile
- attr_reader :file, :statted
+ class NoSuchFile < Puppet::Error; end
+ class Util::LoadedFile
+ attr_reader :file, :statted
- # Provide a hook for setting the timestamp during testing, so we don't
- # have to depend on the granularity of the filesystem.
- attr_writer :tstamp
+ # Provide a hook for setting the timestamp during testing, so we don't
+ # have to depend on the granularity of the filesystem.
+ attr_writer :tstamp
- # Determine whether the file has changed and thus whether it should
- # be reparsed.
- def changed?
- # Allow the timeout to be disabled entirely.
- return true if Puppet[:filetimeout] < 0
- tmp = stamp
+ # Determine whether the file has changed and thus whether it should
+ # be reparsed.
+ def changed?
+ # Allow the timeout to be disabled entirely.
+ return true if Puppet[:filetimeout] < 0
+ tmp = stamp
- # We use a different internal variable than the stamp method
- # because it doesn't keep historical state and we do -- that is,
- # we will always be comparing two timestamps, whereas
- # stamp just always wants the latest one.
- if tmp == @tstamp
- return false
- else
- @tstamp = tmp
- return @tstamp
- end
- end
+ # We use a different internal variable than the stamp method
+ # because it doesn't keep historical state and we do -- that is,
+ # we will always be comparing two timestamps, whereas
+ # stamp just always wants the latest one.
+ if tmp == @tstamp
+ return false
+ else
+ @tstamp = tmp
+ return @tstamp
+ end
+ end
- # Create the file. Must be passed the file path.
- def initialize(file)
- @file = file
- unless FileTest.exists?(@file)
- raise Puppet::NoSuchFile,
- "Can not use a non-existent file for parsing"
- end
- @statted = 0
- @stamp = nil
- @tstamp = stamp
- end
+ # Create the file. Must be passed the file path.
+ def initialize(file)
+ @file = file
+ unless FileTest.exists?(@file)
+ raise Puppet::NoSuchFile,
+ "Can not use a non-existent file for parsing"
+ end
+ @statted = 0
+ @stamp = nil
+ @tstamp = stamp
+ end
- # Retrieve the filestamp, but only refresh it if we're beyond our
- # filetimeout
- def stamp
- if @stamp.nil? or (Time.now.to_i - @statted >= Puppet[:filetimeout])
- @statted = Time.now.to_i
- begin
- @stamp = File.stat(@file).ctime
- rescue Errno::ENOENT
- @stamp = Time.now
- end
- end
- @stamp
+ # Retrieve the filestamp, but only refresh it if we're beyond our
+ # filetimeout
+ def stamp
+ if @stamp.nil? or (Time.now.to_i - @statted >= Puppet[:filetimeout])
+ @statted = Time.now.to_i
+ begin
+ @stamp = File.stat(@file).ctime
+ rescue Errno::ENOENT
+ @stamp = Time.now
end
+ end
+ @stamp
+ end
- def to_s
- @file
- end
+ def to_s
+ @file
end
+ end
end
diff --git a/lib/puppet/util/log.rb b/lib/puppet/util/log.rb
index c47aa0d..36a765c 100644
--- a/lib/puppet/util/log.rb
+++ b/lib/puppet/util/log.rb
@@ -5,250 +5,250 @@ require 'puppet/util/classgen'
# expected that that will be the most common log destination. Supports
# multiple destinations, one of which is a remote server.
class Puppet::Util::Log
- include Puppet::Util
- extend Puppet::Util::ClassGen
- include Puppet::Util::Tagging
+ include Puppet::Util
+ extend Puppet::Util::ClassGen
+ include Puppet::Util::Tagging
- @levels = [:debug,:info,:notice,:warning,:err,:alert,:emerg,:crit]
- @loglevel = 2
+ @levels = [:debug,:info,:notice,:warning,:err,:alert,:emerg,:crit]
+ @loglevel = 2
- @desttypes = {}
+ @desttypes = {}
- # Create a new destination type.
- def self.newdesttype(name, options = {}, &block)
+ # Create a new destination type.
+ def self.newdesttype(name, options = {}, &block)
- dest = genclass(
- name, :parent => Puppet::Util::Log::Destination, :prefix => "Dest",
- :block => block,
- :hash => @desttypes,
+ dest = genclass(
+ name, :parent => Puppet::Util::Log::Destination, :prefix => "Dest",
+ :block => block,
+ :hash => @desttypes,
- :attributes => options
- )
- dest.match(dest.name)
-
- dest
- end
+ :attributes => options
+ )
+ dest.match(dest.name)
- require 'puppet/util/log/destination'
- require 'puppet/util/log/destinations'
+ dest
+ end
- @destinations = {}
+ require 'puppet/util/log/destination'
+ require 'puppet/util/log/destinations'
- @queued = []
+ @destinations = {}
- class << self
- include Puppet::Util
- include Puppet::Util::ClassGen
-
- attr_reader :desttypes
- end
-
- # Reset log to basics. Basically just flushes and closes files and
- # undefs other objects.
- def Log.close(destination)
- if @destinations.include?(destination)
- @destinations[destination].flush if @destinations[destination].respond_to?(:flush)
- @destinations[destination].close if @destinations[destination].respond_to?(:close)
- @destinations.delete(destination)
- end
- end
-
- def self.close_all
- destinations.keys.each { |dest|
- close(dest)
- }
- end
-
- # Flush any log destinations that support such operations.
- def Log.flush
- @destinations.each { |type, dest|
- dest.flush if dest.respond_to?(:flush)
- }
- end
-
- # Create a new log message. The primary role of this method is to
- # avoid creating log messages below the loglevel.
- def Log.create(hash)
- raise Puppet::DevError, "Logs require a level" unless hash.include?(:level)
- raise Puppet::DevError, "Invalid log level #{hash[:level]}" unless @levels.index(hash[:level])
- @levels.index(hash[:level]) >= @loglevel ? Puppet::Util::Log.new(hash) : nil
- end
-
- def Log.destinations
- @destinations
- end
-
- # Yield each valid level in turn
- def Log.eachlevel
- @levels.each { |level| yield level }
- end
+ @queued = []
- # Return the current log level.
- def Log.level
- @levels[@loglevel]
+ class << self
+ include Puppet::Util
+ include Puppet::Util::ClassGen
+
+ attr_reader :desttypes
+ end
+
+ # Reset log to basics. Basically just flushes and closes files and
+ # undefs other objects.
+ def Log.close(destination)
+ if @destinations.include?(destination)
+ @destinations[destination].flush if @destinations[destination].respond_to?(:flush)
+ @destinations[destination].close if @destinations[destination].respond_to?(:close)
+ @destinations.delete(destination)
end
-
- # Set the current log level.
- def Log.level=(level)
- level = level.intern unless level.is_a?(Symbol)
-
- raise Puppet::DevError, "Invalid loglevel #{level}" unless @levels.include?(level)
-
- @loglevel = @levels.index(level)
+ end
+
+ def self.close_all
+ destinations.keys.each { |dest|
+ close(dest)
+ }
+ end
+
+ # Flush any log destinations that support such operations.
+ def Log.flush
+ @destinations.each { |type, dest|
+ dest.flush if dest.respond_to?(:flush)
+ }
+ end
+
+ # Create a new log message. The primary role of this method is to
+ # avoid creating log messages below the loglevel.
+ def Log.create(hash)
+ raise Puppet::DevError, "Logs require a level" unless hash.include?(:level)
+ raise Puppet::DevError, "Invalid log level #{hash[:level]}" unless @levels.index(hash[:level])
+ @levels.index(hash[:level]) >= @loglevel ? Puppet::Util::Log.new(hash) : nil
+ end
+
+ def Log.destinations
+ @destinations
+ end
+
+ # Yield each valid level in turn
+ def Log.eachlevel
+ @levels.each { |level| yield level }
+ end
+
+ # Return the current log level.
+ def Log.level
+ @levels[@loglevel]
+ end
+
+ # Set the current log level.
+ def Log.level=(level)
+ level = level.intern unless level.is_a?(Symbol)
+
+ raise Puppet::DevError, "Invalid loglevel #{level}" unless @levels.include?(level)
+
+ @loglevel = @levels.index(level)
+ end
+
+ def Log.levels
+ @levels.dup
+ end
+
+ # Create a new log destination.
+ def Log.newdestination(dest)
+ # Each destination can only occur once.
+ if @destinations.find { |name, obj| obj.name == dest }
+ return
end
- def Log.levels
- @levels.dup
+ name, type = @desttypes.find do |name, klass|
+ klass.match?(dest)
end
- # Create a new log destination.
- def Log.newdestination(dest)
- # Each destination can only occur once.
- if @destinations.find { |name, obj| obj.name == dest }
- return
- end
-
- name, type = @desttypes.find do |name, klass|
- klass.match?(dest)
- end
-
- raise Puppet::DevError, "Unknown destination type #{dest}" unless type
-
- begin
- if type.instance_method(:initialize).arity == 1
- @destinations[dest] = type.new(dest)
- else
- @destinations[dest] = type.new
- end
- flushqueue
- @destinations[dest]
- rescue => detail
- puts detail.backtrace if Puppet[:debug]
-
- # If this was our only destination, then add the console back in.
- newdestination(:console) if @destinations.empty? and (dest != :console and dest != "console")
- end
+ raise Puppet::DevError, "Unknown destination type #{dest}" unless type
+
+ begin
+ if type.instance_method(:initialize).arity == 1
+ @destinations[dest] = type.new(dest)
+ else
+ @destinations[dest] = type.new
+ end
+ flushqueue
+ @destinations[dest]
+ rescue => detail
+ puts detail.backtrace if Puppet[:debug]
+
+ # If this was our only destination, then add the console back in.
+ newdestination(:console) if @destinations.empty? and (dest != :console and dest != "console")
end
+ end
- # Route the actual message. FIXME There are lots of things this method
- # should do, like caching and a bit more. It's worth noting that there's
- # a potential for a loop here, if the machine somehow gets the destination set as
- # itself.
- def Log.newmessage(msg)
- return if @levels.index(msg.level) < @loglevel
+ # Route the actual message. FIXME There are lots of things this method
+ # should do, like caching and a bit more. It's worth noting that there's
+ # a potential for a loop here, if the machine somehow gets the destination set as
+ # itself.
+ def Log.newmessage(msg)
+ return if @levels.index(msg.level) < @loglevel
- queuemessage(msg) if @destinations.length == 0
-
- @destinations.each do |name, dest|
- threadlock(dest) do
- dest.handle(msg)
- end
- end
- end
-
- def Log.queuemessage(msg)
- @queued.push(msg)
- end
+ queuemessage(msg) if @destinations.length == 0
- def Log.flushqueue
- return unless @destinations.size >= 1
- @queued.each do |msg|
- Log.newmessage(msg)
- end
- @queued.clear
+ @destinations.each do |name, dest|
+ threadlock(dest) do
+ dest.handle(msg)
+ end
end
+ end
- def Log.sendlevel?(level)
- @levels.index(level) >= @loglevel
- end
+ def Log.queuemessage(msg)
+ @queued.push(msg)
+ end
- # Reopen all of our logs.
- def Log.reopen
- Puppet.notice "Reopening log files"
- types = @destinations.keys
- @destinations.each { |type, dest|
- dest.close if dest.respond_to?(:close)
- }
- @destinations.clear
- # We need to make sure we always end up with some kind of destination
- begin
- types.each { |type|
- Log.newdestination(type)
- }
- rescue => detail
- if @destinations.empty?
- Log.newdestination(:syslog)
- Puppet.err detail.to_s
- end
- end
+ def Log.flushqueue
+ return unless @destinations.size >= 1
+ @queued.each do |msg|
+ Log.newmessage(msg)
end
-
- # Is the passed level a valid log level?
- def self.validlevel?(level)
- @levels.include?(level)
+ @queued.clear
+ end
+
+ def Log.sendlevel?(level)
+ @levels.index(level) >= @loglevel
+ end
+
+ # Reopen all of our logs.
+ def Log.reopen
+ Puppet.notice "Reopening log files"
+ types = @destinations.keys
+ @destinations.each { |type, dest|
+ dest.close if dest.respond_to?(:close)
+ }
+ @destinations.clear
+ # We need to make sure we always end up with some kind of destination
+ begin
+ types.each { |type|
+ Log.newdestination(type)
+ }
+ rescue => detail
+ if @destinations.empty?
+ Log.newdestination(:syslog)
+ Puppet.err detail.to_s
+ end
end
+ end
- attr_accessor :time, :remote, :file, :line, :version, :source
- attr_reader :level, :message
-
- def initialize(args)
- self.level = args[:level]
- self.message = args[:message]
- self.source = args[:source] || "Puppet"
-
- @time = Time.now
+ # Is the passed level a valid log level?
+ def self.validlevel?(level)
+ @levels.include?(level)
+ end
- if tags = args[:tags]
- tags.each { |t| self.tag(t) }
- end
+ attr_accessor :time, :remote, :file, :line, :version, :source
+ attr_reader :level, :message
- [:file, :line, :version].each do |attr|
- next unless value = args[attr]
- send(attr.to_s + "=", value)
- end
+ def initialize(args)
+ self.level = args[:level]
+ self.message = args[:message]
+ self.source = args[:source] || "Puppet"
- Log.newmessage(self)
- end
+ @time = Time.now
- def message=(msg)
- raise ArgumentError, "Puppet::Util::Log requires a message" unless msg
- @message = msg.to_s
+ if tags = args[:tags]
+ tags.each { |t| self.tag(t) }
end
- def level=(level)
- raise ArgumentError, "Puppet::Util::Log requires a log level" unless level
- @level = level.to_sym
- raise ArgumentError, "Invalid log level #{@level}" unless self.class.validlevel?(@level)
-
- # Tag myself with my log level
- tag(level)
+ [:file, :line, :version].each do |attr|
+ next unless value = args[attr]
+ send(attr.to_s + "=", value)
end
- # If they pass a source in to us, we make sure it is a string, and
- # we retrieve any tags we can.
- def source=(source)
- if source.respond_to?(:source_descriptors)
- descriptors = source.source_descriptors
- @source = descriptors[:path]
-
- descriptors[:tags].each { |t| tag(t) }
-
- [:file, :line, :version].each do |param|
- next unless descriptors[param]
- send(param.to_s + "=", descriptors[param])
- end
- else
- @source = source.to_s
- end
+ Log.newmessage(self)
+ end
+
+ def message=(msg)
+ raise ArgumentError, "Puppet::Util::Log requires a message" unless msg
+ @message = msg.to_s
+ end
+
+ def level=(level)
+ raise ArgumentError, "Puppet::Util::Log requires a log level" unless level
+ @level = level.to_sym
+ raise ArgumentError, "Invalid log level #{@level}" unless self.class.validlevel?(@level)
+
+ # Tag myself with my log level
+ tag(level)
+ end
+
+ # If they pass a source in to us, we make sure it is a string, and
+ # we retrieve any tags we can.
+ def source=(source)
+ if source.respond_to?(:source_descriptors)
+ descriptors = source.source_descriptors
+ @source = descriptors[:path]
+
+ descriptors[:tags].each { |t| tag(t) }
+
+ [:file, :line, :version].each do |param|
+ next unless descriptors[param]
+ send(param.to_s + "=", descriptors[param])
+ end
+ else
+ @source = source.to_s
end
+ end
- def to_report
- "#{time} #{source} (#{level}): #{to_s}"
- end
+ def to_report
+ "#{time} #{source} (#{level}): #{to_s}"
+ end
- def to_s
- message
- end
+ def to_s
+ message
+ end
end
# This is for backward compatibility from when we changed the constant to Puppet::Util::Log
diff --git a/lib/puppet/util/log/destination.rb b/lib/puppet/util/log/destination.rb
index 35565b4..11ebd7d 100644
--- a/lib/puppet/util/log/destination.rb
+++ b/lib/puppet/util/log/destination.rb
@@ -1,49 +1,49 @@
# A type of log destination.
class Puppet::Util::Log::Destination
- class << self
- attr_accessor :name
+ class << self
+ attr_accessor :name
+ end
+
+ def self.initvars
+ @matches = []
+ end
+
+ # Mark the things we're supposed to match.
+ def self.match(obj)
+ @matches ||= []
+ @matches << obj
+ end
+
+ # See whether we match a given thing.
+ def self.match?(obj)
+ # Convert single-word strings into symbols like :console and :syslog
+ if obj.is_a? String and obj =~ /^\w+$/
+ obj = obj.downcase.intern
end
- def self.initvars
- @matches = []
+ @matches.each do |thing|
+ # Search for direct matches or class matches
+ return true if thing === obj or thing == obj.class.to_s
end
-
- # Mark the things we're supposed to match.
- def self.match(obj)
- @matches ||= []
- @matches << obj
- end
-
- # See whether we match a given thing.
- def self.match?(obj)
- # Convert single-word strings into symbols like :console and :syslog
- if obj.is_a? String and obj =~ /^\w+$/
- obj = obj.downcase.intern
- end
-
- @matches.each do |thing|
- # Search for direct matches or class matches
- return true if thing === obj or thing == obj.class.to_s
- end
- false
+ false
+ end
+
+ def name
+ if defined?(@name)
+ return @name
+ else
+ return self.class.name
end
+ end
- def name
- if defined?(@name)
- return @name
- else
- return self.class.name
- end
- end
+ # Set how to handle a message.
+ def self.sethandler(&block)
+ define_method(:handle, &block)
+ end
- # Set how to handle a message.
- def self.sethandler(&block)
- define_method(:handle, &block)
- end
-
- # Mark how to initialize our object.
- def self.setinit(&block)
- define_method(:initialize, &block)
- end
+ # Mark how to initialize our object.
+ def self.setinit(&block)
+ define_method(:initialize, &block)
+ end
end
diff --git a/lib/puppet/util/log/destinations.rb b/lib/puppet/util/log/destinations.rb
index 515568c..22b3ded 100644
--- a/lib/puppet/util/log/destinations.rb
+++ b/lib/puppet/util/log/destinations.rb
@@ -1,217 +1,217 @@
Puppet::Util::Log.newdesttype :syslog do
- def close
- Syslog.close
- end
-
- def initialize
- Syslog.close if Syslog.opened?
- name = Puppet[:name]
- name = "puppet-#{name}" unless name =~ /puppet/
-
- options = Syslog::LOG_PID | Syslog::LOG_NDELAY
-
- # XXX This should really be configurable.
- str = Puppet[:syslogfacility]
- begin
- facility = Syslog.const_get("LOG_#{str.upcase}")
- rescue NameError
- raise Puppet::Error, "Invalid syslog facility #{str}"
- end
-
- @syslog = Syslog.open(name, options, facility)
- end
-
- def handle(msg)
- # XXX Syslog currently has a bug that makes it so you
- # cannot log a message with a '%' in it. So, we get rid
- # of them.
- if msg.source == "Puppet"
- @syslog.send(msg.level, msg.to_s.gsub("%", '%%'))
- else
- @syslog.send(msg.level, "(%s) %s" % [msg.source.to_s.gsub("%", ""),
- msg.to_s.gsub("%", '%%')
- ]
- )
- end
- end
+ def close
+ Syslog.close
+ end
+
+ def initialize
+ Syslog.close if Syslog.opened?
+ name = Puppet[:name]
+ name = "puppet-#{name}" unless name =~ /puppet/
+
+ options = Syslog::LOG_PID | Syslog::LOG_NDELAY
+
+ # XXX This should really be configurable.
+ str = Puppet[:syslogfacility]
+ begin
+ facility = Syslog.const_get("LOG_#{str.upcase}")
+ rescue NameError
+ raise Puppet::Error, "Invalid syslog facility #{str}"
+ end
+
+ @syslog = Syslog.open(name, options, facility)
+ end
+
+ def handle(msg)
+ # XXX Syslog currently has a bug that makes it so you
+ # cannot log a message with a '%' in it. So, we get rid
+ # of them.
+ if msg.source == "Puppet"
+ @syslog.send(msg.level, msg.to_s.gsub("%", '%%'))
+ else
+ @syslog.send(msg.level, "(%s) %s" % [msg.source.to_s.gsub("%", ""),
+ msg.to_s.gsub("%", '%%')
+ ]
+ )
+ end
+ end
end
Puppet::Util::Log.newdesttype :file do
- match(/^\//)
+ match(/^\//)
- def close
- if defined?(@file)
- @file.close
- @file = nil
- end
+ def close
+ if defined?(@file)
+ @file.close
+ @file = nil
end
+ end
- def flush
- @file.flush if defined?(@file)
- end
+ def flush
+ @file.flush if defined?(@file)
+ end
- def initialize(path)
- @name = path
- # first make sure the directory exists
- # We can't just use 'Config.use' here, because they've
- # specified a "special" destination.
- unless FileTest.exist?(File.dirname(path))
- Puppet.recmkdir(File.dirname(path))
- Puppet.info "Creating log directory #{File.dirname(path)}"
- end
+ def initialize(path)
+ @name = path
+ # first make sure the directory exists
+ # We can't just use 'Config.use' here, because they've
+ # specified a "special" destination.
+ unless FileTest.exist?(File.dirname(path))
+ Puppet.recmkdir(File.dirname(path))
+ Puppet.info "Creating log directory #{File.dirname(path)}"
+ end
- # create the log file, if it doesn't already exist
- file = File.open(path, File::WRONLY|File::CREAT|File::APPEND)
+ # create the log file, if it doesn't already exist
+ file = File.open(path, File::WRONLY|File::CREAT|File::APPEND)
- @file = file
+ @file = file
- @autoflush = Puppet[:autoflush]
- end
+ @autoflush = Puppet[:autoflush]
+ end
- def handle(msg)
- @file.puts("#{msg.time} #{msg.source} (#{msg.level}): #{msg}")
+ def handle(msg)
+ @file.puts("#{msg.time} #{msg.source} (#{msg.level}): #{msg}")
- @file.flush if @autoflush
- end
+ @file.flush if @autoflush
+ end
end
Puppet::Util::Log.newdesttype :console do
- RED = {:console => "[0;31m", :html => "FFA0A0"}
- GREEN = {:console => "[0;32m", :html => "00CD00"}
- YELLOW = {:console => "[0;33m", :html => "FFFF60"}
- BLUE = {:console => "[0;34m", :html => "80A0FF"}
- PURPLE = {:console => "[0;35m", :html => "FFA500"}
- CYAN = {:console => "[0;36m", :html => "40FFFF"}
- WHITE = {:console => "[0;37m", :html => "FFFFFF"}
- HRED = {:console => "[1;31m", :html => "FFA0A0"}
- HGREEN = {:console => "[1;32m", :html => "00CD00"}
- HYELLOW = {:console => "[1;33m", :html => "FFFF60"}
- HBLUE = {:console => "[1;34m", :html => "80A0FF"}
- HPURPLE = {:console => "[1;35m", :html => "FFA500"}
- HCYAN = {:console => "[1;36m", :html => "40FFFF"}
- HWHITE = {:console => "[1;37m", :html => "FFFFFF"}
- RESET = {:console => "[0m", :html => "" }
-
- @@colormap = {
- :debug => WHITE,
- :info => GREEN,
- :notice => CYAN,
- :warning => YELLOW,
- :err => HPURPLE,
- :alert => RED,
- :emerg => HRED,
- :crit => HRED
- }
-
- def colorize(level, str)
- case Puppet[:color]
- when true, :ansi, "ansi", "yes"; console_color(level, str)
- when :html, "html"; html_color(level, str)
- else
- str
- end
- end
-
- def console_color(level, str)
- @@colormap[level][:console] + str + RESET[:console]
- end
-
- def html_color(level, str)
- %{<span style="color: %s">%s</span>} % [@@colormap[level][:html], str]
- end
-
- def initialize
- # Flush output immediately.
- $stdout.sync = true
- end
-
- def handle(msg)
- if msg.source == "Puppet"
- puts colorize(msg.level, "#{msg.level}: #{msg}")
- else
- puts colorize(msg.level, "#{msg.level}: #{msg.source}: #{msg}")
- end
- end
+ RED = {:console => "[0;31m", :html => "FFA0A0"}
+ GREEN = {:console => "[0;32m", :html => "00CD00"}
+ YELLOW = {:console => "[0;33m", :html => "FFFF60"}
+ BLUE = {:console => "[0;34m", :html => "80A0FF"}
+ PURPLE = {:console => "[0;35m", :html => "FFA500"}
+ CYAN = {:console => "[0;36m", :html => "40FFFF"}
+ WHITE = {:console => "[0;37m", :html => "FFFFFF"}
+ HRED = {:console => "[1;31m", :html => "FFA0A0"}
+ HGREEN = {:console => "[1;32m", :html => "00CD00"}
+ HYELLOW = {:console => "[1;33m", :html => "FFFF60"}
+ HBLUE = {:console => "[1;34m", :html => "80A0FF"}
+ HPURPLE = {:console => "[1;35m", :html => "FFA500"}
+ HCYAN = {:console => "[1;36m", :html => "40FFFF"}
+ HWHITE = {:console => "[1;37m", :html => "FFFFFF"}
+ RESET = {:console => "[0m", :html => "" }
+
+ @@colormap = {
+ :debug => WHITE,
+ :info => GREEN,
+ :notice => CYAN,
+ :warning => YELLOW,
+ :err => HPURPLE,
+ :alert => RED,
+ :emerg => HRED,
+ :crit => HRED
+ }
+
+ def colorize(level, str)
+ case Puppet[:color]
+ when true, :ansi, "ansi", "yes"; console_color(level, str)
+ when :html, "html"; html_color(level, str)
+ else
+ str
+ end
+ end
+
+ def console_color(level, str)
+ @@colormap[level][:console] + str + RESET[:console]
+ end
+
+ def html_color(level, str)
+ %{<span style="color: %s">%s</span>} % [@@colormap[level][:html], str]
+ end
+
+ def initialize
+ # Flush output immediately.
+ $stdout.sync = true
+ end
+
+ def handle(msg)
+ if msg.source == "Puppet"
+ puts colorize(msg.level, "#{msg.level}: #{msg}")
+ else
+ puts colorize(msg.level, "#{msg.level}: #{msg.source}: #{msg}")
+ end
+ end
end
Puppet::Util::Log.newdesttype :host do
- def initialize(host)
- Puppet.info "Treating #{host} as a hostname"
- args = {}
- if host =~ /:(\d+)/
- args[:Port] = $1
- args[:Server] = host.sub(/:\d+/, '')
- else
- args[:Server] = host
- end
-
- @name = host
-
- @driver = Puppet::Network::Client::LogClient.new(args)
- end
-
- def handle(msg)
- unless msg.is_a?(String) or msg.remote
- @hostname ||= Facter["hostname"].value
- unless defined?(@domain)
- @domain = Facter["domain"].value
- @hostname += ".#{@domain}" if @domain
- end
- if msg.source =~ /^\//
- msg.source = @hostname + ":#{msg.source}"
- elsif msg.source == "Puppet"
- msg.source = @hostname + " #{msg.source}"
- else
- msg.source = @hostname + " #{msg.source}"
- end
- begin
- #puts "would have sent #{msg}"
- #puts "would have sent %s" %
- # CGI.escape(YAML.dump(msg))
- begin
- tmp = CGI.escape(YAML.dump(msg))
- rescue => detail
- puts "Could not dump: #{detail}"
- return
- end
- # Add the hostname to the source
- @driver.addlog(tmp)
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err detail
- Puppet::Util::Log.close(self)
- end
+ def initialize(host)
+ Puppet.info "Treating #{host} as a hostname"
+ args = {}
+ if host =~ /:(\d+)/
+ args[:Port] = $1
+ args[:Server] = host.sub(/:\d+/, '')
+ else
+ args[:Server] = host
+ end
+
+ @name = host
+
+ @driver = Puppet::Network::Client::LogClient.new(args)
+ end
+
+ def handle(msg)
+ unless msg.is_a?(String) or msg.remote
+ @hostname ||= Facter["hostname"].value
+ unless defined?(@domain)
+ @domain = Facter["domain"].value
+ @hostname += ".#{@domain}" if @domain
+ end
+ if msg.source =~ /^\//
+ msg.source = @hostname + ":#{msg.source}"
+ elsif msg.source == "Puppet"
+ msg.source = @hostname + " #{msg.source}"
+ else
+ msg.source = @hostname + " #{msg.source}"
+ end
+ begin
+ #puts "would have sent #{msg}"
+ #puts "would have sent %s" %
+ # CGI.escape(YAML.dump(msg))
+ begin
+ tmp = CGI.escape(YAML.dump(msg))
+ rescue => detail
+ puts "Could not dump: #{detail}"
+ return
end
- end
+ # Add the hostname to the source
+ @driver.addlog(tmp)
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err detail
+ Puppet::Util::Log.close(self)
+ end
+ end
+ end
end
# Log to a transaction report.
Puppet::Util::Log.newdesttype :report do
- attr_reader :report
+ attr_reader :report
- match "Puppet::Transaction::Report"
+ match "Puppet::Transaction::Report"
- def initialize(report)
- @report = report
- end
+ def initialize(report)
+ @report = report
+ end
- def handle(msg)
- @report << msg
- end
+ def handle(msg)
+ @report << msg
+ end
end
# Log to an array, just for testing.
Puppet::Util::Log.newdesttype :array do
- match "Array"
+ match "Array"
- def initialize(messages)
- @messages = messages
- end
+ def initialize(messages)
+ @messages = messages
+ end
- def handle(msg)
- @messages << msg
- end
+ def handle(msg)
+ @messages << msg
+ end
end
diff --git a/lib/puppet/util/log_paths.rb b/lib/puppet/util/log_paths.rb
index e09ceb7..f59197e 100644
--- a/lib/puppet/util/log_paths.rb
+++ b/lib/puppet/util/log_paths.rb
@@ -2,26 +2,26 @@
# Copyright (c) 2007. All rights reserved.
module Puppet::Util::LogPaths
- # return the full path to us, for logging and rollback
- # some classes (e.g., FileTypeRecords) will have to override this
- def path
- @path ||= pathbuilder
+ # return the full path to us, for logging and rollback
+ # some classes (e.g., FileTypeRecords) will have to override this
+ def path
+ @path ||= pathbuilder
- "/" + @path.join("/")
- end
-
- def source_descriptors
- descriptors = {}
+ "/" + @path.join("/")
+ end
- descriptors[:tags] = tags
+ def source_descriptors
+ descriptors = {}
- [:path, :file, :line, :version].each do |param|
- next unless value = send(param)
- descriptors[param] = value
- end
+ descriptors[:tags] = tags
- descriptors
+ [:path, :file, :line, :version].each do |param|
+ next unless value = send(param)
+ descriptors[param] = value
end
+ descriptors
+ end
+
end
diff --git a/lib/puppet/util/logging.rb b/lib/puppet/util/logging.rb
index b4a531b..f20444a 100644
--- a/lib/puppet/util/logging.rb
+++ b/lib/puppet/util/logging.rb
@@ -3,38 +3,38 @@ require 'puppet/util/log'
module Puppet::Util::Logging
- def send_log(level, message)
- Puppet::Util::Log.create({:level => level, :source => log_source, :message => message}.merge(log_metadata))
+ def send_log(level, message)
+ Puppet::Util::Log.create({:level => level, :source => log_source, :message => message}.merge(log_metadata))
+ end
+
+ # Create a method for each log level.
+ Puppet::Util::Log.eachlevel do |level|
+ define_method(level) do |args|
+ args = args.join(" ") if args.is_a?(Array)
+ send_log(level, args)
end
+ end
- # Create a method for each log level.
- Puppet::Util::Log.eachlevel do |level|
- define_method(level) do |args|
- args = args.join(" ") if args.is_a?(Array)
- send_log(level, args)
- end
- end
+ private
- private
+ def is_resource?
+ defined?(Puppet::Type) && is_a?(Puppet::Type)
+ end
- def is_resource?
- defined?(Puppet::Type) && is_a?(Puppet::Type)
- end
+ def is_resource_parameter?
+ defined?(Puppet::Parameter) && is_a?(Puppet::Parameter)
+ end
- def is_resource_parameter?
- defined?(Puppet::Parameter) && is_a?(Puppet::Parameter)
+ def log_metadata
+ [:file, :line, :version, :tags].inject({}) do |result, attr|
+ result[attr] = send(attr) if respond_to?(attr)
+ result
end
+ end
- def log_metadata
- [:file, :line, :version, :tags].inject({}) do |result, attr|
- result[attr] = send(attr) if respond_to?(attr)
- result
- end
- end
-
- def log_source
- # We need to guard the existence of the constants, since this module is used by the base Puppet module.
- (is_resource? or is_resource_parameter?) and respond_to?(:path) and return path.to_s
- to_s
- end
+ def log_source
+ # We need to guard the existence of the constants, since this module is used by the base Puppet module.
+ (is_resource? or is_resource_parameter?) and respond_to?(:path) and return path.to_s
+ to_s
+ end
end
diff --git a/lib/puppet/util/metaid.rb b/lib/puppet/util/metaid.rb
index 076775c..4092e4f 100644
--- a/lib/puppet/util/metaid.rb
+++ b/lib/puppet/util/metaid.rb
@@ -1,21 +1,21 @@
class Object
- # The hidden singleton lurks behind everyone
- def singleton_class; class << self; self; end; end
- def meta_eval(&blk); singleton_class.instance_eval(&blk); end
+ # The hidden singleton lurks behind everyone
+ def singleton_class; class << self; self; end; end
+ def meta_eval(&blk); singleton_class.instance_eval(&blk); end
- # Adds methods to a singleton_class
- def meta_def(name, &blk)
- meta_eval { define_method name, &blk }
- end
+ # Adds methods to a singleton_class
+ def meta_def(name, &blk)
+ meta_eval { define_method name, &blk }
+ end
- # Remove singleton_class methods.
- def meta_undef(name, &blk)
- meta_eval { remove_method name }
- end
+ # Remove singleton_class methods.
+ def meta_undef(name, &blk)
+ meta_eval { remove_method name }
+ end
- # Defines an instance method within a class
- def class_def(name, &blk)
- class_eval { define_method name, &blk }
- end
+ # Defines an instance method within a class
+ def class_def(name, &blk)
+ class_eval { define_method name, &blk }
+ end
end
diff --git a/lib/puppet/util/methodhelper.rb b/lib/puppet/util/methodhelper.rb
index f8dc2ce..2dd3afd 100644
--- a/lib/puppet/util/methodhelper.rb
+++ b/lib/puppet/util/methodhelper.rb
@@ -1,32 +1,32 @@
# Where we store helper methods related to, um, methods.
module Puppet::Util::MethodHelper
- def requiredopts(*names)
- names.each do |name|
- devfail("#{name} is a required option for #{self.class}") if self.send(name).nil?
- end
+ def requiredopts(*names)
+ names.each do |name|
+ devfail("#{name} is a required option for #{self.class}") if self.send(name).nil?
end
+ end
- # Iterate over a hash, treating each member as an attribute.
- def set_options(options)
- options.each do |param,value|
- method = param.to_s + "="
- if respond_to? method
- self.send(method, value)
- else
- raise ArgumentError, "Invalid parameter #{param} to object class #{self.class}"
- end
- end
+ # Iterate over a hash, treating each member as an attribute.
+ def set_options(options)
+ options.each do |param,value|
+ method = param.to_s + "="
+ if respond_to? method
+ self.send(method, value)
+ else
+ raise ArgumentError, "Invalid parameter #{param} to object class #{self.class}"
+ end
end
+ end
- # Take a hash and convert all of the keys to symbols if possible.
- def symbolize_options(options)
- options.inject({}) do |hash, opts|
- if opts[0].respond_to? :intern
- hash[opts[0].intern] = opts[1]
- else
- hash[opts[0]] = opts[1]
- end
- hash
- end
+ # Take a hash and convert all of the keys to symbols if possible.
+ def symbolize_options(options)
+ options.inject({}) do |hash, opts|
+ if opts[0].respond_to? :intern
+ hash[opts[0].intern] = opts[1]
+ else
+ hash[opts[0]] = opts[1]
+ end
+ hash
end
+ end
end
diff --git a/lib/puppet/util/metric.rb b/lib/puppet/util/metric.rb
index eb25d77..7e14a5f 100644
--- a/lib/puppet/util/metric.rb
+++ b/lib/puppet/util/metric.rb
@@ -4,152 +4,152 @@ require 'puppet'
# A class for handling metrics. This is currently ridiculously hackish.
class Puppet::Util::Metric
- attr_accessor :type, :name, :value, :label
- attr_writer :values
-
- attr_writer :basedir
-
- # Return a specific value
- def [](name)
- if value = @values.find { |v| v[0] == name }
- return value[2]
- else
- return 0
- end
+ attr_accessor :type, :name, :value, :label
+ attr_writer :values
+
+ attr_writer :basedir
+
+ # Return a specific value
+ def [](name)
+ if value = @values.find { |v| v[0] == name }
+ return value[2]
+ else
+ return 0
end
+ end
- def basedir
- if defined?(@basedir)
- @basedir
- else
- Puppet[:rrddir]
- end
+ def basedir
+ if defined?(@basedir)
+ @basedir
+ else
+ Puppet[:rrddir]
end
+ end
- def create(start = nil)
- Puppet.settings.use(:main, :metrics)
+ def create(start = nil)
+ Puppet.settings.use(:main, :metrics)
- start ||= Time.now.to_i - 5
+ start ||= Time.now.to_i - 5
- @rrd = RRDtool.new(self.path)
- args = []
+ @rrd = RRDtool.new(self.path)
+ args = []
- values.each { |value|
- # the 7200 is the heartbeat -- this means that any data that isn't
- # more frequently than every two hours gets thrown away
- args.push "DS:#{value[0]}:GAUGE:7200:U:U"
- }
- args.push "RRA:AVERAGE:0.5:1:300"
+ values.each { |value|
+ # the 7200 is the heartbeat -- this means that any data that isn't
+ # more frequently than every two hours gets thrown away
+ args.push "DS:#{value[0]}:GAUGE:7200:U:U"
+ }
+ args.push "RRA:AVERAGE:0.5:1:300"
- begin
- @rrd.create( Puppet[:rrdinterval].to_i, start, args)
- rescue => detail
- raise "Could not create RRD file #{path}: #{detail}"
- end
+ begin
+ @rrd.create( Puppet[:rrdinterval].to_i, start, args)
+ rescue => detail
+ raise "Could not create RRD file #{path}: #{detail}"
end
+ end
+
+ def dump
+ puts @rrd.info
+ end
- def dump
- puts @rrd.info
+ def graph(range = nil)
+ unless Puppet.features.rrd?
+ Puppet.warning "RRD library is missing; cannot graph metrics"
+ return
end
- def graph(range = nil)
- unless Puppet.features.rrd?
- Puppet.warning "RRD library is missing; cannot graph metrics"
- return
- end
-
- unit = 60 * 60 * 24
- colorstack = %w{#00ff00 #ff0000 #0000ff #ffff00 #ff99ff #ff9966 #66ffff #990000 #099000 #000990 #f00990 #0f0f0f #555555 #333333 #ffffff}
-
- {:daily => unit, :weekly => unit * 7, :monthly => unit * 30, :yearly => unit * 365}.each do |name, time|
- file = self.path.sub(/\.rrd$/, "-#{name}.png")
- args = [file]
-
- args.push("--title",self.label)
- args.push("--imgformat","PNG")
- args.push("--interlace")
- i = 0
- defs = []
- lines = []
- #p @values.collect { |s,l| s }
- values.zip(colorstack).each { |value,color|
- next if value.nil?
- # this actually uses the data label
- defs.push("DEF:#{value[0]}=#{self.path}:#{value[0]}:AVERAGE")
- lines.push("LINE2:#{value[0]}#{color}:#{value[1]}")
- }
- args << defs
- args << lines
- args.flatten!
- if range
- args.push("--start",range[0],"--end",range[1])
- else
- args.push("--start", Time.now.to_i - time, "--end", Time.now.to_i)
- end
-
- begin
- #Puppet.warning "args = #{args}"
- RRDtool.graph( args )
- rescue => detail
- Puppet.err "Failed to graph #{self.name}: #{detail}"
- end
- end
+ unit = 60 * 60 * 24
+ colorstack = %w{#00ff00 #ff0000 #0000ff #ffff00 #ff99ff #ff9966 #66ffff #990000 #099000 #000990 #f00990 #0f0f0f #555555 #333333 #ffffff}
+
+ {:daily => unit, :weekly => unit * 7, :monthly => unit * 30, :yearly => unit * 365}.each do |name, time|
+ file = self.path.sub(/\.rrd$/, "-#{name}.png")
+ args = [file]
+
+ args.push("--title",self.label)
+ args.push("--imgformat","PNG")
+ args.push("--interlace")
+ i = 0
+ defs = []
+ lines = []
+ #p @values.collect { |s,l| s }
+ values.zip(colorstack).each { |value,color|
+ next if value.nil?
+ # this actually uses the data label
+ defs.push("DEF:#{value[0]}=#{self.path}:#{value[0]}:AVERAGE")
+ lines.push("LINE2:#{value[0]}#{color}:#{value[1]}")
+ }
+ args << defs
+ args << lines
+ args.flatten!
+ if range
+ args.push("--start",range[0],"--end",range[1])
+ else
+ args.push("--start", Time.now.to_i - time, "--end", Time.now.to_i)
+ end
+
+ begin
+ #Puppet.warning "args = #{args}"
+ RRDtool.graph( args )
+ rescue => detail
+ Puppet.err "Failed to graph #{self.name}: #{detail}"
+ end
end
+ end
- def initialize(name,label = nil)
- @name = name.to_s
+ def initialize(name,label = nil)
+ @name = name.to_s
- @label = label || labelize(name)
+ @label = label || labelize(name)
- @values = []
- end
+ @values = []
+ end
- def path
- File.join(self.basedir, @name + ".rrd")
- end
+ def path
+ File.join(self.basedir, @name + ".rrd")
+ end
- def newvalue(name,value,label = nil)
- label ||= labelize(name)
- @values.push [name,label,value]
- end
+ def newvalue(name,value,label = nil)
+ label ||= labelize(name)
+ @values.push [name,label,value]
+ end
- def store(time)
- unless Puppet.features.rrd?
- Puppet.warning "RRD library is missing; cannot store metrics"
- return
- end
- self.create(time - 5) unless FileTest.exists?(self.path)
-
- @rrd ||= RRDtool.new(self.path)
-
- # XXX this is not terribly error-resistant
- args = [time]
- temps = []
- values.each { |value|
- #Puppet.warning "value[0]: #{value[0]}; value[1]: #{value[1]}; value[2]: #{value[2]}; "
- args.push value[2]
- temps.push value[0]
- }
- arg = args.join(":")
- template = temps.join(":")
- begin
- @rrd.update( template, [ arg ] )
- #system("rrdtool updatev #{self.path} '#{arg}'")
- rescue => detail
- raise Puppet::Error, "Failed to update #{self.name}: #{detail}"
- end
+ def store(time)
+ unless Puppet.features.rrd?
+ Puppet.warning "RRD library is missing; cannot store metrics"
+ return
end
-
- def values
- @values.sort { |a, b| a[1] <=> b[1] }
+ self.create(time - 5) unless FileTest.exists?(self.path)
+
+ @rrd ||= RRDtool.new(self.path)
+
+ # XXX this is not terribly error-resistant
+ args = [time]
+ temps = []
+ values.each { |value|
+ #Puppet.warning "value[0]: #{value[0]}; value[1]: #{value[1]}; value[2]: #{value[2]}; "
+ args.push value[2]
+ temps.push value[0]
+ }
+ arg = args.join(":")
+ template = temps.join(":")
+ begin
+ @rrd.update( template, [ arg ] )
+ #system("rrdtool updatev #{self.path} '#{arg}'")
+ rescue => detail
+ raise Puppet::Error, "Failed to update #{self.name}: #{detail}"
end
+ end
- private
+ def values
+ @values.sort { |a, b| a[1] <=> b[1] }
+ end
- # Convert a name into a label.
- def labelize(name)
- name.to_s.capitalize.gsub("_", " ")
- end
+ private
+
+ # Convert a name into a label.
+ def labelize(name)
+ name.to_s.capitalize.gsub("_", " ")
+ end
end
# This is necessary because we changed the class path in early 2007,
diff --git a/lib/puppet/util/monkey_patches.rb b/lib/puppet/util/monkey_patches.rb
index e5e835e..e035afd 100644
--- a/lib/puppet/util/monkey_patches.rb
+++ b/lib/puppet/util/monkey_patches.rb
@@ -1,12 +1,12 @@
Process.maxgroups = 1024
module RDoc
- def self.caller(skip=nil)
- in_gem_wrapper = false
- Kernel.caller.reject { |call|
- in_gem_wrapper ||= call =~ /#{Regexp.escape $0}:\d+:in `load'/
- }
- end
+ def self.caller(skip=nil)
+ in_gem_wrapper = false
+ Kernel.caller.reject { |call|
+ in_gem_wrapper ||= call =~ /#{Regexp.escape $0}:\d+:in `load'/
+ }
+ end
end
@@ -14,22 +14,22 @@ require "yaml"
require "puppet/util/zaml.rb"
class Symbol
- def to_zaml(z)
- z.emit("!ruby/sym ")
- to_s.to_zaml(z)
- end
+ def to_zaml(z)
+ z.emit("!ruby/sym ")
+ to_s.to_zaml(z)
+ end
end
[Object, Exception, Integer, Struct, Date, Time, Range, Regexp, Hash, Array, Float, String, FalseClass, TrueClass, Symbol, NilClass, Class].each { |cls|
- cls.class_eval do
- def to_yaml
- ZAML.dump(self)
- end
+ cls.class_eval do
+ def to_yaml
+ ZAML.dump(self)
end
+ end
}
def YAML.dump(*args)
- ZAML.dump(*args)
+ ZAML.dump(*args)
end
#
@@ -38,10 +38,10 @@ end
# for details
#
if RUBY_VERSION == '1.8.7'
- class NilClass
- def closed?
- true
- end
+ class NilClass
+ def closed?
+ true
end
+ end
end
diff --git a/lib/puppet/util/nagios_maker.rb b/lib/puppet/util/nagios_maker.rb
index e824b1d..59ed820 100644
--- a/lib/puppet/util/nagios_maker.rb
+++ b/lib/puppet/util/nagios_maker.rb
@@ -3,59 +3,59 @@ require 'puppet/external/nagios/base'
require 'puppet/provider/naginator'
module Puppet::Util::NagiosMaker
- # Create a new nagios type, using all of the parameters
- # from the parser.
- def self.create_nagios_type(name)
- name = name.to_sym
- full_name = ("nagios_#{name}").to_sym
+ # Create a new nagios type, using all of the parameters
+ # from the parser.
+ def self.create_nagios_type(name)
+ name = name.to_sym
+ full_name = ("nagios_#{name}").to_sym
- raise(Puppet::DevError, "No nagios type for #{name}") unless nagtype = Nagios::Base.type(name)
+ raise(Puppet::DevError, "No nagios type for #{name}") unless nagtype = Nagios::Base.type(name)
- type = Puppet::Type.newtype(full_name) {}
+ type = Puppet::Type.newtype(full_name) {}
- type.ensurable
+ type.ensurable
- type.newparam(nagtype.namevar, :namevar => true) do
- desc "The name parameter for Nagios type #{nagtype.name}"
- end
+ type.newparam(nagtype.namevar, :namevar => true) do
+ desc "The name parameter for Nagios type #{nagtype.name}"
+ end
- # We deduplicate the parameters because it makes sense to allow Naginator to have dupes.
- nagtype.parameters.uniq.each do |param|
- next if param == nagtype.namevar
+ # We deduplicate the parameters because it makes sense to allow Naginator to have dupes.
+ nagtype.parameters.uniq.each do |param|
+ next if param == nagtype.namevar
- # We can't turn these parameter names into constants, so at least for now they aren't
- # supported.
- next if param.to_s =~ /^[0-9]/
+ # We can't turn these parameter names into constants, so at least for now they aren't
+ # supported.
+ next if param.to_s =~ /^[0-9]/
- type.newproperty(param) do
- desc "Nagios configuration file parameter."
- end
- end
+ type.newproperty(param) do
+ desc "Nagios configuration file parameter."
+ end
+ end
- type.newproperty(:target) do
- desc 'target'
+ type.newproperty(:target) do
+ desc 'target'
- defaultto do
- resource.class.defaultprovider.default_target
- end
- end
+ defaultto do
+ resource.class.defaultprovider.default_target
+ end
+ end
- target = "/etc/nagios/#{full_name.to_s}.cfg"
- provider = type.provide(:naginator, :parent => Puppet::Provider::Naginator, :default_target => target) {}
- provider.nagios_type
+ target = "/etc/nagios/#{full_name.to_s}.cfg"
+ provider = type.provide(:naginator, :parent => Puppet::Provider::Naginator, :default_target => target) {}
+ provider.nagios_type
- type.desc "The Nagios type #{name.to_s}. This resource type is autogenerated using the
- model developed in Naginator_, and all of the Nagios types are generated using the
- same code and the same library.
+ type.desc "The Nagios type #{name.to_s}. This resource type is autogenerated using the
+ model developed in Naginator_, and all of the Nagios types are generated using the
+ same code and the same library.
- This type generates Nagios configuration statements in Nagios-parseable configuration
- files. By default, the statements will be added to ``#{target}``, but
- you can send them to a different file by setting their ``target`` attribute.
+ This type generates Nagios configuration statements in Nagios-parseable configuration
+ files. By default, the statements will be added to ``#{target}``, but
+ you can send them to a different file by setting their ``target`` attribute.
- You can purge Nagios resources using the ``resources`` type, but *only*
- in the default file locations. This is an architectural limitation.
+ You can purge Nagios resources using the ``resources`` type, but *only*
+ in the default file locations. This is an architectural limitation.
- .. _naginator: http://projects.reductivelabs.com/projects/naginator
- "
- end
+ .. _naginator: http://projects.reductivelabs.com/projects/naginator
+ "
+ end
end
diff --git a/lib/puppet/util/package.rb b/lib/puppet/util/package.rb
index ecac778..5f1fc74 100644
--- a/lib/puppet/util/package.rb
+++ b/lib/puppet/util/package.rb
@@ -1,31 +1,31 @@
module Puppet::Util::Package
- def versioncmp(version_a, version_b)
- vre = /[-.]|\d+|[^-.\d]+/
- ax = version_a.scan(vre)
- bx = version_b.scan(vre)
+ def versioncmp(version_a, version_b)
+ vre = /[-.]|\d+|[^-.\d]+/
+ ax = version_a.scan(vre)
+ bx = version_b.scan(vre)
- while (ax.length>0 && bx.length>0)
- a = ax.shift
- b = bx.shift
+ while (ax.length>0 && bx.length>0)
+ a = ax.shift
+ b = bx.shift
- if( a == b ) then next
- elsif (a == '-' && b == '-') then next
- elsif (a == '-') then return -1
- elsif (b == '-') then return 1
- elsif (a == '.' && b == '.') then next
- elsif (a == '.' ) then return -1
- elsif (b == '.' ) then return 1
- elsif (a =~ /^\d+$/ && b =~ /^\d+$/) then
- if( a =~ /^0/ or b =~ /^0/ ) then
- return a.to_s.upcase <=> b.to_s.upcase
- end
- return a.to_i <=> b.to_i
- else
- return a.upcase <=> b.upcase
- end
+ if( a == b ) then next
+ elsif (a == '-' && b == '-') then next
+ elsif (a == '-') then return -1
+ elsif (b == '-') then return 1
+ elsif (a == '.' && b == '.') then next
+ elsif (a == '.' ) then return -1
+ elsif (b == '.' ) then return 1
+ elsif (a =~ /^\d+$/ && b =~ /^\d+$/) then
+ if( a =~ /^0/ or b =~ /^0/ ) then
+ return a.to_s.upcase <=> b.to_s.upcase
end
- version_a <=> version_b;
+ return a.to_i <=> b.to_i
+ else
+ return a.upcase <=> b.upcase
+ end
end
+ version_a <=> version_b;
+ end
- module_function :versioncmp
+ module_function :versioncmp
end
diff --git a/lib/puppet/util/pidlock.rb b/lib/puppet/util/pidlock.rb
index d24b837..05e1459 100644
--- a/lib/puppet/util/pidlock.rb
+++ b/lib/puppet/util/pidlock.rb
@@ -1,68 +1,68 @@
require 'fileutils'
class Puppet::Util::Pidlock
- attr_reader :lockfile
+ attr_reader :lockfile
- def initialize(lockfile)
- @lockfile = lockfile
- end
+ def initialize(lockfile)
+ @lockfile = lockfile
+ end
- def locked?
- clear_if_stale
- File.exists? @lockfile
- end
+ def locked?
+ clear_if_stale
+ File.exists? @lockfile
+ end
- def mine?
- Process.pid == lock_pid
- end
+ def mine?
+ Process.pid == lock_pid
+ end
- def anonymous?
- return false unless File.exists?(@lockfile)
- File.read(@lockfile) == ""
- end
+ def anonymous?
+ return false unless File.exists?(@lockfile)
+ File.read(@lockfile) == ""
+ end
- def lock(opts = {})
- opts = {:anonymous => false}.merge(opts)
+ def lock(opts = {})
+ opts = {:anonymous => false}.merge(opts)
- if locked?
- mine?
- else
- if opts[:anonymous]
- File.open(@lockfile, 'w') { |fd| true }
- else
- File.open(@lockfile, "w") { |fd| fd.write(Process.pid) }
- end
- true
- end
+ if locked?
+ mine?
+ else
+ if opts[:anonymous]
+ File.open(@lockfile, 'w') { |fd| true }
+ else
+ File.open(@lockfile, "w") { |fd| fd.write(Process.pid) }
+ end
+ true
end
+ end
- def unlock(opts = {})
- opts = {:anonymous => false}.merge(opts)
+ def unlock(opts = {})
+ opts = {:anonymous => false}.merge(opts)
- if mine? or (opts[:anonymous] and anonymous?)
- File.unlink(@lockfile)
- true
- else
- false
- end
+ if mine? or (opts[:anonymous] and anonymous?)
+ File.unlink(@lockfile)
+ true
+ else
+ false
end
+ end
- private
- def lock_pid
- if File.exists? @lockfile
- File.read(@lockfile).to_i
- else
- nil
- end
+ private
+ def lock_pid
+ if File.exists? @lockfile
+ File.read(@lockfile).to_i
+ else
+ nil
end
+ end
- def clear_if_stale
- return if lock_pid.nil?
+ def clear_if_stale
+ return if lock_pid.nil?
- begin
- Process.kill(0, lock_pid)
- rescue Errno::ESRCH
- File.unlink(@lockfile)
- end
+ begin
+ Process.kill(0, lock_pid)
+ rescue Errno::ESRCH
+ File.unlink(@lockfile)
end
+ end
end
diff --git a/lib/puppet/util/posix.rb b/lib/puppet/util/posix.rb
index 6bb94b0..4cabe24 100755
--- a/lib/puppet/util/posix.rb
+++ b/lib/puppet/util/posix.rb
@@ -1,137 +1,137 @@
# Utility methods for interacting with POSIX objects; mostly user and group
module Puppet::Util::POSIX
- # Retrieve a field from a POSIX Etc object. The id can be either an integer
- # or a name. This only works for users and groups. It's also broken on
- # some platforms, unfortunately, which is why we fall back to the other
- # method search_posix_field in the gid and uid methods if a sanity check
- # fails
- def get_posix_field(space, field, id)
- raise Puppet::DevError, "Did not get id from caller" unless id
+ # Retrieve a field from a POSIX Etc object. The id can be either an integer
+ # or a name. This only works for users and groups. It's also broken on
+ # some platforms, unfortunately, which is why we fall back to the other
+ # method search_posix_field in the gid and uid methods if a sanity check
+ # fails
+ def get_posix_field(space, field, id)
+ raise Puppet::DevError, "Did not get id from caller" unless id
- if id.is_a?(Integer)
- if id > Puppet[:maximum_uid].to_i
- Puppet.err "Tried to get #{field} field for silly id #{id}"
- return nil
- end
- method = methodbyid(space)
- else
- method = methodbyname(space)
- end
+ if id.is_a?(Integer)
+ if id > Puppet[:maximum_uid].to_i
+ Puppet.err "Tried to get #{field} field for silly id #{id}"
+ return nil
+ end
+ method = methodbyid(space)
+ else
+ method = methodbyname(space)
+ end
- begin
- return Etc.send(method, id).send(field)
- rescue ArgumentError => detail
- # ignore it; we couldn't find the object
- return nil
- end
+ begin
+ return Etc.send(method, id).send(field)
+ rescue ArgumentError => detail
+ # ignore it; we couldn't find the object
+ return nil
end
+ end
- # A degenerate method of retrieving name/id mappings. The job of this method is
- # to retrieve all objects of a certain type, search for a specific entry
- # and then return a given field from that entry.
- def search_posix_field(type, field, id)
- idmethod = idfield(type)
- integer = false
- if id.is_a?(Integer)
- integer = true
- if id > Puppet[:maximum_uid].to_i
- Puppet.err "Tried to get #{field} field for silly id #{id}"
- return nil
- end
- end
+ # A degenerate method of retrieving name/id mappings. The job of this method is
+ # to retrieve all objects of a certain type, search for a specific entry
+ # and then return a given field from that entry.
+ def search_posix_field(type, field, id)
+ idmethod = idfield(type)
+ integer = false
+ if id.is_a?(Integer)
+ integer = true
+ if id > Puppet[:maximum_uid].to_i
+ Puppet.err "Tried to get #{field} field for silly id #{id}"
+ return nil
+ end
+ end
- Etc.send(type) do |object|
- if integer and object.send(idmethod) == id
- return object.send(field)
- elsif object.name == id
- return object.send(field)
- end
- end
+ Etc.send(type) do |object|
+ if integer and object.send(idmethod) == id
+ return object.send(field)
+ elsif object.name == id
+ return object.send(field)
+ end
+ end
- # Apparently the group/passwd methods need to get reset; if we skip
- # this call, then new users aren't found.
- case type
- when :passwd; Etc.send(:endpwent)
- when :group; Etc.send(:endgrent)
- end
- nil
+ # Apparently the group/passwd methods need to get reset; if we skip
+ # this call, then new users aren't found.
+ case type
+ when :passwd; Etc.send(:endpwent)
+ when :group; Etc.send(:endgrent)
end
+ nil
+ end
- # Determine what the field name is for users and groups.
- def idfield(space)
- case Puppet::Util.symbolize(space)
- when :gr, :group; return :gid
- when :pw, :user, :passwd; return :uid
- else
- raise ArgumentError.new("Can only handle users and groups")
- end
+ # Determine what the field name is for users and groups.
+ def idfield(space)
+ case Puppet::Util.symbolize(space)
+ when :gr, :group; return :gid
+ when :pw, :user, :passwd; return :uid
+ else
+ raise ArgumentError.new("Can only handle users and groups")
end
+ end
- # Determine what the method is to get users and groups by id
- def methodbyid(space)
- case Puppet::Util.symbolize(space)
- when :gr, :group; return :getgrgid
- when :pw, :user, :passwd; return :getpwuid
- else
- raise ArgumentError.new("Can only handle users and groups")
- end
+ # Determine what the method is to get users and groups by id
+ def methodbyid(space)
+ case Puppet::Util.symbolize(space)
+ when :gr, :group; return :getgrgid
+ when :pw, :user, :passwd; return :getpwuid
+ else
+ raise ArgumentError.new("Can only handle users and groups")
end
+ end
- # Determine what the method is to get users and groups by name
- def methodbyname(space)
- case Puppet::Util.symbolize(space)
- when :gr, :group; return :getgrnam
- when :pw, :user, :passwd; return :getpwnam
- else
- raise ArgumentError.new("Can only handle users and groups")
- end
+ # Determine what the method is to get users and groups by name
+ def methodbyname(space)
+ case Puppet::Util.symbolize(space)
+ when :gr, :group; return :getgrnam
+ when :pw, :user, :passwd; return :getpwnam
+ else
+ raise ArgumentError.new("Can only handle users and groups")
end
+ end
- # Get the GID of a given group, provided either a GID or a name
- def gid(group)
- begin
- group = Integer(group)
- rescue ArgumentError
- # pass
- end
- if group.is_a?(Integer)
- return nil unless name = get_posix_field(:group, :name, group)
- gid = get_posix_field(:group, :gid, name)
- check_value = gid
- else
- return nil unless gid = get_posix_field(:group, :gid, group)
- name = get_posix_field(:group, :name, gid)
- check_value = name
- end
- if check_value != group
- return search_posix_field(:group, :gid, group)
- else
- return gid
- end
+ # Get the GID of a given group, provided either a GID or a name
+ def gid(group)
+ begin
+ group = Integer(group)
+ rescue ArgumentError
+ # pass
+ end
+ if group.is_a?(Integer)
+ return nil unless name = get_posix_field(:group, :name, group)
+ gid = get_posix_field(:group, :gid, name)
+ check_value = gid
+ else
+ return nil unless gid = get_posix_field(:group, :gid, group)
+ name = get_posix_field(:group, :name, gid)
+ check_value = name
end
+ if check_value != group
+ return search_posix_field(:group, :gid, group)
+ else
+ return gid
+ end
+ end
- # Get the UID of a given user, whether a UID or name is provided
- def uid(user)
- begin
- user = Integer(user)
- rescue ArgumentError
- # pass
- end
- if user.is_a?(Integer)
- return nil unless name = get_posix_field(:passwd, :name, user)
- uid = get_posix_field(:passwd, :uid, name)
- check_value = uid
- else
- return nil unless uid = get_posix_field(:passwd, :uid, user)
- name = get_posix_field(:passwd, :name, uid)
- check_value = name
- end
- if check_value != user
- return search_posix_field(:passwd, :uid, user)
- else
- return uid
- end
+ # Get the UID of a given user, whether a UID or name is provided
+ def uid(user)
+ begin
+ user = Integer(user)
+ rescue ArgumentError
+ # pass
+ end
+ if user.is_a?(Integer)
+ return nil unless name = get_posix_field(:passwd, :name, user)
+ uid = get_posix_field(:passwd, :uid, name)
+ check_value = uid
+ else
+ return nil unless uid = get_posix_field(:passwd, :uid, user)
+ name = get_posix_field(:passwd, :name, uid)
+ check_value = name
+ end
+ if check_value != user
+ return search_posix_field(:passwd, :uid, user)
+ else
+ return uid
end
+ end
end
diff --git a/lib/puppet/util/provider_features.rb b/lib/puppet/util/provider_features.rb
index e0f90ae..ac294d2 100644
--- a/lib/puppet/util/provider_features.rb
+++ b/lib/puppet/util/provider_features.rb
@@ -3,167 +3,167 @@ require 'puppet/util/methodhelper'
require 'puppet/util/docs'
require 'puppet/util'
module Puppet::Util::ProviderFeatures
+ include Puppet::Util::Docs
+ # The class that models the features and handles checking whether the features
+ # are present.
+ class ProviderFeature
+ include Puppet::Util
+ include Puppet::Util::MethodHelper
include Puppet::Util::Docs
- # The class that models the features and handles checking whether the features
- # are present.
- class ProviderFeature
- include Puppet::Util
- include Puppet::Util::MethodHelper
- include Puppet::Util::Docs
- attr_accessor :name, :docs, :methods
-
- # Are all of the requirements met?
- def available?(obj)
- if self.methods
- return !!methods_available?(obj)
- else
- # In this case, the provider has to declare support for this
- # feature, and that's been checked before we ever get to the
- # method checks.
- return false
- end
- end
-
- def initialize(name, docs, hash)
- self.name = symbolize(name)
- self.docs = docs
- hash = symbolize_options(hash)
- set_options(hash)
- end
-
- private
-
- # Are all of the required methods available?
- def methods_available?(obj)
- methods.each do |m|
- if obj.is_a?(Class)
- return false unless obj.public_method_defined?(m)
- else
- return false unless obj.respond_to?(m)
- end
- end
- true
- end
+ attr_accessor :name, :docs, :methods
+
+ # Are all of the requirements met?
+ def available?(obj)
+ if self.methods
+ return !!methods_available?(obj)
+ else
+ # In this case, the provider has to declare support for this
+ # feature, and that's been checked before we ever get to the
+ # method checks.
+ return false
+ end
end
- # Define one or more features. At a minimum, features require a name
- # and docs, and at this point they should also specify a list of methods
- # required to determine if the feature is present.
- def feature(name, docs, hash = {})
- @features ||= {}
- raise(Puppet::DevError, "Feature #{name} is already defined") if @features.include?(name)
- begin
- obj = ProviderFeature.new(name, docs, hash)
- @features[obj.name] = obj
- rescue ArgumentError => detail
- error = ArgumentError.new(
- "Could not create feature #{name}: #{detail}"
- )
- error.set_backtrace(detail.backtrace)
- raise error
- end
+ def initialize(name, docs, hash)
+ self.name = symbolize(name)
+ self.docs = docs
+ hash = symbolize_options(hash)
+ set_options(hash)
end
- # Return a hash of all feature documentation.
- def featuredocs
- str = ""
- @features ||= {}
- return nil if @features.empty?
- names = @features.keys.sort { |a,b| a.to_s <=> b.to_s }
- names.each do |name|
- doc = @features[name].docs.gsub(/\n\s+/, " ")
- str += "- **#{name}**: #{doc}\n"
- end
+ private
- if providers.length > 0
- headers = ["Provider", names].flatten
- data = {}
- providers.each do |provname|
- data[provname] = []
- prov = provider(provname)
- names.each do |name|
- if prov.feature?(name)
- data[provname] << "**X**"
- else
- data[provname] << ""
- end
- end
- end
- str += doctable(headers, data)
+ # Are all of the required methods available?
+ def methods_available?(obj)
+ methods.each do |m|
+ if obj.is_a?(Class)
+ return false unless obj.public_method_defined?(m)
+ else
+ return false unless obj.respond_to?(m)
end
- str
+ end
+ true
+ end
+ end
+
+ # Define one or more features. At a minimum, features require a name
+ # and docs, and at this point they should also specify a list of methods
+ # required to determine if the feature is present.
+ def feature(name, docs, hash = {})
+ @features ||= {}
+ raise(Puppet::DevError, "Feature #{name} is already defined") if @features.include?(name)
+ begin
+ obj = ProviderFeature.new(name, docs, hash)
+ @features[obj.name] = obj
+ rescue ArgumentError => detail
+ error = ArgumentError.new(
+ "Could not create feature #{name}: #{detail}"
+ )
+ error.set_backtrace(detail.backtrace)
+ raise error
+ end
+ end
+
+ # Return a hash of all feature documentation.
+ def featuredocs
+ str = ""
+ @features ||= {}
+ return nil if @features.empty?
+ names = @features.keys.sort { |a,b| a.to_s <=> b.to_s }
+ names.each do |name|
+ doc = @features[name].docs.gsub(/\n\s+/, " ")
+ str += "- **#{name}**: #{doc}\n"
end
- # Return a list of features.
- def features
- @features ||= {}
- @features.keys
+ if providers.length > 0
+ headers = ["Provider", names].flatten
+ data = {}
+ providers.each do |provname|
+ data[provname] = []
+ prov = provider(provname)
+ names.each do |name|
+ if prov.feature?(name)
+ data[provname] << "**X**"
+ else
+ data[provname] << ""
+ end
+ end
+ end
+ str += doctable(headers, data)
end
+ str
+ end
+
+ # Return a list of features.
+ def features
+ @features ||= {}
+ @features.keys
+ end
+
+ # Generate a module that sets up the boolean methods to test for given
+ # features.
+ def feature_module
+ unless defined?(@feature_module)
+ @features ||= {}
+ @feature_module = ::Module.new
+ const_set("FeatureModule", @feature_module)
+ features = @features
+ # Create a feature? method that can be passed a feature name and
+ # determine if the feature is present.
+ @feature_module.send(:define_method, :feature?) do |name|
+ method = name.to_s + "?"
+ return !!(respond_to?(method) and send(method))
+ end
+
+ # Create a method that will list all functional features.
+ @feature_module.send(:define_method, :features) do
+ return false unless defined?(features)
+ features.keys.find_all { |n| feature?(n) }.sort { |a,b|
+ a.to_s <=> b.to_s
+ }
+ end
+
+ # Create a method that will determine if a provided list of
+ # features are satisfied by the curred provider.
+ @feature_module.send(:define_method, :satisfies?) do |*needed|
+ ret = true
+ needed.flatten.each do |feature|
+ unless feature?(feature)
+ ret = false
+ break
+ end
+ end
+ ret
+ end
+
+ # Create a boolean method for each feature so you can test them
+ # individually as you might need.
+ @features.each do |name, feature|
+ method = name.to_s + "?"
+ @feature_module.send(:define_method, method) do
+ (is_a?(Class) ? declared_feature?(name) : self.class.declared_feature?(name)) or feature.available?(self)
+ end
+ end
- # Generate a module that sets up the boolean methods to test for given
- # features.
- def feature_module
- unless defined?(@feature_module)
- @features ||= {}
- @feature_module = ::Module.new
- const_set("FeatureModule", @feature_module)
- features = @features
- # Create a feature? method that can be passed a feature name and
- # determine if the feature is present.
- @feature_module.send(:define_method, :feature?) do |name|
- method = name.to_s + "?"
- return !!(respond_to?(method) and send(method))
- end
-
- # Create a method that will list all functional features.
- @feature_module.send(:define_method, :features) do
- return false unless defined?(features)
- features.keys.find_all { |n| feature?(n) }.sort { |a,b|
- a.to_s <=> b.to_s
- }
- end
-
- # Create a method that will determine if a provided list of
- # features are satisfied by the curred provider.
- @feature_module.send(:define_method, :satisfies?) do |*needed|
- ret = true
- needed.flatten.each do |feature|
- unless feature?(feature)
- ret = false
- break
- end
- end
- ret
- end
-
- # Create a boolean method for each feature so you can test them
- # individually as you might need.
- @features.each do |name, feature|
- method = name.to_s + "?"
- @feature_module.send(:define_method, method) do
- (is_a?(Class) ? declared_feature?(name) : self.class.declared_feature?(name)) or feature.available?(self)
- end
- end
-
- # Allow the provider to declare that it has a given feature.
- @feature_module.send(:define_method, :has_features) do |*names|
- @declared_features ||= []
- names.each do |name|
- name = symbolize(name)
- @declared_features << name
- end
- end
- # Aaah, grammatical correctness
- @feature_module.send(:alias_method, :has_feature, :has_features)
+ # Allow the provider to declare that it has a given feature.
+ @feature_module.send(:define_method, :has_features) do |*names|
+ @declared_features ||= []
+ names.each do |name|
+ name = symbolize(name)
+ @declared_features << name
end
- @feature_module
+ end
+ # Aaah, grammatical correctness
+ @feature_module.send(:alias_method, :has_feature, :has_features)
end
+ @feature_module
+ end
- # Return the actual provider feature instance. Really only used for testing.
- def provider_feature(name)
- return nil unless defined?(@features)
+ # Return the actual provider feature instance. Really only used for testing.
+ def provider_feature(name)
+ return nil unless defined?(@features)
- @features[name]
- end
+ @features[name]
+ end
end
diff --git a/lib/puppet/util/pson.rb b/lib/puppet/util/pson.rb
index 87afbe0..1441069 100644
--- a/lib/puppet/util/pson.rb
+++ b/lib/puppet/util/pson.rb
@@ -6,8 +6,8 @@
# figure out what class we're working on, we don't need that, and we don't want
# our consumers and producers to need to know anything about our internals.
module Puppet::Util::Pson
- def pson_create(pson)
- raise ArgumentError, "No data provided in pson data" unless pson['data']
- from_pson(pson['data'])
- end
+ def pson_create(pson)
+ raise ArgumentError, "No data provided in pson data" unless pson['data']
+ from_pson(pson['data'])
+ end
end
diff --git a/lib/puppet/util/queue.rb b/lib/puppet/util/queue.rb
index d09d32c..0235774 100644
--- a/lib/puppet/util/queue.rb
+++ b/lib/puppet/util/queue.rb
@@ -34,63 +34,63 @@ require 'puppet/util/instance_loader'
# * <tt>subscribe(queue)</tt> _block_ subscribes to _queue_ and executes _block_ upon receiving a message.
# * _queue_ names are simple names independent of the message broker or client library. No "/queue/" prefixes like in Stomp::Client.
module Puppet::Util::Queue
- extend Puppet::Util::InstanceLoader
- instance_load :queue_clients, 'puppet/util/queue'
+ extend Puppet::Util::InstanceLoader
+ instance_load :queue_clients, 'puppet/util/queue'
- # Adds a new class/queue-type pair to the registry. The _type_ argument is optional; if not provided,
- # _type_ defaults to a lowercased, underscored symbol programmatically derived from the rightmost
- # namespace of <em>klass.name</em>.
- #
- # # register with default name +:you+
- # register_queue_type(Foo::You)
- #
- # # register with explicit queue type name +:myself+
- # register_queue_type(Foo::Me, :myself)
- #
- # If the type is already registered, an exception is thrown. No checking is performed of _klass_,
- # however; a given class could be registered any number of times, as long as the _type_ differs with
- # each registration.
- def self.register_queue_type(klass, type = nil)
- type ||= queue_type_from_class(klass)
- raise Puppet::Error, "Queue type #{type} is already registered" if instance_hash(:queue_clients).include?(type)
- instance_hash(:queue_clients)[type] = klass
- end
+ # Adds a new class/queue-type pair to the registry. The _type_ argument is optional; if not provided,
+ # _type_ defaults to a lowercased, underscored symbol programmatically derived from the rightmost
+ # namespace of <em>klass.name</em>.
+ #
+ # # register with default name +:you+
+ # register_queue_type(Foo::You)
+ #
+ # # register with explicit queue type name +:myself+
+ # register_queue_type(Foo::Me, :myself)
+ #
+ # If the type is already registered, an exception is thrown. No checking is performed of _klass_,
+ # however; a given class could be registered any number of times, as long as the _type_ differs with
+ # each registration.
+ def self.register_queue_type(klass, type = nil)
+ type ||= queue_type_from_class(klass)
+ raise Puppet::Error, "Queue type #{type} is already registered" if instance_hash(:queue_clients).include?(type)
+ instance_hash(:queue_clients)[type] = klass
+ end
- # Given a queue type symbol, returns the associated +Class+ object. If the queue type is unknown
- # (meaning it hasn't been registered with this module), an exception is thrown.
- def self.queue_type_to_class(type)
- c = loaded_instance :queue_clients, type
- raise Puppet::Error, "Queue type #{type} is unknown." unless c
- c
- end
+ # Given a queue type symbol, returns the associated +Class+ object. If the queue type is unknown
+ # (meaning it hasn't been registered with this module), an exception is thrown.
+ def self.queue_type_to_class(type)
+ c = loaded_instance :queue_clients, type
+ raise Puppet::Error, "Queue type #{type} is unknown." unless c
+ c
+ end
- # Given a class object _klass_, returns the programmatic default queue type name symbol for _klass_.
- # The algorithm is as shown in earlier examples; the last namespace segment of _klass.name_ is taken
- # and converted from mixed case to underscore-separated lowercase, and interned.
- # queue_type_from_class(Foo) -> :foo
- # queue_type_from_class(Foo::Too) -> :too
- # queue_type_from_class(Foo::ForYouTwo) -> :for_you_too
- #
- # The implicit assumption here, consistent with Puppet's approach to plugins in general,
- # is that all your client modules live in the same namespace, such that reduction to
- # a flat namespace of symbols is reasonably safe.
- def self.queue_type_from_class(klass)
- # convert last segment of classname from studly caps to lower case with underscores, and symbolize
- klass.name.split('::').pop.sub(/^[A-Z]/) {|c| c.downcase}.gsub(/[A-Z]/) {|c| '_' + c.downcase }.intern
- end
+ # Given a class object _klass_, returns the programmatic default queue type name symbol for _klass_.
+ # The algorithm is as shown in earlier examples; the last namespace segment of _klass.name_ is taken
+ # and converted from mixed case to underscore-separated lowercase, and interned.
+ # queue_type_from_class(Foo) -> :foo
+ # queue_type_from_class(Foo::Too) -> :too
+ # queue_type_from_class(Foo::ForYouTwo) -> :for_you_too
+ #
+ # The implicit assumption here, consistent with Puppet's approach to plugins in general,
+ # is that all your client modules live in the same namespace, such that reduction to
+ # a flat namespace of symbols is reasonably safe.
+ def self.queue_type_from_class(klass)
+ # convert last segment of classname from studly caps to lower case with underscores, and symbolize
+ klass.name.split('::').pop.sub(/^[A-Z]/) {|c| c.downcase}.gsub(/[A-Z]/) {|c| '_' + c.downcase }.intern
+ end
- # The class object for the client to be used, determined by queue configuration
- # settings.
- # Looks to the <tt>:queue_type</tt> configuration entry in the running application for
- # the default queue type to use.
- def client_class
- Puppet::Util::Queue.queue_type_to_class(Puppet[:queue_type])
- end
+ # The class object for the client to be used, determined by queue configuration
+ # settings.
+ # Looks to the <tt>:queue_type</tt> configuration entry in the running application for
+ # the default queue type to use.
+ def client_class
+ Puppet::Util::Queue.queue_type_to_class(Puppet[:queue_type])
+ end
- # Returns (instantiating as necessary) the singleton queue client instance, according to the
- # client_class. No arguments go to the client class constructor, meaning its up to the client class
- # to know how to determine its queue message source (presumably through Puppet configuration data).
- def client
- @client ||= client_class.new
- end
+ # Returns (instantiating as necessary) the singleton queue client instance, according to the
+ # client_class. No arguments go to the client class constructor, meaning its up to the client class
+ # to know how to determine its queue message source (presumably through Puppet configuration data).
+ def client
+ @client ||= client_class.new
+ end
end
diff --git a/lib/puppet/util/queue/stomp.rb b/lib/puppet/util/queue/stomp.rb
index ffe745f..c18edae 100644
--- a/lib/puppet/util/queue/stomp.rb
+++ b/lib/puppet/util/queue/stomp.rb
@@ -9,39 +9,39 @@ require 'uri'
# consequently, for this client to work, <tt>Puppet[:queue_source]</tt> must use the Stomp::Client URL-like
# syntax for identifying the Stomp message broker: <em>login:pass at host.port</em>
class Puppet::Util::Queue::Stomp
- attr_accessor :stomp_client
+ attr_accessor :stomp_client
- def initialize
- begin
- uri = URI.parse(Puppet[:queue_source])
- rescue => detail
- raise ArgumentError, "Could not create Stomp client instance - queue source #{Puppet[:queue_source]} is invalid: #{detail}"
- end
- unless uri.scheme == "stomp"
- raise ArgumentError, "Could not create Stomp client instance - queue source #{Puppet[:queue_source]} is not a Stomp URL: #{detail}"
- end
-
- begin
- self.stomp_client = Stomp::Client.new(uri.user, uri.password, uri.host, uri.port, true)
- rescue => detail
- raise ArgumentError, "Could not create Stomp client instance with queue source #{Puppet[:queue_source]}: got internal Stomp client error #{detail}"
- end
+ def initialize
+ begin
+ uri = URI.parse(Puppet[:queue_source])
+ rescue => detail
+ raise ArgumentError, "Could not create Stomp client instance - queue source #{Puppet[:queue_source]} is invalid: #{detail}"
end
-
- def send_message(target, msg)
- stomp_client.send(stompify_target(target), msg, :persistent => true)
+ unless uri.scheme == "stomp"
+ raise ArgumentError, "Could not create Stomp client instance - queue source #{Puppet[:queue_source]} is not a Stomp URL: #{detail}"
end
- def subscribe(target)
- stomp_client.subscribe(stompify_target(target), :ack => :client) do |stomp_message|
- yield(stomp_message.body)
- stomp_client.acknowledge(stomp_message)
- end
+ begin
+ self.stomp_client = Stomp::Client.new(uri.user, uri.password, uri.host, uri.port, true)
+ rescue => detail
+ raise ArgumentError, "Could not create Stomp client instance with queue source #{Puppet[:queue_source]}: got internal Stomp client error #{detail}"
end
+ end
- def stompify_target(target)
- '/queue/' + target.to_s
+ def send_message(target, msg)
+ stomp_client.send(stompify_target(target), msg, :persistent => true)
+ end
+
+ def subscribe(target)
+ stomp_client.subscribe(stompify_target(target), :ack => :client) do |stomp_message|
+ yield(stomp_message.body)
+ stomp_client.acknowledge(stomp_message)
end
+ end
+
+ def stompify_target(target)
+ '/queue/' + target.to_s
+ end
- Puppet::Util::Queue.register_queue_type(self, :stomp)
+ Puppet::Util::Queue.register_queue_type(self, :stomp)
end
diff --git a/lib/puppet/util/rails/cache_accumulator.rb b/lib/puppet/util/rails/cache_accumulator.rb
index 7c59a5d..4b3717f 100644
--- a/lib/puppet/util/rails/cache_accumulator.rb
+++ b/lib/puppet/util/rails/cache_accumulator.rb
@@ -1,65 +1,65 @@
require 'puppet/util'
module Puppet::Util::CacheAccumulator
- def self.included(klass)
- klass.extend ClassMethods
- end
+ def self.included(klass)
+ klass.extend ClassMethods
+ end
- class Base
- attr_reader :klass, :attribute
+ class Base
+ attr_reader :klass, :attribute
- def initialize(klass, attribute)
- @klass = klass
- @attribute = attribute
- @find_or_create = "find_or_create_by_#{@attribute.to_s}".intern
- end
+ def initialize(klass, attribute)
+ @klass = klass
+ @attribute = attribute
+ @find_or_create = "find_or_create_by_#{@attribute.to_s}".intern
+ end
- def store
- @store || reset
- end
+ def store
+ @store || reset
+ end
- def reset
- @store = {}
- end
+ def reset
+ @store = {}
+ end
- def find(*keys)
- result = nil
- if keys.length == 1
- result = store[keys[0]] ||= @klass.send(@find_or_create, *keys)
- else
- found, missing = keys.partition {|k| store.include? k}
- result = found.length
- result += do_multi_find(missing) if missing.length > 0
- end
- result
- end
+ def find(*keys)
+ result = nil
+ if keys.length == 1
+ result = store[keys[0]] ||= @klass.send(@find_or_create, *keys)
+ else
+ found, missing = keys.partition {|k| store.include? k}
+ result = found.length
+ result += do_multi_find(missing) if missing.length > 0
+ end
+ result
+ end
- def do_multi_find(keys)
- result = 0
- @klass.find(:all, :conditions => {@attribute => keys}).each do |obj|
- store[obj.send(@attribute)] = obj
- result += 1
- end
- result
- end
+ def do_multi_find(keys)
+ result = 0
+ @klass.find(:all, :conditions => {@attribute => keys}).each do |obj|
+ store[obj.send(@attribute)] = obj
+ result += 1
+ end
+ result
end
+ end
- module ClassMethods
- def accumulates(*attributes)
- attributes.each {|attrib| install_accumulator(attrib)}
- end
+ module ClassMethods
+ def accumulates(*attributes)
+ attributes.each {|attrib| install_accumulator(attrib)}
+ end
- def accumulators
- @accumulators ||= {}
- end
+ def accumulators
+ @accumulators ||= {}
+ end
- def install_accumulator(attribute)
- self.accumulators[attribute] = Base.new(self, attribute)
- module_eval %{
- def self.accumulate_by_#{attribute.to_s}(*keys)
- accumulators[:#{attribute.to_s}].find(*keys)
- end
- }
+ def install_accumulator(attribute)
+ self.accumulators[attribute] = Base.new(self, attribute)
+ module_eval %{
+ def self.accumulate_by_#{attribute.to_s}(*keys)
+ accumulators[:#{attribute.to_s}].find(*keys)
end
+ }
end
+ end
end
diff --git a/lib/puppet/util/rails/collection_merger.rb b/lib/puppet/util/rails/collection_merger.rb
index 3a28bb3..f95d3d3 100644
--- a/lib/puppet/util/rails/collection_merger.rb
+++ b/lib/puppet/util/rails/collection_merger.rb
@@ -1,17 +1,17 @@
module Puppet::Util::CollectionMerger
- def ar_hash_merge(db_hash, mem_hash, args)
- (db_hash.keys | mem_hash.keys).each do |key|
- if (db_hash[key] && mem_hash[key])
- # in both, update value
- args[:modify].call(db_hash[key], mem_hash[key])
- elsif (db_hash[key])
- # in db, not memory, delete from database
- args[:delete].call(db_hash[key])
- else
- # in mem, not in db, insert into the database
- args[:create].call(key, mem_hash[key])
- end
- end
+ def ar_hash_merge(db_hash, mem_hash, args)
+ (db_hash.keys | mem_hash.keys).each do |key|
+ if (db_hash[key] && mem_hash[key])
+ # in both, update value
+ args[:modify].call(db_hash[key], mem_hash[key])
+ elsif (db_hash[key])
+ # in db, not memory, delete from database
+ args[:delete].call(db_hash[key])
+ else
+ # in mem, not in db, insert into the database
+ args[:create].call(key, mem_hash[key])
+ end
end
+ end
end
diff --git a/lib/puppet/util/rails/reference_serializer.rb b/lib/puppet/util/rails/reference_serializer.rb
index a23f2cb..9beeb00 100644
--- a/lib/puppet/util/rails/reference_serializer.rb
+++ b/lib/puppet/util/rails/reference_serializer.rb
@@ -1,32 +1,32 @@
module Puppet::Util::ReferenceSerializer
- def unserialize_value(val)
- case val
- when /^--- /
- YAML.load(val)
- when "true"
- true
- when "false"
- false
- else
- val
- end
+ def unserialize_value(val)
+ case val
+ when /^--- /
+ YAML.load(val)
+ when "true"
+ true
+ when "false"
+ false
+ else
+ val
end
+ end
- def serialize_value(val)
- case val
- when Puppet::Resource
- YAML.dump(val)
- when true, false
- # The database does this for us, but I prefer the
- # methods be their exact inverses.
- # Note that this means quoted booleans get returned
- # as actual booleans, but there doesn't appear to be
- # a way to fix that while keeping the ability to
- # search for parameters set to true.
- val.to_s
- else
- val
- end
+ def serialize_value(val)
+ case val
+ when Puppet::Resource
+ YAML.dump(val)
+ when true, false
+ # The database does this for us, but I prefer the
+ # methods be their exact inverses.
+ # Note that this means quoted booleans get returned
+ # as actual booleans, but there doesn't appear to be
+ # a way to fix that while keeping the ability to
+ # search for parameters set to true.
+ val.to_s
+ else
+ val
end
+ end
end
diff --git a/lib/puppet/util/rdoc.rb b/lib/puppet/util/rdoc.rb
index ef208ca..4a80b06 100644
--- a/lib/puppet/util/rdoc.rb
+++ b/lib/puppet/util/rdoc.rb
@@ -1,91 +1,91 @@
module Puppet::Util::RDoc
- module_function
-
- # launch a rdoc documenation process
- # with the files/dir passed in +files+
- def rdoc(outputdir, files, charset = nil)
- Puppet[:ignoreimport] = true
-
- # then rdoc
- require 'rdoc/rdoc'
-
- # load our parser
- require 'puppet/util/rdoc/parser'
-
- r = RDoc::RDoc.new
-
- RDoc::RDoc::GENERATORS["puppet"] = RDoc::RDoc::Generator.new(
- "puppet/util/rdoc/generators/puppet_generator.rb",
- "PuppetGenerator".intern,
-
- "puppet")
- # specify our own format & where to output
- options = [ "--fmt", "puppet",
- "--quiet",
- "--force-update",
- "--exclude", "/modules/[^/]*/files/.*\.pp$",
- "--op", outputdir ]
-
- options += [ "--charset", charset] if charset
- options += files
-
- # launch the documentation process
- r.document(options)
- rescue RDoc::RDocError => e
- raise Puppet::ParseError.new("RDoc error #{e}")
+ module_function
+
+ # launch a rdoc documenation process
+ # with the files/dir passed in +files+
+ def rdoc(outputdir, files, charset = nil)
+ Puppet[:ignoreimport] = true
+
+ # then rdoc
+ require 'rdoc/rdoc'
+
+ # load our parser
+ require 'puppet/util/rdoc/parser'
+
+ r = RDoc::RDoc.new
+
+ RDoc::RDoc::GENERATORS["puppet"] = RDoc::RDoc::Generator.new(
+ "puppet/util/rdoc/generators/puppet_generator.rb",
+ "PuppetGenerator".intern,
+
+ "puppet")
+ # specify our own format & where to output
+ options = [ "--fmt", "puppet",
+ "--quiet",
+ "--force-update",
+ "--exclude", "/modules/[^/]*/files/.*\.pp$",
+ "--op", outputdir ]
+
+ options += [ "--charset", charset] if charset
+ options += files
+
+ # launch the documentation process
+ r.document(options)
+ rescue RDoc::RDocError => e
+ raise Puppet::ParseError.new("RDoc error #{e}")
+ end
+
+ # launch a output to console manifest doc
+ def manifestdoc(files)
+ Puppet[:ignoreimport] = true
+ files.select { |f| FileTest.file?(f) }.each do |f|
+ parser = Puppet::Parser::Parser.new(:environment => Puppet[:environment])
+ parser.file = f
+ ast = parser.parse
+ output(f, ast)
end
-
- # launch a output to console manifest doc
- def manifestdoc(files)
- Puppet[:ignoreimport] = true
- files.select { |f| FileTest.file?(f) }.each do |f|
- parser = Puppet::Parser::Parser.new(:environment => Puppet[:environment])
- parser.file = f
- ast = parser.parse
- output(f, ast)
- end
+ end
+
+ # Ouputs to the console the documentation
+ # of a manifest
+ def output(file, ast)
+ astobj = []
+ ast.nodes.each do |name, k|
+ astobj << k if k.file == file
end
- # Ouputs to the console the documentation
- # of a manifest
- def output(file, ast)
- astobj = []
- ast.nodes.each do |name, k|
- astobj << k if k.file == file
- end
-
- ast.hostclasses.each do |name,k|
- astobj << k if k.file == file
- end
-
- ast.definitions.each do |name, k|
- astobj << k if k.file == file
- end
- astobj.sort! {|a,b| a.line <=> b.line }.each do |k|
- output_astnode_doc(k)
- end
+ ast.hostclasses.each do |name,k|
+ astobj << k if k.file == file
end
- def output_astnode_doc(ast)
- puts ast.doc if !ast.doc.nil? and !ast.doc.empty?
- if Puppet.settings[:document_all]
- # scan each underlying resources to produce documentation
- code = ast.code.children if ast.code.is_a?(Puppet::Parser::AST::ASTArray)
- code ||= ast.code
- output_resource_doc(code) unless code.nil?
- end
+ ast.definitions.each do |name, k|
+ astobj << k if k.file == file
+ end
+ astobj.sort! {|a,b| a.line <=> b.line }.each do |k|
+ output_astnode_doc(k)
+ end
+ end
+
+ def output_astnode_doc(ast)
+ puts ast.doc if !ast.doc.nil? and !ast.doc.empty?
+ if Puppet.settings[:document_all]
+ # scan each underlying resources to produce documentation
+ code = ast.code.children if ast.code.is_a?(Puppet::Parser::AST::ASTArray)
+ code ||= ast.code
+ output_resource_doc(code) unless code.nil?
end
+ end
- def output_resource_doc(code)
- code.sort { |a,b| a.line <=> b.line }.each do |stmt|
- output_resource_doc(stmt.children) if stmt.is_a?(Puppet::Parser::AST::ASTArray)
+ def output_resource_doc(code)
+ code.sort { |a,b| a.line <=> b.line }.each do |stmt|
+ output_resource_doc(stmt.children) if stmt.is_a?(Puppet::Parser::AST::ASTArray)
- if stmt.is_a?(Puppet::Parser::AST::Resource)
- puts stmt.doc if !stmt.doc.nil? and !stmt.doc.empty?
- end
- end
+ if stmt.is_a?(Puppet::Parser::AST::Resource)
+ puts stmt.doc if !stmt.doc.nil? and !stmt.doc.empty?
+ end
end
+ end
end
\ No newline at end of file
diff --git a/lib/puppet/util/rdoc/code_objects.rb b/lib/puppet/util/rdoc/code_objects.rb
index 9ee26f4..3854fbc 100644
--- a/lib/puppet/util/rdoc/code_objects.rb
+++ b/lib/puppet/util/rdoc/code_objects.rb
@@ -2,240 +2,240 @@ require 'rdoc/code_objects'
module RDoc
- # This modules contains various class that are used to hold information
- # about the various Puppet language structures we found while parsing.
- #
- # Those will be mapped to their html counterparts which are defined in
- # PuppetGenerator.
-
- # PuppetTopLevel is a top level (usually a .pp/.rb file)
- class PuppetTopLevel < TopLevel
- attr_accessor :module_name, :global
-
- # will contain all plugins
- @@all_plugins = {}
-
- # contains all cutoms facts
- @@all_facts = {}
-
- def initialize(toplevel)
- super(toplevel.file_relative_name)
- end
-
- def self.all_plugins
- @@all_plugins.values
- end
-
- def self.all_facts
- @@all_facts.values
- end
- end
-
- # PuppetModule holds a Puppet Module
- # This is mapped to an HTMLPuppetModule
- # it leverage the RDoc (ruby) module infrastructure
- class PuppetModule < NormalModule
- attr_accessor :facts, :plugins
-
- def initialize(name,superclass=nil)
- @facts = []
- @plugins = []
- super(name,superclass)
- end
-
- def initialize_classes_and_modules
- super
- @nodes = {}
- end
-
- def add_plugin(plugin)
- add_to(@plugins, plugin)
- end
-
- def add_fact(fact)
- add_to(@facts, fact)
- end
-
- def add_node(name,superclass)
- cls = @nodes[name]
- unless cls
- cls = PuppetNode.new(name, superclass)
- @nodes[name] = cls if !@done_documenting
- cls.parent = self
- cls.section = @current_section
- end
- cls
- end
-
- def each_fact
- @facts.each {|c| yield c}
- end
-
- def each_plugin
- @plugins.each {|c| yield c}
- end
-
- def each_node
- @nodes.each {|c| yield c}
- end
-
- def nodes
- @nodes.values
- end
- end
-
- # PuppetClass holds a puppet class
- # It is mapped to a HTMLPuppetClass for display
- # It leverages RDoc (ruby) Class
- class PuppetClass < ClassModule
- attr_accessor :resource_list, :requires, :childs, :realizes
-
- def initialize(name, superclass)
- super(name,superclass)
- @resource_list = []
- @requires = []
- @realizes = []
- @childs = []
- end
-
- def add_resource(resource)
- add_to(@resource_list, resource)
- end
-
- def is_module?
- false
- end
-
- def superclass=(superclass)
- @superclass = superclass
- end
-
- # we're (ab)using the RDoc require system here.
- # we're adding a required Puppet class, overriding
- # the RDoc add_require method which sees ruby required files.
- def add_require(required)
- add_to(@requires, required)
- end
-
- def add_realize(realized)
- add_to(@realizes, realized)
- end
-
- def add_child(child)
- @childs << child
- end
- end
-
- # PuppetNode holds a puppet node
- # It is mapped to a HTMLPuppetNode for display
- # A node is just a variation of a class
- class PuppetNode < PuppetClass
- def initialize(name, superclass)
- super(name,superclass)
- end
-
- def is_module?
- false
- end
- end
-
- # Plugin holds a native puppet plugin (function,type...)
- # It is mapped to a HTMLPuppetPlugin for display
- class Plugin < Context
- attr_accessor :name, :type
-
- def initialize(name, type)
- super()
- @name = name
- @type = type
- @comment = ""
- end
-
- def <=>(other)
- @name <=> other.name
- end
-
- def full_name
- @name
- end
-
- def http_url(prefix)
- path = full_name.split("::")
- File.join(prefix, *path) + ".html"
- end
-
- def is_fact?
- false
- end
-
- def to_s
- res = self.class.name + ": #{@name} (#{@type})\n"
- res << @comment.to_s
- res
- end
- end
-
- # Fact holds a custom fact
- # It is mapped to a HTMLPuppetPlugin for display
- class Fact < Context
- attr_accessor :name, :confine
-
- def initialize(name, confine)
- super()
- @name = name
- @confine = confine
- @comment = ""
- end
-
- def <=>(other)
- @name <=> other.name
- end
-
- def is_fact?
- true
- end
-
- def full_name
- @name
- end
-
- def to_s
- res = self.class.name + ": #{@name}\n"
- res << @comment.to_s
- res
- end
- end
-
- # PuppetResource holds a puppet resource
- # It is mapped to a HTMLPuppetResource for display
- # A resource is defined by its "normal" form Type[title]
- class PuppetResource < CodeObject
- attr_accessor :type, :title, :params
-
- def initialize(type, title, comment, params)
- super()
- @type = type
- @title = title
- @comment = comment
- @params = params
- end
-
- def <=>(other)
- full_name <=> other.full_name
- end
-
- def full_name
- @type + "[#{@title}]"
- end
-
- def name
- full_name
- end
-
- def to_s
- res = @type + "[#{@title}]\n"
- res << @comment.to_s
- res
- end
+ # This modules contains various class that are used to hold information
+ # about the various Puppet language structures we found while parsing.
+ #
+ # Those will be mapped to their html counterparts which are defined in
+ # PuppetGenerator.
+
+ # PuppetTopLevel is a top level (usually a .pp/.rb file)
+ class PuppetTopLevel < TopLevel
+ attr_accessor :module_name, :global
+
+ # will contain all plugins
+ @@all_plugins = {}
+
+ # contains all cutoms facts
+ @@all_facts = {}
+
+ def initialize(toplevel)
+ super(toplevel.file_relative_name)
+ end
+
+ def self.all_plugins
+ @@all_plugins.values
+ end
+
+ def self.all_facts
+ @@all_facts.values
+ end
+ end
+
+ # PuppetModule holds a Puppet Module
+ # This is mapped to an HTMLPuppetModule
+ # it leverage the RDoc (ruby) module infrastructure
+ class PuppetModule < NormalModule
+ attr_accessor :facts, :plugins
+
+ def initialize(name,superclass=nil)
+ @facts = []
+ @plugins = []
+ super(name,superclass)
+ end
+
+ def initialize_classes_and_modules
+ super
+ @nodes = {}
+ end
+
+ def add_plugin(plugin)
+ add_to(@plugins, plugin)
+ end
+
+ def add_fact(fact)
+ add_to(@facts, fact)
+ end
+
+ def add_node(name,superclass)
+ cls = @nodes[name]
+ unless cls
+ cls = PuppetNode.new(name, superclass)
+ @nodes[name] = cls if !@done_documenting
+ cls.parent = self
+ cls.section = @current_section
+ end
+ cls
+ end
+
+ def each_fact
+ @facts.each {|c| yield c}
+ end
+
+ def each_plugin
+ @plugins.each {|c| yield c}
+ end
+
+ def each_node
+ @nodes.each {|c| yield c}
+ end
+
+ def nodes
+ @nodes.values
+ end
+ end
+
+ # PuppetClass holds a puppet class
+ # It is mapped to a HTMLPuppetClass for display
+ # It leverages RDoc (ruby) Class
+ class PuppetClass < ClassModule
+ attr_accessor :resource_list, :requires, :childs, :realizes
+
+ def initialize(name, superclass)
+ super(name,superclass)
+ @resource_list = []
+ @requires = []
+ @realizes = []
+ @childs = []
+ end
+
+ def add_resource(resource)
+ add_to(@resource_list, resource)
+ end
+
+ def is_module?
+ false
+ end
+
+ def superclass=(superclass)
+ @superclass = superclass
+ end
+
+ # we're (ab)using the RDoc require system here.
+ # we're adding a required Puppet class, overriding
+ # the RDoc add_require method which sees ruby required files.
+ def add_require(required)
+ add_to(@requires, required)
+ end
+
+ def add_realize(realized)
+ add_to(@realizes, realized)
+ end
+
+ def add_child(child)
+ @childs << child
+ end
+ end
+
+ # PuppetNode holds a puppet node
+ # It is mapped to a HTMLPuppetNode for display
+ # A node is just a variation of a class
+ class PuppetNode < PuppetClass
+ def initialize(name, superclass)
+ super(name,superclass)
+ end
+
+ def is_module?
+ false
+ end
+ end
+
+ # Plugin holds a native puppet plugin (function,type...)
+ # It is mapped to a HTMLPuppetPlugin for display
+ class Plugin < Context
+ attr_accessor :name, :type
+
+ def initialize(name, type)
+ super()
+ @name = name
+ @type = type
+ @comment = ""
+ end
+
+ def <=>(other)
+ @name <=> other.name
+ end
+
+ def full_name
+ @name
+ end
+
+ def http_url(prefix)
+ path = full_name.split("::")
+ File.join(prefix, *path) + ".html"
+ end
+
+ def is_fact?
+ false
+ end
+
+ def to_s
+ res = self.class.name + ": #{@name} (#{@type})\n"
+ res << @comment.to_s
+ res
+ end
+ end
+
+ # Fact holds a custom fact
+ # It is mapped to a HTMLPuppetPlugin for display
+ class Fact < Context
+ attr_accessor :name, :confine
+
+ def initialize(name, confine)
+ super()
+ @name = name
+ @confine = confine
+ @comment = ""
+ end
+
+ def <=>(other)
+ @name <=> other.name
+ end
+
+ def is_fact?
+ true
+ end
+
+ def full_name
+ @name
+ end
+
+ def to_s
+ res = self.class.name + ": #{@name}\n"
+ res << @comment.to_s
+ res
+ end
+ end
+
+ # PuppetResource holds a puppet resource
+ # It is mapped to a HTMLPuppetResource for display
+ # A resource is defined by its "normal" form Type[title]
+ class PuppetResource < CodeObject
+ attr_accessor :type, :title, :params
+
+ def initialize(type, title, comment, params)
+ super()
+ @type = type
+ @title = title
+ @comment = comment
+ @params = params
+ end
+
+ def <=>(other)
+ full_name <=> other.full_name
+ end
+
+ def full_name
+ @type + "[#{@title}]"
+ end
+
+ def name
+ full_name
+ end
+
+ def to_s
+ res = @type + "[#{@title}]\n"
+ res << @comment.to_s
+ res
end
+ end
end
diff --git a/lib/puppet/util/rdoc/generators/puppet_generator.rb b/lib/puppet/util/rdoc/generators/puppet_generator.rb
index 24579d6..9caeacd 100644
--- a/lib/puppet/util/rdoc/generators/puppet_generator.rb
+++ b/lib/puppet/util/rdoc/generators/puppet_generator.rb
@@ -4,884 +4,884 @@ require 'digest/md5'
module Generators
- # This module holds all the classes needed to generate the HTML documentation
- # of a bunch of puppet manifests.
- #
- # It works by traversing all the code objects defined by the Puppet RDoc::Parser
- # and produces HTML counterparts objects that in turns are used by RDoc template engine
- # to produce the final HTML.
- #
- # It is also responsible of creating the whole directory hierarchy, and various index
- # files.
- #
- # It is to be noted that the whole system is built on top of ruby RDoc. As such there
- # is an implicit mapping of puppet entities to ruby entitites:
- #
- # Puppet => Ruby
- # ------------------------
- # Module Module
- # Class Class
- # Definition Method
- # Resource
- # Node
- # Plugin
- # Fact
-
- MODULE_DIR = "modules"
- NODE_DIR = "nodes"
- PLUGIN_DIR = "plugins"
-
- # This is a specialized HTMLGenerator tailored to Puppet manifests
- class PuppetGenerator < HTMLGenerator
-
- def PuppetGenerator.for(options)
- AllReferences::reset
- HtmlMethod::reset
-
- if options.all_one_file
- PuppetGeneratorInOne.new(options)
- else
- PuppetGenerator.new(options)
- end
- end
+ # This module holds all the classes needed to generate the HTML documentation
+ # of a bunch of puppet manifests.
+ #
+ # It works by traversing all the code objects defined by the Puppet RDoc::Parser
+ # and produces HTML counterparts objects that in turns are used by RDoc template engine
+ # to produce the final HTML.
+ #
+ # It is also responsible of creating the whole directory hierarchy, and various index
+ # files.
+ #
+ # It is to be noted that the whole system is built on top of ruby RDoc. As such there
+ # is an implicit mapping of puppet entities to ruby entitites:
+ #
+ # Puppet => Ruby
+ # ------------------------
+ # Module Module
+ # Class Class
+ # Definition Method
+ # Resource
+ # Node
+ # Plugin
+ # Fact
+
+ MODULE_DIR = "modules"
+ NODE_DIR = "nodes"
+ PLUGIN_DIR = "plugins"
+
+ # This is a specialized HTMLGenerator tailored to Puppet manifests
+ class PuppetGenerator < HTMLGenerator
+
+ def PuppetGenerator.for(options)
+ AllReferences::reset
+ HtmlMethod::reset
+
+ if options.all_one_file
+ PuppetGeneratorInOne.new(options)
+ else
+ PuppetGenerator.new(options)
+ end
+ end
- def initialize(options) #:not-new:
- @options = options
- load_html_template
- end
+ def initialize(options) #:not-new:
+ @options = options
+ load_html_template
+ end
- # loads our own html template file
- def load_html_template
- require 'puppet/util/rdoc/generators/template/puppet/puppet'
- extend RDoc::Page
- rescue LoadError
- $stderr.puts "Could not find Puppet template '#{template}'"
- exit 99
- end
+ # loads our own html template file
+ def load_html_template
+ require 'puppet/util/rdoc/generators/template/puppet/puppet'
+ extend RDoc::Page
+ rescue LoadError
+ $stderr.puts "Could not find Puppet template '#{template}'"
+ exit 99
+ end
- def gen_method_index
- # we don't generate an all define index
- # as the presentation is per module/per class
- end
+ def gen_method_index
+ # we don't generate an all define index
+ # as the presentation is per module/per class
+ end
- # This is the central method, it generates the whole structures
- # along with all the indices.
- def generate_html
- super
- gen_into(@nodes)
- gen_into(@plugins)
- end
+ # This is the central method, it generates the whole structures
+ # along with all the indices.
+ def generate_html
+ super
+ gen_into(@nodes)
+ gen_into(@plugins)
+ end
- ##
- # Generate:
- # the list of modules
- # the list of classes and definitions of a specific module
- # the list of all classes
- # the list of nodes
- # the list of resources
- def build_indices
- @allfiles = []
- @nodes = []
- @plugins = []
-
- # contains all the seen modules
- @modules = {}
- @allclasses = {}
-
- # build the modules, classes and per modules classes and define list
- @toplevels.each do |toplevel|
- next unless toplevel.document_self
- file = HtmlFile.new(toplevel, @options, FILE_DIR)
- classes = []
- methods = []
- modules = []
- nodes = []
-
- # find all classes of this toplevel
- # store modules if we find one
- toplevel.each_classmodule do |k|
- generate_class_list(classes, modules, k, toplevel, CLASS_DIR)
- end
-
- # find all defines belonging to this toplevel
- HtmlMethod.all_methods.each do |m|
- # find parent module, check this method is not already
- # defined.
- if m.context.parent.toplevel === toplevel
- methods << m
- end
- end
-
- classes.each do |k|
- @allclasses[k.index_name] = k if !@allclasses.has_key?(k.index_name)
- end
-
- # generate nodes and plugins found
- classes.each do |k|
- if k.context.is_module?
- k.context.each_node do |name,node|
- nodes << HTMLPuppetNode.new(node, toplevel, NODE_DIR, @options)
- @nodes << nodes.last
- end
- k.context.each_plugin do |plugin|
- @plugins << HTMLPuppetPlugin.new(plugin, toplevel, PLUGIN_DIR, @options)
- end
- k.context.each_fact do |fact|
- @plugins << HTMLPuppetPlugin.new(fact, toplevel, PLUGIN_DIR, @options)
- end
- end
- end
-
- @files << file
- @allfiles << { "file" => file, "modules" => modules, "classes" => classes, "methods" => methods, "nodes" => nodes }
- end
+ ##
+ # Generate:
+ # the list of modules
+ # the list of classes and definitions of a specific module
+ # the list of all classes
+ # the list of nodes
+ # the list of resources
+ def build_indices
+ @allfiles = []
+ @nodes = []
+ @plugins = []
- # scan all classes to create the childs references
- @allclasses.values.each do |klass|
- if superklass = klass.context.superclass
- if superklass = AllReferences[superklass] and (superklass.is_a?(HTMLPuppetClass) or superklass.is_a?(HTMLPuppetNode))
- superklass.context.add_child(klass.context)
- end
- end
- end
+ # contains all the seen modules
+ @modules = {}
+ @allclasses = {}
- @classes = @allclasses.values
- end
+ # build the modules, classes and per modules classes and define list
+ @toplevels.each do |toplevel|
+ next unless toplevel.document_self
+ file = HtmlFile.new(toplevel, @options, FILE_DIR)
+ classes = []
+ methods = []
+ modules = []
+ nodes = []
- # produce a class/module list of HTMLPuppetModule/HTMLPuppetClass
- # based on the code object traversal.
- def generate_class_list(classes, modules, from, html_file, class_dir)
- if from.is_module? and !@modules.has_key?(from.name)
- k = HTMLPuppetModule.new(from, html_file, class_dir, @options)
- classes << k
- @modules[from.name] = k
- modules << @modules[from.name]
- elsif from.is_module?
- modules << @modules[from.name]
- elsif !from.is_module?
- k = HTMLPuppetClass.new(from, html_file, class_dir, @options)
- classes << k
- end
- from.each_classmodule do |mod|
- generate_class_list(classes, modules, mod, html_file, class_dir)
- end
+ # find all classes of this toplevel
+ # store modules if we find one
+ toplevel.each_classmodule do |k|
+ generate_class_list(classes, modules, k, toplevel, CLASS_DIR)
end
- # generate all the subdirectories, modules, classes and files
- def gen_sub_directories
- super
- File.makedirs(MODULE_DIR)
- File.makedirs(NODE_DIR)
- File.makedirs(PLUGIN_DIR)
- rescue
- $stderr.puts $ERROR_INFO.message
- exit 1
+ # find all defines belonging to this toplevel
+ HtmlMethod.all_methods.each do |m|
+ # find parent module, check this method is not already
+ # defined.
+ if m.context.parent.toplevel === toplevel
+ methods << m
+ end
end
- # generate the index of modules
- def gen_file_index
- gen_top_index(@modules.values, 'All Modules', RDoc::Page::TOP_INDEX, "fr_modules_index.html")
+ classes.each do |k|
+ @allclasses[k.index_name] = k if !@allclasses.has_key?(k.index_name)
end
- # generate a top index
- def gen_top_index(collection, title, template, filename)
- template = TemplatePage.new(RDoc::Page::FR_INDEX_BODY, template)
- res = []
- collection.sort.each do |f|
- if f.document_self
- res << { "classlist" => CGI.escapeHTML("#{MODULE_DIR}/fr_#{f.index_name}.html"), "module" => CGI.escapeHTML("#{CLASS_DIR}/#{f.index_name}.html"),"name" => CGI.escapeHTML(f.index_name) }
- end
+ # generate nodes and plugins found
+ classes.each do |k|
+ if k.context.is_module?
+ k.context.each_node do |name,node|
+ nodes << HTMLPuppetNode.new(node, toplevel, NODE_DIR, @options)
+ @nodes << nodes.last
end
-
- values = {
- "entries" => res,
- 'list_title' => CGI.escapeHTML(title),
- 'index_url' => main_url,
- 'charset' => @options.charset,
- 'style_url' => style_url('', @options.css),
- }
-
- File.open(filename, "w") do |f|
- template.write_html_on(f, values)
+ k.context.each_plugin do |plugin|
+ @plugins << HTMLPuppetPlugin.new(plugin, toplevel, PLUGIN_DIR, @options)
end
- end
-
- # generate the all classes index file and the combo index
- def gen_class_index
- gen_an_index(@classes, 'All Classes', RDoc::Page::CLASS_INDEX, "fr_class_index.html")
- @allfiles.each do |file|
- unless file['file'].context.file_relative_name =~ /\.rb$/
-
- gen_composite_index(
- file,
- RDoc::Page::COMBO_INDEX,
-
- "#{MODULE_DIR}/fr_#{file["file"].context.module_name}.html")
- end
+ k.context.each_fact do |fact|
+ @plugins << HTMLPuppetPlugin.new(fact, toplevel, PLUGIN_DIR, @options)
end
+ end
end
- def gen_composite_index(collection, template, filename)\
- return if FileTest.exists?(filename)
+ @files << file
+ @allfiles << { "file" => file, "modules" => modules, "classes" => classes, "methods" => methods, "nodes" => nodes }
+ end
- template = TemplatePage.new(RDoc::Page::FR_INDEX_BODY, template)
- res1 = []
- collection['classes'].sort.each do |f|
- if f.document_self
- res1 << { "href" => "../"+CGI.escapeHTML(f.path), "name" => CGI.escapeHTML(f.index_name) } unless f.context.is_module?
- end
- end
-
- res2 = []
- collection['methods'].sort.each do |f|
- res2 << { "href" => "../#{f.path}", "name" => f.index_name.sub(/\(.*\)$/,'') } if f.document_self
- end
+ # scan all classes to create the childs references
+ @allclasses.values.each do |klass|
+ if superklass = klass.context.superclass
+ if superklass = AllReferences[superklass] and (superklass.is_a?(HTMLPuppetClass) or superklass.is_a?(HTMLPuppetNode))
+ superklass.context.add_child(klass.context)
+ end
+ end
+ end
- module_name = []
- res3 = []
- res4 = []
- collection['modules'].sort.each do |f|
- module_name << { "href" => "../"+CGI.escapeHTML(f.path), "name" => CGI.escapeHTML(f.index_name) }
- unless f.facts.nil?
- f.facts.each do |fact|
- res3 << {"href" => "../"+CGI.escapeHTML(AllReferences["PLUGIN(#{fact.name})"].path), "name" => CGI.escapeHTML(fact.name)}
- end
- end
- unless f.plugins.nil?
- f.plugins.each do |plugin|
- res4 << {"href" => "../"+CGI.escapeHTML(AllReferences["PLUGIN(#{plugin.name})"].path), "name" => CGI.escapeHTML(plugin.name)}
- end
- end
- end
+ @classes = @allclasses.values
+ end
- res5 = []
- collection['nodes'].sort.each do |f|
- res5 << { "href" => "../"+CGI.escapeHTML(f.path), "name" => CGI.escapeHTML(f.name) } if f.document_self
- end
+ # produce a class/module list of HTMLPuppetModule/HTMLPuppetClass
+ # based on the code object traversal.
+ def generate_class_list(classes, modules, from, html_file, class_dir)
+ if from.is_module? and !@modules.has_key?(from.name)
+ k = HTMLPuppetModule.new(from, html_file, class_dir, @options)
+ classes << k
+ @modules[from.name] = k
+ modules << @modules[from.name]
+ elsif from.is_module?
+ modules << @modules[from.name]
+ elsif !from.is_module?
+ k = HTMLPuppetClass.new(from, html_file, class_dir, @options)
+ classes << k
+ end
+ from.each_classmodule do |mod|
+ generate_class_list(classes, modules, mod, html_file, class_dir)
+ end
+ end
- values = {
- "module" => module_name,
- "classes" => res1,
- 'classes_title' => CGI.escapeHTML("Classes"),
- 'defines_title' => CGI.escapeHTML("Defines"),
- 'facts_title' => CGI.escapeHTML("Custom Facts"),
- 'plugins_title' => CGI.escapeHTML("Plugins"),
- 'nodes_title' => CGI.escapeHTML("Nodes"),
- 'index_url' => main_url,
- 'charset' => @options.charset,
- 'style_url' => style_url('', @options.css),
- }
-
- values["defines"] = res2 if res2.size>0
- values["facts"] = res3 if res3.size>0
- values["plugins"] = res4 if res4.size>0
- values["nodes"] = res5 if res5.size>0
-
- File.open(filename, "w") do |f|
- template.write_html_on(f, values)
- end
- end
+ # generate all the subdirectories, modules, classes and files
+ def gen_sub_directories
+ super
+ File.makedirs(MODULE_DIR)
+ File.makedirs(NODE_DIR)
+ File.makedirs(PLUGIN_DIR)
+ rescue
+ $stderr.puts $ERROR_INFO.message
+ exit 1
+ end
- # returns the initial_page url
- def main_url
- main_page = @options.main_page
- ref = nil
- if main_page
- ref = AllReferences[main_page]
- if ref
- ref = ref.path
- else
- $stderr.puts "Could not find main page #{main_page}"
- end
- end
+ # generate the index of modules
+ def gen_file_index
+ gen_top_index(@modules.values, 'All Modules', RDoc::Page::TOP_INDEX, "fr_modules_index.html")
+ end
- unless ref
- for file in @files
- if file.document_self and file.context.global
- ref = CGI.escapeHTML("#{CLASS_DIR}/#{file.context.module_name}.html")
- break
- end
- end
- end
+ # generate a top index
+ def gen_top_index(collection, title, template, filename)
+ template = TemplatePage.new(RDoc::Page::FR_INDEX_BODY, template)
+ res = []
+ collection.sort.each do |f|
+ if f.document_self
+ res << { "classlist" => CGI.escapeHTML("#{MODULE_DIR}/fr_#{f.index_name}.html"), "module" => CGI.escapeHTML("#{CLASS_DIR}/#{f.index_name}.html"),"name" => CGI.escapeHTML(f.index_name) }
+ end
+ end
+
+ values = {
+ "entries" => res,
+ 'list_title' => CGI.escapeHTML(title),
+ 'index_url' => main_url,
+ 'charset' => @options.charset,
+ 'style_url' => style_url('', @options.css),
+ }
+
+ File.open(filename, "w") do |f|
+ template.write_html_on(f, values)
+ end
+ end
- unless ref
- for file in @files
- if file.document_self and !file.context.global
- ref = CGI.escapeHTML("#{CLASS_DIR}/#{file.context.module_name}.html")
- break
- end
- end
- end
+ # generate the all classes index file and the combo index
+ def gen_class_index
+ gen_an_index(@classes, 'All Classes', RDoc::Page::CLASS_INDEX, "fr_class_index.html")
+ @allfiles.each do |file|
+ unless file['file'].context.file_relative_name =~ /\.rb$/
- unless ref
- $stderr.puts "Couldn't find anything to document"
- $stderr.puts "Perhaps you've used :stopdoc: in all classes"
- exit(1)
- end
+ gen_composite_index(
+ file,
+ RDoc::Page::COMBO_INDEX,
- ref
+ "#{MODULE_DIR}/fr_#{file["file"].context.module_name}.html")
end
-
+ end
end
- # This module is used to generate a referenced full name list of ContextUser
- module ReferencedListBuilder
- def build_referenced_list(list)
- res = []
- list.each do |i|
- ref = AllReferences[i.name] || @context.find_symbol(i.name)
- ref = ref.viewer if ref and ref.respond_to?(:viewer)
- name = i.respond_to?(:full_name) ? i.full_name : i.name
- h_name = CGI.escapeHTML(name)
- if ref and ref.document_self
- path = url(ref.path)
- res << { "name" => h_name, "aref" => path }
- else
- res << { "name" => h_name }
- end
- end
- res
- end
+ def gen_composite_index(collection, template, filename)\
+ return if FileTest.exists?(filename)
+
+ template = TemplatePage.new(RDoc::Page::FR_INDEX_BODY, template)
+ res1 = []
+ collection['classes'].sort.each do |f|
+ if f.document_self
+ res1 << { "href" => "../"+CGI.escapeHTML(f.path), "name" => CGI.escapeHTML(f.index_name) } unless f.context.is_module?
+ end
+ end
+
+ res2 = []
+ collection['methods'].sort.each do |f|
+ res2 << { "href" => "../#{f.path}", "name" => f.index_name.sub(/\(.*\)$/,'') } if f.document_self
+ end
+
+ module_name = []
+ res3 = []
+ res4 = []
+ collection['modules'].sort.each do |f|
+ module_name << { "href" => "../"+CGI.escapeHTML(f.path), "name" => CGI.escapeHTML(f.index_name) }
+ unless f.facts.nil?
+ f.facts.each do |fact|
+ res3 << {"href" => "../"+CGI.escapeHTML(AllReferences["PLUGIN(#{fact.name})"].path), "name" => CGI.escapeHTML(fact.name)}
+ end
+ end
+ unless f.plugins.nil?
+ f.plugins.each do |plugin|
+ res4 << {"href" => "../"+CGI.escapeHTML(AllReferences["PLUGIN(#{plugin.name})"].path), "name" => CGI.escapeHTML(plugin.name)}
+ end
+ end
+ end
+
+ res5 = []
+ collection['nodes'].sort.each do |f|
+ res5 << { "href" => "../"+CGI.escapeHTML(f.path), "name" => CGI.escapeHTML(f.name) } if f.document_self
+ end
+
+ values = {
+ "module" => module_name,
+ "classes" => res1,
+ 'classes_title' => CGI.escapeHTML("Classes"),
+ 'defines_title' => CGI.escapeHTML("Defines"),
+ 'facts_title' => CGI.escapeHTML("Custom Facts"),
+ 'plugins_title' => CGI.escapeHTML("Plugins"),
+ 'nodes_title' => CGI.escapeHTML("Nodes"),
+ 'index_url' => main_url,
+ 'charset' => @options.charset,
+ 'style_url' => style_url('', @options.css),
+ }
+
+ values["defines"] = res2 if res2.size>0
+ values["facts"] = res3 if res3.size>0
+ values["plugins"] = res4 if res4.size>0
+ values["nodes"] = res5 if res5.size>0
+
+ File.open(filename, "w") do |f|
+ template.write_html_on(f, values)
+ end
end
- # This module is used to hold/generate a list of puppet resources
- # this is used in HTMLPuppetClass and HTMLPuppetNode
- module ResourceContainer
- def collect_resources
- list = @context.resource_list
- @resources = list.collect {|m| HTMLPuppetResource.new(m, self, @options) }
- end
-
- def build_resource_summary_list(path_prefix='')
- collect_resources unless @resources
- resources = @resources.sort
- res = []
- resources.each do |r|
- res << {
- "name" => CGI.escapeHTML(r.name),
- "aref" => CGI.escape(path_prefix)+"\#"+CGI.escape(r.aref)
- }
- end
- res
- end
+ # returns the initial_page url
+ def main_url
+ main_page = @options.main_page
+ ref = nil
+ if main_page
+ ref = AllReferences[main_page]
+ if ref
+ ref = ref.path
+ else
+ $stderr.puts "Could not find main page #{main_page}"
+ end
+ end
+
+ unless ref
+ for file in @files
+ if file.document_self and file.context.global
+ ref = CGI.escapeHTML("#{CLASS_DIR}/#{file.context.module_name}.html")
+ break
+ end
+ end
+ end
+
+ unless ref
+ for file in @files
+ if file.document_self and !file.context.global
+ ref = CGI.escapeHTML("#{CLASS_DIR}/#{file.context.module_name}.html")
+ break
+ end
+ end
+ end
+
+ unless ref
+ $stderr.puts "Couldn't find anything to document"
+ $stderr.puts "Perhaps you've used :stopdoc: in all classes"
+ exit(1)
+ end
+
+ ref
+ end
- def build_resource_detail_list(section)
- outer = []
- resources = @resources.sort
- resources.each do |r|
- row = {}
- if r.section == section and r.document_self
- row["name"] = CGI.escapeHTML(r.name)
- desc = r.description.strip
- row["m_desc"] = desc unless desc.empty?
- row["aref"] = r.aref
- row["params"] = r.params
- outer << row
- end
- end
- outer
- end
+ end
+
+ # This module is used to generate a referenced full name list of ContextUser
+ module ReferencedListBuilder
+ def build_referenced_list(list)
+ res = []
+ list.each do |i|
+ ref = AllReferences[i.name] || @context.find_symbol(i.name)
+ ref = ref.viewer if ref and ref.respond_to?(:viewer)
+ name = i.respond_to?(:full_name) ? i.full_name : i.name
+ h_name = CGI.escapeHTML(name)
+ if ref and ref.document_self
+ path = url(ref.path)
+ res << { "name" => h_name, "aref" => path }
+ else
+ res << { "name" => h_name }
+ end
+ end
+ res
+ end
+ end
+
+ # This module is used to hold/generate a list of puppet resources
+ # this is used in HTMLPuppetClass and HTMLPuppetNode
+ module ResourceContainer
+ def collect_resources
+ list = @context.resource_list
+ @resources = list.collect {|m| HTMLPuppetResource.new(m, self, @options) }
end
- class HTMLPuppetClass < HtmlClass
- include ResourceContainer, ReferencedListBuilder
+ def build_resource_summary_list(path_prefix='')
+ collect_resources unless @resources
+ resources = @resources.sort
+ res = []
+ resources.each do |r|
+ res << {
+ "name" => CGI.escapeHTML(r.name),
+ "aref" => CGI.escape(path_prefix)+"\#"+CGI.escape(r.aref)
+ }
+ end
+ res
+ end
- def value_hash
- super
- rl = build_resource_summary_list
- @values["resources"] = rl unless rl.empty?
+ def build_resource_detail_list(section)
+ outer = []
+ resources = @resources.sort
+ resources.each do |r|
+ row = {}
+ if r.section == section and r.document_self
+ row["name"] = CGI.escapeHTML(r.name)
+ desc = r.description.strip
+ row["m_desc"] = desc unless desc.empty?
+ row["aref"] = r.aref
+ row["params"] = r.params
+ outer << row
+ end
+ end
+ outer
+ end
+ end
- @context.sections.each do |section|
- secdata = @values["sections"].select { |secdata| secdata["secsequence"] == section.sequence }
- if secdata.size == 1
- secdata = secdata[0]
+ class HTMLPuppetClass < HtmlClass
+ include ResourceContainer, ReferencedListBuilder
- rdl = build_resource_detail_list(section)
- secdata["resource_list"] = rdl unless rdl.empty?
- end
- end
+ def value_hash
+ super
+ rl = build_resource_summary_list
+ @values["resources"] = rl unless rl.empty?
- rl = build_require_list(@context)
- @values["requires"] = rl unless rl.empty?
+ @context.sections.each do |section|
+ secdata = @values["sections"].select { |secdata| secdata["secsequence"] == section.sequence }
+ if secdata.size == 1
+ secdata = secdata[0]
- rl = build_realize_list(@context)
- @values["realizes"] = rl unless rl.empty?
+ rdl = build_resource_detail_list(section)
+ secdata["resource_list"] = rdl unless rdl.empty?
+ end
+ end
- cl = build_child_list(@context)
- @values["childs"] = cl unless cl.empty?
+ rl = build_require_list(@context)
+ @values["requires"] = rl unless rl.empty?
- @values
- end
+ rl = build_realize_list(@context)
+ @values["realizes"] = rl unless rl.empty?
- def build_require_list(context)
- build_referenced_list(context.requires)
- end
+ cl = build_child_list(@context)
+ @values["childs"] = cl unless cl.empty?
- def build_realize_list(context)
- build_referenced_list(context.realizes)
- end
+ @values
+ end
- def build_child_list(context)
- build_referenced_list(context.childs)
- end
+ def build_require_list(context)
+ build_referenced_list(context.requires)
end
- class HTMLPuppetNode < ContextUser
- include ResourceContainer, ReferencedListBuilder
+ def build_realize_list(context)
+ build_referenced_list(context.realizes)
+ end
- attr_reader :path
+ def build_child_list(context)
+ build_referenced_list(context.childs)
+ end
+ end
- def initialize(context, html_file, prefix, options)
- super(context, options)
+ class HTMLPuppetNode < ContextUser
+ include ResourceContainer, ReferencedListBuilder
- @html_file = html_file
- @is_module = context.is_module?
- @values = {}
+ attr_reader :path
- context.viewer = self
+ def initialize(context, html_file, prefix, options)
+ super(context, options)
- if options.all_one_file
- @path = context.full_name
- else
- @path = http_url(context.full_name, prefix)
- end
+ @html_file = html_file
+ @is_module = context.is_module?
+ @values = {}
- AllReferences.add("NODE(#{@context.full_name})", self)
- end
+ context.viewer = self
- def name
- @context.name
- end
+ if options.all_one_file
+ @path = context.full_name
+ else
+ @path = http_url(context.full_name, prefix)
+ end
- # return the relative file name to store this class in,
- # which is also its url
- def http_url(full_name, prefix)
- path = full_name.dup
- path.gsub!(/<<\s*(\w*)/) { "from-#$1" } if path['<<']
- File.join(prefix, path.split("::").collect { |p| Digest::MD5.hexdigest(p) }) + ".html"
- end
+ AllReferences.add("NODE(#{@context.full_name})", self)
+ end
- def parent_name
- @context.parent.full_name
- end
+ def name
+ @context.name
+ end
- def index_name
- name
- end
+ # return the relative file name to store this class in,
+ # which is also its url
+ def http_url(full_name, prefix)
+ path = full_name.dup
+ path.gsub!(/<<\s*(\w*)/) { "from-#$1" } if path['<<']
+ File.join(prefix, path.split("::").collect { |p| Digest::MD5.hexdigest(p) }) + ".html"
+ end
- def write_on(f)
- value_hash
+ def parent_name
+ @context.parent.full_name
+ end
- template = TemplatePage.new(
- RDoc::Page::BODYINC,
- RDoc::Page::NODE_PAGE,
+ def index_name
+ name
+ end
- RDoc::Page::METHOD_LIST)
- template.write_html_on(f, @values)
- end
+ def write_on(f)
+ value_hash
- def value_hash
- class_attribute_values
- add_table_of_sections
+ template = TemplatePage.new(
+ RDoc::Page::BODYINC,
+ RDoc::Page::NODE_PAGE,
- @values["charset"] = @options.charset
- @values["style_url"] = style_url(path, @options.css)
+ RDoc::Page::METHOD_LIST)
+ template.write_html_on(f, @values)
+ end
- d = markup(@context.comment)
- @values["description"] = d unless d.empty?
+ def value_hash
+ class_attribute_values
+ add_table_of_sections
- ml = build_method_summary_list
- @values["methods"] = ml unless ml.empty?
+ @values["charset"] = @options.charset
+ @values["style_url"] = style_url(path, @options.css)
- rl = build_resource_summary_list
- @values["resources"] = rl unless rl.empty?
+ d = markup(@context.comment)
+ @values["description"] = d unless d.empty?
- il = build_include_list(@context)
- @values["includes"] = il unless il.empty?
+ ml = build_method_summary_list
+ @values["methods"] = ml unless ml.empty?
- rl = build_require_list(@context)
- @values["requires"] = rl unless rl.empty?
+ rl = build_resource_summary_list
+ @values["resources"] = rl unless rl.empty?
- rl = build_realize_list(@context)
- @values["realizes"] = rl unless rl.empty?
+ il = build_include_list(@context)
+ @values["includes"] = il unless il.empty?
- cl = build_child_list(@context)
- @values["childs"] = cl unless cl.empty?
+ rl = build_require_list(@context)
+ @values["requires"] = rl unless rl.empty?
- @values["sections"] = @context.sections.map do |section|
+ rl = build_realize_list(@context)
+ @values["realizes"] = rl unless rl.empty?
- secdata = {
- "sectitle" => section.title,
- "secsequence" => section.sequence,
- "seccomment" => markup(section.comment)
- }
+ cl = build_child_list(@context)
+ @values["childs"] = cl unless cl.empty?
- al = build_alias_summary_list(section)
- secdata["aliases"] = al unless al.empty?
+ @values["sections"] = @context.sections.map do |section|
- co = build_constants_summary_list(section)
- secdata["constants"] = co unless co.empty?
+ secdata = {
+ "sectitle" => section.title,
+ "secsequence" => section.sequence,
+ "seccomment" => markup(section.comment)
+ }
- al = build_attribute_list(section)
- secdata["attributes"] = al unless al.empty?
+ al = build_alias_summary_list(section)
+ secdata["aliases"] = al unless al.empty?
- cl = build_class_list(0, @context, section)
- secdata["classlist"] = cl unless cl.empty?
+ co = build_constants_summary_list(section)
+ secdata["constants"] = co unless co.empty?
- mdl = build_method_detail_list(section)
- secdata["method_list"] = mdl unless mdl.empty?
+ al = build_attribute_list(section)
+ secdata["attributes"] = al unless al.empty?
- rdl = build_resource_detail_list(section)
- secdata["resource_list"] = rdl unless rdl.empty?
+ cl = build_class_list(0, @context, section)
+ secdata["classlist"] = cl unless cl.empty?
- secdata
- end
+ mdl = build_method_detail_list(section)
+ secdata["method_list"] = mdl unless mdl.empty?
- @values
- end
+ rdl = build_resource_detail_list(section)
+ secdata["resource_list"] = rdl unless rdl.empty?
- def build_attribute_list(section)
- atts = @context.attributes.sort
- res = []
- atts.each do |att|
- next unless att.section == section
- if att.visibility == :public || att.visibility == :protected || @options.show_all
- entry = {
- "name" => CGI.escapeHTML(att.name),
- "rw" => att.rw,
- "a_desc" => markup(att.comment, true)
- }
- unless att.visibility == :public || att.visibility == :protected
- entry["rw"] << "-"
- end
- res << entry
- end
- end
- res
- end
+ secdata
+ end
- def class_attribute_values
- h_name = CGI.escapeHTML(name)
+ @values
+ end
- @values["classmod"] = "Node"
- @values["title"] = CGI.escapeHTML("#{@values['classmod']}: #{h_name}")
+ def build_attribute_list(section)
+ atts = @context.attributes.sort
+ res = []
+ atts.each do |att|
+ next unless att.section == section
+ if att.visibility == :public || att.visibility == :protected || @options.show_all
+ entry = {
+ "name" => CGI.escapeHTML(att.name),
+ "rw" => att.rw,
+ "a_desc" => markup(att.comment, true)
+ }
+ unless att.visibility == :public || att.visibility == :protected
+ entry["rw"] << "-"
+ end
+ res << entry
+ end
+ end
+ res
+ end
- c = @context
- c = c.parent while c and !c.diagram
+ def class_attribute_values
+ h_name = CGI.escapeHTML(name)
- @values["diagram"] = diagram_reference(c.diagram) if c && c.diagram
+ @values["classmod"] = "Node"
+ @values["title"] = CGI.escapeHTML("#{@values['classmod']}: #{h_name}")
- @values["full_name"] = h_name
+ c = @context
+ c = c.parent while c and !c.diagram
- parent_class = @context.superclass
+ @values["diagram"] = diagram_reference(c.diagram) if c && c.diagram
- if parent_class
- @values["parent"] = CGI.escapeHTML(parent_class)
+ @values["full_name"] = h_name
- if parent_name
- lookup = parent_name + "::#{parent_class}"
- else
- lookup = parent_class
- end
- lookup = "NODE(#{lookup})"
- parent_url = AllReferences[lookup] || AllReferences[parent_class]
- @values["par_url"] = aref_to(parent_url.path) if parent_url and parent_url.document_self
- end
+ parent_class = @context.superclass
- files = []
- @context.in_files.each do |f|
- res = {}
- full_path = CGI.escapeHTML(f.file_absolute_name)
+ if parent_class
+ @values["parent"] = CGI.escapeHTML(parent_class)
- res["full_path"] = full_path
- res["full_path_url"] = aref_to(f.viewer.path) if f.document_self
+ if parent_name
+ lookup = parent_name + "::#{parent_class}"
+ else
+ lookup = parent_class
+ end
+ lookup = "NODE(#{lookup})"
+ parent_url = AllReferences[lookup] || AllReferences[parent_class]
+ @values["par_url"] = aref_to(parent_url.path) if parent_url and parent_url.document_self
+ end
- res["cvsurl"] = cvs_url( @options.webcvs, full_path ) if @options.webcvs
+ files = []
+ @context.in_files.each do |f|
+ res = {}
+ full_path = CGI.escapeHTML(f.file_absolute_name)
- files << res
- end
+ res["full_path"] = full_path
+ res["full_path_url"] = aref_to(f.viewer.path) if f.document_self
- @values['infiles'] = files
- end
+ res["cvsurl"] = cvs_url( @options.webcvs, full_path ) if @options.webcvs
- def build_require_list(context)
- build_referenced_list(context.requires)
- end
+ files << res
+ end
- def build_realize_list(context)
- build_referenced_list(context.realizes)
- end
+ @values['infiles'] = files
+ end
- def build_child_list(context)
- build_referenced_list(context.childs)
- end
+ def build_require_list(context)
+ build_referenced_list(context.requires)
+ end
- def <=>(other)
- self.name <=> other.name
- end
+ def build_realize_list(context)
+ build_referenced_list(context.realizes)
end
- class HTMLPuppetModule < HtmlClass
+ def build_child_list(context)
+ build_referenced_list(context.childs)
+ end
- def initialize(context, html_file, prefix, options)
- super(context, html_file, prefix, options)
- end
+ def <=>(other)
+ self.name <=> other.name
+ end
+ end
- def value_hash
- @values = super
+ class HTMLPuppetModule < HtmlClass
- fl = build_facts_summary_list
- @values["facts"] = fl unless fl.empty?
+ def initialize(context, html_file, prefix, options)
+ super(context, html_file, prefix, options)
+ end
- pl = build_plugins_summary_list
- @values["plugins"] = pl unless pl.empty?
+ def value_hash
+ @values = super
- nl = build_nodes_list(0, @context)
- @values["nodelist"] = nl unless nl.empty?
+ fl = build_facts_summary_list
+ @values["facts"] = fl unless fl.empty?
- @values
- end
+ pl = build_plugins_summary_list
+ @values["plugins"] = pl unless pl.empty?
- def build_nodes_list(level, context)
- res = ""
- prefix = " ::" * level;
-
- context.nodes.sort.each do |node|
- if node.document_self
- res <<
- prefix <<
- "Node " <<
- href(url(node.viewer.path), "link", node.full_name) <<
- "<br />\n"
- end
- end
- res
- end
+ nl = build_nodes_list(0, @context)
+ @values["nodelist"] = nl unless nl.empty?
- def build_facts_summary_list
- potentially_referenced_list(context.facts) {|fn| ["PLUGIN(#{fn})"] }
- end
+ @values
+ end
- def build_plugins_summary_list
- potentially_referenced_list(context.plugins) {|fn| ["PLUGIN(#{fn})"] }
- end
+ def build_nodes_list(level, context)
+ res = ""
+ prefix = " ::" * level;
- def facts
- @context.facts
+ context.nodes.sort.each do |node|
+ if node.document_self
+ res <<
+ prefix <<
+ "Node " <<
+ href(url(node.viewer.path), "link", node.full_name) <<
+ "<br />\n"
end
+ end
+ res
+ end
- def plugins
- @context.plugins
- end
+ def build_facts_summary_list
+ potentially_referenced_list(context.facts) {|fn| ["PLUGIN(#{fn})"] }
+ end
+ def build_plugins_summary_list
+ potentially_referenced_list(context.plugins) {|fn| ["PLUGIN(#{fn})"] }
end
- class HTMLPuppetPlugin < ContextUser
- attr_reader :path
+ def facts
+ @context.facts
+ end
- def initialize(context, html_file, prefix, options)
- super(context, options)
+ def plugins
+ @context.plugins
+ end
- @html_file = html_file
- @is_module = false
- @values = {}
+ end
- context.viewer = self
+ class HTMLPuppetPlugin < ContextUser
+ attr_reader :path
- if options.all_one_file
- @path = context.full_name
- else
- @path = http_url(context.full_name, prefix)
- end
+ def initialize(context, html_file, prefix, options)
+ super(context, options)
- AllReferences.add("PLUGIN(#{@context.full_name})", self)
- end
+ @html_file = html_file
+ @is_module = false
+ @values = {}
- def name
- @context.name
- end
+ context.viewer = self
- # return the relative file name to store this class in,
- # which is also its url
- def http_url(full_name, prefix)
- path = full_name.dup
- path.gsub!(/<<\s*(\w*)/) { "from-#$1" } if path['<<']
- File.join(prefix, path.split("::")) + ".html"
- end
+ if options.all_one_file
+ @path = context.full_name
+ else
+ @path = http_url(context.full_name, prefix)
+ end
- def parent_name
- @context.parent.full_name
- end
+ AllReferences.add("PLUGIN(#{@context.full_name})", self)
+ end
- def index_name
- name
- end
+ def name
+ @context.name
+ end
- def write_on(f)
- value_hash
+ # return the relative file name to store this class in,
+ # which is also its url
+ def http_url(full_name, prefix)
+ path = full_name.dup
+ path.gsub!(/<<\s*(\w*)/) { "from-#$1" } if path['<<']
+ File.join(prefix, path.split("::")) + ".html"
+ end
- template = TemplatePage.new(
- RDoc::Page::BODYINC,
- RDoc::Page::PLUGIN_PAGE,
+ def parent_name
+ @context.parent.full_name
+ end
- RDoc::Page::PLUGIN_LIST)
- template.write_html_on(f, @values)
- end
+ def index_name
+ name
+ end
- def value_hash
- attribute_values
- add_table_of_sections
-
- @values["charset"] = @options.charset
- @values["style_url"] = style_url(path, @options.css)
-
- d = markup(@context.comment)
- @values["description"] = d unless d.empty?
-
- if context.is_fact?
- unless context.confine.empty?
- res = {}
- res["type"] = context.confine[:type]
- res["value"] = context.confine[:value]
- @values["confine"] = [res]
- end
- else
- @values["type"] = context.type
- end
+ def write_on(f)
+ value_hash
- @values["sections"] = @context.sections.map do |section|
- secdata = {
- "sectitle" => section.title,
- "secsequence" => section.sequence,
- "seccomment" => markup(section.comment)
- }
- secdata
- end
+ template = TemplatePage.new(
+ RDoc::Page::BODYINC,
+ RDoc::Page::PLUGIN_PAGE,
- @values
- end
+ RDoc::Page::PLUGIN_LIST)
+ template.write_html_on(f, @values)
+ end
- def attribute_values
- h_name = CGI.escapeHTML(name)
+ def value_hash
+ attribute_values
+ add_table_of_sections
+
+ @values["charset"] = @options.charset
+ @values["style_url"] = style_url(path, @options.css)
+
+ d = markup(@context.comment)
+ @values["description"] = d unless d.empty?
+
+ if context.is_fact?
+ unless context.confine.empty?
+ res = {}
+ res["type"] = context.confine[:type]
+ res["value"] = context.confine[:value]
+ @values["confine"] = [res]
+ end
+ else
+ @values["type"] = context.type
+ end
+
+ @values["sections"] = @context.sections.map do |section|
+ secdata = {
+ "sectitle" => section.title,
+ "secsequence" => section.sequence,
+ "seccomment" => markup(section.comment)
+ }
+ secdata
+ end
+
+ @values
+ end
- if @context.is_fact?
- @values["classmod"] = "Fact"
- else
- @values["classmod"] = "Plugin"
- end
- @values["title"] = "#{@values['classmod']}: #{h_name}"
+ def attribute_values
+ h_name = CGI.escapeHTML(name)
- c = @context
- @values["full_name"] = h_name
+ if @context.is_fact?
+ @values["classmod"] = "Fact"
+ else
+ @values["classmod"] = "Plugin"
+ end
+ @values["title"] = "#{@values['classmod']}: #{h_name}"
- files = []
- @context.in_files.each do |f|
- res = {}
- full_path = CGI.escapeHTML(f.file_absolute_name)
+ c = @context
+ @values["full_name"] = h_name
- res["full_path"] = full_path
- res["full_path_url"] = aref_to(f.viewer.path) if f.document_self
+ files = []
+ @context.in_files.each do |f|
+ res = {}
+ full_path = CGI.escapeHTML(f.file_absolute_name)
- res["cvsurl"] = cvs_url( @options.webcvs, full_path ) if @options.webcvs
+ res["full_path"] = full_path
+ res["full_path_url"] = aref_to(f.viewer.path) if f.document_self
- files << res
- end
+ res["cvsurl"] = cvs_url( @options.webcvs, full_path ) if @options.webcvs
- @values['infiles'] = files
- end
+ files << res
+ end
- def <=>(other)
- self.name <=> other.name
- end
+ @values['infiles'] = files
+ end
+ def <=>(other)
+ self.name <=> other.name
end
- class HTMLPuppetResource
- include MarkUp
+ end
- attr_reader :context
+ class HTMLPuppetResource
+ include MarkUp
- @@seq = "R000000"
+ attr_reader :context
- def initialize(context, html_class, options)
- @context = context
- @html_class = html_class
- @options = options
- @@seq = @@seq.succ
- @seq = @@seq
+ @@seq = "R000000"
- context.viewer = self
+ def initialize(context, html_class, options)
+ @context = context
+ @html_class = html_class
+ @options = options
+ @@seq = @@seq.succ
+ @seq = @@seq
- AllReferences.add(name, self)
- end
+ context.viewer = self
- def as_href(from_path)
- if @options.all_one_file
- "##{path}"
- else
- HTMLGenerator.gen_url(from_path, path)
- end
- end
+ AllReferences.add(name, self)
+ end
- def name
- @context.name
- end
+ def as_href(from_path)
+ if @options.all_one_file
+ "##{path}"
+ else
+ HTMLGenerator.gen_url(from_path, path)
+ end
+ end
- def section
- @context.section
- end
+ def name
+ @context.name
+ end
- def index_name
- "#{@context.name}"
- end
+ def section
+ @context.section
+ end
- def params
- @context.params
- end
+ def index_name
+ "#{@context.name}"
+ end
- def parent_name
- if @context.parent.parent
- @context.parent.parent.full_name
- else
- nil
- end
- end
+ def params
+ @context.params
+ end
- def aref
- @seq
- end
+ def parent_name
+ if @context.parent.parent
+ @context.parent.parent.full_name
+ else
+ nil
+ end
+ end
- def path
- if @options.all_one_file
- aref
- else
- @html_class.path + "##{aref}"
- end
- end
+ def aref
+ @seq
+ end
- def description
- markup(@context.comment)
- end
+ def path
+ if @options.all_one_file
+ aref
+ else
+ @html_class.path + "##{aref}"
+ end
+ end
- def <=>(other)
- @context <=> other.context
- end
+ def description
+ markup(@context.comment)
+ end
- def document_self
- @context.document_self
- end
+ def <=>(other)
+ @context <=> other.context
+ end
- def find_symbol(symbol, method=nil)
- res = @context.parent.find_symbol(symbol, method)
- res &&= res.viewer
- end
+ def document_self
+ @context.document_self
+ end
+ def find_symbol(symbol, method=nil)
+ res = @context.parent.find_symbol(symbol, method)
+ res &&= res.viewer
end
- class PuppetGeneratorInOne < HTMLGeneratorInOne
- def gen_method_index
- gen_an_index(HtmlMethod.all_methods, 'Defines')
- end
+ end
+
+ class PuppetGeneratorInOne < HTMLGeneratorInOne
+ def gen_method_index
+ gen_an_index(HtmlMethod.all_methods, 'Defines')
end
+ end
end
diff --git a/lib/puppet/util/rdoc/parser.rb b/lib/puppet/util/rdoc/parser.rb
index b0ff988..573d176 100644
--- a/lib/puppet/util/rdoc/parser.rb
+++ b/lib/puppet/util/rdoc/parser.rb
@@ -13,463 +13,463 @@ require "rdoc/parsers/parserfactory"
module RDoc
class Parser
- extend ParserFactory
-
- attr_accessor :ast, :input_file_name, :top_level
-
- # parser registration into RDoc
- parse_files_matching(/\.(rb|pp)$/)
-
- # called with the top level file
- def initialize(top_level, file_name, content, options, stats)
- @options = options
- @stats = stats
- @input_file_name = file_name
- @top_level = PuppetTopLevel.new(top_level)
- @progress = $stderr unless options.quiet
+ extend ParserFactory
+
+ attr_accessor :ast, :input_file_name, :top_level
+
+ # parser registration into RDoc
+ parse_files_matching(/\.(rb|pp)$/)
+
+ # called with the top level file
+ def initialize(top_level, file_name, content, options, stats)
+ @options = options
+ @stats = stats
+ @input_file_name = file_name
+ @top_level = PuppetTopLevel.new(top_level)
+ @progress = $stderr unless options.quiet
+ end
+
+ # main entry point
+ def scan
+ Puppet.info "rdoc: scanning #{@input_file_name}"
+ if @input_file_name =~ /\.pp$/
+ @parser = Puppet::Parser::Parser.new(Puppet[:environment])
+ @parser.file = @input_file_name
+ @ast = @parser.parse
end
-
- # main entry point
- def scan
- Puppet.info "rdoc: scanning #{@input_file_name}"
- if @input_file_name =~ /\.pp$/
- @parser = Puppet::Parser::Parser.new(Puppet[:environment])
- @parser.file = @input_file_name
- @ast = @parser.parse
- end
- scan_top_level(@top_level)
- @top_level
+ scan_top_level(@top_level)
+ @top_level
+ end
+
+ # Due to a bug in RDoc, we need to roll our own find_module_named
+ # The issue is that RDoc tries harder by asking the parent for a class/module
+ # of the name. But by doing so, it can mistakenly use a module of same name
+ # but from which we are not descendant.
+ def find_object_named(container, name)
+ return container if container.name == name
+ container.each_classmodule do |m|
+ return m if m.name == name
end
+ nil
+ end
- # Due to a bug in RDoc, we need to roll our own find_module_named
- # The issue is that RDoc tries harder by asking the parent for a class/module
- # of the name. But by doing so, it can mistakenly use a module of same name
- # but from which we are not descendant.
- def find_object_named(container, name)
- return container if container.name == name
- container.each_classmodule do |m|
- return m if m.name == name
- end
- nil
- end
-
- # walk down the namespace and lookup/create container as needed
- def get_class_or_module(container, name)
+ # walk down the namespace and lookup/create container as needed
+ def get_class_or_module(container, name)
- # class ::A -> A is in the top level
- if name =~ /^::/
- container = @top_level
- end
+ # class ::A -> A is in the top level
+ if name =~ /^::/
+ container = @top_level
+ end
- names = name.split('::')
+ names = name.split('::')
- final_name = names.pop
- names.each do |name|
- prev_container = container
- container = find_object_named(container, name)
- container ||= prev_container.add_class(PuppetClass, name, nil)
- end
- [container, final_name]
+ final_name = names.pop
+ names.each do |name|
+ prev_container = container
+ container = find_object_named(container, name)
+ container ||= prev_container.add_class(PuppetClass, name, nil)
end
-
- # split_module tries to find if +path+ belongs to the module path
- # if it does, it returns the module name, otherwise if we are sure
- # it is part of the global manifest path, "<site>" is returned.
- # And finally if this path couldn't be mapped anywhere, nil is returned.
- def split_module(path)
- # find a module
- fullpath = File.expand_path(path)
- Puppet.debug "rdoc: testing #{fullpath}"
- if fullpath =~ /(.*)\/([^\/]+)\/(?:manifests|plugins|lib)\/.+\.(pp|rb)$/
- modpath = $1
- name = $2
- Puppet.debug "rdoc: module #{name} into #{modpath} ?"
- Puppet::Module.modulepath.each do |mp|
- if File.identical?(modpath,mp)
- Puppet.debug "rdoc: found module #{name}"
- return name
- end
- end
- end
- if fullpath =~ /\.(pp|rb)$/
- # there can be paths we don't want to scan under modules
- # imagine a ruby or manifest that would be distributed as part as a module
- # but we don't want those to be hosted under <site>
- Puppet::Module.modulepath.each do |mp|
- # check that fullpath is a descendant of mp
- dirname = fullpath
- while (dirname = File.dirname(dirname)) != '/'
- return nil if File.identical?(dirname,mp)
- end
- end
+ [container, final_name]
+ end
+
+ # split_module tries to find if +path+ belongs to the module path
+ # if it does, it returns the module name, otherwise if we are sure
+ # it is part of the global manifest path, "<site>" is returned.
+ # And finally if this path couldn't be mapped anywhere, nil is returned.
+ def split_module(path)
+ # find a module
+ fullpath = File.expand_path(path)
+ Puppet.debug "rdoc: testing #{fullpath}"
+ if fullpath =~ /(.*)\/([^\/]+)\/(?:manifests|plugins|lib)\/.+\.(pp|rb)$/
+ modpath = $1
+ name = $2
+ Puppet.debug "rdoc: module #{name} into #{modpath} ?"
+ Puppet::Module.modulepath.each do |mp|
+ if File.identical?(modpath,mp)
+ Puppet.debug "rdoc: found module #{name}"
+ return name
end
- # we are under a global manifests
- Puppet.debug "rdoc: global manifests"
- "<site>"
+ end
end
-
- # create documentation for the top level +container+
- def scan_top_level(container)
- # use the module README as documentation for the module
- comment = ""
- readme = File.join(File.dirname(File.dirname(@input_file_name)), "README")
- comment = File.open(readme,"r") { |f| f.read } if FileTest.readable?(readme)
- look_for_directives_in(container, comment) unless comment.empty?
-
- # infer module name from directory
- name = split_module(@input_file_name)
- if name.nil?
- # skip .pp files that are not in manifests directories as we can't guarantee they're part
- # of a module or the global configuration.
- container.document_self = false
- return
+ if fullpath =~ /\.(pp|rb)$/
+ # there can be paths we don't want to scan under modules
+ # imagine a ruby or manifest that would be distributed as part as a module
+ # but we don't want those to be hosted under <site>
+ Puppet::Module.modulepath.each do |mp|
+ # check that fullpath is a descendant of mp
+ dirname = fullpath
+ while (dirname = File.dirname(dirname)) != '/'
+ return nil if File.identical?(dirname,mp)
end
+ end
+ end
+ # we are under a global manifests
+ Puppet.debug "rdoc: global manifests"
+ "<site>"
+ end
+
+ # create documentation for the top level +container+
+ def scan_top_level(container)
+ # use the module README as documentation for the module
+ comment = ""
+ readme = File.join(File.dirname(File.dirname(@input_file_name)), "README")
+ comment = File.open(readme,"r") { |f| f.read } if FileTest.readable?(readme)
+ look_for_directives_in(container, comment) unless comment.empty?
+
+ # infer module name from directory
+ name = split_module(@input_file_name)
+ if name.nil?
+ # skip .pp files that are not in manifests directories as we can't guarantee they're part
+ # of a module or the global configuration.
+ container.document_self = false
+ return
+ end
- Puppet.debug "rdoc: scanning for #{name}"
+ Puppet.debug "rdoc: scanning for #{name}"
- container.module_name = name
- container.global=true if name == "<site>"
+ container.module_name = name
+ container.global=true if name == "<site>"
- @stats.num_modules += 1
- container, name = get_class_or_module(container,name)
- mod = container.add_module(PuppetModule, name)
- mod.record_location(@top_level)
- mod.comment = comment
+ @stats.num_modules += 1
+ container, name = get_class_or_module(container,name)
+ mod = container.add_module(PuppetModule, name)
+ mod.record_location(@top_level)
+ mod.comment = comment
- if @input_file_name =~ /\.pp$/
- parse_elements(mod)
- elsif @input_file_name =~ /\.rb$/
- parse_plugins(mod)
- end
+ if @input_file_name =~ /\.pp$/
+ parse_elements(mod)
+ elsif @input_file_name =~ /\.rb$/
+ parse_plugins(mod)
end
-
- # create documentation for include statements we can find in +code+
- # and associate it with +container+
- def scan_for_include_or_require(container, code)
- code = [code] unless code.is_a?(Array)
- code.each do |stmt|
- scan_for_include_or_require(container,stmt.children) if stmt.is_a?(Puppet::Parser::AST::ASTArray)
-
- if stmt.is_a?(Puppet::Parser::AST::Function) and ['include','require'].include?(stmt.name)
- stmt.arguments.each do |included|
- Puppet.debug "found #{stmt.name}: #{included.value}"
- container.send("add_#{stmt.name}",Include.new(included.value, stmt.doc))
- end
- end
+ end
+
+ # create documentation for include statements we can find in +code+
+ # and associate it with +container+
+ def scan_for_include_or_require(container, code)
+ code = [code] unless code.is_a?(Array)
+ code.each do |stmt|
+ scan_for_include_or_require(container,stmt.children) if stmt.is_a?(Puppet::Parser::AST::ASTArray)
+
+ if stmt.is_a?(Puppet::Parser::AST::Function) and ['include','require'].include?(stmt.name)
+ stmt.arguments.each do |included|
+ Puppet.debug "found #{stmt.name}: #{included.value}"
+ container.send("add_#{stmt.name}",Include.new(included.value, stmt.doc))
end
+ end
end
-
- # create documentation for realize statements we can find in +code+
- # and associate it with +container+
- def scan_for_realize(container, code)
- code = [code] unless code.is_a?(Array)
- code.each do |stmt|
- scan_for_realize(container,stmt.children) if stmt.is_a?(Puppet::Parser::AST::ASTArray)
-
- if stmt.is_a?(Puppet::Parser::AST::Function) and stmt.name == 'realize'
- stmt.arguments.each do |realized|
- Puppet.debug "found #{stmt.name}: #{realized}"
- container.add_realize(Include.new(realized.to_s, stmt.doc))
- end
- end
+ end
+
+ # create documentation for realize statements we can find in +code+
+ # and associate it with +container+
+ def scan_for_realize(container, code)
+ code = [code] unless code.is_a?(Array)
+ code.each do |stmt|
+ scan_for_realize(container,stmt.children) if stmt.is_a?(Puppet::Parser::AST::ASTArray)
+
+ if stmt.is_a?(Puppet::Parser::AST::Function) and stmt.name == 'realize'
+ stmt.arguments.each do |realized|
+ Puppet.debug "found #{stmt.name}: #{realized}"
+ container.add_realize(Include.new(realized.to_s, stmt.doc))
end
+ end
end
-
- # create documentation for global variables assignements we can find in +code+
- # and associate it with +container+
- def scan_for_vardef(container, code)
- code = [code] unless code.is_a?(Array)
- code.each do |stmt|
- scan_for_vardef(container,stmt.children) if stmt.is_a?(Puppet::Parser::AST::ASTArray)
-
- if stmt.is_a?(Puppet::Parser::AST::VarDef)
- Puppet.debug "rdoc: found constant: #{stmt.name} = #{stmt.value}"
- container.add_constant(Constant.new(stmt.name.to_s, stmt.value.to_s, stmt.doc))
- end
- end
+ end
+
+ # create documentation for global variables assignements we can find in +code+
+ # and associate it with +container+
+ def scan_for_vardef(container, code)
+ code = [code] unless code.is_a?(Array)
+ code.each do |stmt|
+ scan_for_vardef(container,stmt.children) if stmt.is_a?(Puppet::Parser::AST::ASTArray)
+
+ if stmt.is_a?(Puppet::Parser::AST::VarDef)
+ Puppet.debug "rdoc: found constant: #{stmt.name} = #{stmt.value}"
+ container.add_constant(Constant.new(stmt.name.to_s, stmt.value.to_s, stmt.doc))
+ end
end
-
- # create documentation for resources we can find in +code+
- # and associate it with +container+
- def scan_for_resource(container, code)
- code = [code] unless code.is_a?(Array)
- code.each do |stmt|
- scan_for_resource(container,stmt.children) if stmt.is_a?(Puppet::Parser::AST::ASTArray)
-
- if stmt.is_a?(Puppet::Parser::AST::Resource) and !stmt.type.nil?
- begin
- type = stmt.type.split("::").collect { |s| s.capitalize }.join("::")
- title = stmt.title.is_a?(Puppet::Parser::AST::ASTArray) ? stmt.title.to_s.gsub(/\[(.*)\]/,'\1') : stmt.title.to_s
- Puppet.debug "rdoc: found resource: #{type}[#{title}]"
-
- param = []
- stmt.params.children.each do |p|
- res = {}
- res["name"] = p.param
- res["value"] = "#{p.value.to_s}" unless p.value.nil?
-
- param << res
- end
-
- container.add_resource(PuppetResource.new(type, title, stmt.doc, param))
- rescue => detail
- raise Puppet::ParseError, "impossible to parse resource in #{stmt.file} at line #{stmt.line}: #{detail}"
- end
- end
+ end
+
+ # create documentation for resources we can find in +code+
+ # and associate it with +container+
+ def scan_for_resource(container, code)
+ code = [code] unless code.is_a?(Array)
+ code.each do |stmt|
+ scan_for_resource(container,stmt.children) if stmt.is_a?(Puppet::Parser::AST::ASTArray)
+
+ if stmt.is_a?(Puppet::Parser::AST::Resource) and !stmt.type.nil?
+ begin
+ type = stmt.type.split("::").collect { |s| s.capitalize }.join("::")
+ title = stmt.title.is_a?(Puppet::Parser::AST::ASTArray) ? stmt.title.to_s.gsub(/\[(.*)\]/,'\1') : stmt.title.to_s
+ Puppet.debug "rdoc: found resource: #{type}[#{title}]"
+
+ param = []
+ stmt.params.children.each do |p|
+ res = {}
+ res["name"] = p.param
+ res["value"] = "#{p.value.to_s}" unless p.value.nil?
+
+ param << res
+ end
+
+ container.add_resource(PuppetResource.new(type, title, stmt.doc, param))
+ rescue => detail
+ raise Puppet::ParseError, "impossible to parse resource in #{stmt.file} at line #{stmt.line}: #{detail}"
end
+ end
end
+ end
- def resource_stmt_to_ref(stmt)
- type = stmt.type.split("::").collect { |s| s.capitalize }.join("::")
- title = stmt.title.is_a?(Puppet::Parser::AST::ASTArray) ? stmt.title.to_s.gsub(/\[(.*)\]/,'\1') : stmt.title.to_s
+ def resource_stmt_to_ref(stmt)
+ type = stmt.type.split("::").collect { |s| s.capitalize }.join("::")
+ title = stmt.title.is_a?(Puppet::Parser::AST::ASTArray) ? stmt.title.to_s.gsub(/\[(.*)\]/,'\1') : stmt.title.to_s
- param = stmt.params.children.collect do |p|
- {"name" => p.param, "value" => p.value.to_s}
- end
- PuppetResource.new(type, title, stmt.doc, param)
+ param = stmt.params.children.collect do |p|
+ {"name" => p.param, "value" => p.value.to_s}
end
-
- # create documentation for a class named +name+
- def document_class(name, klass, container)
- Puppet.debug "rdoc: found new class #{name}"
- container, name = get_class_or_module(container, name)
-
- superclass = klass.parent
- superclass = "" if superclass.nil? or superclass.empty?
-
- @stats.num_classes += 1
- comment = klass.doc
- look_for_directives_in(container, comment) unless comment.empty?
- cls = container.add_class(PuppetClass, name, superclass)
- # it is possible we already encountered this class, while parsing some namespaces
- # from other classes of other files. But at that time we couldn't know this class superclass
- # so, now we know it and force it.
- cls.superclass = superclass
- cls.record_location(@top_level)
-
- # scan class code for include
- code = klass.code.children if klass.code.is_a?(Puppet::Parser::AST::ASTArray)
- code ||= klass.code
- unless code.nil?
- scan_for_include_or_require(cls, code)
- scan_for_realize(cls, code)
- scan_for_resource(cls, code) if Puppet.settings[:document_all]
- end
-
- cls.comment = comment
- rescue => detail
- raise Puppet::ParseError, "impossible to parse class '#{name}' in #{klass.file} at line #{klass.line}: #{detail}"
+ PuppetResource.new(type, title, stmt.doc, param)
+ end
+
+ # create documentation for a class named +name+
+ def document_class(name, klass, container)
+ Puppet.debug "rdoc: found new class #{name}"
+ container, name = get_class_or_module(container, name)
+
+ superclass = klass.parent
+ superclass = "" if superclass.nil? or superclass.empty?
+
+ @stats.num_classes += 1
+ comment = klass.doc
+ look_for_directives_in(container, comment) unless comment.empty?
+ cls = container.add_class(PuppetClass, name, superclass)
+ # it is possible we already encountered this class, while parsing some namespaces
+ # from other classes of other files. But at that time we couldn't know this class superclass
+ # so, now we know it and force it.
+ cls.superclass = superclass
+ cls.record_location(@top_level)
+
+ # scan class code for include
+ code = klass.code.children if klass.code.is_a?(Puppet::Parser::AST::ASTArray)
+ code ||= klass.code
+ unless code.nil?
+ scan_for_include_or_require(cls, code)
+ scan_for_realize(cls, code)
+ scan_for_resource(cls, code) if Puppet.settings[:document_all]
end
- # create documentation for a node
- def document_node(name, node, container)
- Puppet.debug "rdoc: found new node #{name}"
- superclass = node.parent
- superclass = "" if superclass.nil? or superclass.empty?
-
- comment = node.doc
- look_for_directives_in(container, comment) unless comment.empty?
- n = container.add_node(name, superclass)
- n.record_location(@top_level)
-
- code = node.code.children if node.code.is_a?(Puppet::Parser::AST::ASTArray)
- code ||= node.code
- unless code.nil?
- scan_for_include_or_require(n, code)
- scan_for_realize(n, code)
- scan_for_vardef(n, code)
- scan_for_resource(n, code) if Puppet.settings[:document_all]
- end
-
- n.comment = comment
- rescue => detail
- raise Puppet::ParseError, "impossible to parse node '#{name}' in #{node.file} at line #{node.line}: #{detail}"
+ cls.comment = comment
+ rescue => detail
+ raise Puppet::ParseError, "impossible to parse class '#{name}' in #{klass.file} at line #{klass.line}: #{detail}"
+ end
+
+ # create documentation for a node
+ def document_node(name, node, container)
+ Puppet.debug "rdoc: found new node #{name}"
+ superclass = node.parent
+ superclass = "" if superclass.nil? or superclass.empty?
+
+ comment = node.doc
+ look_for_directives_in(container, comment) unless comment.empty?
+ n = container.add_node(name, superclass)
+ n.record_location(@top_level)
+
+ code = node.code.children if node.code.is_a?(Puppet::Parser::AST::ASTArray)
+ code ||= node.code
+ unless code.nil?
+ scan_for_include_or_require(n, code)
+ scan_for_realize(n, code)
+ scan_for_vardef(n, code)
+ scan_for_resource(n, code) if Puppet.settings[:document_all]
end
- # create documentation for a define
- def document_define(name, define, container)
- Puppet.debug "rdoc: found new definition #{name}"
- # find superclas if any
- @stats.num_methods += 1
-
- # find the parent
- # split define name by :: to find the complete module hierarchy
- container, name = get_class_or_module(container,name)
-
- # build up declaration
- declaration = ""
- define.arguments.each do |arg,value|
- declaration << "\$#{arg}"
- unless value.nil?
- declaration << " => "
- case value
- when Puppet::Parser::AST::Leaf
- declaration << "'#{value.value}'"
- when Puppet::Parser::AST::ASTArray
- declaration << "[#{value.children.collect { |v| "'#{v}'" }.join(", ")}]"
- else
- declaration << "#{value.to_s}"
- end
- end
- declaration << ", "
+ n.comment = comment
+ rescue => detail
+ raise Puppet::ParseError, "impossible to parse node '#{name}' in #{node.file} at line #{node.line}: #{detail}"
+ end
+
+ # create documentation for a define
+ def document_define(name, define, container)
+ Puppet.debug "rdoc: found new definition #{name}"
+ # find superclas if any
+ @stats.num_methods += 1
+
+ # find the parent
+ # split define name by :: to find the complete module hierarchy
+ container, name = get_class_or_module(container,name)
+
+ # build up declaration
+ declaration = ""
+ define.arguments.each do |arg,value|
+ declaration << "\$#{arg}"
+ unless value.nil?
+ declaration << " => "
+ case value
+ when Puppet::Parser::AST::Leaf
+ declaration << "'#{value.value}'"
+ when Puppet::Parser::AST::ASTArray
+ declaration << "[#{value.children.collect { |v| "'#{v}'" }.join(", ")}]"
+ else
+ declaration << "#{value.to_s}"
end
- declaration.chop!.chop! if declaration.size > 1
-
- # register method into the container
- meth = AnyMethod.new(declaration, name)
- meth.comment = define.doc
- container.add_method(meth)
- look_for_directives_in(container, meth.comment) unless meth.comment.empty?
- meth.params = "( #{declaration} )"
- meth.visibility = :public
- meth.document_self = true
- meth.singleton = false
- rescue => detail
- raise Puppet::ParseError, "impossible to parse definition '#{name}' in #{define.file} at line #{define.line}: #{detail}"
+ end
+ declaration << ", "
end
-
- # Traverse the AST tree and produce code-objects node
- # that contains the documentation
- def parse_elements(container)
- Puppet.debug "rdoc: scanning manifest"
- @ast.hostclasses.values.sort { |a,b| a.name <=> b.name }.each do |klass|
- name = klass.name
- if klass.file == @input_file_name
- unless name.empty?
- document_class(name,klass,container)
- else # on main class document vardefs
- code = klass.code.children if klass.code.is_a?(Puppet::Parser::AST::ASTArray)
- code ||= klass.code
- scan_for_vardef(container, code) unless code.nil?
- end
- end
- end
-
- @ast.definitions.each do |name, define|
- if define.file == @input_file_name
- document_define(name,define,container)
- end
- end
-
- @ast.nodes.each do |name, node|
- if node.file == @input_file_name
- document_node(name.to_s,node,container)
- end
+ declaration.chop!.chop! if declaration.size > 1
+
+ # register method into the container
+ meth = AnyMethod.new(declaration, name)
+ meth.comment = define.doc
+ container.add_method(meth)
+ look_for_directives_in(container, meth.comment) unless meth.comment.empty?
+ meth.params = "( #{declaration} )"
+ meth.visibility = :public
+ meth.document_self = true
+ meth.singleton = false
+ rescue => detail
+ raise Puppet::ParseError, "impossible to parse definition '#{name}' in #{define.file} at line #{define.line}: #{detail}"
+ end
+
+ # Traverse the AST tree and produce code-objects node
+ # that contains the documentation
+ def parse_elements(container)
+ Puppet.debug "rdoc: scanning manifest"
+ @ast.hostclasses.values.sort { |a,b| a.name <=> b.name }.each do |klass|
+ name = klass.name
+ if klass.file == @input_file_name
+ unless name.empty?
+ document_class(name,klass,container)
+ else # on main class document vardefs
+ code = klass.code.children if klass.code.is_a?(Puppet::Parser::AST::ASTArray)
+ code ||= klass.code
+ scan_for_vardef(container, code) unless code.nil?
end
+ end
end
- # create documentation for plugins
- def parse_plugins(container)
- Puppet.debug "rdoc: scanning plugin or fact"
- if @input_file_name =~ /\/facter\/[^\/]+\.rb$/
- parse_fact(container)
- else
- parse_puppet_plugin(container)
- end
+ @ast.definitions.each do |name, define|
+ if define.file == @input_file_name
+ document_define(name,define,container)
+ end
end
- # this is a poor man custom fact parser :-)
- def parse_fact(container)
- comments = ""
- current_fact = nil
- File.open(@input_file_name) do |of|
- of.each do |line|
- # fetch comments
- if line =~ /^[ \t]*# ?(.*)$/
- comments += $1 + "\n"
- elsif line =~ /^[ \t]*Facter.add\(['"](.*?)['"]\)/
- current_fact = Fact.new($1,{})
- look_for_directives_in(container, comments) unless comments.empty?
- current_fact.comment = comments
- container.add_fact(current_fact)
- current_fact.record_location(@top_level)
- comments = ""
- Puppet.debug "rdoc: found custom fact #{current_fact.name}"
- elsif line =~ /^[ \t]*confine[ \t]*:(.*?)[ \t]*=>[ \t]*(.*)$/
- current_fact.confine = { :type => $1, :value => $2 } unless current_fact.nil?
- else # unknown line type
- comments =""
- end
- end
- end
+ @ast.nodes.each do |name, node|
+ if node.file == @input_file_name
+ document_node(name.to_s,node,container)
+ end
end
-
- # this is a poor man puppet plugin parser :-)
- # it doesn't extract doc nor desc :-(
- def parse_puppet_plugin(container)
- comments = ""
- current_plugin = nil
-
- File.open(@input_file_name) do |of|
- of.each do |line|
- # fetch comments
- if line =~ /^[ \t]*# ?(.*)$/
- comments += $1 + "\n"
- elsif line =~ /^[ \t]*newfunction[ \t]*\([ \t]*:(.*?)[ \t]*,[ \t]*:type[ \t]*=>[ \t]*(:rvalue|:lvalue)\)/
- current_plugin = Plugin.new($1, "function")
- container.add_plugin(current_plugin)
- look_for_directives_in(container, comments) unless comments.empty?
- current_plugin.comment = comments
- current_plugin.record_location(@top_level)
- comments = ""
- Puppet.debug "rdoc: found new function plugins #{current_plugin.name}"
- elsif line =~ /^[ \t]*Puppet::Type.newtype[ \t]*\([ \t]*:(.*?)\)/
- current_plugin = Plugin.new($1, "type")
- container.add_plugin(current_plugin)
- look_for_directives_in(container, comments) unless comments.empty?
- current_plugin.comment = comments
- current_plugin.record_location(@top_level)
- comments = ""
- Puppet.debug "rdoc: found new type plugins #{current_plugin.name}"
- elsif line =~ /module Puppet::Parser::Functions/
- # skip
- else # unknown line type
- comments =""
- end
- end
+ end
+
+ # create documentation for plugins
+ def parse_plugins(container)
+ Puppet.debug "rdoc: scanning plugin or fact"
+ if @input_file_name =~ /\/facter\/[^\/]+\.rb$/
+ parse_fact(container)
+ else
+ parse_puppet_plugin(container)
+ end
+ end
+
+ # this is a poor man custom fact parser :-)
+ def parse_fact(container)
+ comments = ""
+ current_fact = nil
+ File.open(@input_file_name) do |of|
+ of.each do |line|
+ # fetch comments
+ if line =~ /^[ \t]*# ?(.*)$/
+ comments += $1 + "\n"
+ elsif line =~ /^[ \t]*Facter.add\(['"](.*?)['"]\)/
+ current_fact = Fact.new($1,{})
+ look_for_directives_in(container, comments) unless comments.empty?
+ current_fact.comment = comments
+ container.add_fact(current_fact)
+ current_fact.record_location(@top_level)
+ comments = ""
+ Puppet.debug "rdoc: found custom fact #{current_fact.name}"
+ elsif line =~ /^[ \t]*confine[ \t]*:(.*?)[ \t]*=>[ \t]*(.*)$/
+ current_fact.confine = { :type => $1, :value => $2 } unless current_fact.nil?
+ else # unknown line type
+ comments =""
end
+ end
end
-
- # look_for_directives_in scans the current +comment+ for RDoc directives
- def look_for_directives_in(context, comment)
- preprocess = SM::PreProcess.new(@input_file_name, @options.rdoc_include)
-
- preprocess.handle(comment) do |directive, param|
- case directive
- when "stopdoc"
- context.stop_doc
- ""
- when "startdoc"
- context.start_doc
- context.force_documentation = true
- ""
- when "enddoc"
- #context.done_documenting = true
- #""
- throw :enddoc
- when "main"
- options = Options.instance
- options.main_page = param
- ""
- when "title"
- options = Options.instance
- options.title = param
- ""
- when "section"
- context.set_current_section(param, comment)
- comment.replace("") # 1.8 doesn't support #clear
- break
- else
- warn "Unrecognized directive '#{directive}'"
- break
- end
+ end
+
+ # this is a poor man puppet plugin parser :-)
+ # it doesn't extract doc nor desc :-(
+ def parse_puppet_plugin(container)
+ comments = ""
+ current_plugin = nil
+
+ File.open(@input_file_name) do |of|
+ of.each do |line|
+ # fetch comments
+ if line =~ /^[ \t]*# ?(.*)$/
+ comments += $1 + "\n"
+ elsif line =~ /^[ \t]*newfunction[ \t]*\([ \t]*:(.*?)[ \t]*,[ \t]*:type[ \t]*=>[ \t]*(:rvalue|:lvalue)\)/
+ current_plugin = Plugin.new($1, "function")
+ container.add_plugin(current_plugin)
+ look_for_directives_in(container, comments) unless comments.empty?
+ current_plugin.comment = comments
+ current_plugin.record_location(@top_level)
+ comments = ""
+ Puppet.debug "rdoc: found new function plugins #{current_plugin.name}"
+ elsif line =~ /^[ \t]*Puppet::Type.newtype[ \t]*\([ \t]*:(.*?)\)/
+ current_plugin = Plugin.new($1, "type")
+ container.add_plugin(current_plugin)
+ look_for_directives_in(container, comments) unless comments.empty?
+ current_plugin.comment = comments
+ current_plugin.record_location(@top_level)
+ comments = ""
+ Puppet.debug "rdoc: found new type plugins #{current_plugin.name}"
+ elsif line =~ /module Puppet::Parser::Functions/
+ # skip
+ else # unknown line type
+ comments =""
end
- remove_private_comments(comment)
+ end
end
-
- def remove_private_comments(comment)
- comment.gsub!(/^#--.*?^#\+\+/m, '')
- comment.sub!(/^#--.*/m, '')
+ end
+
+ # look_for_directives_in scans the current +comment+ for RDoc directives
+ def look_for_directives_in(context, comment)
+ preprocess = SM::PreProcess.new(@input_file_name, @options.rdoc_include)
+
+ preprocess.handle(comment) do |directive, param|
+ case directive
+ when "stopdoc"
+ context.stop_doc
+ ""
+ when "startdoc"
+ context.start_doc
+ context.force_documentation = true
+ ""
+ when "enddoc"
+ #context.done_documenting = true
+ #""
+ throw :enddoc
+ when "main"
+ options = Options.instance
+ options.main_page = param
+ ""
+ when "title"
+ options = Options.instance
+ options.title = param
+ ""
+ when "section"
+ context.set_current_section(param, comment)
+ comment.replace("") # 1.8 doesn't support #clear
+ break
+ else
+ warn "Unrecognized directive '#{directive}'"
+ break
+ end
end
+ remove_private_comments(comment)
+ end
+
+ def remove_private_comments(comment)
+ comment.gsub!(/^#--.*?^#\+\+/m, '')
+ comment.sub!(/^#--.*/m, '')
+ end
end
end
diff --git a/lib/puppet/util/reference.rb b/lib/puppet/util/reference.rb
index 7830421..62bab64 100644
--- a/lib/puppet/util/reference.rb
+++ b/lib/puppet/util/reference.rb
@@ -3,205 +3,205 @@ require 'fileutils'
# Manage Reference Documentation.
class Puppet::Util::Reference
- include Puppet::Util
- include Puppet::Util::Docs
-
- extend Puppet::Util::InstanceLoader
-
- instance_load(:reference, 'puppet/reference')
-
- def self.footer
- "\n\n----------------\n\n*This page autogenerated on #{Time.now}*\n"
- end
-
- def self.modes
- %w{pdf trac text markdown}
- end
+ include Puppet::Util
+ include Puppet::Util::Docs
- def self.newreference(name, options = {}, &block)
- ref = self.new(name, options, &block)
- instance_hash(:reference)[symbolize(name)] = ref
+ extend Puppet::Util::InstanceLoader
- ref
- end
+ instance_load(:reference, 'puppet/reference')
- def self.page(*sections)
- depth = 4
- # Use the minimum depth
- sections.each do |name|
- section = reference(name) or raise "Could not find section #{name}"
- depth = section.depth if section.depth < depth
- end
- text = ".. contents:: :depth: 2\n\n"
- end
+ def self.footer
+ "\n\n----------------\n\n*This page autogenerated on #{Time.now}*\n"
+ end
+
+ def self.modes
+ %w{pdf trac text markdown}
+ end
- def self.pdf(text)
- puts "creating pdf"
- Puppet::Util.secure_open("/tmp/puppetdoc.txt", "w") do |f|
- f.puts text
- end
- rst2latex = %x{which rst2latex}
- if $CHILD_STATUS != 0 or rst2latex =~ /no /
- rst2latex = %x{which rst2latex.py}
- end
- if $CHILD_STATUS != 0 or rst2latex =~ /no /
- raise "Could not find rst2latex"
- end
- rst2latex.chomp!
- cmd = %{#{rst2latex} /tmp/puppetdoc.txt > /tmp/puppetdoc.tex}
- Puppet::Util.secure_open("/tmp/puppetdoc.tex","w") do |f|
- # If we get here without an error, /tmp/puppetdoc.tex isn't a tricky cracker's symlink
- end
- output = %x{#{cmd}}
- unless $CHILD_STATUS == 0
- $stderr.puts "rst2latex failed"
- $stderr.puts output
- exit(1)
- end
- $stderr.puts output
+ def self.newreference(name, options = {}, &block)
+ ref = self.new(name, options, &block)
+ instance_hash(:reference)[symbolize(name)] = ref
- # Now convert to pdf
- Dir.chdir("/tmp") do
- %x{texi2pdf puppetdoc.tex >/dev/null 2>/dev/null}
- end
+ ref
+ end
+ def self.page(*sections)
+ depth = 4
+ # Use the minimum depth
+ sections.each do |name|
+ section = reference(name) or raise "Could not find section #{name}"
+ depth = section.depth if section.depth < depth
end
+ text = ".. contents:: :depth: 2\n\n"
+ end
- def self.markdown(name, text)
- puts "Creating markdown for #{name} reference."
- dir = "/tmp/#{Puppet::PUPPETVERSION}"
- FileUtils.mkdir(dir) unless File.directory?(dir)
- Puppet::Util.secure_open(dir + "/#{name}.rst", "w") do |f|
- f.puts text
- end
- pandoc = %x{which pandoc}
- if $CHILD_STATUS != 0 or pandoc =~ /no /
- pandoc = %x{which pandoc}
- end
- if $CHILD_STATUS != 0 or pandoc =~ /no /
- raise "Could not find pandoc"
- end
- pandoc.chomp!
- cmd = %{#{pandoc} -s -r rst -w markdown #{dir}/#{name}.rst -o #{dir}/#{name}.mdwn}
- output = %x{#{cmd}}
- unless $CHILD_STATUS == 0
- $stderr.puts "Pandoc failed to create #{name} reference."
- $stderr.puts output
- exit(1)
- end
+ def self.pdf(text)
+ puts "creating pdf"
+ Puppet::Util.secure_open("/tmp/puppetdoc.txt", "w") do |f|
+ f.puts text
+ end
+ rst2latex = %x{which rst2latex}
+ if $CHILD_STATUS != 0 or rst2latex =~ /no /
+ rst2latex = %x{which rst2latex.py}
+ end
+ if $CHILD_STATUS != 0 or rst2latex =~ /no /
+ raise "Could not find rst2latex"
+ end
+ rst2latex.chomp!
+ cmd = %{#{rst2latex} /tmp/puppetdoc.txt > /tmp/puppetdoc.tex}
+ Puppet::Util.secure_open("/tmp/puppetdoc.tex","w") do |f|
+ # If we get here without an error, /tmp/puppetdoc.tex isn't a tricky cracker's symlink
+ end
+ output = %x{#{cmd}}
+ unless $CHILD_STATUS == 0
+ $stderr.puts "rst2latex failed"
+ $stderr.puts output
+ exit(1)
+ end
+ $stderr.puts output
- File.unlink(dir + "/#{name}.rst")
+ # Now convert to pdf
+ Dir.chdir("/tmp") do
+ %x{texi2pdf puppetdoc.tex >/dev/null 2>/dev/null}
end
- def self.references
- instance_loader(:reference).loadall
- loaded_instances(:reference).sort { |a,b| a.to_s <=> b.to_s }
+ end
+
+ def self.markdown(name, text)
+ puts "Creating markdown for #{name} reference."
+ dir = "/tmp/#{Puppet::PUPPETVERSION}"
+ FileUtils.mkdir(dir) unless File.directory?(dir)
+ Puppet::Util.secure_open(dir + "/#{name}.rst", "w") do |f|
+ f.puts text
+ end
+ pandoc = %x{which pandoc}
+ if $CHILD_STATUS != 0 or pandoc =~ /no /
+ pandoc = %x{which pandoc}
+ end
+ if $CHILD_STATUS != 0 or pandoc =~ /no /
+ raise "Could not find pandoc"
+ end
+ pandoc.chomp!
+ cmd = %{#{pandoc} -s -r rst -w markdown #{dir}/#{name}.rst -o #{dir}/#{name}.mdwn}
+ output = %x{#{cmd}}
+ unless $CHILD_STATUS == 0
+ $stderr.puts "Pandoc failed to create #{name} reference."
+ $stderr.puts output
+ exit(1)
end
- HEADER_LEVELS = [nil, "=", "-", "+", "'", "~"]
+ File.unlink(dir + "/#{name}.rst")
+ end
- attr_accessor :page, :depth, :header, :title, :dynamic
- attr_writer :doc
+ def self.references
+ instance_loader(:reference).loadall
+ loaded_instances(:reference).sort { |a,b| a.to_s <=> b.to_s }
+ end
- def doc
- if defined?(@doc)
- return "#{@name} - #{@doc}"
- else
- return @title
- end
- end
+ HEADER_LEVELS = [nil, "=", "-", "+", "'", "~"]
- def dynamic?
- self.dynamic
- end
+ attr_accessor :page, :depth, :header, :title, :dynamic
+ attr_writer :doc
- def h(name, level)
- "#{name}\n#{HEADER_LEVELS[level] * name.to_s.length}\n\n"
+ def doc
+ if defined?(@doc)
+ return "#{@name} - #{@doc}"
+ else
+ return @title
end
+ end
- def initialize(name, options = {}, &block)
- @name = name
- options.each do |option, value|
- send(option.to_s + "=", value)
- end
+ def dynamic?
+ self.dynamic
+ end
- meta_def(:generate, &block)
+ def h(name, level)
+ "#{name}\n#{HEADER_LEVELS[level] * name.to_s.length}\n\n"
+ end
- # Now handle the defaults
- @title ||= "#{@name.to_s.capitalize} Reference"
- @page ||= @title.gsub(/\s+/, '')
- @depth ||= 2
- @header ||= ""
+ def initialize(name, options = {}, &block)
+ @name = name
+ options.each do |option, value|
+ send(option.to_s + "=", value)
end
- # Indent every line in the chunk except those which begin with '..'.
- def indent(text, tab)
- text.gsub(/(^|\A)/, tab).gsub(/^ +\.\./, "..")
- end
+ meta_def(:generate, &block)
- def option(name, value)
- ":#{name.to_s.capitalize}: #{value}\n"
- end
+ # Now handle the defaults
+ @title ||= "#{@name.to_s.capitalize} Reference"
+ @page ||= @title.gsub(/\s+/, '')
+ @depth ||= 2
+ @header ||= ""
+ end
- def paramwrap(name, text, options = {})
- options[:level] ||= 5
- #str = "#{name} : "
- str = h(name, options[:level])
- str += "- **namevar**\n\n" if options[:namevar]
- str += text
- #str += text.gsub(/\n/, "\n ")
+ # Indent every line in the chunk except those which begin with '..'.
+ def indent(text, tab)
+ text.gsub(/(^|\A)/, tab).gsub(/^ +\.\./, "..")
+ end
- str += "\n\n"
- end
+ def option(name, value)
+ ":#{name.to_s.capitalize}: #{value}\n"
+ end
- # Remove all trac links.
- def strip_trac(text)
- text.gsub(/`\w+\s+([^`]+)`:trac:/) { |m| $1 }
- end
+ def paramwrap(name, text, options = {})
+ options[:level] ||= 5
+ #str = "#{name} : "
+ str = h(name, options[:level])
+ str += "- **namevar**\n\n" if options[:namevar]
+ str += text
+ #str += text.gsub(/\n/, "\n ")
- def text
- puts output
- end
+ str += "\n\n"
+ end
- def to_rest(withcontents = true)
- # First the header
- text = h(@title, 1)
- text += "\n\n**This page is autogenerated; any changes will get overwritten** *(last generated on #{Time.now.to_s})*\n\n"
- text += ".. contents:: :depth: #{@depth}\n\n" if withcontents
+ # Remove all trac links.
+ def strip_trac(text)
+ text.gsub(/`\w+\s+([^`]+)`:trac:/) { |m| $1 }
+ end
- text += @header
+ def text
+ puts output
+ end
- text += generate
+ def to_rest(withcontents = true)
+ # First the header
+ text = h(@title, 1)
+ text += "\n\n**This page is autogenerated; any changes will get overwritten** *(last generated on #{Time.now.to_s})*\n\n"
+ text += ".. contents:: :depth: #{@depth}\n\n" if withcontents
- text += self.class.footer if withcontents
+ text += @header
- text
- end
+ text += generate
- def to_text(withcontents = true)
- strip_trac(to_rest(withcontents))
- end
+ text += self.class.footer if withcontents
- def to_trac(with_contents = true)
- "{{{\n#!rst\n#{self.to_rest(with_contents)}\n}}}"
- end
+ text
+ end
+
+ def to_text(withcontents = true)
+ strip_trac(to_rest(withcontents))
+ end
- def trac
- Puppet::Util.secure_open("/tmp/puppetdoc.txt", "w") do |f|
- f.puts self.to_trac
- end
+ def to_trac(with_contents = true)
+ "{{{\n#!rst\n#{self.to_rest(with_contents)}\n}}}"
+ end
- puts "Writing #{@name} reference to trac as #{@page}"
- cmd = %{sudo trac-admin /opt/rl/trac/puppet wiki import %s /tmp/puppetdoc.txt} % self.page
- output = %x{#{cmd}}
- unless $CHILD_STATUS == 0
- $stderr.puts "trac-admin failed"
- $stderr.puts output
- exit(1)
- end
- unless output =~ /^\s+/
- $stderr.puts output
- end
+ def trac
+ Puppet::Util.secure_open("/tmp/puppetdoc.txt", "w") do |f|
+ f.puts self.to_trac
+ end
+
+ puts "Writing #{@name} reference to trac as #{@page}"
+ cmd = %{sudo trac-admin /opt/rl/trac/puppet wiki import %s /tmp/puppetdoc.txt} % self.page
+ output = %x{#{cmd}}
+ unless $CHILD_STATUS == 0
+ $stderr.puts "trac-admin failed"
+ $stderr.puts output
+ exit(1)
+ end
+ unless output =~ /^\s+/
+ $stderr.puts output
end
+ end
end
diff --git a/lib/puppet/util/resource_template.rb b/lib/puppet/util/resource_template.rb
index ceb9ea3..b12b125 100644
--- a/lib/puppet/util/resource_template.rb
+++ b/lib/puppet/util/resource_template.rb
@@ -36,26 +36,26 @@ require 'erb'
# parameters, which is generally most useful, since it allows you to configure
# the generated resource via the generating resource.
class Puppet::Util::ResourceTemplate
- include Puppet::Util::Logging
+ include Puppet::Util::Logging
- def evaluate
- set_resource_variables
- ERB.new(File.read(@file), 0, "-").result(binding)
- end
+ def evaluate
+ set_resource_variables
+ ERB.new(File.read(@file), 0, "-").result(binding)
+ end
- def initialize(file, resource)
- raise ArgumentError, "Template #{file} does not exist" unless FileTest.exist?(file)
- @file = file
- @resource = resource
- end
+ def initialize(file, resource)
+ raise ArgumentError, "Template #{file} does not exist" unless FileTest.exist?(file)
+ @file = file
+ @resource = resource
+ end
- private
+ private
- def set_resource_variables
- @resource.to_hash.each do |param, value|
- var = "@#{param.to_s}"
- instance_variable_set(var, value)
- end
+ def set_resource_variables
+ @resource.to_hash.each do |param, value|
+ var = "@#{param.to_s}"
+ instance_variable_set(var, value)
end
+ end
end
diff --git a/lib/puppet/util/run_mode.rb b/lib/puppet/util/run_mode.rb
index bf74574..eb9c511 100644
--- a/lib/puppet/util/run_mode.rb
+++ b/lib/puppet/util/run_mode.rb
@@ -1,81 +1,81 @@
module Puppet
- module Util
- class RunMode
- def initialize(name)
- @name = name.to_sym
- end
+ module Util
+ class RunMode
+ def initialize(name)
+ @name = name.to_sym
+ end
- @@run_modes = Hash.new {|h, k| h[k] = RunMode.new(k)}
+ @@run_modes = Hash.new {|h, k| h[k] = RunMode.new(k)}
- attr :name
+ attr :name
- def self.[](name)
- @@run_modes[name]
- end
+ def self.[](name)
+ @@run_modes[name]
+ end
- def master?
- name == :master
- end
+ def master?
+ name == :master
+ end
- def agent?
- name == :agent
- end
+ def agent?
+ name == :agent
+ end
- def user?
- name == :user
- end
+ def user?
+ name == :user
+ end
- def conf_dir
- which_dir(
- (Puppet.features.microsoft_windows? ? File.join(Dir::WINDOWS, "puppet", "etc") : "/etc/puppet"),
- "~/.puppet"
- )
- end
+ def conf_dir
+ which_dir(
+ (Puppet.features.microsoft_windows? ? File.join(Dir::WINDOWS, "puppet", "etc") : "/etc/puppet"),
+ "~/.puppet"
+ )
+ end
- def var_dir
- which_dir(
- (Puppet.features.microsoft_windows? ? File.join(Dir::WINDOWS, "puppet", "var") : "/var/lib/puppet"),
- "~/.puppet/var"
- )
- end
+ def var_dir
+ which_dir(
+ (Puppet.features.microsoft_windows? ? File.join(Dir::WINDOWS, "puppet", "var") : "/var/lib/puppet"),
+ "~/.puppet/var"
+ )
+ end
- def run_dir
- which_dir("/var/run/puppet", "~/.puppet/var")
- end
+ def run_dir
+ which_dir("/var/run/puppet", "~/.puppet/var")
+ end
- def logopts
- if name == :master
- {
- :default => "$vardir/log",
- :mode => 0750,
- :owner => "service",
- :group => "service",
- :desc => "The Puppet log directory."
- }
- else
- ["$vardir/log", "The Puppet log directory."]
- end
- end
+ def logopts
+ if name == :master
+ {
+ :default => "$vardir/log",
+ :mode => 0750,
+ :owner => "service",
+ :group => "service",
+ :desc => "The Puppet log directory."
+ }
+ else
+ ["$vardir/log", "The Puppet log directory."]
+ end
+ end
- private
+ private
- def which_dir( global, user )
- #FIXME: we should test if we're user "puppet"
- # there's a comment that suggests that we do that
- # and we currently don't.
- expand_path case
- when name == :master; global
- when Puppet.features.root?; global
- else user
- end
- end
+ def which_dir( global, user )
+ #FIXME: we should test if we're user "puppet"
+ # there's a comment that suggests that we do that
+ # and we currently don't.
+ expand_path case
+ when name == :master; global
+ when Puppet.features.root?; global
+ else user
+ end
+ end
- def expand_path( dir )
- require 'etc'
- ENV["HOME"] ||= Etc.getpwuid(Process.uid).dir
- File.expand_path(dir)
- end
+ def expand_path( dir )
+ require 'etc'
+ ENV["HOME"] ||= Etc.getpwuid(Process.uid).dir
+ File.expand_path(dir)
+ end
- end
end
+ end
end
diff --git a/lib/puppet/util/selinux.rb b/lib/puppet/util/selinux.rb
index 5aafd9c..9d0e0a7 100644
--- a/lib/puppet/util/selinux.rb
+++ b/lib/puppet/util/selinux.rb
@@ -13,204 +13,204 @@ require 'pathname'
module Puppet::Util::SELinux
- def selinux_support?
- return false unless defined?(Selinux)
- if Selinux.is_selinux_enabled == 1
- return true
- end
- false
+ def selinux_support?
+ return false unless defined?(Selinux)
+ if Selinux.is_selinux_enabled == 1
+ return true
end
-
- # Retrieve and return the full context of the file. If we don't have
- # SELinux support or if the SELinux call fails then return nil.
- def get_selinux_current_context(file)
- return nil unless selinux_support?
- retval = Selinux.lgetfilecon(file)
- if retval == -1
- return nil
- end
- retval[1]
+ false
+ end
+
+ # Retrieve and return the full context of the file. If we don't have
+ # SELinux support or if the SELinux call fails then return nil.
+ def get_selinux_current_context(file)
+ return nil unless selinux_support?
+ retval = Selinux.lgetfilecon(file)
+ if retval == -1
+ return nil
end
-
- # Retrieve and return the default context of the file. If we don't have
- # SELinux support or if the SELinux call fails to file a default then return nil.
- def get_selinux_default_context(file)
- return nil unless selinux_support?
- # If the filesystem has no support for SELinux labels, return a default of nil
- # instead of what matchpathcon would return
- return nil unless selinux_label_support?(file)
- # If the file exists we should pass the mode to matchpathcon for the most specific
- # matching. If not, we can pass a mode of 0.
- begin
- filestat = File.lstat(file)
- mode = filestat.mode
- rescue Errno::ENOENT
- mode = 0
- end
- retval = Selinux.matchpathcon(file, mode)
- if retval == -1
- return nil
- end
- retval[1]
+ retval[1]
+ end
+
+ # Retrieve and return the default context of the file. If we don't have
+ # SELinux support or if the SELinux call fails to file a default then return nil.
+ def get_selinux_default_context(file)
+ return nil unless selinux_support?
+ # If the filesystem has no support for SELinux labels, return a default of nil
+ # instead of what matchpathcon would return
+ return nil unless selinux_label_support?(file)
+ # If the file exists we should pass the mode to matchpathcon for the most specific
+ # matching. If not, we can pass a mode of 0.
+ begin
+ filestat = File.lstat(file)
+ mode = filestat.mode
+ rescue Errno::ENOENT
+ mode = 0
end
-
- # Take the full SELinux context returned from the tools and parse it
- # out to the three (or four) component parts. Supports :seluser, :selrole,
- # :seltype, and on systems with range support, :selrange.
- def parse_selinux_context(component, context)
- if context.nil? or context == "unlabeled"
- return nil
- end
- unless context =~ /^([a-z0-9_]+):([a-z0-9_]+):([a-zA-Z0-9_]+)(?::([a-zA-Z0-9:,._-]+))?/
- raise Puppet::Error, "Invalid context to parse: #{context}"
- end
- ret = {
- :seluser => $1,
- :selrole => $2,
- :seltype => $3,
- :selrange => $4,
- }
- ret[component]
+ retval = Selinux.matchpathcon(file, mode)
+ if retval == -1
+ return nil
end
-
- # This updates the actual SELinux label on the file. You can update
- # only a single component or update the entire context.
- # The caveat is that since setting a partial context makes no sense the
- # file has to already exist. Puppet (via the File resource) will always
- # just try to set components, even if all values are specified by the manifest.
- # I believe that the OS should always provide at least a fall-through context
- # though on any well-running system.
- def set_selinux_context(file, value, component = false)
- return nil unless selinux_support? && selinux_label_support?(file)
-
- if component
- # Must first get existing context to replace a single component
- context = Selinux.lgetfilecon(file)[1]
- if context == -1
- # We can't set partial context components when no context exists
- # unless/until we can find a way to make Puppet call this method
- # once for all selinux file label attributes.
- Puppet.warning "Can't set SELinux context on file unless the file already has some kind of context"
- return nil
- end
- context = context.split(':')
- case component
- when :seluser
- context[0] = value
- when :selrole
- context[1] = value
- when :seltype
- context[2] = value
- when :selrange
- context[3] = value
- else
- raise ArguementError, "set_selinux_context component must be one of :seluser, :selrole, :seltype, or :selrange"
- end
- context = context.join(':')
- else
- context = value
- end
-
- retval = Selinux.lsetfilecon(file, context)
- if retval == 0
- return true
+ retval[1]
+ end
+
+ # Take the full SELinux context returned from the tools and parse it
+ # out to the three (or four) component parts. Supports :seluser, :selrole,
+ # :seltype, and on systems with range support, :selrange.
+ def parse_selinux_context(component, context)
+ if context.nil? or context == "unlabeled"
+ return nil
+ end
+ unless context =~ /^([a-z0-9_]+):([a-z0-9_]+):([a-zA-Z0-9_]+)(?::([a-zA-Z0-9:,._-]+))?/
+ raise Puppet::Error, "Invalid context to parse: #{context}"
+ end
+ ret = {
+ :seluser => $1,
+ :selrole => $2,
+ :seltype => $3,
+ :selrange => $4,
+ }
+ ret[component]
+ end
+
+ # This updates the actual SELinux label on the file. You can update
+ # only a single component or update the entire context.
+ # The caveat is that since setting a partial context makes no sense the
+ # file has to already exist. Puppet (via the File resource) will always
+ # just try to set components, even if all values are specified by the manifest.
+ # I believe that the OS should always provide at least a fall-through context
+ # though on any well-running system.
+ def set_selinux_context(file, value, component = false)
+ return nil unless selinux_support? && selinux_label_support?(file)
+
+ if component
+ # Must first get existing context to replace a single component
+ context = Selinux.lgetfilecon(file)[1]
+ if context == -1
+ # We can't set partial context components when no context exists
+ # unless/until we can find a way to make Puppet call this method
+ # once for all selinux file label attributes.
+ Puppet.warning "Can't set SELinux context on file unless the file already has some kind of context"
+ return nil
+ end
+ context = context.split(':')
+ case component
+ when :seluser
+ context[0] = value
+ when :selrole
+ context[1] = value
+ when :seltype
+ context[2] = value
+ when :selrange
+ context[3] = value
else
- Puppet.warning "Failed to set SELinux context #{context} on #{file}"
- return false
- end
+ raise ArguementError, "set_selinux_context component must be one of :seluser, :selrole, :seltype, or :selrange"
+ end
+ context = context.join(':')
+ else
+ context = value
end
- # Since this call relies on get_selinux_default_context it also needs a
- # full non-relative path to the file. Fortunately, that seems to be all
- # Puppet uses. This will set the file's SELinux context to the policy's
- # default context (if any) if it differs from the context currently on
- # the file.
- def set_selinux_default_context(file)
- new_context = get_selinux_default_context(file)
- return nil unless new_context
- cur_context = get_selinux_current_context(file)
- if new_context != cur_context
- set_selinux_context(file, new_context)
- return new_context
- end
- nil
+ retval = Selinux.lsetfilecon(file, context)
+ if retval == 0
+ return true
+ else
+ Puppet.warning "Failed to set SELinux context #{context} on #{file}"
+ return false
end
-
- # Internal helper function to read and parse /proc/mounts
- def read_mounts
- mounts = ""
- begin
- if File.instance_methods.include? "read_nonblock"
- # If possible we use read_nonblock in a loop rather than read to work-
- # a linux kernel bug. See ticket #1963 for details.
- mountfh = File.open("/proc/mounts")
- mounts += mountfh.read_nonblock(1024) while true
- else
- # Otherwise we shell out and let cat do it for us
- mountfh = IO.popen("/bin/cat /proc/mounts")
- mounts = mountfh.read
- end
- rescue EOFError
- # that's expected
- rescue
- return nil
- ensure
- mountfh.close if mountfh
- end
-
- mntpoint = {}
-
- # Read all entries in /proc/mounts. The second column is the
- # mountpoint and the third column is the filesystem type.
- # We skip rootfs because it is always mounted at /
- mounts.collect do |line|
- params = line.split(' ')
- next if params[2] == 'rootfs'
- mntpoint[params[1]] = params[2]
- end
- mntpoint
+ end
+
+ # Since this call relies on get_selinux_default_context it also needs a
+ # full non-relative path to the file. Fortunately, that seems to be all
+ # Puppet uses. This will set the file's SELinux context to the policy's
+ # default context (if any) if it differs from the context currently on
+ # the file.
+ def set_selinux_default_context(file)
+ new_context = get_selinux_default_context(file)
+ return nil unless new_context
+ cur_context = get_selinux_current_context(file)
+ if new_context != cur_context
+ set_selinux_context(file, new_context)
+ return new_context
end
-
- def realpath(path)
- path, rest = Pathname.new(path), []
- path, rest = path.dirname, [path.basename] + rest while ! path.exist?
- File.join( path.realpath, *rest )
+ nil
+ end
+
+ # Internal helper function to read and parse /proc/mounts
+ def read_mounts
+ mounts = ""
+ begin
+ if File.instance_methods.include? "read_nonblock"
+ # If possible we use read_nonblock in a loop rather than read to work-
+ # a linux kernel bug. See ticket #1963 for details.
+ mountfh = File.open("/proc/mounts")
+ mounts += mountfh.read_nonblock(1024) while true
+ else
+ # Otherwise we shell out and let cat do it for us
+ mountfh = IO.popen("/bin/cat /proc/mounts")
+ mounts = mountfh.read
+ end
+ rescue EOFError
+ # that's expected
+ rescue
+ return nil
+ ensure
+ mountfh.close if mountfh
end
- def parent_directory(path)
- Pathname.new(path).dirname.to_s
- end
+ mntpoint = {}
- # Internal helper function to return which type of filesystem a
- # given file path resides on
- def find_fs(path)
- unless mnts = read_mounts
- return nil
- end
-
- # For a given file:
- # Check if the filename is in the data structure;
- # return the fstype if it is.
- # Just in case: return something if you're down to "/" or ""
- # Remove the last slash and everything after it,
- # and repeat with that as the file for the next loop through.
- path = realpath(path)
- while not path.empty?
- return mnts[path] if mnts.has_key?(path)
- path = parent_directory(path)
- end
- mnts['/']
+ # Read all entries in /proc/mounts. The second column is the
+ # mountpoint and the third column is the filesystem type.
+ # We skip rootfs because it is always mounted at /
+ mounts.collect do |line|
+ params = line.split(' ')
+ next if params[2] == 'rootfs'
+ mntpoint[params[1]] = params[2]
+ end
+ mntpoint
+ end
+
+ def realpath(path)
+ path, rest = Pathname.new(path), []
+ path, rest = path.dirname, [path.basename] + rest while ! path.exist?
+ File.join( path.realpath, *rest )
+ end
+
+ def parent_directory(path)
+ Pathname.new(path).dirname.to_s
+ end
+
+ # Internal helper function to return which type of filesystem a
+ # given file path resides on
+ def find_fs(path)
+ unless mnts = read_mounts
+ return nil
end
- # Check filesystem a path resides on for SELinux support against
- # whitelist of known-good filesystems.
- # Returns true if the filesystem can support SELinux labels and
- # false if not.
- def selinux_label_support?(file)
- fstype = find_fs(file)
- return false if fstype.nil?
- filesystems = ['ext2', 'ext3', 'ext4', 'gfs', 'gfs2', 'xfs', 'jfs']
- filesystems.include?(fstype)
+ # For a given file:
+ # Check if the filename is in the data structure;
+ # return the fstype if it is.
+ # Just in case: return something if you're down to "/" or ""
+ # Remove the last slash and everything after it,
+ # and repeat with that as the file for the next loop through.
+ path = realpath(path)
+ while not path.empty?
+ return mnts[path] if mnts.has_key?(path)
+ path = parent_directory(path)
end
+ mnts['/']
+ end
+
+ # Check filesystem a path resides on for SELinux support against
+ # whitelist of known-good filesystems.
+ # Returns true if the filesystem can support SELinux labels and
+ # false if not.
+ def selinux_label_support?(file)
+ fstype = find_fs(file)
+ return false if fstype.nil?
+ filesystems = ['ext2', 'ext3', 'ext4', 'gfs', 'gfs2', 'xfs', 'jfs']
+ filesystems.include?(fstype)
+ end
end
diff --git a/lib/puppet/util/settings.rb b/lib/puppet/util/settings.rb
index 5573145..cbb12a8 100644
--- a/lib/puppet/util/settings.rb
+++ b/lib/puppet/util/settings.rb
@@ -7,581 +7,581 @@ require 'puppet/util/loadedfile'
# The class for handling configuration files.
class Puppet::Util::Settings
- include Enumerable
- include Puppet::Util::Cacher
-
- require 'puppet/util/settings/setting'
- require 'puppet/util/settings/file_setting'
- require 'puppet/util/settings/boolean_setting'
-
- attr_accessor :file
- attr_reader :timer
-
- ReadOnly = [:run_mode, :name]
-
- # Retrieve a config value
- def [](param)
- value(param)
- end
-
- # Set a config value. This doesn't set the defaults, it sets the value itself.
- def []=(param, value)
- set_value(param, value, :memory)
- end
-
- # Generate the list of valid arguments, in a format that GetoptLong can
- # understand, and add them to the passed option list.
- def addargs(options)
- # Add all of the config parameters as valid options.
- self.each { |name, setting|
- setting.getopt_args.each { |args| options << args }
- }
-
- options
- end
-
- # Generate the list of valid arguments, in a format that OptionParser can
- # understand, and add them to the passed option list.
- def optparse_addargs(options)
- # Add all of the config parameters as valid options.
- self.each { |name, setting|
- options << setting.optparse_args
- }
-
- options
- end
-
- # Is our parameter a boolean parameter?
- def boolean?(param)
- param = param.to_sym
- !!(@config.include?(param) and @config[param].kind_of? BooleanSetting)
- end
-
- # Remove all set values, potentially skipping cli values.
- def clear(exceptcli = false)
- @sync.synchronize do
- unsafe_clear(exceptcli)
- end
- end
-
- # Remove all set values, potentially skipping cli values.
- def unsafe_clear(exceptcli = false)
- @values.each do |name, values|
- @values.delete(name) unless exceptcli and name == :cli
- end
-
- # Don't clear the 'used' in this case, since it's a config file reparse,
- # and we want to retain this info.
- @used = [] unless exceptcli
-
- @cache.clear
- end
-
- # This is mostly just used for testing.
- def clearused
- @cache.clear
- @used = []
- end
-
- # Do variable interpolation on the value.
- def convert(value, environment = nil)
- return value unless value
- return value unless value.is_a? String
- newval = value.gsub(/\$(\w+)|\$\{(\w+)\}/) do |value|
- varname = $2 || $1
- if varname == "environment" and environment
- environment
- elsif pval = self.value(varname)
- pval
- else
- raise Puppet::DevError, "Could not find value for #{value}"
- end
- end
-
- newval
- end
-
- # Return a value's description.
- def description(name)
- if obj = @config[name.to_sym]
- obj.desc
- else
- nil
- end
- end
-
- def each
- @config.each { |name, object|
- yield name, object
- }
- end
-
- # Iterate over each section name.
- def eachsection
- yielded = []
- @config.each do |name, object|
- section = object.section
- unless yielded.include? section
- yield section
- yielded << section
- end
- end
- end
-
- # Return an object by name.
- def setting(param)
- param = param.to_sym
- @config[param]
- end
-
- # Handle a command-line argument.
- def handlearg(opt, value = nil)
- @cache.clear
- value &&= munge_value(value)
- str = opt.sub(/^--/,'')
-
- bool = true
- newstr = str.sub(/^no-/, '')
- if newstr != str
- str = newstr
- bool = false
- end
- str = str.intern
-
- if @config[str].is_a?(Puppet::Util::Settings::BooleanSetting)
- if value == "" or value.nil?
- value = bool
- end
- end
-
- set_value(str, value, :cli)
- end
-
- def without_noop
- old_noop = value(:noop,:cli) and set_value(:noop, false, :cli) if valid?(:noop)
- yield
- ensure
- set_value(:noop, old_noop, :cli) if valid?(:noop)
- end
-
- def include?(name)
- name = name.intern if name.is_a? String
- @config.include?(name)
- end
-
- # check to see if a short name is already defined
- def shortinclude?(short)
- short = short.intern if name.is_a? String
- @shortnames.include?(short)
- end
-
- # Create a new collection of config settings.
- def initialize
- @config = {}
- @shortnames = {}
-
- @created = []
- @searchpath = nil
-
- # Mutex-like thing to protect @values
- @sync = Sync.new
-
- # Keep track of set values.
- @values = Hash.new { |hash, key| hash[key] = {} }
-
- # And keep a per-environment cache
- @cache = Hash.new { |hash, key| hash[key] = {} }
-
- # The list of sections we've used.
- @used = []
- end
-
- # NOTE: ACS ahh the util classes. . .sigh
- # as part of a fix for 1183, I pulled the logic for the following 5 methods out of the executables and puppet.rb
- # They probably deserve their own class, but I don't want to do that until I can refactor environments
- # its a little better than where they were
-
- # Prints the contents of a config file with the available config settings, or it
- # prints a single value of a config setting.
- def print_config_options
- env = value(:environment)
- val = value(:configprint)
- if val == "all"
- hash = {}
- each do |name, obj|
- val = value(name,env)
- val = val.inspect if val == ""
- hash[name] = val
- end
- hash.sort { |a,b| a[0].to_s <=> b[0].to_s }.each do |name, val|
- puts "#{name} = #{val}"
- end
- else
- val.split(/\s*,\s*/).sort.each do |v|
- if include?(v)
- #if there is only one value, just print it for back compatibility
- if v == val
- puts value(val,env)
- break
- end
- puts "#{v} = #{value(v,env)}"
- else
- puts "invalid parameter: #{v}"
- return false
- end
- end
- end
- true
- end
-
- def generate_config
- puts to_config
- true
- end
-
- def generate_manifest
- puts to_manifest
- true
- end
-
- def print_configs
- return print_config_options if value(:configprint) != ""
- return generate_config if value(:genconfig)
- generate_manifest if value(:genmanifest)
- end
-
- def print_configs?
- (value(:configprint) != "" || value(:genconfig) || value(:genmanifest)) && true
- end
-
- # Return a given object's file metadata.
- def metadata(param)
- if obj = @config[param.to_sym] and obj.is_a?(FileSetting)
- return [:owner, :group, :mode].inject({}) do |meta, p|
- if v = obj.send(p)
- meta[p] = v
- end
- meta
- end
- else
- nil
- end
- end
-
- # Make a directory with the appropriate user, group, and mode
- def mkdir(default)
- obj = get_config_file_default(default)
-
- Puppet::Util::SUIDManager.asuser(obj.owner, obj.group) do
- mode = obj.mode || 0750
- Dir.mkdir(obj.value, mode)
- end
- end
-
- # Figure out the section name for the run_mode.
- def run_mode
- Puppet.run_mode.name
- end
-
- # Return all of the parameters associated with a given section.
- def params(section = nil)
- if section
- section = section.intern if section.is_a? String
- @config.find_all { |name, obj|
- obj.section == section
- }.collect { |name, obj|
- name
- }
- else
- @config.keys
- end
- end
-
- # Parse the configuration file. Just provides
- # thread safety.
- def parse
- raise "No :config setting defined; cannot parse unknown config file" unless self[:config]
-
- @sync.synchronize do
- unsafe_parse(self[:config])
- end
-
- # Create a timer so that this file will get checked automatically
- # and reparsed if necessary.
- set_filetimeout_timer
- end
-
- # Unsafely parse the file -- this isn't thread-safe and causes plenty of problems if used directly.
- def unsafe_parse(file)
- return unless FileTest.exist?(file)
- begin
- data = parse_file(file)
- rescue => details
- puts details.backtrace if Puppet[:trace]
- Puppet.err "Could not parse #{file}: #{details}"
- return
- end
-
- unsafe_clear(true)
-
- metas = {}
- data.each do |area, values|
- metas[area] = values.delete(:_meta)
- values.each do |key,value|
- set_value(key, value, area, :dont_trigger_handles => true, :ignore_bad_settings => true )
- end
- end
-
- # Determine our environment, if we have one.
- if @config[:environment]
- env = self.value(:environment).to_sym
- else
- env = "none"
- end
-
- # Call any hooks we should be calling.
- settings_with_hooks.each do |setting|
- each_source(env) do |source|
- if value = @values[source][setting.name]
- # We still have to use value to retrieve the value, since
- # we want the fully interpolated value, not $vardir/lib or whatever.
- # This results in extra work, but so few of the settings
- # will have associated hooks that it ends up being less work this
- # way overall.
- setting.handle(self.value(setting.name, env))
- break
- end
- end
- end
-
- # We have to do it in the reverse of the search path,
- # because multiple sections could set the same value
- # and I'm too lazy to only set the metadata once.
- searchpath.reverse.each do |source|
- source = run_mode if source == :run_mode
- source = @name if (@name && source == :name)
- if meta = metas[source]
- set_metadata(meta)
- end
- end
- end
-
- # Create a new setting. The value is passed in because it's used to determine
- # what kind of setting we're creating, but the value itself might be either
- # a default or a value, so we can't actually assign it.
- def newsetting(hash)
- klass = nil
- hash[:section] = hash[:section].to_sym if hash[:section]
- if type = hash[:type]
- unless klass = {:setting => Setting, :file => FileSetting, :boolean => BooleanSetting}[type]
- raise ArgumentError, "Invalid setting type '#{type}'"
- end
- hash.delete(:type)
- else
- case hash[:default]
- when true, false, "true", "false"
- klass = BooleanSetting
- when /^\$\w+\//, /^\//, /^\w:\//
- klass = FileSetting
- when String, Integer, Float # nothing
- klass = Setting
- else
- raise ArgumentError, "Invalid value '#{hash[:default].inspect}' for #{hash[:name]}"
- end
- end
- hash[:settings] = self
- setting = klass.new(hash)
-
- setting
- end
-
- # This has to be private, because it doesn't add the settings to @config
- private :newsetting
-
- # Iterate across all of the objects in a given section.
- def persection(section)
- section = section.to_sym
- self.each { |name, obj|
- if obj.section == section
- yield obj
- end
- }
- end
-
- # Cache this in an easily clearable way, since we were
- # having trouble cleaning it up after tests.
- cached_attr(:file) do
- if path = self[:config] and FileTest.exist?(path)
- Puppet::Util::LoadedFile.new(path)
- end
- end
-
- # Reparse our config file, if necessary.
- def reparse
- if file and file.changed?
- Puppet.notice "Reparsing #{file.file}"
- parse
- reuse
- end
- end
-
- def reuse
- return unless defined?(@used)
- @sync.synchronize do # yay, thread-safe
- new = @used
- @used = []
- self.use(*new)
- end
- end
-
- # The order in which to search for values.
- def searchpath(environment = nil)
- if environment
- [:cli, :memory, environment, :run_mode, :main, :mutable_defaults]
+ include Enumerable
+ include Puppet::Util::Cacher
+
+ require 'puppet/util/settings/setting'
+ require 'puppet/util/settings/file_setting'
+ require 'puppet/util/settings/boolean_setting'
+
+ attr_accessor :file
+ attr_reader :timer
+
+ ReadOnly = [:run_mode, :name]
+
+ # Retrieve a config value
+ def [](param)
+ value(param)
+ end
+
+ # Set a config value. This doesn't set the defaults, it sets the value itself.
+ def []=(param, value)
+ set_value(param, value, :memory)
+ end
+
+ # Generate the list of valid arguments, in a format that GetoptLong can
+ # understand, and add them to the passed option list.
+ def addargs(options)
+ # Add all of the config parameters as valid options.
+ self.each { |name, setting|
+ setting.getopt_args.each { |args| options << args }
+ }
+
+ options
+ end
+
+ # Generate the list of valid arguments, in a format that OptionParser can
+ # understand, and add them to the passed option list.
+ def optparse_addargs(options)
+ # Add all of the config parameters as valid options.
+ self.each { |name, setting|
+ options << setting.optparse_args
+ }
+
+ options
+ end
+
+ # Is our parameter a boolean parameter?
+ def boolean?(param)
+ param = param.to_sym
+ !!(@config.include?(param) and @config[param].kind_of? BooleanSetting)
+ end
+
+ # Remove all set values, potentially skipping cli values.
+ def clear(exceptcli = false)
+ @sync.synchronize do
+ unsafe_clear(exceptcli)
+ end
+ end
+
+ # Remove all set values, potentially skipping cli values.
+ def unsafe_clear(exceptcli = false)
+ @values.each do |name, values|
+ @values.delete(name) unless exceptcli and name == :cli
+ end
+
+ # Don't clear the 'used' in this case, since it's a config file reparse,
+ # and we want to retain this info.
+ @used = [] unless exceptcli
+
+ @cache.clear
+ end
+
+ # This is mostly just used for testing.
+ def clearused
+ @cache.clear
+ @used = []
+ end
+
+ # Do variable interpolation on the value.
+ def convert(value, environment = nil)
+ return value unless value
+ return value unless value.is_a? String
+ newval = value.gsub(/\$(\w+)|\$\{(\w+)\}/) do |value|
+ varname = $2 || $1
+ if varname == "environment" and environment
+ environment
+ elsif pval = self.value(varname)
+ pval
+ else
+ raise Puppet::DevError, "Could not find value for #{value}"
+ end
+ end
+
+ newval
+ end
+
+ # Return a value's description.
+ def description(name)
+ if obj = @config[name.to_sym]
+ obj.desc
+ else
+ nil
+ end
+ end
+
+ def each
+ @config.each { |name, object|
+ yield name, object
+ }
+ end
+
+ # Iterate over each section name.
+ def eachsection
+ yielded = []
+ @config.each do |name, object|
+ section = object.section
+ unless yielded.include? section
+ yield section
+ yielded << section
+ end
+ end
+ end
+
+ # Return an object by name.
+ def setting(param)
+ param = param.to_sym
+ @config[param]
+ end
+
+ # Handle a command-line argument.
+ def handlearg(opt, value = nil)
+ @cache.clear
+ value &&= munge_value(value)
+ str = opt.sub(/^--/,'')
+
+ bool = true
+ newstr = str.sub(/^no-/, '')
+ if newstr != str
+ str = newstr
+ bool = false
+ end
+ str = str.intern
+
+ if @config[str].is_a?(Puppet::Util::Settings::BooleanSetting)
+ if value == "" or value.nil?
+ value = bool
+ end
+ end
+
+ set_value(str, value, :cli)
+ end
+
+ def without_noop
+ old_noop = value(:noop,:cli) and set_value(:noop, false, :cli) if valid?(:noop)
+ yield
+ ensure
+ set_value(:noop, old_noop, :cli) if valid?(:noop)
+ end
+
+ def include?(name)
+ name = name.intern if name.is_a? String
+ @config.include?(name)
+ end
+
+ # check to see if a short name is already defined
+ def shortinclude?(short)
+ short = short.intern if name.is_a? String
+ @shortnames.include?(short)
+ end
+
+ # Create a new collection of config settings.
+ def initialize
+ @config = {}
+ @shortnames = {}
+
+ @created = []
+ @searchpath = nil
+
+ # Mutex-like thing to protect @values
+ @sync = Sync.new
+
+ # Keep track of set values.
+ @values = Hash.new { |hash, key| hash[key] = {} }
+
+ # And keep a per-environment cache
+ @cache = Hash.new { |hash, key| hash[key] = {} }
+
+ # The list of sections we've used.
+ @used = []
+ end
+
+ # NOTE: ACS ahh the util classes. . .sigh
+ # as part of a fix for 1183, I pulled the logic for the following 5 methods out of the executables and puppet.rb
+ # They probably deserve their own class, but I don't want to do that until I can refactor environments
+ # its a little better than where they were
+
+ # Prints the contents of a config file with the available config settings, or it
+ # prints a single value of a config setting.
+ def print_config_options
+ env = value(:environment)
+ val = value(:configprint)
+ if val == "all"
+ hash = {}
+ each do |name, obj|
+ val = value(name,env)
+ val = val.inspect if val == ""
+ hash[name] = val
+ end
+ hash.sort { |a,b| a[0].to_s <=> b[0].to_s }.each do |name, val|
+ puts "#{name} = #{val}"
+ end
+ else
+ val.split(/\s*,\s*/).sort.each do |v|
+ if include?(v)
+ #if there is only one value, just print it for back compatibility
+ if v == val
+ puts value(val,env)
+ break
+ end
+ puts "#{v} = #{value(v,env)}"
else
- [:cli, :memory, :run_mode, :main, :mutable_defaults]
- end
- end
-
- # Get a list of objects per section
- def sectionlist
- sectionlist = []
- self.each { |name, obj|
- section = obj.section || "puppet"
- sections[section] ||= []
- sectionlist << section unless sectionlist.include?(section)
- sections[section] << obj
- }
-
- return sectionlist, sections
- end
-
- def service_user_available?
- return @service_user_available if defined?(@service_user_available)
-
- return @service_user_available = false unless user_name = self[:user]
-
- user = Puppet::Type.type(:user).new :name => self[:user], :audit => :ensure
-
- @service_user_available = user.exists?
- end
-
- def legacy_to_mode(type, param)
- if not defined?(@app_names)
- require 'puppet/util/command_line'
- command_line = Puppet::Util::CommandLine.new
- @app_names = Puppet::Util::CommandLine::LegacyName.inject({}) do |hash, pair|
- app, legacy = pair
- command_line.require_application app
- hash[legacy.to_sym] = Puppet::Application.find(app).run_mode.name
- hash
- end
- end
- if new_type = @app_names[type]
- Puppet.warning "You have configuration parameter $#{param} specified in [#{type}], which is a deprecated section. I'm assuming you meant [#{new_type}]"
- return new_type
- end
- type
- end
-
- def set_value(param, value, type, options = {})
- param = param.to_sym
- unless setting = @config[param]
- if options[:ignore_bad_settings]
- return
- else
- raise ArgumentError,
- "Attempt to assign a value to unknown configuration parameter #{param.inspect}"
- end
- end
- value = setting.munge(value) if setting.respond_to?(:munge)
- setting.handle(value) if setting.respond_to?(:handle) and not options[:dont_trigger_handles]
- if ReadOnly.include? param and type != :mutable_defaults
- raise ArgumentError,
- "You're attempting to set configuration parameter $#{param}, which is read-only."
- end
- type = legacy_to_mode(type, param)
- @sync.synchronize do # yay, thread-safe
- @values[type][param] = value
- @cache.clear
-
- clearused
-
- # Clear the list of environments, because they cache, at least, the module path.
- # We *could* preferentially just clear them if the modulepath is changed,
- # but we don't really know if, say, the vardir is changed and the modulepath
- # is defined relative to it. We need the defined?(stuff) because of loading
- # order issues.
- Puppet::Node::Environment.clear if defined?(Puppet::Node) and defined?(Puppet::Node::Environment)
- end
-
- value
- end
-
- # Set a bunch of defaults in a given section. The sections are actually pretty
- # pointless, but they help break things up a bit, anyway.
- def setdefaults(section, defs)
- section = section.to_sym
- call = []
- defs.each { |name, hash|
- if hash.is_a? Array
- unless hash.length == 2
- raise ArgumentError, "Defaults specified as an array must contain only the default value and the decription"
- end
- tmp = hash
- hash = {}
- [:default, :desc].zip(tmp).each { |p,v| hash[p] = v }
- end
- name = name.to_sym
- hash[:name] = name
- hash[:section] = section
- raise ArgumentError, "Parameter #{name} is already defined" if @config.include?(name)
- tryconfig = newsetting(hash)
- if short = tryconfig.short
- if other = @shortnames[short]
- raise ArgumentError, "Parameter #{other.name} is already using short name '#{short}'"
- end
- @shortnames[short] = tryconfig
- end
- @config[name] = tryconfig
-
- # Collect the settings that need to have their hooks called immediately.
- # We have to collect them so that we can be sure we're fully initialized before
- # the hook is called.
- call << tryconfig if tryconfig.call_on_define
- }
-
- call.each { |setting| setting.handle(self.value(setting.name)) }
- end
-
- # Create a timer to check whether the file should be reparsed.
- def set_filetimeout_timer
- return unless timeout = self[:filetimeout] and timeout = Integer(timeout) and timeout > 0
- timer = EventLoop::Timer.new(:interval => timeout, :tolerance => 1, :start? => true) { self.reparse }
- end
-
- # Convert the settings we manage into a catalog full of resources that model those settings.
- def to_catalog(*sections)
- sections = nil if sections.empty?
-
- catalog = Puppet::Resource::Catalog.new("Settings")
-
- @config.values.find_all { |value| value.is_a?(FileSetting) }.each do |file|
- next unless (sections.nil? or sections.include?(file.section))
- next unless resource = file.to_resource
- next if catalog.resource(resource.ref)
-
- catalog.add_resource(resource)
- end
-
- add_user_resources(catalog, sections)
-
- catalog
- end
-
- # Convert our list of config settings into a configuration file.
- def to_config
- str = %{The configuration file for #{Puppet[:name]}. Note that this file
+ puts "invalid parameter: #{v}"
+ return false
+ end
+ end
+ end
+ true
+ end
+
+ def generate_config
+ puts to_config
+ true
+ end
+
+ def generate_manifest
+ puts to_manifest
+ true
+ end
+
+ def print_configs
+ return print_config_options if value(:configprint) != ""
+ return generate_config if value(:genconfig)
+ generate_manifest if value(:genmanifest)
+ end
+
+ def print_configs?
+ (value(:configprint) != "" || value(:genconfig) || value(:genmanifest)) && true
+ end
+
+ # Return a given object's file metadata.
+ def metadata(param)
+ if obj = @config[param.to_sym] and obj.is_a?(FileSetting)
+ return [:owner, :group, :mode].inject({}) do |meta, p|
+ if v = obj.send(p)
+ meta[p] = v
+ end
+ meta
+ end
+ else
+ nil
+ end
+ end
+
+ # Make a directory with the appropriate user, group, and mode
+ def mkdir(default)
+ obj = get_config_file_default(default)
+
+ Puppet::Util::SUIDManager.asuser(obj.owner, obj.group) do
+ mode = obj.mode || 0750
+ Dir.mkdir(obj.value, mode)
+ end
+ end
+
+ # Figure out the section name for the run_mode.
+ def run_mode
+ Puppet.run_mode.name
+ end
+
+ # Return all of the parameters associated with a given section.
+ def params(section = nil)
+ if section
+ section = section.intern if section.is_a? String
+ @config.find_all { |name, obj|
+ obj.section == section
+ }.collect { |name, obj|
+ name
+ }
+ else
+ @config.keys
+ end
+ end
+
+ # Parse the configuration file. Just provides
+ # thread safety.
+ def parse
+ raise "No :config setting defined; cannot parse unknown config file" unless self[:config]
+
+ @sync.synchronize do
+ unsafe_parse(self[:config])
+ end
+
+ # Create a timer so that this file will get checked automatically
+ # and reparsed if necessary.
+ set_filetimeout_timer
+ end
+
+ # Unsafely parse the file -- this isn't thread-safe and causes plenty of problems if used directly.
+ def unsafe_parse(file)
+ return unless FileTest.exist?(file)
+ begin
+ data = parse_file(file)
+ rescue => details
+ puts details.backtrace if Puppet[:trace]
+ Puppet.err "Could not parse #{file}: #{details}"
+ return
+ end
+
+ unsafe_clear(true)
+
+ metas = {}
+ data.each do |area, values|
+ metas[area] = values.delete(:_meta)
+ values.each do |key,value|
+ set_value(key, value, area, :dont_trigger_handles => true, :ignore_bad_settings => true )
+ end
+ end
+
+ # Determine our environment, if we have one.
+ if @config[:environment]
+ env = self.value(:environment).to_sym
+ else
+ env = "none"
+ end
+
+ # Call any hooks we should be calling.
+ settings_with_hooks.each do |setting|
+ each_source(env) do |source|
+ if value = @values[source][setting.name]
+ # We still have to use value to retrieve the value, since
+ # we want the fully interpolated value, not $vardir/lib or whatever.
+ # This results in extra work, but so few of the settings
+ # will have associated hooks that it ends up being less work this
+ # way overall.
+ setting.handle(self.value(setting.name, env))
+ break
+ end
+ end
+ end
+
+ # We have to do it in the reverse of the search path,
+ # because multiple sections could set the same value
+ # and I'm too lazy to only set the metadata once.
+ searchpath.reverse.each do |source|
+ source = run_mode if source == :run_mode
+ source = @name if (@name && source == :name)
+ if meta = metas[source]
+ set_metadata(meta)
+ end
+ end
+ end
+
+ # Create a new setting. The value is passed in because it's used to determine
+ # what kind of setting we're creating, but the value itself might be either
+ # a default or a value, so we can't actually assign it.
+ def newsetting(hash)
+ klass = nil
+ hash[:section] = hash[:section].to_sym if hash[:section]
+ if type = hash[:type]
+ unless klass = {:setting => Setting, :file => FileSetting, :boolean => BooleanSetting}[type]
+ raise ArgumentError, "Invalid setting type '#{type}'"
+ end
+ hash.delete(:type)
+ else
+ case hash[:default]
+ when true, false, "true", "false"
+ klass = BooleanSetting
+ when /^\$\w+\//, /^\//, /^\w:\//
+ klass = FileSetting
+ when String, Integer, Float # nothing
+ klass = Setting
+ else
+ raise ArgumentError, "Invalid value '#{hash[:default].inspect}' for #{hash[:name]}"
+ end
+ end
+ hash[:settings] = self
+ setting = klass.new(hash)
+
+ setting
+ end
+
+ # This has to be private, because it doesn't add the settings to @config
+ private :newsetting
+
+ # Iterate across all of the objects in a given section.
+ def persection(section)
+ section = section.to_sym
+ self.each { |name, obj|
+ if obj.section == section
+ yield obj
+ end
+ }
+ end
+
+ # Cache this in an easily clearable way, since we were
+ # having trouble cleaning it up after tests.
+ cached_attr(:file) do
+ if path = self[:config] and FileTest.exist?(path)
+ Puppet::Util::LoadedFile.new(path)
+ end
+ end
+
+ # Reparse our config file, if necessary.
+ def reparse
+ if file and file.changed?
+ Puppet.notice "Reparsing #{file.file}"
+ parse
+ reuse
+ end
+ end
+
+ def reuse
+ return unless defined?(@used)
+ @sync.synchronize do # yay, thread-safe
+ new = @used
+ @used = []
+ self.use(*new)
+ end
+ end
+
+ # The order in which to search for values.
+ def searchpath(environment = nil)
+ if environment
+ [:cli, :memory, environment, :run_mode, :main, :mutable_defaults]
+ else
+ [:cli, :memory, :run_mode, :main, :mutable_defaults]
+ end
+ end
+
+ # Get a list of objects per section
+ def sectionlist
+ sectionlist = []
+ self.each { |name, obj|
+ section = obj.section || "puppet"
+ sections[section] ||= []
+ sectionlist << section unless sectionlist.include?(section)
+ sections[section] << obj
+ }
+
+ return sectionlist, sections
+ end
+
+ def service_user_available?
+ return @service_user_available if defined?(@service_user_available)
+
+ return @service_user_available = false unless user_name = self[:user]
+
+ user = Puppet::Type.type(:user).new :name => self[:user], :audit => :ensure
+
+ @service_user_available = user.exists?
+ end
+
+ def legacy_to_mode(type, param)
+ if not defined?(@app_names)
+ require 'puppet/util/command_line'
+ command_line = Puppet::Util::CommandLine.new
+ @app_names = Puppet::Util::CommandLine::LegacyName.inject({}) do |hash, pair|
+ app, legacy = pair
+ command_line.require_application app
+ hash[legacy.to_sym] = Puppet::Application.find(app).run_mode.name
+ hash
+ end
+ end
+ if new_type = @app_names[type]
+ Puppet.warning "You have configuration parameter $#{param} specified in [#{type}], which is a deprecated section. I'm assuming you meant [#{new_type}]"
+ return new_type
+ end
+ type
+ end
+
+ def set_value(param, value, type, options = {})
+ param = param.to_sym
+ unless setting = @config[param]
+ if options[:ignore_bad_settings]
+ return
+ else
+ raise ArgumentError,
+ "Attempt to assign a value to unknown configuration parameter #{param.inspect}"
+ end
+ end
+ value = setting.munge(value) if setting.respond_to?(:munge)
+ setting.handle(value) if setting.respond_to?(:handle) and not options[:dont_trigger_handles]
+ if ReadOnly.include? param and type != :mutable_defaults
+ raise ArgumentError,
+ "You're attempting to set configuration parameter $#{param}, which is read-only."
+ end
+ type = legacy_to_mode(type, param)
+ @sync.synchronize do # yay, thread-safe
+ @values[type][param] = value
+ @cache.clear
+
+ clearused
+
+ # Clear the list of environments, because they cache, at least, the module path.
+ # We *could* preferentially just clear them if the modulepath is changed,
+ # but we don't really know if, say, the vardir is changed and the modulepath
+ # is defined relative to it. We need the defined?(stuff) because of loading
+ # order issues.
+ Puppet::Node::Environment.clear if defined?(Puppet::Node) and defined?(Puppet::Node::Environment)
+ end
+
+ value
+ end
+
+ # Set a bunch of defaults in a given section. The sections are actually pretty
+ # pointless, but they help break things up a bit, anyway.
+ def setdefaults(section, defs)
+ section = section.to_sym
+ call = []
+ defs.each { |name, hash|
+ if hash.is_a? Array
+ unless hash.length == 2
+ raise ArgumentError, "Defaults specified as an array must contain only the default value and the decription"
+ end
+ tmp = hash
+ hash = {}
+ [:default, :desc].zip(tmp).each { |p,v| hash[p] = v }
+ end
+ name = name.to_sym
+ hash[:name] = name
+ hash[:section] = section
+ raise ArgumentError, "Parameter #{name} is already defined" if @config.include?(name)
+ tryconfig = newsetting(hash)
+ if short = tryconfig.short
+ if other = @shortnames[short]
+ raise ArgumentError, "Parameter #{other.name} is already using short name '#{short}'"
+ end
+ @shortnames[short] = tryconfig
+ end
+ @config[name] = tryconfig
+
+ # Collect the settings that need to have their hooks called immediately.
+ # We have to collect them so that we can be sure we're fully initialized before
+ # the hook is called.
+ call << tryconfig if tryconfig.call_on_define
+ }
+
+ call.each { |setting| setting.handle(self.value(setting.name)) }
+ end
+
+ # Create a timer to check whether the file should be reparsed.
+ def set_filetimeout_timer
+ return unless timeout = self[:filetimeout] and timeout = Integer(timeout) and timeout > 0
+ timer = EventLoop::Timer.new(:interval => timeout, :tolerance => 1, :start? => true) { self.reparse }
+ end
+
+ # Convert the settings we manage into a catalog full of resources that model those settings.
+ def to_catalog(*sections)
+ sections = nil if sections.empty?
+
+ catalog = Puppet::Resource::Catalog.new("Settings")
+
+ @config.values.find_all { |value| value.is_a?(FileSetting) }.each do |file|
+ next unless (sections.nil? or sections.include?(file.section))
+ next unless resource = file.to_resource
+ next if catalog.resource(resource.ref)
+
+ catalog.add_resource(resource)
+ end
+
+ add_user_resources(catalog, sections)
+
+ catalog
+ end
+
+ # Convert our list of config settings into a configuration file.
+ def to_config
+ str = %{The configuration file for #{Puppet[:name]}. Note that this file
is likely to have unused configuration parameters in it; any parameter that's
valid anywhere in Puppet can be in any config file, even if it's not used.
@@ -596,346 +596,346 @@ Generated on #{Time.now}.
# Add a section heading that matches our name.
if @config.include?(:run_mode)
- str += "[#{self[:run_mode]}]\n"
- end
- eachsection do |section|
- persection(section) do |obj|
- str += obj.to_config + "\n" unless ReadOnly.include? obj.name
- end
- end
-
- return str
- end
-
- # Convert to a parseable manifest
- def to_manifest
- catalog = to_catalog
- catalog.resource_refs.collect do |ref|
- catalog.resource(ref).to_manifest
- end.join("\n\n")
- end
-
- # Create the necessary objects to use a section. This is idempotent;
- # you can 'use' a section as many times as you want.
- def use(*sections)
- sections = sections.collect { |s| s.to_sym }
- @sync.synchronize do # yay, thread-safe
- sections = sections.reject { |s| @used.include?(s) }
-
- return if sections.empty?
-
- begin
- catalog = to_catalog(*sections).to_ral
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Could not create resources for managing Puppet's files and directories in sections #{sections.inspect}: #{detail}"
-
- # We need some way to get rid of any resources created during the catalog creation
- # but not cleaned up.
- return
- end
-
- without_noop do
- catalog.host_config = false
- catalog.apply do |transaction|
- if transaction.any_failed?
- report = transaction.report
- failures = report.logs.find_all { |log| log.level == :err }
- raise "Got #{failures.length} failure(s) while initializing: #{failures.collect { |l| l.to_s }.join("; ")}"
- end
- end
- end
-
- sections.each { |s| @used << s }
- @used.uniq!
- end
- end
-
- def valid?(param)
- param = param.to_sym
- @config.has_key?(param)
- end
-
- def uninterpolated_value(param, environment = nil)
- param = param.to_sym
- environment &&= environment.to_sym
-
- # See if we can find it within our searchable list of values
- val = catch :foundval do
- each_source(environment) do |source|
- # Look for the value. We have to test the hash for whether
- # it exists, because the value might be false.
- @sync.synchronize do
- throw :foundval, @values[source][param] if @values[source].include?(param)
- end
- end
- throw :foundval, nil
+ str += "[#{self[:run_mode]}]\n"
+ end
+ eachsection do |section|
+ persection(section) do |obj|
+ str += obj.to_config + "\n" unless ReadOnly.include? obj.name
+ end
+ end
+
+ return str
+ end
+
+ # Convert to a parseable manifest
+ def to_manifest
+ catalog = to_catalog
+ catalog.resource_refs.collect do |ref|
+ catalog.resource(ref).to_manifest
+ end.join("\n\n")
+ end
+
+ # Create the necessary objects to use a section. This is idempotent;
+ # you can 'use' a section as many times as you want.
+ def use(*sections)
+ sections = sections.collect { |s| s.to_sym }
+ @sync.synchronize do # yay, thread-safe
+ sections = sections.reject { |s| @used.include?(s) }
+
+ return if sections.empty?
+
+ begin
+ catalog = to_catalog(*sections).to_ral
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Could not create resources for managing Puppet's files and directories in sections #{sections.inspect}: #{detail}"
+
+ # We need some way to get rid of any resources created during the catalog creation
+ # but not cleaned up.
+ return
+ end
+
+ without_noop do
+ catalog.host_config = false
+ catalog.apply do |transaction|
+ if transaction.any_failed?
+ report = transaction.report
+ failures = report.logs.find_all { |log| log.level == :err }
+ raise "Got #{failures.length} failure(s) while initializing: #{failures.collect { |l| l.to_s }.join("; ")}"
+ end
+ end
+ end
+
+ sections.each { |s| @used << s }
+ @used.uniq!
+ end
+ end
+
+ def valid?(param)
+ param = param.to_sym
+ @config.has_key?(param)
+ end
+
+ def uninterpolated_value(param, environment = nil)
+ param = param.to_sym
+ environment &&= environment.to_sym
+
+ # See if we can find it within our searchable list of values
+ val = catch :foundval do
+ each_source(environment) do |source|
+ # Look for the value. We have to test the hash for whether
+ # it exists, because the value might be false.
+ @sync.synchronize do
+ throw :foundval, @values[source][param] if @values[source].include?(param)
end
-
- # If we didn't get a value, use the default
- val = @config[param].default if val.nil?
-
- val
+ end
+ throw :foundval, nil
end
- # Find the correct value using our search path. Optionally accept an environment
- # in which to search before the other configuration sections.
- def value(param, environment = nil)
- param = param.to_sym
- environment &&= environment.to_sym
-
- # Short circuit to nil for undefined parameters.
- return nil unless @config.include?(param)
+ # If we didn't get a value, use the default
+ val = @config[param].default if val.nil?
- # Yay, recursion.
- #self.reparse unless [:config, :filetimeout].include?(param)
+ val
+ end
- # Check the cache first. It needs to be a per-environment
- # cache so that we don't spread values from one env
- # to another.
- if cached = @cache[environment||"none"][param]
- return cached
- end
-
- val = uninterpolated_value(param, environment)
+ # Find the correct value using our search path. Optionally accept an environment
+ # in which to search before the other configuration sections.
+ def value(param, environment = nil)
+ param = param.to_sym
+ environment &&= environment.to_sym
- if param == :code
- # if we interpolate code, all hell breaks loose.
- return val
- end
+ # Short circuit to nil for undefined parameters.
+ return nil unless @config.include?(param)
- # Convert it if necessary
- val = convert(val, environment)
+ # Yay, recursion.
+ #self.reparse unless [:config, :filetimeout].include?(param)
- # And cache it
- @cache[environment||"none"][param] = val
- val
+ # Check the cache first. It needs to be a per-environment
+ # cache so that we don't spread values from one env
+ # to another.
+ if cached = @cache[environment||"none"][param]
+ return cached
end
- # Open a file with the appropriate user, group, and mode
- def write(default, *args, &bloc)
- obj = get_config_file_default(default)
- writesub(default, value(obj.name), *args, &bloc)
- end
+ val = uninterpolated_value(param, environment)
- # Open a non-default file under a default dir with the appropriate user,
- # group, and mode
- def writesub(default, file, *args, &bloc)
- obj = get_config_file_default(default)
- chown = nil
- if Puppet.features.root?
- chown = [obj.owner, obj.group]
- else
- chown = [nil, nil]
- end
-
- Puppet::Util::SUIDManager.asuser(*chown) do
- mode = obj.mode || 0640
- args << "w" if args.empty?
-
- args << mode
-
- # Update the umask to make non-executable files
- Puppet::Util.withumask(File.umask ^ 0111) do
- File.open(file, *args) do |file|
- yield file
- end
- end
- end
- end
-
- def readwritelock(default, *args, &bloc)
- file = value(get_config_file_default(default).name)
- tmpfile = file + ".tmp"
- sync = Sync.new
- raise Puppet::DevError, "Cannot create #{file}; directory #{File.dirname(file)} does not exist" unless FileTest.directory?(File.dirname(tmpfile))
-
- sync.synchronize(Sync::EX) do
- File.open(file, ::File::CREAT|::File::RDWR, 0600) do |rf|
- rf.lock_exclusive do
- if File.exist?(tmpfile)
- raise Puppet::Error, ".tmp file already exists for #{file}; Aborting locked write. Check the .tmp file and delete if appropriate"
- end
-
- # If there's a failure, remove our tmpfile
- begin
- writesub(default, tmpfile, *args, &bloc)
- rescue
- File.unlink(tmpfile) if FileTest.exist?(tmpfile)
- raise
- end
-
- begin
- File.rename(tmpfile, file)
- rescue => detail
- Puppet.err "Could not rename #{file} to #{tmpfile}: #{detail}"
- File.unlink(tmpfile) if FileTest.exist?(tmpfile)
- end
- end
- end
- end
+ if param == :code
+ # if we interpolate code, all hell breaks loose.
+ return val
end
- private
+ # Convert it if necessary
+ val = convert(val, environment)
- def get_config_file_default(default)
- obj = nil
- unless obj = @config[default]
- raise ArgumentError, "Unknown default #{default}"
- end
+ # And cache it
+ @cache[environment||"none"][param] = val
+ val
+ end
- raise ArgumentError, "Default #{default} is not a file" unless obj.is_a? FileSetting
+ # Open a file with the appropriate user, group, and mode
+ def write(default, *args, &bloc)
+ obj = get_config_file_default(default)
+ writesub(default, value(obj.name), *args, &bloc)
+ end
- obj
+ # Open a non-default file under a default dir with the appropriate user,
+ # group, and mode
+ def writesub(default, file, *args, &bloc)
+ obj = get_config_file_default(default)
+ chown = nil
+ if Puppet.features.root?
+ chown = [obj.owner, obj.group]
+ else
+ chown = [nil, nil]
end
- # Create the transportable objects for users and groups.
- def add_user_resources(catalog, sections)
- return unless Puppet.features.root?
- return unless self[:mkusers]
-
- @config.each do |name, setting|
- next unless setting.respond_to?(:owner)
- next unless sections.nil? or sections.include?(setting.section)
+ Puppet::Util::SUIDManager.asuser(*chown) do
+ mode = obj.mode || 0640
+ args << "w" if args.empty?
- if user = setting.owner and user != "root" and catalog.resource(:user, user).nil?
- resource = Puppet::Resource.new(:user, user, :parameters => {:ensure => :present})
- resource[:gid] = self[:group] if self[:group]
- catalog.add_resource resource
- end
- if group = setting.group and ! %w{root wheel}.include?(group) and catalog.resource(:group, group).nil?
- catalog.add_resource Puppet::Resource.new(:group, group, :parameters => {:ensure => :present})
- end
- end
- end
+ args << mode
- # Yield each search source in turn.
- def each_source(environment)
- searchpath(environment).each do |source|
- # Modify the source as necessary.
- source = self.run_mode if source == :run_mode
- yield source
- end
- end
-
- # Return all settings that have associated hooks; this is so
- # we can call them after parsing the configuration file.
- def settings_with_hooks
- @config.values.find_all { |setting| setting.respond_to?(:handle) }
- end
-
- # Extract extra setting information for files.
- def extract_fileinfo(string)
- result = {}
- value = string.sub(/\{\s*([^}]+)\s*\}/) do
- params = $1
- params.split(/\s*,\s*/).each do |str|
- if str =~ /^\s*(\w+)\s*=\s*([\w\d]+)\s*$/
- param, value = $1.intern, $2
- result[param] = value
- raise ArgumentError, "Invalid file option '#{param}'" unless [:owner, :mode, :group].include?(param)
-
- if param == :mode and value !~ /^\d+$/
- raise ArgumentError, "File modes must be numbers"
- end
- else
- raise ArgumentError, "Could not parse '#{string}'"
- end
- end
- ''
- end
- result[:value] = value.sub(/\s*$/, '')
- result
- end
-
- # Convert arguments into booleans, integers, or whatever.
- def munge_value(value)
- # Handle different data types correctly
- return case value
- when /^false$/i; false
- when /^true$/i; true
- when /^\d+$/i; Integer(value)
- when true; true
- when false; false
- else
- value.gsub(/^["']|["']$/,'').sub(/\s+$/, '')
+ # Update the umask to make non-executable files
+ Puppet::Util.withumask(File.umask ^ 0111) do
+ File.open(file, *args) do |file|
+ yield file
+ end
+ end
+ end
+ end
+
+ def readwritelock(default, *args, &bloc)
+ file = value(get_config_file_default(default).name)
+ tmpfile = file + ".tmp"
+ sync = Sync.new
+ raise Puppet::DevError, "Cannot create #{file}; directory #{File.dirname(file)} does not exist" unless FileTest.directory?(File.dirname(tmpfile))
+
+ sync.synchronize(Sync::EX) do
+ File.open(file, ::File::CREAT|::File::RDWR, 0600) do |rf|
+ rf.lock_exclusive do
+ if File.exist?(tmpfile)
+ raise Puppet::Error, ".tmp file already exists for #{file}; Aborting locked write. Check the .tmp file and delete if appropriate"
+ end
+
+ # If there's a failure, remove our tmpfile
+ begin
+ writesub(default, tmpfile, *args, &bloc)
+ rescue
+ File.unlink(tmpfile) if FileTest.exist?(tmpfile)
+ raise
+ end
+
+ begin
+ File.rename(tmpfile, file)
+ rescue => detail
+ Puppet.err "Could not rename #{file} to #{tmpfile}: #{detail}"
+ File.unlink(tmpfile) if FileTest.exist?(tmpfile)
+ end
+ end
+ end
+ end
+ end
+
+ private
+
+ def get_config_file_default(default)
+ obj = nil
+ unless obj = @config[default]
+ raise ArgumentError, "Unknown default #{default}"
+ end
+
+ raise ArgumentError, "Default #{default} is not a file" unless obj.is_a? FileSetting
+
+ obj
+ end
+
+ # Create the transportable objects for users and groups.
+ def add_user_resources(catalog, sections)
+ return unless Puppet.features.root?
+ return unless self[:mkusers]
+
+ @config.each do |name, setting|
+ next unless setting.respond_to?(:owner)
+ next unless sections.nil? or sections.include?(setting.section)
+
+ if user = setting.owner and user != "root" and catalog.resource(:user, user).nil?
+ resource = Puppet::Resource.new(:user, user, :parameters => {:ensure => :present})
+ resource[:gid] = self[:group] if self[:group]
+ catalog.add_resource resource
+ end
+ if group = setting.group and ! %w{root wheel}.include?(group) and catalog.resource(:group, group).nil?
+ catalog.add_resource Puppet::Resource.new(:group, group, :parameters => {:ensure => :present})
+ end
+ end
+ end
+
+ # Yield each search source in turn.
+ def each_source(environment)
+ searchpath(environment).each do |source|
+ # Modify the source as necessary.
+ source = self.run_mode if source == :run_mode
+ yield source
+ end
+ end
+
+ # Return all settings that have associated hooks; this is so
+ # we can call them after parsing the configuration file.
+ def settings_with_hooks
+ @config.values.find_all { |setting| setting.respond_to?(:handle) }
+ end
+
+ # Extract extra setting information for files.
+ def extract_fileinfo(string)
+ result = {}
+ value = string.sub(/\{\s*([^}]+)\s*\}/) do
+ params = $1
+ params.split(/\s*,\s*/).each do |str|
+ if str =~ /^\s*(\w+)\s*=\s*([\w\d]+)\s*$/
+ param, value = $1.intern, $2
+ result[param] = value
+ raise ArgumentError, "Invalid file option '#{param}'" unless [:owner, :mode, :group].include?(param)
+
+ if param == :mode and value !~ /^\d+$/
+ raise ArgumentError, "File modes must be numbers"
+ end
+ else
+ raise ArgumentError, "Could not parse '#{string}'"
+ end
+ end
+ ''
+ end
+ result[:value] = value.sub(/\s*$/, '')
+ result
+ end
+
+ # Convert arguments into booleans, integers, or whatever.
+ def munge_value(value)
+ # Handle different data types correctly
+ return case value
+ when /^false$/i; false
+ when /^true$/i; true
+ when /^\d+$/i; Integer(value)
+ when true; true
+ when false; false
+ else
+ value.gsub(/^["']|["']$/,'').sub(/\s+$/, '')
+ end
+ end
+
+ # This method just turns a file in to a hash of hashes.
+ def parse_file(file)
+ text = read_file(file)
+
+ result = Hash.new { |names, name|
+ names[name] = {}
+ }
+
+ count = 0
+
+ # Default to 'main' for the section.
+ section = :main
+ result[section][:_meta] = {}
+ text.split(/\n/).each { |line|
+ count += 1
+ case line
+ when /^\s*\[(\w+)\]\s*$/
+ section = $1.intern # Section names
+ # Add a meta section
+ result[section][:_meta] ||= {}
+ when /^\s*#/; next # Skip comments
+ when /^\s*$/; next # Skip blanks
+ when /^\s*(\w+)\s*=\s*(.*?)\s*$/ # settings
+ var = $1.intern
+
+ # We don't want to munge modes, because they're specified in octal, so we'll
+ # just leave them as a String, since Puppet handles that case correctly.
+ if var == :mode
+ value = $2
+ else
+ value = munge_value($2)
end
- end
- # This method just turns a file in to a hash of hashes.
- def parse_file(file)
- text = read_file(file)
-
- result = Hash.new { |names, name|
- names[name] = {}
- }
-
- count = 0
-
- # Default to 'main' for the section.
- section = :main
- result[section][:_meta] = {}
- text.split(/\n/).each { |line|
- count += 1
- case line
- when /^\s*\[(\w+)\]\s*$/
- section = $1.intern # Section names
- # Add a meta section
- result[section][:_meta] ||= {}
- when /^\s*#/; next # Skip comments
- when /^\s*$/; next # Skip blanks
- when /^\s*(\w+)\s*=\s*(.*?)\s*$/ # settings
- var = $1.intern
-
- # We don't want to munge modes, because they're specified in octal, so we'll
- # just leave them as a String, since Puppet handles that case correctly.
- if var == :mode
- value = $2
- else
- value = munge_value($2)
- end
-
- # Check to see if this is a file argument and it has extra options
- begin
- if value.is_a?(String) and options = extract_fileinfo(value)
- value = options[:value]
- options.delete(:value)
- result[section][:_meta][var] = options
- end
- result[section][var] = value
- rescue Puppet::Error => detail
- detail.file = file
- detail.line = line
- raise
- end
- else
- error = Puppet::Error.new("Could not match line #{line}")
- error.file = file
- error.line = line
- raise error
- end
- }
-
- result
- end
-
- # Read the file in.
- def read_file(file)
+ # Check to see if this is a file argument and it has extra options
begin
- return File.read(file)
- rescue Errno::ENOENT
- raise ArgumentError, "No such file #{file}"
- rescue Errno::EACCES
- raise ArgumentError, "Permission denied to file #{file}"
- end
- end
-
- # Set file metadata.
- def set_metadata(meta)
- meta.each do |var, values|
- values.each do |param, value|
- @config[var].send(param.to_s + "=", value)
- end
- end
- end
+ if value.is_a?(String) and options = extract_fileinfo(value)
+ value = options[:value]
+ options.delete(:value)
+ result[section][:_meta][var] = options
+ end
+ result[section][var] = value
+ rescue Puppet::Error => detail
+ detail.file = file
+ detail.line = line
+ raise
+ end
+ else
+ error = Puppet::Error.new("Could not match line #{line}")
+ error.file = file
+ error.line = line
+ raise error
+ end
+ }
+
+ result
+ end
+
+ # Read the file in.
+ def read_file(file)
+ begin
+ return File.read(file)
+ rescue Errno::ENOENT
+ raise ArgumentError, "No such file #{file}"
+ rescue Errno::EACCES
+ raise ArgumentError, "Permission denied to file #{file}"
+ end
+ end
+
+ # Set file metadata.
+ def set_metadata(meta)
+ meta.each do |var, values|
+ values.each do |param, value|
+ @config[var].send(param.to_s + "=", value)
+ end
+ end
+ end
end
diff --git a/lib/puppet/util/settings/boolean_setting.rb b/lib/puppet/util/settings/boolean_setting.rb
index 67fce9a..e4678c9 100644
--- a/lib/puppet/util/settings/boolean_setting.rb
+++ b/lib/puppet/util/settings/boolean_setting.rb
@@ -2,29 +2,29 @@ require 'puppet/util/settings/setting'
# A simple boolean.
class Puppet::Util::Settings::BooleanSetting < Puppet::Util::Settings::Setting
- # get the arguments in getopt format
- def getopt_args
- if short
- [["--#{name}", "-#{short}", GetoptLong::NO_ARGUMENT], ["--no-#{name}", GetoptLong::NO_ARGUMENT]]
- else
- [["--#{name}", GetoptLong::NO_ARGUMENT], ["--no-#{name}", GetoptLong::NO_ARGUMENT]]
- end
+ # get the arguments in getopt format
+ def getopt_args
+ if short
+ [["--#{name}", "-#{short}", GetoptLong::NO_ARGUMENT], ["--no-#{name}", GetoptLong::NO_ARGUMENT]]
+ else
+ [["--#{name}", GetoptLong::NO_ARGUMENT], ["--no-#{name}", GetoptLong::NO_ARGUMENT]]
end
+ end
- def optparse_args
- if short
- ["--[no-]#{name}", "-#{short}", desc, :NONE ]
- else
- ["--[no-]#{name}", desc, :NONE]
- end
+ def optparse_args
+ if short
+ ["--[no-]#{name}", "-#{short}", desc, :NONE ]
+ else
+ ["--[no-]#{name}", desc, :NONE]
end
+ end
- def munge(value)
- case value
- when true, "true"; return true
- when false, "false"; return false
- else
- raise ArgumentError, "Invalid value '#{value.inspect}' for #{@name}"
- end
+ def munge(value)
+ case value
+ when true, "true"; return true
+ when false, "false"; return false
+ else
+ raise ArgumentError, "Invalid value '#{value.inspect}' for #{@name}"
end
+ end
end
diff --git a/lib/puppet/util/settings/file_setting.rb b/lib/puppet/util/settings/file_setting.rb
index ee17d7d..edbab1d 100644
--- a/lib/puppet/util/settings/file_setting.rb
+++ b/lib/puppet/util/settings/file_setting.rb
@@ -2,122 +2,122 @@ require 'puppet/util/settings/setting'
# A file.
class Puppet::Util::Settings::FileSetting < Puppet::Util::Settings::Setting
- AllowedOwners = %w{root service}
- AllowedGroups = %w{root service}
+ AllowedOwners = %w{root service}
+ AllowedGroups = %w{root service}
- class SettingError < StandardError; end
+ class SettingError < StandardError; end
- attr_accessor :mode, :create
+ attr_accessor :mode, :create
- # Should we create files, rather than just directories?
- def create_files?
- create
- end
+ # Should we create files, rather than just directories?
+ def create_files?
+ create
+ end
- def group=(value)
- unless AllowedGroups.include?(value)
- identifying_fields = [desc,name,default].compact.join(': ')
- raise SettingError, "Internal error: The :group setting for #{identifying_fields} must be 'service', not '#{value}'"
- end
- @group = value
+ def group=(value)
+ unless AllowedGroups.include?(value)
+ identifying_fields = [desc,name,default].compact.join(': ')
+ raise SettingError, "Internal error: The :group setting for #{identifying_fields} must be 'service', not '#{value}'"
end
-
- def group
- return unless @group
- @settings[:group]
+ @group = value
+ end
+
+ def group
+ return unless @group
+ @settings[:group]
+ end
+
+ def owner=(value)
+ unless AllowedOwners.include?(value)
+ identifying_fields = [desc,name,default].compact.join(': ')
+ raise SettingError, "Internal error: The :owner setting for #{identifying_fields} must be either 'root' or 'service', not '#{value}'"
end
-
- def owner=(value)
- unless AllowedOwners.include?(value)
- identifying_fields = [desc,name,default].compact.join(': ')
- raise SettingError, "Internal error: The :owner setting for #{identifying_fields} must be either 'root' or 'service', not '#{value}'"
- end
- @owner = value
+ @owner = value
+ end
+
+ def owner
+ return unless @owner
+ return "root" if @owner == "root" or ! use_service_user?
+ @settings[:user]
+ end
+
+ def use_service_user?
+ @settings[:mkusers] or @settings.service_user_available?
+ end
+
+ # Set the type appropriately. Yep, a hack. This supports either naming
+ # the variable 'dir', or adding a slash at the end.
+ def munge(value)
+ # If it's not a fully qualified path...
+ if value.is_a?(String) and value !~ /^\$/ and value != 'false'
+ # Make it one
+ value = File.expand_path(value)
end
-
- def owner
- return unless @owner
- return "root" if @owner == "root" or ! use_service_user?
- @settings[:user]
+ if value.to_s =~ /\/$/
+ @type = :directory
+ return value.sub(/\/$/, '')
end
-
- def use_service_user?
- @settings[:mkusers] or @settings.service_user_available?
+ value
+ end
+
+ # Return the appropriate type.
+ def type
+ value = @settings.value(self.name)
+ if @name.to_s =~ /dir/
+ return :directory
+ elsif value.to_s =~ /\/$/
+ return :directory
+ elsif value.is_a? String
+ return :file
+ else
+ return nil
end
+ end
- # Set the type appropriately. Yep, a hack. This supports either naming
- # the variable 'dir', or adding a slash at the end.
- def munge(value)
- # If it's not a fully qualified path...
- if value.is_a?(String) and value !~ /^\$/ and value != 'false'
- # Make it one
- value = File.expand_path(value)
- end
- if value.to_s =~ /\/$/
- @type = :directory
- return value.sub(/\/$/, '')
- end
- value
- end
+ # Turn our setting thing into a Puppet::Resource instance.
+ def to_resource
+ return nil unless type = self.type
- # Return the appropriate type.
- def type
- value = @settings.value(self.name)
- if @name.to_s =~ /dir/
- return :directory
- elsif value.to_s =~ /\/$/
- return :directory
- elsif value.is_a? String
- return :file
- else
- return nil
- end
- end
+ path = self.value
- # Turn our setting thing into a Puppet::Resource instance.
- def to_resource
- return nil unless type = self.type
+ return nil unless path.is_a?(String)
- path = self.value
+ # Make sure the paths are fully qualified.
+ path = File.expand_path(path)
- return nil unless path.is_a?(String)
+ return nil unless type == :directory or create_files? or File.exist?(path)
+ return nil if path =~ /^\/dev/
- # Make sure the paths are fully qualified.
- path = File.expand_path(path)
+ resource = Puppet::Resource.new(:file, path)
- return nil unless type == :directory or create_files? or File.exist?(path)
- return nil if path =~ /^\/dev/
+ if Puppet[:manage_internal_file_permissions]
+ resource[:mode] = self.mode if self.mode
- resource = Puppet::Resource.new(:file, path)
-
- if Puppet[:manage_internal_file_permissions]
- resource[:mode] = self.mode if self.mode
-
- if Puppet.features.root?
- resource[:owner] = self.owner if self.owner
- resource[:group] = self.group if self.group
- end
- end
-
- resource[:ensure] = type
- resource[:loglevel] = :debug
- resource[:backup] = false
-
- resource.tag(self.section, self.name, "settings")
-
- resource
+ if Puppet.features.root?
+ resource[:owner] = self.owner if self.owner
+ resource[:group] = self.group if self.group
+ end
end
- # Make sure any provided variables look up to something.
- def validate(value)
- return true unless value.is_a? String
- value.scan(/\$(\w+)/) { |name|
- name = $1
- unless @settings.include?(name)
- raise ArgumentError,
- "Settings parameter '#{name}' is undefined"
- end
- }
- end
+ resource[:ensure] = type
+ resource[:loglevel] = :debug
+ resource[:backup] = false
+
+ resource.tag(self.section, self.name, "settings")
+
+ resource
+ end
+
+ # Make sure any provided variables look up to something.
+ def validate(value)
+ return true unless value.is_a? String
+ value.scan(/\$(\w+)/) { |name|
+ name = $1
+ unless @settings.include?(name)
+ raise ArgumentError,
+ "Settings parameter '#{name}' is undefined"
+ end
+ }
+ end
end
diff --git a/lib/puppet/util/settings/setting.rb b/lib/puppet/util/settings/setting.rb
index a14dcf0..07409ee 100644
--- a/lib/puppet/util/settings/setting.rb
+++ b/lib/puppet/util/settings/setting.rb
@@ -1,94 +1,94 @@
# The base element type.
class Puppet::Util::Settings::Setting
- attr_accessor :name, :section, :default, :setbycli, :call_on_define
- attr_reader :desc, :short
-
- def desc=(value)
- @desc = value.gsub(/^\s*/, '')
+ attr_accessor :name, :section, :default, :setbycli, :call_on_define
+ attr_reader :desc, :short
+
+ def desc=(value)
+ @desc = value.gsub(/^\s*/, '')
+ end
+
+ # get the arguments in getopt format
+ def getopt_args
+ if short
+ [["--#{name}", "-#{short}", GetoptLong::REQUIRED_ARGUMENT]]
+ else
+ [["--#{name}", GetoptLong::REQUIRED_ARGUMENT]]
end
-
- # get the arguments in getopt format
- def getopt_args
- if short
- [["--#{name}", "-#{short}", GetoptLong::REQUIRED_ARGUMENT]]
- else
- [["--#{name}", GetoptLong::REQUIRED_ARGUMENT]]
- end
+ end
+
+ # get the arguments in OptionParser format
+ def optparse_args
+ if short
+ ["--#{name}", "-#{short}", desc, :REQUIRED]
+ else
+ ["--#{name}", desc, :REQUIRED]
end
+ end
- # get the arguments in OptionParser format
- def optparse_args
- if short
- ["--#{name}", "-#{short}", desc, :REQUIRED]
- else
- ["--#{name}", desc, :REQUIRED]
- end
- end
+ def hook=(block)
+ meta_def :handle, &block
+ end
- def hook=(block)
- meta_def :handle, &block
+ # Create the new element. Pretty much just sets the name.
+ def initialize(args = {})
+ unless @settings = args.delete(:settings)
+ raise ArgumentError.new("You must refer to a settings object")
end
- # Create the new element. Pretty much just sets the name.
- def initialize(args = {})
- unless @settings = args.delete(:settings)
- raise ArgumentError.new("You must refer to a settings object")
- end
-
- args.each do |param, value|
- method = param.to_s + "="
- raise ArgumentError, "#{self.class} does not accept #{param}" unless self.respond_to? method
+ args.each do |param, value|
+ method = param.to_s + "="
+ raise ArgumentError, "#{self.class} does not accept #{param}" unless self.respond_to? method
- self.send(method, value)
- end
-
- raise ArgumentError, "You must provide a description for the #{self.name} config option" unless self.desc
+ self.send(method, value)
end
- def iscreated
- @iscreated = true
- end
+ raise ArgumentError, "You must provide a description for the #{self.name} config option" unless self.desc
+ end
- def iscreated?
- @iscreated
- end
+ def iscreated
+ @iscreated = true
+ end
- def set?
- !!(!@value.nil?)
- end
-
- # short name for the celement
- def short=(value)
- raise ArgumentError, "Short names can only be one character." if value.to_s.length != 1
- @short = value.to_s
- end
+ def iscreated?
+ @iscreated
+ end
- # Convert the object to a config statement.
- def to_config
- str = @desc.gsub(/^/, "# ") + "\n"
+ def set?
+ !!(!@value.nil?)
+ end
- # Add in a statement about the default.
- str += "# The default value is '#{@default}'.\n" if @default
+ # short name for the celement
+ def short=(value)
+ raise ArgumentError, "Short names can only be one character." if value.to_s.length != 1
+ @short = value.to_s
+ end
- # If the value has not been overridden, then print it out commented
- # and unconverted, so it's clear that that's the default and how it
- # works.
- value = @settings.value(self.name)
+ # Convert the object to a config statement.
+ def to_config
+ str = @desc.gsub(/^/, "# ") + "\n"
- if value != @default
- line = "#{@name} = #{value}"
- else
- line = "# #{@name} = #{@default}"
- end
+ # Add in a statement about the default.
+ str += "# The default value is '#{@default}'.\n" if @default
- str += line + "\n"
+ # If the value has not been overridden, then print it out commented
+ # and unconverted, so it's clear that that's the default and how it
+ # works.
+ value = @settings.value(self.name)
- str.gsub(/^/, " ")
+ if value != @default
+ line = "#{@name} = #{value}"
+ else
+ line = "# #{@name} = #{@default}"
end
- # Retrieves the value, or if it's not set, retrieves the default.
- def value
- @settings.value(self.name)
- end
+ str += line + "\n"
+
+ str.gsub(/^/, " ")
+ end
+
+ # Retrieves the value, or if it's not set, retrieves the default.
+ def value
+ @settings.value(self.name)
+ end
end
diff --git a/lib/puppet/util/storage.rb b/lib/puppet/util/storage.rb
index 6927092..abc0bbc 100644
--- a/lib/puppet/util/storage.rb
+++ b/lib/puppet/util/storage.rb
@@ -5,92 +5,92 @@ require 'puppet/util/file_locking'
# a class for storing state
class Puppet::Util::Storage
- include Singleton
- include Puppet::Util
-
- def self.state
- @@state
+ include Singleton
+ include Puppet::Util
+
+ def self.state
+ @@state
+ end
+
+ def initialize
+ self.class.load
+ end
+
+ # Return a hash that will be stored to disk. It's worth noting
+ # here that we use the object's full path, not just the name/type
+ # combination. At the least, this is useful for those non-isomorphic
+ # types like exec, but it also means that if an object changes locations
+ # in the configuration it will lose its cache.
+ def self.cache(object)
+ if object.is_a?(Symbol)
+ name = object
+ else
+ name = object.to_s
end
- def initialize
- self.class.load
- end
+ @@state[name] ||= {}
+ end
- # Return a hash that will be stored to disk. It's worth noting
- # here that we use the object's full path, not just the name/type
- # combination. At the least, this is useful for those non-isomorphic
- # types like exec, but it also means that if an object changes locations
- # in the configuration it will lose its cache.
- def self.cache(object)
- if object.is_a?(Symbol)
- name = object
- else
- name = object.to_s
- end
-
- @@state[name] ||= {}
- end
-
- def self.clear
- @@state.clear
- Storage.init
- end
-
- def self.init
- @@state = {}
- @@splitchar = "\t"
- end
+ def self.clear
+ @@state.clear
+ Storage.init
+ end
- self.init
+ def self.init
+ @@state = {}
+ @@splitchar = "\t"
+ end
- def self.load
- Puppet.settings.use(:main) unless FileTest.directory?(Puppet[:statedir])
+ self.init
- unless File.exists?(Puppet[:statefile])
- self.init unless !@@state.nil?
- return
- end
- unless File.file?(Puppet[:statefile])
- Puppet.warning("Checksumfile #{Puppet[:statefile]} is not a file, ignoring")
- return
- end
- Puppet::Util.benchmark(:debug, "Loaded state") do
- Puppet::Util::FileLocking.readlock(Puppet[:statefile]) do |file|
- begin
- @@state = YAML.load(file)
- rescue => detail
- Puppet.err "Checksumfile #{Puppet[:statefile]} is corrupt (#{detail}); replacing"
- begin
- File.rename(Puppet[:statefile], Puppet[:statefile] + ".bad")
- rescue
- raise Puppet::Error,
- "Could not rename corrupt #{Puppet[:statefile]}; remove manually"
- end
- end
- end
- end
+ def self.load
+ Puppet.settings.use(:main) unless FileTest.directory?(Puppet[:statedir])
- unless @@state.is_a?(Hash)
- Puppet.err "State got corrupted"
- self.init
+ unless File.exists?(Puppet[:statefile])
+ self.init unless !@@state.nil?
+ return
+ end
+ unless File.file?(Puppet[:statefile])
+ Puppet.warning("Checksumfile #{Puppet[:statefile]} is not a file, ignoring")
+ return
+ end
+ Puppet::Util.benchmark(:debug, "Loaded state") do
+ Puppet::Util::FileLocking.readlock(Puppet[:statefile]) do |file|
+ begin
+ @@state = YAML.load(file)
+ rescue => detail
+ Puppet.err "Checksumfile #{Puppet[:statefile]} is corrupt (#{detail}); replacing"
+ begin
+ File.rename(Puppet[:statefile], Puppet[:statefile] + ".bad")
+ rescue
+ raise Puppet::Error,
+ "Could not rename corrupt #{Puppet[:statefile]}; remove manually"
+ end
end
-
- #Puppet.debug "Loaded state is #{@@state.inspect}"
+ end
end
- def self.stateinspect
- @@state.inspect
+ unless @@state.is_a?(Hash)
+ Puppet.err "State got corrupted"
+ self.init
end
- def self.store
- Puppet.debug "Storing state"
+ #Puppet.debug "Loaded state is #{@@state.inspect}"
+ end
- Puppet.info "Creating state file #{Puppet[:statefile]}" unless FileTest.exist?(Puppet[:statefile])
+ def self.stateinspect
+ @@state.inspect
+ end
- Puppet::Util.benchmark(:debug, "Stored state") do
- Puppet::Util::FileLocking.writelock(Puppet[:statefile], 0660) do |file|
- file.print YAML.dump(@@state)
- end
- end
+ def self.store
+ Puppet.debug "Storing state"
+
+ Puppet.info "Creating state file #{Puppet[:statefile]}" unless FileTest.exist?(Puppet[:statefile])
+
+ Puppet::Util.benchmark(:debug, "Stored state") do
+ Puppet::Util::FileLocking.writelock(Puppet[:statefile], 0660) do |file|
+ file.print YAML.dump(@@state)
+ end
end
+ end
end
diff --git a/lib/puppet/util/subclass_loader.rb b/lib/puppet/util/subclass_loader.rb
index ee6b68b..3fb0488 100644
--- a/lib/puppet/util/subclass_loader.rb
+++ b/lib/puppet/util/subclass_loader.rb
@@ -4,79 +4,79 @@
#
# This module is currently used by network handlers and clients.
module Puppet::Util::SubclassLoader
- attr_accessor :loader, :classloader
+ attr_accessor :loader, :classloader
- # Iterate over each of the subclasses.
- def each
- @subclasses ||= []
- @subclasses.each { |c| yield c }
- end
+ # Iterate over each of the subclasses.
+ def each
+ @subclasses ||= []
+ @subclasses.each { |c| yield c }
+ end
- # The hook method that sets up subclass loading. We need the name
- # of the method to create and the path in which to look for them.
- def handle_subclasses(name, path)
- raise ArgumentError, "Must be a class to use SubclassLoader" unless self.is_a?(Class)
- @subclasses = []
+ # The hook method that sets up subclass loading. We need the name
+ # of the method to create and the path in which to look for them.
+ def handle_subclasses(name, path)
+ raise ArgumentError, "Must be a class to use SubclassLoader" unless self.is_a?(Class)
+ @subclasses = []
- @loader = Puppet::Util::Autoload.new(
- self,
+ @loader = Puppet::Util::Autoload.new(
+ self,
- path, :wrap => false
- )
+ path, :wrap => false
+ )
- @subclassname = name
+ @subclassname = name
- @classloader = self
+ @classloader = self
- # Now create a method for retrieving these subclasses by name. Note
- # that we're defining a class method here, not an instance.
- meta_def(name) do |subname|
- subname = subname.to_s.downcase
+ # Now create a method for retrieving these subclasses by name. Note
+ # that we're defining a class method here, not an instance.
+ meta_def(name) do |subname|
+ subname = subname.to_s.downcase
- unless c = @subclasses.find { |c| c.name.to_s.downcase == subname }
- loader.load(subname)
- c = @subclasses.find { |c| c.name.to_s.downcase == subname }
+ unless c = @subclasses.find { |c| c.name.to_s.downcase == subname }
+ loader.load(subname)
+ c = @subclasses.find { |c| c.name.to_s.downcase == subname }
- # Now make the method that returns this subclass. This way we
- # normally avoid the method_missing method.
- define_method(subname) { c } if c and ! respond_to?(subname)
- end
- return c
- end
+ # Now make the method that returns this subclass. This way we
+ # normally avoid the method_missing method.
+ define_method(subname) { c } if c and ! respond_to?(subname)
+ end
+ return c
end
+ end
- # Add a new class to our list. Note that this has to handle subclasses of
- # subclasses, thus the reason we're keeping track of the @@classloader.
- def inherited(sub)
- @subclasses ||= []
- sub.classloader = self.classloader
- if self.classloader == self
- @subclasses << sub
- else
- @classloader.inherited(sub)
- end
+ # Add a new class to our list. Note that this has to handle subclasses of
+ # subclasses, thus the reason we're keeping track of the @@classloader.
+ def inherited(sub)
+ @subclasses ||= []
+ sub.classloader = self.classloader
+ if self.classloader == self
+ @subclasses << sub
+ else
+ @classloader.inherited(sub)
end
+ end
- # See if we can load a class.
- def method_missing(method, *args)
- unless self == self.classloader
- super
- end
- return nil unless defined?(@subclassname)
- self.send(@subclassname, method) || nil
+ # See if we can load a class.
+ def method_missing(method, *args)
+ unless self == self.classloader
+ super
end
+ return nil unless defined?(@subclassname)
+ self.send(@subclassname, method) || nil
+ end
- # Retrieve or calculate a name.
- def name(dummy_argument=:work_arround_for_ruby_GC_bug)
- @name ||= self.to_s.sub(/.+::/, '').intern
+ # Retrieve or calculate a name.
+ def name(dummy_argument=:work_arround_for_ruby_GC_bug)
+ @name ||= self.to_s.sub(/.+::/, '').intern
- @name
- end
+ @name
+ end
- # Provide a list of all subclasses.
- def subclasses
- @loader.loadall
- @subclasses.collect { |klass| klass.name }
- end
+ # Provide a list of all subclasses.
+ def subclasses
+ @loader.loadall
+ @subclasses.collect { |klass| klass.name }
+ end
end
diff --git a/lib/puppet/util/suidmanager.rb b/lib/puppet/util/suidmanager.rb
index 9815646..4d2c322 100644
--- a/lib/puppet/util/suidmanager.rb
+++ b/lib/puppet/util/suidmanager.rb
@@ -2,105 +2,105 @@ require 'puppet/util/warnings'
require 'forwardable'
module Puppet::Util::SUIDManager
- include Puppet::Util::Warnings
- extend Forwardable
-
- # Note groups= is handled specially due to a bug in OS X 10.6
- to_delegate_to_process = [ :euid=, :euid, :egid=, :egid, :uid=, :uid, :gid=, :gid, :groups ]
-
- to_delegate_to_process.each do |method|
- def_delegator Process, method
- module_function method
- end
-
- def osx_maj_ver
- return @osx_maj_ver unless @osx_maj_ver.nil?
- require 'facter'
- # 'kernel' is available without explicitly loading all facts
- if Facter.value('kernel') != 'Darwin'
- @osx_maj_ver = false
- return @osx_maj_ver
- end
- # But 'macosx_productversion_major' requires it.
- Facter.loadfacts
- @osx_maj_ver = Facter.value('macosx_productversion_major')
- end
- module_function :osx_maj_ver
-
- def groups=(grouplist)
- if osx_maj_ver == '10.6'
- return true
- else
- return Process.groups = grouplist
- end
- end
- module_function :groups=
-
- if Facter['kernel'].value == 'Darwin'
- # Cannot change real UID on Darwin so we set euid
- alias :uid :euid
- alias :gid :egid
+ include Puppet::Util::Warnings
+ extend Forwardable
+
+ # Note groups= is handled specially due to a bug in OS X 10.6
+ to_delegate_to_process = [ :euid=, :euid, :egid=, :egid, :uid=, :uid, :gid=, :gid, :groups ]
+
+ to_delegate_to_process.each do |method|
+ def_delegator Process, method
+ module_function method
+ end
+
+ def osx_maj_ver
+ return @osx_maj_ver unless @osx_maj_ver.nil?
+ require 'facter'
+ # 'kernel' is available without explicitly loading all facts
+ if Facter.value('kernel') != 'Darwin'
+ @osx_maj_ver = false
+ return @osx_maj_ver
end
-
- def self.root?
- Process.uid == 0
- end
-
- # Runs block setting uid and gid if provided then restoring original ids
- def asuser(new_uid=nil, new_gid=nil)
- return yield if Puppet.features.microsoft_windows? or !root?
-
- # We set both because some programs like to drop privs, i.e. bash.
- old_uid, old_gid = self.uid, self.gid
- old_euid, old_egid = self.euid, self.egid
- old_groups = self.groups
- begin
- self.egid = convert_xid :gid, new_gid if new_gid
- self.initgroups(convert_xid(:uid, new_uid)) if new_uid
- self.euid = convert_xid :uid, new_uid if new_uid
-
- yield
- ensure
- self.euid, self.egid = old_euid, old_egid
- self.groups = old_groups
- end
+ # But 'macosx_productversion_major' requires it.
+ Facter.loadfacts
+ @osx_maj_ver = Facter.value('macosx_productversion_major')
+ end
+ module_function :osx_maj_ver
+
+ def groups=(grouplist)
+ if osx_maj_ver == '10.6'
+ return true
+ else
+ return Process.groups = grouplist
end
- module_function :asuser
-
- # Make sure the passed argument is a number.
- def convert_xid(type, id)
- map = {:gid => :group, :uid => :user}
- raise ArgumentError, "Invalid id type #{type}" unless map.include?(type)
- ret = Puppet::Util.send(type, id)
- if ret == nil
- raise Puppet::Error, "Invalid #{map[type]}: #{id}"
- end
- ret
+ end
+ module_function :groups=
+
+ if Facter['kernel'].value == 'Darwin'
+ # Cannot change real UID on Darwin so we set euid
+ alias :uid :euid
+ alias :gid :egid
+ end
+
+ def self.root?
+ Process.uid == 0
+ end
+
+ # Runs block setting uid and gid if provided then restoring original ids
+ def asuser(new_uid=nil, new_gid=nil)
+ return yield if Puppet.features.microsoft_windows? or !root?
+
+ # We set both because some programs like to drop privs, i.e. bash.
+ old_uid, old_gid = self.uid, self.gid
+ old_euid, old_egid = self.euid, self.egid
+ old_groups = self.groups
+ begin
+ self.egid = convert_xid :gid, new_gid if new_gid
+ self.initgroups(convert_xid(:uid, new_uid)) if new_uid
+ self.euid = convert_xid :uid, new_uid if new_uid
+
+ yield
+ ensure
+ self.euid, self.egid = old_euid, old_egid
+ self.groups = old_groups
end
- module_function :convert_xid
-
- # Initialize supplementary groups
- def initgroups(user)
- require 'etc'
- Process.initgroups(Etc.getpwuid(user).name, Process.gid)
- end
-
- module_function :initgroups
-
- def run_and_capture(command, new_uid=nil, new_gid=nil)
- output = Puppet::Util.execute(command, :failonfail => false, :uid => new_uid, :gid => new_gid)
- [output, $CHILD_STATUS.dup]
+ end
+ module_function :asuser
+
+ # Make sure the passed argument is a number.
+ def convert_xid(type, id)
+ map = {:gid => :group, :uid => :user}
+ raise ArgumentError, "Invalid id type #{type}" unless map.include?(type)
+ ret = Puppet::Util.send(type, id)
+ if ret == nil
+ raise Puppet::Error, "Invalid #{map[type]}: #{id}"
end
- module_function :run_and_capture
-
- def system(command, new_uid=nil, new_gid=nil)
- status = nil
- asuser(new_uid, new_gid) do
- Kernel.system(command)
- status = $CHILD_STATUS.dup
- end
- status
+ ret
+ end
+ module_function :convert_xid
+
+ # Initialize supplementary groups
+ def initgroups(user)
+ require 'etc'
+ Process.initgroups(Etc.getpwuid(user).name, Process.gid)
+ end
+
+ module_function :initgroups
+
+ def run_and_capture(command, new_uid=nil, new_gid=nil)
+ output = Puppet::Util.execute(command, :failonfail => false, :uid => new_uid, :gid => new_gid)
+ [output, $CHILD_STATUS.dup]
+ end
+ module_function :run_and_capture
+
+ def system(command, new_uid=nil, new_gid=nil)
+ status = nil
+ asuser(new_uid, new_gid) do
+ Kernel.system(command)
+ status = $CHILD_STATUS.dup
end
- module_function :system
+ status
+ end
+ module_function :system
end
diff --git a/lib/puppet/util/tagging.rb b/lib/puppet/util/tagging.rb
index 1f185e4..6323ee0 100644
--- a/lib/puppet/util/tagging.rb
+++ b/lib/puppet/util/tagging.rb
@@ -3,54 +3,54 @@
# A common module to handle tagging.
module Puppet::Util::Tagging
- # Add a tag to our current list. These tags will be added to all
- # of the objects contained in this scope.
- def tag(*ary)
- @tags ||= []
+ # Add a tag to our current list. These tags will be added to all
+ # of the objects contained in this scope.
+ def tag(*ary)
+ @tags ||= []
- qualified = []
+ qualified = []
- ary.collect { |tag| tag.to_s.downcase }.each do |tag|
- fail(Puppet::ParseError, "Invalid tag #{tag.inspect}") unless valid_tag?(tag)
- qualified << tag if tag.include?("::")
- @tags << tag unless @tags.include?(tag)
- end
-
- handle_qualified_tags( qualified )
+ ary.collect { |tag| tag.to_s.downcase }.each do |tag|
+ fail(Puppet::ParseError, "Invalid tag #{tag.inspect}") unless valid_tag?(tag)
+ qualified << tag if tag.include?("::")
+ @tags << tag unless @tags.include?(tag)
end
- # Are we tagged with the provided tag?
- def tagged?(*tags)
- not ( self.tags & tags.flatten.collect { |t| t.to_s } ).empty?
- end
+ handle_qualified_tags( qualified )
+ end
- # Return a copy of the tag list, so someone can't ask for our tags
- # and then modify them.
- def tags
- @tags ||= []
- @tags.dup
- end
+ # Are we tagged with the provided tag?
+ def tagged?(*tags)
+ not ( self.tags & tags.flatten.collect { |t| t.to_s } ).empty?
+ end
- def tags=(tags)
- @tags = []
+ # Return a copy of the tag list, so someone can't ask for our tags
+ # and then modify them.
+ def tags
+ @tags ||= []
+ @tags.dup
+ end
- return if tags.nil? or tags == ""
+ def tags=(tags)
+ @tags = []
- tags = tags.strip.split(/\s*,\s*/) if tags.is_a?(String)
+ return if tags.nil? or tags == ""
- tags.each do |t|
- tag(t)
- end
+ tags = tags.strip.split(/\s*,\s*/) if tags.is_a?(String)
+
+ tags.each do |t|
+ tag(t)
end
+ end
- private
+ private
- def handle_qualified_tags( qualified )
- # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
- qualified.collect { |name| x = name.split("::") }.flatten.each { |tag| @tags << tag unless @tags.include?(tag) }
- end
+ def handle_qualified_tags( qualified )
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ qualified.collect { |name| x = name.split("::") }.flatten.each { |tag| @tags << tag unless @tags.include?(tag) }
+ end
- def valid_tag?(tag)
- tag =~ /^\w[-\w:.]*$/
- end
+ def valid_tag?(tag)
+ tag =~ /^\w[-\w:.]*$/
+ end
end
diff --git a/lib/puppet/util/user_attr.rb b/lib/puppet/util/user_attr.rb
index c26c491..9b19058 100644
--- a/lib/puppet/util/user_attr.rb
+++ b/lib/puppet/util/user_attr.rb
@@ -1,21 +1,21 @@
class UserAttr
- def self.get_attributes_by_name(name)
- attributes = nil
+ def self.get_attributes_by_name(name)
+ attributes = nil
- File.readlines('/etc/user_attr').each do |line|
- next if line =~ /^#/
+ File.readlines('/etc/user_attr').each do |line|
+ next if line =~ /^#/
- token = line.split(':')
+ token = line.split(':')
- if token[0] == name
- attributes = {:name => name}
- token[4].split(';').each do |attr|
- key_value = attr.split('=')
- attributes[key_value[0].intern] = key_value[1].strip
- end
- break
- end
+ if token[0] == name
+ attributes = {:name => name}
+ token[4].split(';').each do |attr|
+ key_value = attr.split('=')
+ attributes[key_value[0].intern] = key_value[1].strip
end
- attributes
+ break
+ end
end
+ attributes
+ end
end
diff --git a/lib/puppet/util/warnings.rb b/lib/puppet/util/warnings.rb
index 3550108..7e26fea 100644
--- a/lib/puppet/util/warnings.rb
+++ b/lib/puppet/util/warnings.rb
@@ -1,29 +1,29 @@
# Methods to help with handling warnings.
module Puppet::Util::Warnings
- module_function
+ module_function
- def notice_once(msg)
- Puppet::Util::Warnings.maybe_log(msg, self.class) { Puppet.notice msg }
- end
+ def notice_once(msg)
+ Puppet::Util::Warnings.maybe_log(msg, self.class) { Puppet.notice msg }
+ end
- def warnonce(msg)
- Puppet::Util::Warnings.maybe_log(msg, self.class) { Puppet.warning msg }
- end
+ def warnonce(msg)
+ Puppet::Util::Warnings.maybe_log(msg, self.class) { Puppet.warning msg }
+ end
- def clear_warnings
- @stampwarnings = {}
- nil
- end
+ def clear_warnings
+ @stampwarnings = {}
+ nil
+ end
- protected
+ protected
- def self.maybe_log(message, klass)
- @stampwarnings ||= {}
- @stampwarnings[klass] ||= []
- return nil if @stampwarnings[klass].include? message
- yield
- @stampwarnings[klass] << message
- nil
- end
+ def self.maybe_log(message, klass)
+ @stampwarnings ||= {}
+ @stampwarnings[klass] ||= []
+ return nil if @stampwarnings[klass].include? message
+ yield
+ @stampwarnings[klass] << message
+ nil
+ end
end
diff --git a/lib/puppet/util/zaml.rb b/lib/puppet/util/zaml.rb
index aff8370..8ecc2c8 100644
--- a/lib/puppet/util/zaml.rb
+++ b/lib/puppet/util/zaml.rb
@@ -13,101 +13,101 @@
require 'yaml'
class ZAML
- VERSION = "0.1.1"
+ VERSION = "0.1.1"
+ #
+ # Class Methods
+ #
+ def self.dump(stuff, where='')
+ z = new
+ stuff.to_zaml(z)
+ where << z.to_s
+ end
+ #
+ # Instance Methods
+ #
+ def initialize
+ @result = []
+ @indent = nil
+ @structured_key_prefix = nil
+ Label.counter_reset
+ emit('--- ')
+ end
+ def nested(tail=' ')
+ old_indent = @indent
+ @indent = "#{@indent || "\n"}#{tail}"
+ yield
+ @indent = old_indent
+ end
+ class Label
#
- # Class Methods
+ # YAML only wants objects in the datastream once; if the same object
+ # occurs more than once, we need to emit a label ("&idxxx") on the
+ # first occurrence and then emit a back reference (*idxxx") on any
+ # subsequent occurrence(s).
#
- def self.dump(stuff, where='')
- z = new
- stuff.to_zaml(z)
- where << z.to_s
- end
- #
- # Instance Methods
+ # To accomplish this we keeps a hash (by object id) of the labels of
+ # the things we serialize as we begin to serialize them. The labels
+ # initially serialize as an empty string (since most objects are only
+ # going to be be encountered once), but can be changed to a valid
+ # (by assigning it a number) the first time it is subsequently used,
+ # if it ever is. Note that we need to do the label setup BEFORE we
+ # start to serialize the object so that circular structures (in
+ # which we will encounter a reference to the object as we serialize
+ # it can be handled).
#
- def initialize
- @result = []
- @indent = nil
- @structured_key_prefix = nil
- Label.counter_reset
- emit('--- ')
- end
- def nested(tail=' ')
- old_indent = @indent
- @indent = "#{@indent || "\n"}#{tail}"
- yield
- @indent = old_indent
- end
- class Label
- #
- # YAML only wants objects in the datastream once; if the same object
- # occurs more than once, we need to emit a label ("&idxxx") on the
- # first occurrence and then emit a back reference (*idxxx") on any
- # subsequent occurrence(s).
- #
- # To accomplish this we keeps a hash (by object id) of the labels of
- # the things we serialize as we begin to serialize them. The labels
- # initially serialize as an empty string (since most objects are only
- # going to be be encountered once), but can be changed to a valid
- # (by assigning it a number) the first time it is subsequently used,
- # if it ever is. Note that we need to do the label setup BEFORE we
- # start to serialize the object so that circular structures (in
- # which we will encounter a reference to the object as we serialize
- # it can be handled).
- #
- def self.counter_reset
- @@previously_emitted_object = {}
- @@next_free_label_number = 0
- end
- def initialize(obj,indent)
- @indent = indent
- @this_label_number = nil
- @@previously_emitted_object[obj.object_id] = self
- end
- def to_s
- @this_label_number ? ('&id%03d%s' % [@this_label_number, @indent]) : ''
- end
- def reference
- @this_label_number ||= (@@next_free_label_number += 1)
- @reference ||= '*id%03d' % @this_label_number
- end
- def self.for(obj)
- @@previously_emitted_object[obj.object_id]
- end
- end
- def new_label_for(obj)
- Label.new(obj,(Hash === obj || Array === obj) ? "#{@indent || "\n"} " : ' ')
+ def self.counter_reset
+ @@previously_emitted_object = {}
+ @@next_free_label_number = 0
end
- def first_time_only(obj)
- if label = Label.for(obj)
- emit(label.reference)
- else
- if @structured_key_prefix and not obj.is_a? String
- emit(@structured_key_prefix)
- @structured_key_prefix = nil
- end
- emit(new_label_for(obj))
- yield
- end
+ def initialize(obj,indent)
+ @indent = indent
+ @this_label_number = nil
+ @@previously_emitted_object[obj.object_id] = self
end
- def emit(s)
- @result << s
- @recent_nl = false unless s.kind_of?(Label)
+ def to_s
+ @this_label_number ? ('&id%03d%s' % [@this_label_number, @indent]) : ''
end
- def nl(s='')
- emit(@indent || "\n") unless @recent_nl
- emit(s)
- @recent_nl = true
+ def reference
+ @this_label_number ||= (@@next_free_label_number += 1)
+ @reference ||= '*id%03d' % @this_label_number
end
- def to_s
- @result.join
+ def self.for(obj)
+ @@previously_emitted_object[obj.object_id]
end
- def prefix_structured_keys(x)
- @structured_key_prefix = x
- yield
- nl unless @structured_key_prefix
+ end
+ def new_label_for(obj)
+ Label.new(obj,(Hash === obj || Array === obj) ? "#{@indent || "\n"} " : ' ')
+ end
+ def first_time_only(obj)
+ if label = Label.for(obj)
+ emit(label.reference)
+ else
+ if @structured_key_prefix and not obj.is_a? String
+ emit(@structured_key_prefix)
@structured_key_prefix = nil
+ end
+ emit(new_label_for(obj))
+ yield
end
+ end
+ def emit(s)
+ @result << s
+ @recent_nl = false unless s.kind_of?(Label)
+ end
+ def nl(s='')
+ emit(@indent || "\n") unless @recent_nl
+ emit(s)
+ @recent_nl = true
+ end
+ def to_s
+ @result.join
+ end
+ def prefix_structured_keys(x)
+ @structured_key_prefix = x
+ yield
+ nl unless @structured_key_prefix
+ @structured_key_prefix = nil
+ end
end
################################################################
@@ -117,31 +117,31 @@ end
################################################################
class Object
- def to_yaml_properties
- instance_variables.sort # Default YAML behavior
- end
- def zamlized_class_name(root)
- cls = self.class
- "!ruby/#{root.name.downcase}#{cls == root ? '' : ":#{cls.respond_to?(:name) ? cls.name : cls}"}"
- end
- def to_zaml(z)
- z.first_time_only(self) {
- z.emit(zamlized_class_name(Object))
- z.nested {
- instance_variables = to_yaml_properties
- if instance_variables.empty?
- z.emit(" {}")
- else
- instance_variables.each { |v|
- z.nl
- v[1..-1].to_zaml(z) # Remove leading '@'
- z.emit(': ')
- instance_variable_get(v).to_zaml(z)
- }
- end
- }
- }
- end
+ def to_yaml_properties
+ instance_variables.sort # Default YAML behavior
+ end
+ def zamlized_class_name(root)
+ cls = self.class
+ "!ruby/#{root.name.downcase}#{cls == root ? '' : ":#{cls.respond_to?(:name) ? cls.name : cls}"}"
+ end
+ def to_zaml(z)
+ z.first_time_only(self) {
+ z.emit(zamlized_class_name(Object))
+ z.nested {
+ instance_variables = to_yaml_properties
+ if instance_variables.empty?
+ z.emit(" {}")
+ else
+ instance_variables.each { |v|
+ z.nl
+ v[1..-1].to_zaml(z) # Remove leading '@'
+ z.emit(': ')
+ instance_variable_get(v).to_zaml(z)
+ }
+ end
+ }
+ }
+ end
end
################################################################
@@ -151,169 +151,169 @@ end
################################################################
class NilClass
- def to_zaml(z)
- z.emit('') # NOTE: blank turns into nil in YAML.load
- end
+ def to_zaml(z)
+ z.emit('') # NOTE: blank turns into nil in YAML.load
+ end
end
class Symbol
- def to_zaml(z)
- z.emit(self.inspect)
- end
+ def to_zaml(z)
+ z.emit(self.inspect)
+ end
end
class TrueClass
- def to_zaml(z)
- z.emit('true')
- end
+ def to_zaml(z)
+ z.emit('true')
+ end
end
class FalseClass
- def to_zaml(z)
- z.emit('false')
- end
+ def to_zaml(z)
+ z.emit('false')
+ end
end
class Numeric
- def to_zaml(z)
- z.emit(self)
- end
+ def to_zaml(z)
+ z.emit(self)
+ end
end
class Regexp
- def to_zaml(z)
- z.first_time_only(self) { z.emit("#{zamlized_class_name(Regexp)} #{inspect}") }
- end
+ def to_zaml(z)
+ z.first_time_only(self) { z.emit("#{zamlized_class_name(Regexp)} #{inspect}") }
+ end
end
class Exception
- def to_zaml(z)
- z.emit(zamlized_class_name(Exception))
- z.nested {
- z.nl("message: ")
- message.to_zaml(z)
- }
- end
- #
- # Monkey patch for buggy Exception restore in YAML
- #
- # This makes it work for now but is not very future-proof; if things
- # change we'll most likely want to remove this. To mitigate the risks
- # as much as possible, we test for the bug before appling the patch.
- #
- if respond_to? :yaml_new and yaml_new(self, :tag, "message" => "blurp").message != "blurp"
- def self.yaml_new( klass, tag, val )
- o = YAML.object_maker( klass, {} ).exception(val.delete( 'message'))
- val.each_pair do |k,v|
- o.instance_variable_set("@#{k}", v)
- end
- o
- end
+ def to_zaml(z)
+ z.emit(zamlized_class_name(Exception))
+ z.nested {
+ z.nl("message: ")
+ message.to_zaml(z)
+ }
+ end
+ #
+ # Monkey patch for buggy Exception restore in YAML
+ #
+ # This makes it work for now but is not very future-proof; if things
+ # change we'll most likely want to remove this. To mitigate the risks
+ # as much as possible, we test for the bug before appling the patch.
+ #
+ if respond_to? :yaml_new and yaml_new(self, :tag, "message" => "blurp").message != "blurp"
+ def self.yaml_new( klass, tag, val )
+ o = YAML.object_maker( klass, {} ).exception(val.delete( 'message'))
+ val.each_pair do |k,v|
+ o.instance_variable_set("@#{k}", v)
+ end
+ o
end
+ end
end
class String
- ZAML_ESCAPES = %w{\x00 \x01 \x02 \x03 \x04 \x05 \x06 \a \x08 \t \n \v \f \r \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \e \x1c \x1d \x1e \x1f }
- def escaped_for_zaml
- gsub( /\x5C/, "\\\\\\" ). # Demi-kludge for Maglev/rubinius; the regexp should be /\\/ but parsetree chokes on that.
- gsub( /"/, "\\\"" ).
- gsub( /([\x00-\x1F])/ ) { |x| ZAML_ESCAPES[ x.unpack("C")[0] ] }.
- gsub( /([\x80-\xFF])/ ) { |x| "\\x#{x.unpack("C")[0].to_s(16)}" }
- end
- def to_zaml(z)
- z.first_time_only(self) {
- num = '[-+]?(0x)?\d+\.?\d*'
- case
- when self == ''
- z.emit('""')
- # when self =~ /[\x00-\x08\x0B\x0C\x0E-\x1F\x80-\xFF]/
- # z.emit("!binary |\n")
- # z.emit([self].pack("m*"))
- when (
- (self =~ /\A(true|false|yes|no|on|null|off|#{num}(:#{num})*|!|=|~)$/i) or
- (self =~ /\A\n* /) or
- (self =~ /[\s:]$/) or
- (self =~ /^[>|][-+\d]*\s/i) or
- (self[-1..-1] =~ /\s/) or
- (self =~ /[\x00-\x08\x0B\x0C\x0E-\x1F\x80-\xFF]/) or
- (self =~ /[,\[\]\{\}\r\t]|:\s|\s#/) or
- (self =~ /\A([-:?!#&*'"]|<<|%.+:.)/)
- )
- z.emit("\"#{escaped_for_zaml}\"")
- when self =~ /\n/
- if self[-1..-1] == "\n" then z.emit('|+') else z.emit('|-') end
- z.nested { split("\n",-1).each { |line| z.nl; z.emit(line.chomp("\n")) } }
- z.nl
- else
- z.emit(self)
- end
- }
- end
+ ZAML_ESCAPES = %w{\x00 \x01 \x02 \x03 \x04 \x05 \x06 \a \x08 \t \n \v \f \r \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \e \x1c \x1d \x1e \x1f }
+ def escaped_for_zaml
+ gsub( /\x5C/, "\\\\\\" ). # Demi-kludge for Maglev/rubinius; the regexp should be /\\/ but parsetree chokes on that.
+ gsub( /"/, "\\\"" ).
+ gsub( /([\x00-\x1F])/ ) { |x| ZAML_ESCAPES[ x.unpack("C")[0] ] }.
+ gsub( /([\x80-\xFF])/ ) { |x| "\\x#{x.unpack("C")[0].to_s(16)}" }
+ end
+ def to_zaml(z)
+ z.first_time_only(self) {
+ num = '[-+]?(0x)?\d+\.?\d*'
+ case
+ when self == ''
+ z.emit('""')
+ # when self =~ /[\x00-\x08\x0B\x0C\x0E-\x1F\x80-\xFF]/
+ # z.emit("!binary |\n")
+ # z.emit([self].pack("m*"))
+ when (
+ (self =~ /\A(true|false|yes|no|on|null|off|#{num}(:#{num})*|!|=|~)$/i) or
+ (self =~ /\A\n* /) or
+ (self =~ /[\s:]$/) or
+ (self =~ /^[>|][-+\d]*\s/i) or
+ (self[-1..-1] =~ /\s/) or
+ (self =~ /[\x00-\x08\x0B\x0C\x0E-\x1F\x80-\xFF]/) or
+ (self =~ /[,\[\]\{\}\r\t]|:\s|\s#/) or
+ (self =~ /\A([-:?!#&*'"]|<<|%.+:.)/)
+ )
+ z.emit("\"#{escaped_for_zaml}\"")
+ when self =~ /\n/
+ if self[-1..-1] == "\n" then z.emit('|+') else z.emit('|-') end
+ z.nested { split("\n",-1).each { |line| z.nl; z.emit(line.chomp("\n")) } }
+ z.nl
+ else
+ z.emit(self)
+ end
+ }
+ end
end
class Hash
- def to_zaml(z)
- z.first_time_only(self) {
- z.nested {
- if empty?
- z.emit('{}')
- else
- each_pair { |k, v|
- z.nl
- z.prefix_structured_keys('? ') { k.to_zaml(z) }
- z.emit(': ')
- v.to_zaml(z)
- }
- end
- }
- }
- end
+ def to_zaml(z)
+ z.first_time_only(self) {
+ z.nested {
+ if empty?
+ z.emit('{}')
+ else
+ each_pair { |k, v|
+ z.nl
+ z.prefix_structured_keys('? ') { k.to_zaml(z) }
+ z.emit(': ')
+ v.to_zaml(z)
+ }
+ end
+ }
+ }
+ end
end
class Array
- def to_zaml(z)
- z.first_time_only(self) {
- z.nested {
- if empty?
- z.emit('[]')
- else
- each { |v| z.nl('- '); v.to_zaml(z) }
- end
- }
- }
- end
+ def to_zaml(z)
+ z.first_time_only(self) {
+ z.nested {
+ if empty?
+ z.emit('[]')
+ else
+ each { |v| z.nl('- '); v.to_zaml(z) }
+ end
+ }
+ }
+ end
end
class Time
- def to_zaml(z)
- # 2008-12-06 10:06:51.373758 -07:00
- ms = ("%0.6f" % (usec * 1e-6)).sub(/^\d+\./,'')
- offset = "%+0.2i:%0.2i" % [utc_offset / 3600, (utc_offset / 60) % 60]
- z.emit(self.strftime("%Y-%m-%d %H:%M:%S.#{ms} #{offset}"))
- end
+ def to_zaml(z)
+ # 2008-12-06 10:06:51.373758 -07:00
+ ms = ("%0.6f" % (usec * 1e-6)).sub(/^\d+\./,'')
+ offset = "%+0.2i:%0.2i" % [utc_offset / 3600, (utc_offset / 60) % 60]
+ z.emit(self.strftime("%Y-%m-%d %H:%M:%S.#{ms} #{offset}"))
+ end
end
class Date
- def to_zaml(z)
- z.emit(strftime('%Y-%m-%d'))
- end
+ def to_zaml(z)
+ z.emit(strftime('%Y-%m-%d'))
+ end
end
class Range
- def to_zaml(z)
- z.first_time_only(self) {
- z.emit(zamlized_class_name(Range))
- z.nested {
- z.nl
- z.emit('begin: ')
- z.emit(first)
- z.nl
- z.emit('end: ')
- z.emit(last)
- z.nl
- z.emit('excl: ')
- z.emit(exclude_end?)
- }
- }
- end
+ def to_zaml(z)
+ z.first_time_only(self) {
+ z.emit(zamlized_class_name(Range))
+ z.nested {
+ z.nl
+ z.emit('begin: ')
+ z.emit(first)
+ z.nl
+ z.emit('end: ')
+ z.emit(last)
+ z.nl
+ z.emit('excl: ')
+ z.emit(exclude_end?)
+ }
+ }
+ end
end
diff --git a/spec/integration/application/apply_spec.rb b/spec/integration/application/apply_spec.rb
index c6e73e8..840917e 100755
--- a/spec/integration/application/apply_spec.rb
+++ b/spec/integration/application/apply_spec.rb
@@ -7,27 +7,27 @@ require 'puppet_spec/files'
require 'puppet/application/apply'
describe "apply" do
- include PuppetSpec::Files
+ include PuppetSpec::Files
- describe "when applying provided catalogs" do
- confine "PSON library is missing; cannot test applying catalogs" => Puppet.features.pson?
- it "should be able to apply catalogs provided in a file in pson" do
- file_to_create = tmpfile("pson_catalog")
- catalog = Puppet::Resource::Catalog.new
- resource = Puppet::Resource.new(:file, file_to_create, :parameters => {:content => "my stuff"})
- catalog.add_resource resource
+ describe "when applying provided catalogs" do
+ confine "PSON library is missing; cannot test applying catalogs" => Puppet.features.pson?
+ it "should be able to apply catalogs provided in a file in pson" do
+ file_to_create = tmpfile("pson_catalog")
+ catalog = Puppet::Resource::Catalog.new
+ resource = Puppet::Resource.new(:file, file_to_create, :parameters => {:content => "my stuff"})
+ catalog.add_resource resource
- manifest = tmpfile("manifest")
+ manifest = tmpfile("manifest")
- File.open(manifest, "w") { |f| f.print catalog.to_pson }
+ File.open(manifest, "w") { |f| f.print catalog.to_pson }
- puppet = Puppet::Application[:apply]
- puppet.options[:catalog] = manifest
+ puppet = Puppet::Application[:apply]
+ puppet.options[:catalog] = manifest
- puppet.apply
+ puppet.apply
- File.should be_exist(file_to_create)
- File.read(file_to_create).should == "my stuff"
- end
+ File.should be_exist(file_to_create)
+ File.read(file_to_create).should == "my stuff"
end
+ end
end
diff --git a/spec/integration/configurer_spec.rb b/spec/integration/configurer_spec.rb
index fce24a1..9a8b66f 100755
--- a/spec/integration/configurer_spec.rb
+++ b/spec/integration/configurer_spec.rb
@@ -5,31 +5,31 @@ require File.dirname(__FILE__) + '/../spec_helper'
require 'puppet/configurer'
describe Puppet::Configurer do
- describe "when downloading plugins" do
- it "should use the :pluginsignore setting, split on whitespace, for ignoring remote files" do
- resource = Puppet::Type.type(:notify).new :name => "yay"
- Puppet::Type.type(:file).expects(:new).with { |args| args[:ignore] == Puppet[:pluginsignore].split(/\s+/) }.returns resource
-
- configurer = Puppet::Configurer.new
- configurer.stubs(:download_plugins?).returns true
- configurer.download_plugins
- end
+ describe "when downloading plugins" do
+ it "should use the :pluginsignore setting, split on whitespace, for ignoring remote files" do
+ resource = Puppet::Type.type(:notify).new :name => "yay"
+ Puppet::Type.type(:file).expects(:new).with { |args| args[:ignore] == Puppet[:pluginsignore].split(/\s+/) }.returns resource
+
+ configurer = Puppet::Configurer.new
+ configurer.stubs(:download_plugins?).returns true
+ configurer.download_plugins
end
+ end
- describe "when running" do
- it "should send a transaction report with valid data" do
- catalog = Puppet::Resource::Catalog.new
- catalog.add_resource(Puppet::Type.type(:notify).new(:title => "testing"))
+ describe "when running" do
+ it "should send a transaction report with valid data" do
+ catalog = Puppet::Resource::Catalog.new
+ catalog.add_resource(Puppet::Type.type(:notify).new(:title => "testing"))
- configurer = Puppet::Configurer.new
+ configurer = Puppet::Configurer.new
- Puppet::Transaction::Report.indirection.expects(:save).with do |x, report|
- report.time.class == Time and report.logs.length > 0
- end
+ Puppet::Transaction::Report.indirection.expects(:save).with do |x, report|
+ report.time.class == Time and report.logs.length > 0
+ end
- Puppet[:report] = true
+ Puppet[:report] = true
- configurer.run :catalog => catalog
- end
+ configurer.run :catalog => catalog
end
+ end
end
diff --git a/spec/integration/defaults_spec.rb b/spec/integration/defaults_spec.rb
index 3fa7538..4ae2983 100755
--- a/spec/integration/defaults_spec.rb
+++ b/spec/integration/defaults_spec.rb
@@ -5,254 +5,254 @@ require File.dirname(__FILE__) + '/../spec_helper'
require 'puppet/defaults'
describe "Puppet defaults" do
- include Puppet::Util::Execution
- after { Puppet.settings.clear }
+ include Puppet::Util::Execution
+ after { Puppet.settings.clear }
- describe "when setting the :factpath" do
- it "should add the :factpath to Facter's search paths" do
- Facter.expects(:search).with("/my/fact/path")
+ describe "when setting the :factpath" do
+ it "should add the :factpath to Facter's search paths" do
+ Facter.expects(:search).with("/my/fact/path")
- Puppet.settings[:factpath] = "/my/fact/path"
- end
+ Puppet.settings[:factpath] = "/my/fact/path"
end
+ end
- describe "when setting the :certname" do
- it "should fail if the certname is not downcased" do
- lambda { Puppet.settings[:certname] = "Host.Domain.Com" }.should raise_error(ArgumentError)
- end
+ describe "when setting the :certname" do
+ it "should fail if the certname is not downcased" do
+ lambda { Puppet.settings[:certname] = "Host.Domain.Com" }.should raise_error(ArgumentError)
end
+ end
- describe "when configuring the :crl" do
- it "should warn if :cacrl is set to false" do
- Puppet.expects(:warning)
- Puppet.settings[:cacrl] = 'false'
- end
+ describe "when configuring the :crl" do
+ it "should warn if :cacrl is set to false" do
+ Puppet.expects(:warning)
+ Puppet.settings[:cacrl] = 'false'
end
+ end
- describe "when setting the :catalog_format" do
- it "should log a deprecation notice" do
- Puppet.expects(:warning)
- Puppet.settings[:catalog_format] = 'marshal'
- end
- it "should copy the value to :preferred_serialization_format" do
- Puppet.settings[:catalog_format] = 'marshal'
- Puppet.settings[:preferred_serialization_format].should == 'marshal'
- end
+ describe "when setting the :catalog_format" do
+ it "should log a deprecation notice" do
+ Puppet.expects(:warning)
+ Puppet.settings[:catalog_format] = 'marshal'
end
-
- it "should have a clientyamldir setting" do
- Puppet.settings[:clientyamldir].should_not be_nil
+ it "should copy the value to :preferred_serialization_format" do
+ Puppet.settings[:catalog_format] = 'marshal'
+ Puppet.settings[:preferred_serialization_format].should == 'marshal'
end
-
- it "should have different values for the yamldir and clientyamldir" do
- Puppet.settings[:yamldir].should_not == Puppet.settings[:clientyamldir]
+ end
+
+ it "should have a clientyamldir setting" do
+ Puppet.settings[:clientyamldir].should_not be_nil
+ end
+
+ it "should have different values for the yamldir and clientyamldir" do
+ Puppet.settings[:yamldir].should_not == Puppet.settings[:clientyamldir]
+ end
+
+ it "should have a client_datadir setting" do
+ Puppet.settings[:client_datadir].should_not be_nil
+ end
+
+ it "should have different values for the server_datadir and client_datadir" do
+ Puppet.settings[:server_datadir].should_not == Puppet.settings[:client_datadir]
+ end
+
+ # See #1232
+ it "should not specify a user or group for the clientyamldir" do
+ Puppet.settings.setting(:clientyamldir).owner.should be_nil
+ Puppet.settings.setting(:clientyamldir).group.should be_nil
+ end
+
+ it "should use the service user and group for the yamldir" do
+ Puppet.settings.stubs(:service_user_available?).returns true
+ Puppet.settings.setting(:yamldir).owner.should == Puppet.settings[:user]
+ Puppet.settings.setting(:yamldir).group.should == Puppet.settings[:group]
+ end
+
+ # See #1232
+ it "should not specify a user or group for the rundir" do
+ Puppet.settings.setting(:rundir).owner.should be_nil
+ Puppet.settings.setting(:rundir).group.should be_nil
+ end
+
+ it "should specify that the host private key should be owned by the service user" do
+ Puppet.settings.stubs(:service_user_available?).returns true
+ Puppet.settings.setting(:hostprivkey).owner.should == Puppet.settings[:user]
+ end
+
+ it "should specify that the host certificate should be owned by the service user" do
+ Puppet.settings.stubs(:service_user_available?).returns true
+ Puppet.settings.setting(:hostcert).owner.should == Puppet.settings[:user]
+ end
+
+ it "should use a bind address of ''" do
+ Puppet.settings.clear
+ Puppet.settings[:bindaddress].should == ""
+ end
+
+ [:factdest].each do |setting|
+ it "should force the :factdest to be a directory" do
+ Puppet.settings[setting].should =~ /\/$/
end
+ end
- it "should have a client_datadir setting" do
- Puppet.settings[:client_datadir].should_not be_nil
+ [:modulepath, :factpath].each do |setting|
+ it "should configure '#{setting}' not to be a file setting, so multi-directory settings are acceptable" do
+ Puppet.settings.setting(setting).should be_instance_of(Puppet::Util::Settings::Setting)
end
+ end
- it "should have different values for the server_datadir and client_datadir" do
- Puppet.settings[:server_datadir].should_not == Puppet.settings[:client_datadir]
+ it "should add /usr/sbin and /sbin to the path if they're not there" do
+ withenv("PATH" => "/usr/bin:/usr/local/bin") do
+ Puppet.settings[:path] = "none" # this causes it to ignore the setting
+ ENV["PATH"].split(File::PATH_SEPARATOR).should be_include("/usr/sbin")
+ ENV["PATH"].split(File::PATH_SEPARATOR).should be_include("/sbin")
end
+ end
- # See #1232
- it "should not specify a user or group for the clientyamldir" do
- Puppet.settings.setting(:clientyamldir).owner.should be_nil
- Puppet.settings.setting(:clientyamldir).group.should be_nil
- end
+ it "should default to pson for the preferred serialization format" do
+ Puppet.settings.value(:preferred_serialization_format).should == "pson"
+ end
- it "should use the service user and group for the yamldir" do
- Puppet.settings.stubs(:service_user_available?).returns true
- Puppet.settings.setting(:yamldir).owner.should == Puppet.settings[:user]
- Puppet.settings.setting(:yamldir).group.should == Puppet.settings[:group]
- end
+ describe "when enabling storeconfigs" do
+ before do
+ Puppet::Resource::Catalog.stubs(:cache_class=)
+ Puppet::Node::Facts.stubs(:cache_class=)
+ Puppet::Node.stubs(:cache_class=)
- # See #1232
- it "should not specify a user or group for the rundir" do
- Puppet.settings.setting(:rundir).owner.should be_nil
- Puppet.settings.setting(:rundir).group.should be_nil
+ Puppet.features.stubs(:rails?).returns true
end
- it "should specify that the host private key should be owned by the service user" do
- Puppet.settings.stubs(:service_user_available?).returns true
- Puppet.settings.setting(:hostprivkey).owner.should == Puppet.settings[:user]
+ it "should set the Catalog cache class to :active_record" do
+ Puppet::Resource::Catalog.expects(:cache_class=).with(:active_record)
+ Puppet.settings[:storeconfigs] = true
end
- it "should specify that the host certificate should be owned by the service user" do
- Puppet.settings.stubs(:service_user_available?).returns true
- Puppet.settings.setting(:hostcert).owner.should == Puppet.settings[:user]
+ it "should not set the Catalog cache class to :active_record if asynchronous storeconfigs is enabled" do
+ Puppet::Resource::Catalog.expects(:cache_class=).with(:active_record).never
+ Puppet.settings.expects(:value).with(:async_storeconfigs).returns true
+ Puppet.settings[:storeconfigs] = true
end
- it "should use a bind address of ''" do
- Puppet.settings.clear
- Puppet.settings[:bindaddress].should == ""
+ it "should set the Facts cache class to :active_record" do
+ Puppet::Node::Facts.expects(:cache_class=).with(:active_record)
+ Puppet.settings[:storeconfigs] = true
end
- [:factdest].each do |setting|
- it "should force the :factdest to be a directory" do
- Puppet.settings[setting].should =~ /\/$/
- end
+ it "should set the Node cache class to :active_record" do
+ Puppet::Node.expects(:cache_class=).with(:active_record)
+ Puppet.settings[:storeconfigs] = true
end
- [:modulepath, :factpath].each do |setting|
- it "should configure '#{setting}' not to be a file setting, so multi-directory settings are acceptable" do
- Puppet.settings.setting(setting).should be_instance_of(Puppet::Util::Settings::Setting)
- end
+ it "should fail if rails is not available" do
+ Puppet.features.stubs(:rails?).returns false
+ lambda { Puppet.settings[:storeconfigs] = true }.should raise_error
end
-
- it "should add /usr/sbin and /sbin to the path if they're not there" do
- withenv("PATH" => "/usr/bin:/usr/local/bin") do
- Puppet.settings[:path] = "none" # this causes it to ignore the setting
- ENV["PATH"].split(File::PATH_SEPARATOR).should be_include("/usr/sbin")
- ENV["PATH"].split(File::PATH_SEPARATOR).should be_include("/sbin")
- end
+ end
+
+ describe "when enabling asynchronous storeconfigs" do
+ before do
+ Puppet::Resource::Catalog.stubs(:cache_class=)
+ Puppet::Node::Facts.stubs(:cache_class=)
+ Puppet::Node.stubs(:cache_class=)
+ Puppet.features.stubs(:rails?).returns true
end
- it "should default to pson for the preferred serialization format" do
- Puppet.settings.value(:preferred_serialization_format).should == "pson"
+ it "should set storeconfigs to true" do
+ Puppet.settings[:async_storeconfigs] = true
+ Puppet.settings[:storeconfigs].should be_true
end
- describe "when enabling storeconfigs" do
- before do
- Puppet::Resource::Catalog.stubs(:cache_class=)
- Puppet::Node::Facts.stubs(:cache_class=)
- Puppet::Node.stubs(:cache_class=)
-
- Puppet.features.stubs(:rails?).returns true
- end
-
- it "should set the Catalog cache class to :active_record" do
- Puppet::Resource::Catalog.expects(:cache_class=).with(:active_record)
- Puppet.settings[:storeconfigs] = true
- end
-
- it "should not set the Catalog cache class to :active_record if asynchronous storeconfigs is enabled" do
- Puppet::Resource::Catalog.expects(:cache_class=).with(:active_record).never
- Puppet.settings.expects(:value).with(:async_storeconfigs).returns true
- Puppet.settings[:storeconfigs] = true
- end
-
- it "should set the Facts cache class to :active_record" do
- Puppet::Node::Facts.expects(:cache_class=).with(:active_record)
- Puppet.settings[:storeconfigs] = true
- end
-
- it "should set the Node cache class to :active_record" do
- Puppet::Node.expects(:cache_class=).with(:active_record)
- Puppet.settings[:storeconfigs] = true
- end
-
- it "should fail if rails is not available" do
- Puppet.features.stubs(:rails?).returns false
- lambda { Puppet.settings[:storeconfigs] = true }.should raise_error
- end
+ it "should set the Catalog cache class to :queue" do
+ Puppet::Resource::Catalog.expects(:cache_class=).with(:queue)
+ Puppet.settings[:async_storeconfigs] = true
end
- describe "when enabling asynchronous storeconfigs" do
- before do
- Puppet::Resource::Catalog.stubs(:cache_class=)
- Puppet::Node::Facts.stubs(:cache_class=)
- Puppet::Node.stubs(:cache_class=)
- Puppet.features.stubs(:rails?).returns true
- end
-
- it "should set storeconfigs to true" do
- Puppet.settings[:async_storeconfigs] = true
- Puppet.settings[:storeconfigs].should be_true
- end
-
- it "should set the Catalog cache class to :queue" do
- Puppet::Resource::Catalog.expects(:cache_class=).with(:queue)
- Puppet.settings[:async_storeconfigs] = true
- end
-
- it "should set the Facts cache class to :active_record" do
- Puppet::Node::Facts.expects(:cache_class=).with(:active_record)
- Puppet.settings[:storeconfigs] = true
- end
-
- it "should set the Node cache class to :active_record" do
- Puppet::Node.expects(:cache_class=).with(:active_record)
- Puppet.settings[:storeconfigs] = true
- end
+ it "should set the Facts cache class to :active_record" do
+ Puppet::Node::Facts.expects(:cache_class=).with(:active_record)
+ Puppet.settings[:storeconfigs] = true
end
- describe "when enabling thin storeconfigs" do
- before do
- Puppet::Resource::Catalog.stubs(:cache_class=)
- Puppet::Node::Facts.stubs(:cache_class=)
- Puppet::Node.stubs(:cache_class=)
- Puppet.features.stubs(:rails?).returns true
- end
-
- it "should set storeconfigs to true" do
- Puppet.settings[:thin_storeconfigs] = true
- Puppet.settings[:storeconfigs].should be_true
- end
+ it "should set the Node cache class to :active_record" do
+ Puppet::Node.expects(:cache_class=).with(:active_record)
+ Puppet.settings[:storeconfigs] = true
end
-
- it "should have a setting for determining the configuration version and should default to an empty string" do
- Puppet.settings[:config_version].should == ""
- end
-
- describe "when enabling reports" do
- it "should use the default server value when report server is unspecified" do
- Puppet.settings[:server] = "server"
- Puppet.settings[:report_server].should == "server"
- end
-
- it "should use the default masterport value when report port is unspecified" do
- Puppet.settings[:masterport] = "1234"
- Puppet.settings[:report_port].should == "1234"
- end
-
- it "should set report_server when reportserver is set" do
- Puppet.settings[:reportserver] = "reportserver"
- Puppet.settings[:report_server].should == "reportserver"
- end
-
- it "should use report_port when set" do
- Puppet.settings[:masterport] = "1234"
- Puppet.settings[:report_port] = "5678"
- Puppet.settings[:report_port].should == "5678"
- end
-
- it "should prefer report_server over reportserver" do
- Puppet.settings[:reportserver] = "reportserver"
- Puppet.settings[:report_server] = "report_server"
- Puppet.settings[:report_server].should == "report_server"
- end
+ end
+
+ describe "when enabling thin storeconfigs" do
+ before do
+ Puppet::Resource::Catalog.stubs(:cache_class=)
+ Puppet::Node::Facts.stubs(:cache_class=)
+ Puppet::Node.stubs(:cache_class=)
+ Puppet.features.stubs(:rails?).returns true
end
- it "should have a :caname setting that defaults to the cert name" do
- Puppet.settings[:certname] = "foo"
- Puppet.settings[:ca_name].should == "foo"
+ it "should set storeconfigs to true" do
+ Puppet.settings[:thin_storeconfigs] = true
+ Puppet.settings[:storeconfigs].should be_true
end
+ end
- it "should have a 'prerun_command' that defaults to the empty string" do
- Puppet.settings[:prerun_command].should == ""
- end
+ it "should have a setting for determining the configuration version and should default to an empty string" do
+ Puppet.settings[:config_version].should == ""
+ end
- it "should have a 'postrun_command' that defaults to the empty string" do
- Puppet.settings[:postrun_command].should == ""
+ describe "when enabling reports" do
+ it "should use the default server value when report server is unspecified" do
+ Puppet.settings[:server] = "server"
+ Puppet.settings[:report_server].should == "server"
end
- it "should have a 'certificate_revocation' setting that defaults to true" do
- Puppet.settings[:certificate_revocation].should be_true
+ it "should use the default masterport value when report port is unspecified" do
+ Puppet.settings[:masterport] = "1234"
+ Puppet.settings[:report_port].should == "1234"
end
- it "should have an http_compression setting that defaults to false" do
- Puppet.settings[:http_compression].should be_false
+ it "should set report_server when reportserver is set" do
+ Puppet.settings[:reportserver] = "reportserver"
+ Puppet.settings[:report_server].should == "reportserver"
end
- describe "reportdir" do
- subject { Puppet.settings[:reportdir] }
- it { should == "#{Puppet[:vardir]}/reports" }
+ it "should use report_port when set" do
+ Puppet.settings[:masterport] = "1234"
+ Puppet.settings[:report_port] = "5678"
+ Puppet.settings[:report_port].should == "5678"
end
- describe "reporturl" do
- subject { Puppet.settings[:reporturl] }
- it { should == "http://localhost:3000/reports" }
+ it "should prefer report_server over reportserver" do
+ Puppet.settings[:reportserver] = "reportserver"
+ Puppet.settings[:report_server] = "report_server"
+ Puppet.settings[:report_server].should == "report_server"
end
+ end
+
+ it "should have a :caname setting that defaults to the cert name" do
+ Puppet.settings[:certname] = "foo"
+ Puppet.settings[:ca_name].should == "foo"
+ end
+
+ it "should have a 'prerun_command' that defaults to the empty string" do
+ Puppet.settings[:prerun_command].should == ""
+ end
+
+ it "should have a 'postrun_command' that defaults to the empty string" do
+ Puppet.settings[:postrun_command].should == ""
+ end
+
+ it "should have a 'certificate_revocation' setting that defaults to true" do
+ Puppet.settings[:certificate_revocation].should be_true
+ end
+
+ it "should have an http_compression setting that defaults to false" do
+ Puppet.settings[:http_compression].should be_false
+ end
+
+ describe "reportdir" do
+ subject { Puppet.settings[:reportdir] }
+ it { should == "#{Puppet[:vardir]}/reports" }
+ end
+
+ describe "reporturl" do
+ subject { Puppet.settings[:reporturl] }
+ it { should == "http://localhost:3000/reports" }
+ end
end
diff --git a/spec/integration/file_serving/content_spec.rb b/spec/integration/file_serving/content_spec.rb
index a51b362..1443b95 100755
--- a/spec/integration/file_serving/content_spec.rb
+++ b/spec/integration/file_serving/content_spec.rb
@@ -9,12 +9,12 @@ require 'puppet/file_serving/content'
require 'shared_behaviours/file_serving'
describe Puppet::FileServing::Content, " when finding files" do
- it_should_behave_like "Puppet::FileServing::Files"
+ it_should_behave_like "Puppet::FileServing::Files"
- before do
- @test_class = Puppet::FileServing::Content
- @indirection = Puppet::FileServing::Content.indirection
- end
+ before do
+ @test_class = Puppet::FileServing::Content
+ @indirection = Puppet::FileServing::Content.indirection
+ end
- after { Puppet::Util::Cacher.expire }
+ after { Puppet::Util::Cacher.expire }
end
diff --git a/spec/integration/file_serving/fileset_spec.rb b/spec/integration/file_serving/fileset_spec.rb
index 80bf0f3..e5afe8f 100755
--- a/spec/integration/file_serving/fileset_spec.rb
+++ b/spec/integration/file_serving/fileset_spec.rb
@@ -5,10 +5,10 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/file_serving/fileset'
describe Puppet::FileServing::Fileset do
- it "should be able to recurse on a single file" do
- @path = Tempfile.new("fileset_integration")
+ it "should be able to recurse on a single file" do
+ @path = Tempfile.new("fileset_integration")
- fileset = Puppet::FileServing::Fileset.new(@path.path)
- lambda { fileset.files }.should_not raise_error
- end
+ fileset = Puppet::FileServing::Fileset.new(@path.path)
+ lambda { fileset.files }.should_not raise_error
+ end
end
diff --git a/spec/integration/file_serving/metadata_spec.rb b/spec/integration/file_serving/metadata_spec.rb
index bd105e4..1e67309 100755
--- a/spec/integration/file_serving/metadata_spec.rb
+++ b/spec/integration/file_serving/metadata_spec.rb
@@ -10,12 +10,12 @@ require 'shared_behaviours/file_serving'
require 'puppet/indirector/file_metadata/file_server'
describe Puppet::FileServing::Metadata, " when finding files" do
- it_should_behave_like "Puppet::FileServing::Files"
+ it_should_behave_like "Puppet::FileServing::Files"
- before do
- @test_class = Puppet::FileServing::Metadata
- @indirection = Puppet::FileServing::Metadata.indirection
- end
+ before do
+ @test_class = Puppet::FileServing::Metadata
+ @indirection = Puppet::FileServing::Metadata.indirection
+ end
- after { Puppet::Util::Cacher.expire }
+ after { Puppet::Util::Cacher.expire }
end
diff --git a/spec/integration/file_serving/terminus_helper_spec.rb b/spec/integration/file_serving/terminus_helper_spec.rb
index 7d2587a..5fd47c9 100755
--- a/spec/integration/file_serving/terminus_helper_spec.rb
+++ b/spec/integration/file_serving/terminus_helper_spec.rb
@@ -5,18 +5,18 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/file_serving/terminus_helper'
class TerminusHelperIntegrationTester
- include Puppet::FileServing::TerminusHelper
- def model
- Puppet::FileServing::Metadata
- end
+ include Puppet::FileServing::TerminusHelper
+ def model
+ Puppet::FileServing::Metadata
+ end
end
describe Puppet::FileServing::TerminusHelper do
- it "should be able to recurse on a single file" do
- @path = Tempfile.new("fileset_integration")
- request = Puppet::Indirector::Request.new(:metadata, :find, @path.path, :recurse => true)
+ it "should be able to recurse on a single file" do
+ @path = Tempfile.new("fileset_integration")
+ request = Puppet::Indirector::Request.new(:metadata, :find, @path.path, :recurse => true)
- tester = TerminusHelperIntegrationTester.new
- lambda { tester.path2instances(request, @path.path) }.should_not raise_error
- end
+ tester = TerminusHelperIntegrationTester.new
+ lambda { tester.path2instances(request, @path.path) }.should_not raise_error
+ end
end
diff --git a/spec/integration/indirector/bucket_file/rest_spec.rb b/spec/integration/indirector/bucket_file/rest_spec.rb
index 94d6e3a..4d90a8c 100644
--- a/spec/integration/indirector/bucket_file/rest_spec.rb
+++ b/spec/integration/indirector/bucket_file/rest_spec.rb
@@ -7,62 +7,62 @@ require 'puppet/network/server'
require 'puppet/network/http/webrick/rest'
describe "Filebucket REST Terminus" do
- before do
- Puppet[:masterport] = 34343
- Puppet[:server] = "localhost"
-
- # Get a safe temporary file
- @tmpfile = Tempfile.new("webrick_integration_testing")
- @dir = @tmpfile.path + "_dir"
-
- Puppet.settings[:confdir] = @dir
- Puppet.settings[:vardir] = @dir
- Puppet.settings[:server] = "127.0.0.1"
- Puppet.settings[:masterport] = "34343"
-
- Puppet::Util::Cacher.expire
-
- Puppet[:servertype] = 'webrick'
- Puppet[:server] = '127.0.0.1'
- Puppet[:certname] = '127.0.0.1'
-
- # Generate the certificate with a local CA
- Puppet::SSL::Host.ca_location = :local
- ca = Puppet::SSL::CertificateAuthority.new
- ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname])
- ca.generate("foo.madstop.com") unless Puppet::SSL::Certificate.find(Puppet[:certname])
-
- @host = Puppet::SSL::Host.new(Puppet[:certname])
-
- @params = { :port => 34343, :handlers => [ :file_bucket_file ] }
- @server = Puppet::Network::Server.new(@params)
- @server.listen
-
- @old_terminus = Puppet::FileBucket::File.indirection.terminus_class
- Puppet::FileBucket::File.terminus_class = :rest
-
- # LAK:NOTE We need to have a fake model here so that our indirected methods get
- # passed through REST; otherwise we'd be stubbing 'find', which would cause an immediate
- # return.
- @file_bucket_file = stub_everything 'file_bucket_file'
- @mock_model = stub('faked model', :name => "file_bucket_file", :convert_from => @file_bucket_file)
- Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
-
- Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization)
- end
-
- after do
- Puppet::Network::HttpPool.expire
- Puppet::SSL::Host.ca_location = :none
- Puppet.settings.clear
- @server.unlisten
- Puppet::FileBucket::File.terminus_class = @old_terminus
- end
-
- it "should be able save a file to the remote filebucket" do
- @file_bucket_file.expects(:save)
-
- file_bucket_file = Puppet::FileBucket::File.new("pouet")
- file_bucket_file.save
- end
+ before do
+ Puppet[:masterport] = 34343
+ Puppet[:server] = "localhost"
+
+ # Get a safe temporary file
+ @tmpfile = Tempfile.new("webrick_integration_testing")
+ @dir = @tmpfile.path + "_dir"
+
+ Puppet.settings[:confdir] = @dir
+ Puppet.settings[:vardir] = @dir
+ Puppet.settings[:server] = "127.0.0.1"
+ Puppet.settings[:masterport] = "34343"
+
+ Puppet::Util::Cacher.expire
+
+ Puppet[:servertype] = 'webrick'
+ Puppet[:server] = '127.0.0.1'
+ Puppet[:certname] = '127.0.0.1'
+
+ # Generate the certificate with a local CA
+ Puppet::SSL::Host.ca_location = :local
+ ca = Puppet::SSL::CertificateAuthority.new
+ ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname])
+ ca.generate("foo.madstop.com") unless Puppet::SSL::Certificate.find(Puppet[:certname])
+
+ @host = Puppet::SSL::Host.new(Puppet[:certname])
+
+ @params = { :port => 34343, :handlers => [ :file_bucket_file ] }
+ @server = Puppet::Network::Server.new(@params)
+ @server.listen
+
+ @old_terminus = Puppet::FileBucket::File.indirection.terminus_class
+ Puppet::FileBucket::File.terminus_class = :rest
+
+ # LAK:NOTE We need to have a fake model here so that our indirected methods get
+ # passed through REST; otherwise we'd be stubbing 'find', which would cause an immediate
+ # return.
+ @file_bucket_file = stub_everything 'file_bucket_file'
+ @mock_model = stub('faked model', :name => "file_bucket_file", :convert_from => @file_bucket_file)
+ Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
+
+ Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization)
+ end
+
+ after do
+ Puppet::Network::HttpPool.expire
+ Puppet::SSL::Host.ca_location = :none
+ Puppet.settings.clear
+ @server.unlisten
+ Puppet::FileBucket::File.terminus_class = @old_terminus
+ end
+
+ it "should be able save a file to the remote filebucket" do
+ @file_bucket_file.expects(:save)
+
+ file_bucket_file = Puppet::FileBucket::File.new("pouet")
+ file_bucket_file.save
+ end
end
diff --git a/spec/integration/indirector/catalog/compiler_spec.rb b/spec/integration/indirector/catalog/compiler_spec.rb
index 4905b38..ede502e 100755
--- a/spec/integration/indirector/catalog/compiler_spec.rb
+++ b/spec/integration/indirector/catalog/compiler_spec.rb
@@ -7,62 +7,62 @@ require 'puppet/resource/catalog'
Puppet::Resource::Catalog.indirection.terminus(:compiler)
describe Puppet::Resource::Catalog::Compiler do
- before do
- Facter.stubs(:value).returns "something"
- @catalog = Puppet::Resource::Catalog.new
-
- @one = Puppet::Resource.new(:file, "/one")
-
- @two = Puppet::Resource.new(:file, "/two")
- @catalog.add_resource(@one, @two)
- end
-
- after { Puppet.settings.clear }
-
- it "should remove virtual resources when filtering" do
- @one.virtual = true
- Puppet::Resource::Catalog.indirection.terminus.filter(@catalog).resource_refs.should == [ @two.ref ]
- end
-
- it "should not remove exported resources when filtering" do
- @one.exported = true
- Puppet::Resource::Catalog.indirection.terminus.filter(@catalog).resource_refs.sort.should == [ @one.ref, @two.ref ]
- end
-
- it "should remove virtual exported resources when filtering" do
- @one.exported = true
- @one.virtual = true
- Puppet::Resource::Catalog.indirection.terminus.filter(@catalog).resource_refs.should == [ @two.ref ]
- end
-
- it "should filter out virtual resources when finding a catalog" do
- @one.virtual = true
- request = stub 'request', :name => "mynode"
- Puppet::Resource::Catalog.indirection.terminus.stubs(:extract_facts_from_request)
- Puppet::Resource::Catalog.indirection.terminus.stubs(:node_from_request)
- Puppet::Resource::Catalog.indirection.terminus.stubs(:compile).returns(@catalog)
-
- Puppet::Resource::Catalog.find(request).resource_refs.should == [ @two.ref ]
- end
-
- it "should not filter out exported resources when finding a catalog" do
- @one.exported = true
- request = stub 'request', :name => "mynode"
- Puppet::Resource::Catalog.indirection.terminus.stubs(:extract_facts_from_request)
- Puppet::Resource::Catalog.indirection.terminus.stubs(:node_from_request)
- Puppet::Resource::Catalog.indirection.terminus.stubs(:compile).returns(@catalog)
-
- Puppet::Resource::Catalog.find(request).resource_refs.sort.should == [ @one.ref, @two.ref ]
- end
-
- it "should filter out virtual exported resources when finding a catalog" do
- @one.exported = true
- @one.virtual = true
- request = stub 'request', :name => "mynode"
- Puppet::Resource::Catalog.indirection.terminus.stubs(:extract_facts_from_request)
- Puppet::Resource::Catalog.indirection.terminus.stubs(:node_from_request)
- Puppet::Resource::Catalog.indirection.terminus.stubs(:compile).returns(@catalog)
-
- Puppet::Resource::Catalog.find(request).resource_refs.should == [ @two.ref ]
- end
+ before do
+ Facter.stubs(:value).returns "something"
+ @catalog = Puppet::Resource::Catalog.new
+
+ @one = Puppet::Resource.new(:file, "/one")
+
+ @two = Puppet::Resource.new(:file, "/two")
+ @catalog.add_resource(@one, @two)
+ end
+
+ after { Puppet.settings.clear }
+
+ it "should remove virtual resources when filtering" do
+ @one.virtual = true
+ Puppet::Resource::Catalog.indirection.terminus.filter(@catalog).resource_refs.should == [ @two.ref ]
+ end
+
+ it "should not remove exported resources when filtering" do
+ @one.exported = true
+ Puppet::Resource::Catalog.indirection.terminus.filter(@catalog).resource_refs.sort.should == [ @one.ref, @two.ref ]
+ end
+
+ it "should remove virtual exported resources when filtering" do
+ @one.exported = true
+ @one.virtual = true
+ Puppet::Resource::Catalog.indirection.terminus.filter(@catalog).resource_refs.should == [ @two.ref ]
+ end
+
+ it "should filter out virtual resources when finding a catalog" do
+ @one.virtual = true
+ request = stub 'request', :name => "mynode"
+ Puppet::Resource::Catalog.indirection.terminus.stubs(:extract_facts_from_request)
+ Puppet::Resource::Catalog.indirection.terminus.stubs(:node_from_request)
+ Puppet::Resource::Catalog.indirection.terminus.stubs(:compile).returns(@catalog)
+
+ Puppet::Resource::Catalog.find(request).resource_refs.should == [ @two.ref ]
+ end
+
+ it "should not filter out exported resources when finding a catalog" do
+ @one.exported = true
+ request = stub 'request', :name => "mynode"
+ Puppet::Resource::Catalog.indirection.terminus.stubs(:extract_facts_from_request)
+ Puppet::Resource::Catalog.indirection.terminus.stubs(:node_from_request)
+ Puppet::Resource::Catalog.indirection.terminus.stubs(:compile).returns(@catalog)
+
+ Puppet::Resource::Catalog.find(request).resource_refs.sort.should == [ @one.ref, @two.ref ]
+ end
+
+ it "should filter out virtual exported resources when finding a catalog" do
+ @one.exported = true
+ @one.virtual = true
+ request = stub 'request', :name => "mynode"
+ Puppet::Resource::Catalog.indirection.terminus.stubs(:extract_facts_from_request)
+ Puppet::Resource::Catalog.indirection.terminus.stubs(:node_from_request)
+ Puppet::Resource::Catalog.indirection.terminus.stubs(:compile).returns(@catalog)
+
+ Puppet::Resource::Catalog.find(request).resource_refs.should == [ @two.ref ]
+ end
end
diff --git a/spec/integration/indirector/catalog/queue_spec.rb b/spec/integration/indirector/catalog/queue_spec.rb
index 5a781c1..0f8bd41 100755
--- a/spec/integration/indirector/catalog/queue_spec.rb
+++ b/spec/integration/indirector/catalog/queue_spec.rb
@@ -6,56 +6,56 @@ require 'puppet/resource/catalog'
describe "Puppet::Resource::Catalog::Queue" do
- confine "Missing pson support; cannot test queue" => Puppet.features.pson?
+ confine "Missing pson support; cannot test queue" => Puppet.features.pson?
- before do
- Puppet::Resource::Catalog.indirection.terminus(:queue)
- @catalog = Puppet::Resource::Catalog.new
+ before do
+ Puppet::Resource::Catalog.indirection.terminus(:queue)
+ @catalog = Puppet::Resource::Catalog.new
- @one = Puppet::Resource.new(:file, "/one")
- @two = Puppet::Resource.new(:file, "/two")
- @catalog.add_resource(@one, @two)
+ @one = Puppet::Resource.new(:file, "/one")
+ @two = Puppet::Resource.new(:file, "/two")
+ @catalog.add_resource(@one, @two)
- @catalog.add_edge(@one, @two)
+ @catalog.add_edge(@one, @two)
- Puppet[:trace] = true
- end
+ Puppet[:trace] = true
+ end
- after { Puppet.settings.clear }
+ after { Puppet.settings.clear }
- it "should render catalogs to pson and send them via the queue client when catalogs are saved" do
- terminus = Puppet::Resource::Catalog.indirection.terminus(:queue)
+ it "should render catalogs to pson and send them via the queue client when catalogs are saved" do
+ terminus = Puppet::Resource::Catalog.indirection.terminus(:queue)
- client = mock 'client'
- terminus.stubs(:client).returns client
+ client = mock 'client'
+ terminus.stubs(:client).returns client
- client.expects(:send_message).with(:catalog, @catalog.to_pson)
+ client.expects(:send_message).with(:catalog, @catalog.to_pson)
- request = Puppet::Indirector::Request.new(:catalog, :save, "foo", :instance => @catalog)
+ request = Puppet::Indirector::Request.new(:catalog, :save, "foo", :instance => @catalog)
- terminus.save(request)
- end
+ terminus.save(request)
+ end
- it "should intern catalog messages when they are passed via a subscription" do
- client = mock 'client'
- Puppet::Resource::Catalog::Queue.stubs(:client).returns client
+ it "should intern catalog messages when they are passed via a subscription" do
+ client = mock 'client'
+ Puppet::Resource::Catalog::Queue.stubs(:client).returns client
- pson = @catalog.to_pson
+ pson = @catalog.to_pson
- client.expects(:subscribe).with(:catalog).yields(pson)
+ client.expects(:subscribe).with(:catalog).yields(pson)
- Puppet.expects(:err).never
+ Puppet.expects(:err).never
- result = []
- Puppet::Resource::Catalog::Queue.subscribe do |catalog|
- result << catalog
- end
+ result = []
+ Puppet::Resource::Catalog::Queue.subscribe do |catalog|
+ result << catalog
+ end
- catalog = result.shift
- catalog.should be_instance_of(Puppet::Resource::Catalog)
+ catalog = result.shift
+ catalog.should be_instance_of(Puppet::Resource::Catalog)
- catalog.resource(:file, "/one").should be_instance_of(Puppet::Resource)
- catalog.resource(:file, "/two").should be_instance_of(Puppet::Resource)
- catalog.should be_edge(catalog.resource(:file, "/one"), catalog.resource(:file, "/two"))
- end
+ catalog.resource(:file, "/one").should be_instance_of(Puppet::Resource)
+ catalog.resource(:file, "/two").should be_instance_of(Puppet::Resource)
+ catalog.should be_edge(catalog.resource(:file, "/one"), catalog.resource(:file, "/two"))
+ end
end
diff --git a/spec/integration/indirector/certificate/rest_spec.rb b/spec/integration/indirector/certificate/rest_spec.rb
index 8042f86..356a7d3 100755
--- a/spec/integration/indirector/certificate/rest_spec.rb
+++ b/spec/integration/indirector/certificate/rest_spec.rb
@@ -7,62 +7,62 @@ require 'puppet/network/server'
require 'puppet/network/http/webrick/rest'
describe "Certificate REST Terminus" do
- before do
- Puppet[:masterport] = 34343
- Puppet[:server] = "localhost"
-
- # Get a safe temporary file
- @tmpfile = Tempfile.new("webrick_integration_testing")
- @dir = @tmpfile.path + "_dir"
-
- Puppet.settings[:confdir] = @dir
- Puppet.settings[:vardir] = @dir
- Puppet.settings[:server] = "127.0.0.1"
- Puppet.settings[:masterport] = "34343"
-
- Puppet::Util::Cacher.expire
-
- Puppet[:servertype] = 'webrick'
- Puppet[:server] = '127.0.0.1'
- Puppet[:certname] = '127.0.0.1'
-
- # Generate the certificate with a local CA
- Puppet::SSL::Host.ca_location = :local
- ca = Puppet::SSL::CertificateAuthority.new
- ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname])
- ca.generate("foo.madstop.com") unless Puppet::SSL::Certificate.find(Puppet[:certname])
-
- @host = Puppet::SSL::Host.new(Puppet[:certname])
-
- @params = { :port => 34343, :handlers => [ :certificate ] }
- @server = Puppet::Network::Server.new(@params)
- @server.listen
-
- # Then switch to a remote CA, so that we go through REST.
- Puppet::SSL::Host.ca_location = :remote
-
- # LAK:NOTE We need to have a fake model here so that our indirected methods get
- # passed through REST; otherwise we'd be stubbing 'find', which would cause an immediate
- # return.
- @mock_model = stub('faked model', :name => "certificate")
- Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
-
- Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization).returns(true)
- end
-
- after do
- Puppet::Network::HttpPool.expire
- Puppet::SSL::Host.ca_location = :none
- Puppet.settings.clear
- @server.unlisten
- end
-
- it "should be able to retrieve a remote certificate" do
- @mock_model.expects(:find).returns @host.certificate
- result = Puppet::SSL::Certificate.find('bar')
-
- # There's no good '==' method on certs.
- result.content.to_s.should == @host.certificate.content.to_s
- result.name.should == "bar"
- end
+ before do
+ Puppet[:masterport] = 34343
+ Puppet[:server] = "localhost"
+
+ # Get a safe temporary file
+ @tmpfile = Tempfile.new("webrick_integration_testing")
+ @dir = @tmpfile.path + "_dir"
+
+ Puppet.settings[:confdir] = @dir
+ Puppet.settings[:vardir] = @dir
+ Puppet.settings[:server] = "127.0.0.1"
+ Puppet.settings[:masterport] = "34343"
+
+ Puppet::Util::Cacher.expire
+
+ Puppet[:servertype] = 'webrick'
+ Puppet[:server] = '127.0.0.1'
+ Puppet[:certname] = '127.0.0.1'
+
+ # Generate the certificate with a local CA
+ Puppet::SSL::Host.ca_location = :local
+ ca = Puppet::SSL::CertificateAuthority.new
+ ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname])
+ ca.generate("foo.madstop.com") unless Puppet::SSL::Certificate.find(Puppet[:certname])
+
+ @host = Puppet::SSL::Host.new(Puppet[:certname])
+
+ @params = { :port => 34343, :handlers => [ :certificate ] }
+ @server = Puppet::Network::Server.new(@params)
+ @server.listen
+
+ # Then switch to a remote CA, so that we go through REST.
+ Puppet::SSL::Host.ca_location = :remote
+
+ # LAK:NOTE We need to have a fake model here so that our indirected methods get
+ # passed through REST; otherwise we'd be stubbing 'find', which would cause an immediate
+ # return.
+ @mock_model = stub('faked model', :name => "certificate")
+ Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
+
+ Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization).returns(true)
+ end
+
+ after do
+ Puppet::Network::HttpPool.expire
+ Puppet::SSL::Host.ca_location = :none
+ Puppet.settings.clear
+ @server.unlisten
+ end
+
+ it "should be able to retrieve a remote certificate" do
+ @mock_model.expects(:find).returns @host.certificate
+ result = Puppet::SSL::Certificate.find('bar')
+
+ # There's no good '==' method on certs.
+ result.content.to_s.should == @host.certificate.content.to_s
+ result.name.should == "bar"
+ end
end
diff --git a/spec/integration/indirector/certificate_request/rest_spec.rb b/spec/integration/indirector/certificate_request/rest_spec.rb
index 86fb1ba..2c98ef6 100755
--- a/spec/integration/indirector/certificate_request/rest_spec.rb
+++ b/spec/integration/indirector/certificate_request/rest_spec.rb
@@ -7,82 +7,82 @@ require 'puppet/network/server'
require 'puppet/network/http/webrick/rest'
describe "Certificate Request REST Terminus" do
- before do
- Puppet::Util::Cacher.expire
-
- Puppet[:masterport] = 34343
- Puppet[:server] = "localhost"
-
- # Get a safe temporary file
- @tmpfile = Tempfile.new("webrick_integration_testing")
- @dir = @tmpfile.path + "_dir"
-
- Puppet.settings[:confdir] = @dir
- Puppet.settings[:vardir] = @dir
- Puppet.settings[:server] = "127.0.0.1"
- Puppet.settings[:masterport] = "34343"
-
- Puppet[:servertype] = 'webrick'
- Puppet[:server] = '127.0.0.1'
- Puppet[:certname] = '127.0.0.1'
-
- # Generate the certificate with a local CA
- Puppet::SSL::Host.ca_location = :local
- ca = Puppet::SSL::CertificateAuthority.new
- ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname])
-
- # Create the CSR and write it to disk
- @host = Puppet::SSL::Host.new("foo.madstop.com")
- @host.generate_certificate_request
-
- # Now remove the cached csr
- Puppet::SSL::Host.ca_location = :none
- Puppet::SSL::Host.destroy("foo.madstop.com")
-
- @params = { :port => 34343, :handlers => [ :certificate_request ] }
- @server = Puppet::Network::Server.new(@params)
- @server.listen
-
- # Then switch to a remote CA, so that we go through REST.
- Puppet::SSL::Host.ca_location = :remote
-
- # LAK:NOTE We need to have a fake model here so that our indirected methods get
- # passed through REST; otherwise we'd be stubbing 'find', which would cause an immediate
- # return.
- @mock_model = stub('faked model', :name => "certificate request")
- Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
-
- Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization).returns(true)
- end
-
- after do
- Puppet::Network::HttpPool.expire
- Puppet::SSL::Host.ca_location = :none
- Puppet.settings.clear
- @server.unlisten
- end
-
- it "should be able to save a certificate request to the CA" do
- key = Puppet::SSL::Key.new("bar.madstop.com")
- key.generate
-
- csr = Puppet::SSL::CertificateRequest.new("bar.madstop.com")
- csr.generate(key.content)
-
- server_csr = mock 'csr'
- server_csr.expects(:save)
- @mock_model.expects(:convert_from).with("s", csr.content.to_s).returns server_csr
-
- csr.save
- end
-
- it "should be able to retrieve a remote certificate request" do
- # We're finding the cached value :/
- @mock_model.expects(:find).returns @host.certificate_request
- result = Puppet::SSL::CertificateRequest.find('foo.madstop.com')
-
- # There's no good '==' method on certs.
- result.content.to_s.should == @host.certificate_request.content.to_s
- result.name.should == @host.certificate_request.name
- end
+ before do
+ Puppet::Util::Cacher.expire
+
+ Puppet[:masterport] = 34343
+ Puppet[:server] = "localhost"
+
+ # Get a safe temporary file
+ @tmpfile = Tempfile.new("webrick_integration_testing")
+ @dir = @tmpfile.path + "_dir"
+
+ Puppet.settings[:confdir] = @dir
+ Puppet.settings[:vardir] = @dir
+ Puppet.settings[:server] = "127.0.0.1"
+ Puppet.settings[:masterport] = "34343"
+
+ Puppet[:servertype] = 'webrick'
+ Puppet[:server] = '127.0.0.1'
+ Puppet[:certname] = '127.0.0.1'
+
+ # Generate the certificate with a local CA
+ Puppet::SSL::Host.ca_location = :local
+ ca = Puppet::SSL::CertificateAuthority.new
+ ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname])
+
+ # Create the CSR and write it to disk
+ @host = Puppet::SSL::Host.new("foo.madstop.com")
+ @host.generate_certificate_request
+
+ # Now remove the cached csr
+ Puppet::SSL::Host.ca_location = :none
+ Puppet::SSL::Host.destroy("foo.madstop.com")
+
+ @params = { :port => 34343, :handlers => [ :certificate_request ] }
+ @server = Puppet::Network::Server.new(@params)
+ @server.listen
+
+ # Then switch to a remote CA, so that we go through REST.
+ Puppet::SSL::Host.ca_location = :remote
+
+ # LAK:NOTE We need to have a fake model here so that our indirected methods get
+ # passed through REST; otherwise we'd be stubbing 'find', which would cause an immediate
+ # return.
+ @mock_model = stub('faked model', :name => "certificate request")
+ Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
+
+ Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization).returns(true)
+ end
+
+ after do
+ Puppet::Network::HttpPool.expire
+ Puppet::SSL::Host.ca_location = :none
+ Puppet.settings.clear
+ @server.unlisten
+ end
+
+ it "should be able to save a certificate request to the CA" do
+ key = Puppet::SSL::Key.new("bar.madstop.com")
+ key.generate
+
+ csr = Puppet::SSL::CertificateRequest.new("bar.madstop.com")
+ csr.generate(key.content)
+
+ server_csr = mock 'csr'
+ server_csr.expects(:save)
+ @mock_model.expects(:convert_from).with("s", csr.content.to_s).returns server_csr
+
+ csr.save
+ end
+
+ it "should be able to retrieve a remote certificate request" do
+ # We're finding the cached value :/
+ @mock_model.expects(:find).returns @host.certificate_request
+ result = Puppet::SSL::CertificateRequest.find('foo.madstop.com')
+
+ # There's no good '==' method on certs.
+ result.content.to_s.should == @host.certificate_request.content.to_s
+ result.name.should == @host.certificate_request.name
+ end
end
diff --git a/spec/integration/indirector/certificate_revocation_list/rest_spec.rb b/spec/integration/indirector/certificate_revocation_list/rest_spec.rb
index 8c8d6e1..62a2f80 100755
--- a/spec/integration/indirector/certificate_revocation_list/rest_spec.rb
+++ b/spec/integration/indirector/certificate_revocation_list/rest_spec.rb
@@ -7,70 +7,70 @@ require 'puppet/network/server'
require 'puppet/network/http/webrick/rest'
describe "Certificate REST Terminus" do
- before do
- Puppet[:masterport] = 34343
- Puppet[:server] = "localhost"
-
- # Get a safe temporary file
- @tmpfile = Tempfile.new("webrick_integration_testing")
- @dir = @tmpfile.path + "_dir"
-
- Puppet.settings[:confdir] = @dir
- Puppet.settings[:vardir] = @dir
- Puppet.settings[:server] = "127.0.0.1"
- Puppet.settings[:masterport] = "34343"
-
- Puppet::Util::Cacher.expire
-
- Puppet[:servertype] = 'webrick'
- Puppet[:server] = '127.0.0.1'
- Puppet[:certname] = '127.0.0.1'
-
- # Generate the certificate with a local CA
- Puppet::SSL::Host.ca_location = :local
- ca = Puppet::SSL::CertificateAuthority.new
- ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname])
-
- @params = { :port => 34343, :handlers => [ :certificate_revocation_list ] }
- @server = Puppet::Network::Server.new(@params)
- @server.listen
-
- # And make sure we've generated the CRL
- @crl = ca.crl
-
- # Now remove the cached crl
- Puppet::SSL::Host.ca_location = :none
- Puppet::SSL::CertificateRevocationList.destroy(Puppet::SSL::CA_NAME)
-
- # This is necessary so that we create the SSL store before we start
- # using REST. This is necessary to prevent an infinite loop,
- # which only occurs during testing.
- Puppet::Network::HttpPool.ssl_host.ssl_store
-
- # Then switch to a remote CA, so that we go through REST.
- Puppet::SSL::Host.ca_location = :remote
-
- # LAK:NOTE We need to have a fake model here so that our indirected methods get
- # passed through REST; otherwise we'd be stubbing 'find', which would cause an immediate
- # return.
- @mock_model = stub('faked model', :name => "certificate")
- Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
-
- Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization).returns(true)
- end
-
- after do
- Puppet::Network::HttpPool.expire
- Puppet::SSL::Host.ca_location = :none
- Puppet.settings.clear
- @server.unlisten
- end
-
- it "should be able to retrieve a remote CRL" do
- @mock_model.expects(:find).returns @crl
- result = Puppet::SSL::CertificateRevocationList.find('bar')
-
- # There's no good '==' method on certs.
- result.content.to_s.should == @crl.content.to_s
- end
+ before do
+ Puppet[:masterport] = 34343
+ Puppet[:server] = "localhost"
+
+ # Get a safe temporary file
+ @tmpfile = Tempfile.new("webrick_integration_testing")
+ @dir = @tmpfile.path + "_dir"
+
+ Puppet.settings[:confdir] = @dir
+ Puppet.settings[:vardir] = @dir
+ Puppet.settings[:server] = "127.0.0.1"
+ Puppet.settings[:masterport] = "34343"
+
+ Puppet::Util::Cacher.expire
+
+ Puppet[:servertype] = 'webrick'
+ Puppet[:server] = '127.0.0.1'
+ Puppet[:certname] = '127.0.0.1'
+
+ # Generate the certificate with a local CA
+ Puppet::SSL::Host.ca_location = :local
+ ca = Puppet::SSL::CertificateAuthority.new
+ ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname])
+
+ @params = { :port => 34343, :handlers => [ :certificate_revocation_list ] }
+ @server = Puppet::Network::Server.new(@params)
+ @server.listen
+
+ # And make sure we've generated the CRL
+ @crl = ca.crl
+
+ # Now remove the cached crl
+ Puppet::SSL::Host.ca_location = :none
+ Puppet::SSL::CertificateRevocationList.destroy(Puppet::SSL::CA_NAME)
+
+ # This is necessary so that we create the SSL store before we start
+ # using REST. This is necessary to prevent an infinite loop,
+ # which only occurs during testing.
+ Puppet::Network::HttpPool.ssl_host.ssl_store
+
+ # Then switch to a remote CA, so that we go through REST.
+ Puppet::SSL::Host.ca_location = :remote
+
+ # LAK:NOTE We need to have a fake model here so that our indirected methods get
+ # passed through REST; otherwise we'd be stubbing 'find', which would cause an immediate
+ # return.
+ @mock_model = stub('faked model', :name => "certificate")
+ Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
+
+ Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization).returns(true)
+ end
+
+ after do
+ Puppet::Network::HttpPool.expire
+ Puppet::SSL::Host.ca_location = :none
+ Puppet.settings.clear
+ @server.unlisten
+ end
+
+ it "should be able to retrieve a remote CRL" do
+ @mock_model.expects(:find).returns @crl
+ result = Puppet::SSL::CertificateRevocationList.find('bar')
+
+ # There's no good '==' method on certs.
+ result.content.to_s.should == @crl.content.to_s
+ end
end
diff --git a/spec/integration/indirector/direct_file_server_spec.rb b/spec/integration/indirector/direct_file_server_spec.rb
index d2b933c..24a55a3 100755
--- a/spec/integration/indirector/direct_file_server_spec.rb
+++ b/spec/integration/indirector/direct_file_server_spec.rb
@@ -8,66 +8,66 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector/file_content/file'
describe Puppet::Indirector::DirectFileServer, " when interacting with the filesystem and the model" do
- before do
- # We just test a subclass, since it's close enough.
- @terminus = Puppet::Indirector::FileContent::File.new
+ before do
+ # We just test a subclass, since it's close enough.
+ @terminus = Puppet::Indirector::FileContent::File.new
- @filepath = "/path/to/my/file"
- end
+ @filepath = "/path/to/my/file"
+ end
- it "should return an instance of the model" do
- FileTest.expects(:exists?).with(@filepath).returns(true)
+ it "should return an instance of the model" do
+ FileTest.expects(:exists?).with(@filepath).returns(true)
- @terminus.find(@terminus.indirection.request(:find, "file://host#{@filepath}")).should be_instance_of(Puppet::FileServing::Content)
- end
+ @terminus.find(@terminus.indirection.request(:find, "file://host#{@filepath}")).should be_instance_of(Puppet::FileServing::Content)
+ end
- it "should return an instance capable of returning its content" do
- FileTest.expects(:exists?).with(@filepath).returns(true)
- File.stubs(:lstat).with(@filepath).returns(stub("stat", :ftype => "file"))
- File.expects(:read).with(@filepath).returns("my content")
+ it "should return an instance capable of returning its content" do
+ FileTest.expects(:exists?).with(@filepath).returns(true)
+ File.stubs(:lstat).with(@filepath).returns(stub("stat", :ftype => "file"))
+ File.expects(:read).with(@filepath).returns("my content")
- instance = @terminus.find(@terminus.indirection.request(:find, "file://host#{@filepath}"))
+ instance = @terminus.find(@terminus.indirection.request(:find, "file://host#{@filepath}"))
- instance.content.should == "my content"
- end
+ instance.content.should == "my content"
+ end
end
describe Puppet::Indirector::DirectFileServer, " when interacting with FileServing::Fileset and the model" do
- before do
- @terminus = Puppet::Indirector::FileContent::File.new
-
- @path = Tempfile.new("direct_file_server_testing")
- path = @path.path
- @path.close!
- @path = path
-
- Dir.mkdir(@path)
- File.open(File.join(@path, "one"), "w") { |f| f.print "one content" }
- File.open(File.join(@path, "two"), "w") { |f| f.print "two content" }
-
- @request = @terminus.indirection.request(:search, "file:///#{@path}", :recurse => true)
- end
-
- after do
- system("rm -rf #{@path}")
- end
-
- it "should return an instance for every file in the fileset" do
- result = @terminus.search(@request)
- result.should be_instance_of(Array)
- result.length.should == 3
- result.each { |r| r.should be_instance_of(Puppet::FileServing::Content) }
- end
-
- it "should return instances capable of returning their content" do
- @terminus.search(@request).each do |instance|
- case instance.full_path
- when /one/; instance.content.should == "one content"
- when /two/; instance.content.should == "two content"
- when @path
- else
- raise "No valid key for #{instance.path.inspect}"
- end
- end
+ before do
+ @terminus = Puppet::Indirector::FileContent::File.new
+
+ @path = Tempfile.new("direct_file_server_testing")
+ path = @path.path
+ @path.close!
+ @path = path
+
+ Dir.mkdir(@path)
+ File.open(File.join(@path, "one"), "w") { |f| f.print "one content" }
+ File.open(File.join(@path, "two"), "w") { |f| f.print "two content" }
+
+ @request = @terminus.indirection.request(:search, "file:///#{@path}", :recurse => true)
+ end
+
+ after do
+ system("rm -rf #{@path}")
+ end
+
+ it "should return an instance for every file in the fileset" do
+ result = @terminus.search(@request)
+ result.should be_instance_of(Array)
+ result.length.should == 3
+ result.each { |r| r.should be_instance_of(Puppet::FileServing::Content) }
+ end
+
+ it "should return instances capable of returning their content" do
+ @terminus.search(@request).each do |instance|
+ case instance.full_path
+ when /one/; instance.content.should == "one content"
+ when /two/; instance.content.should == "two content"
+ when @path
+ else
+ raise "No valid key for #{instance.path.inspect}"
+ end
end
+ end
end
diff --git a/spec/integration/indirector/file_content/file_server_spec.rb b/spec/integration/indirector/file_content/file_server_spec.rb
index e8f777e..5de7f1d 100755
--- a/spec/integration/indirector/file_content/file_server_spec.rb
+++ b/spec/integration/indirector/file_content/file_server_spec.rb
@@ -11,84 +11,84 @@ require 'shared_behaviours/file_server_terminus'
require 'puppet_spec/files'
describe Puppet::Indirector::FileContent::FileServer, " when finding files" do
- it_should_behave_like "Puppet::Indirector::FileServerTerminus"
- include PuppetSpec::Files
+ it_should_behave_like "Puppet::Indirector::FileServerTerminus"
+ include PuppetSpec::Files
- before do
- @terminus = Puppet::Indirector::FileContent::FileServer.new
- @test_class = Puppet::FileServing::Content
- end
+ before do
+ @terminus = Puppet::Indirector::FileContent::FileServer.new
+ @test_class = Puppet::FileServing::Content
+ end
- it "should find plugin file content in the environment specified in the request" do
- path = tmpfile("file_content_with_env")
+ it "should find plugin file content in the environment specified in the request" do
+ path = tmpfile("file_content_with_env")
- Dir.mkdir(path)
+ Dir.mkdir(path)
- modpath = File.join(path, "mod")
- FileUtils.mkdir_p(File.join(modpath, "lib"))
- file = File.join(modpath, "lib", "file.rb")
- File.open(file, "w") { |f| f.puts "1" }
+ modpath = File.join(path, "mod")
+ FileUtils.mkdir_p(File.join(modpath, "lib"))
+ file = File.join(modpath, "lib", "file.rb")
+ File.open(file, "w") { |f| f.puts "1" }
- Puppet.settings[:modulepath] = "/no/such/file"
+ Puppet.settings[:modulepath] = "/no/such/file"
- env = Puppet::Node::Environment.new("foo")
- env.stubs(:modulepath).returns [path]
+ env = Puppet::Node::Environment.new("foo")
+ env.stubs(:modulepath).returns [path]
- result = Puppet::FileServing::Content.search("plugins", :environment => "foo", :recurse => true)
+ result = Puppet::FileServing::Content.search("plugins", :environment => "foo", :recurse => true)
- result.should_not be_nil
- result.length.should == 2
- result[1].should be_instance_of(Puppet::FileServing::Content)
- result[1].content.should == "1\n"
- end
+ result.should_not be_nil
+ result.length.should == 2
+ result[1].should be_instance_of(Puppet::FileServing::Content)
+ result[1].content.should == "1\n"
+ end
- it "should find file content in modules" do
- path = tmpfile("file_content")
+ it "should find file content in modules" do
+ path = tmpfile("file_content")
- Dir.mkdir(path)
+ Dir.mkdir(path)
- modpath = File.join(path, "mymod")
- FileUtils.mkdir_p(File.join(modpath, "files"))
- file = File.join(modpath, "files", "myfile")
- File.open(file, "w") { |f| f.puts "1" }
+ modpath = File.join(path, "mymod")
+ FileUtils.mkdir_p(File.join(modpath, "files"))
+ file = File.join(modpath, "files", "myfile")
+ File.open(file, "w") { |f| f.puts "1" }
- Puppet.settings[:modulepath] = path
+ Puppet.settings[:modulepath] = path
- result = Puppet::FileServing::Content.find("modules/mymod/myfile")
+ result = Puppet::FileServing::Content.find("modules/mymod/myfile")
- result.should_not be_nil
- result.should be_instance_of(Puppet::FileServing::Content)
- result.content.should == "1\n"
- end
+ result.should_not be_nil
+ result.should be_instance_of(Puppet::FileServing::Content)
+ result.content.should == "1\n"
+ end
- it "should find file content in files when node name expansions are used" do
- Puppet::Util::Cacher.expire
- FileTest.stubs(:exists?).returns true
- FileTest.stubs(:exists?).with(Puppet[:fileserverconfig]).returns(true)
+ it "should find file content in files when node name expansions are used" do
+ Puppet::Util::Cacher.expire
+ FileTest.stubs(:exists?).returns true
+ FileTest.stubs(:exists?).with(Puppet[:fileserverconfig]).returns(true)
- @path = tmpfile("file_server_testing")
+ @path = tmpfile("file_server_testing")
- Dir.mkdir(@path)
- subdir = File.join(@path, "mynode")
- Dir.mkdir(subdir)
- File.open(File.join(subdir, "myfile"), "w") { |f| f.puts "1" }
+ Dir.mkdir(@path)
+ subdir = File.join(@path, "mynode")
+ Dir.mkdir(subdir)
+ File.open(File.join(subdir, "myfile"), "w") { |f| f.puts "1" }
- # Use a real mount, so the integration is a bit deeper.
- @mount1 = Puppet::FileServing::Configuration::Mount::File.new("one")
- @mount1.stubs(:allowed?).returns true
- @mount1.path = File.join(@path, "%h")
+ # Use a real mount, so the integration is a bit deeper.
+ @mount1 = Puppet::FileServing::Configuration::Mount::File.new("one")
+ @mount1.stubs(:allowed?).returns true
+ @mount1.path = File.join(@path, "%h")
- @parser = stub 'parser', :changed? => false
- @parser.stubs(:parse).returns("one" => @mount1)
+ @parser = stub 'parser', :changed? => false
+ @parser.stubs(:parse).returns("one" => @mount1)
- Puppet::FileServing::Configuration::Parser.stubs(:new).returns(@parser)
+ Puppet::FileServing::Configuration::Parser.stubs(:new).returns(@parser)
- path = File.join(@path, "myfile")
+ path = File.join(@path, "myfile")
- result = Puppet::FileServing::Content.find("one/myfile", :environment => "foo", :node => "mynode")
+ result = Puppet::FileServing::Content.find("one/myfile", :environment => "foo", :node => "mynode")
- result.should_not be_nil
- result.should be_instance_of(Puppet::FileServing::Content)
- result.content.should == "1\n"
- end
+ result.should_not be_nil
+ result.should be_instance_of(Puppet::FileServing::Content)
+ result.content.should == "1\n"
+ end
end
diff --git a/spec/integration/indirector/file_metadata/file_server_spec.rb b/spec/integration/indirector/file_metadata/file_server_spec.rb
index 7caa2e4..d600121 100755
--- a/spec/integration/indirector/file_metadata/file_server_spec.rb
+++ b/spec/integration/indirector/file_metadata/file_server_spec.rb
@@ -9,10 +9,10 @@ require 'puppet/indirector/file_metadata/file_server'
require 'shared_behaviours/file_server_terminus'
describe Puppet::Indirector::FileMetadata::FileServer, " when finding files" do
- it_should_behave_like "Puppet::Indirector::FileServerTerminus"
+ it_should_behave_like "Puppet::Indirector::FileServerTerminus"
- before do
- @terminus = Puppet::Indirector::FileMetadata::FileServer.new
- @test_class = Puppet::FileServing::Metadata
- end
+ before do
+ @terminus = Puppet::Indirector::FileMetadata::FileServer.new
+ @test_class = Puppet::FileServing::Metadata
+ end
end
diff --git a/spec/integration/indirector/node/ldap_spec.rb b/spec/integration/indirector/node/ldap_spec.rb
index 8227311..e4c0867 100755
--- a/spec/integration/indirector/node/ldap_spec.rb
+++ b/spec/integration/indirector/node/ldap_spec.rb
@@ -5,11 +5,11 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/node/ldap'
describe Puppet::Node::Ldap do
- it "should use a restrictive filter when searching for nodes in a class" do
- ldap = Puppet::Node.indirection.terminus(:ldap)
- Puppet::Node.indirection.stubs(:terminus).returns ldap
- ldap.expects(:ldapsearch).with("(&(objectclass=puppetClient)(puppetclass=foo))")
+ it "should use a restrictive filter when searching for nodes in a class" do
+ ldap = Puppet::Node.indirection.terminus(:ldap)
+ Puppet::Node.indirection.stubs(:terminus).returns ldap
+ ldap.expects(:ldapsearch).with("(&(objectclass=puppetClient)(puppetclass=foo))")
- Puppet::Node.search "eh", :class => "foo"
- end
+ Puppet::Node.search "eh", :class => "foo"
+ end
end
diff --git a/spec/integration/indirector/report/rest_spec.rb b/spec/integration/indirector/report/rest_spec.rb
index 1ddced9..089f8fd 100644
--- a/spec/integration/indirector/report/rest_spec.rb
+++ b/spec/integration/indirector/report/rest_spec.rb
@@ -7,90 +7,90 @@ require 'puppet/network/server'
require 'puppet/network/http/webrick/rest'
describe "Report REST Terminus" do
- before do
- Puppet[:masterport] = 34343
- Puppet[:server] = "localhost"
-
- # Get a safe temporary file
- @tmpfile = Tempfile.new("webrick_integration_testing")
- @dir = @tmpfile.path + "_dir"
-
- Puppet.settings[:confdir] = @dir
- Puppet.settings[:vardir] = @dir
- Puppet.settings[:server] = "127.0.0.1"
- Puppet.settings[:masterport] = "34343"
-
- Puppet::Util::Cacher.expire
-
- Puppet[:servertype] = 'webrick'
- Puppet[:server] = '127.0.0.1'
- Puppet[:certname] = '127.0.0.1'
-
- # Generate the certificate with a local CA
- Puppet::SSL::Host.ca_location = :local
- ca = Puppet::SSL::CertificateAuthority.new
- ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname])
- ca.generate("foo.madstop.com") unless Puppet::SSL::Certificate.find(Puppet[:certname])
-
- @host = Puppet::SSL::Host.new(Puppet[:certname])
-
- @params = { :port => 34343, :handlers => [ :report ] }
- @server = Puppet::Network::Server.new(@params)
- @server.listen
-
- # Let's use REST for our reports :-)
- @old_terminus = Puppet::Transaction::Report.indirection.terminus_class
- Puppet::Transaction::Report.terminus_class = :rest
-
- # LAK:NOTE We need to have a fake model here so that our indirected methods get
- # passed through REST; otherwise we'd be stubbing 'save', which would cause an immediate
- # return.
- @report = stub_everything 'report'
- @mock_model = stub_everything 'faked model', :name => "report", :convert_from => @report
- Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
-
- Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization)
- end
-
- after do
- Puppet::Network::HttpPool.expire
- Puppet::SSL::Host.ca_location = :none
- Puppet.settings.clear
- @server.unlisten
- Puppet::Transaction::Report.terminus_class = @old_terminus
- end
-
- it "should be able to send a report to the server" do
- @report.expects(:save)
-
- report = Puppet::Transaction::Report.new
-
- resourcemetrics = {
- :total => 12,
- :out_of_sync => 20,
- :applied => 45,
- :skipped => 1,
- :restarted => 23,
- :failed_restarts => 1,
- :scheduled => 10
- }
- report.add_metric(:resources, resourcemetrics)
-
- timemetrics = {
- :resource1 => 10,
- :resource2 => 50,
- :resource3 => 40,
- :resource4 => 20,
- }
- report.add_metric(:times, timemetrics)
-
-
- report.add_metric(
- :changes,
+ before do
+ Puppet[:masterport] = 34343
+ Puppet[:server] = "localhost"
+
+ # Get a safe temporary file
+ @tmpfile = Tempfile.new("webrick_integration_testing")
+ @dir = @tmpfile.path + "_dir"
+
+ Puppet.settings[:confdir] = @dir
+ Puppet.settings[:vardir] = @dir
+ Puppet.settings[:server] = "127.0.0.1"
+ Puppet.settings[:masterport] = "34343"
+
+ Puppet::Util::Cacher.expire
+
+ Puppet[:servertype] = 'webrick'
+ Puppet[:server] = '127.0.0.1'
+ Puppet[:certname] = '127.0.0.1'
+
+ # Generate the certificate with a local CA
+ Puppet::SSL::Host.ca_location = :local
+ ca = Puppet::SSL::CertificateAuthority.new
+ ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname])
+ ca.generate("foo.madstop.com") unless Puppet::SSL::Certificate.find(Puppet[:certname])
+
+ @host = Puppet::SSL::Host.new(Puppet[:certname])
+
+ @params = { :port => 34343, :handlers => [ :report ] }
+ @server = Puppet::Network::Server.new(@params)
+ @server.listen
+
+ # Let's use REST for our reports :-)
+ @old_terminus = Puppet::Transaction::Report.indirection.terminus_class
+ Puppet::Transaction::Report.terminus_class = :rest
+
+ # LAK:NOTE We need to have a fake model here so that our indirected methods get
+ # passed through REST; otherwise we'd be stubbing 'save', which would cause an immediate
+ # return.
+ @report = stub_everything 'report'
+ @mock_model = stub_everything 'faked model', :name => "report", :convert_from => @report
+ Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
+
+ Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization)
+ end
+
+ after do
+ Puppet::Network::HttpPool.expire
+ Puppet::SSL::Host.ca_location = :none
+ Puppet.settings.clear
+ @server.unlisten
+ Puppet::Transaction::Report.terminus_class = @old_terminus
+ end
+
+ it "should be able to send a report to the server" do
+ @report.expects(:save)
+
+ report = Puppet::Transaction::Report.new
+
+ resourcemetrics = {
+ :total => 12,
+ :out_of_sync => 20,
+ :applied => 45,
+ :skipped => 1,
+ :restarted => 23,
+ :failed_restarts => 1,
+ :scheduled => 10
+ }
+ report.add_metric(:resources, resourcemetrics)
+
+ timemetrics = {
+ :resource1 => 10,
+ :resource2 => 50,
+ :resource3 => 40,
+ :resource4 => 20,
+ }
+ report.add_metric(:times, timemetrics)
+
+
+ report.add_metric(
+ :changes,
- :total => 20
- )
+ :total => 20
+ )
- report.save
- end
+ report.save
+ end
end
diff --git a/spec/integration/indirector/rest_spec.rb b/spec/integration/indirector/rest_spec.rb
index 57ace85..e904839 100755
--- a/spec/integration/indirector/rest_spec.rb
+++ b/spec/integration/indirector/rest_spec.rb
@@ -7,23 +7,23 @@ require 'puppet/indirector/rest'
# a fake class that will be indirected via REST
class Puppet::TestIndirectedFoo
- extend Puppet::Indirector
- indirects :test_indirected_foo, :terminus_setting => :test_indirected_foo_terminus
+ extend Puppet::Indirector
+ indirects :test_indirected_foo, :terminus_setting => :test_indirected_foo_terminus
- attr_reader :value
- attr_accessor :name
+ attr_reader :value
+ attr_accessor :name
- def initialize(value = 0)
- @value = value
- end
+ def initialize(value = 0)
+ @value = value
+ end
- def self.from_yaml(yaml)
- YAML.load(yaml)
- end
+ def self.from_yaml(yaml)
+ YAML.load(yaml)
+ end
- def name
- "bob"
- end
+ def name
+ "bob"
+ end
end
# empty Terminus class -- this would normally have to be in a directory findable by the autoloader, but we short-circuit that below
@@ -32,493 +32,493 @@ end
describe Puppet::Indirector::REST do
- before do
- # Get a safe temporary file
- @tmpfile = Tempfile.new("webrick_integration_testing")
- @dir = @tmpfile.path + "_dir"
+ before do
+ # Get a safe temporary file
+ @tmpfile = Tempfile.new("webrick_integration_testing")
+ @dir = @tmpfile.path + "_dir"
+
+ Puppet.settings[:confdir] = @dir
+ Puppet.settings[:vardir] = @dir
+ Puppet.settings[:server] = "127.0.0.1"
+ Puppet.settings[:masterport] = "34343"
+
+ Puppet::SSL::Host.ca_location = :local
+
+ Puppet::TestIndirectedFoo.terminus_class = :rest
+ end
+
+ after do
+ Puppet::Network::HttpPool.expire
+ Puppet::SSL::Host.ca_location = :none
+ Puppet.settings.clear
+ end
+
+ describe "when using webrick" do
+ before :each do
+ Puppet::Util::Cacher.expire
+
+ Puppet[:servertype] = 'webrick'
+ Puppet[:server] = '127.0.0.1'
+ Puppet[:certname] = '127.0.0.1'
+
+ ca = Puppet::SSL::CertificateAuthority.new
+ ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname])
+
+ @params = { :port => 34343, :handlers => [ :test_indirected_foo ], :xmlrpc_handlers => [ :status ] }
+ @server = Puppet::Network::Server.new(@params)
+ @server.listen
+
+ # LAK:NOTE We need to have a fake model here so that our indirected methods get
+ # passed through REST; otherwise we'd be stubbing 'find', which would cause an immediate
+ # return.
+ @mock_model = stub('faked model', :name => "foo")
+ Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
+
+ # do not trigger the authorization layer
+ Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization).returns(true)
+ end
+
+ describe "when finding a model instance over REST" do
+ describe "when a matching model instance can be found" do
+ before :each do
+ @model_instance = Puppet::TestIndirectedFoo.new(23)
+ @mock_model.stubs(:find).returns @model_instance
+ end
+
+ it "should not fail" do
+ lambda { Puppet::TestIndirectedFoo.find('bar') }.should_not raise_error
+ end
+
+ it 'should return an instance of the model class' do
+ Puppet::TestIndirectedFoo.find('bar').class.should == Puppet::TestIndirectedFoo
+ end
+
+ it "should pass options all the way through" do
+ @mock_model.expects(:find).with { |key, args| args[:one] == "two" and args[:three] == "four" }.returns @model_instance
+ Puppet::TestIndirectedFoo.find('bar', :one => "two", :three => "four")
+ end
+
+ it 'should return the instance of the model class associated with the provided lookup key' do
+ Puppet::TestIndirectedFoo.find('bar').value.should == @model_instance.value
+ end
+
+ it 'should set an expiration on model instance' do
+ Puppet::TestIndirectedFoo.find('bar').expiration.should_not be_nil
+ end
+
+ it "should use a supported format" do
+ Puppet::TestIndirectedFoo.expects(:supported_formats).returns ["marshal"]
+ text = Marshal.dump(@model_instance)
+ @model_instance.expects(:render).with(Puppet::Network::FormatHandler.format("marshal")).returns text
+ Puppet::TestIndirectedFoo.find('bar')
+ end
+ end
+
+ describe "when no matching model instance can be found" do
+ before :each do
+ @mock_model = stub('faked model', :name => "foo", :find => nil)
+ Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
+ end
+
+ it "should return nil" do
+ Puppet::TestIndirectedFoo.find('bar').should be_nil
+ end
+ end
+
+ describe "when an exception is encountered in looking up a model instance" do
+ before :each do
+ @mock_model = stub('faked model', :name => "foo")
+ @mock_model.stubs(:find).raises(RuntimeError)
+ Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
+ end
+
+ it "should raise an exception" do
+ lambda { Puppet::TestIndirectedFoo.find('bar') }.should raise_error(Net::HTTPError)
+ end
+ end
+ end
+
+ describe "when searching for model instances over REST" do
+ describe "when matching model instances can be found" do
+ before :each do
+ @model_instances = [ Puppet::TestIndirectedFoo.new(23), Puppet::TestIndirectedFoo.new(24) ]
+ @mock_model.stubs(:search).returns @model_instances
+
+ # Force yaml, because otherwise our mocks can't work correctly
+ Puppet::TestIndirectedFoo.stubs(:supported_formats).returns %w{yaml}
+
+ @mock_model.stubs(:render_multiple).returns @model_instances.to_yaml
+ end
+
+ it "should not fail" do
+ lambda { Puppet::TestIndirectedFoo.search('bar') }.should_not raise_error
+ end
+
+ it 'should return all matching results' do
+ Puppet::TestIndirectedFoo.search('bar').length.should == @model_instances.length
+ end
+
+ it "should pass options all the way through" do
+ @mock_model.expects(:search).with { |key, args| args[:one] == "two" and args[:three] == "four" }.returns @model_instances
+ Puppet::TestIndirectedFoo.search("foo", :one => "two", :three => "four")
+ end
+
+ it 'should return model instances' do
+ Puppet::TestIndirectedFoo.search('bar').each do |result|
+ result.class.should == Puppet::TestIndirectedFoo
+ end
+ end
+
+ it 'should return the instance of the model class associated with the provided lookup key' do
+ Puppet::TestIndirectedFoo.search('bar').collect { |i| i.value }.should == @model_instances.collect { |i| i.value }
+ end
+ end
+
+ describe "when no matching model instance can be found" do
+ before :each do
+ @mock_model = stub('faked model', :name => "foo", :find => nil)
+ Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
+ end
+
+ it "should return nil" do
+ Puppet::TestIndirectedFoo.find('bar').should be_nil
+ end
+ end
+
+ describe "when an exception is encountered in looking up a model instance" do
+ before :each do
+ @mock_model = stub('faked model')
+ @mock_model.stubs(:find).raises(RuntimeError)
+ Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
+ end
+
+ it "should raise an exception" do
+ lambda { Puppet::TestIndirectedFoo.find('bar') }.should raise_error(Net::HTTPError)
+ end
+ end
+ end
+
+ describe "when destroying a model instance over REST" do
+ describe "when a matching model instance can be found" do
+ before :each do
+ @mock_model.stubs(:destroy).returns true
+ end
+
+ it "should not fail" do
+ lambda { Puppet::TestIndirectedFoo.destroy('bar') }.should_not raise_error
+ end
+
+ it 'should return success' do
+ Puppet::TestIndirectedFoo.destroy('bar').should == true
+ end
+ end
+
+ describe "when no matching model instance can be found" do
+ before :each do
+ @mock_model.stubs(:destroy).returns false
+ end
+
+ it "should return failure" do
+ Puppet::TestIndirectedFoo.destroy('bar').should == false
+ end
+ end
+
+ describe "when an exception is encountered in destroying a model instance" do
+ before :each do
+ @mock_model.stubs(:destroy).raises(RuntimeError)
+ end
+
+ it "should raise an exception" do
+ lambda { Puppet::TestIndirectedFoo.destroy('bar') }.should raise_error(Net::HTTPError)
+ end
+ end
+ end
+
+ describe "when saving a model instance over REST" do
+ before :each do
+ @instance = Puppet::TestIndirectedFoo.new(42)
+ @mock_model.stubs(:save_object).returns @instance
+ @mock_model.stubs(:convert_from).returns @instance
+ Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:save_object).returns(@instance)
+ end
- Puppet.settings[:confdir] = @dir
- Puppet.settings[:vardir] = @dir
- Puppet.settings[:server] = "127.0.0.1"
- Puppet.settings[:masterport] = "34343"
+ describe "when a successful save can be performed" do
+ before :each do
+ end
+
+ it "should not fail" do
+ lambda { @instance.save }.should_not raise_error
+ end
- Puppet::SSL::Host.ca_location = :local
+ it 'should return an instance of the model class' do
+ @instance.save.class.should == Puppet::TestIndirectedFoo
+ end
- Puppet::TestIndirectedFoo.terminus_class = :rest
+ it 'should return a matching instance of the model class' do
+ @instance.save.value.should == @instance.value
+ end
+ end
+
+ describe "when a save cannot be completed" do
+ before :each do
+ Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:save_object).returns(false)
+ end
+
+ it "should return failure" do
+ @instance.save.should == false
+ end
+ end
+
+ describe "when an exception is encountered in performing a save" do
+ before :each do
+ Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:save_object).raises(RuntimeError)
+ end
+
+ it "should raise an exception" do
+ lambda { @instance.save }.should raise_error(Net::HTTPError)
+ end
+ end
+ end
+
+ after :each do
+ @server.unlisten
+ end
+ end
+
+ describe "when using mongrel" do
+ confine "Mongrel is not available" => Puppet.features.mongrel?
+
+ before :each do
+ Puppet[:servertype] = 'mongrel'
+ @params = { :port => 34343, :handlers => [ :test_indirected_foo ] }
+
+ # Make sure we never get a cert, since mongrel can't speak ssl
+ Puppet::SSL::Certificate.stubs(:find).returns nil
+
+ # We stub ssl to be off, since mongrel can't speak ssl
+ Net::HTTP.any_instance.stubs(:use_ssl?).returns false
+
+ @server = Puppet::Network::Server.new(@params)
+ @server.listen
+
+ # LAK:NOTE We need to have a fake model here so that our indirected methods get
+ # passed through REST; otherwise we'd be stubbing 'find', which would cause an immediate
+ # return.
+ @mock_model = stub('faked model', :name => "foo")
+ Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
+
+ # do not trigger the authorization layer
+ Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:check_authorization).returns(true)
end
after do
- Puppet::Network::HttpPool.expire
- Puppet::SSL::Host.ca_location = :none
- Puppet.settings.clear
+ @server.unlisten
end
- describe "when using webrick" do
+ describe "when finding a model instance over REST" do
+ describe "when a matching model instance can be found" do
+ before :each do
+ @model_instance = Puppet::TestIndirectedFoo.new(23)
+ @mock_model.stubs(:find).returns @model_instance
+ end
+
+ it "should not fail" do
+ lambda { Puppet::TestIndirectedFoo.find('bar') }.should_not raise_error
+ end
+
+ it 'should return an instance of the model class' do
+ Puppet::TestIndirectedFoo.find('bar').class.should == Puppet::TestIndirectedFoo
+ end
+
+ it "should pass options all the way through" do
+ @mock_model.expects(:find).with { |key, args| args[:one] == "two" and args[:three] == "four" }.returns @model_instance
+ Puppet::TestIndirectedFoo.find('bar', :one => "two", :three => "four")
+ end
+
+ it 'should return the instance of the model class associated with the provided lookup key' do
+ Puppet::TestIndirectedFoo.find('bar').value.should == @model_instance.value
+ end
+
+ it 'should set an expiration on model instance' do
+ Puppet::TestIndirectedFoo.find('bar').expiration.should_not be_nil
+ end
+
+ it "should use a supported format" do
+ Puppet::TestIndirectedFoo.expects(:supported_formats).returns ["marshal"]
+ format = stub 'format'
+ text = Marshal.dump(@model_instance)
+ @model_instance.expects(:render).with(Puppet::Network::FormatHandler.format("marshal")).returns text
+ Puppet::TestIndirectedFoo.find('bar')
+ end
+ end
+
+ describe "when no matching model instance can be found" do
+ before :each do
+ @mock_model.stubs(:find).returns nil
+ end
+
+ it "should return nil" do
+ Puppet::TestIndirectedFoo.find('bar').should be_nil
+ end
+ end
+
+ describe "when an exception is encountered in looking up a model instance" do
before :each do
- Puppet::Util::Cacher.expire
-
- Puppet[:servertype] = 'webrick'
- Puppet[:server] = '127.0.0.1'
- Puppet[:certname] = '127.0.0.1'
-
- ca = Puppet::SSL::CertificateAuthority.new
- ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname])
-
- @params = { :port => 34343, :handlers => [ :test_indirected_foo ], :xmlrpc_handlers => [ :status ] }
- @server = Puppet::Network::Server.new(@params)
- @server.listen
-
- # LAK:NOTE We need to have a fake model here so that our indirected methods get
- # passed through REST; otherwise we'd be stubbing 'find', which would cause an immediate
- # return.
- @mock_model = stub('faked model', :name => "foo")
- Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
-
- # do not trigger the authorization layer
- Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization).returns(true)
- end
-
- describe "when finding a model instance over REST" do
- describe "when a matching model instance can be found" do
- before :each do
- @model_instance = Puppet::TestIndirectedFoo.new(23)
- @mock_model.stubs(:find).returns @model_instance
- end
-
- it "should not fail" do
- lambda { Puppet::TestIndirectedFoo.find('bar') }.should_not raise_error
- end
-
- it 'should return an instance of the model class' do
- Puppet::TestIndirectedFoo.find('bar').class.should == Puppet::TestIndirectedFoo
- end
-
- it "should pass options all the way through" do
- @mock_model.expects(:find).with { |key, args| args[:one] == "two" and args[:three] == "four" }.returns @model_instance
- Puppet::TestIndirectedFoo.find('bar', :one => "two", :three => "four")
- end
-
- it 'should return the instance of the model class associated with the provided lookup key' do
- Puppet::TestIndirectedFoo.find('bar').value.should == @model_instance.value
- end
-
- it 'should set an expiration on model instance' do
- Puppet::TestIndirectedFoo.find('bar').expiration.should_not be_nil
- end
-
- it "should use a supported format" do
- Puppet::TestIndirectedFoo.expects(:supported_formats).returns ["marshal"]
- text = Marshal.dump(@model_instance)
- @model_instance.expects(:render).with(Puppet::Network::FormatHandler.format("marshal")).returns text
- Puppet::TestIndirectedFoo.find('bar')
- end
- end
-
- describe "when no matching model instance can be found" do
- before :each do
- @mock_model = stub('faked model', :name => "foo", :find => nil)
- Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
- end
-
- it "should return nil" do
- Puppet::TestIndirectedFoo.find('bar').should be_nil
- end
- end
-
- describe "when an exception is encountered in looking up a model instance" do
- before :each do
- @mock_model = stub('faked model', :name => "foo")
- @mock_model.stubs(:find).raises(RuntimeError)
- Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
- end
-
- it "should raise an exception" do
- lambda { Puppet::TestIndirectedFoo.find('bar') }.should raise_error(Net::HTTPError)
- end
- end
- end
-
- describe "when searching for model instances over REST" do
- describe "when matching model instances can be found" do
- before :each do
- @model_instances = [ Puppet::TestIndirectedFoo.new(23), Puppet::TestIndirectedFoo.new(24) ]
- @mock_model.stubs(:search).returns @model_instances
-
- # Force yaml, because otherwise our mocks can't work correctly
- Puppet::TestIndirectedFoo.stubs(:supported_formats).returns %w{yaml}
-
- @mock_model.stubs(:render_multiple).returns @model_instances.to_yaml
- end
-
- it "should not fail" do
- lambda { Puppet::TestIndirectedFoo.search('bar') }.should_not raise_error
- end
-
- it 'should return all matching results' do
- Puppet::TestIndirectedFoo.search('bar').length.should == @model_instances.length
- end
-
- it "should pass options all the way through" do
- @mock_model.expects(:search).with { |key, args| args[:one] == "two" and args[:three] == "four" }.returns @model_instances
- Puppet::TestIndirectedFoo.search("foo", :one => "two", :three => "four")
- end
-
- it 'should return model instances' do
- Puppet::TestIndirectedFoo.search('bar').each do |result|
- result.class.should == Puppet::TestIndirectedFoo
- end
- end
-
- it 'should return the instance of the model class associated with the provided lookup key' do
- Puppet::TestIndirectedFoo.search('bar').collect { |i| i.value }.should == @model_instances.collect { |i| i.value }
- end
- end
-
- describe "when no matching model instance can be found" do
- before :each do
- @mock_model = stub('faked model', :name => "foo", :find => nil)
- Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
- end
-
- it "should return nil" do
- Puppet::TestIndirectedFoo.find('bar').should be_nil
- end
- end
-
- describe "when an exception is encountered in looking up a model instance" do
- before :each do
- @mock_model = stub('faked model')
- @mock_model.stubs(:find).raises(RuntimeError)
- Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
- end
-
- it "should raise an exception" do
- lambda { Puppet::TestIndirectedFoo.find('bar') }.should raise_error(Net::HTTPError)
- end
- end
- end
-
- describe "when destroying a model instance over REST" do
- describe "when a matching model instance can be found" do
- before :each do
- @mock_model.stubs(:destroy).returns true
- end
-
- it "should not fail" do
- lambda { Puppet::TestIndirectedFoo.destroy('bar') }.should_not raise_error
- end
-
- it 'should return success' do
- Puppet::TestIndirectedFoo.destroy('bar').should == true
- end
- end
-
- describe "when no matching model instance can be found" do
- before :each do
- @mock_model.stubs(:destroy).returns false
- end
-
- it "should return failure" do
- Puppet::TestIndirectedFoo.destroy('bar').should == false
- end
- end
-
- describe "when an exception is encountered in destroying a model instance" do
- before :each do
- @mock_model.stubs(:destroy).raises(RuntimeError)
- end
-
- it "should raise an exception" do
- lambda { Puppet::TestIndirectedFoo.destroy('bar') }.should raise_error(Net::HTTPError)
- end
- end
- end
-
- describe "when saving a model instance over REST" do
- before :each do
- @instance = Puppet::TestIndirectedFoo.new(42)
- @mock_model.stubs(:save_object).returns @instance
- @mock_model.stubs(:convert_from).returns @instance
- Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:save_object).returns(@instance)
- end
-
- describe "when a successful save can be performed" do
- before :each do
- end
-
- it "should not fail" do
- lambda { @instance.save }.should_not raise_error
- end
-
- it 'should return an instance of the model class' do
- @instance.save.class.should == Puppet::TestIndirectedFoo
- end
-
- it 'should return a matching instance of the model class' do
- @instance.save.value.should == @instance.value
- end
- end
-
- describe "when a save cannot be completed" do
- before :each do
- Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:save_object).returns(false)
- end
-
- it "should return failure" do
- @instance.save.should == false
- end
- end
-
- describe "when an exception is encountered in performing a save" do
- before :each do
- Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:save_object).raises(RuntimeError)
- end
-
- it "should raise an exception" do
- lambda { @instance.save }.should raise_error(Net::HTTPError)
- end
- end
- end
-
- after :each do
- @server.unlisten
+ @mock_model.stubs(:find).raises(RuntimeError)
end
+
+ it "should raise an exception" do
+ lambda { Puppet::TestIndirectedFoo.find('bar') }.should raise_error(Net::HTTPError)
+ end
+ end
end
- describe "when using mongrel" do
- confine "Mongrel is not available" => Puppet.features.mongrel?
+ describe "when searching for model instances over REST" do
+ describe "when matching model instances can be found" do
+ before :each do
+ @model_instances = [ Puppet::TestIndirectedFoo.new(23), Puppet::TestIndirectedFoo.new(24) ]
+
+ # Force yaml, because otherwise our mocks can't work correctly
+ Puppet::TestIndirectedFoo.stubs(:supported_formats).returns %w{yaml}
+
+ @mock_model.stubs(:search).returns @model_instances
+ @mock_model.stubs(:render_multiple).returns @model_instances.to_yaml
+ end
+ it "should not fail" do
+ lambda { Puppet::TestIndirectedFoo.search('bar') }.should_not raise_error
+ end
+
+ it 'should return all matching results' do
+ Puppet::TestIndirectedFoo.search('bar').length.should == @model_instances.length
+ end
+
+ it "should pass options all the way through" do
+ @mock_model.expects(:search).with { |key, args| args[:one] == "two" and args[:three] == "four" }.returns @model_instances
+ Puppet::TestIndirectedFoo.search('bar', :one => "two", :three => "four")
+ end
+
+ it 'should return model instances' do
+ Puppet::TestIndirectedFoo.search('bar').each do |result|
+ result.class.should == Puppet::TestIndirectedFoo
+ end
+ end
+
+ it 'should return the instance of the model class associated with the provided lookup key' do
+ Puppet::TestIndirectedFoo.search('bar').collect { |i| i.value }.should == @model_instances.collect { |i| i.value }
+ end
+
+ it 'should set an expiration on model instances' do
+ Puppet::TestIndirectedFoo.search('bar').each do |result|
+ result.expiration.should_not be_nil
+ end
+ end
+ end
+
+ describe "when no matching model instance can be found" do
+ before :each do
+ @mock_model.stubs(:search).returns nil
+ @mock_model.stubs(:render_multiple).returns nil.to_yaml
+ end
+
+ it "should return nil" do
+ Puppet::TestIndirectedFoo.search('bar').should == []
+ end
+ end
+
+ describe "when an exception is encountered in looking up a model instance" do
before :each do
- Puppet[:servertype] = 'mongrel'
- @params = { :port => 34343, :handlers => [ :test_indirected_foo ] }
+ @mock_model.stubs(:find).raises(RuntimeError)
+ end
+
+ it "should raise an exception" do
+ lambda { Puppet::TestIndirectedFoo.find('bar') }.should raise_error(Net::HTTPError)
+ end
+ end
+ end
- # Make sure we never get a cert, since mongrel can't speak ssl
- Puppet::SSL::Certificate.stubs(:find).returns nil
+ describe "when destroying a model instance over REST" do
+ describe "when a matching model instance can be found" do
+ before :each do
+ @mock_model.stubs(:destroy).returns true
+ end
- # We stub ssl to be off, since mongrel can't speak ssl
- Net::HTTP.any_instance.stubs(:use_ssl?).returns false
+ it "should not fail" do
+ lambda { Puppet::TestIndirectedFoo.destroy('bar') }.should_not raise_error
+ end
+
+ it 'should return success' do
+ Puppet::TestIndirectedFoo.destroy('bar').should == true
+ end
+ end
+
+ describe "when no matching model instance can be found" do
+ before :each do
+ @mock_model.stubs(:destroy).returns false
+ end
+
+ it "should return failure" do
+ Puppet::TestIndirectedFoo.destroy('bar').should == false
+ end
+ end
+
+ describe "when an exception is encountered in destroying a model instance" do
+ before :each do
+ @mock_model.stubs(:destroy).raises(RuntimeError)
+ end
+
+ it "should raise an exception" do
+ lambda { Puppet::TestIndirectedFoo.destroy('bar') }.should raise_error(Net::HTTPError)
+ end
+ end
+ end
+
+ describe "when saving a model instance over REST" do
+ before :each do
+ @instance = Puppet::TestIndirectedFoo.new(42)
+ @mock_model.stubs(:convert_from).returns @instance
+
+ # LAK:NOTE This stub is necessary to prevent the REST call from calling
+ # REST.save again, thus producing painful infinite recursion.
+ Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:save_object).returns(@instance)
+ end
+
+ describe "when a successful save can be performed" do
+ before :each do
+ end
+
+ it "should not fail" do
+ lambda { @instance.save }.should_not raise_error
+ end
+
+ it 'should return an instance of the model class' do
+ @instance.save.class.should == Puppet::TestIndirectedFoo
+ end
+
+ it 'should return a matching instance of the model class' do
+ @instance.save.value.should == @instance.value
+ end
+ end
+
+ describe "when a save cannot be completed" do
+ before :each do
+ Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:save_object).returns(false)
+ end
+
+ it "should return failure" do
+ @instance.save.should == false
+ end
+ end
+
+ describe "when an exception is encountered in performing a save" do
+ before :each do
+ Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:save_object).raises(RuntimeError)
+ end
- @server = Puppet::Network::Server.new(@params)
- @server.listen
-
- # LAK:NOTE We need to have a fake model here so that our indirected methods get
- # passed through REST; otherwise we'd be stubbing 'find', which would cause an immediate
- # return.
- @mock_model = stub('faked model', :name => "foo")
- Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
-
- # do not trigger the authorization layer
- Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:check_authorization).returns(true)
- end
-
- after do
- @server.unlisten
- end
-
- describe "when finding a model instance over REST" do
- describe "when a matching model instance can be found" do
- before :each do
- @model_instance = Puppet::TestIndirectedFoo.new(23)
- @mock_model.stubs(:find).returns @model_instance
- end
-
- it "should not fail" do
- lambda { Puppet::TestIndirectedFoo.find('bar') }.should_not raise_error
- end
-
- it 'should return an instance of the model class' do
- Puppet::TestIndirectedFoo.find('bar').class.should == Puppet::TestIndirectedFoo
- end
-
- it "should pass options all the way through" do
- @mock_model.expects(:find).with { |key, args| args[:one] == "two" and args[:three] == "four" }.returns @model_instance
- Puppet::TestIndirectedFoo.find('bar', :one => "two", :three => "four")
- end
-
- it 'should return the instance of the model class associated with the provided lookup key' do
- Puppet::TestIndirectedFoo.find('bar').value.should == @model_instance.value
- end
-
- it 'should set an expiration on model instance' do
- Puppet::TestIndirectedFoo.find('bar').expiration.should_not be_nil
- end
-
- it "should use a supported format" do
- Puppet::TestIndirectedFoo.expects(:supported_formats).returns ["marshal"]
- format = stub 'format'
- text = Marshal.dump(@model_instance)
- @model_instance.expects(:render).with(Puppet::Network::FormatHandler.format("marshal")).returns text
- Puppet::TestIndirectedFoo.find('bar')
- end
- end
-
- describe "when no matching model instance can be found" do
- before :each do
- @mock_model.stubs(:find).returns nil
- end
-
- it "should return nil" do
- Puppet::TestIndirectedFoo.find('bar').should be_nil
- end
- end
-
- describe "when an exception is encountered in looking up a model instance" do
- before :each do
- @mock_model.stubs(:find).raises(RuntimeError)
- end
-
- it "should raise an exception" do
- lambda { Puppet::TestIndirectedFoo.find('bar') }.should raise_error(Net::HTTPError)
- end
- end
- end
-
- describe "when searching for model instances over REST" do
- describe "when matching model instances can be found" do
- before :each do
- @model_instances = [ Puppet::TestIndirectedFoo.new(23), Puppet::TestIndirectedFoo.new(24) ]
-
- # Force yaml, because otherwise our mocks can't work correctly
- Puppet::TestIndirectedFoo.stubs(:supported_formats).returns %w{yaml}
-
- @mock_model.stubs(:search).returns @model_instances
- @mock_model.stubs(:render_multiple).returns @model_instances.to_yaml
- end
-
- it "should not fail" do
- lambda { Puppet::TestIndirectedFoo.search('bar') }.should_not raise_error
- end
-
- it 'should return all matching results' do
- Puppet::TestIndirectedFoo.search('bar').length.should == @model_instances.length
- end
-
- it "should pass options all the way through" do
- @mock_model.expects(:search).with { |key, args| args[:one] == "two" and args[:three] == "four" }.returns @model_instances
- Puppet::TestIndirectedFoo.search('bar', :one => "two", :three => "four")
- end
-
- it 'should return model instances' do
- Puppet::TestIndirectedFoo.search('bar').each do |result|
- result.class.should == Puppet::TestIndirectedFoo
- end
- end
-
- it 'should return the instance of the model class associated with the provided lookup key' do
- Puppet::TestIndirectedFoo.search('bar').collect { |i| i.value }.should == @model_instances.collect { |i| i.value }
- end
-
- it 'should set an expiration on model instances' do
- Puppet::TestIndirectedFoo.search('bar').each do |result|
- result.expiration.should_not be_nil
- end
- end
- end
-
- describe "when no matching model instance can be found" do
- before :each do
- @mock_model.stubs(:search).returns nil
- @mock_model.stubs(:render_multiple).returns nil.to_yaml
- end
-
- it "should return nil" do
- Puppet::TestIndirectedFoo.search('bar').should == []
- end
- end
-
- describe "when an exception is encountered in looking up a model instance" do
- before :each do
- @mock_model.stubs(:find).raises(RuntimeError)
- end
-
- it "should raise an exception" do
- lambda { Puppet::TestIndirectedFoo.find('bar') }.should raise_error(Net::HTTPError)
- end
- end
- end
-
- describe "when destroying a model instance over REST" do
- describe "when a matching model instance can be found" do
- before :each do
- @mock_model.stubs(:destroy).returns true
- end
-
- it "should not fail" do
- lambda { Puppet::TestIndirectedFoo.destroy('bar') }.should_not raise_error
- end
-
- it 'should return success' do
- Puppet::TestIndirectedFoo.destroy('bar').should == true
- end
- end
-
- describe "when no matching model instance can be found" do
- before :each do
- @mock_model.stubs(:destroy).returns false
- end
-
- it "should return failure" do
- Puppet::TestIndirectedFoo.destroy('bar').should == false
- end
- end
-
- describe "when an exception is encountered in destroying a model instance" do
- before :each do
- @mock_model.stubs(:destroy).raises(RuntimeError)
- end
-
- it "should raise an exception" do
- lambda { Puppet::TestIndirectedFoo.destroy('bar') }.should raise_error(Net::HTTPError)
- end
- end
- end
-
- describe "when saving a model instance over REST" do
- before :each do
- @instance = Puppet::TestIndirectedFoo.new(42)
- @mock_model.stubs(:convert_from).returns @instance
-
- # LAK:NOTE This stub is necessary to prevent the REST call from calling
- # REST.save again, thus producing painful infinite recursion.
- Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:save_object).returns(@instance)
- end
-
- describe "when a successful save can be performed" do
- before :each do
- end
-
- it "should not fail" do
- lambda { @instance.save }.should_not raise_error
- end
-
- it 'should return an instance of the model class' do
- @instance.save.class.should == Puppet::TestIndirectedFoo
- end
-
- it 'should return a matching instance of the model class' do
- @instance.save.value.should == @instance.value
- end
- end
-
- describe "when a save cannot be completed" do
- before :each do
- Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:save_object).returns(false)
- end
-
- it "should return failure" do
- @instance.save.should == false
- end
- end
-
- describe "when an exception is encountered in performing a save" do
- before :each do
- Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:save_object).raises(RuntimeError)
- end
-
- it "should raise an exception" do
- lambda { @instance.save }.should raise_error(Net::HTTPError)
- end
- end
+ it "should raise an exception" do
+ lambda { @instance.save }.should raise_error(Net::HTTPError)
end
+ end
end
+ end
end
diff --git a/spec/integration/network/client_spec.rb b/spec/integration/network/client_spec.rb
index 06d145a..4bf3ad8 100755
--- a/spec/integration/network/client_spec.rb
+++ b/spec/integration/network/client_spec.rb
@@ -5,15 +5,15 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/network/client'
describe Puppet::Network::Client do
- %w{ca file report runner status}.each do |name|
- it "should have a #{name} client" do
- Puppet::Network::Client.client(name).should be_instance_of(Class)
- end
+ %w{ca file report runner status}.each do |name|
+ it "should have a #{name} client" do
+ Puppet::Network::Client.client(name).should be_instance_of(Class)
+ end
- [:name, :handler, :drivername].each do |data|
- it "should have a #{data} value for the #{name} client" do
- Puppet::Network::Client.client(name).send(data).should_not be_nil
- end
- end
+ [:name, :handler, :drivername].each do |data|
+ it "should have a #{data} value for the #{name} client" do
+ Puppet::Network::Client.client(name).send(data).should_not be_nil
+ end
end
+ end
end
diff --git a/spec/integration/network/formats_spec.rb b/spec/integration/network/formats_spec.rb
index 35e7977..e6cf28a 100755
--- a/spec/integration/network/formats_spec.rb
+++ b/spec/integration/network/formats_spec.rb
@@ -5,106 +5,106 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/network/formats'
class PsonIntTest
- attr_accessor :string
- def ==(other)
- other.class == self.class and string == other.string
- end
-
- def self.from_pson(data)
- new(data[0])
- end
-
- def initialize(string)
- @string = string
- end
-
- def to_pson(*args)
- {
- 'type' => self.class.name,
- 'data' => [@string]
- }.to_pson(*args)
- end
-
- def self.canonical_order(s)
- s.gsub(/\{"data":\[(.*?)\],"type":"PsonIntTest"\}/,'{"type":"PsonIntTest","data":[\1]}')
- end
+ attr_accessor :string
+ def ==(other)
+ other.class == self.class and string == other.string
+ end
+
+ def self.from_pson(data)
+ new(data[0])
+ end
+
+ def initialize(string)
+ @string = string
+ end
+
+ def to_pson(*args)
+ {
+ 'type' => self.class.name,
+ 'data' => [@string]
+ }.to_pson(*args)
+ end
+
+ def self.canonical_order(s)
+ s.gsub(/\{"data":\[(.*?)\],"type":"PsonIntTest"\}/,'{"type":"PsonIntTest","data":[\1]}')
+ end
end
describe Puppet::Network::FormatHandler.format(:s) do
- before do
- @format = Puppet::Network::FormatHandler.format(:s)
- end
+ before do
+ @format = Puppet::Network::FormatHandler.format(:s)
+ end
- it "should support certificates" do
- @format.should be_supported(Puppet::SSL::Certificate)
- end
+ it "should support certificates" do
+ @format.should be_supported(Puppet::SSL::Certificate)
+ end
- it "should not support catalogs" do
- @format.should_not be_supported(Puppet::Resource::Catalog)
- end
+ it "should not support catalogs" do
+ @format.should_not be_supported(Puppet::Resource::Catalog)
+ end
end
describe Puppet::Network::FormatHandler.format(:pson) do
- describe "when pson is absent" do
- confine "'pson' library is present" => (! Puppet.features.pson?)
+ describe "when pson is absent" do
+ confine "'pson' library is present" => (! Puppet.features.pson?)
- before do
- @pson = Puppet::Network::FormatHandler.format(:pson)
- end
+ before do
+ @pson = Puppet::Network::FormatHandler.format(:pson)
+ end
- it "should not be suitable" do
- @pson.should_not be_suitable
- end
+ it "should not be suitable" do
+ @pson.should_not be_suitable
end
+ end
- describe "when pson is available" do
- confine "Missing 'pson' library" => Puppet.features.pson?
+ describe "when pson is available" do
+ confine "Missing 'pson' library" => Puppet.features.pson?
- before do
- @pson = Puppet::Network::FormatHandler.format(:pson)
- end
+ before do
+ @pson = Puppet::Network::FormatHandler.format(:pson)
+ end
- it "should be able to render an instance to pson" do
- instance = PsonIntTest.new("foo")
- PsonIntTest.canonical_order(@pson.render(instance)).should == PsonIntTest.canonical_order('{"type":"PsonIntTest","data":["foo"]}' )
- end
+ it "should be able to render an instance to pson" do
+ instance = PsonIntTest.new("foo")
+ PsonIntTest.canonical_order(@pson.render(instance)).should == PsonIntTest.canonical_order('{"type":"PsonIntTest","data":["foo"]}' )
+ end
- it "should be able to render arrays to pson" do
- @pson.render([1,2]).should == '[1,2]'
- end
+ it "should be able to render arrays to pson" do
+ @pson.render([1,2]).should == '[1,2]'
+ end
- it "should be able to render arrays containing hashes to pson" do
- @pson.render([{"one"=>1},{"two"=>2}]).should == '[{"one":1},{"two":2}]'
- end
+ it "should be able to render arrays containing hashes to pson" do
+ @pson.render([{"one"=>1},{"two"=>2}]).should == '[{"one":1},{"two":2}]'
+ end
- it "should be able to render multiple instances to pson" do
- Puppet.features.add(:pson, :libs => ["pson"])
+ it "should be able to render multiple instances to pson" do
+ Puppet.features.add(:pson, :libs => ["pson"])
- one = PsonIntTest.new("one")
- two = PsonIntTest.new("two")
+ one = PsonIntTest.new("one")
+ two = PsonIntTest.new("two")
- PsonIntTest.canonical_order(@pson.render([one,two])).should == PsonIntTest.canonical_order('[{"type":"PsonIntTest","data":["one"]},{"type":"PsonIntTest","data":["two"]}]')
- end
+ PsonIntTest.canonical_order(@pson.render([one,two])).should == PsonIntTest.canonical_order('[{"type":"PsonIntTest","data":["one"]},{"type":"PsonIntTest","data":["two"]}]')
+ end
- it "should be able to intern pson into an instance" do
- @pson.intern(PsonIntTest, '{"type":"PsonIntTest","data":["foo"]}').should == PsonIntTest.new("foo")
- end
+ it "should be able to intern pson into an instance" do
+ @pson.intern(PsonIntTest, '{"type":"PsonIntTest","data":["foo"]}').should == PsonIntTest.new("foo")
+ end
- it "should be able to intern pson with no class information into an instance" do
- @pson.intern(PsonIntTest, '["foo"]').should == PsonIntTest.new("foo")
- end
+ it "should be able to intern pson with no class information into an instance" do
+ @pson.intern(PsonIntTest, '["foo"]').should == PsonIntTest.new("foo")
+ end
- it "should be able to intern multiple instances from pson" do
- @pson.intern_multiple(PsonIntTest, '[{"type": "PsonIntTest", "data": ["one"]},{"type": "PsonIntTest", "data": ["two"]}]').should == [
- PsonIntTest.new("one"), PsonIntTest.new("two")
- ]
- end
+ it "should be able to intern multiple instances from pson" do
+ @pson.intern_multiple(PsonIntTest, '[{"type": "PsonIntTest", "data": ["one"]},{"type": "PsonIntTest", "data": ["two"]}]').should == [
+ PsonIntTest.new("one"), PsonIntTest.new("two")
+ ]
+ end
- it "should be able to intern multiple instances from pson with no class information" do
- @pson.intern_multiple(PsonIntTest, '[["one"],["two"]]').should == [
- PsonIntTest.new("one"), PsonIntTest.new("two")
- ]
- end
+ it "should be able to intern multiple instances from pson with no class information" do
+ @pson.intern_multiple(PsonIntTest, '[["one"],["two"]]').should == [
+ PsonIntTest.new("one"), PsonIntTest.new("two")
+ ]
end
+ end
end
diff --git a/spec/integration/network/handler_spec.rb b/spec/integration/network/handler_spec.rb
index 1c2e605..021f1ce 100755
--- a/spec/integration/network/handler_spec.rb
+++ b/spec/integration/network/handler_spec.rb
@@ -5,21 +5,21 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/network/client'
describe Puppet::Network::Handler do
- %w{ca filebucket fileserver master report runner status}.each do |name|
- it "should have a #{name} client" do
- Puppet::Network::Handler.handler(name).should be_instance_of(Class)
- end
+ %w{ca filebucket fileserver master report runner status}.each do |name|
+ it "should have a #{name} client" do
+ Puppet::Network::Handler.handler(name).should be_instance_of(Class)
+ end
- it "should have a name" do
- Puppet::Network::Handler.handler(name).name.to_s.downcase.should == name.to_s.downcase
- end
+ it "should have a name" do
+ Puppet::Network::Handler.handler(name).name.to_s.downcase.should == name.to_s.downcase
+ end
- it "should have an interface" do
- Puppet::Network::Handler.handler(name).interface.should_not be_nil
- end
+ it "should have an interface" do
+ Puppet::Network::Handler.handler(name).interface.should_not be_nil
+ end
- it "should have a prefix for the interface" do
- Puppet::Network::Handler.handler(name).interface.prefix.should_not be_nil
- end
+ it "should have a prefix for the interface" do
+ Puppet::Network::Handler.handler(name).interface.prefix.should_not be_nil
end
+ end
end
diff --git a/spec/integration/network/server/mongrel_spec.rb b/spec/integration/network/server/mongrel_spec.rb
index 1365fbd..cc90773 100755
--- a/spec/integration/network/server/mongrel_spec.rb
+++ b/spec/integration/network/server/mongrel_spec.rb
@@ -5,62 +5,62 @@ require 'puppet/network/server'
require 'socket'
describe Puppet::Network::Server do
- describe "when using mongrel" do
- confine "Mongrel is not available" => Puppet.features.mongrel?
+ describe "when using mongrel" do
+ confine "Mongrel is not available" => Puppet.features.mongrel?
- before :each do
- Puppet[:servertype] = 'mongrel'
- Puppet[:server] = '127.0.0.1'
- @params = { :port => 34346, :handlers => [ :node ] }
- @server = Puppet::Network::Server.new(@params)
- end
+ before :each do
+ Puppet[:servertype] = 'mongrel'
+ Puppet[:server] = '127.0.0.1'
+ @params = { :port => 34346, :handlers => [ :node ] }
+ @server = Puppet::Network::Server.new(@params)
+ end
- after { Puppet.settings.clear }
+ after { Puppet.settings.clear }
- describe "before listening" do
- it "should not be reachable at the specified address and port" do
- lambda { TCPSocket.new('127.0.0.1', 34346) }.should raise_error(Errno::ECONNREFUSED)
- end
- end
+ describe "before listening" do
+ it "should not be reachable at the specified address and port" do
+ lambda { TCPSocket.new('127.0.0.1', 34346) }.should raise_error(Errno::ECONNREFUSED)
+ end
+ end
- describe "when listening" do
- it "should be reachable on the specified address and port" do
- @server.listen
- lambda { TCPSocket.new('127.0.0.1', 34346) }.should_not raise_error
- end
+ describe "when listening" do
+ it "should be reachable on the specified address and port" do
+ @server.listen
+ lambda { TCPSocket.new('127.0.0.1', 34346) }.should_not raise_error
+ end
- it "should default to '127.0.0.1' as its bind address" do
- @server = Puppet::Network::Server.new(@params.merge(:port => 34343))
- @server.stubs(:unlisten) # we're breaking listening internally, so we have to keep it from unlistening
- @server.send(:http_server).expects(:listen).with { |args| args[:address] == "127.0.0.1" }
- @server.listen
- end
+ it "should default to '127.0.0.1' as its bind address" do
+ @server = Puppet::Network::Server.new(@params.merge(:port => 34343))
+ @server.stubs(:unlisten) # we're breaking listening internally, so we have to keep it from unlistening
+ @server.send(:http_server).expects(:listen).with { |args| args[:address] == "127.0.0.1" }
+ @server.listen
+ end
- it "should use any specified bind address" do
- Puppet[:bindaddress] = "0.0.0.0"
- @server = Puppet::Network::Server.new(@params.merge(:port => 34343))
- @server.stubs(:unlisten) # we're breaking listening internally, so we have to keep it from unlistening
- @server.send(:http_server).expects(:listen).with { |args| args[:address] == "0.0.0.0" }
- @server.listen
- end
+ it "should use any specified bind address" do
+ Puppet[:bindaddress] = "0.0.0.0"
+ @server = Puppet::Network::Server.new(@params.merge(:port => 34343))
+ @server.stubs(:unlisten) # we're breaking listening internally, so we have to keep it from unlistening
+ @server.send(:http_server).expects(:listen).with { |args| args[:address] == "0.0.0.0" }
+ @server.listen
+ end
- it "should not allow multiple servers to listen on the same address and port" do
- @server.listen
- @server2 = Puppet::Network::Server.new(@params)
- lambda { @server2.listen }.should raise_error
- end
- end
+ it "should not allow multiple servers to listen on the same address and port" do
+ @server.listen
+ @server2 = Puppet::Network::Server.new(@params)
+ lambda { @server2.listen }.should raise_error
+ end
+ end
- describe "after unlistening" do
- it "should not be reachable on the port and address assigned" do
- @server.listen
- @server.unlisten
- lambda { TCPSocket.new('127.0.0.1', 34346) }.should raise_error(Errno::ECONNREFUSED)
- end
- end
+ describe "after unlistening" do
+ it "should not be reachable on the port and address assigned" do
+ @server.listen
+ @server.unlisten
+ lambda { TCPSocket.new('127.0.0.1', 34346) }.should raise_error(Errno::ECONNREFUSED)
+ end
+ end
- after :each do
- @server.unlisten if @server.listening?
- end
+ after :each do
+ @server.unlisten if @server.listening?
end
+ end
end
diff --git a/spec/integration/network/server/webrick_spec.rb b/spec/integration/network/server/webrick_spec.rb
index 50994f1..2809df7 100755
--- a/spec/integration/network/server/webrick_spec.rb
+++ b/spec/integration/network/server/webrick_spec.rb
@@ -6,80 +6,80 @@ require 'puppet/ssl/certificate_authority'
require 'socket'
describe Puppet::Network::Server do
- describe "when using webrick" do
- before :each do
- Puppet[:servertype] = 'webrick'
- Puppet[:server] = '127.0.0.1'
- @params = { :port => 34343, :handlers => [ :node ], :xmlrpc_handlers => [ :status ] }
-
- # Get a safe temporary file
- @tmpfile = Tempfile.new("webrick_integration_testing")
- @dir = @tmpfile.path + "_dir"
-
- Puppet.settings[:confdir] = @dir
- Puppet.settings[:vardir] = @dir
-
- Puppet::SSL::Host.ca_location = :local
-
- ca = Puppet::SSL::CertificateAuthority.new
- ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname])
- end
-
- after do
- @tmpfile.delete
- Puppet.settings.clear
-
- system("rm -rf #{@dir}")
-
- Puppet::Util::Cacher.expire
- end
-
- describe "before listening" do
- it "should not be reachable at the specified address and port" do
- lambda { TCPSocket.new('127.0.0.1', 34343) }.should raise_error
- end
- end
-
- describe "when listening" do
- it "should be reachable on the specified address and port" do
- @server = Puppet::Network::Server.new(@params.merge(:port => 34343))
- @server.listen
- lambda { TCPSocket.new('127.0.0.1', 34343) }.should_not raise_error
- end
-
- it "should default to '0.0.0.0' as its bind address" do
- Puppet.settings.clear
- Puppet[:servertype] = 'webrick'
- Puppet[:bindaddress].should == '0.0.0.0'
- end
-
- it "should use any specified bind address" do
- Puppet[:bindaddress] = "127.0.0.1"
- @server = Puppet::Network::Server.new(@params.merge(:port => 34343))
- @server.stubs(:unlisten) # we're breaking listening internally, so we have to keep it from unlistening
- @server.send(:http_server).expects(:listen).with { |args| args[:address] == "127.0.0.1" }
- @server.listen
- end
-
- it "should not allow multiple servers to listen on the same address and port" do
- @server = Puppet::Network::Server.new(@params.merge(:port => 34343))
- @server.listen
- @server2 = Puppet::Network::Server.new(@params.merge(:port => 34343))
- lambda { @server2.listen }.should raise_error
- end
-
- after :each do
- @server.unlisten if @server && @server.listening?
- end
- end
-
- describe "after unlistening" do
- it "should not be reachable on the port and address assigned" do
- @server = Puppet::Network::Server.new(@params.merge(:port => 34343))
- @server.listen
- @server.unlisten
- lambda { TCPSocket.new('127.0.0.1', 34343) }.should raise_error(Errno::ECONNREFUSED)
- end
- end
+ describe "when using webrick" do
+ before :each do
+ Puppet[:servertype] = 'webrick'
+ Puppet[:server] = '127.0.0.1'
+ @params = { :port => 34343, :handlers => [ :node ], :xmlrpc_handlers => [ :status ] }
+
+ # Get a safe temporary file
+ @tmpfile = Tempfile.new("webrick_integration_testing")
+ @dir = @tmpfile.path + "_dir"
+
+ Puppet.settings[:confdir] = @dir
+ Puppet.settings[:vardir] = @dir
+
+ Puppet::SSL::Host.ca_location = :local
+
+ ca = Puppet::SSL::CertificateAuthority.new
+ ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname])
+ end
+
+ after do
+ @tmpfile.delete
+ Puppet.settings.clear
+
+ system("rm -rf #{@dir}")
+
+ Puppet::Util::Cacher.expire
+ end
+
+ describe "before listening" do
+ it "should not be reachable at the specified address and port" do
+ lambda { TCPSocket.new('127.0.0.1', 34343) }.should raise_error
+ end
+ end
+
+ describe "when listening" do
+ it "should be reachable on the specified address and port" do
+ @server = Puppet::Network::Server.new(@params.merge(:port => 34343))
+ @server.listen
+ lambda { TCPSocket.new('127.0.0.1', 34343) }.should_not raise_error
+ end
+
+ it "should default to '0.0.0.0' as its bind address" do
+ Puppet.settings.clear
+ Puppet[:servertype] = 'webrick'
+ Puppet[:bindaddress].should == '0.0.0.0'
+ end
+
+ it "should use any specified bind address" do
+ Puppet[:bindaddress] = "127.0.0.1"
+ @server = Puppet::Network::Server.new(@params.merge(:port => 34343))
+ @server.stubs(:unlisten) # we're breaking listening internally, so we have to keep it from unlistening
+ @server.send(:http_server).expects(:listen).with { |args| args[:address] == "127.0.0.1" }
+ @server.listen
+ end
+
+ it "should not allow multiple servers to listen on the same address and port" do
+ @server = Puppet::Network::Server.new(@params.merge(:port => 34343))
+ @server.listen
+ @server2 = Puppet::Network::Server.new(@params.merge(:port => 34343))
+ lambda { @server2.listen }.should raise_error
+ end
+
+ after :each do
+ @server.unlisten if @server && @server.listening?
+ end
+ end
+
+ describe "after unlistening" do
+ it "should not be reachable on the port and address assigned" do
+ @server = Puppet::Network::Server.new(@params.merge(:port => 34343))
+ @server.listen
+ @server.unlisten
+ lambda { TCPSocket.new('127.0.0.1', 34343) }.should raise_error(Errno::ECONNREFUSED)
+ end
end
+ end
end
diff --git a/spec/integration/node/environment_spec.rb b/spec/integration/node/environment_spec.rb
index 68dfd93..8c51537 100755
--- a/spec/integration/node/environment_spec.rb
+++ b/spec/integration/node/environment_spec.rb
@@ -5,54 +5,54 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet_spec/files'
describe Puppet::Node::Environment do
- include PuppetSpec::Files
-
- it "should be able to return each module from its environment with the environment, name, and path set correctly" do
- base = tmpfile("env_modules")
- Dir.mkdir(base)
-
- dirs = []
- mods = {}
- %w{1 2}.each do |num|
- dir = File.join(base, "dir#{num}")
- dirs << dir
- Dir.mkdir(dir)
- mod = "mod#{num}"
- moddir = File.join(dir, mod)
- mods[mod] = moddir
- Dir.mkdir(moddir)
- end
-
- environment = Puppet::Node::Environment.new("foo")
- environment.stubs(:modulepath).returns dirs
-
- environment.modules.each do |mod|
- mod.environment.should == environment
- mod.path.should == mods[mod.name]
- end
+ include PuppetSpec::Files
+
+ it "should be able to return each module from its environment with the environment, name, and path set correctly" do
+ base = tmpfile("env_modules")
+ Dir.mkdir(base)
+
+ dirs = []
+ mods = {}
+ %w{1 2}.each do |num|
+ dir = File.join(base, "dir#{num}")
+ dirs << dir
+ Dir.mkdir(dir)
+ mod = "mod#{num}"
+ moddir = File.join(dir, mod)
+ mods[mod] = moddir
+ Dir.mkdir(moddir)
end
- it "should not yield the same module from different module paths" do
- base = tmpfile("env_modules")
- Dir.mkdir(base)
-
- dirs = []
- mods = {}
- %w{1 2}.each do |num|
- dir = File.join(base, "dir#{num}")
- dirs << dir
- Dir.mkdir(dir)
- mod = "mod"
- moddir = File.join(dir, mod)
- mods[mod] = moddir
- Dir.mkdir(moddir)
- end
-
- environment = Puppet::Node::Environment.new("foo")
- environment.stubs(:modulepath).returns dirs
-
- mods = environment.modules
- mods.length.should == 1
- mods[0].path.should == File.join(base, "dir1", "mod")
+ environment = Puppet::Node::Environment.new("foo")
+ environment.stubs(:modulepath).returns dirs
+
+ environment.modules.each do |mod|
+ mod.environment.should == environment
+ mod.path.should == mods[mod.name]
+ end
+ end
+
+ it "should not yield the same module from different module paths" do
+ base = tmpfile("env_modules")
+ Dir.mkdir(base)
+
+ dirs = []
+ mods = {}
+ %w{1 2}.each do |num|
+ dir = File.join(base, "dir#{num}")
+ dirs << dir
+ Dir.mkdir(dir)
+ mod = "mod"
+ moddir = File.join(dir, mod)
+ mods[mod] = moddir
+ Dir.mkdir(moddir)
end
+
+ environment = Puppet::Node::Environment.new("foo")
+ environment.stubs(:modulepath).returns dirs
+
+ mods = environment.modules
+ mods.length.should == 1
+ mods[0].path.should == File.join(base, "dir1", "mod")
+ end
end
diff --git a/spec/integration/node/facts_spec.rb b/spec/integration/node/facts_spec.rb
index 0a4d21e..4cc2f4c 100755
--- a/spec/integration/node/facts_spec.rb
+++ b/spec/integration/node/facts_spec.rb
@@ -6,42 +6,42 @@
require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::Node::Facts do
- describe "when using the indirector" do
- after { Puppet::Util::Cacher.expire }
+ describe "when using the indirector" do
+ after { Puppet::Util::Cacher.expire }
- it "should expire any cached node instances when it is saved" do
- Puppet::Node::Facts.indirection.stubs(:terminus_class).returns :yaml
+ it "should expire any cached node instances when it is saved" do
+ Puppet::Node::Facts.indirection.stubs(:terminus_class).returns :yaml
- Puppet::Node::Facts.indirection.terminus(:yaml).should equal(Puppet::Node::Facts.indirection.terminus(:yaml))
- terminus = Puppet::Node::Facts.indirection.terminus(:yaml)
- terminus.stubs :save
+ Puppet::Node::Facts.indirection.terminus(:yaml).should equal(Puppet::Node::Facts.indirection.terminus(:yaml))
+ terminus = Puppet::Node::Facts.indirection.terminus(:yaml)
+ terminus.stubs :save
- Puppet::Node.expects(:expire).with("me")
+ Puppet::Node.expects(:expire).with("me")
- facts = Puppet::Node::Facts.new("me")
- facts.save
- end
+ facts = Puppet::Node::Facts.new("me")
+ facts.save
+ end
- it "should be able to delegate to the :yaml terminus" do
- Puppet::Node::Facts.indirection.stubs(:terminus_class).returns :yaml
+ it "should be able to delegate to the :yaml terminus" do
+ Puppet::Node::Facts.indirection.stubs(:terminus_class).returns :yaml
- # Load now, before we stub the exists? method.
- terminus = Puppet::Node::Facts.indirection.terminus(:yaml)
+ # Load now, before we stub the exists? method.
+ terminus = Puppet::Node::Facts.indirection.terminus(:yaml)
- terminus.expects(:path).with("me").returns "/my/yaml/file"
- FileTest.expects(:exist?).with("/my/yaml/file").returns false
+ terminus.expects(:path).with("me").returns "/my/yaml/file"
+ FileTest.expects(:exist?).with("/my/yaml/file").returns false
- Puppet::Node::Facts.find("me").should be_nil
- end
+ Puppet::Node::Facts.find("me").should be_nil
+ end
- it "should be able to delegate to the :facter terminus" do
- Puppet::Node::Facts.indirection.stubs(:terminus_class).returns :facter
+ it "should be able to delegate to the :facter terminus" do
+ Puppet::Node::Facts.indirection.stubs(:terminus_class).returns :facter
- Facter.expects(:to_hash).returns "facter_hash"
- facts = Puppet::Node::Facts.new("me")
- Puppet::Node::Facts.expects(:new).with("me", "facter_hash").returns facts
+ Facter.expects(:to_hash).returns "facter_hash"
+ facts = Puppet::Node::Facts.new("me")
+ Puppet::Node::Facts.expects(:new).with("me", "facter_hash").returns facts
- Puppet::Node::Facts.find("me").should equal(facts)
- end
+ Puppet::Node::Facts.find("me").should equal(facts)
end
+ end
end
diff --git a/spec/integration/node_spec.rb b/spec/integration/node_spec.rb
index de95d0e..c635e7f 100755
--- a/spec/integration/node_spec.rb
+++ b/spec/integration/node_spec.rb
@@ -8,86 +8,86 @@ require File.dirname(__FILE__) + '/../spec_helper'
require 'puppet/node'
describe Puppet::Node do
- describe "when delegating indirection calls" do
- before do
- @name = "me"
- @node = Puppet::Node.new(@name)
- end
-
- it "should be able to use the exec terminus" do
- Puppet::Node.indirection.stubs(:terminus_class).returns :exec
-
- # Load now so we can stub
- terminus = Puppet::Node.indirection.terminus(:exec)
-
- terminus.expects(:query).with(@name).returns "myresults"
- terminus.expects(:translate).with(@name, "myresults").returns "translated_results"
- terminus.expects(:create_node).with(@name, "translated_results").returns @node
-
- Puppet::Node.find(@name).should equal(@node)
- end
-
- it "should be able to use the yaml terminus" do
- Puppet::Node.indirection.stubs(:terminus_class).returns :yaml
-
- # Load now, before we stub the exists? method.
- terminus = Puppet::Node.indirection.terminus(:yaml)
-
- terminus.expects(:path).with(@name).returns "/my/yaml/file"
-
- FileTest.expects(:exist?).with("/my/yaml/file").returns false
- Puppet::Node.find(@name).should be_nil
- end
-
- it "should have an ldap terminus" do
- Puppet::Node.indirection.terminus(:ldap).should_not be_nil
- end
-
- it "should be able to use the plain terminus" do
- Puppet::Node.indirection.stubs(:terminus_class).returns :plain
-
- # Load now, before we stub the exists? method.
- Puppet::Node.indirection.terminus(:plain)
-
- Puppet::Node.expects(:new).with(@name).returns @node
-
- Puppet::Node.find(@name).should equal(@node)
- end
-
- describe "and using the memory terminus" do
- before do
- @name = "me"
- @old_terminus = Puppet::Node.indirection.terminus_class
- @terminus = Puppet::Node.indirection.terminus(:memory)
- Puppet::Node.indirection.stubs(:terminus).returns @terminus
- @node = Puppet::Node.new(@name)
- end
-
- it "should find no nodes by default" do
- Puppet::Node.find(@name).should be_nil
- end
-
- it "should be able to find nodes that were previously saved" do
- @node.save
- Puppet::Node.find(@name).should equal(@node)
- end
-
- it "should replace existing saved nodes when a new node with the same name is saved" do
- @node.save
- two = Puppet::Node.new(@name)
- two.save
- Puppet::Node.find(@name).should equal(two)
- end
-
- it "should be able to remove previously saved nodes" do
- @node.save
- Puppet::Node.destroy(@node.name)
- Puppet::Node.find(@name).should be_nil
- end
-
- it "should fail when asked to destroy a node that does not exist" do
- proc { Puppet::Node.destroy(@node) }.should raise_error(ArgumentError)
- end
- end
+ describe "when delegating indirection calls" do
+ before do
+ @name = "me"
+ @node = Puppet::Node.new(@name)
end
+
+ it "should be able to use the exec terminus" do
+ Puppet::Node.indirection.stubs(:terminus_class).returns :exec
+
+ # Load now so we can stub
+ terminus = Puppet::Node.indirection.terminus(:exec)
+
+ terminus.expects(:query).with(@name).returns "myresults"
+ terminus.expects(:translate).with(@name, "myresults").returns "translated_results"
+ terminus.expects(:create_node).with(@name, "translated_results").returns @node
+
+ Puppet::Node.find(@name).should equal(@node)
+ end
+
+ it "should be able to use the yaml terminus" do
+ Puppet::Node.indirection.stubs(:terminus_class).returns :yaml
+
+ # Load now, before we stub the exists? method.
+ terminus = Puppet::Node.indirection.terminus(:yaml)
+
+ terminus.expects(:path).with(@name).returns "/my/yaml/file"
+
+ FileTest.expects(:exist?).with("/my/yaml/file").returns false
+ Puppet::Node.find(@name).should be_nil
+ end
+
+ it "should have an ldap terminus" do
+ Puppet::Node.indirection.terminus(:ldap).should_not be_nil
+ end
+
+ it "should be able to use the plain terminus" do
+ Puppet::Node.indirection.stubs(:terminus_class).returns :plain
+
+ # Load now, before we stub the exists? method.
+ Puppet::Node.indirection.terminus(:plain)
+
+ Puppet::Node.expects(:new).with(@name).returns @node
+
+ Puppet::Node.find(@name).should equal(@node)
+ end
+
+ describe "and using the memory terminus" do
+ before do
+ @name = "me"
+ @old_terminus = Puppet::Node.indirection.terminus_class
+ @terminus = Puppet::Node.indirection.terminus(:memory)
+ Puppet::Node.indirection.stubs(:terminus).returns @terminus
+ @node = Puppet::Node.new(@name)
+ end
+
+ it "should find no nodes by default" do
+ Puppet::Node.find(@name).should be_nil
+ end
+
+ it "should be able to find nodes that were previously saved" do
+ @node.save
+ Puppet::Node.find(@name).should equal(@node)
+ end
+
+ it "should replace existing saved nodes when a new node with the same name is saved" do
+ @node.save
+ two = Puppet::Node.new(@name)
+ two.save
+ Puppet::Node.find(@name).should equal(two)
+ end
+
+ it "should be able to remove previously saved nodes" do
+ @node.save
+ Puppet::Node.destroy(@node.name)
+ Puppet::Node.find(@name).should be_nil
+ end
+
+ it "should fail when asked to destroy a node that does not exist" do
+ proc { Puppet::Node.destroy(@node) }.should raise_error(ArgumentError)
+ end
+ end
+ end
end
diff --git a/spec/integration/parser/collector_spec.rb b/spec/integration/parser/collector_spec.rb
index 4b1279e..73273c9 100755
--- a/spec/integration/parser/collector_spec.rb
+++ b/spec/integration/parser/collector_spec.rb
@@ -5,34 +5,34 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/parser/collector'
describe Puppet::Parser::Collector do
- before do
- @scope = Puppet::Parser::Scope.new(:compiler => Puppet::Parser::Compiler.new(Puppet::Node.new("mynode")))
+ before do
+ @scope = Puppet::Parser::Scope.new(:compiler => Puppet::Parser::Compiler.new(Puppet::Node.new("mynode")))
- @resource = Puppet::Parser::Resource.new("file", "/tmp/testing", :scope => @scope, :source => "fakesource")
- {:owner => "root", :group => "bin", :mode => "644"}.each do |param, value|
- @resource[param] = value
- end
+ @resource = Puppet::Parser::Resource.new("file", "/tmp/testing", :scope => @scope, :source => "fakesource")
+ {:owner => "root", :group => "bin", :mode => "644"}.each do |param, value|
+ @resource[param] = value
end
+ end
- def query(text)
- code = "File <| #{text} |>"
- parser = Puppet::Parser::Parser.new(@scope.compiler)
- parser.parse(code).hostclass("").code[0].query
- end
+ def query(text)
+ code = "File <| #{text} |>"
+ parser = Puppet::Parser::Parser.new(@scope.compiler)
+ parser.parse(code).hostclass("").code[0].query
+ end
- {true => [%{title == "/tmp/testing"}, %{(title == "/tmp/testing")}, %{group == bin},
- %{title == "/tmp/testing" and group == bin}, %{title == bin or group == bin},
- %{title == "/tmp/testing" or title == bin}, %{title == "/tmp/testing"},
- %{(title == "/tmp/testing" or title == bin) and group == bin}],
- false => [%{title == bin}, %{title == bin or (title == bin and group == bin)},
- %{title != "/tmp/testing"}, %{title != "/tmp/testing" and group != bin}]
- }.each do |result, ary|
- ary.each do |string|
- it "should return '#{result}' when collecting resources with '#{string}'" do
- str, code = query(string).evaluate @scope
- code.should be_instance_of(Proc)
- code.call(@resource).should == result
- end
- end
+ {true => [%{title == "/tmp/testing"}, %{(title == "/tmp/testing")}, %{group == bin},
+ %{title == "/tmp/testing" and group == bin}, %{title == bin or group == bin},
+ %{title == "/tmp/testing" or title == bin}, %{title == "/tmp/testing"},
+ %{(title == "/tmp/testing" or title == bin) and group == bin}],
+ false => [%{title == bin}, %{title == bin or (title == bin and group == bin)},
+ %{title != "/tmp/testing"}, %{title != "/tmp/testing" and group != bin}]
+ }.each do |result, ary|
+ ary.each do |string|
+ it "should return '#{result}' when collecting resources with '#{string}'" do
+ str, code = query(string).evaluate @scope
+ code.should be_instance_of(Proc)
+ code.call(@resource).should == result
+ end
end
+ end
end
diff --git a/spec/integration/parser/compiler_spec.rb b/spec/integration/parser/compiler_spec.rb
index 512924f..83bbf95 100755
--- a/spec/integration/parser/compiler_spec.rb
+++ b/spec/integration/parser/compiler_spec.rb
@@ -3,27 +3,27 @@
require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::Parser::Compiler do
- before :each do
- @node = Puppet::Node.new "testnode"
+ before :each do
+ @node = Puppet::Node.new "testnode"
- @scope_resource = stub 'scope_resource', :builtin? => true, :finish => nil, :ref => 'Class[main]'
- @scope = stub 'scope', :resource => @scope_resource, :source => mock("source")
- end
+ @scope_resource = stub 'scope_resource', :builtin? => true, :finish => nil, :ref => 'Class[main]'
+ @scope = stub 'scope', :resource => @scope_resource, :source => mock("source")
+ end
- after do
- Puppet.settings.clear
- end
+ after do
+ Puppet.settings.clear
+ end
- it "should be able to determine the configuration version from a local version control repository" do
- # This should always work, because we should always be
- # in the puppet repo when we run this.
- version = %x{git rev-parse HEAD}.chomp
+ it "should be able to determine the configuration version from a local version control repository" do
+ # This should always work, because we should always be
+ # in the puppet repo when we run this.
+ version = %x{git rev-parse HEAD}.chomp
- Puppet.settings[:config_version] = 'git rev-parse HEAD'
+ Puppet.settings[:config_version] = 'git rev-parse HEAD'
- @parser = Puppet::Parser::Parser.new "development"
- @compiler = Puppet::Parser::Compiler.new(@node)
+ @parser = Puppet::Parser::Parser.new "development"
+ @compiler = Puppet::Parser::Compiler.new(@node)
- @compiler.catalog.version.should == version
- end
+ @compiler.catalog.version.should == version
+ end
end
diff --git a/spec/integration/parser/functions/require_spec.rb b/spec/integration/parser/functions/require_spec.rb
index 3d65a50..8b3beef 100755
--- a/spec/integration/parser/functions/require_spec.rb
+++ b/spec/integration/parser/functions/require_spec.rb
@@ -3,42 +3,42 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
describe "The require function" do
- before :each do
- @node = Puppet::Node.new("mynode")
- @compiler = Puppet::Parser::Compiler.new(@node)
-
- @compiler.send(:evaluate_main)
- @compiler.catalog.client_version = "0.25"
- @scope = @compiler.topscope
- # preload our functions
- Puppet::Parser::Functions.function(:include)
- Puppet::Parser::Functions.function(:require)
- end
-
- it "should add a dependency between the 'required' class and our class" do
- @compiler.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "requiredclass")
-
- @scope.function_require("requiredclass")
- @scope.resource["require"].should_not be_nil
- ref = @scope.resource["require"].shift
- ref.type.should == "Class"
- ref.title.should == "Requiredclass"
- end
-
- it "should queue relationships between the 'required' class and our classes" do
- @compiler.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "requiredclass1")
- @compiler.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "requiredclass2")
-
- @scope.function_require("requiredclass1")
- @scope.function_require("requiredclass2")
-
- @scope.resource["require"].should_not be_nil
-
- (ref1,ref2) = @scope.resource["require"]
- ref1.type.should == "Class"
- ref1.title.should == "Requiredclass1"
- ref2.type.should == "Class"
- ref2.title.should == "Requiredclass2"
- end
+ before :each do
+ @node = Puppet::Node.new("mynode")
+ @compiler = Puppet::Parser::Compiler.new(@node)
+
+ @compiler.send(:evaluate_main)
+ @compiler.catalog.client_version = "0.25"
+ @scope = @compiler.topscope
+ # preload our functions
+ Puppet::Parser::Functions.function(:include)
+ Puppet::Parser::Functions.function(:require)
+ end
+
+ it "should add a dependency between the 'required' class and our class" do
+ @compiler.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "requiredclass")
+
+ @scope.function_require("requiredclass")
+ @scope.resource["require"].should_not be_nil
+ ref = @scope.resource["require"].shift
+ ref.type.should == "Class"
+ ref.title.should == "Requiredclass"
+ end
+
+ it "should queue relationships between the 'required' class and our classes" do
+ @compiler.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "requiredclass1")
+ @compiler.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "requiredclass2")
+
+ @scope.function_require("requiredclass1")
+ @scope.function_require("requiredclass2")
+
+ @scope.resource["require"].should_not be_nil
+
+ (ref1,ref2) = @scope.resource["require"]
+ ref1.type.should == "Class"
+ ref1.title.should == "Requiredclass1"
+ ref2.type.should == "Class"
+ ref2.title.should == "Requiredclass2"
+ end
end
diff --git a/spec/integration/parser/parser_spec.rb b/spec/integration/parser/parser_spec.rb
index ff81758..7b85bca 100755
--- a/spec/integration/parser/parser_spec.rb
+++ b/spec/integration/parser/parser_spec.rb
@@ -3,111 +3,111 @@
require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::Parser::Parser do
- module ParseMatcher
- class ParseAs
- def initialize(klass)
- @parser = Puppet::Parser::Parser.new "development"
- @class = klass
- end
-
- def result_instance
- @result.hostclass("").code[0]
- end
-
- def matches?(string)
- @string = string
- @result = @parser.parse(string)
- result_instance.instance_of?(@class)
- end
-
- def description
- "parse as a #{@class}"
- end
-
- def failure_message
- " expected #{@string} to parse as #{@class} but was #{result_instance.class}"
- end
-
- def negative_failure_message
- " expected #{@string} not to parse as #{@class}"
- end
- end
-
- def parse_as(klass)
- ParseAs.new(klass)
- end
-
- class ParseWith
- def initialize(block)
- @parser = Puppet::Parser::Parser.new "development"
- @block = block
- end
-
- def result_instance
- @result.hostclass("").code[0]
- end
-
- def matches?(string)
- @string = string
- @result = @parser.parse(string)
- @block.call(result_instance)
- end
-
- def description
- "parse with the block evaluating to true"
- end
-
- def failure_message
- " expected #{@string} to parse with a true result in the block"
- end
-
- def negative_failure_message
- " expected #{@string} not to parse with a true result in the block"
- end
- end
-
- def parse_with(&block)
- ParseWith.new(block)
- end
+ module ParseMatcher
+ class ParseAs
+ def initialize(klass)
+ @parser = Puppet::Parser::Parser.new "development"
+ @class = klass
+ end
+
+ def result_instance
+ @result.hostclass("").code[0]
+ end
+
+ def matches?(string)
+ @string = string
+ @result = @parser.parse(string)
+ result_instance.instance_of?(@class)
+ end
+
+ def description
+ "parse as a #{@class}"
+ end
+
+ def failure_message
+ " expected #{@string} to parse as #{@class} but was #{result_instance.class}"
+ end
+
+ def negative_failure_message
+ " expected #{@string} not to parse as #{@class}"
+ end
end
- include ParseMatcher
+ def parse_as(klass)
+ ParseAs.new(klass)
+ end
- before :each do
- @resource_type_collection = Puppet::Resource::TypeCollection.new("env")
+ class ParseWith
+ def initialize(block)
@parser = Puppet::Parser::Parser.new "development"
+ @block = block
+ end
+
+ def result_instance
+ @result.hostclass("").code[0]
+ end
+
+ def matches?(string)
+ @string = string
+ @result = @parser.parse(string)
+ @block.call(result_instance)
+ end
+
+ def description
+ "parse with the block evaluating to true"
+ end
+
+ def failure_message
+ " expected #{@string} to parse with a true result in the block"
+ end
+
+ def negative_failure_message
+ " expected #{@string} not to parse with a true result in the block"
+ end
end
- describe "when parsing comments before statement" do
- it "should associate the documentation to the statement AST node" do
- ast = @parser.parse("""
- # comment
- class test {}
- """)
+ def parse_with(&block)
+ ParseWith.new(block)
+ end
+ end
+
+ include ParseMatcher
+
+ before :each do
+ @resource_type_collection = Puppet::Resource::TypeCollection.new("env")
+ @parser = Puppet::Parser::Parser.new "development"
+ end
- ast.hostclass("test").doc.should == "comment\n"
- end
+ describe "when parsing comments before statement" do
+ it "should associate the documentation to the statement AST node" do
+ ast = @parser.parse("""
+ # comment
+ class test {}
+ """)
+
+ ast.hostclass("test").doc.should == "comment\n"
end
+ end
- describe "when parsing" do
- it "should be able to parse normal left to right relationships" do
- "Notify[foo] -> Notify[bar]".should parse_as(Puppet::Parser::AST::Relationship)
- end
+ describe "when parsing" do
+ it "should be able to parse normal left to right relationships" do
+ "Notify[foo] -> Notify[bar]".should parse_as(Puppet::Parser::AST::Relationship)
+ end
- it "should be able to parse right to left relationships" do
- "Notify[foo] <- Notify[bar]".should parse_as(Puppet::Parser::AST::Relationship)
- end
+ it "should be able to parse right to left relationships" do
+ "Notify[foo] <- Notify[bar]".should parse_as(Puppet::Parser::AST::Relationship)
+ end
- it "should be able to parse normal left to right subscriptions" do
- "Notify[foo] ~> Notify[bar]".should parse_as(Puppet::Parser::AST::Relationship)
- end
+ it "should be able to parse normal left to right subscriptions" do
+ "Notify[foo] ~> Notify[bar]".should parse_as(Puppet::Parser::AST::Relationship)
+ end
- it "should be able to parse right to left subscriptions" do
- "Notify[foo] <~ Notify[bar]".should parse_as(Puppet::Parser::AST::Relationship)
- end
+ it "should be able to parse right to left subscriptions" do
+ "Notify[foo] <~ Notify[bar]".should parse_as(Puppet::Parser::AST::Relationship)
+ end
- it "should correctly set the arrow type of a relationship" do
- "Notify[foo] <~ Notify[bar]".should parse_with { |rel| rel.arrow == "<~" }
- end
+ it "should correctly set the arrow type of a relationship" do
+ "Notify[foo] <~ Notify[bar]".should parse_with { |rel| rel.arrow == "<~" }
end
+ end
end
diff --git a/spec/integration/provider/mailalias/aliases_spec.rb b/spec/integration/provider/mailalias/aliases_spec.rb
index fde0b00..8106c2c 100755
--- a/spec/integration/provider/mailalias/aliases_spec.rb
+++ b/spec/integration/provider/mailalias/aliases_spec.rb
@@ -9,17 +9,17 @@ require 'puppettest/fileparsing'
provider_class = Puppet::Type.type(:mailalias).provider(:aliases)
describe provider_class do
- include PuppetTest
- include PuppetTest::FileParsing
+ include PuppetTest
+ include PuppetTest::FileParsing
- before :each do
- @provider = provider_class
- end
+ before :each do
+ @provider = provider_class
+ end
- # #1560
- PuppetTest.fakedata("data/providers/mailalias/aliases").each { |file|
- it "should be able to parse the examples in #{file}" do
- fakedataparse(file)
- end
- }
+ # #1560
+ PuppetTest.fakedata("data/providers/mailalias/aliases").each { |file|
+ it "should be able to parse the examples in #{file}" do
+ fakedataparse(file)
+ end
+ }
end
diff --git a/spec/integration/provider/package_spec.rb b/spec/integration/provider/package_spec.rb
index 6c854fb..736a34e 100755
--- a/spec/integration/provider/package_spec.rb
+++ b/spec/integration/provider/package_spec.rb
@@ -3,24 +3,24 @@
Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") }
describe "Package Provider" do
- Puppet::Type.type(:package).providers.each do |name|
- provider = Puppet::Type.type(:package).provider(name)
+ Puppet::Type.type(:package).providers.each do |name|
+ provider = Puppet::Type.type(:package).provider(name)
- describe name do
- confine "Provider #{name} is not suitable" => provider.suitable?
+ describe name do
+ confine "Provider #{name} is not suitable" => provider.suitable?
- it "should fail when asked to install an invalid package" do
- pending("This test hangs forever with recent versions of RubyGems") if provider.name == :gem
- pkg = Puppet::Type.newpackage :name => "nosuch#{provider.name}", :provider => provider.name
- lambda { pkg.provider.install }.should raise_error
- end
+ it "should fail when asked to install an invalid package" do
+ pending("This test hangs forever with recent versions of RubyGems") if provider.name == :gem
+ pkg = Puppet::Type.newpackage :name => "nosuch#{provider.name}", :provider => provider.name
+ lambda { pkg.provider.install }.should raise_error
+ end
- it "should be able to get a list of existing packages" do
- provider.instances.each do |package|
- package.should be_instance_of(provider)
- package.properties[:provider].should == provider.name
- end
- end
+ it "should be able to get a list of existing packages" do
+ provider.instances.each do |package|
+ package.should be_instance_of(provider)
+ package.properties[:provider].should == provider.name
end
+ end
end
+ end
end
diff --git a/spec/integration/provider/service/init_spec.rb b/spec/integration/provider/service/init_spec.rb
index e185247..d916ab3 100755
--- a/spec/integration/provider/service/init_spec.rb
+++ b/spec/integration/provider/service/init_spec.rb
@@ -6,27 +6,27 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
provider = Puppet::Type.type(:service).provider(:init)
describe provider do
- describe "when running on FreeBSD" do
- confine "Not running on FreeBSD" => (Facter.value(:operatingsystem) == "FreeBSD")
+ describe "when running on FreeBSD" do
+ confine "Not running on FreeBSD" => (Facter.value(:operatingsystem) == "FreeBSD")
- it "should set its default path to include /etc/init.d and /usr/local/etc/init.d" do
- provider.defpath.should == ["/etc/rc.d", "/usr/local/etc/rc.d"]
- end
+ it "should set its default path to include /etc/init.d and /usr/local/etc/init.d" do
+ provider.defpath.should == ["/etc/rc.d", "/usr/local/etc/rc.d"]
end
+ end
- describe "when running on HP-UX" do
- confine "Not running on HP-UX" => (Facter.value(:operatingsystem) == "HP-UX")
+ describe "when running on HP-UX" do
+ confine "Not running on HP-UX" => (Facter.value(:operatingsystem) == "HP-UX")
- it "should set its default path to include /sbin/init.d" do
- provider.defpath.should == "/sbin/init.d"
- end
+ it "should set its default path to include /sbin/init.d" do
+ provider.defpath.should == "/sbin/init.d"
end
+ end
- describe "when not running on FreeBSD or HP-UX" do
- confine "Running on HP-UX or FreeBSD" => (! %w{HP-UX FreeBSD}.include?(Facter.value(:operatingsystem)))
+ describe "when not running on FreeBSD or HP-UX" do
+ confine "Running on HP-UX or FreeBSD" => (! %w{HP-UX FreeBSD}.include?(Facter.value(:operatingsystem)))
- it "should set its default path to include /etc/init.d" do
- provider.defpath.should == "/etc/init.d"
- end
+ it "should set its default path to include /etc/init.d" do
+ provider.defpath.should == "/etc/init.d"
end
+ end
end
diff --git a/spec/integration/reference/providers_spec.rb b/spec/integration/reference/providers_spec.rb
index 79b6ce1..8b95ca1 100755
--- a/spec/integration/reference/providers_spec.rb
+++ b/spec/integration/reference/providers_spec.rb
@@ -7,11 +7,11 @@ require 'puppet/util/reference'
reference = Puppet::Util::Reference.reference(:providers)
describe reference do
- it "should exist" do
- reference.should_not be_nil
- end
+ it "should exist" do
+ reference.should_not be_nil
+ end
- it "should be able to be rendered as text" do
- lambda { reference.to_text }.should_not raise_error
- end
+ it "should be able to be rendered as text" do
+ lambda { reference.to_text }.should_not raise_error
+ end
end
diff --git a/spec/integration/reports_spec.rb b/spec/integration/reports_spec.rb
index cc4ae8f..40e5284 100755
--- a/spec/integration/reports_spec.rb
+++ b/spec/integration/reports_spec.rb
@@ -8,11 +8,11 @@ require File.dirname(__FILE__) + '/../spec_helper'
require 'puppet/reports'
describe Puppet::Reports, " when using report types" do
- before do
- Puppet.settings.stubs(:use)
- end
+ before do
+ Puppet.settings.stubs(:use)
+ end
- it "should load report types as modules" do
- Puppet::Reports.report(:store).should be_instance_of(Module)
- end
+ it "should load report types as modules" do
+ Puppet::Reports.report(:store).should be_instance_of(Module)
+ end
end
diff --git a/spec/integration/resource/catalog_spec.rb b/spec/integration/resource/catalog_spec.rb
index f400445..0a3d47a 100755
--- a/spec/integration/resource/catalog_spec.rb
+++ b/spec/integration/resource/catalog_spec.rb
@@ -6,56 +6,56 @@
require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::Resource::Catalog do
- describe "when pson is available" do
- confine "PSON library is missing" => Puppet.features.pson?
- it "should support pson" do
- Puppet::Resource::Catalog.supported_formats.should be_include(:pson)
- end
+ describe "when pson is available" do
+ confine "PSON library is missing" => Puppet.features.pson?
+ it "should support pson" do
+ Puppet::Resource::Catalog.supported_formats.should be_include(:pson)
+ end
+ end
+
+ describe "when using the indirector" do
+ after { Puppet::Util::Cacher.expire }
+ before do
+ # This is so the tests work w/out networking.
+ Facter.stubs(:to_hash).returns({"hostname" => "foo.domain.com"})
+ Facter.stubs(:value).returns("eh")
end
-
- describe "when using the indirector" do
- after { Puppet::Util::Cacher.expire }
- before do
- # This is so the tests work w/out networking.
- Facter.stubs(:to_hash).returns({"hostname" => "foo.domain.com"})
- Facter.stubs(:value).returns("eh")
- end
- it "should be able to delegate to the :yaml terminus" do
- Puppet::Resource::Catalog.indirection.stubs(:terminus_class).returns :yaml
+ it "should be able to delegate to the :yaml terminus" do
+ Puppet::Resource::Catalog.indirection.stubs(:terminus_class).returns :yaml
- # Load now, before we stub the exists? method.
- terminus = Puppet::Resource::Catalog.indirection.terminus(:yaml)
- terminus.expects(:path).with("me").returns "/my/yaml/file"
+ # Load now, before we stub the exists? method.
+ terminus = Puppet::Resource::Catalog.indirection.terminus(:yaml)
+ terminus.expects(:path).with("me").returns "/my/yaml/file"
- FileTest.expects(:exist?).with("/my/yaml/file").returns false
- Puppet::Resource::Catalog.find("me").should be_nil
- end
+ FileTest.expects(:exist?).with("/my/yaml/file").returns false
+ Puppet::Resource::Catalog.find("me").should be_nil
+ end
- it "should be able to delegate to the :compiler terminus" do
- Puppet::Resource::Catalog.indirection.stubs(:terminus_class).returns :compiler
+ it "should be able to delegate to the :compiler terminus" do
+ Puppet::Resource::Catalog.indirection.stubs(:terminus_class).returns :compiler
- # Load now, before we stub the exists? method.
- compiler = Puppet::Resource::Catalog.indirection.terminus(:compiler)
+ # Load now, before we stub the exists? method.
+ compiler = Puppet::Resource::Catalog.indirection.terminus(:compiler)
- node = mock 'node'
- node.stub_everything
+ node = mock 'node'
+ node.stub_everything
- Puppet::Node.expects(:find).returns(node)
- compiler.expects(:compile).with(node).returns nil
+ Puppet::Node.expects(:find).returns(node)
+ compiler.expects(:compile).with(node).returns nil
- Puppet::Resource::Catalog.find("me").should be_nil
- end
+ Puppet::Resource::Catalog.find("me").should be_nil
+ end
- it "should pass provided node information directly to the terminus" do
- terminus = mock 'terminus'
+ it "should pass provided node information directly to the terminus" do
+ terminus = mock 'terminus'
- Puppet::Resource::Catalog.indirection.stubs(:terminus).returns terminus
+ Puppet::Resource::Catalog.indirection.stubs(:terminus).returns terminus
- node = mock 'node'
- terminus.expects(:find).with { |request| request.options[:use_node] == node }
- Puppet::Resource::Catalog.find("me", :use_node => node)
- end
+ node = mock 'node'
+ terminus.expects(:find).with { |request| request.options[:use_node] == node }
+ Puppet::Resource::Catalog.find("me", :use_node => node)
end
+ end
end
diff --git a/spec/integration/resource/type_collection_spec.rb b/spec/integration/resource/type_collection_spec.rb
index da309c6..318dd4d 100755
--- a/spec/integration/resource/type_collection_spec.rb
+++ b/spec/integration/resource/type_collection_spec.rb
@@ -6,91 +6,91 @@ require 'puppet_spec/files'
require 'puppet/resource/type_collection'
describe Puppet::Resource::TypeCollection do
- describe "when autoloading from modules" do
- include PuppetSpec::Files
+ describe "when autoloading from modules" do
+ include PuppetSpec::Files
- before do
- @dir = tmpfile("autoload_testing")
- Puppet[:modulepath] = @dir
+ before do
+ @dir = tmpfile("autoload_testing")
+ Puppet[:modulepath] = @dir
- FileUtils.mkdir_p @dir
- @code = Puppet::Resource::TypeCollection.new("env")
- Puppet::Node::Environment.new("env").stubs(:known_resource_types).returns @code
- end
+ FileUtils.mkdir_p @dir
+ @code = Puppet::Resource::TypeCollection.new("env")
+ Puppet::Node::Environment.new("env").stubs(:known_resource_types).returns @code
+ end
- # Setup a module.
- def mk_module(name, files = {})
- mdir = File.join(@dir, name)
- mandir = File.join(mdir, "manifests")
- FileUtils.mkdir_p mandir
-
- defs = files.delete(:define)
-
- Dir.chdir(mandir) do
- files.each do |file, classes|
- File.open("#{file}.pp", "w") do |f|
- classes.each { |klass|
- if defs
- f.puts "define #{klass} {}"
- else
- f.puts "class #{klass} {}"
- end
- }
- end
- end
- end
+ # Setup a module.
+ def mk_module(name, files = {})
+ mdir = File.join(@dir, name)
+ mandir = File.join(mdir, "manifests")
+ FileUtils.mkdir_p mandir
+
+ defs = files.delete(:define)
+
+ Dir.chdir(mandir) do
+ files.each do |file, classes|
+ File.open("#{file}.pp", "w") do |f|
+ classes.each { |klass|
+ if defs
+ f.puts "define #{klass} {}"
+ else
+ f.puts "class #{klass} {}"
+ end
+ }
+ end
end
+ end
+ end
- it "should return nil when a class can't be found or loaded" do
- @code.find_hostclass('', 'nosuchclass').should be_nil
- end
+ it "should return nil when a class can't be found or loaded" do
+ @code.find_hostclass('', 'nosuchclass').should be_nil
+ end
- it "should load the module's init file first" do
- name = "simple"
- mk_module(name, :init => [name])
+ it "should load the module's init file first" do
+ name = "simple"
+ mk_module(name, :init => [name])
- @code.find_hostclass("", name).name.should == name
- end
+ @code.find_hostclass("", name).name.should == name
+ end
- it "should load the module's init file even when searching from a different namespace" do
- name = "simple"
- mk_module(name, :init => [name])
+ it "should load the module's init file even when searching from a different namespace" do
+ name = "simple"
+ mk_module(name, :init => [name])
- @code.find_hostclass("other::ns", name).name.should == name
- end
+ @code.find_hostclass("other::ns", name).name.should == name
+ end
- it "should be able to load definitions from the module base file" do
- name = "simpdef"
- mk_module(name, :define => true, :init => [name])
- @code.find_definition("", name).name.should == name
- end
+ it "should be able to load definitions from the module base file" do
+ name = "simpdef"
+ mk_module(name, :define => true, :init => [name])
+ @code.find_definition("", name).name.should == name
+ end
- it "should be able to load qualified classes from the module base file" do
- modname = "both"
- name = "sub"
- mk_module(modname, :init => %w{both both::sub})
+ it "should be able to load qualified classes from the module base file" do
+ modname = "both"
+ name = "sub"
+ mk_module(modname, :init => %w{both both::sub})
- @code.find_hostclass("both", name).name.should == "both::sub"
- end
+ @code.find_hostclass("both", name).name.should == "both::sub"
+ end
- it "should be able load classes from a separate file" do
- modname = "separate"
- name = "sub"
- mk_module(modname, :init => %w{separate}, :sub => %w{separate::sub})
- @code.find_hostclass("separate", name).name.should == "separate::sub"
- end
+ it "should be able load classes from a separate file" do
+ modname = "separate"
+ name = "sub"
+ mk_module(modname, :init => %w{separate}, :sub => %w{separate::sub})
+ @code.find_hostclass("separate", name).name.should == "separate::sub"
+ end
- it "should not fail when loading from a separate file if there is no module file" do
- modname = "alone"
- name = "sub"
- mk_module(modname, :sub => %w{alone::sub})
- lambda { @code.find_hostclass("alone", name) }.should_not raise_error
- end
+ it "should not fail when loading from a separate file if there is no module file" do
+ modname = "alone"
+ name = "sub"
+ mk_module(modname, :sub => %w{alone::sub})
+ lambda { @code.find_hostclass("alone", name) }.should_not raise_error
+ end
- it "should be able to load definitions from their own file" do
- name = "mymod"
- mk_module(name, :define => true, :mydefine => ["mymod::mydefine"])
- @code.find_definition("", "mymod::mydefine").name.should == "mymod::mydefine"
- end
+ it "should be able to load definitions from their own file" do
+ name = "mymod"
+ mk_module(name, :define => true, :mydefine => ["mymod::mydefine"])
+ @code.find_definition("", "mymod::mydefine").name.should == "mymod::mydefine"
end
+ end
end
diff --git a/spec/integration/ssl/certificate_authority_spec.rb b/spec/integration/ssl/certificate_authority_spec.rb
index 5fcbed8..be82b5f 100755
--- a/spec/integration/ssl/certificate_authority_spec.rb
+++ b/spec/integration/ssl/certificate_authority_spec.rb
@@ -9,127 +9,127 @@ require 'puppet/ssl/certificate_authority'
require 'tempfile'
describe Puppet::SSL::CertificateAuthority do
- before do
- # Get a safe temporary file
- file = Tempfile.new("ca_integration_testing")
- @dir = file.path
- file.delete
+ before do
+ # Get a safe temporary file
+ file = Tempfile.new("ca_integration_testing")
+ @dir = file.path
+ file.delete
- Puppet.settings[:confdir] = @dir
- Puppet.settings[:vardir] = @dir
+ Puppet.settings[:confdir] = @dir
+ Puppet.settings[:vardir] = @dir
- Puppet::SSL::Host.ca_location = :local
- @ca = Puppet::SSL::CertificateAuthority.new
- end
+ Puppet::SSL::Host.ca_location = :local
+ @ca = Puppet::SSL::CertificateAuthority.new
+ end
- after {
- Puppet::SSL::Host.ca_location = :none
+ after {
+ Puppet::SSL::Host.ca_location = :none
- system("rm -rf #{@dir}")
- Puppet.settings.clear
+ system("rm -rf #{@dir}")
+ Puppet.settings.clear
- Puppet::Util::Cacher.expire
+ Puppet::Util::Cacher.expire
- Puppet::SSL::CertificateAuthority.instance_variable_set("@instance", nil)
- }
+ Puppet::SSL::CertificateAuthority.instance_variable_set("@instance", nil)
+ }
- it "should create a CA host" do
- @ca.host.should be_ca
- end
+ it "should create a CA host" do
+ @ca.host.should be_ca
+ end
- it "should be able to generate a certificate" do
- @ca.generate_ca_certificate
+ it "should be able to generate a certificate" do
+ @ca.generate_ca_certificate
- @ca.host.certificate.should be_instance_of(Puppet::SSL::Certificate)
- end
+ @ca.host.certificate.should be_instance_of(Puppet::SSL::Certificate)
+ end
- it "should be able to generate a new host certificate" do
- @ca.generate("newhost")
+ it "should be able to generate a new host certificate" do
+ @ca.generate("newhost")
- Puppet::SSL::Certificate.find("newhost").should be_instance_of(Puppet::SSL::Certificate)
- end
+ Puppet::SSL::Certificate.find("newhost").should be_instance_of(Puppet::SSL::Certificate)
+ end
- it "should be able to revoke a host certificate" do
- @ca.generate("newhost")
+ it "should be able to revoke a host certificate" do
+ @ca.generate("newhost")
- @ca.revoke("newhost")
+ @ca.revoke("newhost")
- lambda { @ca.verify("newhost") }.should raise_error
- end
+ lambda { @ca.verify("newhost") }.should raise_error
+ end
- it "should have a CRL" do
- @ca.generate_ca_certificate
- @ca.crl.should_not be_nil
- end
+ it "should have a CRL" do
+ @ca.generate_ca_certificate
+ @ca.crl.should_not be_nil
+ end
- it "should be able to read in a previously created CRL" do
- @ca.generate_ca_certificate
+ it "should be able to read in a previously created CRL" do
+ @ca.generate_ca_certificate
- # Create it to start with.
- @ca.crl
+ # Create it to start with.
+ @ca.crl
- Puppet::SSL::CertificateAuthority.new.crl.should_not be_nil
- end
+ Puppet::SSL::CertificateAuthority.new.crl.should_not be_nil
+ end
- describe "when signing certificates" do
- before do
- @host = Puppet::SSL::Host.new("luke.madstop.com")
+ describe "when signing certificates" do
+ before do
+ @host = Puppet::SSL::Host.new("luke.madstop.com")
- # We have to provide the key, since when we're in :ca_only mode, we can only interact
- # with the CA key.
- key = Puppet::SSL::Key.new(@host.name)
- key.generate
+ # We have to provide the key, since when we're in :ca_only mode, we can only interact
+ # with the CA key.
+ key = Puppet::SSL::Key.new(@host.name)
+ key.generate
- @host.key = key
- @host.generate_certificate_request
+ @host.key = key
+ @host.generate_certificate_request
- path = File.join(Puppet[:requestdir], "luke.madstop.com.pem")
- end
+ path = File.join(Puppet[:requestdir], "luke.madstop.com.pem")
+ end
- it "should be able to sign certificates" do
- @ca.sign("luke.madstop.com")
- end
+ it "should be able to sign certificates" do
+ @ca.sign("luke.madstop.com")
+ end
- it "should save the signed certificate" do
- @ca.sign("luke.madstop.com")
+ it "should save the signed certificate" do
+ @ca.sign("luke.madstop.com")
- Puppet::SSL::Certificate.find("luke.madstop.com").should be_instance_of(Puppet::SSL::Certificate)
- end
+ Puppet::SSL::Certificate.find("luke.madstop.com").should be_instance_of(Puppet::SSL::Certificate)
+ end
- it "should be able to sign multiple certificates" do
- @other = Puppet::SSL::Host.new("other.madstop.com")
- okey = Puppet::SSL::Key.new(@other.name)
- okey.generate
- @other.key = okey
- @other.generate_certificate_request
+ it "should be able to sign multiple certificates" do
+ @other = Puppet::SSL::Host.new("other.madstop.com")
+ okey = Puppet::SSL::Key.new(@other.name)
+ okey.generate
+ @other.key = okey
+ @other.generate_certificate_request
- @ca.sign("luke.madstop.com")
- @ca.sign("other.madstop.com")
+ @ca.sign("luke.madstop.com")
+ @ca.sign("other.madstop.com")
- Puppet::SSL::Certificate.find("other.madstop.com").should be_instance_of(Puppet::SSL::Certificate)
- Puppet::SSL::Certificate.find("luke.madstop.com").should be_instance_of(Puppet::SSL::Certificate)
- end
+ Puppet::SSL::Certificate.find("other.madstop.com").should be_instance_of(Puppet::SSL::Certificate)
+ Puppet::SSL::Certificate.find("luke.madstop.com").should be_instance_of(Puppet::SSL::Certificate)
+ end
- it "should save the signed certificate to the :signeddir" do
- @ca.sign("luke.madstop.com")
+ it "should save the signed certificate to the :signeddir" do
+ @ca.sign("luke.madstop.com")
- client_cert = File.join(Puppet[:signeddir], "luke.madstop.com.pem")
- File.read(client_cert).should == Puppet::SSL::Certificate.find("luke.madstop.com").content.to_s
- end
+ client_cert = File.join(Puppet[:signeddir], "luke.madstop.com.pem")
+ File.read(client_cert).should == Puppet::SSL::Certificate.find("luke.madstop.com").content.to_s
+ end
- it "should save valid certificates" do
- @ca.sign("luke.madstop.com")
+ it "should save valid certificates" do
+ @ca.sign("luke.madstop.com")
- ssl = %x{which openssl}
+ ssl = %x{which openssl}
- unless ssl
- pending "No ssl available"
- else
- ca_cert = Puppet[:cacert]
- client_cert = File.join(Puppet[:signeddir], "luke.madstop.com.pem")
- output = %x{openssl verify -CAfile #{ca_cert} #{client_cert}}
- $CHILD_STATUS.should == 0
- end
- end
+ unless ssl
+ pending "No ssl available"
+ else
+ ca_cert = Puppet[:cacert]
+ client_cert = File.join(Puppet[:signeddir], "luke.madstop.com.pem")
+ output = %x{openssl verify -CAfile #{ca_cert} #{client_cert}}
+ $CHILD_STATUS.should == 0
+ end
end
+ end
end
diff --git a/spec/integration/ssl/certificate_request_spec.rb b/spec/integration/ssl/certificate_request_spec.rb
index 5266ba6..365ecce 100755
--- a/spec/integration/ssl/certificate_request_spec.rb
+++ b/spec/integration/ssl/certificate_request_spec.rb
@@ -9,53 +9,53 @@ require 'puppet/ssl/certificate_request'
require 'tempfile'
describe Puppet::SSL::CertificateRequest do
- before do
- # Get a safe temporary file
- file = Tempfile.new("csr_integration_testing")
- @dir = file.path
- file.delete
+ before do
+ # Get a safe temporary file
+ file = Tempfile.new("csr_integration_testing")
+ @dir = file.path
+ file.delete
- Dir.mkdir(@dir)
+ Dir.mkdir(@dir)
- Puppet.settings.clear
+ Puppet.settings.clear
- Puppet.settings[:confdir] = @dir
- Puppet.settings[:vardir] = @dir
+ Puppet.settings[:confdir] = @dir
+ Puppet.settings[:vardir] = @dir
- Puppet::SSL::Host.ca_location = :none
+ Puppet::SSL::Host.ca_location = :none
- @csr = Puppet::SSL::CertificateRequest.new("luke.madstop.com")
+ @csr = Puppet::SSL::CertificateRequest.new("luke.madstop.com")
- @key = OpenSSL::PKey::RSA.new(512)
- end
+ @key = OpenSSL::PKey::RSA.new(512)
+ end
- after do
- system("rm -rf #{@dir}")
- Puppet.settings.clear
+ after do
+ system("rm -rf #{@dir}")
+ Puppet.settings.clear
- # This is necessary so the terminus instances don't lie around.
- Puppet::Util::Cacher.expire
- end
+ # This is necessary so the terminus instances don't lie around.
+ Puppet::Util::Cacher.expire
+ end
- it "should be able to generate CSRs" do
- @csr.generate(@key)
- end
+ it "should be able to generate CSRs" do
+ @csr.generate(@key)
+ end
- it "should be able to save CSRs" do
- @csr.save
- end
+ it "should be able to save CSRs" do
+ @csr.save
+ end
- it "should be able to find saved certificate requests via the Indirector" do
- @csr.generate(@key)
- @csr.save
+ it "should be able to find saved certificate requests via the Indirector" do
+ @csr.generate(@key)
+ @csr.save
- Puppet::SSL::CertificateRequest.find("luke.madstop.com").should be_instance_of(Puppet::SSL::CertificateRequest)
- end
+ Puppet::SSL::CertificateRequest.find("luke.madstop.com").should be_instance_of(Puppet::SSL::CertificateRequest)
+ end
- it "should save the completely CSR when saving" do
- @csr.generate(@key)
- @csr.save
+ it "should save the completely CSR when saving" do
+ @csr.generate(@key)
+ @csr.save
- Puppet::SSL::CertificateRequest.find("luke.madstop.com").content.to_s.should == @csr.content.to_s
- end
+ Puppet::SSL::CertificateRequest.find("luke.madstop.com").content.to_s.should == @csr.content.to_s
+ end
end
diff --git a/spec/integration/ssl/certificate_revocation_list_spec.rb b/spec/integration/ssl/certificate_revocation_list_spec.rb
index 6328ae4..127654c 100755
--- a/spec/integration/ssl/certificate_revocation_list_spec.rb
+++ b/spec/integration/ssl/certificate_revocation_list_spec.rb
@@ -9,34 +9,34 @@ require 'puppet/ssl/certificate_revocation_list'
require 'tempfile'
describe Puppet::SSL::CertificateRevocationList do
- before do
- # Get a safe temporary file
- file = Tempfile.new("ca_integration_testing")
- @dir = file.path
- file.delete
+ before do
+ # Get a safe temporary file
+ file = Tempfile.new("ca_integration_testing")
+ @dir = file.path
+ file.delete
- Puppet.settings[:confdir] = @dir
- Puppet.settings[:vardir] = @dir
+ Puppet.settings[:confdir] = @dir
+ Puppet.settings[:vardir] = @dir
- Puppet::SSL::Host.ca_location = :local
- end
+ Puppet::SSL::Host.ca_location = :local
+ end
- after {
- Puppet::SSL::Host.ca_location = :none
+ after {
+ Puppet::SSL::Host.ca_location = :none
- system("rm -rf #{@dir}")
- Puppet.settings.clear
+ system("rm -rf #{@dir}")
+ Puppet.settings.clear
- # This is necessary so the terminus instances don't lie around.
- Puppet::Util::Cacher.expire
- }
+ # This is necessary so the terminus instances don't lie around.
+ Puppet::Util::Cacher.expire
+ }
- it "should be able to read in written out CRLs with no revoked certificates" do
- ca = Puppet::SSL::CertificateAuthority.new
+ it "should be able to read in written out CRLs with no revoked certificates" do
+ ca = Puppet::SSL::CertificateAuthority.new
- raise "CRL not created" unless FileTest.exist?(Puppet[:hostcrl])
+ raise "CRL not created" unless FileTest.exist?(Puppet[:hostcrl])
- crl = Puppet::SSL::CertificateRevocationList.new("crl_int_testing")
- crl.read(Puppet[:hostcrl])
- end
+ crl = Puppet::SSL::CertificateRevocationList.new("crl_int_testing")
+ crl.read(Puppet[:hostcrl])
+ end
end
diff --git a/spec/integration/ssl/host_spec.rb b/spec/integration/ssl/host_spec.rb
index 5f2f1e5..9b4152e 100755
--- a/spec/integration/ssl/host_spec.rb
+++ b/spec/integration/ssl/host_spec.rb
@@ -9,82 +9,82 @@ require 'puppet/ssl/host'
require 'tempfile'
describe Puppet::SSL::Host do
- before do
- # Get a safe temporary file
- file = Tempfile.new("host_integration_testing")
- @dir = file.path
- file.delete
+ before do
+ # Get a safe temporary file
+ file = Tempfile.new("host_integration_testing")
+ @dir = file.path
+ file.delete
- Puppet.settings[:confdir] = @dir
- Puppet.settings[:vardir] = @dir
+ Puppet.settings[:confdir] = @dir
+ Puppet.settings[:vardir] = @dir
- Puppet::SSL::Host.ca_location = :local
+ Puppet::SSL::Host.ca_location = :local
- @host = Puppet::SSL::Host.new("luke.madstop.com")
- @ca = Puppet::SSL::CertificateAuthority.new
- end
+ @host = Puppet::SSL::Host.new("luke.madstop.com")
+ @ca = Puppet::SSL::CertificateAuthority.new
+ end
- after {
- Puppet::SSL::Host.ca_location = :none
+ after {
+ Puppet::SSL::Host.ca_location = :none
- system("rm -rf #{@dir}")
- Puppet.settings.clear
- Puppet::Util::Cacher.expire
- }
+ system("rm -rf #{@dir}")
+ Puppet.settings.clear
+ Puppet::Util::Cacher.expire
+ }
- it "should be considered a CA host if its name is equal to 'ca'" do
- Puppet::SSL::Host.new(Puppet::SSL::CA_NAME).should be_ca
- end
+ it "should be considered a CA host if its name is equal to 'ca'" do
+ Puppet::SSL::Host.new(Puppet::SSL::CA_NAME).should be_ca
+ end
- describe "when managing its key" do
- it "should be able to generate and save a key" do
- @host.generate_key
- end
+ describe "when managing its key" do
+ it "should be able to generate and save a key" do
+ @host.generate_key
+ end
- it "should save the key such that the Indirector can find it" do
- @host.generate_key
+ it "should save the key such that the Indirector can find it" do
+ @host.generate_key
- Puppet::SSL::Key.find(@host.name).content.to_s.should == @host.key.to_s
- end
+ Puppet::SSL::Key.find(@host.name).content.to_s.should == @host.key.to_s
+ end
- it "should save the private key into the :privatekeydir" do
- @host.generate_key
- File.read(File.join(Puppet.settings[:privatekeydir], "luke.madstop.com.pem")).should == @host.key.to_s
- end
+ it "should save the private key into the :privatekeydir" do
+ @host.generate_key
+ File.read(File.join(Puppet.settings[:privatekeydir], "luke.madstop.com.pem")).should == @host.key.to_s
end
+ end
- describe "when managing its certificate request" do
- it "should be able to generate and save a certificate request" do
- @host.generate_certificate_request
- end
+ describe "when managing its certificate request" do
+ it "should be able to generate and save a certificate request" do
+ @host.generate_certificate_request
+ end
- it "should save the certificate request such that the Indirector can find it" do
- @host.generate_certificate_request
+ it "should save the certificate request such that the Indirector can find it" do
+ @host.generate_certificate_request
- Puppet::SSL::CertificateRequest.find(@host.name).content.to_s.should == @host.certificate_request.to_s
- end
+ Puppet::SSL::CertificateRequest.find(@host.name).content.to_s.should == @host.certificate_request.to_s
+ end
- it "should save the private certificate request into the :privatekeydir" do
- @host.generate_certificate_request
- File.read(File.join(Puppet.settings[:requestdir], "luke.madstop.com.pem")).should == @host.certificate_request.to_s
- end
+ it "should save the private certificate request into the :privatekeydir" do
+ @host.generate_certificate_request
+ File.read(File.join(Puppet.settings[:requestdir], "luke.madstop.com.pem")).should == @host.certificate_request.to_s
end
+ end
- describe "when the CA host" do
- it "should never store its key in the :privatekeydir" do
- Puppet.settings.use(:main, :ssl, :ca)
- @ca = Puppet::SSL::Host.new(Puppet::SSL::Host.ca_name)
- @ca.generate_key
+ describe "when the CA host" do
+ it "should never store its key in the :privatekeydir" do
+ Puppet.settings.use(:main, :ssl, :ca)
+ @ca = Puppet::SSL::Host.new(Puppet::SSL::Host.ca_name)
+ @ca.generate_key
- FileTest.should_not be_exist(File.join(Puppet[:privatekeydir], "ca.pem"))
- end
+ FileTest.should_not be_exist(File.join(Puppet[:privatekeydir], "ca.pem"))
end
+ end
- it "should pass the verification of its own SSL store" do
- @host.generate
- @ca = Puppet::SSL::CertificateAuthority.new
- @ca.sign(@host.name)
+ it "should pass the verification of its own SSL store" do
+ @host.generate
+ @ca = Puppet::SSL::CertificateAuthority.new
+ @ca.sign(@host.name)
- @host.ssl_store.verify(@host.certificate.content).should be_true
- end
+ @host.ssl_store.verify(@host.certificate.content).should be_true
+ end
end
diff --git a/spec/integration/transaction/report_spec.rb b/spec/integration/transaction/report_spec.rb
index b704e56..eed7aca 100755
--- a/spec/integration/transaction/report_spec.rb
+++ b/spec/integration/transaction/report_spec.rb
@@ -6,24 +6,24 @@
require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::Transaction::Report do
- describe "when using the indirector" do
- after do
- Puppet::Util::Cacher.expire
- Puppet.settings.stubs(:use)
- end
+ describe "when using the indirector" do
+ after do
+ Puppet::Util::Cacher.expire
+ Puppet.settings.stubs(:use)
+ end
- it "should be able to delegate to the :processor terminus" do
- Puppet::Transaction::Report.indirection.stubs(:terminus_class).returns :processor
+ it "should be able to delegate to the :processor terminus" do
+ Puppet::Transaction::Report.indirection.stubs(:terminus_class).returns :processor
- terminus = Puppet::Transaction::Report.indirection.terminus(:processor)
+ terminus = Puppet::Transaction::Report.indirection.terminus(:processor)
- Facter.stubs(:value).returns "host.domain.com"
+ Facter.stubs(:value).returns "host.domain.com"
- report = Puppet::Transaction::Report.new
+ report = Puppet::Transaction::Report.new
- terminus.expects(:process).with(report)
+ terminus.expects(:process).with(report)
- report.save
- end
+ report.save
end
+ end
end
diff --git a/spec/integration/transaction_spec.rb b/spec/integration/transaction_spec.rb
index 1b8d7ec..d5478d7 100755
--- a/spec/integration/transaction_spec.rb
+++ b/spec/integration/transaction_spec.rb
@@ -7,278 +7,278 @@ require 'puppet/transaction'
require 'puppet_spec/files'
describe Puppet::Transaction do
- include PuppetSpec::Files
+ include PuppetSpec::Files
- before do
- Puppet::Util::Storage.stubs(:store)
- end
+ before do
+ Puppet::Util::Storage.stubs(:store)
+ end
- def mk_catalog(*resources)
- catalog = Puppet::Resource::Catalog.new(Puppet::Node.new("mynode"))
- resources.each { |res| catalog.add_resource res }
- catalog
- end
+ def mk_catalog(*resources)
+ catalog = Puppet::Resource::Catalog.new(Puppet::Node.new("mynode"))
+ resources.each { |res| catalog.add_resource res }
+ catalog
+ end
- it "should not apply generated resources if the parent resource fails" do
- catalog = Puppet::Resource::Catalog.new
- resource = Puppet::Type.type(:file).new :path => "/foo/bar", :backup => false
- catalog.add_resource resource
+ it "should not apply generated resources if the parent resource fails" do
+ catalog = Puppet::Resource::Catalog.new
+ resource = Puppet::Type.type(:file).new :path => "/foo/bar", :backup => false
+ catalog.add_resource resource
- child_resource = Puppet::Type.type(:file).new :path => "/foo/bar/baz", :backup => false
+ child_resource = Puppet::Type.type(:file).new :path => "/foo/bar/baz", :backup => false
- resource.expects(:eval_generate).returns([child_resource])
+ resource.expects(:eval_generate).returns([child_resource])
- transaction = Puppet::Transaction.new(catalog)
+ transaction = Puppet::Transaction.new(catalog)
- resource.expects(:retrieve).raises "this is a failure"
- resource.stubs(:err)
+ resource.expects(:retrieve).raises "this is a failure"
+ resource.stubs(:err)
- child_resource.expects(:retrieve).never
+ child_resource.expects(:retrieve).never
- transaction.evaluate
- end
+ transaction.evaluate
+ end
- it "should not apply virtual resources" do
- catalog = Puppet::Resource::Catalog.new
- resource = Puppet::Type.type(:file).new :path => "/foo/bar", :backup => false
- resource.virtual = true
- catalog.add_resource resource
+ it "should not apply virtual resources" do
+ catalog = Puppet::Resource::Catalog.new
+ resource = Puppet::Type.type(:file).new :path => "/foo/bar", :backup => false
+ resource.virtual = true
+ catalog.add_resource resource
- transaction = Puppet::Transaction.new(catalog)
+ transaction = Puppet::Transaction.new(catalog)
- resource.expects(:evaluate).never
+ resource.expects(:evaluate).never
- transaction.evaluate
- end
+ transaction.evaluate
+ end
- it "should apply exported resources" do
- catalog = Puppet::Resource::Catalog.new
- path = tmpfile("exported_files")
- resource = Puppet::Type.type(:file).new :path => path, :backup => false, :ensure => :file
- resource.exported = true
- catalog.add_resource resource
+ it "should apply exported resources" do
+ catalog = Puppet::Resource::Catalog.new
+ path = tmpfile("exported_files")
+ resource = Puppet::Type.type(:file).new :path => path, :backup => false, :ensure => :file
+ resource.exported = true
+ catalog.add_resource resource
- catalog.apply
- FileTest.should be_exist(path)
- end
+ catalog.apply
+ FileTest.should be_exist(path)
+ end
- it "should not apply virtual exported resources" do
- catalog = Puppet::Resource::Catalog.new
- resource = Puppet::Type.type(:file).new :path => "/foo/bar", :backup => false
- resource.exported = true
- resource.virtual = true
- catalog.add_resource resource
+ it "should not apply virtual exported resources" do
+ catalog = Puppet::Resource::Catalog.new
+ resource = Puppet::Type.type(:file).new :path => "/foo/bar", :backup => false
+ resource.exported = true
+ resource.virtual = true
+ catalog.add_resource resource
- transaction = Puppet::Transaction.new(catalog)
+ transaction = Puppet::Transaction.new(catalog)
- resource.expects(:evaluate).never
+ resource.expects(:evaluate).never
- transaction.evaluate
- end
+ transaction.evaluate
+ end
- # Verify that one component requiring another causes the contained
- # resources in the requiring component to get refreshed.
- it "should propagate events from a contained resource through its container to its dependent container's contained resources" do
- transaction = nil
- file = Puppet::Type.type(:file).new :path => tmpfile("event_propagation"), :ensure => :present
- execfile = File.join(tmpdir("exec_event"), "exectestingness2")
- exec = Puppet::Type.type(:exec).new :command => "touch #{execfile}", :path => ENV['PATH']
- catalog = mk_catalog(file)
+ # Verify that one component requiring another causes the contained
+ # resources in the requiring component to get refreshed.
+ it "should propagate events from a contained resource through its container to its dependent container's contained resources" do
+ transaction = nil
+ file = Puppet::Type.type(:file).new :path => tmpfile("event_propagation"), :ensure => :present
+ execfile = File.join(tmpdir("exec_event"), "exectestingness2")
+ exec = Puppet::Type.type(:exec).new :command => "touch #{execfile}", :path => ENV['PATH']
+ catalog = mk_catalog(file)
- fcomp = Puppet::Type.type(:component).new(:name => "Foo[file]")
- catalog.add_resource fcomp
- catalog.add_edge(fcomp, file)
+ fcomp = Puppet::Type.type(:component).new(:name => "Foo[file]")
+ catalog.add_resource fcomp
+ catalog.add_edge(fcomp, file)
- ecomp = Puppet::Type.type(:component).new(:name => "Foo[exec]")
- catalog.add_resource ecomp
- catalog.add_resource exec
- catalog.add_edge(ecomp, exec)
+ ecomp = Puppet::Type.type(:component).new(:name => "Foo[exec]")
+ catalog.add_resource ecomp
+ catalog.add_resource exec
+ catalog.add_edge(ecomp, exec)
- ecomp[:subscribe] = Puppet::Resource.new(:foo, "file")
- exec[:refreshonly] = true
+ ecomp[:subscribe] = Puppet::Resource.new(:foo, "file")
+ exec[:refreshonly] = true
- exec.expects(:refresh)
- catalog.apply
- end
+ exec.expects(:refresh)
+ catalog.apply
+ end
- # Make sure that multiple subscriptions get triggered.
- it "should propagate events to all dependent resources" do
- path = tmpfile("path")
- file1 = tmpfile("file1")
- file2 = tmpfile("file2")
+ # Make sure that multiple subscriptions get triggered.
+ it "should propagate events to all dependent resources" do
+ path = tmpfile("path")
+ file1 = tmpfile("file1")
+ file2 = tmpfile("file2")
- file = Puppet::Type.type(:file).new(
+ file = Puppet::Type.type(:file).new(
- :path => path,
+ :path => path,
- :ensure => "file"
- )
+ :ensure => "file"
+ )
- exec1 = Puppet::Type.type(:exec).new(
+ exec1 = Puppet::Type.type(:exec).new(
- :path => ENV["PATH"],
- :command => "touch #{file1}",
- :refreshonly => true,
+ :path => ENV["PATH"],
+ :command => "touch #{file1}",
+ :refreshonly => true,
- :subscribe => Puppet::Resource.new(:file, path)
- )
+ :subscribe => Puppet::Resource.new(:file, path)
+ )
- exec2 = Puppet::Type.type(:exec).new(
+ exec2 = Puppet::Type.type(:exec).new(
- :path => ENV["PATH"],
- :command => "touch #{file2}",
- :refreshonly => true,
+ :path => ENV["PATH"],
+ :command => "touch #{file2}",
+ :refreshonly => true,
- :subscribe => Puppet::Resource.new(:file, path)
- )
+ :subscribe => Puppet::Resource.new(:file, path)
+ )
- catalog = mk_catalog(file, exec1, exec2)
- catalog.apply
- FileTest.should be_exist(file1)
- FileTest.should be_exist(file2)
- end
+ catalog = mk_catalog(file, exec1, exec2)
+ catalog.apply
+ FileTest.should be_exist(file1)
+ FileTest.should be_exist(file2)
+ end
- it "should not let one failed refresh result in other refreshes failing" do
- path = tmpfile("path")
- newfile = tmpfile("file")
+ it "should not let one failed refresh result in other refreshes failing" do
+ path = tmpfile("path")
+ newfile = tmpfile("file")
- file = Puppet::Type.type(:file).new(
+ file = Puppet::Type.type(:file).new(
- :path => path,
+ :path => path,
- :ensure => "file"
- )
+ :ensure => "file"
+ )
- exec1 = Puppet::Type.type(:exec).new(
+ exec1 = Puppet::Type.type(:exec).new(
- :path => ENV["PATH"],
- :command => "touch /this/cannot/possibly/exist",
- :logoutput => true,
- :refreshonly => true,
- :subscribe => file,
+ :path => ENV["PATH"],
+ :command => "touch /this/cannot/possibly/exist",
+ :logoutput => true,
+ :refreshonly => true,
+ :subscribe => file,
- :title => "one"
- )
+ :title => "one"
+ )
- exec2 = Puppet::Type.type(:exec).new(
+ exec2 = Puppet::Type.type(:exec).new(
- :path => ENV["PATH"],
- :command => "touch #{newfile}",
- :logoutput => true,
- :refreshonly => true,
- :subscribe => [file, exec1],
+ :path => ENV["PATH"],
+ :command => "touch #{newfile}",
+ :logoutput => true,
+ :refreshonly => true,
+ :subscribe => [file, exec1],
- :title => "two"
- )
+ :title => "two"
+ )
- exec1.stubs(:err)
+ exec1.stubs(:err)
- catalog = mk_catalog(file, exec1, exec2)
- catalog.apply
- FileTest.should be_exists(newfile)
- end
+ catalog = mk_catalog(file, exec1, exec2)
+ catalog.apply
+ FileTest.should be_exists(newfile)
+ end
- it "should still trigger skipped resources" do
- catalog = mk_catalog
- catalog.add_resource(*Puppet::Type.type(:schedule).mkdefaultschedules)
+ it "should still trigger skipped resources" do
+ catalog = mk_catalog
+ catalog.add_resource(*Puppet::Type.type(:schedule).mkdefaultschedules)
- Puppet[:ignoreschedules] = false
+ Puppet[:ignoreschedules] = false
- file = Puppet::Type.type(:file).new(
+ file = Puppet::Type.type(:file).new(
- :name => tmpfile("file"),
+ :name => tmpfile("file"),
- :ensure => "file",
- :backup => false
- )
+ :ensure => "file",
+ :backup => false
+ )
- fname = tmpfile("exec")
+ fname = tmpfile("exec")
- exec = Puppet::Type.type(:exec).new(
+ exec = Puppet::Type.type(:exec).new(
- :name => "touch #{fname}",
- :path => "/usr/bin:/bin",
- :schedule => "monthly",
+ :name => "touch #{fname}",
+ :path => "/usr/bin:/bin",
+ :schedule => "monthly",
- :subscribe => Puppet::Resource.new("file", file.name)
- )
+ :subscribe => Puppet::Resource.new("file", file.name)
+ )
- catalog.add_resource(file, exec)
+ catalog.add_resource(file, exec)
- # Run it once
- catalog.apply
- FileTest.should be_exists(fname)
+ # Run it once
+ catalog.apply
+ FileTest.should be_exists(fname)
- # Now remove it, so it can get created again
- File.unlink(fname)
+ # Now remove it, so it can get created again
+ File.unlink(fname)
- file[:content] = "some content"
+ file[:content] = "some content"
- catalog.apply
- FileTest.should be_exists(fname)
+ catalog.apply
+ FileTest.should be_exists(fname)
- # Now remove it, so it can get created again
- File.unlink(fname)
+ # Now remove it, so it can get created again
+ File.unlink(fname)
- # And tag our exec
- exec.tag("testrun")
+ # And tag our exec
+ exec.tag("testrun")
- # And our file, so it runs
- file.tag("norun")
+ # And our file, so it runs
+ file.tag("norun")
- Puppet[:tags] = "norun"
+ Puppet[:tags] = "norun"
- file[:content] = "totally different content"
+ file[:content] = "totally different content"
- catalog.apply
- FileTest.should be_exists(fname)
- end
+ catalog.apply
+ FileTest.should be_exists(fname)
+ end
- it "should not attempt to evaluate resources with failed dependencies" do
+ it "should not attempt to evaluate resources with failed dependencies" do
- exec = Puppet::Type.type(:exec).new(
+ exec = Puppet::Type.type(:exec).new(
- :command => "/bin/mkdir /this/path/cannot/possibly/exit",
+ :command => "/bin/mkdir /this/path/cannot/possibly/exit",
- :title => "mkdir"
- )
+ :title => "mkdir"
+ )
- file1 = Puppet::Type.type(:file).new(
+ file1 = Puppet::Type.type(:file).new(
- :title => "file1",
- :path => tmpfile("file1"),
+ :title => "file1",
+ :path => tmpfile("file1"),
- :require => exec,
- :ensure => :file
- )
+ :require => exec,
+ :ensure => :file
+ )
- file2 = Puppet::Type.type(:file).new(
+ file2 = Puppet::Type.type(:file).new(
- :title => "file2",
- :path => tmpfile("file2"),
+ :title => "file2",
+ :path => tmpfile("file2"),
- :require => file1,
- :ensure => :file
- )
+ :require => file1,
+ :ensure => :file
+ )
- catalog = mk_catalog(exec, file1, file2)
- catalog.apply
+ catalog = mk_catalog(exec, file1, file2)
+ catalog.apply
- FileTest.should_not be_exists(file1[:path])
- FileTest.should_not be_exists(file2[:path])
- end
+ FileTest.should_not be_exists(file1[:path])
+ FileTest.should_not be_exists(file2[:path])
+ end
- # #801 -- resources only checked in noop should be rescheduled immediately.
- it "should immediately reschedule noop resources" do
- Puppet::Type.type(:schedule).mkdefaultschedules
- resource = Puppet::Type.type(:notify).new(:name => "mymessage", :noop => true)
- catalog = Puppet::Resource::Catalog.new
- catalog.add_resource resource
+ # #801 -- resources only checked in noop should be rescheduled immediately.
+ it "should immediately reschedule noop resources" do
+ Puppet::Type.type(:schedule).mkdefaultschedules
+ resource = Puppet::Type.type(:notify).new(:name => "mymessage", :noop => true)
+ catalog = Puppet::Resource::Catalog.new
+ catalog.add_resource resource
- trans = catalog.apply
+ trans = catalog.apply
- trans.resource_harness.should be_scheduled(trans.resource_status(resource), resource)
- end
+ trans.resource_harness.should be_scheduled(trans.resource_status(resource), resource)
+ end
end
diff --git a/spec/integration/type/file_spec.rb b/spec/integration/type/file_spec.rb
index 8ecf42b..4b91e5e 100755
--- a/spec/integration/type/file_spec.rb
+++ b/spec/integration/type/file_spec.rb
@@ -5,502 +5,502 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet_spec/files'
describe Puppet::Type.type(:file) do
- include PuppetSpec::Files
+ include PuppetSpec::Files
- before do
- # stub this to not try to create state.yaml
- Puppet::Util::Storage.stubs(:store)
- end
+ before do
+ # stub this to not try to create state.yaml
+ Puppet::Util::Storage.stubs(:store)
+ end
- it "should not attempt to manage files that do not exist if no means of creating the file is specified" do
- file = Puppet::Type.type(:file).new :path => "/my/file", :mode => "755"
- catalog = Puppet::Resource::Catalog.new
- catalog.add_resource file
+ it "should not attempt to manage files that do not exist if no means of creating the file is specified" do
+ file = Puppet::Type.type(:file).new :path => "/my/file", :mode => "755"
+ catalog = Puppet::Resource::Catalog.new
+ catalog.add_resource file
- file.parameter(:mode).expects(:retrieve).never
+ file.parameter(:mode).expects(:retrieve).never
- transaction = Puppet::Transaction.new(catalog)
- transaction.resource_harness.evaluate(file).should_not be_failed
- end
+ transaction = Puppet::Transaction.new(catalog)
+ transaction.resource_harness.evaluate(file).should_not be_failed
+ end
- describe "when writing files" do
- it "should backup files to a filebucket when one is configured" do
- bucket = Puppet::Type.type(:filebucket).new :path => tmpfile("filebucket"), :name => "mybucket"
- file = Puppet::Type.type(:file).new :path => tmpfile("bucket_backs"), :backup => "mybucket", :content => "foo"
- catalog = Puppet::Resource::Catalog.new
- catalog.add_resource file, bucket
+ describe "when writing files" do
+ it "should backup files to a filebucket when one is configured" do
+ bucket = Puppet::Type.type(:filebucket).new :path => tmpfile("filebucket"), :name => "mybucket"
+ file = Puppet::Type.type(:file).new :path => tmpfile("bucket_backs"), :backup => "mybucket", :content => "foo"
+ catalog = Puppet::Resource::Catalog.new
+ catalog.add_resource file, bucket
- File.open(file[:path], "w") { |f| f.puts "bar" }
+ File.open(file[:path], "w") { |f| f.puts "bar" }
- md5 = Digest::MD5.hexdigest(File.read(file[:path]))
+ md5 = Digest::MD5.hexdigest(File.read(file[:path]))
- catalog.apply
+ catalog.apply
- bucket.bucket.getfile(md5).should == "bar\n"
- end
+ bucket.bucket.getfile(md5).should == "bar\n"
+ end
- it "should backup files in the local directory when a backup string is provided" do
- file = Puppet::Type.type(:file).new :path => tmpfile("bucket_backs"), :backup => ".bak", :content => "foo"
- catalog = Puppet::Resource::Catalog.new
- catalog.add_resource file
+ it "should backup files in the local directory when a backup string is provided" do
+ file = Puppet::Type.type(:file).new :path => tmpfile("bucket_backs"), :backup => ".bak", :content => "foo"
+ catalog = Puppet::Resource::Catalog.new
+ catalog.add_resource file
- File.open(file[:path], "w") { |f| f.puts "bar" }
+ File.open(file[:path], "w") { |f| f.puts "bar" }
- catalog.apply
+ catalog.apply
- backup = file[:path] + ".bak"
- FileTest.should be_exist(backup)
- File.read(backup).should == "bar\n"
- end
+ backup = file[:path] + ".bak"
+ FileTest.should be_exist(backup)
+ File.read(backup).should == "bar\n"
+ end
- it "should fail if no backup can be performed" do
- dir = tmpfile("backups")
- Dir.mkdir(dir)
- path = File.join(dir, "testfile")
- file = Puppet::Type.type(:file).new :path => path, :backup => ".bak", :content => "foo"
- catalog = Puppet::Resource::Catalog.new
- catalog.add_resource file
+ it "should fail if no backup can be performed" do
+ dir = tmpfile("backups")
+ Dir.mkdir(dir)
+ path = File.join(dir, "testfile")
+ file = Puppet::Type.type(:file).new :path => path, :backup => ".bak", :content => "foo"
+ catalog = Puppet::Resource::Catalog.new
+ catalog.add_resource file
- File.open(file[:path], "w") { |f| f.puts "bar" }
+ File.open(file[:path], "w") { |f| f.puts "bar" }
- # Create a directory where the backup should be so that writing to it fails
- Dir.mkdir(File.join(dir, "testfile.bak"))
+ # Create a directory where the backup should be so that writing to it fails
+ Dir.mkdir(File.join(dir, "testfile.bak"))
- Puppet::Util::Log.stubs(:newmessage)
+ Puppet::Util::Log.stubs(:newmessage)
- catalog.apply
+ catalog.apply
- File.read(file[:path]).should == "bar\n"
- end
+ File.read(file[:path]).should == "bar\n"
+ end
- it "should not backup symlinks" do
- link = tmpfile("link")
- dest1 = tmpfile("dest1")
- dest2 = tmpfile("dest2")
- bucket = Puppet::Type.type(:filebucket).new :path => tmpfile("filebucket"), :name => "mybucket"
- file = Puppet::Type.type(:file).new :path => link, :target => dest2, :ensure => :link, :backup => "mybucket"
- catalog = Puppet::Resource::Catalog.new
- catalog.add_resource file, bucket
+ it "should not backup symlinks" do
+ link = tmpfile("link")
+ dest1 = tmpfile("dest1")
+ dest2 = tmpfile("dest2")
+ bucket = Puppet::Type.type(:filebucket).new :path => tmpfile("filebucket"), :name => "mybucket"
+ file = Puppet::Type.type(:file).new :path => link, :target => dest2, :ensure => :link, :backup => "mybucket"
+ catalog = Puppet::Resource::Catalog.new
+ catalog.add_resource file, bucket
- File.open(dest1, "w") { |f| f.puts "whatever" }
- File.symlink(dest1, link)
+ File.open(dest1, "w") { |f| f.puts "whatever" }
+ File.symlink(dest1, link)
- md5 = Digest::MD5.hexdigest(File.read(file[:path]))
+ md5 = Digest::MD5.hexdigest(File.read(file[:path]))
- catalog.apply
+ catalog.apply
- File.readlink(link).should == dest2
- Find.find(bucket[:path]) { |f| File.file?(f) }.should be_nil
- end
+ File.readlink(link).should == dest2
+ Find.find(bucket[:path]) { |f| File.file?(f) }.should be_nil
+ end
- it "should backup directories to the local filesystem by copying the whole directory" do
- file = Puppet::Type.type(:file).new :path => tmpfile("bucket_backs"), :backup => ".bak", :content => "foo", :force => true
- catalog = Puppet::Resource::Catalog.new
- catalog.add_resource file
+ it "should backup directories to the local filesystem by copying the whole directory" do
+ file = Puppet::Type.type(:file).new :path => tmpfile("bucket_backs"), :backup => ".bak", :content => "foo", :force => true
+ catalog = Puppet::Resource::Catalog.new
+ catalog.add_resource file
- Dir.mkdir(file[:path])
- otherfile = File.join(file[:path], "foo")
- File.open(otherfile, "w") { |f| f.print "yay" }
+ Dir.mkdir(file[:path])
+ otherfile = File.join(file[:path], "foo")
+ File.open(otherfile, "w") { |f| f.print "yay" }
- catalog.apply
+ catalog.apply
- backup = file[:path] + ".bak"
- FileTest.should be_directory(backup)
- File.read(File.join(backup, "foo")).should == "yay"
- end
+ backup = file[:path] + ".bak"
+ FileTest.should be_directory(backup)
+ File.read(File.join(backup, "foo")).should == "yay"
+ end
- it "should backup directories to filebuckets by backing up each file separately" do
- bucket = Puppet::Type.type(:filebucket).new :path => tmpfile("filebucket"), :name => "mybucket"
- file = Puppet::Type.type(:file).new :path => tmpfile("bucket_backs"), :backup => "mybucket", :content => "foo", :force => true
- catalog = Puppet::Resource::Catalog.new
- catalog.add_resource file, bucket
+ it "should backup directories to filebuckets by backing up each file separately" do
+ bucket = Puppet::Type.type(:filebucket).new :path => tmpfile("filebucket"), :name => "mybucket"
+ file = Puppet::Type.type(:file).new :path => tmpfile("bucket_backs"), :backup => "mybucket", :content => "foo", :force => true
+ catalog = Puppet::Resource::Catalog.new
+ catalog.add_resource file, bucket
- Dir.mkdir(file[:path])
- foofile = File.join(file[:path], "foo")
- barfile = File.join(file[:path], "bar")
- File.open(foofile, "w") { |f| f.print "fooyay" }
- File.open(barfile, "w") { |f| f.print "baryay" }
+ Dir.mkdir(file[:path])
+ foofile = File.join(file[:path], "foo")
+ barfile = File.join(file[:path], "bar")
+ File.open(foofile, "w") { |f| f.print "fooyay" }
+ File.open(barfile, "w") { |f| f.print "baryay" }
- foomd5 = Digest::MD5.hexdigest(File.read(foofile))
- barmd5 = Digest::MD5.hexdigest(File.read(barfile))
+ foomd5 = Digest::MD5.hexdigest(File.read(foofile))
+ barmd5 = Digest::MD5.hexdigest(File.read(barfile))
- catalog.apply
+ catalog.apply
- bucket.bucket.getfile(foomd5).should == "fooyay"
- bucket.bucket.getfile(barmd5).should == "baryay"
- end
+ bucket.bucket.getfile(foomd5).should == "fooyay"
+ bucket.bucket.getfile(barmd5).should == "baryay"
+ end
- it "should propagate failures encountered when renaming the temporary file" do
- file = Puppet::Type.type(:file).new :path => tmpfile("fail_rename"), :content => "foo"
- file.stubs(:remove_existing) # because it tries to make a backup
+ it "should propagate failures encountered when renaming the temporary file" do
+ file = Puppet::Type.type(:file).new :path => tmpfile("fail_rename"), :content => "foo"
+ file.stubs(:remove_existing) # because it tries to make a backup
- catalog = Puppet::Resource::Catalog.new
- catalog.add_resource file
+ catalog = Puppet::Resource::Catalog.new
+ catalog.add_resource file
- File.open(file[:path], "w") { |f| f.print "bar" }
+ File.open(file[:path], "w") { |f| f.print "bar" }
- File.expects(:rename).raises ArgumentError
+ File.expects(:rename).raises ArgumentError
- lambda { file.write(:content) }.should raise_error(Puppet::Error)
- File.read(file[:path]).should == "bar"
- end
+ lambda { file.write(:content) }.should raise_error(Puppet::Error)
+ File.read(file[:path]).should == "bar"
end
-
- describe "when recursing" do
- def build_path(dir)
- Dir.mkdir(dir)
- File.chmod(0750, dir)
-
- @dirs = [dir]
- @files = []
-
- %w{one two}.each do |subdir|
- fdir = File.join(dir, subdir)
- Dir.mkdir(fdir)
- File.chmod(0750, fdir)
- @dirs << fdir
-
- %w{three}.each do |file|
- ffile = File.join(fdir, file)
- @files << ffile
- File.open(ffile, "w") { |f| f.puts "test #{file}" }
- File.chmod(0640, ffile)
- end
- end
+ end
+
+ describe "when recursing" do
+ def build_path(dir)
+ Dir.mkdir(dir)
+ File.chmod(0750, dir)
+
+ @dirs = [dir]
+ @files = []
+
+ %w{one two}.each do |subdir|
+ fdir = File.join(dir, subdir)
+ Dir.mkdir(fdir)
+ File.chmod(0750, fdir)
+ @dirs << fdir
+
+ %w{three}.each do |file|
+ ffile = File.join(fdir, file)
+ @files << ffile
+ File.open(ffile, "w") { |f| f.puts "test #{file}" }
+ File.chmod(0640, ffile)
end
+ end
+ end
- it "should be able to recurse over a nonexistent file" do
- @path = tmpfile("file_integration_tests")
+ it "should be able to recurse over a nonexistent file" do
+ @path = tmpfile("file_integration_tests")
- @file = Puppet::Type::File.new(:name => @path, :mode => 0644, :recurse => true, :backup => false)
+ @file = Puppet::Type::File.new(:name => @path, :mode => 0644, :recurse => true, :backup => false)
- @catalog = Puppet::Resource::Catalog.new
- @catalog.add_resource @file
+ @catalog = Puppet::Resource::Catalog.new
+ @catalog.add_resource @file
- lambda { @file.eval_generate }.should_not raise_error
- end
+ lambda { @file.eval_generate }.should_not raise_error
+ end
- it "should be able to recursively set properties on existing files" do
- @path = tmpfile("file_integration_tests")
+ it "should be able to recursively set properties on existing files" do
+ @path = tmpfile("file_integration_tests")
- build_path(@path)
+ build_path(@path)
- @file = Puppet::Type::File.new(:name => @path, :mode => 0644, :recurse => true, :backup => false)
+ @file = Puppet::Type::File.new(:name => @path, :mode => 0644, :recurse => true, :backup => false)
- @catalog = Puppet::Resource::Catalog.new
- @catalog.add_resource @file
+ @catalog = Puppet::Resource::Catalog.new
+ @catalog.add_resource @file
- @catalog.apply
+ @catalog.apply
- @dirs.each do |path|
- (File.stat(path).mode & 007777).should == 0755
- end
+ @dirs.each do |path|
+ (File.stat(path).mode & 007777).should == 0755
+ end
- @files.each do |path|
- (File.stat(path).mode & 007777).should == 0644
- end
- end
+ @files.each do |path|
+ (File.stat(path).mode & 007777).should == 0644
+ end
+ end
- it "should be able to recursively make links to other files" do
- source = tmpfile("file_link_integration_source")
+ it "should be able to recursively make links to other files" do
+ source = tmpfile("file_link_integration_source")
- build_path(source)
+ build_path(source)
- dest = tmpfile("file_link_integration_dest")
+ dest = tmpfile("file_link_integration_dest")
- @file = Puppet::Type::File.new(:name => dest, :target => source, :recurse => true, :ensure => :link, :backup => false)
+ @file = Puppet::Type::File.new(:name => dest, :target => source, :recurse => true, :ensure => :link, :backup => false)
- @catalog = Puppet::Resource::Catalog.new
- @catalog.add_resource @file
+ @catalog = Puppet::Resource::Catalog.new
+ @catalog.add_resource @file
- @catalog.apply
+ @catalog.apply
- @dirs.each do |path|
- link_path = path.sub(source, dest)
+ @dirs.each do |path|
+ link_path = path.sub(source, dest)
- File.lstat(link_path).should be_directory
- end
+ File.lstat(link_path).should be_directory
+ end
- @files.each do |path|
- link_path = path.sub(source, dest)
+ @files.each do |path|
+ link_path = path.sub(source, dest)
- File.lstat(link_path).ftype.should == "link"
- end
- end
+ File.lstat(link_path).ftype.should == "link"
+ end
+ end
- it "should be able to recursively copy files" do
- source = tmpfile("file_source_integration_source")
+ it "should be able to recursively copy files" do
+ source = tmpfile("file_source_integration_source")
- build_path(source)
+ build_path(source)
- dest = tmpfile("file_source_integration_dest")
+ dest = tmpfile("file_source_integration_dest")
- @file = Puppet::Type::File.new(:name => dest, :source => source, :recurse => true, :backup => false)
+ @file = Puppet::Type::File.new(:name => dest, :source => source, :recurse => true, :backup => false)
- @catalog = Puppet::Resource::Catalog.new
- @catalog.add_resource @file
+ @catalog = Puppet::Resource::Catalog.new
+ @catalog.add_resource @file
- @catalog.apply
+ @catalog.apply
- @dirs.each do |path|
- newpath = path.sub(source, dest)
+ @dirs.each do |path|
+ newpath = path.sub(source, dest)
- File.lstat(newpath).should be_directory
- end
+ File.lstat(newpath).should be_directory
+ end
- @files.each do |path|
- newpath = path.sub(source, dest)
+ @files.each do |path|
+ newpath = path.sub(source, dest)
- File.lstat(newpath).ftype.should == "file"
- end
- end
+ File.lstat(newpath).ftype.should == "file"
+ end
+ end
- it "should not recursively manage files managed by a more specific explicit file" do
- dir = tmpfile("recursion_vs_explicit_1")
+ it "should not recursively manage files managed by a more specific explicit file" do
+ dir = tmpfile("recursion_vs_explicit_1")
- subdir = File.join(dir, "subdir")
- file = File.join(subdir, "file")
+ subdir = File.join(dir, "subdir")
+ file = File.join(subdir, "file")
- FileUtils.mkdir_p(subdir)
- File.open(file, "w") { |f| f.puts "" }
+ FileUtils.mkdir_p(subdir)
+ File.open(file, "w") { |f| f.puts "" }
- base = Puppet::Type::File.new(:name => dir, :recurse => true, :backup => false, :mode => "755")
- sub = Puppet::Type::File.new(:name => subdir, :recurse => true, :backup => false, :mode => "644")
+ base = Puppet::Type::File.new(:name => dir, :recurse => true, :backup => false, :mode => "755")
+ sub = Puppet::Type::File.new(:name => subdir, :recurse => true, :backup => false, :mode => "644")
- @catalog = Puppet::Resource::Catalog.new
- @catalog.add_resource base
- @catalog.add_resource sub
+ @catalog = Puppet::Resource::Catalog.new
+ @catalog.add_resource base
+ @catalog.add_resource sub
- @catalog.apply
+ @catalog.apply
- (File.stat(file).mode & 007777).should == 0644
- end
+ (File.stat(file).mode & 007777).should == 0644
+ end
- it "should recursively manage files even if there is an explicit file whose name is a prefix of the managed file" do
- dir = tmpfile("recursion_vs_explicit_2")
+ it "should recursively manage files even if there is an explicit file whose name is a prefix of the managed file" do
+ dir = tmpfile("recursion_vs_explicit_2")
- managed = File.join(dir, "file")
- generated = File.join(dir, "file_with_a_name_starting_with_the_word_file")
+ managed = File.join(dir, "file")
+ generated = File.join(dir, "file_with_a_name_starting_with_the_word_file")
- FileUtils.mkdir_p(dir)
- File.open(managed, "w") { |f| f.puts "" }
- File.open(generated, "w") { |f| f.puts "" }
+ FileUtils.mkdir_p(dir)
+ File.open(managed, "w") { |f| f.puts "" }
+ File.open(generated, "w") { |f| f.puts "" }
- @catalog = Puppet::Resource::Catalog.new
- @catalog.add_resource Puppet::Type::File.new(:name => dir, :recurse => true, :backup => false, :mode => "755")
- @catalog.add_resource Puppet::Type::File.new(:name => managed, :recurse => true, :backup => false, :mode => "644")
+ @catalog = Puppet::Resource::Catalog.new
+ @catalog.add_resource Puppet::Type::File.new(:name => dir, :recurse => true, :backup => false, :mode => "755")
+ @catalog.add_resource Puppet::Type::File.new(:name => managed, :recurse => true, :backup => false, :mode => "644")
- @catalog.apply
+ @catalog.apply
- (File.stat(generated).mode & 007777).should == 0755
- end
+ (File.stat(generated).mode & 007777).should == 0755
end
+ end
- describe "when generating resources" do
- before do
- @source = tmpfile("generating_in_catalog_source")
+ describe "when generating resources" do
+ before do
+ @source = tmpfile("generating_in_catalog_source")
- @dest = tmpfile("generating_in_catalog_dest")
+ @dest = tmpfile("generating_in_catalog_dest")
- Dir.mkdir(@source)
+ Dir.mkdir(@source)
- s1 = File.join(@source, "one")
- s2 = File.join(@source, "two")
+ s1 = File.join(@source, "one")
+ s2 = File.join(@source, "two")
- File.open(s1, "w") { |f| f.puts "uno" }
- File.open(s2, "w") { |f| f.puts "dos" }
+ File.open(s1, "w") { |f| f.puts "uno" }
+ File.open(s2, "w") { |f| f.puts "dos" }
- @file = Puppet::Type::File.new(:name => @dest, :source => @source, :recurse => true, :backup => false)
+ @file = Puppet::Type::File.new(:name => @dest, :source => @source, :recurse => true, :backup => false)
- @catalog = Puppet::Resource::Catalog.new
- @catalog.add_resource @file
- end
+ @catalog = Puppet::Resource::Catalog.new
+ @catalog.add_resource @file
+ end
- it "should add each generated resource to the catalog" do
- @catalog.apply do |trans|
- @catalog.resource(:file, File.join(@dest, "one")).should be_instance_of(@file.class)
- @catalog.resource(:file, File.join(@dest, "two")).should be_instance_of(@file.class)
- end
- end
+ it "should add each generated resource to the catalog" do
+ @catalog.apply do |trans|
+ @catalog.resource(:file, File.join(@dest, "one")).should be_instance_of(@file.class)
+ @catalog.resource(:file, File.join(@dest, "two")).should be_instance_of(@file.class)
+ end
+ end
- it "should have an edge to each resource in the relationship graph" do
- @catalog.apply do |trans|
- one = @catalog.resource(:file, File.join(@dest, "one"))
- @catalog.relationship_graph.should be_edge(@file, one)
+ it "should have an edge to each resource in the relationship graph" do
+ @catalog.apply do |trans|
+ one = @catalog.resource(:file, File.join(@dest, "one"))
+ @catalog.relationship_graph.should be_edge(@file, one)
- two = @catalog.resource(:file, File.join(@dest, "two"))
- @catalog.relationship_graph.should be_edge(@file, two)
- end
- end
+ two = @catalog.resource(:file, File.join(@dest, "two"))
+ @catalog.relationship_graph.should be_edge(@file, two)
+ end
end
+ end
- describe "when copying files" do
- # Ticket #285.
- it "should be able to copy files with pound signs in their names" do
- source = tmpfile("filewith#signs")
+ describe "when copying files" do
+ # Ticket #285.
+ it "should be able to copy files with pound signs in their names" do
+ source = tmpfile("filewith#signs")
- dest = tmpfile("destwith#signs")
+ dest = tmpfile("destwith#signs")
- File.open(source, "w") { |f| f.print "foo" }
+ File.open(source, "w") { |f| f.print "foo" }
- file = Puppet::Type::File.new(:name => dest, :source => source)
+ file = Puppet::Type::File.new(:name => dest, :source => source)
- catalog = Puppet::Resource::Catalog.new
- catalog.add_resource file
+ catalog = Puppet::Resource::Catalog.new
+ catalog.add_resource file
- catalog.apply
+ catalog.apply
- File.read(dest).should == "foo"
- end
+ File.read(dest).should == "foo"
+ end
- it "should be able to copy files with spaces in their names" do
- source = tmpfile("filewith spaces")
+ it "should be able to copy files with spaces in their names" do
+ source = tmpfile("filewith spaces")
- dest = tmpfile("destwith spaces")
+ dest = tmpfile("destwith spaces")
- File.open(source, "w") { |f| f.print "foo" }
- File.chmod(0755, source)
+ File.open(source, "w") { |f| f.print "foo" }
+ File.chmod(0755, source)
- file = Puppet::Type::File.new(:path => dest, :source => source)
+ file = Puppet::Type::File.new(:path => dest, :source => source)
- catalog = Puppet::Resource::Catalog.new
- catalog.add_resource file
+ catalog = Puppet::Resource::Catalog.new
+ catalog.add_resource file
- catalog.apply
+ catalog.apply
- File.read(dest).should == "foo"
- (File.stat(dest).mode & 007777).should == 0755
- end
+ File.read(dest).should == "foo"
+ (File.stat(dest).mode & 007777).should == 0755
+ end
- it "should be able to copy individual files even if recurse has been specified" do
- source = tmpfile("source")
- dest = tmpfile("dest")
+ it "should be able to copy individual files even if recurse has been specified" do
+ source = tmpfile("source")
+ dest = tmpfile("dest")
- File.open(source, "w") { |f| f.print "foo" }
+ File.open(source, "w") { |f| f.print "foo" }
- file = Puppet::Type::File.new(:name => dest, :source => source, :recurse => true)
+ file = Puppet::Type::File.new(:name => dest, :source => source, :recurse => true)
- catalog = Puppet::Resource::Catalog.new
- catalog.add_resource file
- catalog.apply
+ catalog = Puppet::Resource::Catalog.new
+ catalog.add_resource file
+ catalog.apply
- File.read(dest).should == "foo"
- end
+ File.read(dest).should == "foo"
end
+ end
- it "should be able to create files when 'content' is specified but 'ensure' is not" do
- dest = tmpfile("files_with_content")
+ it "should be able to create files when 'content' is specified but 'ensure' is not" do
+ dest = tmpfile("files_with_content")
- file = Puppet::Type.type(:file).new(
+ file = Puppet::Type.type(:file).new(
- :name => dest,
+ :name => dest,
- :content => "this is some content, yo"
- )
+ :content => "this is some content, yo"
+ )
- catalog = Puppet::Resource::Catalog.new
- catalog.add_resource file
- catalog.apply
+ catalog = Puppet::Resource::Catalog.new
+ catalog.add_resource file
+ catalog.apply
- File.read(dest).should == "this is some content, yo"
- end
+ File.read(dest).should == "this is some content, yo"
+ end
- it "should create files with content if both 'content' and 'ensure' are set" do
- dest = tmpfile("files_with_content")
+ it "should create files with content if both 'content' and 'ensure' are set" do
+ dest = tmpfile("files_with_content")
- file = Puppet::Type.type(:file).new(
+ file = Puppet::Type.type(:file).new(
- :name => dest,
- :ensure => "file",
+ :name => dest,
+ :ensure => "file",
- :content => "this is some content, yo"
- )
+ :content => "this is some content, yo"
+ )
- catalog = Puppet::Resource::Catalog.new
- catalog.add_resource file
- catalog.apply
+ catalog = Puppet::Resource::Catalog.new
+ catalog.add_resource file
+ catalog.apply
- File.read(dest).should == "this is some content, yo"
- end
+ File.read(dest).should == "this is some content, yo"
+ end
- it "should delete files with sources but that are set for deletion" do
- dest = tmpfile("dest_source_with_ensure")
- source = tmpfile("source_source_with_ensure")
- File.open(source, "w") { |f| f.puts "yay" }
- File.open(dest, "w") { |f| f.puts "boo" }
+ it "should delete files with sources but that are set for deletion" do
+ dest = tmpfile("dest_source_with_ensure")
+ source = tmpfile("source_source_with_ensure")
+ File.open(source, "w") { |f| f.puts "yay" }
+ File.open(dest, "w") { |f| f.puts "boo" }
- file = Puppet::Type.type(:file).new(
+ file = Puppet::Type.type(:file).new(
- :name => dest,
- :ensure => :absent,
- :source => source,
+ :name => dest,
+ :ensure => :absent,
+ :source => source,
- :backup => false
- )
+ :backup => false
+ )
- catalog = Puppet::Resource::Catalog.new
- catalog.add_resource file
- catalog.apply
+ catalog = Puppet::Resource::Catalog.new
+ catalog.add_resource file
+ catalog.apply
- File.should_not be_exist(dest)
- end
+ File.should_not be_exist(dest)
+ end
- describe "when purging files" do
- before do
- @sourcedir = tmpfile("purge_source")
- @destdir = tmpfile("purge_dest")
- Dir.mkdir(@sourcedir)
- Dir.mkdir(@destdir)
- @sourcefile = File.join(@sourcedir, "sourcefile")
- @copiedfile = File.join(@destdir, "sourcefile")
- @localfile = File.join(@destdir, "localfile")
- @purgee = File.join(@destdir, "to_be_purged")
- File.open(@localfile, "w") { |f| f.puts "rahtest" }
- File.open(@sourcefile, "w") { |f| f.puts "funtest" }
- # this file should get removed
- File.open(@purgee, "w") { |f| f.puts "footest" }
-
-
- @lfobj = Puppet::Type.newfile(
+ describe "when purging files" do
+ before do
+ @sourcedir = tmpfile("purge_source")
+ @destdir = tmpfile("purge_dest")
+ Dir.mkdir(@sourcedir)
+ Dir.mkdir(@destdir)
+ @sourcefile = File.join(@sourcedir, "sourcefile")
+ @copiedfile = File.join(@destdir, "sourcefile")
+ @localfile = File.join(@destdir, "localfile")
+ @purgee = File.join(@destdir, "to_be_purged")
+ File.open(@localfile, "w") { |f| f.puts "rahtest" }
+ File.open(@sourcefile, "w") { |f| f.puts "funtest" }
+ # this file should get removed
+ File.open(@purgee, "w") { |f| f.puts "footest" }
+
+
+ @lfobj = Puppet::Type.newfile(
- :title => "localfile",
- :path => @localfile,
- :content => "rahtest\n",
- :ensure => :file,
+ :title => "localfile",
+ :path => @localfile,
+ :content => "rahtest\n",
+ :ensure => :file,
- :backup => false
- )
+ :backup => false
+ )
- @destobj = Puppet::Type.newfile(
- :title => "destdir", :path => @destdir,
- :source => @sourcedir,
- :backup => false,
- :purge => true,
+ @destobj = Puppet::Type.newfile(
+ :title => "destdir", :path => @destdir,
+ :source => @sourcedir,
+ :backup => false,
+ :purge => true,
- :recurse => true)
+ :recurse => true)
- @catalog = Puppet::Resource::Catalog.new
- @catalog.add_resource @lfobj, @destobj
- end
+ @catalog = Puppet::Resource::Catalog.new
+ @catalog.add_resource @lfobj, @destobj
+ end
- it "should still copy remote files" do
- @catalog.apply
- FileTest.should be_exist(@copiedfile)
- end
+ it "should still copy remote files" do
+ @catalog.apply
+ FileTest.should be_exist(@copiedfile)
+ end
- it "should not purge managed, local files" do
- @catalog.apply
- FileTest.should be_exist(@localfile)
- end
+ it "should not purge managed, local files" do
+ @catalog.apply
+ FileTest.should be_exist(@localfile)
+ end
- it "should purge files that are neither remote nor otherwise managed" do
- @catalog.apply
- FileTest.should_not be_exist(@purgee)
- end
+ it "should purge files that are neither remote nor otherwise managed" do
+ @catalog.apply
+ FileTest.should_not be_exist(@purgee)
end
+ end
end
diff --git a/spec/integration/type/package_spec.rb b/spec/integration/type/package_spec.rb
index 4ba9285..c89c18b 100755
--- a/spec/integration/type/package_spec.rb
+++ b/spec/integration/type/package_spec.rb
@@ -3,23 +3,23 @@
require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::Type.type(:package), "when choosing a default package provider" do
- before do
- # the default provider is cached.
- Puppet::Type.type(:package).defaultprovider = nil
- end
+ before do
+ # the default provider is cached.
+ Puppet::Type.type(:package).defaultprovider = nil
+ end
- def provider_name(os)
- {"Ubuntu" => :apt, "Debian" => :apt, "Darwin" => :pkgdmg, "RedHat" => :up2date, "Fedora" => :yum, "FreeBSD" => :ports, "OpenBSD" => :openbsd, "Solaris" => :sun}[os]
- end
+ def provider_name(os)
+ {"Ubuntu" => :apt, "Debian" => :apt, "Darwin" => :pkgdmg, "RedHat" => :up2date, "Fedora" => :yum, "FreeBSD" => :ports, "OpenBSD" => :openbsd, "Solaris" => :sun}[os]
+ end
- it "should have a default provider" do
- Puppet::Type.type(:package).defaultprovider.should_not be_nil
- end
+ it "should have a default provider" do
+ Puppet::Type.type(:package).defaultprovider.should_not be_nil
+ end
- it "should choose the correct provider each platform" do
- unless default_provider = provider_name(Facter.value(:operatingsystem))
- pending("No default provider specified in this test for #{Facter.value(:operatingsystem)}")
- end
- Puppet::Type.type(:package).defaultprovider.name.should == default_provider
+ it "should choose the correct provider each platform" do
+ unless default_provider = provider_name(Facter.value(:operatingsystem))
+ pending("No default provider specified in this test for #{Facter.value(:operatingsystem)}")
end
+ Puppet::Type.type(:package).defaultprovider.name.should == default_provider
+ end
end
diff --git a/spec/integration/type/tidy_spec.rb b/spec/integration/type/tidy_spec.rb
index 732e7dc..429ba4c 100755
--- a/spec/integration/type/tidy_spec.rb
+++ b/spec/integration/type/tidy_spec.rb
@@ -6,27 +6,27 @@ require 'puppet_spec/files'
require 'puppet/file_bucket/dipper'
describe Puppet::Type.type(:tidy) do
- include PuppetSpec::Files
+ include PuppetSpec::Files
- before do
- Puppet::Util::Storage.stubs(:store)
- end
+ before do
+ Puppet::Util::Storage.stubs(:store)
+ end
- # Testing #355.
- it "should be able to remove dead links" do
- dir = tmpfile("tidy_link_testing")
- link = File.join(dir, "link")
- target = tmpfile("no_such_file_tidy_link_testing")
- Dir.mkdir(dir)
- File.symlink(target, link)
+ # Testing #355.
+ it "should be able to remove dead links" do
+ dir = tmpfile("tidy_link_testing")
+ link = File.join(dir, "link")
+ target = tmpfile("no_such_file_tidy_link_testing")
+ Dir.mkdir(dir)
+ File.symlink(target, link)
- tidy = Puppet::Type.type(:tidy).new :path => dir, :recurse => true
+ tidy = Puppet::Type.type(:tidy).new :path => dir, :recurse => true
- catalog = Puppet::Resource::Catalog.new
- catalog.add_resource(tidy)
+ catalog = Puppet::Resource::Catalog.new
+ catalog.add_resource(tidy)
- catalog.apply
+ catalog.apply
- FileTest.should_not be_symlink(link)
- end
+ FileTest.should_not be_symlink(link)
+ end
end
diff --git a/spec/integration/type_spec.rb b/spec/integration/type_spec.rb
index 78e8947..957dfe3 100755
--- a/spec/integration/type_spec.rb
+++ b/spec/integration/type_spec.rb
@@ -5,18 +5,18 @@ require File.dirname(__FILE__) + '/../spec_helper'
require 'puppet/type'
describe Puppet::Type do
- it "should not lose its provider list when it is reloaded" do
- type = Puppet::Type.newtype(:integration_test) do
- newparam(:name) {}
- end
-
- provider = type.provide(:myprovider) {}
+ it "should not lose its provider list when it is reloaded" do
+ type = Puppet::Type.newtype(:integration_test) do
+ newparam(:name) {}
+ end
- # reload it
- type = Puppet::Type.newtype(:integration_test) do
- newparam(:name) {}
- end
+ provider = type.provide(:myprovider) {}
- type.provider(:myprovider).should equal(provider)
+ # reload it
+ type = Puppet::Type.newtype(:integration_test) do
+ newparam(:name) {}
end
+
+ type.provider(:myprovider).should equal(provider)
+ end
end
diff --git a/spec/integration/util/autoload_spec.rb b/spec/integration/util/autoload_spec.rb
index ab1ff74..8a5d662 100755
--- a/spec/integration/util/autoload_spec.rb
+++ b/spec/integration/util/autoload_spec.rb
@@ -6,109 +6,109 @@ require 'puppet/util/autoload'
require 'fileutils'
class AutoloadIntegrator
- @things = []
- def self.newthing(name)
- @things << name
- end
-
- def self.thing?(name)
- @things.include? name
- end
-
- def self.clear
- @things.clear
- end
+ @things = []
+ def self.newthing(name)
+ @things << name
+ end
+
+ def self.thing?(name)
+ @things.include? name
+ end
+
+ def self.clear
+ @things.clear
+ end
end
require 'puppet_spec/files'
describe Puppet::Util::Autoload do
- include PuppetSpec::Files
-
- def with_file(name, *path)
- path = File.join(*path)
- # Now create a file to load
- File.open(path, "w") { |f|
- f.puts "\nAutoloadIntegrator.newthing(:#{name.to_s})\n"
- }
- yield
- File.delete(path)
- end
-
- def with_loader(name, path)
- dir = tmpfile(name + path)
- $LOAD_PATH << dir
- Dir.mkdir(dir)
- rbdir = File.join(dir, path.to_s)
- Dir.mkdir(rbdir)
- loader = Puppet::Util::Autoload.new(name, path)
- yield rbdir, loader
- Dir.rmdir(rbdir)
- Dir.rmdir(dir)
- $LOAD_PATH.pop
- AutoloadIntegrator.clear
- end
-
- it "should make instances available by the loading class" do
- loader = Puppet::Util::Autoload.new("foo", "bar")
- Puppet::Util::Autoload["foo"].should == loader
- end
-
- it "should not fail when asked to load a missing file" do
- Puppet::Util::Autoload.new("foo", "bar").load(:eh).should be_false
- end
-
- it "should load and return true when it successfully loads a file" do
- with_loader("foo", "bar") { |dir,loader|
- with_file(:mything, dir, "mything.rb") {
- loader.load(:mything).should be_true
- loader.should be_loaded(:mything)
- AutoloadIntegrator.should be_thing(:mything)
- }
- }
- end
-
- it "should consider a file loaded when asked for the name without an extension" do
- with_loader("foo", "bar") { |dir,loader|
- with_file(:noext, dir, "noext.rb") {
- loader.load(:noext)
- loader.should be_loaded(:noext)
- }
- }
- end
-
- it "should consider a file loaded when asked for the name with an extension" do
- with_loader("foo", "bar") { |dir,loader|
- with_file(:noext, dir, "withext.rb") {
- loader.load(:withext)
- loader.should be_loaded("withext.rb")
- }
- }
- end
-
- it "should register the fact that the instance is loaded with the Autoload base class" do
- with_loader("foo", "bar") { |dir,loader|
- with_file(:baseload, dir, "baseload.rb") {
- loader.load(:baseload)
- Puppet::Util::Autoload.should be_loaded("bar/withext.rb")
- }
- }
- end
-
- it "should be able to load files directly from modules" do
- modulepath = tmpfile("autoload_module_testing")
- libdir = File.join(modulepath, "mymod", "lib", "foo")
- FileUtils.mkdir_p(libdir)
-
- file = File.join(libdir, "plugin.rb")
-
- Puppet[:modulepath] = modulepath
-
- with_loader("foo", "foo") do |dir, loader|
- with_file(:plugin, file.split("/")) do
- loader.load(:plugin)
- loader.should be_loaded("plugin.rb")
- end
- end
+ include PuppetSpec::Files
+
+ def with_file(name, *path)
+ path = File.join(*path)
+ # Now create a file to load
+ File.open(path, "w") { |f|
+ f.puts "\nAutoloadIntegrator.newthing(:#{name.to_s})\n"
+ }
+ yield
+ File.delete(path)
+ end
+
+ def with_loader(name, path)
+ dir = tmpfile(name + path)
+ $LOAD_PATH << dir
+ Dir.mkdir(dir)
+ rbdir = File.join(dir, path.to_s)
+ Dir.mkdir(rbdir)
+ loader = Puppet::Util::Autoload.new(name, path)
+ yield rbdir, loader
+ Dir.rmdir(rbdir)
+ Dir.rmdir(dir)
+ $LOAD_PATH.pop
+ AutoloadIntegrator.clear
+ end
+
+ it "should make instances available by the loading class" do
+ loader = Puppet::Util::Autoload.new("foo", "bar")
+ Puppet::Util::Autoload["foo"].should == loader
+ end
+
+ it "should not fail when asked to load a missing file" do
+ Puppet::Util::Autoload.new("foo", "bar").load(:eh).should be_false
+ end
+
+ it "should load and return true when it successfully loads a file" do
+ with_loader("foo", "bar") { |dir,loader|
+ with_file(:mything, dir, "mything.rb") {
+ loader.load(:mything).should be_true
+ loader.should be_loaded(:mything)
+ AutoloadIntegrator.should be_thing(:mything)
+ }
+ }
+ end
+
+ it "should consider a file loaded when asked for the name without an extension" do
+ with_loader("foo", "bar") { |dir,loader|
+ with_file(:noext, dir, "noext.rb") {
+ loader.load(:noext)
+ loader.should be_loaded(:noext)
+ }
+ }
+ end
+
+ it "should consider a file loaded when asked for the name with an extension" do
+ with_loader("foo", "bar") { |dir,loader|
+ with_file(:noext, dir, "withext.rb") {
+ loader.load(:withext)
+ loader.should be_loaded("withext.rb")
+ }
+ }
+ end
+
+ it "should register the fact that the instance is loaded with the Autoload base class" do
+ with_loader("foo", "bar") { |dir,loader|
+ with_file(:baseload, dir, "baseload.rb") {
+ loader.load(:baseload)
+ Puppet::Util::Autoload.should be_loaded("bar/withext.rb")
+ }
+ }
+ end
+
+ it "should be able to load files directly from modules" do
+ modulepath = tmpfile("autoload_module_testing")
+ libdir = File.join(modulepath, "mymod", "lib", "foo")
+ FileUtils.mkdir_p(libdir)
+
+ file = File.join(libdir, "plugin.rb")
+
+ Puppet[:modulepath] = modulepath
+
+ with_loader("foo", "foo") do |dir, loader|
+ with_file(:plugin, file.split("/")) do
+ loader.load(:plugin)
+ loader.should be_loaded("plugin.rb")
+ end
end
+ end
end
diff --git a/spec/integration/util/feature_spec.rb b/spec/integration/util/feature_spec.rb
index b2adbd0..f1ada90 100755
--- a/spec/integration/util/feature_spec.rb
+++ b/spec/integration/util/feature_spec.rb
@@ -6,49 +6,49 @@ require 'puppet/util/feature'
require 'puppet_spec/files'
describe Puppet::Util::Feature do
- include PuppetSpec::Files
+ include PuppetSpec::Files
- it "should be able to load features from disk" do
- libdir = tmpfile("feature_lib")
- Dir.mkdir(libdir)
+ it "should be able to load features from disk" do
+ libdir = tmpfile("feature_lib")
+ Dir.mkdir(libdir)
- $LOAD_PATH << libdir
+ $LOAD_PATH << libdir
- $features = Puppet::Util::Feature.new("feature_lib")
+ $features = Puppet::Util::Feature.new("feature_lib")
- Dir.mkdir(File.join(libdir, "feature_lib"))
+ Dir.mkdir(File.join(libdir, "feature_lib"))
- File.open(File.join(libdir, "feature_lib", "able_to_load.rb"), "w") do |f|
- f.puts "$features.add(:able_to_load) { true }"
- end
+ File.open(File.join(libdir, "feature_lib", "able_to_load.rb"), "w") do |f|
+ f.puts "$features.add(:able_to_load) { true }"
+ end
- $features.should be_able_to_load
+ $features.should be_able_to_load
+ end
+
+ # TODO: Make this a spec test or remove it.
+ def test_dynamic_loading
+ $features = @features
+ cleanup { $features = nil }
+ # Now create a feature and make sure it loads.
+ FileUtils.mkdir_p(@path)
+ nope = File.join(@path, "nope.rb")
+ File.open(nope, "w") { |f|
+ f.puts "$features.add(:nope, :libs => %w{nosuchlib})"
+ }
+ assert_nothing_raised("Failed to autoload features") do
+ assert(! @features.nope?, "'nope' returned true")
end
- # TODO: Make this a spec test or remove it.
- def test_dynamic_loading
- $features = @features
- cleanup { $features = nil }
- # Now create a feature and make sure it loads.
- FileUtils.mkdir_p(@path)
- nope = File.join(@path, "nope.rb")
- File.open(nope, "w") { |f|
- f.puts "$features.add(:nope, :libs => %w{nosuchlib})"
- }
- assert_nothing_raised("Failed to autoload features") do
- assert(! @features.nope?, "'nope' returned true")
- end
-
- # First make sure "yep?" returns false
- assert_nothing_raised("Missing feature threw an exception") do
- assert(! @features.notyep?, "'notyep' returned true before definition")
- end
-
- yep = File.join(@path, "yep.rb")
- File.open(yep, "w") { |f|
- f.puts "$features.add(:yep, :libs => %w{puppet})"
- }
-
- assert(@features.yep?, "false 'yep' is apparently cached or feature could not be loaded")
+ # First make sure "yep?" returns false
+ assert_nothing_raised("Missing feature threw an exception") do
+ assert(! @features.notyep?, "'notyep' returned true before definition")
end
+
+ yep = File.join(@path, "yep.rb")
+ File.open(yep, "w") { |f|
+ f.puts "$features.add(:yep, :libs => %w{puppet})"
+ }
+
+ assert(@features.yep?, "false 'yep' is apparently cached or feature could not be loaded")
+ end
end
diff --git a/spec/integration/util/file_locking_spec.rb b/spec/integration/util/file_locking_spec.rb
index e584f9e..20c61d3 100755
--- a/spec/integration/util/file_locking_spec.rb
+++ b/spec/integration/util/file_locking_spec.rb
@@ -5,33 +5,33 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
require 'puppet/util/file_locking'
describe Puppet::Util::FileLocking do
- it "should be able to keep file corruption from happening when there are multiple writers" do
- file = Tempfile.new("puppetspec")
- filepath = file.path
- file.close!()
- file = filepath
- data = {:a => :b, :c => "A string", :d => "another string", :e => %w{an array of strings}}
- File.open(file, "w") { |f| f.puts YAML.dump(data) }
+ it "should be able to keep file corruption from happening when there are multiple writers" do
+ file = Tempfile.new("puppetspec")
+ filepath = file.path
+ file.close!()
+ file = filepath
+ data = {:a => :b, :c => "A string", :d => "another string", :e => %w{an array of strings}}
+ File.open(file, "w") { |f| f.puts YAML.dump(data) }
- threads = []
- sync = Sync.new
- 9.times { |a|
- threads << Thread.new {
- 9.times { |b|
- sync.synchronize(Sync::SH) {
- Puppet::Util::FileLocking.readlock(file) { |f|
- YAML.load(f.read).should == data
- }
- }
- sleep 0.01
- sync.synchronize(Sync::EX) {
- Puppet::Util::FileLocking.writelock(file) { |f|
- f.puts YAML.dump(data)
- }
- }
- }
+ threads = []
+ sync = Sync.new
+ 9.times { |a|
+ threads << Thread.new {
+ 9.times { |b|
+ sync.synchronize(Sync::SH) {
+ Puppet::Util::FileLocking.readlock(file) { |f|
+ YAML.load(f.read).should == data
}
+ }
+ sleep 0.01
+ sync.synchronize(Sync::EX) {
+ Puppet::Util::FileLocking.writelock(file) { |f|
+ f.puts YAML.dump(data)
+ }
+ }
}
- threads.each { |th| th.join }
- end
+ }
+ }
+ threads.each { |th| th.join }
+ end
end
diff --git a/spec/integration/util/rdoc/parser_spec.rb b/spec/integration/util/rdoc/parser_spec.rb
index 01bcb64..7d3b0ec 100755
--- a/spec/integration/util/rdoc/parser_spec.rb
+++ b/spec/integration/util/rdoc/parser_spec.rb
@@ -10,50 +10,50 @@ require 'rdoc/options'
require 'rdoc/rdoc'
describe RDoc::Parser do
- require 'puppet_spec/files'
- include PuppetSpec::Files
-
- before :each do
- tmpdir = tmpfile('rdoc_parser_tmp')
- Dir.mkdir(tmpdir)
- @parsedfile = File.join(tmpdir, 'init.pp')
-
- File.open(@parsedfile, 'w') do |f|
- f.puts '# comment'
- f.puts 'class ::test {}'
- end
-
- @top_level = stub_everything 'toplevel', :file_relative_name => @parsedfile
- @module = stub_everything 'module'
- @puppet_top_level = RDoc::PuppetTopLevel.new(@top_level)
- RDoc::PuppetTopLevel.stubs(:new).returns(@puppet_top_level)
- @puppet_top_level.expects(:add_module).returns(@module)
- @parser = RDoc::Parser.new(@top_level, @parsedfile, nil, Options.instance, RDoc::Stats.new)
- end
+ require 'puppet_spec/files'
+ include PuppetSpec::Files
- after(:each) do
- File.unlink(@parsedfile)
- end
+ before :each do
+ tmpdir = tmpfile('rdoc_parser_tmp')
+ Dir.mkdir(tmpdir)
+ @parsedfile = File.join(tmpdir, 'init.pp')
- def get_test_class(toplevel)
- # toplevel -> main -> test
- toplevel.classes[0].classes[0]
+ File.open(@parsedfile, 'w') do |f|
+ f.puts '# comment'
+ f.puts 'class ::test {}'
end
- it "should parse to RDoc data structure" do
- @parser.expects(:document_class).with { |n,k,c| n == "::test" and k.is_a?(Puppet::Resource::Type) }
- @parser.scan
- end
-
- it "should get a PuppetClass for the main class" do
- @parser.scan.classes[0].should be_a(RDoc::PuppetClass)
- end
-
- it "should produce a PuppetClass whose name is test" do
- get_test_class(@parser.scan).name.should == "test"
- end
-
- it "should produce a PuppetClass whose comment is 'comment'" do
- get_test_class(@parser.scan).comment.should == "comment\n"
- end
+ @top_level = stub_everything 'toplevel', :file_relative_name => @parsedfile
+ @module = stub_everything 'module'
+ @puppet_top_level = RDoc::PuppetTopLevel.new(@top_level)
+ RDoc::PuppetTopLevel.stubs(:new).returns(@puppet_top_level)
+ @puppet_top_level.expects(:add_module).returns(@module)
+ @parser = RDoc::Parser.new(@top_level, @parsedfile, nil, Options.instance, RDoc::Stats.new)
+ end
+
+ after(:each) do
+ File.unlink(@parsedfile)
+ end
+
+ def get_test_class(toplevel)
+ # toplevel -> main -> test
+ toplevel.classes[0].classes[0]
+ end
+
+ it "should parse to RDoc data structure" do
+ @parser.expects(:document_class).with { |n,k,c| n == "::test" and k.is_a?(Puppet::Resource::Type) }
+ @parser.scan
+ end
+
+ it "should get a PuppetClass for the main class" do
+ @parser.scan.classes[0].should be_a(RDoc::PuppetClass)
+ end
+
+ it "should produce a PuppetClass whose name is test" do
+ get_test_class(@parser.scan).name.should == "test"
+ end
+
+ it "should produce a PuppetClass whose comment is 'comment'" do
+ get_test_class(@parser.scan).comment.should == "comment\n"
+ end
end
diff --git a/spec/integration/util/settings_spec.rb b/spec/integration/util/settings_spec.rb
index 536eab6..27acd90 100755
--- a/spec/integration/util/settings_spec.rb
+++ b/spec/integration/util/settings_spec.rb
@@ -5,26 +5,26 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet_spec/files'
describe Puppet::Util::Settings do
- include PuppetSpec::Files
+ include PuppetSpec::Files
- def minimal_default_settings
- { :noop => {:default => false, :desc => "noop"} }
- end
+ def minimal_default_settings
+ { :noop => {:default => false, :desc => "noop"} }
+ end
- it "should be able to make needed directories" do
- settings = Puppet::Util::Settings.new
- settings.setdefaults :main, minimal_default_settings.update( :maindir => [tmpfile("main"), "a"] )
- settings.use(:main)
+ it "should be able to make needed directories" do
+ settings = Puppet::Util::Settings.new
+ settings.setdefaults :main, minimal_default_settings.update( :maindir => [tmpfile("main"), "a"] )
+ settings.use(:main)
- File.should be_directory(settings[:maindir])
- end
+ File.should be_directory(settings[:maindir])
+ end
- it "should make its directories with the corret modes" do
- settings = Puppet::Util::Settings.new
- settings.setdefaults :main, minimal_default_settings.update( :maindir => {:default => tmpfile("main"), :desc => "a", :mode => 0750} )
+ it "should make its directories with the corret modes" do
+ settings = Puppet::Util::Settings.new
+ settings.setdefaults :main, minimal_default_settings.update( :maindir => {:default => tmpfile("main"), :desc => "a", :mode => 0750} )
- settings.use(:main)
+ settings.use(:main)
- (File.stat(settings[:maindir]).mode & 007777).should == 0750
- end
+ (File.stat(settings[:maindir]).mode & 007777).should == 0750
+ end
end
diff --git a/spec/lib/puppet_spec/files.rb b/spec/lib/puppet_spec/files.rb
index aad3740..cab4a1e 100644
--- a/spec/lib/puppet_spec/files.rb
+++ b/spec/lib/puppet_spec/files.rb
@@ -2,18 +2,18 @@ require 'fileutils'
# A support module for testing files.
module PuppetSpec::Files
- def tmpfile(name)
- source = Tempfile.new(name)
- path = source.path
- source.close!
- $tmpfiles ||= []
- $tmpfiles << path
- path
- end
+ def tmpfile(name)
+ source = Tempfile.new(name)
+ path = source.path
+ source.close!
+ $tmpfiles ||= []
+ $tmpfiles << path
+ path
+ end
- def tmpdir(name)
- file = tmpfile(name)
- FileUtils.mkdir_p(file)
- file
- end
+ def tmpdir(name)
+ file = tmpfile(name)
+ FileUtils.mkdir_p(file)
+ file
+ end
end
diff --git a/spec/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb b/spec/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb
index 30e73ab..15a7cd0 100644
--- a/spec/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb
+++ b/spec/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb
@@ -1,7 +1,7 @@
dir = File.expand_path(File.dirname(__FILE__))
[ "#{dir}/../../lib", "#{dir}/../../test/lib"].each do |dir|
- fulldir = File.expand_path(dir)
- $LOAD_PATH.unshift(fulldir) unless $LOAD_PATH.include?(fulldir)
+ fulldir = File.expand_path(dir)
+ $LOAD_PATH.unshift(fulldir) unless $LOAD_PATH.include?(fulldir)
end
require 'spec'
@@ -9,39 +9,39 @@ require 'puppettest'
require 'puppettest/runnable_test'
module Spec
- module Runner
- class ExampleGroupRunner
- def run
- prepare
- success = true
- example_groups.each do |example_group|
- unless example_group.runnable?
- warn "Skipping unsuitable example group #{example_group.description}: #{example_group.messages.join(", ")}"
- next
- end
- success = success & example_group.run(@options)
- Puppet.settings.clear
- end
- return success
- ensure
- finish
- end
+ module Runner
+ class ExampleGroupRunner
+ def run
+ prepare
+ success = true
+ example_groups.each do |example_group|
+ unless example_group.runnable?
+ warn "Skipping unsuitable example group #{example_group.description}: #{example_group.messages.join(", ")}"
+ next
+ end
+ success = success & example_group.run(@options)
+ Puppet.settings.clear
end
+ return success
+ ensure
+ finish
+ end
end
+ end
end
module Spec
- module Example
- class ExampleGroup
- extend PuppetTest::RunnableTest
- end
+ module Example
+ class ExampleGroup
+ extend PuppetTest::RunnableTest
end
+ end
end
module Test
- module Unit
- class TestCase
- extend PuppetTest::RunnableTest
- end
+ module Unit
+ class TestCase
+ extend PuppetTest::RunnableTest
end
+ end
end
diff --git a/spec/monkey_patches/alias_should_to_must.rb b/spec/monkey_patches/alias_should_to_must.rb
index 02fa087..c874413 100644
--- a/spec/monkey_patches/alias_should_to_must.rb
+++ b/spec/monkey_patches/alias_should_to_must.rb
@@ -1,6 +1,6 @@
class Object
- # This is necessary because the RAL has a 'should'
- # method.
- alias :must :should
- alias :must_not :should_not
+ # This is necessary because the RAL has a 'should'
+ # method.
+ alias :must :should
+ alias :must_not :should_not
end
diff --git a/spec/shared_behaviours/file_server_terminus.rb b/spec/shared_behaviours/file_server_terminus.rb
index 674651c..665b46c 100644
--- a/spec/shared_behaviours/file_server_terminus.rb
+++ b/spec/shared_behaviours/file_server_terminus.rb
@@ -4,42 +4,42 @@
# Copyright (c) 2007. All rights reserved.
describe "Puppet::Indirector::FileServerTerminus", :shared => true do
- # This only works if the shared behaviour is included before
- # the 'before' block in the including context.
- before do
- Puppet::Util::Cacher.expire
- FileTest.stubs(:exists?).returns true
- FileTest.stubs(:exists?).with(Puppet[:fileserverconfig]).returns(true)
+ # This only works if the shared behaviour is included before
+ # the 'before' block in the including context.
+ before do
+ Puppet::Util::Cacher.expire
+ FileTest.stubs(:exists?).returns true
+ FileTest.stubs(:exists?).with(Puppet[:fileserverconfig]).returns(true)
- @path = Tempfile.new("file_server_testing")
- path = @path.path
- @path.close!
- @path = path
+ @path = Tempfile.new("file_server_testing")
+ path = @path.path
+ @path.close!
+ @path = path
- Dir.mkdir(@path)
- File.open(File.join(@path, "myfile"), "w") { |f| f.print "my content" }
+ Dir.mkdir(@path)
+ File.open(File.join(@path, "myfile"), "w") { |f| f.print "my content" }
- # Use a real mount, so the integration is a bit deeper.
- @mount1 = Puppet::FileServing::Configuration::Mount::File.new("one")
- @mount1.path = @path
+ # Use a real mount, so the integration is a bit deeper.
+ @mount1 = Puppet::FileServing::Configuration::Mount::File.new("one")
+ @mount1.path = @path
- @parser = stub 'parser', :changed? => false
- @parser.stubs(:parse).returns("one" => @mount1)
+ @parser = stub 'parser', :changed? => false
+ @parser.stubs(:parse).returns("one" => @mount1)
- Puppet::FileServing::Configuration::Parser.stubs(:new).returns(@parser)
+ Puppet::FileServing::Configuration::Parser.stubs(:new).returns(@parser)
- # Stub out the modules terminus
- @modules = mock 'modules terminus'
+ # Stub out the modules terminus
+ @modules = mock 'modules terminus'
- @request = Puppet::Indirector::Request.new(:indirection, :method, "puppet://myhost/one/myfile")
- end
+ @request = Puppet::Indirector::Request.new(:indirection, :method, "puppet://myhost/one/myfile")
+ end
- it "should use the file server configuration to find files" do
- @modules.stubs(:find).returns(nil)
- @terminus.indirection.stubs(:terminus).with(:modules).returns(@modules)
+ it "should use the file server configuration to find files" do
+ @modules.stubs(:find).returns(nil)
+ @terminus.indirection.stubs(:terminus).with(:modules).returns(@modules)
- path = File.join(@path, "myfile")
+ path = File.join(@path, "myfile")
- @terminus.find(@request).should be_instance_of(@test_class)
- end
+ @terminus.find(@request).should be_instance_of(@test_class)
+ end
end
diff --git a/spec/shared_behaviours/file_serving.rb b/spec/shared_behaviours/file_serving.rb
index 8768894..c86453a 100644
--- a/spec/shared_behaviours/file_serving.rb
+++ b/spec/shared_behaviours/file_serving.rb
@@ -4,57 +4,57 @@
# Copyright (c) 2007. All rights reserved.
describe "Puppet::FileServing::Files", :shared => true do
- it "should use the rest terminus when the 'puppet' URI scheme is used and a host name is present" do
- uri = "puppet://myhost/fakemod/my/file"
-
- # It appears that the mocking somehow interferes with the caching subsystem.
- # This mock somehow causes another terminus to get generated.
- term = @indirection.terminus(:rest)
- @indirection.stubs(:terminus).with(:rest).returns term
- term.expects(:find)
- @test_class.find(uri)
- end
-
- it "should use the rest terminus when the 'puppet' URI scheme is used, no host name is present, and the process name is not 'puppet'" do
- uri = "puppet:///fakemod/my/file"
- Puppet.settings.stubs(:value).returns "foo"
- Puppet.settings.stubs(:value).with(:name).returns("puppetd")
- Puppet.settings.stubs(:value).with(:modulepath).returns("")
- @indirection.terminus(:rest).expects(:find)
- @test_class.find(uri)
- end
-
- it "should use the file_server terminus when the 'puppet' URI scheme is used, no host name is present, and the process name is 'puppet'" do
- uri = "puppet:///fakemod/my/file"
- Puppet::Node::Environment.stubs(:new).returns(stub("env", :name => "testing", :module => nil, :modulepath => []))
- Puppet.settings.stubs(:value).returns ""
- Puppet.settings.stubs(:value).with(:name).returns("puppet")
- Puppet.settings.stubs(:value).with(:fileserverconfig).returns("/whatever")
- @indirection.terminus(:file_server).expects(:find)
- @indirection.terminus(:file_server).stubs(:authorized?).returns(true)
- @test_class.find(uri)
- end
-
- it "should use the file terminus when the 'file' URI scheme is used" do
- uri = "file:///fakemod/my/file"
- @indirection.terminus(:file).expects(:find)
- @test_class.find(uri)
- end
-
- it "should use the file terminus when a fully qualified path is provided" do
- uri = "/fakemod/my/file"
- @indirection.terminus(:file).expects(:find)
- @test_class.find(uri)
- end
-
- it "should use the configuration to test whether the request is allowed" do
- uri = "fakemod/my/file"
- mount = mock 'mount'
- config = stub 'configuration', :split_path => [mount, "eh"]
- @indirection.terminus(:file_server).stubs(:configuration).returns config
-
- @indirection.terminus(:file_server).expects(:find)
- mount.expects(:allowed?).returns(true)
- @test_class.find(uri, :node => "foo", :ip => "bar")
- end
+ it "should use the rest terminus when the 'puppet' URI scheme is used and a host name is present" do
+ uri = "puppet://myhost/fakemod/my/file"
+
+ # It appears that the mocking somehow interferes with the caching subsystem.
+ # This mock somehow causes another terminus to get generated.
+ term = @indirection.terminus(:rest)
+ @indirection.stubs(:terminus).with(:rest).returns term
+ term.expects(:find)
+ @test_class.find(uri)
+ end
+
+ it "should use the rest terminus when the 'puppet' URI scheme is used, no host name is present, and the process name is not 'puppet'" do
+ uri = "puppet:///fakemod/my/file"
+ Puppet.settings.stubs(:value).returns "foo"
+ Puppet.settings.stubs(:value).with(:name).returns("puppetd")
+ Puppet.settings.stubs(:value).with(:modulepath).returns("")
+ @indirection.terminus(:rest).expects(:find)
+ @test_class.find(uri)
+ end
+
+ it "should use the file_server terminus when the 'puppet' URI scheme is used, no host name is present, and the process name is 'puppet'" do
+ uri = "puppet:///fakemod/my/file"
+ Puppet::Node::Environment.stubs(:new).returns(stub("env", :name => "testing", :module => nil, :modulepath => []))
+ Puppet.settings.stubs(:value).returns ""
+ Puppet.settings.stubs(:value).with(:name).returns("puppet")
+ Puppet.settings.stubs(:value).with(:fileserverconfig).returns("/whatever")
+ @indirection.terminus(:file_server).expects(:find)
+ @indirection.terminus(:file_server).stubs(:authorized?).returns(true)
+ @test_class.find(uri)
+ end
+
+ it "should use the file terminus when the 'file' URI scheme is used" do
+ uri = "file:///fakemod/my/file"
+ @indirection.terminus(:file).expects(:find)
+ @test_class.find(uri)
+ end
+
+ it "should use the file terminus when a fully qualified path is provided" do
+ uri = "/fakemod/my/file"
+ @indirection.terminus(:file).expects(:find)
+ @test_class.find(uri)
+ end
+
+ it "should use the configuration to test whether the request is allowed" do
+ uri = "fakemod/my/file"
+ mount = mock 'mount'
+ config = stub 'configuration', :split_path => [mount, "eh"]
+ @indirection.terminus(:file_server).stubs(:configuration).returns config
+
+ @indirection.terminus(:file_server).expects(:find)
+ mount.expects(:allowed?).returns(true)
+ @test_class.find(uri, :node => "foo", :ip => "bar")
+ end
end
diff --git a/spec/shared_behaviours/memory_terminus.rb b/spec/shared_behaviours/memory_terminus.rb
index a00dc9f..5c9f35c 100644
--- a/spec/shared_behaviours/memory_terminus.rb
+++ b/spec/shared_behaviours/memory_terminus.rb
@@ -3,30 +3,30 @@
# Copyright (c) 2008. All rights reserved.
describe "A Memory Terminus", :shared => true do
- it "should find no instances by default" do
- @searcher.find(@request).should be_nil
- end
+ it "should find no instances by default" do
+ @searcher.find(@request).should be_nil
+ end
- it "should be able to find instances that were previously saved" do
- @searcher.save(@request)
- @searcher.find(@request).should equal(@instance)
- end
+ it "should be able to find instances that were previously saved" do
+ @searcher.save(@request)
+ @searcher.find(@request).should equal(@instance)
+ end
- it "should replace existing saved instances when a new instance with the same name is saved" do
- @searcher.save(@request)
- two = stub 'second', :name => @name
- trequest = stub 'request', :key => @name, :instance => two
- @searcher.save(trequest)
- @searcher.find(@request).should equal(two)
- end
+ it "should replace existing saved instances when a new instance with the same name is saved" do
+ @searcher.save(@request)
+ two = stub 'second', :name => @name
+ trequest = stub 'request', :key => @name, :instance => two
+ @searcher.save(trequest)
+ @searcher.find(@request).should equal(two)
+ end
- it "should be able to remove previously saved instances" do
- @searcher.save(@request)
- @searcher.destroy(@request)
- @searcher.find(@request).should be_nil
- end
+ it "should be able to remove previously saved instances" do
+ @searcher.save(@request)
+ @searcher.destroy(@request)
+ @searcher.find(@request).should be_nil
+ end
- it "should fail when asked to destroy an instance that does not exist" do
- proc { @searcher.destroy(@request) }.should raise_error(ArgumentError)
- end
+ it "should fail when asked to destroy an instance that does not exist" do
+ proc { @searcher.destroy(@request) }.should raise_error(ArgumentError)
+ end
end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 88e5228..539ae20 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -10,12 +10,12 @@ $LOAD_PATH.unshift("#{dir}/../test/lib") # Add the old test dir, so that we can
# include any gems in vendor/gems
Dir["#{dir}/../vendor/gems/**"].each do |path|
- libpath = File.join(path, "lib")
- if File.directory?(libpath)
- $LOAD_PATH.unshift(libpath)
- else
- $LOAD_PATH.unshift(path)
- end
+ libpath = File.join(path, "lib")
+ if File.directory?(libpath)
+ $LOAD_PATH.unshift(libpath)
+ else
+ $LOAD_PATH.unshift(path)
+ end
end
require 'puppettest'
@@ -26,72 +26,72 @@ require 'spec/autorun'
# So everyone else doesn't have to include this base constant.
module PuppetSpec
- FIXTURE_DIR = File.join(dir = File.expand_path(File.dirname(__FILE__)), "fixtures") unless defined?(FIXTURE_DIR)
+ FIXTURE_DIR = File.join(dir = File.expand_path(File.dirname(__FILE__)), "fixtures") unless defined?(FIXTURE_DIR)
end
# load any monkey-patches
Dir["#{dir}/monkey_patches/*.rb"].map { |file| require file }
Spec::Runner.configure do |config|
- config.mock_with :mocha
+ config.mock_with :mocha
# config.prepend_before :all do
# setup_mocks_for_rspec
# setup if respond_to? :setup
# end
#
- config.prepend_after :each do
- Puppet.settings.clear
- Puppet::Node::Environment.clear
- Puppet::Util::Storage.clear
-
- if defined?($tmpfiles)
- $tmpfiles.each do |file|
- file = File.expand_path(file)
- if Puppet.features.posix? and file !~ /^\/tmp/ and file !~ /^\/var\/folders/
- puts "Not deleting tmpfile #{file} outside of /tmp or /var/folders"
- next
- elsif Puppet.features.microsoft_windows?
- tempdir = File.expand_path(File.join(Dir::LOCAL_APPDATA, "Temp"))
- if file !~ /^#{tempdir}/
- puts "Not deleting tmpfile #{file} outside of #{tempdir}"
- next
- end
- end
- if FileTest.exist?(file)
- system("chmod -R 755 '#{file}'")
- system("rm -rf '#{file}'")
- end
- end
- $tmpfiles.clear
+ config.prepend_after :each do
+ Puppet.settings.clear
+ Puppet::Node::Environment.clear
+ Puppet::Util::Storage.clear
+
+ if defined?($tmpfiles)
+ $tmpfiles.each do |file|
+ file = File.expand_path(file)
+ if Puppet.features.posix? and file !~ /^\/tmp/ and file !~ /^\/var\/folders/
+ puts "Not deleting tmpfile #{file} outside of /tmp or /var/folders"
+ next
+ elsif Puppet.features.microsoft_windows?
+ tempdir = File.expand_path(File.join(Dir::LOCAL_APPDATA, "Temp"))
+ if file !~ /^#{tempdir}/
+ puts "Not deleting tmpfile #{file} outside of #{tempdir}"
+ next
+ end
end
-
- @logs.clear
- Puppet::Util::Log.close_all
+ if FileTest.exist?(file)
+ system("chmod -R 755 '#{file}'")
+ system("rm -rf '#{file}'")
+ end
+ end
+ $tmpfiles.clear
end
- config.prepend_before :each do
- # these globals are set by Application
- $puppet_application_mode = nil
- $puppet_application_name = nil
+ @logs.clear
+ Puppet::Util::Log.close_all
+ end
- # Set the confdir and vardir to gibberish so that tests
- # have to be correctly mocked.
- Puppet[:confdir] = "/dev/null"
- Puppet[:vardir] = "/dev/null"
+ config.prepend_before :each do
+ # these globals are set by Application
+ $puppet_application_mode = nil
+ $puppet_application_name = nil
- # Avoid opening ports to the outside world
- Puppet.settings[:bindaddress] = "127.0.0.1"
+ # Set the confdir and vardir to gibberish so that tests
+ # have to be correctly mocked.
+ Puppet[:confdir] = "/dev/null"
+ Puppet[:vardir] = "/dev/null"
- @logs = []
- Puppet::Util::Log.newdestination(@logs)
- end
+ # Avoid opening ports to the outside world
+ Puppet.settings[:bindaddress] = "127.0.0.1"
+
+ @logs = []
+ Puppet::Util::Log.newdestination(@logs)
+ end
end
# We need this because the RAL uses 'should' as a method. This
# allows us the same behaviour but with a different method name.
class Object
- alias :must :should
+ alias :must :should
end
end
diff --git a/spec/spec_specs/runnable_spec.rb b/spec/spec_specs/runnable_spec.rb
index fd2e488..da4faca 100644
--- a/spec/spec_specs/runnable_spec.rb
+++ b/spec/spec_specs/runnable_spec.rb
@@ -1,95 +1,95 @@
require File.dirname(__FILE__) + '/../spec_helper'
describe PuppetTest::RunnableTest do
- before do
- @runnable_test = Class.new.extend(PuppetTest::RunnableTest)
- end
-
- describe "#confine" do
- subject { @runnable_test }
+ before do
+ @runnable_test = Class.new.extend(PuppetTest::RunnableTest)
+ end
- it "should accept a hash" do
- subject.confine({}).should_not raise_error(ArgumentError)
- end
+ describe "#confine" do
+ subject { @runnable_test }
- it "should accept a message and a block" do
- subject.confine(""){}.should_not raise_error(ArgumentError)
- end
+ it "should accept a hash" do
+ subject.confine({}).should_not raise_error(ArgumentError)
+ end
+ it "should accept a message and a block" do
+ subject.confine(""){}.should_not raise_error(ArgumentError)
end
- describe "#runnable?" do
- describe "when the superclass is not runnable" do
- before { @runnable_test.stubs(:superclass).returns(stub("unrunnable superclass", :runnable? => false)) }
- subject { @runnable_test.runnable? }
+ end
- it { should be_false }
- end
+ describe "#runnable?" do
+ describe "when the superclass is not runnable" do
+ before { @runnable_test.stubs(:superclass).returns(stub("unrunnable superclass", :runnable? => false)) }
+ subject { @runnable_test.runnable? }
- describe "when a confine is false" do
- before { @runnable_test.confine(:message => false) }
- subject { @runnable_test.runnable? }
+ it { should be_false }
+ end
- it { should be_false }
- end
+ describe "when a confine is false" do
+ before { @runnable_test.confine(:message => false) }
+ subject { @runnable_test.runnable? }
- describe "when a confine has a block that returns false" do
- before { @runnable_test.confine(:message){ false } }
- subject { @runnable_test.runnable? }
+ it { should be_false }
+ end
- it { should be_false }
- end
+ describe "when a confine has a block that returns false" do
+ before { @runnable_test.confine(:message){ false } }
+ subject { @runnable_test.runnable? }
- describe "when a confine is true and no false confines" do
- before { @runnable_test.confine(:message => true) }
- subject { @runnable_test.runnable? }
+ it { should be_false }
+ end
- it { should be_true }
- end
+ describe "when a confine is true and no false confines" do
+ before { @runnable_test.confine(:message => true) }
+ subject { @runnable_test.runnable? }
- describe "when a confine has block that returns true and no false confines" do
- before { @runnable_test.confine(:message){ true } }
- subject { @runnable_test.runnable? }
+ it { should be_true }
+ end
- it { should be_true }
- end
+ describe "when a confine has block that returns true and no false confines" do
+ before { @runnable_test.confine(:message){ true } }
+ subject { @runnable_test.runnable? }
+ it { should be_true }
end
- describe "#messages" do
- describe "before runnable? is called" do
- subject { @runnable_test.messages }
+ end
- it { should == [] }
- end
+ describe "#messages" do
+ describe "before runnable? is called" do
+ subject { @runnable_test.messages }
- describe "when runnable? is called and returns false" do
- before do
- @runnable_test.confine(:message => false)
- @runnable_test.runnable?
- end
+ it { should == [] }
+ end
- subject { @runnable_test.messages }
+ describe "when runnable? is called and returns false" do
+ before do
+ @runnable_test.confine(:message => false)
+ @runnable_test.runnable?
+ end
- it "should include the failed confine's message" do
- should include(:message)
- end
+ subject { @runnable_test.messages }
- end
+ it "should include the failed confine's message" do
+ should include(:message)
+ end
- describe "when runnable? is called whose block returns false" do
- before do
- @runnable_test.confine(:message){ false }
- @runnable_test.runnable?
- end
+ end
- subject { @runnable_test.messages }
+ describe "when runnable? is called whose block returns false" do
+ before do
+ @runnable_test.confine(:message){ false }
+ @runnable_test.runnable?
+ end
- it "should include the failed confine's message" do
- should include(:message)
- end
+ subject { @runnable_test.messages }
- end
+ it "should include the failed confine's message" do
+ should include(:message)
+ end
end
+
+ end
end
diff --git a/spec/unit/agent/locker_spec.rb b/spec/unit/agent/locker_spec.rb
index 1477c82..ad54c76 100755
--- a/spec/unit/agent/locker_spec.rb
+++ b/spec/unit/agent/locker_spec.rb
@@ -5,96 +5,96 @@ require 'puppet/agent'
require 'puppet/agent/locker'
class LockerTester
- include Puppet::Agent::Locker
+ include Puppet::Agent::Locker
end
describe Puppet::Agent::Locker do
- before do
- @locker = LockerTester.new
- @locker.stubs(:lockfile_path).returns "/my/lock"
- end
+ before do
+ @locker = LockerTester.new
+ @locker.stubs(:lockfile_path).returns "/my/lock"
+ end
- it "should use a Pidlock instance as its lockfile" do
- @locker.lockfile.should be_instance_of(Puppet::Util::Pidlock)
- end
+ it "should use a Pidlock instance as its lockfile" do
+ @locker.lockfile.should be_instance_of(Puppet::Util::Pidlock)
+ end
- it "should use 'lockfile_path' to determine its lockfile path" do
- @locker.expects(:lockfile_path).returns "/my/lock"
- lock = Puppet::Util::Pidlock.new("/my/lock")
- Puppet::Util::Pidlock.expects(:new).with("/my/lock").returns lock
+ it "should use 'lockfile_path' to determine its lockfile path" do
+ @locker.expects(:lockfile_path).returns "/my/lock"
+ lock = Puppet::Util::Pidlock.new("/my/lock")
+ Puppet::Util::Pidlock.expects(:new).with("/my/lock").returns lock
- @locker.lockfile
- end
+ @locker.lockfile
+ end
- it "should reuse the same lock file each time" do
- @locker.lockfile.should equal(@locker.lockfile)
- end
+ it "should reuse the same lock file each time" do
+ @locker.lockfile.should equal(@locker.lockfile)
+ end
- it "should use the lock file to anonymously lock the process when disabled" do
- @locker.lockfile.expects(:lock).with(:anonymous => true)
+ it "should use the lock file to anonymously lock the process when disabled" do
+ @locker.lockfile.expects(:lock).with(:anonymous => true)
- @locker.disable
- end
+ @locker.disable
+ end
- it "should use the lock file to anonymously unlock the process when enabled" do
- @locker.lockfile.expects(:unlock).with(:anonymous => true)
+ it "should use the lock file to anonymously unlock the process when enabled" do
+ @locker.lockfile.expects(:unlock).with(:anonymous => true)
- @locker.enable
- end
+ @locker.enable
+ end
- it "should have a method that yields when a lock is attained" do
- @locker.lockfile.expects(:lock).returns true
+ it "should have a method that yields when a lock is attained" do
+ @locker.lockfile.expects(:lock).returns true
- yielded = false
- @locker.lock do
- yielded = true
- end
- yielded.should be_true
+ yielded = false
+ @locker.lock do
+ yielded = true
end
+ yielded.should be_true
+ end
- it "should return true when the lock method successfully locked" do
- @locker.lockfile.expects(:lock).returns true
+ it "should return true when the lock method successfully locked" do
+ @locker.lockfile.expects(:lock).returns true
- @locker.lock {}.should be_true
- end
+ @locker.lock {}.should be_true
+ end
- it "should return true when the lock method does not receive the lock" do
- @locker.lockfile.expects(:lock).returns false
+ it "should return true when the lock method does not receive the lock" do
+ @locker.lockfile.expects(:lock).returns false
- @locker.lock {}.should be_false
- end
+ @locker.lock {}.should be_false
+ end
- it "should not yield when the lock method does not receive the lock" do
- @locker.lockfile.expects(:lock).returns false
+ it "should not yield when the lock method does not receive the lock" do
+ @locker.lockfile.expects(:lock).returns false
- yielded = false
- @locker.lock { yielded = true }
- yielded.should be_false
- end
+ yielded = false
+ @locker.lock { yielded = true }
+ yielded.should be_false
+ end
- it "should not unlock when a lock was not received" do
- @locker.lockfile.expects(:lock).returns false
- @locker.lockfile.expects(:unlock).never
+ it "should not unlock when a lock was not received" do
+ @locker.lockfile.expects(:lock).returns false
+ @locker.lockfile.expects(:unlock).never
- @locker.lock {}
- end
+ @locker.lock {}
+ end
- it "should unlock after yielding upon obtaining a lock" do
- @locker.lockfile.stubs(:lock).returns true
- @locker.lockfile.expects(:unlock)
+ it "should unlock after yielding upon obtaining a lock" do
+ @locker.lockfile.stubs(:lock).returns true
+ @locker.lockfile.expects(:unlock)
- @locker.lock {}
- end
+ @locker.lock {}
+ end
- it "should unlock after yielding upon obtaining a lock, even if the block throws an exception" do
- @locker.lockfile.stubs(:lock).returns true
- @locker.lockfile.expects(:unlock)
+ it "should unlock after yielding upon obtaining a lock, even if the block throws an exception" do
+ @locker.lockfile.stubs(:lock).returns true
+ @locker.lockfile.expects(:unlock)
- lambda { @locker.lock { raise "foo" } }.should raise_error(RuntimeError)
- end
+ lambda { @locker.lock { raise "foo" } }.should raise_error(RuntimeError)
+ end
- it "should be considered running if the lockfile is locked" do
- @locker.lockfile.expects(:locked?).returns true
- @locker.should be_running
- end
+ it "should be considered running if the lockfile is locked" do
+ @locker.lockfile.expects(:locked?).returns true
+ @locker.should be_running
+ end
end
diff --git a/spec/unit/agent_spec.rb b/spec/unit/agent_spec.rb
index 446ec3d..2b3ee8c 100755
--- a/spec/unit/agent_spec.rb
+++ b/spec/unit/agent_spec.rb
@@ -7,275 +7,275 @@ require File.dirname(__FILE__) + '/../spec_helper'
require 'puppet/agent'
class AgentTestClient
- def run
- # no-op
- end
- def stop
- # no-op
- end
+ def run
+ # no-op
+ end
+ def stop
+ # no-op
+ end
end
def without_warnings
- flag = $VERBOSE
- $VERBOSE = nil
- yield
- $VERBOSE = flag
+ flag = $VERBOSE
+ $VERBOSE = nil
+ yield
+ $VERBOSE = flag
end
describe Puppet::Agent do
- before do
- @agent = Puppet::Agent.new(AgentTestClient)
-
- # So we don't actually try to hit the filesystem.
- @agent.stubs(:lock).yields
-
- # make Puppet::Application safe for stubbing; restore in an :after block; silence warnings for this.
- without_warnings { Puppet::Application = Class.new(Puppet::Application) }
- Puppet::Application.stubs(:clear?).returns(true)
- Puppet::Application.class_eval do
- class << self
- def controlled_run(&block)
- block.call
- end
- end
+ before do
+ @agent = Puppet::Agent.new(AgentTestClient)
+
+ # So we don't actually try to hit the filesystem.
+ @agent.stubs(:lock).yields
+
+ # make Puppet::Application safe for stubbing; restore in an :after block; silence warnings for this.
+ without_warnings { Puppet::Application = Class.new(Puppet::Application) }
+ Puppet::Application.stubs(:clear?).returns(true)
+ Puppet::Application.class_eval do
+ class << self
+ def controlled_run(&block)
+ block.call
end
+ end
end
+ end
- after do
- # restore Puppet::Application from stub-safe subclass, and silence warnings
- without_warnings { Puppet::Application = Puppet::Application.superclass }
- end
+ after do
+ # restore Puppet::Application from stub-safe subclass, and silence warnings
+ without_warnings { Puppet::Application = Puppet::Application.superclass }
+ end
- it "should set its client class at initialization" do
- Puppet::Agent.new("foo").client_class.should == "foo"
- end
+ it "should set its client class at initialization" do
+ Puppet::Agent.new("foo").client_class.should == "foo"
+ end
- it "should include the Locker module" do
- Puppet::Agent.ancestors.should be_include(Puppet::Agent::Locker)
- end
+ it "should include the Locker module" do
+ Puppet::Agent.ancestors.should be_include(Puppet::Agent::Locker)
+ end
- it "should create an instance of its client class and run it when asked to run" do
- client = mock 'client'
- AgentTestClient.expects(:new).returns client
+ it "should create an instance of its client class and run it when asked to run" do
+ client = mock 'client'
+ AgentTestClient.expects(:new).returns client
- client.expects(:run)
+ client.expects(:run)
- @agent.stubs(:running?).returns false
- @agent.run
- end
+ @agent.stubs(:running?).returns false
+ @agent.run
+ end
- it "should determine its lock file path by asking the client class" do
- AgentTestClient.expects(:lockfile_path).returns "/my/lock"
- @agent.lockfile_path.should == "/my/lock"
- end
+ it "should determine its lock file path by asking the client class" do
+ AgentTestClient.expects(:lockfile_path).returns "/my/lock"
+ @agent.lockfile_path.should == "/my/lock"
+ end
- it "should be considered running if the lock file is locked" do
- lockfile = mock 'lockfile'
+ it "should be considered running if the lock file is locked" do
+ lockfile = mock 'lockfile'
- @agent.expects(:lockfile).returns lockfile
- lockfile.expects(:locked?).returns true
+ @agent.expects(:lockfile).returns lockfile
+ lockfile.expects(:locked?).returns true
- @agent.should be_running
- end
+ @agent.should be_running
+ end
- describe "when being run" do
- before do
- @agent.stubs(:running?).returns false
- end
+ describe "when being run" do
+ before do
+ @agent.stubs(:running?).returns false
+ end
- it "should splay" do
- @agent.expects(:splay)
- @agent.stubs(:running?).returns false
+ it "should splay" do
+ @agent.expects(:splay)
+ @agent.stubs(:running?).returns false
- @agent.run
- end
+ @agent.run
+ end
- it "should do nothing if already running" do
- @agent.expects(:running?).returns true
- AgentTestClient.expects(:new).never
- @agent.run
- end
+ it "should do nothing if already running" do
+ @agent.expects(:running?).returns true
+ AgentTestClient.expects(:new).never
+ @agent.run
+ end
- it "should use Puppet::Application.controlled_run to manage process state behavior" do
- calls = sequence('calls')
- Puppet::Application.expects(:controlled_run).yields.in_sequence(calls)
- AgentTestClient.expects(:new).once.in_sequence(calls)
- @agent.run
- end
+ it "should use Puppet::Application.controlled_run to manage process state behavior" do
+ calls = sequence('calls')
+ Puppet::Application.expects(:controlled_run).yields.in_sequence(calls)
+ AgentTestClient.expects(:new).once.in_sequence(calls)
+ @agent.run
+ end
- it "should not fail if a client class instance cannot be created" do
- AgentTestClient.expects(:new).raises "eh"
- Puppet.expects(:err)
- @agent.run
- end
+ it "should not fail if a client class instance cannot be created" do
+ AgentTestClient.expects(:new).raises "eh"
+ Puppet.expects(:err)
+ @agent.run
+ end
- it "should not fail if there is an exception while running its client" do
- client = AgentTestClient.new
- AgentTestClient.expects(:new).returns client
- client.expects(:run).raises "eh"
- Puppet.expects(:err)
- @agent.run
- end
+ it "should not fail if there is an exception while running its client" do
+ client = AgentTestClient.new
+ AgentTestClient.expects(:new).returns client
+ client.expects(:run).raises "eh"
+ Puppet.expects(:err)
+ @agent.run
+ end
- it "should use a mutex to restrict multi-threading" do
- client = AgentTestClient.new
- AgentTestClient.expects(:new).returns client
+ it "should use a mutex to restrict multi-threading" do
+ client = AgentTestClient.new
+ AgentTestClient.expects(:new).returns client
- mutex = mock 'mutex'
- @agent.expects(:sync).returns mutex
+ mutex = mock 'mutex'
+ @agent.expects(:sync).returns mutex
- mutex.expects(:synchronize)
- client.expects(:run).never # if it doesn't run, then we know our yield is what triggers it
- @agent.run
- end
+ mutex.expects(:synchronize)
+ client.expects(:run).never # if it doesn't run, then we know our yield is what triggers it
+ @agent.run
+ end
- it "should use a filesystem lock to restrict multiple processes running the agent" do
- client = AgentTestClient.new
- AgentTestClient.expects(:new).returns client
+ it "should use a filesystem lock to restrict multiple processes running the agent" do
+ client = AgentTestClient.new
+ AgentTestClient.expects(:new).returns client
- @agent.expects(:lock)
+ @agent.expects(:lock)
- client.expects(:run).never # if it doesn't run, then we know our yield is what triggers it
- @agent.run
- end
+ client.expects(:run).never # if it doesn't run, then we know our yield is what triggers it
+ @agent.run
+ end
- it "should make its client instance available while running" do
- client = AgentTestClient.new
- AgentTestClient.expects(:new).returns client
+ it "should make its client instance available while running" do
+ client = AgentTestClient.new
+ AgentTestClient.expects(:new).returns client
- client.expects(:run).with { @agent.client.should equal(client); true }
- @agent.run
- end
+ client.expects(:run).with { @agent.client.should equal(client); true }
+ @agent.run
+ end
- it "should run the client instance with any arguments passed to it" do
- client = AgentTestClient.new
- AgentTestClient.expects(:new).returns client
+ it "should run the client instance with any arguments passed to it" do
+ client = AgentTestClient.new
+ AgentTestClient.expects(:new).returns client
- client.expects(:run).with("testargs")
- @agent.run("testargs")
- end
+ client.expects(:run).with("testargs")
+ @agent.run("testargs")
end
+ end
- describe "when splaying" do
- before do
- Puppet.settings.stubs(:value).with(:splay).returns true
- Puppet.settings.stubs(:value).with(:splaylimit).returns "10"
- end
+ describe "when splaying" do
+ before do
+ Puppet.settings.stubs(:value).with(:splay).returns true
+ Puppet.settings.stubs(:value).with(:splaylimit).returns "10"
+ end
- it "should do nothing if splay is disabled" do
- Puppet.settings.expects(:value).returns false
- @agent.expects(:sleep).never
- @agent.splay
- end
+ it "should do nothing if splay is disabled" do
+ Puppet.settings.expects(:value).returns false
+ @agent.expects(:sleep).never
+ @agent.splay
+ end
- it "should do nothing if it has already splayed" do
- @agent.expects(:splayed?).returns true
- @agent.expects(:sleep).never
- @agent.splay
- end
+ it "should do nothing if it has already splayed" do
+ @agent.expects(:splayed?).returns true
+ @agent.expects(:sleep).never
+ @agent.splay
+ end
- it "should log that it is splaying" do
- @agent.stubs :sleep
- Puppet.expects :info
- @agent.splay
- end
+ it "should log that it is splaying" do
+ @agent.stubs :sleep
+ Puppet.expects :info
+ @agent.splay
+ end
- it "should sleep for a random portion of the splaylimit plus 1" do
- Puppet.settings.expects(:value).with(:splaylimit).returns "50"
- @agent.expects(:rand).with(51).returns 10
- @agent.expects(:sleep).with(10)
- @agent.splay
- end
+ it "should sleep for a random portion of the splaylimit plus 1" do
+ Puppet.settings.expects(:value).with(:splaylimit).returns "50"
+ @agent.expects(:rand).with(51).returns 10
+ @agent.expects(:sleep).with(10)
+ @agent.splay
+ end
- it "should mark that it has splayed" do
- @agent.stubs(:sleep)
- @agent.splay
- @agent.should be_splayed
- end
+ it "should mark that it has splayed" do
+ @agent.stubs(:sleep)
+ @agent.splay
+ @agent.should be_splayed
end
+ end
+
+ describe "when checking execution state" do
+ describe 'with regular run status' do
+ before :each do
+ Puppet::Application.stubs(:restart_requested?).returns(false)
+ Puppet::Application.stubs(:stop_requested?).returns(false)
+ Puppet::Application.stubs(:interrupted?).returns(false)
+ Puppet::Application.stubs(:clear?).returns(true)
+ end
- describe "when checking execution state" do
- describe 'with regular run status' do
- before :each do
- Puppet::Application.stubs(:restart_requested?).returns(false)
- Puppet::Application.stubs(:stop_requested?).returns(false)
- Puppet::Application.stubs(:interrupted?).returns(false)
- Puppet::Application.stubs(:clear?).returns(true)
- end
-
- it 'should be false for :stopping?' do
- @agent.stopping?.should be_false
- end
-
- it 'should be false for :needing_restart?' do
- @agent.needing_restart?.should be_false
- end
- end
+ it 'should be false for :stopping?' do
+ @agent.stopping?.should be_false
+ end
- describe 'with a stop requested' do
- before :each do
- Puppet::Application.stubs(:clear?).returns(false)
- Puppet::Application.stubs(:restart_requested?).returns(false)
- Puppet::Application.stubs(:stop_requested?).returns(true)
- Puppet::Application.stubs(:interrupted?).returns(true)
- end
-
- it 'should be true for :stopping?' do
- @agent.stopping?.should be_true
- end
-
- it 'should be false for :needing_restart?' do
- @agent.needing_restart?.should be_false
- end
- end
+ it 'should be false for :needing_restart?' do
+ @agent.needing_restart?.should be_false
+ end
+ end
- describe 'with a restart requested' do
- before :each do
- Puppet::Application.stubs(:clear?).returns(false)
- Puppet::Application.stubs(:restart_requested?).returns(true)
- Puppet::Application.stubs(:stop_requested?).returns(false)
- Puppet::Application.stubs(:interrupted?).returns(true)
- end
-
- it 'should be false for :stopping?' do
- @agent.stopping?.should be_false
- end
-
- it 'should be true for :needing_restart?' do
- @agent.needing_restart?.should be_true
- end
- end
+ describe 'with a stop requested' do
+ before :each do
+ Puppet::Application.stubs(:clear?).returns(false)
+ Puppet::Application.stubs(:restart_requested?).returns(false)
+ Puppet::Application.stubs(:stop_requested?).returns(true)
+ Puppet::Application.stubs(:interrupted?).returns(true)
+ end
+
+ it 'should be true for :stopping?' do
+ @agent.stopping?.should be_true
+ end
+
+ it 'should be false for :needing_restart?' do
+ @agent.needing_restart?.should be_false
+ end
end
- describe "when starting" do
- before do
- @agent.stubs(:observe_signal)
- end
+ describe 'with a restart requested' do
+ before :each do
+ Puppet::Application.stubs(:clear?).returns(false)
+ Puppet::Application.stubs(:restart_requested?).returns(true)
+ Puppet::Application.stubs(:stop_requested?).returns(false)
+ Puppet::Application.stubs(:interrupted?).returns(true)
+ end
+
+ it 'should be false for :stopping?' do
+ @agent.stopping?.should be_false
+ end
+
+ it 'should be true for :needing_restart?' do
+ @agent.needing_restart?.should be_true
+ end
+ end
+ end
+
+ describe "when starting" do
+ before do
+ @agent.stubs(:observe_signal)
+ end
- it "should create a timer with the runinterval, a tolerance of 1, and :start? set to true" do
- Puppet.settings.expects(:value).with(:runinterval).returns 5
- timer = stub 'timer', :sound_alarm => nil
- EventLoop::Timer.expects(:new).with(:interval => 5, :start? => true, :tolerance => 1).returns timer
+ it "should create a timer with the runinterval, a tolerance of 1, and :start? set to true" do
+ Puppet.settings.expects(:value).with(:runinterval).returns 5
+ timer = stub 'timer', :sound_alarm => nil
+ EventLoop::Timer.expects(:new).with(:interval => 5, :start? => true, :tolerance => 1).returns timer
- @agent.stubs(:run)
- @agent.start
- end
+ @agent.stubs(:run)
+ @agent.start
+ end
- it "should run once immediately" do
- timer = mock 'timer'
- EventLoop::Timer.expects(:new).returns timer
+ it "should run once immediately" do
+ timer = mock 'timer'
+ EventLoop::Timer.expects(:new).returns timer
- timer.expects(:sound_alarm)
+ timer.expects(:sound_alarm)
- @agent.start
- end
+ @agent.start
+ end
- it "should run within the block passed to the timer" do
- timer = stub 'timer', :sound_alarm => nil
- EventLoop::Timer.expects(:new).returns(timer).yields
- @agent.expects(:run)
+ it "should run within the block passed to the timer" do
+ timer = stub 'timer', :sound_alarm => nil
+ EventLoop::Timer.expects(:new).returns(timer).yields
+ @agent.expects(:run)
- @agent.start
- end
+ @agent.start
end
+ end
end
diff --git a/spec/unit/application/agent_spec.rb b/spec/unit/application/agent_spec.rb
index 30d8edb..079e0ad 100755
--- a/spec/unit/application/agent_spec.rb
+++ b/spec/unit/application/agent_spec.rb
@@ -8,597 +8,597 @@ require 'puppet/network/server'
require 'puppet/daemon'
describe Puppet::Application::Agent do
+ before :each do
+ @puppetd = Puppet::Application[:agent]
+ @puppetd.stubs(:puts)
+ @daemon = stub_everything 'daemon'
+ Puppet::Daemon.stubs(:new).returns(@daemon)
+ @agent = stub_everything 'agent'
+ Puppet::Agent.stubs(:new).returns(@agent)
+ @puppetd.preinit
+ Puppet::Util::Log.stubs(:newdestination)
+ Puppet::Util::Log.stubs(:level=)
+
+ Puppet::Node.stubs(:terminus_class=)
+ Puppet::Node.stubs(:cache_class=)
+ Puppet::Node::Facts.stubs(:terminus_class=)
+ end
+
+ it "should operate in agent run_mode" do
+ @puppetd.class.run_mode.name.should == :agent
+ end
+
+ it "should ask Puppet::Application to parse Puppet configuration file" do
+ @puppetd.should_parse_config?.should be_true
+ end
+
+ it "should declare a main command" do
+ @puppetd.should respond_to(:main)
+ end
+
+ it "should declare a onetime command" do
+ @puppetd.should respond_to(:onetime)
+ end
+
+ it "should declare a fingerprint command" do
+ @puppetd.should respond_to(:fingerprint)
+ end
+
+ it "should declare a preinit block" do
+ @puppetd.should respond_to(:preinit)
+ end
+
+ describe "in preinit" do
before :each do
- @puppetd = Puppet::Application[:agent]
- @puppetd.stubs(:puts)
- @daemon = stub_everything 'daemon'
- Puppet::Daemon.stubs(:new).returns(@daemon)
- @agent = stub_everything 'agent'
- Puppet::Agent.stubs(:new).returns(@agent)
- @puppetd.preinit
- Puppet::Util::Log.stubs(:newdestination)
- Puppet::Util::Log.stubs(:level=)
-
- Puppet::Node.stubs(:terminus_class=)
- Puppet::Node.stubs(:cache_class=)
- Puppet::Node::Facts.stubs(:terminus_class=)
+ @puppetd.stubs(:trap)
end
- it "should operate in agent run_mode" do
- @puppetd.class.run_mode.name.should == :agent
- end
+ it "should catch INT" do
+ @puppetd.expects(:trap).with { |arg,block| arg == :INT }
- it "should ask Puppet::Application to parse Puppet configuration file" do
- @puppetd.should_parse_config?.should be_true
+ @puppetd.preinit
end
- it "should declare a main command" do
- @puppetd.should respond_to(:main)
- end
+ it "should set waitforcert to 120" do
+ @puppetd.preinit
- it "should declare a onetime command" do
- @puppetd.should respond_to(:onetime)
+ @puppetd.options[:waitforcert].should == 120
end
- it "should declare a fingerprint command" do
- @puppetd.should respond_to(:fingerprint)
- end
+ it "should init client to true" do
+ @puppetd.preinit
- it "should declare a preinit block" do
- @puppetd.should respond_to(:preinit)
+ @puppetd.options[:client].should be_true
end
- describe "in preinit" do
- before :each do
- @puppetd.stubs(:trap)
- end
-
- it "should catch INT" do
- @puppetd.expects(:trap).with { |arg,block| arg == :INT }
+ it "should init fqdn to nil" do
+ @puppetd.preinit
- @puppetd.preinit
- end
-
- it "should set waitforcert to 120" do
- @puppetd.preinit
-
- @puppetd.options[:waitforcert].should == 120
- end
-
- it "should init client to true" do
- @puppetd.preinit
+ @puppetd.options[:fqdn].should be_nil
+ end
- @puppetd.options[:client].should be_true
- end
+ it "should init serve to []" do
+ @puppetd.preinit
- it "should init fqdn to nil" do
- @puppetd.preinit
+ @puppetd.options[:serve].should == []
+ end
- @puppetd.options[:fqdn].should be_nil
- end
+ it "should use MD5 as default digest algorithm" do
+ @puppetd.preinit
- it "should init serve to []" do
- @puppetd.preinit
+ @puppetd.options[:digest].should == :MD5
+ end
- @puppetd.options[:serve].should == []
- end
+ it "should not fingerprint by default" do
+ @puppetd.preinit
- it "should use MD5 as default digest algorithm" do
- @puppetd.preinit
+ @puppetd.options[:fingerprint].should be_false
+ end
+ end
- @puppetd.options[:digest].should == :MD5
- end
+ describe "when handling options" do
+ before do
+ @puppetd.command_line.stubs(:args).returns([])
+ end
- it "should not fingerprint by default" do
- @puppetd.preinit
+ [:centrallogging, :disable, :enable, :debug, :fqdn, :test, :verbose, :digest].each do |option|
+ it "should declare handle_#{option} method" do
+ @puppetd.should respond_to("handle_#{option}".to_sym)
+ end
- @puppetd.options[:fingerprint].should be_false
- end
+ it "should store argument value when calling handle_#{option}" do
+ @puppetd.options.expects(:[]=).with(option, 'arg')
+ @puppetd.send("handle_#{option}".to_sym, 'arg')
+ end
end
- describe "when handling options" do
- before do
- @puppetd.command_line.stubs(:args).returns([])
- end
+ it "should set an existing handler on server" do
+ Puppet::Network::Handler.stubs(:handler).with("handler").returns(true)
- [:centrallogging, :disable, :enable, :debug, :fqdn, :test, :verbose, :digest].each do |option|
- it "should declare handle_#{option} method" do
- @puppetd.should respond_to("handle_#{option}".to_sym)
- end
+ @puppetd.handle_serve("handler")
+ @puppetd.options[:serve].should == [ :handler ]
+ end
- it "should store argument value when calling handle_#{option}" do
- @puppetd.options.expects(:[]=).with(option, 'arg')
- @puppetd.send("handle_#{option}".to_sym, 'arg')
- end
- end
+ it "should set client to false with --no-client" do
+ @puppetd.handle_no_client(nil)
+ @puppetd.options[:client].should be_false
+ end
- it "should set an existing handler on server" do
- Puppet::Network::Handler.stubs(:handler).with("handler").returns(true)
+ it "should set onetime to true with --onetime" do
+ @puppetd.handle_onetime(nil)
+ Puppet[:onetime].should be_true
+ end
- @puppetd.handle_serve("handler")
- @puppetd.options[:serve].should == [ :handler ]
- end
+ it "should set waitforcert to 0 with --onetime and if --waitforcert wasn't given" do
+ @puppetd.explicit_waitforcert = false
+ @puppetd.handle_onetime(nil)
+ @puppetd.options[:waitforcert].should == 0
+ end
- it "should set client to false with --no-client" do
- @puppetd.handle_no_client(nil)
- @puppetd.options[:client].should be_false
- end
+ it "should not reset waitforcert with --onetime when --waitforcert is used" do
+ @puppetd.explicit_waitforcert = true
+ @puppetd.handle_onetime(nil)
+ @puppetd.options[:waitforcert].should_not == 0
+ end
- it "should set onetime to true with --onetime" do
- @puppetd.handle_onetime(nil)
- Puppet[:onetime].should be_true
- end
+ it "should set the log destination with --logdest" do
+ @puppetd.options.stubs(:[]=).with { |opt,val| opt == :setdest }
+ Puppet::Log.expects(:newdestination).with("console")
- it "should set waitforcert to 0 with --onetime and if --waitforcert wasn't given" do
- @puppetd.explicit_waitforcert = false
- @puppetd.handle_onetime(nil)
- @puppetd.options[:waitforcert].should == 0
- end
+ @puppetd.handle_logdest("console")
+ end
- it "should not reset waitforcert with --onetime when --waitforcert is used" do
- @puppetd.explicit_waitforcert = true
- @puppetd.handle_onetime(nil)
- @puppetd.options[:waitforcert].should_not == 0
- end
+ it "should put the setdest options to true" do
+ @puppetd.options.expects(:[]=).with(:setdest,true)
- it "should set the log destination with --logdest" do
- @puppetd.options.stubs(:[]=).with { |opt,val| opt == :setdest }
- Puppet::Log.expects(:newdestination).with("console")
+ @puppetd.handle_logdest("console")
+ end
- @puppetd.handle_logdest("console")
- end
+ it "should parse the log destination from the command line" do
+ @puppetd.command_line.stubs(:args).returns(%w{--logdest /my/file})
- it "should put the setdest options to true" do
- @puppetd.options.expects(:[]=).with(:setdest,true)
+ Puppet::Util::Log.expects(:newdestination).with("/my/file")
- @puppetd.handle_logdest("console")
- end
+ @puppetd.parse_options
+ end
- it "should parse the log destination from the command line" do
- @puppetd.command_line.stubs(:args).returns(%w{--logdest /my/file})
+ it "should store the waitforcert options with --waitforcert" do
+ @puppetd.options.expects(:[]=).with(:waitforcert,42)
- Puppet::Util::Log.expects(:newdestination).with("/my/file")
+ @puppetd.handle_waitforcert("42")
+ end
- @puppetd.parse_options
- end
+ it "should mark explicit_waitforcert to true with --waitforcert" do
+ @puppetd.options.stubs(:[]=)
- it "should store the waitforcert options with --waitforcert" do
- @puppetd.options.expects(:[]=).with(:waitforcert,42)
+ @puppetd.handle_waitforcert("42")
+ @puppetd.explicit_waitforcert.should be_true
+ end
- @puppetd.handle_waitforcert("42")
- end
+ it "should set args[:Port] with --port" do
+ @puppetd.handle_port("42")
+ @puppetd.args[:Port].should == "42"
+ end
- it "should mark explicit_waitforcert to true with --waitforcert" do
- @puppetd.options.stubs(:[]=)
+ end
- @puppetd.handle_waitforcert("42")
- @puppetd.explicit_waitforcert.should be_true
- end
+ describe "during setup" do
+ before :each do
+ @puppetd.options.stubs(:[])
+ Puppet.stubs(:info)
+ FileTest.stubs(:exists?).returns(true)
+ Puppet.stubs(:[])
+ Puppet.stubs(:[]=)
+ Puppet.stubs(:[]).with(:libdir).returns("/dev/null/lib")
+ Puppet.settings.stubs(:print_config?)
+ Puppet.settings.stubs(:print_config)
+ Puppet::SSL::Host.stubs(:ca_location=)
+ Puppet::Transaction::Report.stubs(:terminus_class=)
+ Puppet::Resource::Catalog.stubs(:terminus_class=)
+ Puppet::Resource::Catalog.stubs(:cache_class=)
+ Puppet::Node::Facts.stubs(:terminus_class=)
+ @host = stub_everything 'host'
+ Puppet::SSL::Host.stubs(:new).returns(@host)
+ Puppet.stubs(:settraps)
+ end
- it "should set args[:Port] with --port" do
- @puppetd.handle_port("42")
- @puppetd.args[:Port].should == "42"
- end
+ describe "with --test" do
+ before :each do
+ Puppet.settings.stubs(:handlearg)
+ @puppetd.options.stubs(:[]=)
+ end
+
+ it "should call setup_test" do
+ @puppetd.options.stubs(:[]).with(:test).returns(true)
+ @puppetd.expects(:setup_test)
+ @puppetd.setup
+ end
+
+ it "should set options[:verbose] to true" do
+ @puppetd.options.expects(:[]=).with(:verbose,true)
+ @puppetd.setup_test
+ end
+ it "should set options[:onetime] to true" do
+ Puppet.expects(:[]=).with(:onetime,true)
+ @puppetd.setup_test
+ end
+ it "should set options[:detailed_exitcodes] to true" do
+ @puppetd.options.expects(:[]=).with(:detailed_exitcodes,true)
+ @puppetd.setup_test
+ end
+ it "should set waitforcert to 0" do
+ @puppetd.options.expects(:[]=).with(:waitforcert,0)
+ @puppetd.setup_test
+ end
+ end
+ it "should call setup_logs" do
+ @puppetd.expects(:setup_logs)
+ @puppetd.setup
end
- describe "during setup" do
- before :each do
- @puppetd.options.stubs(:[])
- Puppet.stubs(:info)
- FileTest.stubs(:exists?).returns(true)
- Puppet.stubs(:[])
- Puppet.stubs(:[]=)
- Puppet.stubs(:[]).with(:libdir).returns("/dev/null/lib")
- Puppet.settings.stubs(:print_config?)
- Puppet.settings.stubs(:print_config)
- Puppet::SSL::Host.stubs(:ca_location=)
- Puppet::Transaction::Report.stubs(:terminus_class=)
- Puppet::Resource::Catalog.stubs(:terminus_class=)
- Puppet::Resource::Catalog.stubs(:cache_class=)
- Puppet::Node::Facts.stubs(:terminus_class=)
- @host = stub_everything 'host'
- Puppet::SSL::Host.stubs(:new).returns(@host)
- Puppet.stubs(:settraps)
- end
+ describe "when setting up logs" do
+ before :each do
+ Puppet::Util::Log.stubs(:newdestination)
+ end
- describe "with --test" do
- before :each do
- Puppet.settings.stubs(:handlearg)
- @puppetd.options.stubs(:[]=)
- end
-
- it "should call setup_test" do
- @puppetd.options.stubs(:[]).with(:test).returns(true)
- @puppetd.expects(:setup_test)
- @puppetd.setup
- end
-
- it "should set options[:verbose] to true" do
- @puppetd.options.expects(:[]=).with(:verbose,true)
- @puppetd.setup_test
- end
- it "should set options[:onetime] to true" do
- Puppet.expects(:[]=).with(:onetime,true)
- @puppetd.setup_test
- end
- it "should set options[:detailed_exitcodes] to true" do
- @puppetd.options.expects(:[]=).with(:detailed_exitcodes,true)
- @puppetd.setup_test
- end
- it "should set waitforcert to 0" do
- @puppetd.options.expects(:[]=).with(:waitforcert,0)
- @puppetd.setup_test
- end
- end
+ it "should set log level to debug if --debug was passed" do
+ @puppetd.options.stubs(:[]).with(:debug).returns(true)
- it "should call setup_logs" do
- @puppetd.expects(:setup_logs)
- @puppetd.setup
- end
+ Puppet::Util::Log.expects(:level=).with(:debug)
- describe "when setting up logs" do
- before :each do
- Puppet::Util::Log.stubs(:newdestination)
- end
+ @puppetd.setup_logs
+ end
- it "should set log level to debug if --debug was passed" do
- @puppetd.options.stubs(:[]).with(:debug).returns(true)
+ it "should set log level to info if --verbose was passed" do
+ @puppetd.options.stubs(:[]).with(:verbose).returns(true)
- Puppet::Util::Log.expects(:level=).with(:debug)
+ Puppet::Util::Log.expects(:level=).with(:info)
- @puppetd.setup_logs
- end
+ @puppetd.setup_logs
+ end
- it "should set log level to info if --verbose was passed" do
- @puppetd.options.stubs(:[]).with(:verbose).returns(true)
+ [:verbose, :debug].each do |level|
+ it "should set console as the log destination with level #{level}" do
+ @puppetd.options.stubs(:[]).with(level).returns(true)
- Puppet::Util::Log.expects(:level=).with(:info)
+ Puppet::Util::Log.expects(:newdestination).with(:console)
- @puppetd.setup_logs
- end
+ @puppetd.setup_logs
+ end
+ end
- [:verbose, :debug].each do |level|
- it "should set console as the log destination with level #{level}" do
- @puppetd.options.stubs(:[]).with(level).returns(true)
+ it "should set syslog as the log destination if no --logdest" do
+ @puppetd.options.stubs(:[]).with(:setdest).returns(false)
- Puppet::Util::Log.expects(:newdestination).with(:console)
+ Puppet::Util::Log.expects(:newdestination).with(:syslog)
- @puppetd.setup_logs
- end
- end
+ @puppetd.setup_logs
+ end
- it "should set syslog as the log destination if no --logdest" do
- @puppetd.options.stubs(:[]).with(:setdest).returns(false)
+ end
- Puppet::Util::Log.expects(:newdestination).with(:syslog)
+ it "should print puppet config if asked to in Puppet config" do
+ @puppetd.stubs(:exit)
+ Puppet.settings.stubs(:print_configs?).returns(true)
- @puppetd.setup_logs
- end
+ Puppet.settings.expects(:print_configs)
- end
+ @puppetd.setup
+ end
- it "should print puppet config if asked to in Puppet config" do
- @puppetd.stubs(:exit)
- Puppet.settings.stubs(:print_configs?).returns(true)
+ it "should exit after printing puppet config if asked to in Puppet config" do
+ Puppet.settings.stubs(:print_configs?).returns(true)
- Puppet.settings.expects(:print_configs)
+ lambda { @puppetd.setup }.should raise_error(SystemExit)
+ end
- @puppetd.setup
- end
+ it "should set a central log destination with --centrallogs" do
+ @puppetd.options.stubs(:[]).with(:centrallogs).returns(true)
+ Puppet.stubs(:[]).with(:server).returns("puppet.reductivelabs.com")
+ Puppet::Util::Log.stubs(:newdestination).with(:syslog)
- it "should exit after printing puppet config if asked to in Puppet config" do
- Puppet.settings.stubs(:print_configs?).returns(true)
+ Puppet::Util::Log.expects(:newdestination).with("puppet.reductivelabs.com")
- lambda { @puppetd.setup }.should raise_error(SystemExit)
- end
+ @puppetd.setup
+ end
- it "should set a central log destination with --centrallogs" do
- @puppetd.options.stubs(:[]).with(:centrallogs).returns(true)
- Puppet.stubs(:[]).with(:server).returns("puppet.reductivelabs.com")
- Puppet::Util::Log.stubs(:newdestination).with(:syslog)
+ it "should use :main, :puppetd, and :ssl" do
+ Puppet.settings.expects(:use).with(:main, :agent, :ssl)
- Puppet::Util::Log.expects(:newdestination).with("puppet.reductivelabs.com")
+ @puppetd.setup
+ end
- @puppetd.setup
- end
+ it "should install a remote ca location" do
+ Puppet::SSL::Host.expects(:ca_location=).with(:remote)
- it "should use :main, :puppetd, and :ssl" do
- Puppet.settings.expects(:use).with(:main, :agent, :ssl)
+ @puppetd.setup
+ end
- @puppetd.setup
- end
+ it "should install a none ca location in fingerprint mode" do
+ @puppetd.options.stubs(:[]).with(:fingerprint).returns(true)
+ Puppet::SSL::Host.expects(:ca_location=).with(:none)
- it "should install a remote ca location" do
- Puppet::SSL::Host.expects(:ca_location=).with(:remote)
+ @puppetd.setup
+ end
- @puppetd.setup
- end
+ it "should tell the report handler to use REST" do
+ Puppet::Transaction::Report.expects(:terminus_class=).with(:rest)
- it "should install a none ca location in fingerprint mode" do
- @puppetd.options.stubs(:[]).with(:fingerprint).returns(true)
- Puppet::SSL::Host.expects(:ca_location=).with(:none)
+ @puppetd.setup
+ end
- @puppetd.setup
- end
+ it "should change the catalog_terminus setting to 'rest'" do
+ Puppet.expects(:[]=).with(:catalog_terminus, :rest)
+ @puppetd.setup
+ end
- it "should tell the report handler to use REST" do
- Puppet::Transaction::Report.expects(:terminus_class=).with(:rest)
+ it "should tell the catalog handler to use cache" do
+ Puppet::Resource::Catalog.expects(:cache_class=).with(:yaml)
- @puppetd.setup
- end
+ @puppetd.setup
+ end
- it "should change the catalog_terminus setting to 'rest'" do
- Puppet.expects(:[]=).with(:catalog_terminus, :rest)
- @puppetd.setup
- end
+ it "should change the facts_terminus setting to 'facter'" do
+ Puppet.expects(:[]=).with(:facts_terminus, :facter)
- it "should tell the catalog handler to use cache" do
- Puppet::Resource::Catalog.expects(:cache_class=).with(:yaml)
+ @puppetd.setup
+ end
- @puppetd.setup
- end
+ it "should create an agent" do
+ Puppet::Agent.stubs(:new).with(Puppet::Configurer)
- it "should change the facts_terminus setting to 'facter'" do
- Puppet.expects(:[]=).with(:facts_terminus, :facter)
+ @puppetd.setup
+ end
- @puppetd.setup
- end
+ [:enable, :disable].each do |action|
+ it "should delegate to enable_disable_client if we #{action} the agent" do
+ @puppetd.options.stubs(:[]).with(action).returns(true)
+ @puppetd.expects(:enable_disable_client).with(@agent)
- it "should create an agent" do
- Puppet::Agent.stubs(:new).with(Puppet::Configurer)
+ @puppetd.setup
+ end
+ end
- @puppetd.setup
- end
+ describe "when enabling or disabling agent" do
+ [:enable, :disable].each do |action|
+ it "should call client.#{action}" do
+ @puppetd.stubs(:exit)
+ @puppetd.options.stubs(:[]).with(action).returns(true)
- [:enable, :disable].each do |action|
- it "should delegate to enable_disable_client if we #{action} the agent" do
- @puppetd.options.stubs(:[]).with(action).returns(true)
- @puppetd.expects(:enable_disable_client).with(@agent)
+ @agent.expects(action)
- @puppetd.setup
- end
+ @puppetd.enable_disable_client(@agent)
end
+ end
- describe "when enabling or disabling agent" do
- [:enable, :disable].each do |action|
- it "should call client.#{action}" do
- @puppetd.stubs(:exit)
- @puppetd.options.stubs(:[]).with(action).returns(true)
-
- @agent.expects(action)
-
- @puppetd.enable_disable_client(@agent)
- end
- end
-
- it "should finally exit" do
- lambda { @puppetd.enable_disable_client(@agent) }.should raise_error(SystemExit)
- end
- end
+ it "should finally exit" do
+ lambda { @puppetd.enable_disable_client(@agent) }.should raise_error(SystemExit)
+ end
+ end
- it "should inform the daemon about our agent if :client is set to 'true'" do
- @puppetd.options.expects(:[]).with(:client).returns true
- @daemon.expects(:agent=).with(@agent)
- @puppetd.setup
- end
+ it "should inform the daemon about our agent if :client is set to 'true'" do
+ @puppetd.options.expects(:[]).with(:client).returns true
+ @daemon.expects(:agent=).with(@agent)
+ @puppetd.setup
+ end
- it "should not inform the daemon about our agent if :client is set to 'false'" do
- @puppetd.options[:client] = false
- @daemon.expects(:agent=).never
- @puppetd.setup
- end
+ it "should not inform the daemon about our agent if :client is set to 'false'" do
+ @puppetd.options[:client] = false
+ @daemon.expects(:agent=).never
+ @puppetd.setup
+ end
- it "should daemonize if needed" do
- Puppet.stubs(:[]).with(:daemonize).returns(true)
+ it "should daemonize if needed" do
+ Puppet.stubs(:[]).with(:daemonize).returns(true)
- @daemon.expects(:daemonize)
+ @daemon.expects(:daemonize)
- @puppetd.setup
- end
+ @puppetd.setup
+ end
- it "should wait for a certificate" do
- @puppetd.options.stubs(:[]).with(:waitforcert).returns(123)
- @host.expects(:wait_for_cert).with(123)
+ it "should wait for a certificate" do
+ @puppetd.options.stubs(:[]).with(:waitforcert).returns(123)
+ @host.expects(:wait_for_cert).with(123)
- @puppetd.setup
- end
+ @puppetd.setup
+ end
- it "should not wait for a certificate in fingerprint mode" do
- @puppetd.options.stubs(:[]).with(:fingerprint).returns(true)
- @puppetd.options.stubs(:[]).with(:waitforcert).returns(123)
- @host.expects(:wait_for_cert).never
+ it "should not wait for a certificate in fingerprint mode" do
+ @puppetd.options.stubs(:[]).with(:fingerprint).returns(true)
+ @puppetd.options.stubs(:[]).with(:waitforcert).returns(123)
+ @host.expects(:wait_for_cert).never
- @puppetd.setup
- end
+ @puppetd.setup
+ end
- it "should setup listen if told to and not onetime" do
- Puppet.stubs(:[]).with(:listen).returns(true)
- @puppetd.options.stubs(:[]).with(:onetime).returns(false)
+ it "should setup listen if told to and not onetime" do
+ Puppet.stubs(:[]).with(:listen).returns(true)
+ @puppetd.options.stubs(:[]).with(:onetime).returns(false)
- @puppetd.expects(:setup_listen)
+ @puppetd.expects(:setup_listen)
- @puppetd.setup
- end
+ @puppetd.setup
+ end
- describe "when setting up listen" do
- before :each do
- Puppet.stubs(:[]).with(:authconfig).returns('auth')
- FileTest.stubs(:exists?).with('auth').returns(true)
- File.stubs(:exist?).returns(true)
- @puppetd.options.stubs(:[]).with(:serve).returns([])
- @puppetd.stubs(:exit)
- @server = stub_everything 'server'
- Puppet::Network::Server.stubs(:new).returns(@server)
- end
+ describe "when setting up listen" do
+ before :each do
+ Puppet.stubs(:[]).with(:authconfig).returns('auth')
+ FileTest.stubs(:exists?).with('auth').returns(true)
+ File.stubs(:exist?).returns(true)
+ @puppetd.options.stubs(:[]).with(:serve).returns([])
+ @puppetd.stubs(:exit)
+ @server = stub_everything 'server'
+ Puppet::Network::Server.stubs(:new).returns(@server)
+ end
- it "should exit if no authorization file" do
- Puppet.stubs(:err)
- FileTest.stubs(:exists?).with('auth').returns(false)
+ it "should exit if no authorization file" do
+ Puppet.stubs(:err)
+ FileTest.stubs(:exists?).with('auth').returns(false)
- @puppetd.expects(:exit)
+ @puppetd.expects(:exit)
- @puppetd.setup_listen
- end
+ @puppetd.setup_listen
+ end
- it "should create a server to listen on at least the Runner handler" do
- Puppet::Network::Server.expects(:new).with { |args| args[:xmlrpc_handlers] == [:Runner] }
+ it "should create a server to listen on at least the Runner handler" do
+ Puppet::Network::Server.expects(:new).with { |args| args[:xmlrpc_handlers] == [:Runner] }
- @puppetd.setup_listen
- end
+ @puppetd.setup_listen
+ end
- it "should create a server to listen for specific handlers" do
- @puppetd.options.stubs(:[]).with(:serve).returns([:handler])
- Puppet::Network::Server.expects(:new).with { |args| args[:xmlrpc_handlers] == [:handler] }
+ it "should create a server to listen for specific handlers" do
+ @puppetd.options.stubs(:[]).with(:serve).returns([:handler])
+ Puppet::Network::Server.expects(:new).with { |args| args[:xmlrpc_handlers] == [:handler] }
- @puppetd.setup_listen
- end
+ @puppetd.setup_listen
+ end
- it "should use puppet default port" do
- Puppet.stubs(:[]).with(:puppetport).returns(:port)
+ it "should use puppet default port" do
+ Puppet.stubs(:[]).with(:puppetport).returns(:port)
- Puppet::Network::Server.expects(:new).with { |args| args[:port] == :port }
+ Puppet::Network::Server.expects(:new).with { |args| args[:port] == :port }
- @puppetd.setup_listen
- end
- end
+ @puppetd.setup_listen
+ end
end
+ end
- describe "when running" do
- before :each do
- @puppetd.agent = @agent
- @puppetd.daemon = @daemon
- @puppetd.options.stubs(:[]).with(:fingerprint).returns(false)
- end
+ describe "when running" do
+ before :each do
+ @puppetd.agent = @agent
+ @puppetd.daemon = @daemon
+ @puppetd.options.stubs(:[]).with(:fingerprint).returns(false)
+ end
- it "should dispatch to fingerprint if --fingerprint is used" do
- @puppetd.options.stubs(:[]).with(:fingerprint).returns(true)
+ it "should dispatch to fingerprint if --fingerprint is used" do
+ @puppetd.options.stubs(:[]).with(:fingerprint).returns(true)
- @puppetd.stubs(:fingerprint)
- @puppetd.run_command
- end
+ @puppetd.stubs(:fingerprint)
+ @puppetd.run_command
+ end
- it "should dispatch to onetime if --onetime is used" do
- @puppetd.options.stubs(:[]).with(:onetime).returns(true)
+ it "should dispatch to onetime if --onetime is used" do
+ @puppetd.options.stubs(:[]).with(:onetime).returns(true)
- @puppetd.stubs(:onetime)
- @puppetd.run_command
- end
+ @puppetd.stubs(:onetime)
+ @puppetd.run_command
+ end
- it "should dispatch to main if --onetime and --fingerprint are not used" do
- @puppetd.options.stubs(:[]).with(:onetime).returns(false)
+ it "should dispatch to main if --onetime and --fingerprint are not used" do
+ @puppetd.options.stubs(:[]).with(:onetime).returns(false)
- @puppetd.stubs(:main)
- @puppetd.run_command
- end
+ @puppetd.stubs(:main)
+ @puppetd.run_command
+ end
- describe "with --onetime" do
+ describe "with --onetime" do
- before :each do
- @agent.stubs(:run).returns(:report)
- @puppetd.options.stubs(:[]).with(:client).returns(:client)
- @puppetd.options.stubs(:[]).with(:detailed_exitcodes).returns(false)
- @puppetd.stubs(:exit).with(0)
- Puppet.stubs(:newservice)
- end
+ before :each do
+ @agent.stubs(:run).returns(:report)
+ @puppetd.options.stubs(:[]).with(:client).returns(:client)
+ @puppetd.options.stubs(:[]).with(:detailed_exitcodes).returns(false)
+ @puppetd.stubs(:exit).with(0)
+ Puppet.stubs(:newservice)
+ end
- it "should exit if no defined --client" do
- $stderr.stubs(:puts)
- @puppetd.options.stubs(:[]).with(:client).returns(nil)
+ it "should exit if no defined --client" do
+ $stderr.stubs(:puts)
+ @puppetd.options.stubs(:[]).with(:client).returns(nil)
- @puppetd.expects(:exit).with(43)
+ @puppetd.expects(:exit).with(43)
- @puppetd.onetime
- end
+ @puppetd.onetime
+ end
- it "should setup traps" do
- @daemon.expects(:set_signal_traps)
+ it "should setup traps" do
+ @daemon.expects(:set_signal_traps)
- @puppetd.onetime
- end
+ @puppetd.onetime
+ end
- it "should let the agent run" do
- @agent.expects(:run).returns(:report)
+ it "should let the agent run" do
+ @agent.expects(:run).returns(:report)
- @puppetd.onetime
- end
+ @puppetd.onetime
+ end
- it "should finish by exiting with 0 error code" do
- @puppetd.expects(:exit).with(0)
+ it "should finish by exiting with 0 error code" do
+ @puppetd.expects(:exit).with(0)
- @puppetd.onetime
- end
+ @puppetd.onetime
+ end
- describe "and --detailed-exitcodes" do
- before :each do
- @puppetd.options.stubs(:[]).with(:detailed_exitcodes).returns(true)
- end
+ describe "and --detailed-exitcodes" do
+ before :each do
+ @puppetd.options.stubs(:[]).with(:detailed_exitcodes).returns(true)
+ end
- it "should exit with report's computed exit status" do
- Puppet.stubs(:[]).with(:noop).returns(false)
- report = stub 'report', :exit_status => 666
- @agent.stubs(:run).returns(report)
- @puppetd.expects(:exit).with(666)
+ it "should exit with report's computed exit status" do
+ Puppet.stubs(:[]).with(:noop).returns(false)
+ report = stub 'report', :exit_status => 666
+ @agent.stubs(:run).returns(report)
+ @puppetd.expects(:exit).with(666)
- @puppetd.onetime
- end
+ @puppetd.onetime
+ end
- it "should always exit with 0 if --noop" do
- Puppet.stubs(:[]).with(:noop).returns(true)
- report = stub 'report', :exit_status => 666
- @agent.stubs(:run).returns(report)
- @puppetd.expects(:exit).with(0)
+ it "should always exit with 0 if --noop" do
+ Puppet.stubs(:[]).with(:noop).returns(true)
+ report = stub 'report', :exit_status => 666
+ @agent.stubs(:run).returns(report)
+ @puppetd.expects(:exit).with(0)
- @puppetd.onetime
- end
- end
+ @puppetd.onetime
end
+ end
+ end
- describe "with --fingerprint" do
- before :each do
- @cert = stub_everything 'cert'
- @puppetd.options.stubs(:[]).with(:fingerprint).returns(true)
- @puppetd.options.stubs(:[]).with(:digest).returns(:MD5)
- @host = stub_everything 'host'
- @puppetd.stubs(:host).returns(@host)
- end
-
- it "should fingerprint the certificate if it exists" do
- @host.expects(:certificate).returns(@cert)
- @cert.expects(:fingerprint).with(:MD5).returns "fingerprint"
- @puppetd.fingerprint
- end
-
- it "should fingerprint the certificate request if no certificate have been signed" do
- @host.expects(:certificate).returns(nil)
- @host.expects(:certificate_request).returns(@cert)
- @cert.expects(:fingerprint).with(:MD5).returns "fingerprint"
- @puppetd.fingerprint
- end
-
- it "should display the fingerprint" do
- @host.stubs(:certificate).returns(@cert)
- @cert.stubs(:fingerprint).with(:MD5).returns("DIGEST")
-
- Puppet.expects(:notice).with("DIGEST")
-
- @puppetd.fingerprint
- end
- end
+ describe "with --fingerprint" do
+ before :each do
+ @cert = stub_everything 'cert'
+ @puppetd.options.stubs(:[]).with(:fingerprint).returns(true)
+ @puppetd.options.stubs(:[]).with(:digest).returns(:MD5)
+ @host = stub_everything 'host'
+ @puppetd.stubs(:host).returns(@host)
+ end
+
+ it "should fingerprint the certificate if it exists" do
+ @host.expects(:certificate).returns(@cert)
+ @cert.expects(:fingerprint).with(:MD5).returns "fingerprint"
+ @puppetd.fingerprint
+ end
+
+ it "should fingerprint the certificate request if no certificate have been signed" do
+ @host.expects(:certificate).returns(nil)
+ @host.expects(:certificate_request).returns(@cert)
+ @cert.expects(:fingerprint).with(:MD5).returns "fingerprint"
+ @puppetd.fingerprint
+ end
+
+ it "should display the fingerprint" do
+ @host.stubs(:certificate).returns(@cert)
+ @cert.stubs(:fingerprint).with(:MD5).returns("DIGEST")
+
+ Puppet.expects(:notice).with("DIGEST")
+
+ @puppetd.fingerprint
+ end
+ end
- describe "without --onetime and --fingerprint" do
- before :each do
- Puppet.stubs(:notice)
- @puppetd.options.stubs(:[]).with(:client)
- end
+ describe "without --onetime and --fingerprint" do
+ before :each do
+ Puppet.stubs(:notice)
+ @puppetd.options.stubs(:[]).with(:client)
+ end
- it "should start our daemon" do
- @daemon.expects(:start)
+ it "should start our daemon" do
+ @daemon.expects(:start)
- @puppetd.main
- end
- end
+ @puppetd.main
+ end
end
+ end
end
diff --git a/spec/unit/application/apply_spec.rb b/spec/unit/application/apply_spec.rb
index a1a7e7b..0b00d1a 100755
--- a/spec/unit/application/apply_spec.rb
+++ b/spec/unit/application/apply_spec.rb
@@ -5,383 +5,383 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/application/apply'
describe Puppet::Application::Apply do
- before :each do
- @apply = Puppet::Application[:apply]
- Puppet::Util::Log.stubs(:newdestination)
- Puppet::Util::Log.stubs(:level=)
- end
-
- [:debug,:loadclasses,:verbose,:use_nodes,:detailed_exitcodes].each do |option|
- it "should declare handle_#{option} method" do
- @apply.should respond_to("handle_#{option}".to_sym)
- end
-
- it "should store argument value when calling handle_#{option}" do
- @apply.options.expects(:[]=).with(option, 'arg')
- @apply.send("handle_#{option}".to_sym, 'arg')
- end
+ before :each do
+ @apply = Puppet::Application[:apply]
+ Puppet::Util::Log.stubs(:newdestination)
+ Puppet::Util::Log.stubs(:level=)
+ end
+
+ [:debug,:loadclasses,:verbose,:use_nodes,:detailed_exitcodes].each do |option|
+ it "should declare handle_#{option} method" do
+ @apply.should respond_to("handle_#{option}".to_sym)
end
- it "should set the code to the provided code when :execute is used" do
- @apply.options.expects(:[]=).with(:code, 'arg')
- @apply.send("handle_execute".to_sym, 'arg')
+ it "should store argument value when calling handle_#{option}" do
+ @apply.options.expects(:[]=).with(option, 'arg')
+ @apply.send("handle_#{option}".to_sym, 'arg')
end
+ end
- it "should ask Puppet::Application to parse Puppet configuration file" do
- @apply.should_parse_config?.should be_true
- end
+ it "should set the code to the provided code when :execute is used" do
+ @apply.options.expects(:[]=).with(:code, 'arg')
+ @apply.send("handle_execute".to_sym, 'arg')
+ end
- describe "when applying options" do
+ it "should ask Puppet::Application to parse Puppet configuration file" do
+ @apply.should_parse_config?.should be_true
+ end
- it "should set the log destination with --logdest" do
- Puppet::Log.expects(:newdestination).with("console")
+ describe "when applying options" do
- @apply.handle_logdest("console")
- end
+ it "should set the log destination with --logdest" do
+ Puppet::Log.expects(:newdestination).with("console")
- it "should put the logset options to true" do
- @apply.options.expects(:[]=).with(:logset,true)
-
- @apply.handle_logdest("console")
- end
+ @apply.handle_logdest("console")
end
- describe "during setup" do
+ it "should put the logset options to true" do
+ @apply.options.expects(:[]=).with(:logset,true)
- before :each do
- Puppet::Log.stubs(:newdestination)
- Puppet.stubs(:trap)
- Puppet::Log.stubs(:level=)
- Puppet.stubs(:parse_config)
- require 'lib/puppet/file_bucket/dipper'
- Puppet::FileBucket::Dipper.stubs(:new)
- STDIN.stubs(:read)
+ @apply.handle_logdest("console")
+ end
+ end
- @apply.options.stubs(:[]).with(any_parameters)
- end
+ describe "during setup" do
- it "should set show_diff on --noop" do
- Puppet.stubs(:[]=)
- Puppet.stubs(:[]).with(:config)
- Puppet.stubs(:[]).with(:noop).returns(true)
+ before :each do
+ Puppet::Log.stubs(:newdestination)
+ Puppet.stubs(:trap)
+ Puppet::Log.stubs(:level=)
+ Puppet.stubs(:parse_config)
+ require 'lib/puppet/file_bucket/dipper'
+ Puppet::FileBucket::Dipper.stubs(:new)
+ STDIN.stubs(:read)
+
+ @apply.options.stubs(:[]).with(any_parameters)
+ end
- Puppet.expects(:[]=).with(:show_diff, true)
+ it "should set show_diff on --noop" do
+ Puppet.stubs(:[]=)
+ Puppet.stubs(:[]).with(:config)
+ Puppet.stubs(:[]).with(:noop).returns(true)
- @apply.setup
- end
+ Puppet.expects(:[]=).with(:show_diff, true)
- it "should set console as the log destination if logdest option wasn't provided" do
- Puppet::Log.expects(:newdestination).with(:console)
+ @apply.setup
+ end
- @apply.setup
- end
+ it "should set console as the log destination if logdest option wasn't provided" do
+ Puppet::Log.expects(:newdestination).with(:console)
- it "should set INT trap" do
- @apply.expects(:trap).with(:INT)
+ @apply.setup
+ end
- @apply.setup
- end
+ it "should set INT trap" do
+ @apply.expects(:trap).with(:INT)
- it "should set log level to debug if --debug was passed" do
- @apply.options.stubs(:[]).with(:debug).returns(true)
+ @apply.setup
+ end
- Puppet::Log.expects(:level=).with(:debug)
+ it "should set log level to debug if --debug was passed" do
+ @apply.options.stubs(:[]).with(:debug).returns(true)
- @apply.setup
- end
+ Puppet::Log.expects(:level=).with(:debug)
- it "should set log level to info if --verbose was passed" do
- @apply.options.stubs(:[]).with(:verbose).returns(true)
+ @apply.setup
+ end
- Puppet::Log.expects(:level=).with(:info)
+ it "should set log level to info if --verbose was passed" do
+ @apply.options.stubs(:[]).with(:verbose).returns(true)
- @apply.setup
- end
+ Puppet::Log.expects(:level=).with(:info)
- it "should print puppet config if asked to in Puppet config" do
- @apply.stubs(:exit)
- Puppet.settings.stubs(:print_configs?).returns(true)
+ @apply.setup
+ end
- Puppet.settings.expects(:print_configs)
+ it "should print puppet config if asked to in Puppet config" do
+ @apply.stubs(:exit)
+ Puppet.settings.stubs(:print_configs?).returns(true)
- @apply.setup
- end
+ Puppet.settings.expects(:print_configs)
- it "should exit after printing puppet config if asked to in Puppet config" do
- Puppet.settings.stubs(:print_configs?).returns(true)
+ @apply.setup
+ end
- lambda { @apply.setup }.should raise_error(SystemExit)
- end
+ it "should exit after printing puppet config if asked to in Puppet config" do
+ Puppet.settings.stubs(:print_configs?).returns(true)
+ lambda { @apply.setup }.should raise_error(SystemExit)
end
- describe "when executing" do
+ end
- it "should dispatch to parseonly if parseonly is set" do
- @apply.stubs(:options).returns({})
- Puppet.stubs(:[]).with(:parseonly).returns(true)
+ describe "when executing" do
- @apply.expects(:parseonly)
- @apply.run_command
- end
+ it "should dispatch to parseonly if parseonly is set" do
+ @apply.stubs(:options).returns({})
+ Puppet.stubs(:[]).with(:parseonly).returns(true)
- it "should dispatch to 'apply' if it was called with 'apply'" do
- @apply.options[:catalog] = "foo"
-
- @apply.expects(:apply)
- @apply.run_command
- end
+ @apply.expects(:parseonly)
+ @apply.run_command
+ end
- it "should dispatch to main if parseonly is not set" do
- @apply.stubs(:options).returns({})
- Puppet.stubs(:[]).with(:parseonly).returns(false)
+ it "should dispatch to 'apply' if it was called with 'apply'" do
+ @apply.options[:catalog] = "foo"
- @apply.expects(:main)
- @apply.run_command
- end
+ @apply.expects(:apply)
+ @apply.run_command
+ end
- describe "the parseonly command" do
- before :each do
- Puppet.stubs(:[]).with(:environment)
- Puppet.stubs(:[]).with(:manifest).returns("site.pp")
- Puppet.stubs(:err)
- @apply.stubs(:exit)
- @apply.options.stubs(:[]).with(:code).returns "some code"
- @collection = stub_everything
- Puppet::Resource::TypeCollection.stubs(:new).returns(@collection)
- end
-
- it "should use a Puppet Resource Type Collection to parse the file" do
- @collection.expects(:perform_initial_import)
- @apply.parseonly
- end
-
- it "should exit with exit code 0 if no error" do
- @apply.expects(:exit).with(0)
- @apply.parseonly
- end
-
- it "should exit with exit code 1 if error" do
- @collection.stubs(:perform_initial_import).raises(Puppet::ParseError)
- @apply.expects(:exit).with(1)
- @apply.parseonly
- end
- end
+ it "should dispatch to main if parseonly is not set" do
+ @apply.stubs(:options).returns({})
+ Puppet.stubs(:[]).with(:parseonly).returns(false)
- describe "the main command" do
- before :each do
- Puppet.stubs(:[])
- Puppet.settings.stubs(:use)
- Puppet.stubs(:[]).with(:prerun_command).returns ""
- Puppet.stubs(:[]).with(:postrun_command).returns ""
- Puppet.stubs(:[]).with(:trace).returns(true)
+ @apply.expects(:main)
+ @apply.run_command
+ end
- @apply.options.stubs(:[])
+ describe "the parseonly command" do
+ before :each do
+ Puppet.stubs(:[]).with(:environment)
+ Puppet.stubs(:[]).with(:manifest).returns("site.pp")
+ Puppet.stubs(:err)
+ @apply.stubs(:exit)
+ @apply.options.stubs(:[]).with(:code).returns "some code"
+ @collection = stub_everything
+ Puppet::Resource::TypeCollection.stubs(:new).returns(@collection)
+ end
+
+ it "should use a Puppet Resource Type Collection to parse the file" do
+ @collection.expects(:perform_initial_import)
+ @apply.parseonly
+ end
+
+ it "should exit with exit code 0 if no error" do
+ @apply.expects(:exit).with(0)
+ @apply.parseonly
+ end
+
+ it "should exit with exit code 1 if error" do
+ @collection.stubs(:perform_initial_import).raises(Puppet::ParseError)
+ @apply.expects(:exit).with(1)
+ @apply.parseonly
+ end
+ end
- @facts = stub_everything 'facts'
- Puppet::Node::Facts.stubs(:find).returns(@facts)
+ describe "the main command" do
+ before :each do
+ Puppet.stubs(:[])
+ Puppet.settings.stubs(:use)
+ Puppet.stubs(:[]).with(:prerun_command).returns ""
+ Puppet.stubs(:[]).with(:postrun_command).returns ""
+ Puppet.stubs(:[]).with(:trace).returns(true)
- @node = stub_everything 'node'
- Puppet::Node.stubs(:find).returns(@node)
+ @apply.options.stubs(:[])
- @catalog = stub_everything 'catalog'
- @catalog.stubs(:to_ral).returns(@catalog)
- Puppet::Resource::Catalog.stubs(:find).returns(@catalog)
+ @facts = stub_everything 'facts'
+ Puppet::Node::Facts.stubs(:find).returns(@facts)
- STDIN.stubs(:read)
+ @node = stub_everything 'node'
+ Puppet::Node.stubs(:find).returns(@node)
- @transaction = stub_everything 'transaction'
- @catalog.stubs(:apply).returns(@transaction)
+ @catalog = stub_everything 'catalog'
+ @catalog.stubs(:to_ral).returns(@catalog)
+ Puppet::Resource::Catalog.stubs(:find).returns(@catalog)
- @apply.stubs(:exit)
- end
+ STDIN.stubs(:read)
- it "should set the code to run from --code" do
- @apply.options.stubs(:[]).with(:code).returns("code to run")
- Puppet.expects(:[]=).with(:code,"code to run")
+ @transaction = stub_everything 'transaction'
+ @catalog.stubs(:apply).returns(@transaction)
- @apply.main
- end
+ @apply.stubs(:exit)
+ end
- it "should set the code to run from STDIN if no arguments" do
- @apply.command_line.stubs(:args).returns([])
- STDIN.stubs(:read).returns("code to run")
+ it "should set the code to run from --code" do
+ @apply.options.stubs(:[]).with(:code).returns("code to run")
+ Puppet.expects(:[]=).with(:code,"code to run")
- Puppet.expects(:[]=).with(:code,"code to run")
+ @apply.main
+ end
- @apply.main
- end
+ it "should set the code to run from STDIN if no arguments" do
+ @apply.command_line.stubs(:args).returns([])
+ STDIN.stubs(:read).returns("code to run")
- it "should set the manifest if some files are passed on command line" do
- @apply.command_line.stubs(:args).returns(['site.pp'])
+ Puppet.expects(:[]=).with(:code,"code to run")
- Puppet.expects(:[]=).with(:manifest,"site.pp")
+ @apply.main
+ end
- @apply.main
- end
+ it "should set the manifest if some files are passed on command line" do
+ @apply.command_line.stubs(:args).returns(['site.pp'])
- it "should collect the node facts" do
- Puppet::Node::Facts.expects(:find).returns(@facts)
+ Puppet.expects(:[]=).with(:manifest,"site.pp")
- @apply.main
- end
+ @apply.main
+ end
- it "should raise an error if we can't find the node" do
- Puppet::Node::Facts.expects(:find).returns(nil)
+ it "should collect the node facts" do
+ Puppet::Node::Facts.expects(:find).returns(@facts)
- lambda { @apply.main }.should raise_error
- end
+ @apply.main
+ end
- it "should find the node" do
- Puppet::Node.expects(:find).returns(@node)
+ it "should raise an error if we can't find the node" do
+ Puppet::Node::Facts.expects(:find).returns(nil)
- @apply.main
- end
+ lambda { @apply.main }.should raise_error
+ end
- it "should raise an error if we can't find the node" do
- Puppet::Node.expects(:find).returns(nil)
+ it "should find the node" do
+ Puppet::Node.expects(:find).returns(@node)
- lambda { @apply.main }.should raise_error
- end
+ @apply.main
+ end
- it "should merge in our node the loaded facts" do
- @facts.stubs(:values).returns("values")
+ it "should raise an error if we can't find the node" do
+ Puppet::Node.expects(:find).returns(nil)
- @node.expects(:merge).with("values")
+ lambda { @apply.main }.should raise_error
+ end
- @apply.main
- end
+ it "should merge in our node the loaded facts" do
+ @facts.stubs(:values).returns("values")
- it "should load custom classes if loadclasses" do
- @apply.options.stubs(:[]).with(:loadclasses).returns(true)
- Puppet.stubs(:[]).with(:classfile).returns("/etc/puppet/classes.txt")
- FileTest.stubs(:exists?).with("/etc/puppet/classes.txt").returns(true)
- FileTest.stubs(:readable?).with("/etc/puppet/classes.txt").returns(true)
- File.stubs(:read).with("/etc/puppet/classes.txt").returns("class")
+ @node.expects(:merge).with("values")
- @node.expects(:classes=)
+ @apply.main
+ end
- @apply.main
- end
+ it "should load custom classes if loadclasses" do
+ @apply.options.stubs(:[]).with(:loadclasses).returns(true)
+ Puppet.stubs(:[]).with(:classfile).returns("/etc/puppet/classes.txt")
+ FileTest.stubs(:exists?).with("/etc/puppet/classes.txt").returns(true)
+ FileTest.stubs(:readable?).with("/etc/puppet/classes.txt").returns(true)
+ File.stubs(:read).with("/etc/puppet/classes.txt").returns("class")
- it "should compile the catalog" do
- Puppet::Resource::Catalog.expects(:find).returns(@catalog)
+ @node.expects(:classes=)
- @apply.main
- end
+ @apply.main
+ end
- it "should transform the catalog to ral" do
+ it "should compile the catalog" do
+ Puppet::Resource::Catalog.expects(:find).returns(@catalog)
- @catalog.expects(:to_ral).returns(@catalog)
+ @apply.main
+ end
- @apply.main
- end
+ it "should transform the catalog to ral" do
- it "should finalize the catalog" do
- @catalog.expects(:finalize)
+ @catalog.expects(:to_ral).returns(@catalog)
- @apply.main
- end
+ @apply.main
+ end
- it "should call the prerun and postrun commands on a Configurer instance" do
- configurer = stub 'configurer'
+ it "should finalize the catalog" do
+ @catalog.expects(:finalize)
- Puppet::Configurer.expects(:new).returns configurer
- configurer.expects(:execute_prerun_command)
- configurer.expects(:execute_postrun_command)
+ @apply.main
+ end
- @apply.main
- end
+ it "should call the prerun and postrun commands on a Configurer instance" do
+ configurer = stub 'configurer'
- it "should apply the catalog" do
- @catalog.expects(:apply)
+ Puppet::Configurer.expects(:new).returns configurer
+ configurer.expects(:execute_prerun_command)
+ configurer.expects(:execute_postrun_command)
- @apply.main
- end
+ @apply.main
+ end
- describe "with detailed_exitcodes" do
- it "should exit with report's computed exit status" do
- Puppet.stubs(:[]).with(:noop).returns(false)
- @apply.options.stubs(:[]).with(:detailed_exitcodes).returns(true)
- report = stub 'report', :exit_status => 666
- @transaction.stubs(:report).returns(report)
- @apply.expects(:exit).with(666)
+ it "should apply the catalog" do
+ @catalog.expects(:apply)
- @apply.main
- end
+ @apply.main
+ end
- it "should always exit with 0 if option is disabled" do
- Puppet.stubs(:[]).with(:noop).returns(false)
- @apply.options.stubs(:[]).with(:detailed_exitcodes).returns(false)
- report = stub 'report', :exit_status => 666
- @transaction.stubs(:report).returns(report)
- @apply.expects(:exit).with(0)
+ describe "with detailed_exitcodes" do
+ it "should exit with report's computed exit status" do
+ Puppet.stubs(:[]).with(:noop).returns(false)
+ @apply.options.stubs(:[]).with(:detailed_exitcodes).returns(true)
+ report = stub 'report', :exit_status => 666
+ @transaction.stubs(:report).returns(report)
+ @apply.expects(:exit).with(666)
- @apply.main
- end
+ @apply.main
+ end
- it "should always exit with 0 if --noop" do
- Puppet.stubs(:[]).with(:noop).returns(true)
- @apply.options.stubs(:[]).with(:detailed_exitcodes).returns(true)
- report = stub 'report', :exit_status => 666
- @transaction.stubs(:report).returns(report)
- @apply.expects(:exit).with(0)
+ it "should always exit with 0 if option is disabled" do
+ Puppet.stubs(:[]).with(:noop).returns(false)
+ @apply.options.stubs(:[]).with(:detailed_exitcodes).returns(false)
+ report = stub 'report', :exit_status => 666
+ @transaction.stubs(:report).returns(report)
+ @apply.expects(:exit).with(0)
- @apply.main
- end
- end
+ @apply.main
end
- describe "the 'apply' command" do
- it "should read the catalog in from disk if a file name is provided" do
- @apply.options[:catalog] = "/my/catalog.pson"
- File.expects(:read).with("/my/catalog.pson").returns "something"
- Puppet::Resource::Catalog.stubs(:convert_from).with(:pson,'something').returns Puppet::Resource::Catalog.new
- @apply.apply
- end
-
- it "should read the catalog in from stdin if '-' is provided" do
- @apply.options[:catalog] = "-"
- $stdin.expects(:read).returns "something"
- Puppet::Resource::Catalog.stubs(:convert_from).with(:pson,'something').returns Puppet::Resource::Catalog.new
- @apply.apply
- end
-
- it "should deserialize the catalog from the default format" do
- @apply.options[:catalog] = "/my/catalog.pson"
- File.stubs(:read).with("/my/catalog.pson").returns "something"
- Puppet::Resource::Catalog.stubs(:default_format).returns :rot13_piglatin
- Puppet::Resource::Catalog.stubs(:convert_from).with(:rot13_piglatin,'something').returns Puppet::Resource::Catalog.new
- @apply.apply
- end
-
- it "should fail helpfully if deserializing fails" do
- @apply.options[:catalog] = "/my/catalog.pson"
- File.stubs(:read).with("/my/catalog.pson").returns "something syntacically invalid"
- lambda { @apply.apply }.should raise_error(Puppet::Error)
- end
-
- it "should convert plain data structures into a catalog if deserialization does not do so" do
- @apply.options[:catalog] = "/my/catalog.pson"
- File.stubs(:read).with("/my/catalog.pson").returns "something"
- Puppet::Resource::Catalog.stubs(:convert_from).with(:pson,"something").returns({:foo => "bar"})
- Puppet::Resource::Catalog.expects(:pson_create).with({:foo => "bar"}).returns(Puppet::Resource::Catalog.new)
- @apply.apply
- end
-
- it "should convert the catalog to a RAL catalog and use a Configurer instance to apply it" do
- @apply.options[:catalog] = "/my/catalog.pson"
- File.stubs(:read).with("/my/catalog.pson").returns "something"
- catalog = Puppet::Resource::Catalog.new
- Puppet::Resource::Catalog.stubs(:convert_from).with(:pson,'something').returns catalog
- catalog.expects(:to_ral).returns "mycatalog"
-
- configurer = stub 'configurer'
- Puppet::Configurer.expects(:new).returns configurer
- configurer.expects(:run).with(:catalog => "mycatalog")
-
- @apply.apply
- end
+ it "should always exit with 0 if --noop" do
+ Puppet.stubs(:[]).with(:noop).returns(true)
+ @apply.options.stubs(:[]).with(:detailed_exitcodes).returns(true)
+ report = stub 'report', :exit_status => 666
+ @transaction.stubs(:report).returns(report)
+ @apply.expects(:exit).with(0)
+
+ @apply.main
end
+ end
+ end
+
+ describe "the 'apply' command" do
+ it "should read the catalog in from disk if a file name is provided" do
+ @apply.options[:catalog] = "/my/catalog.pson"
+ File.expects(:read).with("/my/catalog.pson").returns "something"
+ Puppet::Resource::Catalog.stubs(:convert_from).with(:pson,'something').returns Puppet::Resource::Catalog.new
+ @apply.apply
+ end
+
+ it "should read the catalog in from stdin if '-' is provided" do
+ @apply.options[:catalog] = "-"
+ $stdin.expects(:read).returns "something"
+ Puppet::Resource::Catalog.stubs(:convert_from).with(:pson,'something').returns Puppet::Resource::Catalog.new
+ @apply.apply
+ end
+
+ it "should deserialize the catalog from the default format" do
+ @apply.options[:catalog] = "/my/catalog.pson"
+ File.stubs(:read).with("/my/catalog.pson").returns "something"
+ Puppet::Resource::Catalog.stubs(:default_format).returns :rot13_piglatin
+ Puppet::Resource::Catalog.stubs(:convert_from).with(:rot13_piglatin,'something').returns Puppet::Resource::Catalog.new
+ @apply.apply
+ end
+
+ it "should fail helpfully if deserializing fails" do
+ @apply.options[:catalog] = "/my/catalog.pson"
+ File.stubs(:read).with("/my/catalog.pson").returns "something syntacically invalid"
+ lambda { @apply.apply }.should raise_error(Puppet::Error)
+ end
+
+ it "should convert plain data structures into a catalog if deserialization does not do so" do
+ @apply.options[:catalog] = "/my/catalog.pson"
+ File.stubs(:read).with("/my/catalog.pson").returns "something"
+ Puppet::Resource::Catalog.stubs(:convert_from).with(:pson,"something").returns({:foo => "bar"})
+ Puppet::Resource::Catalog.expects(:pson_create).with({:foo => "bar"}).returns(Puppet::Resource::Catalog.new)
+ @apply.apply
+ end
+
+ it "should convert the catalog to a RAL catalog and use a Configurer instance to apply it" do
+ @apply.options[:catalog] = "/my/catalog.pson"
+ File.stubs(:read).with("/my/catalog.pson").returns "something"
+ catalog = Puppet::Resource::Catalog.new
+ Puppet::Resource::Catalog.stubs(:convert_from).with(:pson,'something').returns catalog
+ catalog.expects(:to_ral).returns "mycatalog"
+
+ configurer = stub 'configurer'
+ Puppet::Configurer.expects(:new).returns configurer
+ configurer.expects(:run).with(:catalog => "mycatalog")
+
+ @apply.apply
+ end
end
+ end
end
diff --git a/spec/unit/application/cert_spec.rb b/spec/unit/application/cert_spec.rb
index c1ff38b..b82a2fe 100755
--- a/spec/unit/application/cert_spec.rb
+++ b/spec/unit/application/cert_spec.rb
@@ -5,190 +5,190 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/application/cert'
describe Puppet::Application::Cert do
- before :each do
- @cert_app = Puppet::Application[:cert]
- Puppet::Util::Log.stubs(:newdestination)
- Puppet::Util::Log.stubs(:level=)
+ before :each do
+ @cert_app = Puppet::Application[:cert]
+ Puppet::Util::Log.stubs(:newdestination)
+ Puppet::Util::Log.stubs(:level=)
+ end
+
+ it "should operate in master run_mode" do
+ @cert_app.class.run_mode.name.should equal :master
+ end
+
+ it "should ask Puppet::Application to parse Puppet configuration file" do
+ @cert_app.should_parse_config?.should be_true
+ end
+
+ it "should declare a main command" do
+ @cert_app.should respond_to(:main)
+ end
+
+ Puppet::SSL::CertificateAuthority::Interface::INTERFACE_METHODS.reject{ |m| m == :destroy }.each do |method|
+ it "should declare option --#{method}" do
+ @cert_app.should respond_to("handle_#{method}".to_sym)
end
+ end
- it "should operate in master run_mode" do
- @cert_app.class.run_mode.name.should equal :master
- end
+ it "should set log level to info with the --verbose option" do
- it "should ask Puppet::Application to parse Puppet configuration file" do
- @cert_app.should_parse_config?.should be_true
- end
+ Puppet::Log.expects(:level=).with(:info)
- it "should declare a main command" do
- @cert_app.should respond_to(:main)
- end
+ @cert_app.handle_verbose(0)
+ end
- Puppet::SSL::CertificateAuthority::Interface::INTERFACE_METHODS.reject{ |m| m == :destroy }.each do |method|
- it "should declare option --#{method}" do
- @cert_app.should respond_to("handle_#{method}".to_sym)
- end
- end
+ it "should set log level to debug with the --debug option" do
- it "should set log level to info with the --verbose option" do
+ Puppet::Log.expects(:level=).with(:debug)
- Puppet::Log.expects(:level=).with(:info)
+ @cert_app.handle_debug(0)
+ end
- @cert_app.handle_verbose(0)
- end
+ it "should set the fingerprint digest with the --digest option" do
+ @cert_app.handle_digest(:digest)
- it "should set log level to debug with the --debug option" do
+ @cert_app.digest.should == :digest
+ end
- Puppet::Log.expects(:level=).with(:debug)
+ it "should set cert_mode to :destroy for --clean" do
+ @cert_app.handle_clean(0)
+ @cert_app.cert_mode.should == :destroy
+ end
- @cert_app.handle_debug(0)
- end
+ it "should set all to true for --all" do
+ @cert_app.handle_all(0)
+ @cert_app.all.should be_true
+ end
- it "should set the fingerprint digest with the --digest option" do
- @cert_app.handle_digest(:digest)
+ it "should set signed to true for --signed" do
+ @cert_app.handle_signed(0)
+ @cert_app.signed.should be_true
+ end
- @cert_app.digest.should == :digest
- end
+ Puppet::SSL::CertificateAuthority::Interface::INTERFACE_METHODS.reject { |m| m == :destroy }.each do |method|
+ it "should set cert_mode to #{method} with option --#{method}" do
+ @cert_app.send("handle_#{method}".to_sym, nil)
- it "should set cert_mode to :destroy for --clean" do
- @cert_app.handle_clean(0)
- @cert_app.cert_mode.should == :destroy
+ @cert_app.cert_mode.should == method
end
+ end
- it "should set all to true for --all" do
- @cert_app.handle_all(0)
- @cert_app.all.should be_true
- end
+ describe "during setup" do
- it "should set signed to true for --signed" do
- @cert_app.handle_signed(0)
- @cert_app.signed.should be_true
+ before :each do
+ Puppet::Log.stubs(:newdestination)
+ Puppet::SSL::Host.stubs(:ca_location=)
+ Puppet::SSL::CertificateAuthority.stubs(:new)
end
- Puppet::SSL::CertificateAuthority::Interface::INTERFACE_METHODS.reject { |m| m == :destroy }.each do |method|
- it "should set cert_mode to #{method} with option --#{method}" do
- @cert_app.send("handle_#{method}".to_sym, nil)
+ it "should set console as the log destination" do
+ Puppet::Log.expects(:newdestination).with(:console)
- @cert_app.cert_mode.should == method
- end
+ @cert_app.setup
end
- describe "during setup" do
-
- before :each do
- Puppet::Log.stubs(:newdestination)
- Puppet::SSL::Host.stubs(:ca_location=)
- Puppet::SSL::CertificateAuthority.stubs(:new)
- end
-
- it "should set console as the log destination" do
- Puppet::Log.expects(:newdestination).with(:console)
-
- @cert_app.setup
- end
-
- it "should print puppet config if asked to in Puppet config" do
- @cert_app.stubs(:exit)
- Puppet.settings.stubs(:print_configs?).returns(true)
-
- Puppet.settings.expects(:print_configs)
+ it "should print puppet config if asked to in Puppet config" do
+ @cert_app.stubs(:exit)
+ Puppet.settings.stubs(:print_configs?).returns(true)
- @cert_app.setup
- end
+ Puppet.settings.expects(:print_configs)
- it "should exit after printing puppet config if asked to in Puppet config" do
- Puppet.settings.stubs(:print_configs?).returns(true)
+ @cert_app.setup
+ end
- lambda { @cert_app.setup }.should raise_error(SystemExit)
- end
+ it "should exit after printing puppet config if asked to in Puppet config" do
+ Puppet.settings.stubs(:print_configs?).returns(true)
- it "should set the CA location to 'only'" do
- Puppet::SSL::Host.expects(:ca_location=).with(:only)
+ lambda { @cert_app.setup }.should raise_error(SystemExit)
+ end
- @cert_app.setup
- end
+ it "should set the CA location to 'only'" do
+ Puppet::SSL::Host.expects(:ca_location=).with(:only)
- it "should create a new certificate authority" do
- Puppet::SSL::CertificateAuthority.expects(:new)
+ @cert_app.setup
+ end
- @cert_app.setup
- end
+ it "should create a new certificate authority" do
+ Puppet::SSL::CertificateAuthority.expects(:new)
- it "should set the ca_location to :local if the cert_mode is generate" do
- @cert_app.find_mode('--generate')
- Puppet::SSL::Host.expects(:ca_location=).with(:local)
- @cert_app.setup
- end
+ @cert_app.setup
+ end
- it "should set the ca_location to :local if the cert_mode is destroy" do
- @cert_app.find_mode('--destroy')
- Puppet::SSL::Host.expects(:ca_location=).with(:local)
- @cert_app.setup
- end
+ it "should set the ca_location to :local if the cert_mode is generate" do
+ @cert_app.find_mode('--generate')
+ Puppet::SSL::Host.expects(:ca_location=).with(:local)
+ @cert_app.setup
+ end
- it "should set the ca_location to :only if the cert_mode is print" do
- @cert_app.find_mode('--print')
- Puppet::SSL::Host.expects(:ca_location=).with(:only)
- @cert_app.setup
- end
+ it "should set the ca_location to :local if the cert_mode is destroy" do
+ @cert_app.find_mode('--destroy')
+ Puppet::SSL::Host.expects(:ca_location=).with(:local)
+ @cert_app.setup
end
- describe "when running" do
- before :each do
- @cert_app.all = false
- @ca = stub_everything 'ca'
- @cert_app.ca = @ca
- @cert_app.command_line.stubs(:args).returns([])
- end
+ it "should set the ca_location to :only if the cert_mode is print" do
+ @cert_app.find_mode('--print')
+ Puppet::SSL::Host.expects(:ca_location=).with(:only)
+ @cert_app.setup
+ end
+ end
- it "should delegate to the CertificateAuthority" do
- @ca.expects(:apply)
+ describe "when running" do
+ before :each do
+ @cert_app.all = false
+ @ca = stub_everything 'ca'
+ @cert_app.ca = @ca
+ @cert_app.command_line.stubs(:args).returns([])
+ end
- @cert_app.main
- end
+ it "should delegate to the CertificateAuthority" do
+ @ca.expects(:apply)
- it "should delegate with :all if option --all was given" do
- @cert_app.handle_all(0)
+ @cert_app.main
+ end
- @ca.expects(:apply).with { |cert_mode,to| to[:to] == :all }
+ it "should delegate with :all if option --all was given" do
+ @cert_app.handle_all(0)
- @cert_app.main
- end
+ @ca.expects(:apply).with { |cert_mode,to| to[:to] == :all }
- it "should delegate to ca.apply with the hosts given on command line" do
- @cert_app.command_line.stubs(:args).returns(["host"])
+ @cert_app.main
+ end
- @ca.expects(:apply).with { |cert_mode,to| to[:to] == ["host"]}
+ it "should delegate to ca.apply with the hosts given on command line" do
+ @cert_app.command_line.stubs(:args).returns(["host"])
- @cert_app.main
- end
+ @ca.expects(:apply).with { |cert_mode,to| to[:to] == ["host"]}
- it "should send the currently set digest" do
- @cert_app.command_line.stubs(:args).returns(["host"])
- @cert_app.handle_digest(:digest)
+ @cert_app.main
+ end
- @ca.expects(:apply).with { |cert_mode,to| to[:digest] == :digest}
+ it "should send the currently set digest" do
+ @cert_app.command_line.stubs(:args).returns(["host"])
+ @cert_app.handle_digest(:digest)
- @cert_app.main
- end
+ @ca.expects(:apply).with { |cert_mode,to| to[:digest] == :digest}
- it "should delegate to ca.apply with current set cert_mode" do
- @cert_app.cert_mode = "currentmode"
- @cert_app.command_line.stubs(:args).returns(["host"])
+ @cert_app.main
+ end
- @ca.expects(:apply).with { |cert_mode,to| cert_mode == "currentmode" }
+ it "should delegate to ca.apply with current set cert_mode" do
+ @cert_app.cert_mode = "currentmode"
+ @cert_app.command_line.stubs(:args).returns(["host"])
- @cert_app.main
- end
+ @ca.expects(:apply).with { |cert_mode,to| cert_mode == "currentmode" }
- it "should revoke cert if cert_mode is clean" do
- @cert_app.cert_mode = :destroy
- @cert_app.command_line.stubs(:args).returns(["host"])
+ @cert_app.main
+ end
- @ca.expects(:apply).with { |cert_mode,to| cert_mode == :revoke }
- @ca.expects(:apply).with { |cert_mode,to| cert_mode == :destroy }
+ it "should revoke cert if cert_mode is clean" do
+ @cert_app.cert_mode = :destroy
+ @cert_app.command_line.stubs(:args).returns(["host"])
- @cert_app.main
- end
+ @ca.expects(:apply).with { |cert_mode,to| cert_mode == :revoke }
+ @ca.expects(:apply).with { |cert_mode,to| cert_mode == :destroy }
+ @cert_app.main
end
+
+ end
end
diff --git a/spec/unit/application/describe_spec.rb b/spec/unit/application/describe_spec.rb
index 002cdb7..7c64ff8 100755
--- a/spec/unit/application/describe_spec.rb
+++ b/spec/unit/application/describe_spec.rb
@@ -5,80 +5,80 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/application/describe'
describe Puppet::Application::Describe do
- before :each do
- @describe = Puppet::Application[:describe]
- end
+ before :each do
+ @describe = Puppet::Application[:describe]
+ end
- it "should ask Puppet::Application to not parse Puppet configuration file" do
- @describe.should_parse_config?.should be_false
- end
+ it "should ask Puppet::Application to not parse Puppet configuration file" do
+ @describe.should_parse_config?.should be_false
+ end
- it "should declare a main command" do
- @describe.should respond_to(:main)
- end
+ it "should declare a main command" do
+ @describe.should respond_to(:main)
+ end
- it "should declare a preinit block" do
- @describe.should respond_to(:preinit)
- end
+ it "should declare a preinit block" do
+ @describe.should respond_to(:preinit)
+ end
- [:providers,:list,:meta].each do |option|
- it "should declare handle_#{option} method" do
- @describe.should respond_to("handle_#{option}".to_sym)
- end
+ [:providers,:list,:meta].each do |option|
+ it "should declare handle_#{option} method" do
+ @describe.should respond_to("handle_#{option}".to_sym)
+ end
- it "should store argument value when calling handle_#{option}" do
- @describe.options.expects(:[]=).with("#{option}".to_sym, 'arg')
- @describe.send("handle_#{option}".to_sym, 'arg')
- end
+ it "should store argument value when calling handle_#{option}" do
+ @describe.options.expects(:[]=).with("#{option}".to_sym, 'arg')
+ @describe.send("handle_#{option}".to_sym, 'arg')
end
+ end
- describe "in preinit" do
- it "should set options[:parameteers] to true" do
- @describe.preinit
+ describe "in preinit" do
+ it "should set options[:parameteers] to true" do
+ @describe.preinit
- @describe.options[:parameters].should be_true
- end
+ @describe.options[:parameters].should be_true
end
+ end
- describe "when handling parameters" do
- it "should set options[:parameters] to false" do
- @describe.handle_short(nil)
+ describe "when handling parameters" do
+ it "should set options[:parameters] to false" do
+ @describe.handle_short(nil)
- @describe.options[:parameters].should be_false
- end
+ @describe.options[:parameters].should be_false
end
+ end
- describe "during setup" do
- it "should collect arguments in options[:types]" do
- @describe.command_line.stubs(:args).returns(['1','2'])
- @describe.setup
+ describe "during setup" do
+ it "should collect arguments in options[:types]" do
+ @describe.command_line.stubs(:args).returns(['1','2'])
+ @describe.setup
- @describe.options[:types].should == ['1','2']
- end
+ @describe.options[:types].should == ['1','2']
end
+ end
- describe "when running" do
+ describe "when running" do
- before :each do
- @typedoc = stub 'type_doc'
- TypeDoc.stubs(:new).returns(@typedoc)
- end
+ before :each do
+ @typedoc = stub 'type_doc'
+ TypeDoc.stubs(:new).returns(@typedoc)
+ end
- it "should call list_types if options list is set" do
- @describe.options[:list] = true
+ it "should call list_types if options list is set" do
+ @describe.options[:list] = true
- @typedoc.expects(:list_types)
+ @typedoc.expects(:list_types)
- @describe.run_command
- end
+ @describe.run_command
+ end
- it "should call format_type for each given types" do
- @describe.options[:list] = false
- @describe.options[:types] = ['type']
+ it "should call format_type for each given types" do
+ @describe.options[:list] = false
+ @describe.options[:types] = ['type']
- @typedoc.expects(:format_type).with('type', @describe.options)
- @describe.run_command
- end
+ @typedoc.expects(:format_type).with('type', @describe.options)
+ @describe.run_command
end
+ end
end
diff --git a/spec/unit/application/doc_spec.rb b/spec/unit/application/doc_spec.rb
index 0c2e7b4..7a22f5b 100755
--- a/spec/unit/application/doc_spec.rb
+++ b/spec/unit/application/doc_spec.rb
@@ -7,362 +7,362 @@ require 'puppet/util/reference'
require 'puppet/util/rdoc'
describe Puppet::Application::Doc do
- before :each do
- @doc = Puppet::Application[:doc]
- @doc.stubs(:puts)
- @doc.preinit
- Puppet::Util::Log.stubs(:newdestination)
- Puppet::Util::Log.stubs(:level=)
+ before :each do
+ @doc = Puppet::Application[:doc]
+ @doc.stubs(:puts)
+ @doc.preinit
+ Puppet::Util::Log.stubs(:newdestination)
+ Puppet::Util::Log.stubs(:level=)
+ end
+
+ it "should ask Puppet::Application to not parse Puppet configuration file" do
+ @doc.should_parse_config?.should be_false
+ end
+
+ it "should declare a other command" do
+ @doc.should respond_to(:other)
+ end
+
+ it "should declare a rdoc command" do
+ @doc.should respond_to(:rdoc)
+ end
+
+ it "should declare a trac command" do
+ @doc.should respond_to(:trac)
+ end
+
+ it "should declare a fallback for unknown options" do
+ @doc.should respond_to(:handle_unknown)
+ end
+
+ it "should declare a preinit block" do
+ @doc.should respond_to(:preinit)
+ end
+
+ describe "in preinit" do
+ it "should set references to []" do
+ @doc.preinit
+
+ @doc.options[:references].should == []
end
- it "should ask Puppet::Application to not parse Puppet configuration file" do
- @doc.should_parse_config?.should be_false
- end
+ it "should init mode to text" do
+ @doc.preinit
- it "should declare a other command" do
- @doc.should respond_to(:other)
+ @doc.options[:mode].should == :text
end
- it "should declare a rdoc command" do
- @doc.should respond_to(:rdoc)
- end
+ it "should init format to to_rest" do
+ @doc.preinit
- it "should declare a trac command" do
- @doc.should respond_to(:trac)
+ @doc.options[:format].should == :to_rest
end
-
- it "should declare a fallback for unknown options" do
- @doc.should respond_to(:handle_unknown)
+ end
+
+ describe "when handling options" do
+ [:all, :outputdir, :verbose, :debug, :charset].each do |option|
+ it "should declare handle_#{option} method" do
+ @doc.should respond_to("handle_#{option}".to_sym)
+ end
+
+ it "should store argument value when calling handle_#{option}" do
+ @doc.options.expects(:[]=).with(option, 'arg')
+ @doc.send("handle_#{option}".to_sym, 'arg')
+ end
end
- it "should declare a preinit block" do
- @doc.should respond_to(:preinit)
- end
+ it "should store the format if valid" do
+ Puppet::Util::Reference.stubs(:method_defined?).with('to_format').returns(true)
- describe "in preinit" do
- it "should set references to []" do
- @doc.preinit
+ @doc.options.expects(:[]=).with(:format, 'to_format')
- @doc.options[:references].should == []
- end
+ @doc.handle_format('format')
+ end
- it "should init mode to text" do
- @doc.preinit
+ it "should raise an error if the format is not valid" do
+ Puppet::Util::Reference.stubs(:method_defined?).with('to_format').returns(false)
+ lambda { @doc.handle_format('format') }
+ end
- @doc.options[:mode].should == :text
- end
+ it "should store the mode if valid" do
+ Puppet::Util::Reference.stubs(:modes).returns(stub('mode', :include? => true))
- it "should init format to to_rest" do
- @doc.preinit
+ @doc.options.expects(:[]=).with(:mode, :mode)
- @doc.options[:format].should == :to_rest
- end
+ @doc.handle_mode('mode')
end
- describe "when handling options" do
- [:all, :outputdir, :verbose, :debug, :charset].each do |option|
- it "should declare handle_#{option} method" do
- @doc.should respond_to("handle_#{option}".to_sym)
- end
+ it "should store the mode if :rdoc" do
+ Puppet::Util::Reference.modes.stubs(:include?).with('rdoc').returns(false)
- it "should store argument value when calling handle_#{option}" do
- @doc.options.expects(:[]=).with(option, 'arg')
- @doc.send("handle_#{option}".to_sym, 'arg')
- end
- end
-
- it "should store the format if valid" do
- Puppet::Util::Reference.stubs(:method_defined?).with('to_format').returns(true)
+ @doc.options.expects(:[]=).with(:mode, :rdoc)
- @doc.options.expects(:[]=).with(:format, 'to_format')
+ @doc.handle_mode('rdoc')
+ end
- @doc.handle_format('format')
- end
+ it "should raise an error if the mode is not valid" do
+ Puppet::Util::Reference.modes.stubs(:include?).with('unknown').returns(false)
+ lambda { @doc.handle_mode('unknown') }
+ end
- it "should raise an error if the format is not valid" do
- Puppet::Util::Reference.stubs(:method_defined?).with('to_format').returns(false)
- lambda { @doc.handle_format('format') }
- end
+ it "should list all references on list and exit" do
+ reference = stubs 'reference'
+ ref = stubs 'ref'
+ Puppet::Util::Reference.stubs(:references).returns([reference])
- it "should store the mode if valid" do
- Puppet::Util::Reference.stubs(:modes).returns(stub('mode', :include? => true))
+ Puppet::Util::Reference.expects(:reference).with(reference).returns(ref)
+ ref.expects(:doc)
+ @doc.expects(:exit)
- @doc.options.expects(:[]=).with(:mode, :mode)
+ @doc.handle_list(nil)
+ end
- @doc.handle_mode('mode')
- end
+ it "should add reference to references list with --reference" do
+ @doc.options[:references] = [:ref1]
- it "should store the mode if :rdoc" do
- Puppet::Util::Reference.modes.stubs(:include?).with('rdoc').returns(false)
+ @doc.handle_reference('ref2')
- @doc.options.expects(:[]=).with(:mode, :rdoc)
+ @doc.options[:references].should == [:ref1,:ref2]
+ end
+ end
- @doc.handle_mode('rdoc')
- end
+ describe "during setup" do
- it "should raise an error if the mode is not valid" do
- Puppet::Util::Reference.modes.stubs(:include?).with('unknown').returns(false)
- lambda { @doc.handle_mode('unknown') }
- end
+ before :each do
+ Puppet::Log.stubs(:newdestination)
+ @doc.command_line.stubs(:args).returns([])
+ end
- it "should list all references on list and exit" do
- reference = stubs 'reference'
- ref = stubs 'ref'
- Puppet::Util::Reference.stubs(:references).returns([reference])
+ it "should default to rdoc mode if there are command line arguments" do
+ @doc.command_line.stubs(:args).returns(["1"])
+ @doc.stubs(:setup_rdoc)
- Puppet::Util::Reference.expects(:reference).with(reference).returns(ref)
- ref.expects(:doc)
- @doc.expects(:exit)
+ @doc.options.expects(:[]=).with(:mode,:rdoc)
- @doc.handle_list(nil)
- end
+ @doc.setup
+ end
- it "should add reference to references list with --reference" do
- @doc.options[:references] = [:ref1]
+ it "should call setup_rdoc in rdoc mode" do
+ @doc.options.stubs(:[]).with(:mode).returns(:rdoc)
- @doc.handle_reference('ref2')
+ @doc.expects(:setup_rdoc)
- @doc.options[:references].should == [:ref1,:ref2]
- end
+ @doc.setup
end
- describe "during setup" do
+ it "should call setup_reference if not rdoc" do
+ @doc.options.stubs(:[]).with(:mode).returns(:test)
- before :each do
- Puppet::Log.stubs(:newdestination)
- @doc.command_line.stubs(:args).returns([])
- end
+ @doc.expects(:setup_reference)
- it "should default to rdoc mode if there are command line arguments" do
- @doc.command_line.stubs(:args).returns(["1"])
- @doc.stubs(:setup_rdoc)
+ @doc.setup
+ end
- @doc.options.expects(:[]=).with(:mode,:rdoc)
+ describe "in non-rdoc mode" do
- @doc.setup
- end
+ it "should get all non-dynamic reference if --all" do
+ @doc.options.stubs(:[]).with(:all).returns(true)
+ @doc.options.stubs(:[]).with(:references).returns([])
+ static = stub 'static', :dynamic? => false
+ dynamic = stub 'dynamic', :dynamic? => true
+ Puppet::Util::Reference.stubs(:reference).with(:static).returns(static)
+ Puppet::Util::Reference.stubs(:reference).with(:dynamic).returns(dynamic)
+ Puppet::Util::Reference.stubs(:references).returns([:static,:dynamic])
- it "should call setup_rdoc in rdoc mode" do
- @doc.options.stubs(:[]).with(:mode).returns(:rdoc)
+ @doc.options.stubs(:[]=).with(:references, [:static])
- @doc.expects(:setup_rdoc)
+ @doc.setup_reference
+ end
- @doc.setup
- end
+ it "should default to :type if no references" do
+ @doc.options.stubs(:[]).with(:all).returns(false)
+ array = stub 'array', :empty? => true
+ @doc.options.stubs(:[]).with(:references).returns(array)
- it "should call setup_reference if not rdoc" do
- @doc.options.stubs(:[]).with(:mode).returns(:test)
+ array.expects(:<<).with(:type)
- @doc.expects(:setup_reference)
+ @doc.setup_reference
+ end
- @doc.setup
- end
-
- describe "in non-rdoc mode" do
-
- it "should get all non-dynamic reference if --all" do
- @doc.options.stubs(:[]).with(:all).returns(true)
- @doc.options.stubs(:[]).with(:references).returns([])
- static = stub 'static', :dynamic? => false
- dynamic = stub 'dynamic', :dynamic? => true
- Puppet::Util::Reference.stubs(:reference).with(:static).returns(static)
- Puppet::Util::Reference.stubs(:reference).with(:dynamic).returns(dynamic)
- Puppet::Util::Reference.stubs(:references).returns([:static,:dynamic])
+ end
- @doc.options.stubs(:[]=).with(:references, [:static])
+ describe "in rdoc mode" do
- @doc.setup_reference
- end
+ before :each do
+ @doc.options.stubs(:[]).returns(false)
+ Puppet.stubs(:parse_config)
+ Puppet::Util::Log.stubs(:level=)
+ Puppet::Util::Log.stubs(:newdestination)
+ end
- it "should default to :type if no references" do
- @doc.options.stubs(:[]).with(:all).returns(false)
- array = stub 'array', :empty? => true
- @doc.options.stubs(:[]).with(:references).returns(array)
+ describe "when there are unknown args" do
- array.expects(:<<).with(:type)
+ it "should expand --modulepath if any" do
+ @doc.unknown_args = [ { :opt => "--modulepath", :arg => "path" } ]
+ Puppet.settings.stubs(:handlearg)
- @doc.setup_reference
- end
+ File.expects(:expand_path).with("path")
+ @doc.setup_rdoc
end
- describe "in rdoc mode" do
-
- before :each do
- @doc.options.stubs(:[]).returns(false)
- Puppet.stubs(:parse_config)
- Puppet::Util::Log.stubs(:level=)
- Puppet::Util::Log.stubs(:newdestination)
- end
-
- describe "when there are unknown args" do
-
- it "should expand --modulepath if any" do
- @doc.unknown_args = [ { :opt => "--modulepath", :arg => "path" } ]
- Puppet.settings.stubs(:handlearg)
-
- File.expects(:expand_path).with("path")
-
- @doc.setup_rdoc
- end
+ it "should expand --manifestdir if any" do
+ @doc.unknown_args = [ { :opt => "--manifestdir", :arg => "path" } ]
+ Puppet.settings.stubs(:handlearg)
- it "should expand --manifestdir if any" do
- @doc.unknown_args = [ { :opt => "--manifestdir", :arg => "path" } ]
- Puppet.settings.stubs(:handlearg)
+ File.expects(:expand_path).with("path")
- File.expects(:expand_path).with("path")
-
- @doc.setup_rdoc
- end
+ @doc.setup_rdoc
+ end
- it "should give them to Puppet.settings" do
- @doc.unknown_args = [ { :opt => :option, :arg => :argument } ]
- Puppet.settings.expects(:handlearg).with(:option,:argument)
+ it "should give them to Puppet.settings" do
+ @doc.unknown_args = [ { :opt => :option, :arg => :argument } ]
+ Puppet.settings.expects(:handlearg).with(:option,:argument)
- @doc.setup_rdoc
- end
- end
+ @doc.setup_rdoc
+ end
+ end
- it "should operate in master run_mode" do
- @doc.class.run_mode.name.should == :master
+ it "should operate in master run_mode" do
+ @doc.class.run_mode.name.should == :master
- @doc.setup_rdoc
- end
+ @doc.setup_rdoc
+ end
- it "should parse puppet configuration" do
- Puppet.expects(:parse_config)
+ it "should parse puppet configuration" do
+ Puppet.expects(:parse_config)
- @doc.setup_rdoc
- end
+ @doc.setup_rdoc
+ end
- it "should set log level to debug if --debug" do
- @doc.options.stubs(:[]).with(:debug).returns(true)
- Puppet::Util::Log.expects(:level=).with(:debug)
+ it "should set log level to debug if --debug" do
+ @doc.options.stubs(:[]).with(:debug).returns(true)
+ Puppet::Util::Log.expects(:level=).with(:debug)
- @doc.setup_rdoc
- end
+ @doc.setup_rdoc
+ end
- it "should set log level to info if --verbose" do
- @doc.options.stubs(:[]).with(:verbose).returns(true)
- Puppet::Util::Log.expects(:level=).with(:info)
+ it "should set log level to info if --verbose" do
+ @doc.options.stubs(:[]).with(:verbose).returns(true)
+ Puppet::Util::Log.expects(:level=).with(:info)
- @doc.setup_rdoc
- end
+ @doc.setup_rdoc
+ end
- it "should set log destination to console if --verbose" do
- @doc.options.stubs(:[]).with(:verbose).returns(true)
+ it "should set log destination to console if --verbose" do
+ @doc.options.stubs(:[]).with(:verbose).returns(true)
- Puppet::Util::Log.expects(:newdestination).with(:console)
+ Puppet::Util::Log.expects(:newdestination).with(:console)
- @doc.setup_rdoc
- end
+ @doc.setup_rdoc
+ end
- it "should set log destination to console if --debug" do
- @doc.options.stubs(:[]).with(:debug).returns(true)
+ it "should set log destination to console if --debug" do
+ @doc.options.stubs(:[]).with(:debug).returns(true)
- Puppet::Util::Log.expects(:newdestination).with(:console)
+ Puppet::Util::Log.expects(:newdestination).with(:console)
- @doc.setup_rdoc
- end
-
- end
+ @doc.setup_rdoc
+ end
end
- describe "when running" do
- before :each do
- end
+ end
- describe "in trac mode" do
- it "should call trac for each reference" do
- ref = stub 'ref'
- Puppet::Util::Reference.stubs(:reference).with(:ref).returns(ref)
- @doc.options.stubs(:[]).with(:references).returns([:ref])
- @doc.options.stubs(:[]).with(:mode).returns(:trac)
+ describe "when running" do
+ before :each do
+ end
- ref.expects(:trac)
+ describe "in trac mode" do
+ it "should call trac for each reference" do
+ ref = stub 'ref'
+ Puppet::Util::Reference.stubs(:reference).with(:ref).returns(ref)
+ @doc.options.stubs(:[]).with(:references).returns([:ref])
+ @doc.options.stubs(:[]).with(:mode).returns(:trac)
- @doc.trac
- end
- end
+ ref.expects(:trac)
- describe "in rdoc mode" do
- before :each do
- @doc.manifest = false
- Puppet.stubs(:info)
- Puppet.stubs(:[]).with(:trace).returns(false)
- @env = stub 'env'
- Puppet::Node::Environment.stubs(:new).returns(@env)
- @env.stubs(:modulepath).returns(['modules'])
- @env.stubs(:[]).with(:manifest).returns('manifests/site.pp')
- Puppet.stubs(:[]).with(:modulepath).returns('modules')
- Puppet.stubs(:[]).with(:manifestdir).returns('manifests')
- @doc.options.stubs(:[]).with(:all).returns(false)
- @doc.options.stubs(:[]).with(:outputdir).returns('doc')
- @doc.options.stubs(:[]).with(:charset).returns(nil)
- Puppet.settings.stubs(:[]=).with(:document_all, false)
- Puppet.settings.stubs(:setdefaults)
- Puppet::Util::RDoc.stubs(:rdoc)
- @doc.stubs(:exit)
- File.stubs(:expand_path).with('modules').returns('modules')
- File.stubs(:expand_path).with('manifests').returns('manifests')
- @doc.command_line.stubs(:args).returns([])
- end
-
- it "should set document_all on --all" do
- @doc.options.expects(:[]).with(:all).returns(true)
- Puppet.settings.expects(:[]=).with(:document_all, true)
-
- @doc.rdoc
- end
-
- it "should call Puppet::Util::RDoc.rdoc in full mode" do
- Puppet::Util::RDoc.expects(:rdoc).with('doc', ['modules','manifests'], nil)
- @doc.rdoc
- end
-
- it "should call Puppet::Util::RDoc.rdoc with a charset if --charset has been provided" do
- @doc.options.expects(:[]).with(:charset).returns("utf-8")
- Puppet::Util::RDoc.expects(:rdoc).with('doc', ['modules','manifests'], "utf-8")
- @doc.rdoc
- end
-
- it "should call Puppet::Util::RDoc.rdoc in full mode with outputdir set to doc if no --outputdir" do
- @doc.options.expects(:[]).with(:outputdir).returns(false)
- Puppet::Util::RDoc.expects(:rdoc).with('doc', ['modules','manifests'], nil)
- @doc.rdoc
- end
-
- it "should call Puppet::Util::RDoc.manifestdoc in manifest mode" do
- @doc.manifest = true
- Puppet::Util::RDoc.expects(:manifestdoc)
- @doc.rdoc
- end
-
- it "should get modulepath and manifestdir values from the environment" do
- @env.expects(:modulepath).returns(['envmodules1','envmodules2'])
- @env.expects(:[]).with(:manifest).returns('envmanifests/site.pp')
-
- Puppet::Util::RDoc.expects(:rdoc).with('doc', ['envmodules1','envmodules2','envmanifests'], nil)
-
- @doc.rdoc
- end
- end
+ @doc.trac
+ end
+ end
- describe "in the other modes" do
- it "should get reference in given format" do
- reference = stub 'reference'
- @doc.options.stubs(:[]).with(:mode).returns(:none)
- @doc.options.stubs(:[]).with(:references).returns([:ref])
- require 'puppet/util/reference'
- Puppet::Util::Reference.expects(:reference).with(:ref).returns(reference)
- @doc.options.stubs(:[]).with(:format).returns(:format)
- @doc.stubs(:exit)
-
- reference.expects(:send).with { |format,contents| format == :format }.returns('doc')
- @doc.other
- end
- end
+ describe "in rdoc mode" do
+ before :each do
+ @doc.manifest = false
+ Puppet.stubs(:info)
+ Puppet.stubs(:[]).with(:trace).returns(false)
+ @env = stub 'env'
+ Puppet::Node::Environment.stubs(:new).returns(@env)
+ @env.stubs(:modulepath).returns(['modules'])
+ @env.stubs(:[]).with(:manifest).returns('manifests/site.pp')
+ Puppet.stubs(:[]).with(:modulepath).returns('modules')
+ Puppet.stubs(:[]).with(:manifestdir).returns('manifests')
+ @doc.options.stubs(:[]).with(:all).returns(false)
+ @doc.options.stubs(:[]).with(:outputdir).returns('doc')
+ @doc.options.stubs(:[]).with(:charset).returns(nil)
+ Puppet.settings.stubs(:[]=).with(:document_all, false)
+ Puppet.settings.stubs(:setdefaults)
+ Puppet::Util::RDoc.stubs(:rdoc)
+ @doc.stubs(:exit)
+ File.stubs(:expand_path).with('modules').returns('modules')
+ File.stubs(:expand_path).with('manifests').returns('manifests')
+ @doc.command_line.stubs(:args).returns([])
+ end
+
+ it "should set document_all on --all" do
+ @doc.options.expects(:[]).with(:all).returns(true)
+ Puppet.settings.expects(:[]=).with(:document_all, true)
+
+ @doc.rdoc
+ end
+
+ it "should call Puppet::Util::RDoc.rdoc in full mode" do
+ Puppet::Util::RDoc.expects(:rdoc).with('doc', ['modules','manifests'], nil)
+ @doc.rdoc
+ end
+
+ it "should call Puppet::Util::RDoc.rdoc with a charset if --charset has been provided" do
+ @doc.options.expects(:[]).with(:charset).returns("utf-8")
+ Puppet::Util::RDoc.expects(:rdoc).with('doc', ['modules','manifests'], "utf-8")
+ @doc.rdoc
+ end
+
+ it "should call Puppet::Util::RDoc.rdoc in full mode with outputdir set to doc if no --outputdir" do
+ @doc.options.expects(:[]).with(:outputdir).returns(false)
+ Puppet::Util::RDoc.expects(:rdoc).with('doc', ['modules','manifests'], nil)
+ @doc.rdoc
+ end
+
+ it "should call Puppet::Util::RDoc.manifestdoc in manifest mode" do
+ @doc.manifest = true
+ Puppet::Util::RDoc.expects(:manifestdoc)
+ @doc.rdoc
+ end
+
+ it "should get modulepath and manifestdir values from the environment" do
+ @env.expects(:modulepath).returns(['envmodules1','envmodules2'])
+ @env.expects(:[]).with(:manifest).returns('envmanifests/site.pp')
+
+ Puppet::Util::RDoc.expects(:rdoc).with('doc', ['envmodules1','envmodules2','envmanifests'], nil)
+
+ @doc.rdoc
+ end
+ end
+ describe "in the other modes" do
+ it "should get reference in given format" do
+ reference = stub 'reference'
+ @doc.options.stubs(:[]).with(:mode).returns(:none)
+ @doc.options.stubs(:[]).with(:references).returns([:ref])
+ require 'puppet/util/reference'
+ Puppet::Util::Reference.expects(:reference).with(:ref).returns(reference)
+ @doc.options.stubs(:[]).with(:format).returns(:format)
+ @doc.stubs(:exit)
+
+ reference.expects(:send).with { |format,contents| format == :format }.returns('doc')
+ @doc.other
+ end
end
+
+ end
end
diff --git a/spec/unit/application/filebucket_spec.rb b/spec/unit/application/filebucket_spec.rb
index 58c7f7c..6e7a7b8 100644
--- a/spec/unit/application/filebucket_spec.rb
+++ b/spec/unit/application/filebucket_spec.rb
@@ -5,219 +5,219 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/application/filebucket'
describe Puppet::Application::Filebucket do
- before :each do
- @filebucket = Puppet::Application[:filebucket]
- end
-
- it "should ask Puppet::Application to not parse Puppet configuration file" do
- @filebucket.should_parse_config?.should be_false
- end
+ before :each do
+ @filebucket = Puppet::Application[:filebucket]
+ end
- it "should declare a get command" do
- @filebucket.should respond_to(:get)
- end
+ it "should ask Puppet::Application to not parse Puppet configuration file" do
+ @filebucket.should_parse_config?.should be_false
+ end
- it "should declare a backup command" do
- @filebucket.should respond_to(:backup)
- end
+ it "should declare a get command" do
+ @filebucket.should respond_to(:get)
+ end
- it "should declare a restore command" do
- @filebucket.should respond_to(:restore)
- end
+ it "should declare a backup command" do
+ @filebucket.should respond_to(:backup)
+ end
- [:bucket, :debug, :local, :remote, :verbose].each do |option|
- it "should declare handle_#{option} method" do
- @filebucket.should respond_to("handle_#{option}".to_sym)
- end
+ it "should declare a restore command" do
+ @filebucket.should respond_to(:restore)
+ end
- it "should store argument value when calling handle_#{option}" do
- @filebucket.options.expects(:[]=).with("#{option}".to_sym, 'arg')
- @filebucket.send("handle_#{option}".to_sym, 'arg')
- end
+ [:bucket, :debug, :local, :remote, :verbose].each do |option|
+ it "should declare handle_#{option} method" do
+ @filebucket.should respond_to("handle_#{option}".to_sym)
end
- describe "during setup" do
+ it "should store argument value when calling handle_#{option}" do
+ @filebucket.options.expects(:[]=).with("#{option}".to_sym, 'arg')
+ @filebucket.send("handle_#{option}".to_sym, 'arg')
+ end
+ end
- before :each do
- Puppet::Log.stubs(:newdestination)
- Puppet.stubs(:settraps)
- Puppet::Log.stubs(:level=)
- Puppet.stubs(:parse_config)
- Puppet::FileBucket::Dipper.stubs(:new)
- @filebucket.options.stubs(:[]).with(any_parameters)
- end
+ describe "during setup" do
+ before :each do
+ Puppet::Log.stubs(:newdestination)
+ Puppet.stubs(:settraps)
+ Puppet::Log.stubs(:level=)
+ Puppet.stubs(:parse_config)
+ Puppet::FileBucket::Dipper.stubs(:new)
+ @filebucket.options.stubs(:[]).with(any_parameters)
+ end
- it "should set console as the log destination" do
- Puppet::Log.expects(:newdestination).with(:console)
- @filebucket.setup
- end
+ it "should set console as the log destination" do
+ Puppet::Log.expects(:newdestination).with(:console)
- it "should trap INT" do
- @filebucket.expects(:trap).with(:INT)
+ @filebucket.setup
+ end
- @filebucket.setup
- end
+ it "should trap INT" do
+ @filebucket.expects(:trap).with(:INT)
- it "should set log level to debug if --debug was passed" do
- @filebucket.options.stubs(:[]).with(:debug).returns(true)
+ @filebucket.setup
+ end
- Puppet::Log.expects(:level=).with(:debug)
+ it "should set log level to debug if --debug was passed" do
+ @filebucket.options.stubs(:[]).with(:debug).returns(true)
- @filebucket.setup
- end
+ Puppet::Log.expects(:level=).with(:debug)
- it "should set log level to info if --verbose was passed" do
- @filebucket.options.stubs(:[]).with(:verbose).returns(true)
+ @filebucket.setup
+ end
- Puppet::Log.expects(:level=).with(:info)
+ it "should set log level to info if --verbose was passed" do
+ @filebucket.options.stubs(:[]).with(:verbose).returns(true)
- @filebucket.setup
- end
+ Puppet::Log.expects(:level=).with(:info)
- it "should Parse puppet config" do
- Puppet.expects(:parse_config)
+ @filebucket.setup
+ end
- @filebucket.setup
- end
+ it "should Parse puppet config" do
+ Puppet.expects(:parse_config)
- it "should print puppet config if asked to in Puppet config" do
- @filebucket.stubs(:exit)
- Puppet.settings.stubs(:print_configs?).returns(true)
+ @filebucket.setup
+ end
- Puppet.settings.expects(:print_configs)
+ it "should print puppet config if asked to in Puppet config" do
+ @filebucket.stubs(:exit)
+ Puppet.settings.stubs(:print_configs?).returns(true)
- @filebucket.setup
- end
+ Puppet.settings.expects(:print_configs)
- it "should exit after printing puppet config if asked to in Puppet config" do
- Puppet.settings.stubs(:print_configs?).returns(true)
+ @filebucket.setup
+ end
- lambda { @filebucket.setup }.should raise_error(SystemExit)
- end
+ it "should exit after printing puppet config if asked to in Puppet config" do
+ Puppet.settings.stubs(:print_configs?).returns(true)
- describe "with local bucket" do
+ lambda { @filebucket.setup }.should raise_error(SystemExit)
+ end
- before :each do
- @filebucket.options.stubs(:[]).with(:local).returns(true)
- end
+ describe "with local bucket" do
- it "should create a client with the default bucket if none passed" do
- Puppet.stubs(:[]).with(:bucketdir).returns("path")
+ before :each do
+ @filebucket.options.stubs(:[]).with(:local).returns(true)
+ end
- Puppet::FileBucket::Dipper.expects(:new).with { |h| h[:Path] == "path" }
+ it "should create a client with the default bucket if none passed" do
+ Puppet.stubs(:[]).with(:bucketdir).returns("path")
- @filebucket.setup
- end
+ Puppet::FileBucket::Dipper.expects(:new).with { |h| h[:Path] == "path" }
- it "should create a local Dipper with the given bucket" do
- @filebucket.options.stubs(:[]).with(:bucket).returns("path")
+ @filebucket.setup
+ end
- Puppet::FileBucket::Dipper.expects(:new).with { |h| h[:Path] == "path" }
+ it "should create a local Dipper with the given bucket" do
+ @filebucket.options.stubs(:[]).with(:bucket).returns("path")
- @filebucket.setup
- end
+ Puppet::FileBucket::Dipper.expects(:new).with { |h| h[:Path] == "path" }
- end
+ @filebucket.setup
+ end
- describe "with remote bucket" do
+ end
- it "should create a remote Client to the configured server" do
- Puppet.stubs(:[]).with(:server).returns("puppet.reductivelabs.com")
+ describe "with remote bucket" do
- Puppet::FileBucket::Dipper.expects(:new).with { |h| h[:Server] == "puppet.reductivelabs.com" }
+ it "should create a remote Client to the configured server" do
+ Puppet.stubs(:[]).with(:server).returns("puppet.reductivelabs.com")
- @filebucket.setup
- end
+ Puppet::FileBucket::Dipper.expects(:new).with { |h| h[:Server] == "puppet.reductivelabs.com" }
- end
+ @filebucket.setup
+ end
end
- describe "when running" do
+ end
- before :each do
- Puppet::Log.stubs(:newdestination)
- Puppet.stubs(:settraps)
- Puppet::Log.stubs(:level=)
- Puppet.stubs(:parse_config)
- Puppet::FileBucket::Dipper.stubs(:new)
- @filebucket.options.stubs(:[]).with(any_parameters)
+ describe "when running" do
- @client = stub 'client'
- Puppet::FileBucket::Dipper.stubs(:new).returns(@client)
+ before :each do
+ Puppet::Log.stubs(:newdestination)
+ Puppet.stubs(:settraps)
+ Puppet::Log.stubs(:level=)
+ Puppet.stubs(:parse_config)
+ Puppet::FileBucket::Dipper.stubs(:new)
+ @filebucket.options.stubs(:[]).with(any_parameters)
- @filebucket.setup
- end
+ @client = stub 'client'
+ Puppet::FileBucket::Dipper.stubs(:new).returns(@client)
- it "should use the first non-option parameter as the dispatch" do
- @filebucket.command_line.stubs(:args).returns(['get'])
+ @filebucket.setup
+ end
- @filebucket.expects(:get)
+ it "should use the first non-option parameter as the dispatch" do
+ @filebucket.command_line.stubs(:args).returns(['get'])
- @filebucket.run_command
- end
+ @filebucket.expects(:get)
- describe "the command get" do
+ @filebucket.run_command
+ end
- before :each do
- @filebucket.stubs(:print)
- @filebucket.stubs(:args).returns([])
- end
+ describe "the command get" do
- it "should call the client getfile method" do
- @client.expects(:getfile)
+ before :each do
+ @filebucket.stubs(:print)
+ @filebucket.stubs(:args).returns([])
+ end
- @filebucket.get
- end
+ it "should call the client getfile method" do
+ @client.expects(:getfile)
- it "should call the client getfile method with the given md5" do
- md5="DEADBEEF"
- @filebucket.stubs(:args).returns([md5])
+ @filebucket.get
+ end
- @client.expects(:getfile).with(md5)
+ it "should call the client getfile method with the given md5" do
+ md5="DEADBEEF"
+ @filebucket.stubs(:args).returns([md5])
- @filebucket.get
- end
+ @client.expects(:getfile).with(md5)
- it "should print the file content" do
- @client.stubs(:getfile).returns("content")
+ @filebucket.get
+ end
- @filebucket.expects(:print).returns("content")
+ it "should print the file content" do
+ @client.stubs(:getfile).returns("content")
- @filebucket.get
- end
+ @filebucket.expects(:print).returns("content")
- end
+ @filebucket.get
+ end
- describe "the command backup" do
- it "should call the client backup method for each given parameter" do
- @filebucket.stubs(:puts)
- FileTest.stubs(:exists?).returns(true)
- FileTest.stubs(:readable?).returns(true)
- @filebucket.stubs(:args).returns(["file1", "file2"])
+ end
- @client.expects(:backup).with("file1")
- @client.expects(:backup).with("file2")
+ describe "the command backup" do
+ it "should call the client backup method for each given parameter" do
+ @filebucket.stubs(:puts)
+ FileTest.stubs(:exists?).returns(true)
+ FileTest.stubs(:readable?).returns(true)
+ @filebucket.stubs(:args).returns(["file1", "file2"])
- @filebucket.backup
- end
- end
+ @client.expects(:backup).with("file1")
+ @client.expects(:backup).with("file2")
- describe "the command restore" do
- it "should call the client getfile method with the given md5" do
- md5="DEADBEEF"
- file="testfile"
- @filebucket.stubs(:args).returns([file, md5])
+ @filebucket.backup
+ end
+ end
- @client.expects(:restore).with(file,md5)
+ describe "the command restore" do
+ it "should call the client getfile method with the given md5" do
+ md5="DEADBEEF"
+ file="testfile"
+ @filebucket.stubs(:args).returns([file, md5])
- @filebucket.restore
- end
- end
+ @client.expects(:restore).with(file,md5)
+ @filebucket.restore
+ end
end
+ end
+
end
diff --git a/spec/unit/application/kick_spec.rb b/spec/unit/application/kick_spec.rb
index 0a530b4..dea7ec1 100755
--- a/spec/unit/application/kick_spec.rb
+++ b/spec/unit/application/kick_spec.rb
@@ -6,308 +6,308 @@ require 'puppet/application/kick'
describe Puppet::Application::Kick do
- confine "Kick's eventloops can only start on POSIX" => Puppet.features.posix?
-
- before :each do
- require 'puppet/util/ldap/connection'
- Puppet::Util::Ldap::Connection.stubs(:new).returns(stub_everything)
- @kick = Puppet::Application[:kick]
- Puppet::Util::Log.stubs(:newdestination)
- Puppet::Util::Log.stubs(:level=)
+ confine "Kick's eventloops can only start on POSIX" => Puppet.features.posix?
+
+ before :each do
+ require 'puppet/util/ldap/connection'
+ Puppet::Util::Ldap::Connection.stubs(:new).returns(stub_everything)
+ @kick = Puppet::Application[:kick]
+ Puppet::Util::Log.stubs(:newdestination)
+ Puppet::Util::Log.stubs(:level=)
+ end
+
+ describe ".new" do
+ it "should take a command-line object as an argument" do
+ command_line = stub_everything "command_line"
+ lambda{ Puppet::Application::Kick.new( command_line ) }.should_not raise_error
end
+ end
- describe ".new" do
- it "should take a command-line object as an argument" do
- command_line = stub_everything "command_line"
- lambda{ Puppet::Application::Kick.new( command_line ) }.should_not raise_error
- end
- end
+ it "should ask Puppet::Application to not parse Puppet configuration file" do
+ @kick.should_parse_config?.should be_false
+ end
- it "should ask Puppet::Application to not parse Puppet configuration file" do
- @kick.should_parse_config?.should be_false
- end
+ it "should declare a main command" do
+ @kick.should respond_to(:main)
+ end
- it "should declare a main command" do
- @kick.should respond_to(:main)
- end
+ it "should declare a test command" do
+ @kick.should respond_to(:test)
+ end
- it "should declare a test command" do
- @kick.should respond_to(:test)
- end
+ it "should declare a preinit block" do
+ @kick.should respond_to(:preinit)
+ end
- it "should declare a preinit block" do
- @kick.should respond_to(:preinit)
+ describe "during preinit" do
+ before :each do
+ @kick.stubs(:trap)
end
- describe "during preinit" do
- before :each do
- @kick.stubs(:trap)
- end
-
- it "should catch INT and TERM" do
- @kick.stubs(:trap).with { |arg,block| arg == :INT or arg == :TERM }
+ it "should catch INT and TERM" do
+ @kick.stubs(:trap).with { |arg,block| arg == :INT or arg == :TERM }
- @kick.preinit
- end
+ @kick.preinit
+ end
- it "should set parallel option to 1" do
- @kick.preinit
+ it "should set parallel option to 1" do
+ @kick.preinit
- @kick.options[:parallel].should == 1
- end
+ @kick.options[:parallel].should == 1
+ end
- it "should set verbose by default" do
- @kick.preinit
+ it "should set verbose by default" do
+ @kick.preinit
- @kick.options[:verbose].should be_true
- end
+ @kick.options[:verbose].should be_true
+ end
- it "should set fqdn by default" do
- @kick.preinit
+ it "should set fqdn by default" do
+ @kick.preinit
- @kick.options[:fqdn].should be_true
- end
+ @kick.options[:fqdn].should be_true
+ end
- it "should set ignoreschedules to 'false'" do
- @kick.preinit
+ it "should set ignoreschedules to 'false'" do
+ @kick.preinit
- @kick.options[:ignoreschedules].should be_false
- end
+ @kick.options[:ignoreschedules].should be_false
+ end
- it "should set foreground to 'false'" do
- @kick.preinit
+ it "should set foreground to 'false'" do
+ @kick.preinit
- @kick.options[:foreground].should be_false
- end
+ @kick.options[:foreground].should be_false
end
+ end
- describe "when applying options" do
+ describe "when applying options" do
- before do
- @kick.preinit
- end
+ before do
+ @kick.preinit
+ end
- [:all, :foreground, :debug, :ping, :test].each do |option|
- it "should declare handle_#{option} method" do
- @kick.should respond_to("handle_#{option}".to_sym)
- end
+ [:all, :foreground, :debug, :ping, :test].each do |option|
+ it "should declare handle_#{option} method" do
+ @kick.should respond_to("handle_#{option}".to_sym)
+ end
- it "should store argument value when calling handle_#{option}" do
- @kick.options.expects(:[]=).with(option, 'arg')
- @kick.send("handle_#{option}".to_sym, 'arg')
- end
- end
+ it "should store argument value when calling handle_#{option}" do
+ @kick.options.expects(:[]=).with(option, 'arg')
+ @kick.send("handle_#{option}".to_sym, 'arg')
+ end
+ end
- it "should add to the host list with the host option" do
- @kick.handle_host('host')
+ it "should add to the host list with the host option" do
+ @kick.handle_host('host')
- @kick.hosts.should == ['host']
- end
+ @kick.hosts.should == ['host']
+ end
- it "should add to the tag list with the tag option" do
- @kick.handle_tag('tag')
+ it "should add to the tag list with the tag option" do
+ @kick.handle_tag('tag')
- @kick.tags.should == ['tag']
- end
+ @kick.tags.should == ['tag']
+ end
- it "should add to the class list with the class option" do
- @kick.handle_class('class')
+ it "should add to the class list with the class option" do
+ @kick.handle_class('class')
- @kick.classes.should == ['class']
- end
+ @kick.classes.should == ['class']
end
+ end
- describe "during setup" do
+ describe "during setup" do
- before :each do
- @kick.classes = []
- @kick.tags = []
- @kick.hosts = []
- Puppet::Log.stubs(:level=)
- @kick.stubs(:trap)
- @kick.stubs(:puts)
- Puppet.stubs(:parse_config)
+ before :each do
+ @kick.classes = []
+ @kick.tags = []
+ @kick.hosts = []
+ Puppet::Log.stubs(:level=)
+ @kick.stubs(:trap)
+ @kick.stubs(:puts)
+ Puppet.stubs(:parse_config)
+
+ @kick.options.stubs(:[]).with(any_parameters)
+ end
- @kick.options.stubs(:[]).with(any_parameters)
- end
+ it "should set log level to debug if --debug was passed" do
+ @kick.options.stubs(:[]).with(:debug).returns(true)
- it "should set log level to debug if --debug was passed" do
- @kick.options.stubs(:[]).with(:debug).returns(true)
+ Puppet::Log.expects(:level=).with(:debug)
- Puppet::Log.expects(:level=).with(:debug)
+ @kick.setup
+ end
- @kick.setup
- end
+ it "should set log level to info if --verbose was passed" do
+ @kick.options.stubs(:[]).with(:verbose).returns(true)
- it "should set log level to info if --verbose was passed" do
- @kick.options.stubs(:[]).with(:verbose).returns(true)
+ Puppet::Log.expects(:level=).with(:info)
- Puppet::Log.expects(:level=).with(:info)
+ @kick.setup
+ end
- @kick.setup
- end
+ it "should Parse puppet config" do
+ Puppet.expects(:parse_config)
- it "should Parse puppet config" do
- Puppet.expects(:parse_config)
+ @kick.setup
+ end
- @kick.setup
- end
+ describe "when using the ldap node terminus" do
+ before :each do
+ Puppet.stubs(:[]).with(:node_terminus).returns("ldap")
+ end
- describe "when using the ldap node terminus" do
- before :each do
- Puppet.stubs(:[]).with(:node_terminus).returns("ldap")
- end
+ it "should pass the fqdn option to search" do
+ @kick.options.stubs(:[]).with(:fqdn).returns(:something)
+ @kick.options.stubs(:[]).with(:all).returns(true)
+ @kick.stubs(:puts)
- it "should pass the fqdn option to search" do
- @kick.options.stubs(:[]).with(:fqdn).returns(:something)
- @kick.options.stubs(:[]).with(:all).returns(true)
- @kick.stubs(:puts)
+ Puppet::Node.expects(:search).with("whatever",:fqdn => :something).returns([])
- Puppet::Node.expects(:search).with("whatever",:fqdn => :something).returns([])
+ @kick.setup
+ end
- @kick.setup
- end
+ it "should search for all nodes if --all" do
+ @kick.options.stubs(:[]).with(:all).returns(true)
+ @kick.stubs(:puts)
- it "should search for all nodes if --all" do
- @kick.options.stubs(:[]).with(:all).returns(true)
- @kick.stubs(:puts)
+ Puppet::Node.expects(:search).with("whatever",:fqdn => nil).returns([])
- Puppet::Node.expects(:search).with("whatever",:fqdn => nil).returns([])
+ @kick.setup
+ end
- @kick.setup
- end
+ it "should search for nodes including given classes" do
+ @kick.options.stubs(:[]).with(:all).returns(false)
+ @kick.stubs(:puts)
+ @kick.classes = ['class']
- it "should search for nodes including given classes" do
- @kick.options.stubs(:[]).with(:all).returns(false)
- @kick.stubs(:puts)
- @kick.classes = ['class']
+ Puppet::Node.expects(:search).with("whatever", :class => "class", :fqdn => nil).returns([])
- Puppet::Node.expects(:search).with("whatever", :class => "class", :fqdn => nil).returns([])
+ @kick.setup
+ end
+ end
- @kick.setup
- end
- end
+ describe "when using regular nodes" do
+ it "should fail if some classes have been specified" do
+ $stderr.stubs(:puts)
+ @kick.classes = ['class']
- describe "when using regular nodes" do
- it "should fail if some classes have been specified" do
- $stderr.stubs(:puts)
- @kick.classes = ['class']
+ @kick.expects(:exit).with(24)
- @kick.expects(:exit).with(24)
+ @kick.setup
+ end
+ end
+ end
- @kick.setup
- end
- end
+ describe "when running" do
+ before :each do
+ @kick.stubs(:puts)
end
- describe "when running" do
- before :each do
- @kick.stubs(:puts)
- end
+ it "should dispatch to test if --test is used" do
+ @kick.options.stubs(:[]).with(:test).returns(true)
- it "should dispatch to test if --test is used" do
- @kick.options.stubs(:[]).with(:test).returns(true)
+ @kick.expects(:test)
+ @kick.run_command
+ end
- @kick.expects(:test)
- @kick.run_command
- end
+ it "should dispatch to main if --test is not used" do
+ @kick.options.stubs(:[]).with(:test).returns(false)
- it "should dispatch to main if --test is not used" do
- @kick.options.stubs(:[]).with(:test).returns(false)
+ @kick.expects(:main)
+ @kick.run_command
+ end
- @kick.expects(:main)
- @kick.run_command
- end
+ describe "the test command" do
+ it "should exit with exit code 0 " do
+ @kick.expects(:exit).with(0)
- describe "the test command" do
- it "should exit with exit code 0 " do
- @kick.expects(:exit).with(0)
+ @kick.test
+ end
+ end
- @kick.test
- end
+ describe "the main command" do
+ before :each do
+ @kick.options.stubs(:[]).with(:parallel).returns(1)
+ @kick.options.stubs(:[]).with(:ping).returns(false)
+ @kick.options.stubs(:[]).with(:ignoreschedules).returns(false)
+ @kick.options.stubs(:[]).with(:foreground).returns(false)
+ @kick.options.stubs(:[]).with(:debug).returns(false)
+ @kick.stubs(:print)
+ @kick.stubs(:exit)
+ @kick.preinit
+ @kick.stubs(:parse_options)
+ @kick.setup
+ $stderr.stubs(:puts)
+ end
+
+ it "should create as much childs as --parallel" do
+ @kick.options.stubs(:[]).with(:parallel).returns(3)
+ @kick.hosts = ['host1', 'host2', 'host3']
+ @kick.stubs(:exit).raises(SystemExit)
+ Process.stubs(:wait).returns(1).then.returns(2).then.returns(3).then.raises(Errno::ECHILD)
+
+ @kick.expects(:fork).times(3).returns(1).then.returns(2).then.returns(3)
+
+ lambda { @kick.main }.should raise_error
+ end
+
+ it "should delegate to run_for_host per host" do
+ @kick.hosts = ['host1', 'host2']
+ @kick.stubs(:exit).raises(SystemExit)
+ @kick.stubs(:fork).returns(1).yields
+ Process.stubs(:wait).returns(1).then.raises(Errno::ECHILD)
+
+ @kick.expects(:run_for_host).times(2)
+
+ lambda { @kick.main }.should raise_error
+ end
+
+ describe "during call of run_for_host" do
+ before do
+ require 'puppet/run'
+ options = {
+ :background => true, :ignoreschedules => false, :tags => []
+ }
+ @kick.preinit
+ @agent_run = Puppet::Run.new( options.dup )
+ @agent_run.stubs(:status).returns("success")
+
+ Puppet::Run.indirection.expects(:terminus_class=).with( :rest )
+ Puppet::Run.expects(:new).with( options ).returns(@agent_run)
end
- describe "the main command" do
- before :each do
- @kick.options.stubs(:[]).with(:parallel).returns(1)
- @kick.options.stubs(:[]).with(:ping).returns(false)
- @kick.options.stubs(:[]).with(:ignoreschedules).returns(false)
- @kick.options.stubs(:[]).with(:foreground).returns(false)
- @kick.options.stubs(:[]).with(:debug).returns(false)
- @kick.stubs(:print)
- @kick.stubs(:exit)
- @kick.preinit
- @kick.stubs(:parse_options)
- @kick.setup
- $stderr.stubs(:puts)
- end
-
- it "should create as much childs as --parallel" do
- @kick.options.stubs(:[]).with(:parallel).returns(3)
- @kick.hosts = ['host1', 'host2', 'host3']
- @kick.stubs(:exit).raises(SystemExit)
- Process.stubs(:wait).returns(1).then.returns(2).then.returns(3).then.raises(Errno::ECHILD)
-
- @kick.expects(:fork).times(3).returns(1).then.returns(2).then.returns(3)
-
- lambda { @kick.main }.should raise_error
- end
-
- it "should delegate to run_for_host per host" do
- @kick.hosts = ['host1', 'host2']
- @kick.stubs(:exit).raises(SystemExit)
- @kick.stubs(:fork).returns(1).yields
- Process.stubs(:wait).returns(1).then.raises(Errno::ECHILD)
+ it "should call run on a Puppet::Run for the given host" do
+ @agent_run.expects(:save).with('https://host:8139/production/run/host').returns(@agent_run)
- @kick.expects(:run_for_host).times(2)
-
- lambda { @kick.main }.should raise_error
- end
-
- describe "during call of run_for_host" do
- before do
- require 'puppet/run'
- options = {
- :background => true, :ignoreschedules => false, :tags => []
- }
- @kick.preinit
- @agent_run = Puppet::Run.new( options.dup )
- @agent_run.stubs(:status).returns("success")
-
- Puppet::Run.indirection.expects(:terminus_class=).with( :rest )
- Puppet::Run.expects(:new).with( options ).returns(@agent_run)
- end
-
- it "should call run on a Puppet::Run for the given host" do
- @agent_run.expects(:save).with('https://host:8139/production/run/host').returns(@agent_run)
-
- @kick.run_for_host('host')
- end
+ @kick.run_for_host('host')
+ end
- it "should exit the child with 0 on success" do
- @agent_run.stubs(:status).returns("success")
+ it "should exit the child with 0 on success" do
+ @agent_run.stubs(:status).returns("success")
- @kick.expects(:exit).with(0)
+ @kick.expects(:exit).with(0)
- @kick.run_for_host('host')
- end
+ @kick.run_for_host('host')
+ end
- it "should exit the child with 3 on running" do
- @agent_run.stubs(:status).returns("running")
+ it "should exit the child with 3 on running" do
+ @agent_run.stubs(:status).returns("running")
- @kick.expects(:exit).with(3)
+ @kick.expects(:exit).with(3)
- @kick.run_for_host('host')
- end
+ @kick.run_for_host('host')
+ end
- it "should exit the child with 12 on unknown answer" do
- @agent_run.stubs(:status).returns("whatever")
+ it "should exit the child with 12 on unknown answer" do
+ @agent_run.stubs(:status).returns("whatever")
- @kick.expects(:exit).with(12)
+ @kick.expects(:exit).with(12)
- @kick.run_for_host('host')
- end
- end
+ @kick.run_for_host('host')
end
+ end
end
+ end
end
diff --git a/spec/unit/application/master_spec.rb b/spec/unit/application/master_spec.rb
index f3c3b35..0baa822 100644
--- a/spec/unit/application/master_spec.rb
+++ b/spec/unit/application/master_spec.rb
@@ -7,447 +7,447 @@ require 'puppet/daemon'
require 'puppet/network/server'
describe Puppet::Application::Master do
+ before :each do
+ @master = Puppet::Application[:master]
+ @daemon = stub_everything 'daemon'
+ Puppet::Daemon.stubs(:new).returns(@daemon)
+ Puppet::Util::Log.stubs(:newdestination)
+ Puppet::Util::Log.stubs(:level=)
+
+ Puppet::Node.stubs(:terminus_class=)
+ Puppet::Node.stubs(:cache_class=)
+ Puppet::Node::Facts.stubs(:terminus_class=)
+ Puppet::Node::Facts.stubs(:cache_class=)
+ Puppet::Transaction::Report.stubs(:terminus_class=)
+ Puppet::Resource::Catalog.stubs(:terminus_class=)
+ end
+
+ it "should operate in master run_mode" do
+ @master.class.run_mode.name.should equal :master
+ end
+
+ it "should ask Puppet::Application to parse Puppet configuration file" do
+ @master.should_parse_config?.should be_true
+ end
+
+ it "should declare a main command" do
+ @master.should respond_to(:main)
+ end
+
+ it "should declare a parseonly command" do
+ @master.should respond_to(:parseonly)
+ end
+
+ it "should declare a compile command" do
+ @master.should respond_to(:compile)
+ end
+
+ it "should declare a preinit block" do
+ @master.should respond_to(:preinit)
+ end
+
+ describe "during preinit" do
before :each do
- @master = Puppet::Application[:master]
- @daemon = stub_everything 'daemon'
- Puppet::Daemon.stubs(:new).returns(@daemon)
- Puppet::Util::Log.stubs(:newdestination)
- Puppet::Util::Log.stubs(:level=)
-
- Puppet::Node.stubs(:terminus_class=)
- Puppet::Node.stubs(:cache_class=)
- Puppet::Node::Facts.stubs(:terminus_class=)
- Puppet::Node::Facts.stubs(:cache_class=)
- Puppet::Transaction::Report.stubs(:terminus_class=)
- Puppet::Resource::Catalog.stubs(:terminus_class=)
+ @master.stubs(:trap)
end
- it "should operate in master run_mode" do
- @master.class.run_mode.name.should equal :master
- end
+ it "should catch INT" do
+ @master.stubs(:trap).with { |arg,block| arg == :INT }
- it "should ask Puppet::Application to parse Puppet configuration file" do
- @master.should_parse_config?.should be_true
+ @master.preinit
end
- it "should declare a main command" do
- @master.should respond_to(:main)
- end
+ it "should create a Puppet Daemon" do
+ Puppet::Daemon.expects(:new).returns(@daemon)
- it "should declare a parseonly command" do
- @master.should respond_to(:parseonly)
+ @master.preinit
end
- it "should declare a compile command" do
- @master.should respond_to(:compile)
- end
+ it "should give ARGV to the Daemon" do
+ argv = stub 'argv'
+ ARGV.stubs(:dup).returns(argv)
+ @daemon.expects(:argv=).with(argv)
- it "should declare a preinit block" do
- @master.should respond_to(:preinit)
+ @master.preinit
end
- describe "during preinit" do
- before :each do
- @master.stubs(:trap)
- end
-
- it "should catch INT" do
- @master.stubs(:trap).with { |arg,block| arg == :INT }
-
- @master.preinit
- end
-
- it "should create a Puppet Daemon" do
- Puppet::Daemon.expects(:new).returns(@daemon)
-
- @master.preinit
- end
-
- it "should give ARGV to the Daemon" do
- argv = stub 'argv'
- ARGV.stubs(:dup).returns(argv)
- @daemon.expects(:argv=).with(argv)
-
- @master.preinit
- end
+ end
+ [:debug,:verbose].each do |option|
+ it "should declare handle_#{option} method" do
+ @master.should respond_to("handle_#{option}".to_sym)
end
- [:debug,:verbose].each do |option|
- it "should declare handle_#{option} method" do
- @master.should respond_to("handle_#{option}".to_sym)
- end
-
- it "should store argument value when calling handle_#{option}" do
- @master.options.expects(:[]=).with(option, 'arg')
- @master.send("handle_#{option}".to_sym, 'arg')
- end
+ it "should store argument value when calling handle_#{option}" do
+ @master.options.expects(:[]=).with(option, 'arg')
+ @master.send("handle_#{option}".to_sym, 'arg')
end
+ end
- describe "when applying options" do
- before do
- @master.command_line.stubs(:args).returns([])
- end
+ describe "when applying options" do
+ before do
+ @master.command_line.stubs(:args).returns([])
+ end
- it "should set the log destination with --logdest" do
- Puppet::Log.expects(:newdestination).with("console")
+ it "should set the log destination with --logdest" do
+ Puppet::Log.expects(:newdestination).with("console")
- @master.handle_logdest("console")
- end
+ @master.handle_logdest("console")
+ end
- it "should put the setdest options to true" do
- @master.options.expects(:[]=).with(:setdest,true)
+ it "should put the setdest options to true" do
+ @master.options.expects(:[]=).with(:setdest,true)
- @master.handle_logdest("console")
- end
+ @master.handle_logdest("console")
+ end
- it "should parse the log destination from ARGV" do
- @master.command_line.stubs(:args).returns(%w{--logdest /my/file})
+ it "should parse the log destination from ARGV" do
+ @master.command_line.stubs(:args).returns(%w{--logdest /my/file})
- Puppet::Util::Log.expects(:newdestination).with("/my/file")
+ Puppet::Util::Log.expects(:newdestination).with("/my/file")
- @master.parse_options
- end
+ @master.parse_options
end
+ end
- describe "during setup" do
+ describe "during setup" do
- before :each do
- Puppet::Log.stubs(:newdestination)
- Puppet.stubs(:settraps)
- Puppet::Log.stubs(:level=)
- Puppet::SSL::CertificateAuthority.stubs(:instance)
- Puppet::SSL::CertificateAuthority.stubs(:ca?)
- Puppet.settings.stubs(:use)
+ before :each do
+ Puppet::Log.stubs(:newdestination)
+ Puppet.stubs(:settraps)
+ Puppet::Log.stubs(:level=)
+ Puppet::SSL::CertificateAuthority.stubs(:instance)
+ Puppet::SSL::CertificateAuthority.stubs(:ca?)
+ Puppet.settings.stubs(:use)
+
+ @master.options.stubs(:[]).with(any_parameters)
+ end
- @master.options.stubs(:[]).with(any_parameters)
- end
+ it "should set log level to debug if --debug was passed" do
+ @master.options.stubs(:[]).with(:debug).returns(true)
- it "should set log level to debug if --debug was passed" do
- @master.options.stubs(:[]).with(:debug).returns(true)
+ Puppet::Log.expects(:level=).with(:debug)
- Puppet::Log.expects(:level=).with(:debug)
+ @master.setup
+ end
- @master.setup
- end
+ it "should set log level to info if --verbose was passed" do
+ @master.options.stubs(:[]).with(:verbose).returns(true)
- it "should set log level to info if --verbose was passed" do
- @master.options.stubs(:[]).with(:verbose).returns(true)
+ Puppet::Log.expects(:level=).with(:info)
- Puppet::Log.expects(:level=).with(:info)
+ @master.setup
+ end
- @master.setup
- end
+ it "should set console as the log destination if no --logdest and --daemonize" do
+ @master.stubs(:[]).with(:daemonize).returns(:false)
- it "should set console as the log destination if no --logdest and --daemonize" do
- @master.stubs(:[]).with(:daemonize).returns(:false)
+ Puppet::Log.expects(:newdestination).with(:syslog)
- Puppet::Log.expects(:newdestination).with(:syslog)
+ @master.setup
+ end
- @master.setup
- end
+ it "should set syslog as the log destination if no --logdest and not --daemonize" do
+ Puppet::Log.expects(:newdestination).with(:syslog)
- it "should set syslog as the log destination if no --logdest and not --daemonize" do
- Puppet::Log.expects(:newdestination).with(:syslog)
+ @master.setup
+ end
- @master.setup
- end
+ it "should set syslog as the log destination if --rack" do
+ @master.options.stubs(:[]).with(:rack).returns(:true)
- it "should set syslog as the log destination if --rack" do
- @master.options.stubs(:[]).with(:rack).returns(:true)
+ Puppet::Log.expects(:newdestination).with(:syslog)
- Puppet::Log.expects(:newdestination).with(:syslog)
+ @master.setup
+ end
- @master.setup
- end
+ it "should print puppet config if asked to in Puppet config" do
+ @master.stubs(:exit)
+ Puppet.settings.stubs(:print_configs?).returns(true)
- it "should print puppet config if asked to in Puppet config" do
- @master.stubs(:exit)
- Puppet.settings.stubs(:print_configs?).returns(true)
+ Puppet.settings.expects(:print_configs)
- Puppet.settings.expects(:print_configs)
+ @master.setup
+ end
- @master.setup
- end
+ it "should exit after printing puppet config if asked to in Puppet config" do
+ Puppet.settings.stubs(:print_configs?).returns(true)
- it "should exit after printing puppet config if asked to in Puppet config" do
- Puppet.settings.stubs(:print_configs?).returns(true)
+ lambda { @master.setup }.should raise_error(SystemExit)
+ end
- lambda { @master.setup }.should raise_error(SystemExit)
- end
+ it "should tell Puppet.settings to use :main,:ssl and :master category" do
+ Puppet.settings.expects(:use).with(:main,:master,:ssl)
- it "should tell Puppet.settings to use :main,:ssl and :master category" do
- Puppet.settings.expects(:use).with(:main,:master,:ssl)
+ @master.setup
+ end
- @master.setup
- end
+ it "should cache class in yaml" do
+ Puppet::Node.expects(:cache_class=).with(:yaml)
- it "should cache class in yaml" do
- Puppet::Node.expects(:cache_class=).with(:yaml)
+ @master.setup
+ end
- @master.setup
- end
+ describe "with no ca" do
- describe "with no ca" do
+ it "should set the ca_location to none" do
+ Puppet::SSL::Host.expects(:ca_location=).with(:none)
- it "should set the ca_location to none" do
- Puppet::SSL::Host.expects(:ca_location=).with(:none)
+ @master.setup
+ end
- @master.setup
- end
+ end
- end
+ describe "with a ca configured" do
- describe "with a ca configured" do
+ before :each do
+ Puppet::SSL::CertificateAuthority.stubs(:ca?).returns(true)
+ end
- before :each do
- Puppet::SSL::CertificateAuthority.stubs(:ca?).returns(true)
- end
+ it "should set the ca_location to local" do
+ Puppet::SSL::Host.expects(:ca_location=).with(:local)
- it "should set the ca_location to local" do
- Puppet::SSL::Host.expects(:ca_location=).with(:local)
+ @master.setup
+ end
- @master.setup
- end
+ it "should tell Puppet.settings to use :ca category" do
+ Puppet.settings.expects(:use).with(:ca)
- it "should tell Puppet.settings to use :ca category" do
- Puppet.settings.expects(:use).with(:ca)
+ @master.setup
+ end
- @master.setup
- end
+ it "should instantiate the CertificateAuthority singleton" do
+ Puppet::SSL::CertificateAuthority.expects(:instance)
- it "should instantiate the CertificateAuthority singleton" do
- Puppet::SSL::CertificateAuthority.expects(:instance)
+ @master.setup
+ end
- @master.setup
- end
+ end
- end
+ end
+ describe "when running" do
+ before do
+ @master.preinit
end
- describe "when running" do
- before do
- @master.preinit
- end
-
- it "should dispatch to parseonly if parseonly is set" do
- Puppet.stubs(:[]).with(:parseonly).returns(true)
- @master.options[:node] = nil
+ it "should dispatch to parseonly if parseonly is set" do
+ Puppet.stubs(:[]).with(:parseonly).returns(true)
+ @master.options[:node] = nil
- @master.expects(:parseonly)
- @master.run_command
- end
+ @master.expects(:parseonly)
+ @master.run_command
+ end
- it "should dispatch to compile if called with --compile" do
- @master.options[:node] = "foo"
- @master.expects(:compile)
- @master.run_command
- end
+ it "should dispatch to compile if called with --compile" do
+ @master.options[:node] = "foo"
+ @master.expects(:compile)
+ @master.run_command
+ end
- it "should dispatch to main if parseonly is not set" do
- Puppet.stubs(:[]).with(:parseonly).returns(false)
- @master.options[:node] = nil
+ it "should dispatch to main if parseonly is not set" do
+ Puppet.stubs(:[]).with(:parseonly).returns(false)
+ @master.options[:node] = nil
- @master.expects(:main)
- @master.run_command
- end
+ @master.expects(:main)
+ @master.run_command
+ end
- describe "the parseonly command" do
- before :each do
- Puppet.stubs(:[]).with(:environment)
- Puppet.stubs(:[]).with(:manifest).returns("site.pp")
- Puppet.stubs(:err)
- @master.stubs(:exit)
- @collection = stub_everything
- Puppet::Resource::TypeCollection.stubs(:new).returns(@collection)
- end
-
- it "should use a Puppet Resource Type Collection to parse the file" do
- @collection.expects(:perform_initial_import)
- @master.parseonly
- end
-
- it "should exit with exit code 0 if no error" do
- @master.expects(:exit).with(0)
- @master.parseonly
- end
-
- it "should exit with exit code 1 if error" do
- @collection.stubs(:perform_initial_import).raises(Puppet::ParseError)
- @master.expects(:exit).with(1)
- @master.parseonly
- end
- end
+ describe "the parseonly command" do
+ before :each do
+ Puppet.stubs(:[]).with(:environment)
+ Puppet.stubs(:[]).with(:manifest).returns("site.pp")
+ Puppet.stubs(:err)
+ @master.stubs(:exit)
+ @collection = stub_everything
+ Puppet::Resource::TypeCollection.stubs(:new).returns(@collection)
+ end
+
+ it "should use a Puppet Resource Type Collection to parse the file" do
+ @collection.expects(:perform_initial_import)
+ @master.parseonly
+ end
+
+ it "should exit with exit code 0 if no error" do
+ @master.expects(:exit).with(0)
+ @master.parseonly
+ end
+
+ it "should exit with exit code 1 if error" do
+ @collection.stubs(:perform_initial_import).raises(Puppet::ParseError)
+ @master.expects(:exit).with(1)
+ @master.parseonly
+ end
+ end
- describe "the compile command" do
- before do
- Puppet.stubs(:[]).with(:environment)
- Puppet.stubs(:[]).with(:manifest).returns("site.pp")
- Puppet.stubs(:err)
- @master.stubs(:jj)
- @master.stubs(:exit)
- Puppet.features.stubs(:pson?).returns true
- end
-
- it "should fail if pson isn't available" do
- Puppet.features.expects(:pson?).returns false
- lambda { @master.compile }.should raise_error
- end
-
- it "should compile a catalog for the specified node" do
- @master.options[:node] = "foo"
- Puppet::Resource::Catalog.expects(:find).with("foo").returns Puppet::Resource::Catalog.new
- $stdout.stubs(:puts)
-
- @master.compile
- end
-
- it "should convert the catalog to a pure-resource catalog and use 'jj' to pretty-print the catalog" do
- catalog = Puppet::Resource::Catalog.new
- Puppet::Resource::Catalog.expects(:find).returns catalog
-
- catalog.expects(:to_resource).returns("rescat")
-
- @master.options[:node] = "foo"
- @master.expects(:jj).with("rescat")
-
- @master.compile
- end
-
- it "should exit with error code 30 if no catalog can be found" do
- @master.options[:node] = "foo"
- Puppet::Resource::Catalog.expects(:find).returns nil
- @master.expects(:exit).with(30)
- $stderr.expects(:puts)
-
- @master.compile
- end
-
- it "should exit with error code 30 if there's a failure" do
- @master.options[:node] = "foo"
- Puppet::Resource::Catalog.expects(:find).raises ArgumentError
- @master.expects(:exit).with(30)
- $stderr.expects(:puts)
-
- @master.compile
- end
- end
+ describe "the compile command" do
+ before do
+ Puppet.stubs(:[]).with(:environment)
+ Puppet.stubs(:[]).with(:manifest).returns("site.pp")
+ Puppet.stubs(:err)
+ @master.stubs(:jj)
+ @master.stubs(:exit)
+ Puppet.features.stubs(:pson?).returns true
+ end
+
+ it "should fail if pson isn't available" do
+ Puppet.features.expects(:pson?).returns false
+ lambda { @master.compile }.should raise_error
+ end
+
+ it "should compile a catalog for the specified node" do
+ @master.options[:node] = "foo"
+ Puppet::Resource::Catalog.expects(:find).with("foo").returns Puppet::Resource::Catalog.new
+ $stdout.stubs(:puts)
+
+ @master.compile
+ end
+
+ it "should convert the catalog to a pure-resource catalog and use 'jj' to pretty-print the catalog" do
+ catalog = Puppet::Resource::Catalog.new
+ Puppet::Resource::Catalog.expects(:find).returns catalog
+
+ catalog.expects(:to_resource).returns("rescat")
+
+ @master.options[:node] = "foo"
+ @master.expects(:jj).with("rescat")
+
+ @master.compile
+ end
+
+ it "should exit with error code 30 if no catalog can be found" do
+ @master.options[:node] = "foo"
+ Puppet::Resource::Catalog.expects(:find).returns nil
+ @master.expects(:exit).with(30)
+ $stderr.expects(:puts)
+
+ @master.compile
+ end
+
+ it "should exit with error code 30 if there's a failure" do
+ @master.options[:node] = "foo"
+ Puppet::Resource::Catalog.expects(:find).raises ArgumentError
+ @master.expects(:exit).with(30)
+ $stderr.expects(:puts)
+
+ @master.compile
+ end
+ end
- describe "the main command" do
- before :each do
- @master.preinit
- @server = stub_everything 'server'
- Puppet::Network::Server.stubs(:new).returns(@server)
- @app = stub_everything 'app'
- Puppet::SSL::Host.stubs(:localhost)
- Puppet::SSL::CertificateAuthority.stubs(:ca?)
- Process.stubs(:uid).returns(1000)
- Puppet.stubs(:service)
- Puppet.stubs(:[])
- Puppet.stubs(:notice)
- Puppet.stubs(:start)
- end
+ describe "the main command" do
+ before :each do
+ @master.preinit
+ @server = stub_everything 'server'
+ Puppet::Network::Server.stubs(:new).returns(@server)
+ @app = stub_everything 'app'
+ Puppet::SSL::Host.stubs(:localhost)
+ Puppet::SSL::CertificateAuthority.stubs(:ca?)
+ Process.stubs(:uid).returns(1000)
+ Puppet.stubs(:service)
+ Puppet.stubs(:[])
+ Puppet.stubs(:notice)
+ Puppet.stubs(:start)
+ end
- it "should create a Server" do
- Puppet::Network::Server.expects(:new)
+ it "should create a Server" do
+ Puppet::Network::Server.expects(:new)
- @master.main
- end
+ @master.main
+ end
- it "should give the server to the daemon" do
- @daemon.expects(:server=).with(@server)
+ it "should give the server to the daemon" do
+ @daemon.expects(:server=).with(@server)
- @master.main
- end
+ @master.main
+ end
- it "should create the server with the right XMLRPC handlers" do
- Puppet::Network::Server.expects(:new).with { |args| args[:xmlrpc_handlers] == [:Status, :FileServer, :Master, :Report, :Filebucket]}
+ it "should create the server with the right XMLRPC handlers" do
+ Puppet::Network::Server.expects(:new).with { |args| args[:xmlrpc_handlers] == [:Status, :FileServer, :Master, :Report, :Filebucket]}
- @master.main
- end
+ @master.main
+ end
- it "should create the server with a :ca xmlrpc handler if needed" do
- Puppet.stubs(:[]).with(:ca).returns(true)
- Puppet::Network::Server.expects(:new).with { |args| args[:xmlrpc_handlers].include?(:CA) }
+ it "should create the server with a :ca xmlrpc handler if needed" do
+ Puppet.stubs(:[]).with(:ca).returns(true)
+ Puppet::Network::Server.expects(:new).with { |args| args[:xmlrpc_handlers].include?(:CA) }
- @master.main
- end
+ @master.main
+ end
- it "should generate a SSL cert for localhost" do
- Puppet::SSL::Host.expects(:localhost)
+ it "should generate a SSL cert for localhost" do
+ Puppet::SSL::Host.expects(:localhost)
- @master.main
- end
+ @master.main
+ end
- it "should make sure to *only* hit the CA for data" do
- Puppet::SSL::CertificateAuthority.stubs(:ca?).returns(true)
+ it "should make sure to *only* hit the CA for data" do
+ Puppet::SSL::CertificateAuthority.stubs(:ca?).returns(true)
- Puppet::SSL::Host.expects(:ca_location=).with(:only)
+ Puppet::SSL::Host.expects(:ca_location=).with(:only)
- @master.main
- end
+ @master.main
+ end
- it "should drop privileges if running as root" do
- Puppet.features.stubs(:root?).returns true
+ it "should drop privileges if running as root" do
+ Puppet.features.stubs(:root?).returns true
- Puppet::Util.expects(:chuser)
+ Puppet::Util.expects(:chuser)
- @master.main
- end
+ @master.main
+ end
- it "should daemonize if needed" do
- Puppet.stubs(:[]).with(:daemonize).returns(true)
+ it "should daemonize if needed" do
+ Puppet.stubs(:[]).with(:daemonize).returns(true)
- @daemon.expects(:daemonize)
+ @daemon.expects(:daemonize)
- @master.main
- end
+ @master.main
+ end
- it "should start the service" do
- @daemon.expects(:start)
+ it "should start the service" do
+ @daemon.expects(:start)
- @master.main
- end
+ @master.main
+ end
- describe "with --rack" do
- confine "Rack is not available" => Puppet.features.rack?
+ describe "with --rack" do
+ confine "Rack is not available" => Puppet.features.rack?
- before do
- require 'puppet/network/http/rack'
- Puppet::Network::HTTP::Rack.stubs(:new).returns(@app)
- end
+ before do
+ require 'puppet/network/http/rack'
+ Puppet::Network::HTTP::Rack.stubs(:new).returns(@app)
+ end
- it "it should create the app with REST and XMLRPC support" do
- @master.options.stubs(:[]).with(:rack).returns(:true)
+ it "it should create the app with REST and XMLRPC support" do
+ @master.options.stubs(:[]).with(:rack).returns(:true)
- Puppet::Network::HTTP::Rack.expects(:new).with { |args|
- args[:xmlrpc_handlers] == [:Status, :FileServer, :Master, :Report, :Filebucket] and
- args[:protocols] == [:rest, :xmlrpc]
- }
+ Puppet::Network::HTTP::Rack.expects(:new).with { |args|
+ args[:xmlrpc_handlers] == [:Status, :FileServer, :Master, :Report, :Filebucket] and
+ args[:protocols] == [:rest, :xmlrpc]
+ }
- @master.main
- end
+ @master.main
+ end
- it "it should not start a daemon" do
- @master.options.stubs(:[]).with(:rack).returns(:true)
+ it "it should not start a daemon" do
+ @master.options.stubs(:[]).with(:rack).returns(:true)
- @daemon.expects(:start).never
+ @daemon.expects(:start).never
- @master.main
- end
+ @master.main
+ end
- it "it should return the app" do
- @master.options.stubs(:[]).with(:rack).returns(:true)
+ it "it should return the app" do
+ @master.options.stubs(:[]).with(:rack).returns(:true)
- app = @master.main
- app.should equal(@app)
- end
+ app = @master.main
+ app.should equal(@app)
+ end
- end
+ end
- end
end
+ end
end
diff --git a/spec/unit/application/queue_spec.rb b/spec/unit/application/queue_spec.rb
index 9f5b6c2..87c96df 100755
--- a/spec/unit/application/queue_spec.rb
+++ b/spec/unit/application/queue_spec.rb
@@ -5,182 +5,182 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/application/queue'
describe Puppet::Application::Queue do
- before :each do
- @queue = Puppet::Application[:queue]
- @queue.stubs(:puts)
- @daemon = stub_everything 'daemon', :daemonize => nil
- Puppet::Util::Log.stubs(:newdestination)
- Puppet::Util::Log.stubs(:level=)
+ before :each do
+ @queue = Puppet::Application[:queue]
+ @queue.stubs(:puts)
+ @daemon = stub_everything 'daemon', :daemonize => nil
+ Puppet::Util::Log.stubs(:newdestination)
+ Puppet::Util::Log.stubs(:level=)
- Puppet::Resource::Catalog.stubs(:terminus_class=)
- end
+ Puppet::Resource::Catalog.stubs(:terminus_class=)
+ end
- it "should ask Puppet::Application to parse Puppet configuration file" do
- @queue.should_parse_config?.should be_true
- end
+ it "should ask Puppet::Application to parse Puppet configuration file" do
+ @queue.should_parse_config?.should be_true
+ end
- it "should declare a main command" do
- @queue.should respond_to(:main)
- end
+ it "should declare a main command" do
+ @queue.should respond_to(:main)
+ end
- it "should declare a preinit block" do
- @queue.should respond_to(:preinit)
- end
+ it "should declare a preinit block" do
+ @queue.should respond_to(:preinit)
+ end
- describe "in preinit" do
- before :each do
- @queue.stubs(:trap)
- end
+ describe "in preinit" do
+ before :each do
+ @queue.stubs(:trap)
+ end
- it "should catch INT" do
- @queue.expects(:trap).with { |arg,block| arg == :INT }
+ it "should catch INT" do
+ @queue.expects(:trap).with { |arg,block| arg == :INT }
- @queue.preinit
- end
+ @queue.preinit
+ end
- it "should init :verbose to false" do
- @queue.preinit
+ it "should init :verbose to false" do
+ @queue.preinit
- @queue.options[:verbose].should be_false
- end
+ @queue.options[:verbose].should be_false
+ end
- it "should init :debug to false" do
- @queue.preinit
+ it "should init :debug to false" do
+ @queue.preinit
- @queue.options[:debug].should be_false
- end
+ @queue.options[:debug].should be_false
+ end
- it "should create a Daemon instance and copy ARGV to it" do
- ARGV.expects(:dup).returns "eh"
- daemon = mock("daemon")
- daemon.expects(:argv=).with("eh")
- Puppet::Daemon.expects(:new).returns daemon
- @queue.preinit
- end
+ it "should create a Daemon instance and copy ARGV to it" do
+ ARGV.expects(:dup).returns "eh"
+ daemon = mock("daemon")
+ daemon.expects(:argv=).with("eh")
+ Puppet::Daemon.expects(:new).returns daemon
+ @queue.preinit
end
+ end
- describe "when handling options" do
+ describe "when handling options" do
- [:debug, :verbose].each do |option|
- it "should declare handle_#{option} method" do
- @queue.should respond_to("handle_#{option}".to_sym)
- end
+ [:debug, :verbose].each do |option|
+ it "should declare handle_#{option} method" do
+ @queue.should respond_to("handle_#{option}".to_sym)
+ end
- it "should store argument value when calling handle_#{option}" do
- @queue.options.expects(:[]=).with(option, 'arg')
- @queue.send("handle_#{option}".to_sym, 'arg')
- end
- end
+ it "should store argument value when calling handle_#{option}" do
+ @queue.options.expects(:[]=).with(option, 'arg')
+ @queue.send("handle_#{option}".to_sym, 'arg')
+ end
end
+ end
- describe "during setup" do
- before :each do
- @queue.options.stubs(:[])
- @queue.daemon.stubs(:daemonize)
- Puppet.stubs(:info)
- Puppet.features.stubs(:stomp?).returns true
- Puppet::Resource::Catalog.stubs(:terminus_class=)
- Puppet.stubs(:settraps)
- Puppet.settings.stubs(:print_config?)
- Puppet.settings.stubs(:print_config)
- end
+ describe "during setup" do
+ before :each do
+ @queue.options.stubs(:[])
+ @queue.daemon.stubs(:daemonize)
+ Puppet.stubs(:info)
+ Puppet.features.stubs(:stomp?).returns true
+ Puppet::Resource::Catalog.stubs(:terminus_class=)
+ Puppet.stubs(:settraps)
+ Puppet.settings.stubs(:print_config?)
+ Puppet.settings.stubs(:print_config)
+ end
- it "should fail if the stomp feature is missing" do
- Puppet.features.expects(:stomp?).returns false
- lambda { @queue.setup }.should raise_error(ArgumentError)
- end
+ it "should fail if the stomp feature is missing" do
+ Puppet.features.expects(:stomp?).returns false
+ lambda { @queue.setup }.should raise_error(ArgumentError)
+ end
- it "should print puppet config if asked to in Puppet config" do
- @queue.stubs(:exit)
- Puppet.settings.stubs(:print_configs?).returns(true)
+ it "should print puppet config if asked to in Puppet config" do
+ @queue.stubs(:exit)
+ Puppet.settings.stubs(:print_configs?).returns(true)
- Puppet.settings.expects(:print_configs)
+ Puppet.settings.expects(:print_configs)
- @queue.setup
- end
+ @queue.setup
+ end
- it "should exit after printing puppet config if asked to in Puppet config" do
- Puppet.settings.stubs(:print_configs?).returns(true)
+ it "should exit after printing puppet config if asked to in Puppet config" do
+ Puppet.settings.stubs(:print_configs?).returns(true)
- lambda { @queue.setup }.should raise_error(SystemExit)
- end
+ lambda { @queue.setup }.should raise_error(SystemExit)
+ end
- it "should call setup_logs" do
- @queue.expects(:setup_logs)
- @queue.setup
- end
+ it "should call setup_logs" do
+ @queue.expects(:setup_logs)
+ @queue.setup
+ end
- describe "when setting up logs" do
- before :each do
- Puppet::Util::Log.stubs(:newdestination)
- end
+ describe "when setting up logs" do
+ before :each do
+ Puppet::Util::Log.stubs(:newdestination)
+ end
- it "should set log level to debug if --debug was passed" do
- @queue.options.stubs(:[]).with(:debug).returns(true)
+ it "should set log level to debug if --debug was passed" do
+ @queue.options.stubs(:[]).with(:debug).returns(true)
- Puppet::Util::Log.expects(:level=).with(:debug)
+ Puppet::Util::Log.expects(:level=).with(:debug)
- @queue.setup_logs
- end
+ @queue.setup_logs
+ end
- it "should set log level to info if --verbose was passed" do
- @queue.options.stubs(:[]).with(:verbose).returns(true)
+ it "should set log level to info if --verbose was passed" do
+ @queue.options.stubs(:[]).with(:verbose).returns(true)
- Puppet::Util::Log.expects(:level=).with(:info)
+ Puppet::Util::Log.expects(:level=).with(:info)
- @queue.setup_logs
- end
+ @queue.setup_logs
+ end
- [:verbose, :debug].each do |level|
- it "should set console as the log destination with level #{level}" do
- @queue.options.stubs(:[]).with(level).returns(true)
+ [:verbose, :debug].each do |level|
+ it "should set console as the log destination with level #{level}" do
+ @queue.options.stubs(:[]).with(level).returns(true)
- Puppet::Util::Log.expects(:newdestination).with(:console)
+ Puppet::Util::Log.expects(:newdestination).with(:console)
- @queue.setup_logs
- end
- end
+ @queue.setup_logs
end
+ end
+ end
- it "should configure the Catalog class to use ActiveRecord" do
- Puppet::Resource::Catalog.expects(:terminus_class=).with(:active_record)
+ it "should configure the Catalog class to use ActiveRecord" do
+ Puppet::Resource::Catalog.expects(:terminus_class=).with(:active_record)
- @queue.setup
- end
+ @queue.setup
+ end
- it "should daemonize if needed" do
- Puppet.expects(:[]).with(:daemonize).returns(true)
+ it "should daemonize if needed" do
+ Puppet.expects(:[]).with(:daemonize).returns(true)
- @queue.daemon.expects(:daemonize)
+ @queue.daemon.expects(:daemonize)
- @queue.setup
- end
+ @queue.setup
end
+ end
- describe "when running" do
- before :each do
- @queue.stubs(:sleep_forever)
- Puppet::Resource::Catalog::Queue.stubs(:subscribe)
- Thread.list.each { |t| t.stubs(:join) }
- end
+ describe "when running" do
+ before :each do
+ @queue.stubs(:sleep_forever)
+ Puppet::Resource::Catalog::Queue.stubs(:subscribe)
+ Thread.list.each { |t| t.stubs(:join) }
+ end
- it "should subscribe to the queue" do
- Puppet::Resource::Catalog::Queue.expects(:subscribe)
- @queue.main
- end
+ it "should subscribe to the queue" do
+ Puppet::Resource::Catalog::Queue.expects(:subscribe)
+ @queue.main
+ end
- it "should log and save each catalog passed by the queue" do
- catalog = mock 'catalog', :name => 'eh'
- catalog.expects(:save)
+ it "should log and save each catalog passed by the queue" do
+ catalog = mock 'catalog', :name => 'eh'
+ catalog.expects(:save)
- Puppet::Resource::Catalog::Queue.expects(:subscribe).yields(catalog)
- Puppet.expects(:notice).times(2)
- @queue.main
- end
+ Puppet::Resource::Catalog::Queue.expects(:subscribe).yields(catalog)
+ Puppet.expects(:notice).times(2)
+ @queue.main
+ end
- it "should join all of the running threads" do
- Thread.list.each { |t| t.expects(:join) }
- @queue.main
- end
+ it "should join all of the running threads" do
+ Thread.list.each { |t| t.expects(:join) }
+ @queue.main
end
+ end
end
diff --git a/spec/unit/application/resource_spec.rb b/spec/unit/application/resource_spec.rb
index 71e35dc..b6c52b1 100755
--- a/spec/unit/application/resource_spec.rb
+++ b/spec/unit/application/resource_spec.rb
@@ -5,229 +5,229 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/application/resource'
describe Puppet::Application::Resource do
- before :each do
- @resource = Puppet::Application[:resource]
- Puppet::Util::Log.stubs(:newdestination)
- Puppet::Util::Log.stubs(:level=)
- Puppet::Resource.indirection.stubs(:terminus_class=)
+ before :each do
+ @resource = Puppet::Application[:resource]
+ Puppet::Util::Log.stubs(:newdestination)
+ Puppet::Util::Log.stubs(:level=)
+ Puppet::Resource.indirection.stubs(:terminus_class=)
+ end
+
+ it "should ask Puppet::Application to not parse Puppet configuration file" do
+ @resource.should_parse_config?.should be_false
+ end
+
+ it "should declare a main command" do
+ @resource.should respond_to(:main)
+ end
+
+ it "should declare a host option" do
+ @resource.should respond_to(:handle_host)
+ end
+
+ it "should declare a types option" do
+ @resource.should respond_to(:handle_types)
+ end
+
+ it "should declare a param option" do
+ @resource.should respond_to(:handle_param)
+ end
+
+ it "should declare a preinit block" do
+ @resource.should respond_to(:preinit)
+ end
+
+ describe "in preinit" do
+ it "should set hosts to nil" do
+ @resource.preinit
+
+ @resource.host.should be_nil
end
- it "should ask Puppet::Application to not parse Puppet configuration file" do
- @resource.should_parse_config?.should be_false
- end
+ it "should init extra_params to empty array" do
+ @resource.preinit
- it "should declare a main command" do
- @resource.should respond_to(:main)
+ @resource.extra_params.should == []
end
- it "should declare a host option" do
- @resource.should respond_to(:handle_host)
+ it "should load Facter facts" do
+ Facter.expects(:loadfacts).once
+ @resource.preinit
end
+ end
- it "should declare a types option" do
- @resource.should respond_to(:handle_types)
- end
+ describe "when handling options" do
- it "should declare a param option" do
- @resource.should respond_to(:handle_param)
- end
+ [:debug, :verbose, :edit].each do |option|
+ it "should declare handle_#{option} method" do
+ @resource.should respond_to("handle_#{option}".to_sym)
+ end
- it "should declare a preinit block" do
- @resource.should respond_to(:preinit)
+ it "should store argument value when calling handle_#{option}" do
+ @resource.options.expects(:[]=).with(option, 'arg')
+ @resource.send("handle_#{option}".to_sym, 'arg')
+ end
end
- describe "in preinit" do
- it "should set hosts to nil" do
- @resource.preinit
+ it "should set options[:host] to given host" do
+ @resource.handle_host(:whatever)
- @resource.host.should be_nil
- end
-
- it "should init extra_params to empty array" do
- @resource.preinit
-
- @resource.extra_params.should == []
- end
-
- it "should load Facter facts" do
- Facter.expects(:loadfacts).once
- @resource.preinit
- end
+ @resource.host.should == :whatever
end
- describe "when handling options" do
-
- [:debug, :verbose, :edit].each do |option|
- it "should declare handle_#{option} method" do
- @resource.should respond_to("handle_#{option}".to_sym)
- end
+ it "should load an display all types with types option" do
+ type1 = stub_everything 'type1', :name => :type1
+ type2 = stub_everything 'type2', :name => :type2
+ Puppet::Type.stubs(:loadall)
+ Puppet::Type.stubs(:eachtype).multiple_yields(type1,type2)
+ @resource.stubs(:exit)
- it "should store argument value when calling handle_#{option}" do
- @resource.options.expects(:[]=).with(option, 'arg')
- @resource.send("handle_#{option}".to_sym, 'arg')
- end
- end
-
- it "should set options[:host] to given host" do
- @resource.handle_host(:whatever)
-
- @resource.host.should == :whatever
- end
-
- it "should load an display all types with types option" do
- type1 = stub_everything 'type1', :name => :type1
- type2 = stub_everything 'type2', :name => :type2
- Puppet::Type.stubs(:loadall)
- Puppet::Type.stubs(:eachtype).multiple_yields(type1,type2)
- @resource.stubs(:exit)
-
- @resource.expects(:puts).with(['type1','type2'])
- @resource.handle_types(nil)
- end
-
- it "should add param to extra_params list" do
- @resource.extra_params = [ :param1 ]
- @resource.handle_param("whatever")
-
- @resource.extra_params.should == [ :param1, :whatever ]
- end
+ @resource.expects(:puts).with(['type1','type2'])
+ @resource.handle_types(nil)
end
- describe "during setup" do
- before :each do
- Puppet::Log.stubs(:newdestination)
- Puppet::Log.stubs(:level=)
- Puppet.stubs(:parse_config)
- end
-
+ it "should add param to extra_params list" do
+ @resource.extra_params = [ :param1 ]
+ @resource.handle_param("whatever")
- it "should set console as the log destination" do
- Puppet::Log.expects(:newdestination).with(:console)
-
- @resource.setup
- end
-
- it "should set log level to debug if --debug was passed" do
- @resource.options.stubs(:[]).with(:debug).returns(true)
+ @resource.extra_params.should == [ :param1, :whatever ]
+ end
+ end
- Puppet::Log.expects(:level=).with(:debug)
+ describe "during setup" do
+ before :each do
+ Puppet::Log.stubs(:newdestination)
+ Puppet::Log.stubs(:level=)
+ Puppet.stubs(:parse_config)
+ end
- @resource.setup
- end
- it "should set log level to info if --verbose was passed" do
- @resource.options.stubs(:[]).with(:debug).returns(false)
- @resource.options.stubs(:[]).with(:verbose).returns(true)
+ it "should set console as the log destination" do
+ Puppet::Log.expects(:newdestination).with(:console)
- Puppet::Log.expects(:level=).with(:info)
+ @resource.setup
+ end
- @resource.setup
- end
+ it "should set log level to debug if --debug was passed" do
+ @resource.options.stubs(:[]).with(:debug).returns(true)
- it "should Parse puppet config" do
- Puppet.expects(:parse_config)
+ Puppet::Log.expects(:level=).with(:debug)
- @resource.setup
- end
+ @resource.setup
end
- describe "when running" do
+ it "should set log level to info if --verbose was passed" do
+ @resource.options.stubs(:[]).with(:debug).returns(false)
+ @resource.options.stubs(:[]).with(:verbose).returns(true)
- before :each do
- @type = stub_everything 'type', :properties => []
- @resource.command_line.stubs(:args).returns(['type'])
- Puppet::Type.stubs(:type).returns(@type)
- end
+ Puppet::Log.expects(:level=).with(:info)
- it "should raise an error if no type is given" do
- @resource.command_line.stubs(:args).returns([])
- lambda { @resource.main }.should raise_error
- end
-
- it "should raise an error when editing a remote host" do
- @resource.options.stubs(:[]).with(:edit).returns(true)
- @resource.host = 'host'
+ @resource.setup
+ end
- lambda { @resource.main }.should raise_error
- end
+ it "should Parse puppet config" do
+ Puppet.expects(:parse_config)
- it "should raise an error if the type is not found" do
- Puppet::Type.stubs(:type).returns(nil)
+ @resource.setup
+ end
+ end
- lambda { @resource.main }.should raise_error
- end
+ describe "when running" do
- describe "with a host" do
- before :each do
- @resource.stubs(:puts)
- @resource.host = 'host'
+ before :each do
+ @type = stub_everything 'type', :properties => []
+ @resource.command_line.stubs(:args).returns(['type'])
+ Puppet::Type.stubs(:type).returns(@type)
+ end
- Puppet::Resource.stubs(:find ).never
- Puppet::Resource.stubs(:search).never
- Puppet::Resource.stubs(:save ).never
- end
+ it "should raise an error if no type is given" do
+ @resource.command_line.stubs(:args).returns([])
+ lambda { @resource.main }.should raise_error
+ end
- it "should search for resources" do
- @resource.command_line.stubs(:args).returns(['type'])
- Puppet::Resource.expects(:search).with('https://host:8139/production/resources/type/', {}).returns([])
- @resource.main
- end
+ it "should raise an error when editing a remote host" do
+ @resource.options.stubs(:[]).with(:edit).returns(true)
+ @resource.host = 'host'
- it "should describe the given resource" do
- @resource.command_line.stubs(:args).returns(['type', 'name'])
- x = stub_everything 'resource'
- Puppet::Resource.expects(:find).with('https://host:8139/production/resources/type/name').returns(x)
- @resource.main
- end
+ lambda { @resource.main }.should raise_error
+ end
- it "should add given parameters to the object" do
- @resource.command_line.stubs(:args).returns(['type','name','param=temp'])
+ it "should raise an error if the type is not found" do
+ Puppet::Type.stubs(:type).returns(nil)
- res = stub "resource"
- res.expects(:save).with('https://host:8139/production/resources/type/name').returns(res)
- res.expects(:collect)
- res.expects(:to_manifest)
- Puppet::Resource.expects(:new).with('type', 'name', :parameters => {'param' => 'temp'}).returns(res)
+ lambda { @resource.main }.should raise_error
+ end
- @resource.main
- end
+ describe "with a host" do
+ before :each do
+ @resource.stubs(:puts)
+ @resource.host = 'host'
+
+ Puppet::Resource.stubs(:find ).never
+ Puppet::Resource.stubs(:search).never
+ Puppet::Resource.stubs(:save ).never
+ end
+
+ it "should search for resources" do
+ @resource.command_line.stubs(:args).returns(['type'])
+ Puppet::Resource.expects(:search).with('https://host:8139/production/resources/type/', {}).returns([])
+ @resource.main
+ end
+
+ it "should describe the given resource" do
+ @resource.command_line.stubs(:args).returns(['type', 'name'])
+ x = stub_everything 'resource'
+ Puppet::Resource.expects(:find).with('https://host:8139/production/resources/type/name').returns(x)
+ @resource.main
+ end
+
+ it "should add given parameters to the object" do
+ @resource.command_line.stubs(:args).returns(['type','name','param=temp'])
+
+ res = stub "resource"
+ res.expects(:save).with('https://host:8139/production/resources/type/name').returns(res)
+ res.expects(:collect)
+ res.expects(:to_manifest)
+ Puppet::Resource.expects(:new).with('type', 'name', :parameters => {'param' => 'temp'}).returns(res)
+
+ @resource.main
+ end
- end
+ end
- describe "without a host" do
- before :each do
- @resource.stubs(:puts)
- @resource.host = nil
+ describe "without a host" do
+ before :each do
+ @resource.stubs(:puts)
+ @resource.host = nil
- Puppet::Resource.stubs(:find ).never
- Puppet::Resource.stubs(:search).never
- Puppet::Resource.stubs(:save ).never
- end
+ Puppet::Resource.stubs(:find ).never
+ Puppet::Resource.stubs(:search).never
+ Puppet::Resource.stubs(:save ).never
+ end
- it "should search for resources" do
- Puppet::Resource.expects(:search).with('type/', {}).returns([])
- @resource.main
- end
+ it "should search for resources" do
+ Puppet::Resource.expects(:search).with('type/', {}).returns([])
+ @resource.main
+ end
- it "should describe the given resource" do
- @resource.command_line.stubs(:args).returns(['type','name'])
- x = stub_everything 'resource'
- Puppet::Resource.expects(:find).with('type/name').returns(x)
- @resource.main
- end
+ it "should describe the given resource" do
+ @resource.command_line.stubs(:args).returns(['type','name'])
+ x = stub_everything 'resource'
+ Puppet::Resource.expects(:find).with('type/name').returns(x)
+ @resource.main
+ end
- it "should add given parameters to the object" do
- @resource.command_line.stubs(:args).returns(['type','name','param=temp'])
+ it "should add given parameters to the object" do
+ @resource.command_line.stubs(:args).returns(['type','name','param=temp'])
- res = stub "resource"
- res.expects(:save).with('type/name').returns(res)
- res.expects(:collect)
- res.expects(:to_manifest)
- Puppet::Resource.expects(:new).with('type', 'name', :parameters => {'param' => 'temp'}).returns(res)
+ res = stub "resource"
+ res.expects(:save).with('type/name').returns(res)
+ res.expects(:collect)
+ res.expects(:to_manifest)
+ Puppet::Resource.expects(:new).with('type', 'name', :parameters => {'param' => 'temp'}).returns(res)
- @resource.main
- end
+ @resource.main
+ end
- end
end
+ end
end
diff --git a/spec/unit/application_spec.rb b/spec/unit/application_spec.rb
index 87424fb..3c354cc 100755
--- a/spec/unit/application_spec.rb
+++ b/spec/unit/application_spec.rb
@@ -8,524 +8,524 @@ require 'getoptlong'
describe Puppet::Application do
- before do
- @app = Class.new(Puppet::Application).new
- @appclass = @app.class
+ before do
+ @app = Class.new(Puppet::Application).new
+ @appclass = @app.class
- # avoid actually trying to parse any settings
- Puppet.settings.stubs(:parse)
+ # avoid actually trying to parse any settings
+ Puppet.settings.stubs(:parse)
+ end
+
+ describe ".run_mode" do
+ it "should default to user" do
+ @appclass.run_mode.name.should == :user
end
- describe ".run_mode" do
- it "should default to user" do
- @appclass.run_mode.name.should == :user
- end
+ it "should set and get a value" do
+ @appclass.run_mode :agent
+ @appclass.run_mode.name.should == :agent
+ end
+ end
- it "should set and get a value" do
- @appclass.run_mode :agent
- @appclass.run_mode.name.should == :agent
- end
+ it "should have a run entry-point" do
+ @app.should respond_to(:run)
+ end
+
+ it "should have a read accessor to options" do
+ @app.should respond_to(:options)
+ end
+
+ it "should include a default setup method" do
+ @app.should respond_to(:setup)
+ end
+
+ it "should include a default preinit method" do
+ @app.should respond_to(:preinit)
+ end
+
+ it "should include a default run_command method" do
+ @app.should respond_to(:run_command)
+ end
+
+ it "should invoke main as the default" do
+ @app.expects( :main )
+ @app.run_command
+ end
+
+ describe 'when invoking clear!' do
+ before :each do
+ Puppet::Application.run_status = :stop_requested
+ Puppet::Application.clear!
end
- it "should have a run entry-point" do
- @app.should respond_to(:run)
+ it 'should have nil run_status' do
+ Puppet::Application.run_status.should be_nil
end
- it "should have a read accessor to options" do
- @app.should respond_to(:options)
+ it 'should return false for restart_requested?' do
+ Puppet::Application.restart_requested?.should be_false
end
- it "should include a default setup method" do
- @app.should respond_to(:setup)
+ it 'should return false for stop_requested?' do
+ Puppet::Application.stop_requested?.should be_false
end
- it "should include a default preinit method" do
- @app.should respond_to(:preinit)
+ it 'should return false for interrupted?' do
+ Puppet::Application.interrupted?.should be_false
end
- it "should include a default run_command method" do
- @app.should respond_to(:run_command)
+ it 'should return true for clear?' do
+ Puppet::Application.clear?.should be_true
end
+ end
- it "should invoke main as the default" do
- @app.expects( :main )
- @app.run_command
+ describe 'after invoking stop!' do
+ before :each do
+ Puppet::Application.run_status = nil
+ Puppet::Application.stop!
end
- describe 'when invoking clear!' do
- before :each do
- Puppet::Application.run_status = :stop_requested
- Puppet::Application.clear!
- end
+ after :each do
+ Puppet::Application.run_status = nil
+ end
- it 'should have nil run_status' do
- Puppet::Application.run_status.should be_nil
- end
+ it 'should have run_status of :stop_requested' do
+ Puppet::Application.run_status.should == :stop_requested
+ end
- it 'should return false for restart_requested?' do
- Puppet::Application.restart_requested?.should be_false
- end
+ it 'should return true for stop_requested?' do
+ Puppet::Application.stop_requested?.should be_true
+ end
- it 'should return false for stop_requested?' do
- Puppet::Application.stop_requested?.should be_false
- end
+ it 'should return false for restart_requested?' do
+ Puppet::Application.restart_requested?.should be_false
+ end
- it 'should return false for interrupted?' do
- Puppet::Application.interrupted?.should be_false
- end
+ it 'should return true for interrupted?' do
+ Puppet::Application.interrupted?.should be_true
+ end
- it 'should return true for clear?' do
- Puppet::Application.clear?.should be_true
- end
+ it 'should return false for clear?' do
+ Puppet::Application.clear?.should be_false
end
+ end
- describe 'after invoking stop!' do
- before :each do
- Puppet::Application.run_status = nil
- Puppet::Application.stop!
- end
+ describe 'when invoking restart!' do
+ before :each do
+ Puppet::Application.run_status = nil
+ Puppet::Application.restart!
+ end
- after :each do
- Puppet::Application.run_status = nil
- end
+ after :each do
+ Puppet::Application.run_status = nil
+ end
- it 'should have run_status of :stop_requested' do
- Puppet::Application.run_status.should == :stop_requested
- end
+ it 'should have run_status of :restart_requested' do
+ Puppet::Application.run_status.should == :restart_requested
+ end
- it 'should return true for stop_requested?' do
- Puppet::Application.stop_requested?.should be_true
- end
+ it 'should return true for restart_requested?' do
+ Puppet::Application.restart_requested?.should be_true
+ end
- it 'should return false for restart_requested?' do
- Puppet::Application.restart_requested?.should be_false
- end
+ it 'should return false for stop_requested?' do
+ Puppet::Application.stop_requested?.should be_false
+ end
- it 'should return true for interrupted?' do
- Puppet::Application.interrupted?.should be_true
- end
+ it 'should return true for interrupted?' do
+ Puppet::Application.interrupted?.should be_true
+ end
- it 'should return false for clear?' do
- Puppet::Application.clear?.should be_false
- end
+ it 'should return false for clear?' do
+ Puppet::Application.clear?.should be_false
+ end
+ end
+
+ describe 'when performing a controlled_run' do
+ it 'should not execute block if not :clear?' do
+ Puppet::Application.run_status = :stop_requested
+ target = mock 'target'
+ target.expects(:some_method).never
+ Puppet::Application.controlled_run do
+ target.some_method
+ end
end
- describe 'when invoking restart!' do
- before :each do
- Puppet::Application.run_status = nil
- Puppet::Application.restart!
- end
+ it 'should execute block if :clear?' do
+ Puppet::Application.run_status = nil
+ target = mock 'target'
+ target.expects(:some_method).once
+ Puppet::Application.controlled_run do
+ target.some_method
+ end
+ end
- after :each do
- Puppet::Application.run_status = nil
- end
+ describe 'on POSIX systems' do
+ confine "HUP works only on POSIX systems" => Puppet.features.posix?
+
+ it 'should signal process with HUP after block if restart requested during block execution' do
+ Puppet::Application.run_status = nil
+ target = mock 'target'
+ target.expects(:some_method).once
+ old_handler = trap('HUP') { target.some_method }
+ begin
+ Puppet::Application.controlled_run do
+ Puppet::Application.run_status = :restart_requested
+ end
+ ensure
+ trap('HUP', old_handler)
+ end
+ end
+ end
- it 'should have run_status of :restart_requested' do
- Puppet::Application.run_status.should == :restart_requested
- end
+ after :each do
+ Puppet::Application.run_status = nil
+ end
+ end
- it 'should return true for restart_requested?' do
- Puppet::Application.restart_requested?.should be_true
- end
+ describe "when parsing command-line options" do
- it 'should return false for stop_requested?' do
- Puppet::Application.stop_requested?.should be_false
- end
+ before :each do
+ @app.command_line.stubs(:args).returns([])
- it 'should return true for interrupted?' do
- Puppet::Application.interrupted?.should be_true
- end
+ Puppet.settings.stubs(:optparse_addargs).returns([])
+ end
- it 'should return false for clear?' do
- Puppet::Application.clear?.should be_false
- end
+ it "should create a new option parser when needed" do
+ option_parser = stub "option parser"
+ option_parser.stubs(:on)
+ option_parser.stubs(:default_argv=)
+ OptionParser.expects(:new).returns(option_parser).once
+ @app.option_parser.should == option_parser
+ @app.option_parser.should == option_parser
end
- describe 'when performing a controlled_run' do
- it 'should not execute block if not :clear?' do
- Puppet::Application.run_status = :stop_requested
- target = mock 'target'
- target.expects(:some_method).never
- Puppet::Application.controlled_run do
- target.some_method
- end
- end
+ it "should pass the banner to the option parser" do
+ option_parser = stub "option parser"
+ option_parser.stubs(:on)
+ option_parser.stubs(:default_argv=)
+ @app.class.instance_eval do
+ banner "banner"
+ end
- it 'should execute block if :clear?' do
- Puppet::Application.run_status = nil
- target = mock 'target'
- target.expects(:some_method).once
- Puppet::Application.controlled_run do
- target.some_method
- end
- end
+ OptionParser.expects(:new).with("banner").returns(option_parser)
- describe 'on POSIX systems' do
- confine "HUP works only on POSIX systems" => Puppet.features.posix?
-
- it 'should signal process with HUP after block if restart requested during block execution' do
- Puppet::Application.run_status = nil
- target = mock 'target'
- target.expects(:some_method).once
- old_handler = trap('HUP') { target.some_method }
- begin
- Puppet::Application.controlled_run do
- Puppet::Application.run_status = :restart_requested
- end
- ensure
- trap('HUP', old_handler)
- end
- end
- end
+ @app.option_parser
+ end
- after :each do
- Puppet::Application.run_status = nil
- end
+ it "should set the optionparser's args to the command line args" do
+ option_parser = stub "option parser"
+ option_parser.stubs(:on)
+ option_parser.expects(:default_argv=).with(%w{ fake args })
+ @app.command_line.stubs(:args).returns(%w{ fake args })
+ OptionParser.expects(:new).returns(option_parser)
+ @app.option_parser
end
- describe "when parsing command-line options" do
+ it "should get options from Puppet.settings.optparse_addargs" do
+ Puppet.settings.expects(:optparse_addargs).returns([])
- before :each do
- @app.command_line.stubs(:args).returns([])
+ @app.parse_options
+ end
- Puppet.settings.stubs(:optparse_addargs).returns([])
- end
+ it "should add Puppet.settings options to OptionParser" do
+ Puppet.settings.stubs(:optparse_addargs).returns( [["--option","-o", "Funny Option"]])
- it "should create a new option parser when needed" do
- option_parser = stub "option parser"
- option_parser.stubs(:on)
- option_parser.stubs(:default_argv=)
- OptionParser.expects(:new).returns(option_parser).once
- @app.option_parser.should == option_parser
- @app.option_parser.should == option_parser
- end
+ @app.option_parser.expects(:on).with { |*arg| arg == ["--option","-o", "Funny Option"] }
- it "should pass the banner to the option parser" do
- option_parser = stub "option parser"
- option_parser.stubs(:on)
- option_parser.stubs(:default_argv=)
- @app.class.instance_eval do
- banner "banner"
- end
+ @app.parse_options
+ end
- OptionParser.expects(:new).with("banner").returns(option_parser)
+ it "should ask OptionParser to parse the command-line argument" do
+ @app.option_parser.expects(:parse!)
- @app.option_parser
- end
+ @app.parse_options
+ end
- it "should set the optionparser's args to the command line args" do
- option_parser = stub "option parser"
- option_parser.stubs(:on)
- option_parser.expects(:default_argv=).with(%w{ fake args })
- @app.command_line.stubs(:args).returns(%w{ fake args })
- OptionParser.expects(:new).returns(option_parser)
- @app.option_parser
- end
+ describe "when using --help" do
+ confine "rdoc" => Puppet.features.usage?
- it "should get options from Puppet.settings.optparse_addargs" do
- Puppet.settings.expects(:optparse_addargs).returns([])
+ it "should call RDoc::usage and exit" do
+ @app.expects(:exit)
+ RDoc.expects(:usage).returns(true)
- @app.parse_options
- end
+ @app.handle_help(nil)
+ end
- it "should add Puppet.settings options to OptionParser" do
- Puppet.settings.stubs(:optparse_addargs).returns( [["--option","-o", "Funny Option"]])
+ end
- @app.option_parser.expects(:on).with { |*arg| arg == ["--option","-o", "Funny Option"] }
+ describe "when using --version" do
+ it "should declare a version option" do
+ @app.should respond_to(:handle_version)
+ end
- @app.parse_options
- end
+ it "should exit after printing the version" do
+ @app.stubs(:puts)
- it "should ask OptionParser to parse the command-line argument" do
- @app.option_parser.expects(:parse!)
+ lambda { @app.handle_version(nil) }.should raise_error(SystemExit)
+ end
+ end
- @app.parse_options
- end
+ describe "when dealing with an argument not declared directly by the application" do
+ it "should pass it to handle_unknown if this method exists" do
+ Puppet.settings.stubs(:optparse_addargs).returns([["--not-handled"]])
+ @app.option_parser.stubs(:on).yields("value")
- describe "when using --help" do
- confine "rdoc" => Puppet.features.usage?
+ @app.expects(:handle_unknown).with("--not-handled", "value").returns(true)
- it "should call RDoc::usage and exit" do
- @app.expects(:exit)
- RDoc.expects(:usage).returns(true)
+ @app.parse_options
+ end
- @app.handle_help(nil)
- end
+ it "should pass it to Puppet.settings if handle_unknown says so" do
+ Puppet.settings.stubs(:optparse_addargs).returns([["--topuppet"]])
+ @app.option_parser.stubs(:on).yields("value")
- end
+ @app.stubs(:handle_unknown).with("--topuppet", "value").returns(false)
- describe "when using --version" do
- it "should declare a version option" do
- @app.should respond_to(:handle_version)
- end
+ Puppet.settings.expects(:handlearg).with("--topuppet", "value")
+ @app.parse_options
+ end
- it "should exit after printing the version" do
- @app.stubs(:puts)
+ it "should pass it to Puppet.settings if there is no handle_unknown method" do
+ Puppet.settings.stubs(:optparse_addargs).returns([["--topuppet"]])
+ @app.option_parser.stubs(:on).yields("value")
- lambda { @app.handle_version(nil) }.should raise_error(SystemExit)
- end
- end
+ @app.stubs(:respond_to?).returns(false)
- describe "when dealing with an argument not declared directly by the application" do
- it "should pass it to handle_unknown if this method exists" do
- Puppet.settings.stubs(:optparse_addargs).returns([["--not-handled"]])
- @app.option_parser.stubs(:on).yields("value")
+ Puppet.settings.expects(:handlearg).with("--topuppet", "value")
+ @app.parse_options
+ end
- @app.expects(:handle_unknown).with("--not-handled", "value").returns(true)
+ it "should transform boolean false value to string for Puppet.settings" do
+ Puppet.settings.expects(:handlearg).with("--option", "false")
+ @app.handlearg("--option", false)
+ end
- @app.parse_options
- end
+ it "should transform boolean true value to string for Puppet.settings" do
+ Puppet.settings.expects(:handlearg).with("--option", "true")
+ @app.handlearg("--option", true)
+ end
- it "should pass it to Puppet.settings if handle_unknown says so" do
- Puppet.settings.stubs(:optparse_addargs).returns([["--topuppet"]])
- @app.option_parser.stubs(:on).yields("value")
+ it "should transform boolean option to normal form for Puppet.settings" do
+ Puppet.settings.expects(:handlearg).with("--option", "true")
+ @app.handlearg("--[no-]option", true)
+ end
- @app.stubs(:handle_unknown).with("--topuppet", "value").returns(false)
+ it "should transform boolean option to no- form for Puppet.settings" do
+ Puppet.settings.expects(:handlearg).with("--no-option", "false")
+ @app.handlearg("--[no-]option", false)
+ end
- Puppet.settings.expects(:handlearg).with("--topuppet", "value")
- @app.parse_options
- end
+ end
- it "should pass it to Puppet.settings if there is no handle_unknown method" do
- Puppet.settings.stubs(:optparse_addargs).returns([["--topuppet"]])
- @app.option_parser.stubs(:on).yields("value")
+ it "should exit if OptionParser raises an error" do
+ $stderr.stubs(:puts)
+ @app.option_parser.stubs(:parse!).raises(OptionParser::ParseError.new("blah blah"))
- @app.stubs(:respond_to?).returns(false)
+ @app.expects(:exit)
- Puppet.settings.expects(:handlearg).with("--topuppet", "value")
- @app.parse_options
- end
+ lambda { @app.parse_options }.should_not raise_error
+ end
- it "should transform boolean false value to string for Puppet.settings" do
- Puppet.settings.expects(:handlearg).with("--option", "false")
- @app.handlearg("--option", false)
- end
+ end
- it "should transform boolean true value to string for Puppet.settings" do
- Puppet.settings.expects(:handlearg).with("--option", "true")
- @app.handlearg("--option", true)
- end
+ describe "when calling default setup" do
- it "should transform boolean option to normal form for Puppet.settings" do
- Puppet.settings.expects(:handlearg).with("--option", "true")
- @app.handlearg("--[no-]option", true)
- end
+ before :each do
+ @app.stubs(:should_parse_config?).returns(false)
+ @app.options.stubs(:[])
+ end
- it "should transform boolean option to no- form for Puppet.settings" do
- Puppet.settings.expects(:handlearg).with("--no-option", "false")
- @app.handlearg("--[no-]option", false)
- end
+ [ :debug, :verbose ].each do |level|
+ it "should honor option #{level}" do
+ @app.options.stubs(:[]).with(level).returns(true)
+ Puppet::Util::Log.stubs(:newdestination)
- end
+ Puppet::Util::Log.expects(:level=).with(level == :verbose ? :info : :debug)
- it "should exit if OptionParser raises an error" do
- $stderr.stubs(:puts)
- @app.option_parser.stubs(:parse!).raises(OptionParser::ParseError.new("blah blah"))
+ @app.setup
+ end
+ end
- @app.expects(:exit)
+ it "should honor setdest option" do
+ @app.options.stubs(:[]).with(:setdest).returns(false)
- lambda { @app.parse_options }.should_not raise_error
- end
+ Puppet::Util::Log.expects(:newdestination).with(:syslog)
+ @app.setup
end
- describe "when calling default setup" do
+ end
- before :each do
- @app.stubs(:should_parse_config?).returns(false)
- @app.options.stubs(:[])
- end
+ describe "when running" do
- [ :debug, :verbose ].each do |level|
- it "should honor option #{level}" do
- @app.options.stubs(:[]).with(level).returns(true)
- Puppet::Util::Log.stubs(:newdestination)
+ before :each do
+ @app.stubs(:preinit)
+ @app.stubs(:setup)
+ @app.stubs(:parse_options)
+ end
- Puppet::Util::Log.expects(:level=).with(level == :verbose ? :info : :debug)
+ it "should call preinit" do
+ @app.stubs(:run_command)
- @app.setup
- end
- end
+ @app.expects(:preinit)
- it "should honor setdest option" do
- @app.options.stubs(:[]).with(:setdest).returns(false)
+ @app.run
+ end
- Puppet::Util::Log.expects(:newdestination).with(:syslog)
+ it "should call parse_options" do
+ @app.stubs(:run_command)
- @app.setup
- end
+ @app.expects(:parse_options)
+ @app.run
end
- describe "when running" do
+ it "should call run_command" do
- before :each do
- @app.stubs(:preinit)
- @app.stubs(:setup)
- @app.stubs(:parse_options)
- end
-
- it "should call preinit" do
- @app.stubs(:run_command)
+ @app.expects(:run_command)
- @app.expects(:preinit)
+ @app.run
+ end
- @app.run
- end
+ it "should parse Puppet configuration if should_parse_config is called" do
+ @app.stubs(:run_command)
+ @app.class.should_parse_config
- it "should call parse_options" do
- @app.stubs(:run_command)
+ Puppet.settings.expects(:parse)
- @app.expects(:parse_options)
+ @app.run
+ end
- @app.run
- end
+ it "should not parse_option if should_not_parse_config is called" do
+ @app.stubs(:run_command)
+ @app.class.should_not_parse_config
- it "should call run_command" do
+ Puppet.settings.expects(:parse).never
- @app.expects(:run_command)
+ @app.run
+ end
- @app.run
- end
+ it "should parse Puppet configuration if needed" do
+ @app.stubs(:run_command)
+ @app.stubs(:should_parse_config?).returns(true)
- it "should parse Puppet configuration if should_parse_config is called" do
- @app.stubs(:run_command)
- @app.class.should_parse_config
+ Puppet.settings.expects(:parse)
- Puppet.settings.expects(:parse)
+ @app.run
+ end
- @app.run
- end
+ it "should call run_command" do
+ @app.expects(:run_command)
- it "should not parse_option if should_not_parse_config is called" do
- @app.stubs(:run_command)
- @app.class.should_not_parse_config
+ @app.run
+ end
- Puppet.settings.expects(:parse).never
+ it "should call main as the default command" do
+ @app.expects(:main)
- @app.run
- end
+ @app.run
+ end
- it "should parse Puppet configuration if needed" do
- @app.stubs(:run_command)
- @app.stubs(:should_parse_config?).returns(true)
+ it "should warn and exit if no command can be called" do
+ $stderr.expects(:puts)
+ @app.expects(:exit).with(1)
+ @app.run
+ end
- Puppet.settings.expects(:parse)
+ it "should raise an error if dispatch returns no command" do
+ @app.stubs(:get_command).returns(nil)
+ $stderr.expects(:puts)
+ @app.expects(:exit).with(1)
+ @app.run
+ end
- @app.run
- end
+ it "should raise an error if dispatch returns an invalid command" do
+ @app.stubs(:get_command).returns(:this_function_doesnt_exist)
+ $stderr.expects(:puts)
+ @app.expects(:exit).with(1)
+ @app.run
+ end
+ end
- it "should call run_command" do
- @app.expects(:run_command)
+ describe "when metaprogramming" do
- @app.run
+ describe "when calling option" do
+ it "should create a new method named after the option" do
+ @app.class.option("--test1","-t") do
end
- it "should call main as the default command" do
- @app.expects(:main)
+ @app.should respond_to(:handle_test1)
+ end
- @app.run
+ it "should transpose in option name any '-' into '_'" do
+ @app.class.option("--test-dashes-again","-t") do
end
- it "should warn and exit if no command can be called" do
- $stderr.expects(:puts)
- @app.expects(:exit).with(1)
- @app.run
- end
+ @app.should respond_to(:handle_test_dashes_again)
+ end
- it "should raise an error if dispatch returns no command" do
- @app.stubs(:get_command).returns(nil)
- $stderr.expects(:puts)
- @app.expects(:exit).with(1)
- @app.run
+ it "should create a new method called handle_test2 with option(\"--[no-]test2\")" do
+ @app.class.option("--[no-]test2","-t") do
end
- it "should raise an error if dispatch returns an invalid command" do
- @app.stubs(:get_command).returns(:this_function_doesnt_exist)
- $stderr.expects(:puts)
- @app.expects(:exit).with(1)
- @app.run
- end
- end
+ @app.should respond_to(:handle_test2)
+ end
- describe "when metaprogramming" do
+ describe "when a block is passed" do
+ it "should create a new method with it" do
+ @app.class.option("--[no-]test2","-t") do
+ raise "I can't believe it, it works!"
+ end
- describe "when calling option" do
- it "should create a new method named after the option" do
- @app.class.option("--test1","-t") do
- end
-
- @app.should respond_to(:handle_test1)
- end
-
- it "should transpose in option name any '-' into '_'" do
- @app.class.option("--test-dashes-again","-t") do
- end
-
- @app.should respond_to(:handle_test_dashes_again)
- end
-
- it "should create a new method called handle_test2 with option(\"--[no-]test2\")" do
- @app.class.option("--[no-]test2","-t") do
- end
-
- @app.should respond_to(:handle_test2)
- end
-
- describe "when a block is passed" do
- it "should create a new method with it" do
- @app.class.option("--[no-]test2","-t") do
- raise "I can't believe it, it works!"
- end
-
- lambda { @app.handle_test2 }.should raise_error
- end
+ lambda { @app.handle_test2 }.should raise_error
+ end
- it "should declare the option to OptionParser" do
- OptionParser.any_instance.stubs(:on)
- OptionParser.any_instance.expects(:on).with { |*arg| arg[0] == "--[no-]test3" }
+ it "should declare the option to OptionParser" do
+ OptionParser.any_instance.stubs(:on)
+ OptionParser.any_instance.expects(:on).with { |*arg| arg[0] == "--[no-]test3" }
- @app.class.option("--[no-]test3","-t") do
- end
+ @app.class.option("--[no-]test3","-t") do
+ end
- @app.option_parser
- end
+ @app.option_parser
+ end
- it "should pass a block that calls our defined method" do
- OptionParser.any_instance.stubs(:on)
- OptionParser.any_instance.stubs(:on).with('--test4','-t').yields(nil)
+ it "should pass a block that calls our defined method" do
+ OptionParser.any_instance.stubs(:on)
+ OptionParser.any_instance.stubs(:on).with('--test4','-t').yields(nil)
- @app.expects(:send).with(:handle_test4, nil)
+ @app.expects(:send).with(:handle_test4, nil)
- @app.class.option("--test4","-t") do
- end
+ @app.class.option("--test4","-t") do
+ end
- @app.option_parser
- end
- end
+ @app.option_parser
+ end
+ end
- describe "when no block is given" do
- it "should declare the option to OptionParser" do
- OptionParser.any_instance.stubs(:on)
- OptionParser.any_instance.expects(:on).with("--test4","-t")
+ describe "when no block is given" do
+ it "should declare the option to OptionParser" do
+ OptionParser.any_instance.stubs(:on)
+ OptionParser.any_instance.expects(:on).with("--test4","-t")
- @app.class.option("--test4","-t")
+ @app.class.option("--test4","-t")
- @app.option_parser
- end
+ @app.option_parser
+ end
- it "should give to OptionParser a block that adds the the value to the options array" do
- OptionParser.any_instance.stubs(:on)
- OptionParser.any_instance.stubs(:on).with("--test4","-t").yields(nil)
+ it "should give to OptionParser a block that adds the the value to the options array" do
+ OptionParser.any_instance.stubs(:on)
+ OptionParser.any_instance.stubs(:on).with("--test4","-t").yields(nil)
- @app.options.expects(:[]=).with(:test4,nil)
+ @app.options.expects(:[]=).with(:test4,nil)
- @app.class.option("--test4","-t")
+ @app.class.option("--test4","-t")
- @app.option_parser
- end
- end
+ @app.option_parser
end
-
+ end
end
+
+ end
end
diff --git a/spec/unit/configurer/downloader_spec.rb b/spec/unit/configurer/downloader_spec.rb
index 80de8db..c57f39f 100755
--- a/spec/unit/configurer/downloader_spec.rb
+++ b/spec/unit/configurer/downloader_spec.rb
@@ -5,184 +5,184 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/configurer/downloader'
describe Puppet::Configurer::Downloader do
- it "should require a name" do
- lambda { Puppet::Configurer::Downloader.new }.should raise_error(ArgumentError)
+ it "should require a name" do
+ lambda { Puppet::Configurer::Downloader.new }.should raise_error(ArgumentError)
+ end
+
+ it "should require a path and a source at initialization" do
+ lambda { Puppet::Configurer::Downloader.new("name") }.should raise_error(ArgumentError)
+ end
+
+ it "should set the name, path and source appropriately" do
+ dler = Puppet::Configurer::Downloader.new("facts", "path", "source")
+ dler.name.should == "facts"
+ dler.path.should == "path"
+ dler.source.should == "source"
+ end
+
+ it "should be able to provide a timeout value" do
+ Puppet::Configurer::Downloader.should respond_to(:timeout)
+ end
+
+ it "should use the configtimeout, converted to an integer, as its timeout" do
+ Puppet.settings.expects(:value).with(:configtimeout).returns "50"
+ Puppet::Configurer::Downloader.timeout.should == 50
+ end
+
+ describe "when creating the file that does the downloading" do
+ before do
+ @dler = Puppet::Configurer::Downloader.new("foo", "path", "source")
end
- it "should require a path and a source at initialization" do
- lambda { Puppet::Configurer::Downloader.new("name") }.should raise_error(ArgumentError)
+ it "should create a file instance with the right path and source" do
+ Puppet::Type.type(:file).expects(:new).with { |opts| opts[:path] == "path" and opts[:source] == "source" }
+ @dler.file
end
- it "should set the name, path and source appropriately" do
- dler = Puppet::Configurer::Downloader.new("facts", "path", "source")
- dler.name.should == "facts"
- dler.path.should == "path"
- dler.source.should == "source"
+ it "should tag the file with the downloader name" do
+ Puppet::Type.type(:file).expects(:new).with { |opts| opts[:tag] == "foo" }
+ @dler.file
end
- it "should be able to provide a timeout value" do
- Puppet::Configurer::Downloader.should respond_to(:timeout)
+ it "should always recurse" do
+ Puppet::Type.type(:file).expects(:new).with { |opts| opts[:recurse] == true }
+ @dler.file
end
- it "should use the configtimeout, converted to an integer, as its timeout" do
- Puppet.settings.expects(:value).with(:configtimeout).returns "50"
- Puppet::Configurer::Downloader.timeout.should == 50
+ it "should always purge" do
+ Puppet::Type.type(:file).expects(:new).with { |opts| opts[:purge] == true }
+ @dler.file
end
- describe "when creating the file that does the downloading" do
- before do
- @dler = Puppet::Configurer::Downloader.new("foo", "path", "source")
- end
-
- it "should create a file instance with the right path and source" do
- Puppet::Type.type(:file).expects(:new).with { |opts| opts[:path] == "path" and opts[:source] == "source" }
- @dler.file
- end
-
- it "should tag the file with the downloader name" do
- Puppet::Type.type(:file).expects(:new).with { |opts| opts[:tag] == "foo" }
- @dler.file
- end
-
- it "should always recurse" do
- Puppet::Type.type(:file).expects(:new).with { |opts| opts[:recurse] == true }
- @dler.file
- end
-
- it "should always purge" do
- Puppet::Type.type(:file).expects(:new).with { |opts| opts[:purge] == true }
- @dler.file
- end
-
- it "should never be in noop" do
- Puppet::Type.type(:file).expects(:new).with { |opts| opts[:noop] == false }
- @dler.file
- end
+ it "should never be in noop" do
+ Puppet::Type.type(:file).expects(:new).with { |opts| opts[:noop] == false }
+ @dler.file
+ end
- it "should always set the owner to the current UID" do
- Process.expects(:uid).returns 51
- Puppet::Type.type(:file).expects(:new).with { |opts| opts[:owner] == 51 }
- @dler.file
- end
+ it "should always set the owner to the current UID" do
+ Process.expects(:uid).returns 51
+ Puppet::Type.type(:file).expects(:new).with { |opts| opts[:owner] == 51 }
+ @dler.file
+ end
- it "should always set the group to the current GID" do
- Process.expects(:gid).returns 61
- Puppet::Type.type(:file).expects(:new).with { |opts| opts[:group] == 61 }
- @dler.file
- end
+ it "should always set the group to the current GID" do
+ Process.expects(:gid).returns 61
+ Puppet::Type.type(:file).expects(:new).with { |opts| opts[:group] == 61 }
+ @dler.file
+ end
- it "should always force the download" do
- Puppet::Type.type(:file).expects(:new).with { |opts| opts[:force] == true }
- @dler.file
- end
+ it "should always force the download" do
+ Puppet::Type.type(:file).expects(:new).with { |opts| opts[:force] == true }
+ @dler.file
+ end
- it "should never back up when downloading" do
- Puppet::Type.type(:file).expects(:new).with { |opts| opts[:backup] == false }
- @dler.file
- end
+ it "should never back up when downloading" do
+ Puppet::Type.type(:file).expects(:new).with { |opts| opts[:backup] == false }
+ @dler.file
+ end
- it "should support providing an 'ignore' parameter" do
- Puppet::Type.type(:file).expects(:new).with { |opts| opts[:ignore] == [".svn"] }
- @dler = Puppet::Configurer::Downloader.new("foo", "path", "source", ".svn")
- @dler.file
- end
+ it "should support providing an 'ignore' parameter" do
+ Puppet::Type.type(:file).expects(:new).with { |opts| opts[:ignore] == [".svn"] }
+ @dler = Puppet::Configurer::Downloader.new("foo", "path", "source", ".svn")
+ @dler.file
+ end
- it "should split the 'ignore' parameter on whitespace" do
- Puppet::Type.type(:file).expects(:new).with { |opts| opts[:ignore] == %w{.svn CVS} }
- @dler = Puppet::Configurer::Downloader.new("foo", "path", "source", ".svn CVS")
- @dler.file
- end
+ it "should split the 'ignore' parameter on whitespace" do
+ Puppet::Type.type(:file).expects(:new).with { |opts| opts[:ignore] == %w{.svn CVS} }
+ @dler = Puppet::Configurer::Downloader.new("foo", "path", "source", ".svn CVS")
+ @dler.file
end
+ end
- describe "when creating the catalog to do the downloading" do
- before do
- @dler = Puppet::Configurer::Downloader.new("foo", "path", "source")
- end
+ describe "when creating the catalog to do the downloading" do
+ before do
+ @dler = Puppet::Configurer::Downloader.new("foo", "path", "source")
+ end
- it "should create a catalog and add the file to it" do
- file = mock 'file'
- catalog = mock 'catalog'
+ it "should create a catalog and add the file to it" do
+ file = mock 'file'
+ catalog = mock 'catalog'
- @dler.expects(:file).returns file
+ @dler.expects(:file).returns file
- Puppet::Resource::Catalog.expects(:new).returns catalog
- catalog.expects(:add_resource).with(file)
+ Puppet::Resource::Catalog.expects(:new).returns catalog
+ catalog.expects(:add_resource).with(file)
- @dler.catalog.should equal(catalog)
- end
+ @dler.catalog.should equal(catalog)
end
+ end
- describe "when downloading" do
- before do
- @dler = Puppet::Configurer::Downloader.new("foo", "path", "source")
- end
+ describe "when downloading" do
+ before do
+ @dler = Puppet::Configurer::Downloader.new("foo", "path", "source")
+ end
- it "should log that it is downloading" do
- Puppet.expects(:info)
- Timeout.stubs(:timeout)
+ it "should log that it is downloading" do
+ Puppet.expects(:info)
+ Timeout.stubs(:timeout)
- @dler.evaluate
- end
+ @dler.evaluate
+ end
- it "should set a timeout for the download" do
- Puppet::Configurer::Downloader.expects(:timeout).returns 50
- Timeout.expects(:timeout).with(50)
+ it "should set a timeout for the download" do
+ Puppet::Configurer::Downloader.expects(:timeout).returns 50
+ Timeout.expects(:timeout).with(50)
- @dler.evaluate
- end
+ @dler.evaluate
+ end
- it "should apply the catalog within the timeout block" do
- catalog = mock 'catalog'
- @dler.expects(:catalog).returns(catalog)
+ it "should apply the catalog within the timeout block" do
+ catalog = mock 'catalog'
+ @dler.expects(:catalog).returns(catalog)
- Timeout.expects(:timeout).yields
+ Timeout.expects(:timeout).yields
- catalog.expects(:apply)
+ catalog.expects(:apply)
- @dler.evaluate
- end
+ @dler.evaluate
+ end
- it "should return all changed file paths" do
- trans = mock 'transaction'
+ it "should return all changed file paths" do
+ trans = mock 'transaction'
- catalog = mock 'catalog'
- @dler.expects(:catalog).returns(catalog)
- catalog.expects(:apply).yields(trans)
+ catalog = mock 'catalog'
+ @dler.expects(:catalog).returns(catalog)
+ catalog.expects(:apply).yields(trans)
- Timeout.expects(:timeout).yields
+ Timeout.expects(:timeout).yields
- resource = mock 'resource'
- resource.expects(:[]).with(:path).returns "/changed/file"
+ resource = mock 'resource'
+ resource.expects(:[]).with(:path).returns "/changed/file"
- trans.expects(:changed?).returns([resource])
+ trans.expects(:changed?).returns([resource])
- @dler.evaluate.should == %w{/changed/file}
- end
+ @dler.evaluate.should == %w{/changed/file}
+ end
- it "should yield the resources if a block is given" do
- trans = mock 'transaction'
+ it "should yield the resources if a block is given" do
+ trans = mock 'transaction'
- catalog = mock 'catalog'
- @dler.expects(:catalog).returns(catalog)
- catalog.expects(:apply).yields(trans)
+ catalog = mock 'catalog'
+ @dler.expects(:catalog).returns(catalog)
+ catalog.expects(:apply).yields(trans)
- Timeout.expects(:timeout).yields
+ Timeout.expects(:timeout).yields
- resource = mock 'resource'
- resource.expects(:[]).with(:path).returns "/changed/file"
+ resource = mock 'resource'
+ resource.expects(:[]).with(:path).returns "/changed/file"
- trans.expects(:changed?).returns([resource])
+ trans.expects(:changed?).returns([resource])
- yielded = nil
- @dler.evaluate { |r| yielded = r }
- yielded.should == resource
- end
+ yielded = nil
+ @dler.evaluate { |r| yielded = r }
+ yielded.should == resource
+ end
- it "should catch and log exceptions" do
- Puppet.expects(:err)
- Timeout.stubs(:timeout).raises(Puppet::Error, "testing")
+ it "should catch and log exceptions" do
+ Puppet.expects(:err)
+ Timeout.stubs(:timeout).raises(Puppet::Error, "testing")
- lambda { @dler.evaluate }.should_not raise_error
- end
+ lambda { @dler.evaluate }.should_not raise_error
end
+ end
end
diff --git a/spec/unit/configurer/fact_handler_spec.rb b/spec/unit/configurer/fact_handler_spec.rb
index 290f1ac..0512701 100755
--- a/spec/unit/configurer/fact_handler_spec.rb
+++ b/spec/unit/configurer/fact_handler_spec.rb
@@ -5,160 +5,160 @@ require 'puppet/configurer'
require 'puppet/configurer/fact_handler'
class FactHandlerTester
- include Puppet::Configurer::FactHandler
+ include Puppet::Configurer::FactHandler
end
describe Puppet::Configurer::FactHandler do
- before do
- @facthandler = FactHandlerTester.new
- end
+ before do
+ @facthandler = FactHandlerTester.new
+ end
- it "should have a method for downloading fact plugins" do
- @facthandler.should respond_to(:download_fact_plugins)
- end
+ it "should have a method for downloading fact plugins" do
+ @facthandler.should respond_to(:download_fact_plugins)
+ end
- it "should have a boolean method for determining whether fact plugins should be downloaded" do
- @facthandler.should respond_to(:download_fact_plugins?)
- end
+ it "should have a boolean method for determining whether fact plugins should be downloaded" do
+ @facthandler.should respond_to(:download_fact_plugins?)
+ end
- it "should download fact plugins when :factsync is true" do
- Puppet.settings.expects(:value).with(:factsync).returns true
- @facthandler.should be_download_fact_plugins
- end
+ it "should download fact plugins when :factsync is true" do
+ Puppet.settings.expects(:value).with(:factsync).returns true
+ @facthandler.should be_download_fact_plugins
+ end
- it "should not download fact plugins when :factsync is false" do
- Puppet.settings.expects(:value).with(:factsync).returns false
- @facthandler.should_not be_download_fact_plugins
- end
+ it "should not download fact plugins when :factsync is false" do
+ Puppet.settings.expects(:value).with(:factsync).returns false
+ @facthandler.should_not be_download_fact_plugins
+ end
- it "should not download fact plugins when downloading is disabled" do
- Puppet::Configurer::Downloader.expects(:new).never
- @facthandler.expects(:download_fact_plugins?).returns false
- @facthandler.download_fact_plugins
- end
+ it "should not download fact plugins when downloading is disabled" do
+ Puppet::Configurer::Downloader.expects(:new).never
+ @facthandler.expects(:download_fact_plugins?).returns false
+ @facthandler.download_fact_plugins
+ end
- it "should use an Agent Downloader, with the name, source, destination, and ignore set correctly, to download fact plugins when downloading is enabled" do
- downloader = mock 'downloader'
+ it "should use an Agent Downloader, with the name, source, destination, and ignore set correctly, to download fact plugins when downloading is enabled" do
+ downloader = mock 'downloader'
- Puppet.settings.expects(:value).with(:factsource).returns "fsource"
- Puppet.settings.expects(:value).with(:factdest).returns "fdest"
- Puppet.settings.expects(:value).with(:factsignore).returns "fignore"
+ Puppet.settings.expects(:value).with(:factsource).returns "fsource"
+ Puppet.settings.expects(:value).with(:factdest).returns "fdest"
+ Puppet.settings.expects(:value).with(:factsignore).returns "fignore"
- Puppet::Configurer::Downloader.expects(:new).with("fact", "fdest", "fsource", "fignore").returns downloader
+ Puppet::Configurer::Downloader.expects(:new).with("fact", "fdest", "fsource", "fignore").returns downloader
- downloader.expects(:evaluate)
+ downloader.expects(:evaluate)
- @facthandler.expects(:download_fact_plugins?).returns true
- @facthandler.download_fact_plugins
- end
+ @facthandler.expects(:download_fact_plugins?).returns true
+ @facthandler.download_fact_plugins
+ end
- it "should warn about factsync deprecation when factsync is enabled" do
- Puppet::Configurer::Downloader.stubs(:new).returns mock("downloader", :evaluate => nil)
+ it "should warn about factsync deprecation when factsync is enabled" do
+ Puppet::Configurer::Downloader.stubs(:new).returns mock("downloader", :evaluate => nil)
- @facthandler.expects(:download_fact_plugins?).returns true
- Puppet.expects(:warning)
- @facthandler.download_fact_plugins
- end
+ @facthandler.expects(:download_fact_plugins?).returns true
+ Puppet.expects(:warning)
+ @facthandler.download_fact_plugins
+ end
- it "should have a method for retrieving facts" do
- @facthandler.should respond_to(:find_facts)
- end
+ it "should have a method for retrieving facts" do
+ @facthandler.should respond_to(:find_facts)
+ end
- it "should use the Facts class with the :certname to find the facts" do
- Puppet.settings.expects(:value).with(:certname).returns "foo"
- Puppet::Node::Facts.expects(:find).with("foo").returns "myfacts"
- @facthandler.stubs(:reload_facter)
- @facthandler.find_facts.should == "myfacts"
- end
+ it "should use the Facts class with the :certname to find the facts" do
+ Puppet.settings.expects(:value).with(:certname).returns "foo"
+ Puppet::Node::Facts.expects(:find).with("foo").returns "myfacts"
+ @facthandler.stubs(:reload_facter)
+ @facthandler.find_facts.should == "myfacts"
+ end
- it "should reload Facter and find local facts when asked to find facts" do
- @facthandler.expects(:reload_facter)
+ it "should reload Facter and find local facts when asked to find facts" do
+ @facthandler.expects(:reload_facter)
- Puppet.settings.expects(:value).with(:certname).returns "myhost"
- Puppet::Node::Facts.expects(:find).with("myhost")
+ Puppet.settings.expects(:value).with(:certname).returns "myhost"
+ Puppet::Node::Facts.expects(:find).with("myhost")
- @facthandler.find_facts
- end
+ @facthandler.find_facts
+ end
- it "should fail if finding facts fails" do
- @facthandler.stubs(:reload_facter)
+ it "should fail if finding facts fails" do
+ @facthandler.stubs(:reload_facter)
- Puppet.settings.stubs(:value).with(:trace).returns false
- Puppet.settings.stubs(:value).with(:certname).returns "myhost"
- Puppet::Node::Facts.expects(:find).raises RuntimeError
+ Puppet.settings.stubs(:value).with(:trace).returns false
+ Puppet.settings.stubs(:value).with(:certname).returns "myhost"
+ Puppet::Node::Facts.expects(:find).raises RuntimeError
- lambda { @facthandler.find_facts }.should raise_error(Puppet::Error)
- end
+ lambda { @facthandler.find_facts }.should raise_error(Puppet::Error)
+ end
- it "should have a method to prepare the facts for uploading" do
- @facthandler.should respond_to(:facts_for_uploading)
- end
+ it "should have a method to prepare the facts for uploading" do
+ @facthandler.should respond_to(:facts_for_uploading)
+ end
- # I couldn't get marshal to work for this, only yaml, so we hard-code yaml.
- it "should serialize and CGI escape the fact values for uploading" do
- facts = stub 'facts'
- facts.expects(:support_format?).with(:b64_zlib_yaml).returns true
- facts.expects(:render).returns "my text"
- text = CGI.escape("my text")
+ # I couldn't get marshal to work for this, only yaml, so we hard-code yaml.
+ it "should serialize and CGI escape the fact values for uploading" do
+ facts = stub 'facts'
+ facts.expects(:support_format?).with(:b64_zlib_yaml).returns true
+ facts.expects(:render).returns "my text"
+ text = CGI.escape("my text")
- @facthandler.expects(:find_facts).returns facts
+ @facthandler.expects(:find_facts).returns facts
- @facthandler.facts_for_uploading.should == {:facts_format => :b64_zlib_yaml, :facts => text}
- end
+ @facthandler.facts_for_uploading.should == {:facts_format => :b64_zlib_yaml, :facts => text}
+ end
- it "should properly accept facts containing a '+'" do
- facts = stub 'facts'
- facts.expects(:support_format?).with(:b64_zlib_yaml).returns true
- facts.expects(:render).returns "my+text"
- text = "my%2Btext"
+ it "should properly accept facts containing a '+'" do
+ facts = stub 'facts'
+ facts.expects(:support_format?).with(:b64_zlib_yaml).returns true
+ facts.expects(:render).returns "my+text"
+ text = "my%2Btext"
- @facthandler.expects(:find_facts).returns facts
+ @facthandler.expects(:find_facts).returns facts
- @facthandler.facts_for_uploading.should == {:facts_format => :b64_zlib_yaml, :facts => text}
- end
+ @facthandler.facts_for_uploading.should == {:facts_format => :b64_zlib_yaml, :facts => text}
+ end
- it "use compressed yaml as the serialization if zlib is supported" do
- facts = stub 'facts'
- facts.expects(:support_format?).with(:b64_zlib_yaml).returns true
- facts.expects(:render).with(:b64_zlib_yaml).returns "my text"
- text = CGI.escape("my text")
+ it "use compressed yaml as the serialization if zlib is supported" do
+ facts = stub 'facts'
+ facts.expects(:support_format?).with(:b64_zlib_yaml).returns true
+ facts.expects(:render).with(:b64_zlib_yaml).returns "my text"
+ text = CGI.escape("my text")
- @facthandler.expects(:find_facts).returns facts
+ @facthandler.expects(:find_facts).returns facts
- @facthandler.facts_for_uploading
- end
+ @facthandler.facts_for_uploading
+ end
+
+ it "should use yaml as the serialization if zlib is not supported" do
+ facts = stub 'facts'
+ facts.expects(:support_format?).with(:b64_zlib_yaml).returns false
+ facts.expects(:render).with(:yaml).returns "my text"
+ text = CGI.escape("my text")
- it "should use yaml as the serialization if zlib is not supported" do
- facts = stub 'facts'
- facts.expects(:support_format?).with(:b64_zlib_yaml).returns false
- facts.expects(:render).with(:yaml).returns "my text"
- text = CGI.escape("my text")
+ @facthandler.expects(:find_facts).returns facts
- @facthandler.expects(:find_facts).returns facts
+ @facthandler.facts_for_uploading
+ end
+
+ describe "when reloading Facter" do
+ before do
+ Facter.stubs(:clear)
+ Facter.stubs(:load)
+ Facter.stubs(:loadfacts)
+ end
+
+ it "should clear Facter" do
+ Facter.expects(:clear)
+ @facthandler.reload_facter
+ end
- @facthandler.facts_for_uploading
+ it "should load all Facter facts" do
+ Facter.expects(:loadfacts)
+ @facthandler.reload_facter
end
- describe "when reloading Facter" do
- before do
- Facter.stubs(:clear)
- Facter.stubs(:load)
- Facter.stubs(:loadfacts)
- end
-
- it "should clear Facter" do
- Facter.expects(:clear)
- @facthandler.reload_facter
- end
-
- it "should load all Facter facts" do
- Facter.expects(:loadfacts)
- @facthandler.reload_facter
- end
-
- it "should use the Facter terminus load all Puppet Fact plugins" do
- Puppet::Node::Facts::Facter.expects(:load_fact_plugins)
- @facthandler.reload_facter
- end
+ it "should use the Facter terminus load all Puppet Fact plugins" do
+ Puppet::Node::Facts::Facter.expects(:load_fact_plugins)
+ @facthandler.reload_facter
end
+ end
end
diff --git a/spec/unit/configurer/plugin_handler_spec.rb b/spec/unit/configurer/plugin_handler_spec.rb
index 7f59d5b..25d2d47 100755
--- a/spec/unit/configurer/plugin_handler_spec.rb
+++ b/spec/unit/configurer/plugin_handler_spec.rb
@@ -5,108 +5,108 @@ require 'puppet/configurer'
require 'puppet/configurer/plugin_handler'
class PluginHandlerTester
- include Puppet::Configurer::PluginHandler
+ include Puppet::Configurer::PluginHandler
end
describe Puppet::Configurer::PluginHandler do
- before do
- @pluginhandler = PluginHandlerTester.new
- end
+ before do
+ @pluginhandler = PluginHandlerTester.new
+ end
- it "should have a method for downloading plugins" do
- @pluginhandler.should respond_to(:download_plugins)
- end
+ it "should have a method for downloading plugins" do
+ @pluginhandler.should respond_to(:download_plugins)
+ end
- it "should have a boolean method for determining whether plugins should be downloaded" do
- @pluginhandler.should respond_to(:download_plugins?)
- end
+ it "should have a boolean method for determining whether plugins should be downloaded" do
+ @pluginhandler.should respond_to(:download_plugins?)
+ end
- it "should download plugins when :pluginsync is true" do
- Puppet.settings.expects(:value).with(:pluginsync).returns true
- @pluginhandler.should be_download_plugins
- end
+ it "should download plugins when :pluginsync is true" do
+ Puppet.settings.expects(:value).with(:pluginsync).returns true
+ @pluginhandler.should be_download_plugins
+ end
- it "should not download plugins when :pluginsync is false" do
- Puppet.settings.expects(:value).with(:pluginsync).returns false
- @pluginhandler.should_not be_download_plugins
- end
+ it "should not download plugins when :pluginsync is false" do
+ Puppet.settings.expects(:value).with(:pluginsync).returns false
+ @pluginhandler.should_not be_download_plugins
+ end
- it "should not download plugins when downloading is disabled" do
- Puppet::Configurer::Downloader.expects(:new).never
- @pluginhandler.expects(:download_plugins?).returns false
- @pluginhandler.download_plugins
- end
+ it "should not download plugins when downloading is disabled" do
+ Puppet::Configurer::Downloader.expects(:new).never
+ @pluginhandler.expects(:download_plugins?).returns false
+ @pluginhandler.download_plugins
+ end
- it "should use an Agent Downloader, with the name, source, destination, and ignore set correctly, to download plugins when downloading is enabled" do
- downloader = mock 'downloader'
+ it "should use an Agent Downloader, with the name, source, destination, and ignore set correctly, to download plugins when downloading is enabled" do
+ downloader = mock 'downloader'
- Puppet.settings.expects(:value).with(:pluginsource).returns "psource"
- Puppet.settings.expects(:value).with(:plugindest).returns "pdest"
- Puppet.settings.expects(:value).with(:pluginsignore).returns "pignore"
+ Puppet.settings.expects(:value).with(:pluginsource).returns "psource"
+ Puppet.settings.expects(:value).with(:plugindest).returns "pdest"
+ Puppet.settings.expects(:value).with(:pluginsignore).returns "pignore"
- Puppet::Configurer::Downloader.expects(:new).with("plugin", "pdest", "psource", "pignore").returns downloader
+ Puppet::Configurer::Downloader.expects(:new).with("plugin", "pdest", "psource", "pignore").returns downloader
- downloader.expects(:evaluate).returns []
+ downloader.expects(:evaluate).returns []
- @pluginhandler.expects(:download_plugins?).returns true
- @pluginhandler.download_plugins
- end
+ @pluginhandler.expects(:download_plugins?).returns true
+ @pluginhandler.download_plugins
+ end
- it "should be able to load plugins" do
- @pluginhandler.should respond_to(:load_plugin)
- end
+ it "should be able to load plugins" do
+ @pluginhandler.should respond_to(:load_plugin)
+ end
- it "should load each downloaded file" do
- FileTest.stubs(:exist?).returns true
- downloader = mock 'downloader'
+ it "should load each downloaded file" do
+ FileTest.stubs(:exist?).returns true
+ downloader = mock 'downloader'
- Puppet::Configurer::Downloader.expects(:new).returns downloader
+ Puppet::Configurer::Downloader.expects(:new).returns downloader
- downloader.expects(:evaluate).returns %w{one two}
+ downloader.expects(:evaluate).returns %w{one two}
- @pluginhandler.expects(:download_plugins?).returns true
+ @pluginhandler.expects(:download_plugins?).returns true
- @pluginhandler.expects(:load_plugin).with("one")
- @pluginhandler.expects(:load_plugin).with("two")
+ @pluginhandler.expects(:load_plugin).with("one")
+ @pluginhandler.expects(:load_plugin).with("two")
- @pluginhandler.download_plugins
- end
+ @pluginhandler.download_plugins
+ end
- it "should load plugins when asked to do so" do
- FileTest.stubs(:exist?).returns true
- @pluginhandler.expects(:load).with("foo")
+ it "should load plugins when asked to do so" do
+ FileTest.stubs(:exist?).returns true
+ @pluginhandler.expects(:load).with("foo")
- @pluginhandler.load_plugin("foo")
- end
+ @pluginhandler.load_plugin("foo")
+ end
- it "should not try to load files that don't exist" do
- FileTest.expects(:exist?).with("foo").returns true
- @pluginhandler.expects(:load).never
+ it "should not try to load files that don't exist" do
+ FileTest.expects(:exist?).with("foo").returns true
+ @pluginhandler.expects(:load).never
- @pluginhandler.load_plugin("foo")
- end
+ @pluginhandler.load_plugin("foo")
+ end
- it "should not try to load directories" do
- FileTest.stubs(:exist?).returns true
- FileTest.expects(:directory?).with("foo").returns true
- @pluginhandler.expects(:load).never
+ it "should not try to load directories" do
+ FileTest.stubs(:exist?).returns true
+ FileTest.expects(:directory?).with("foo").returns true
+ @pluginhandler.expects(:load).never
- @pluginhandler.load_plugin("foo")
- end
+ @pluginhandler.load_plugin("foo")
+ end
- it "should warn but not fail if loading a file raises an exception" do
- FileTest.stubs(:exist?).returns true
- @pluginhandler.expects(:load).with("foo").raises "eh"
+ it "should warn but not fail if loading a file raises an exception" do
+ FileTest.stubs(:exist?).returns true
+ @pluginhandler.expects(:load).with("foo").raises "eh"
- Puppet.expects(:err)
- @pluginhandler.load_plugin("foo")
- end
+ Puppet.expects(:err)
+ @pluginhandler.load_plugin("foo")
+ end
- it "should warn but not fail if loading a file raises a LoadError" do
- FileTest.stubs(:exist?).returns true
- @pluginhandler.expects(:load).with("foo").raises LoadError.new("eh")
+ it "should warn but not fail if loading a file raises a LoadError" do
+ FileTest.stubs(:exist?).returns true
+ @pluginhandler.expects(:load).with("foo").raises LoadError.new("eh")
- Puppet.expects(:err)
- @pluginhandler.load_plugin("foo")
- end
+ Puppet.expects(:err)
+ @pluginhandler.load_plugin("foo")
+ end
end
diff --git a/spec/unit/configurer_spec.rb b/spec/unit/configurer_spec.rb
index 377ac74..0c9d063 100755
--- a/spec/unit/configurer_spec.rb
+++ b/spec/unit/configurer_spec.rb
@@ -7,488 +7,488 @@ require File.dirname(__FILE__) + '/../spec_helper'
require 'puppet/configurer'
describe Puppet::Configurer do
- before do
- Puppet.settings.stubs(:use).returns(true)
- @agent = Puppet::Configurer.new
- end
+ before do
+ Puppet.settings.stubs(:use).returns(true)
+ @agent = Puppet::Configurer.new
+ end
- it "should include the Plugin Handler module" do
- Puppet::Configurer.ancestors.should be_include(Puppet::Configurer::PluginHandler)
- end
+ it "should include the Plugin Handler module" do
+ Puppet::Configurer.ancestors.should be_include(Puppet::Configurer::PluginHandler)
+ end
- it "should include the Fact Handler module" do
- Puppet::Configurer.ancestors.should be_include(Puppet::Configurer::FactHandler)
- end
+ it "should include the Fact Handler module" do
+ Puppet::Configurer.ancestors.should be_include(Puppet::Configurer::FactHandler)
+ end
- it "should use the puppetdlockfile as its lockfile path" do
- Puppet.settings.expects(:value).with(:puppetdlockfile).returns("/my/lock")
- Puppet::Configurer.lockfile_path.should == "/my/lock"
- end
+ it "should use the puppetdlockfile as its lockfile path" do
+ Puppet.settings.expects(:value).with(:puppetdlockfile).returns("/my/lock")
+ Puppet::Configurer.lockfile_path.should == "/my/lock"
+ end
- describe "when executing a pre-run hook" do
- it "should do nothing if the hook is set to an empty string" do
- Puppet.settings[:prerun_command] = ""
- Puppet::Util.expects(:exec).never
+ describe "when executing a pre-run hook" do
+ it "should do nothing if the hook is set to an empty string" do
+ Puppet.settings[:prerun_command] = ""
+ Puppet::Util.expects(:exec).never
- @agent.execute_prerun_command
- end
+ @agent.execute_prerun_command
+ end
- it "should execute any pre-run command provided via the 'prerun_command' setting" do
- Puppet.settings[:prerun_command] = "/my/command"
- Puppet::Util.expects(:execute).with { |args| args[0] == "/my/command" }
+ it "should execute any pre-run command provided via the 'prerun_command' setting" do
+ Puppet.settings[:prerun_command] = "/my/command"
+ Puppet::Util.expects(:execute).with { |args| args[0] == "/my/command" }
- @agent.execute_prerun_command
- end
+ @agent.execute_prerun_command
+ end
- it "should fail if the command fails" do
- Puppet.settings[:prerun_command] = "/my/command"
- Puppet::Util.expects(:execute).raises Puppet::ExecutionFailure
+ it "should fail if the command fails" do
+ Puppet.settings[:prerun_command] = "/my/command"
+ Puppet::Util.expects(:execute).raises Puppet::ExecutionFailure
- lambda { @agent.execute_prerun_command }.should raise_error(Puppet::Configurer::CommandHookError)
- end
+ lambda { @agent.execute_prerun_command }.should raise_error(Puppet::Configurer::CommandHookError)
end
+ end
- describe "when executing a post-run hook" do
- it "should do nothing if the hook is set to an empty string" do
- Puppet.settings[:postrun_command] = ""
- Puppet::Util.expects(:exec).never
+ describe "when executing a post-run hook" do
+ it "should do nothing if the hook is set to an empty string" do
+ Puppet.settings[:postrun_command] = ""
+ Puppet::Util.expects(:exec).never
- @agent.execute_postrun_command
- end
+ @agent.execute_postrun_command
+ end
- it "should execute any post-run command provided via the 'postrun_command' setting" do
- Puppet.settings[:postrun_command] = "/my/command"
- Puppet::Util.expects(:execute).with { |args| args[0] == "/my/command" }
+ it "should execute any post-run command provided via the 'postrun_command' setting" do
+ Puppet.settings[:postrun_command] = "/my/command"
+ Puppet::Util.expects(:execute).with { |args| args[0] == "/my/command" }
- @agent.execute_postrun_command
- end
+ @agent.execute_postrun_command
+ end
- it "should fail if the command fails" do
- Puppet.settings[:postrun_command] = "/my/command"
- Puppet::Util.expects(:execute).raises Puppet::ExecutionFailure
+ it "should fail if the command fails" do
+ Puppet.settings[:postrun_command] = "/my/command"
+ Puppet::Util.expects(:execute).raises Puppet::ExecutionFailure
- lambda { @agent.execute_postrun_command }.should raise_error(Puppet::Configurer::CommandHookError)
- end
+ lambda { @agent.execute_postrun_command }.should raise_error(Puppet::Configurer::CommandHookError)
end
+ end
end
describe Puppet::Configurer, "when initializing a report" do
- it "should return an instance of a transaction report" do
- Puppet.settings.stubs(:use).returns(true)
- @agent = Puppet::Configurer.new
- @agent.initialize_report.should be_instance_of(Puppet::Transaction::Report)
- end
+ it "should return an instance of a transaction report" do
+ Puppet.settings.stubs(:use).returns(true)
+ @agent = Puppet::Configurer.new
+ @agent.initialize_report.should be_instance_of(Puppet::Transaction::Report)
+ end
end
describe Puppet::Configurer, "when executing a catalog run" do
- before do
- Puppet.settings.stubs(:use).returns(true)
- @agent = Puppet::Configurer.new
- @agent.stubs(:prepare)
- @agent.stubs(:facts_for_uploading).returns({})
- @catalog = Puppet::Resource::Catalog.new
- @catalog.stubs(:apply)
- @agent.stubs(:retrieve_catalog).returns @catalog
-
- Puppet::Util::Log.stubs(:newdestination)
- Puppet::Util::Log.stubs(:close)
- end
+ before do
+ Puppet.settings.stubs(:use).returns(true)
+ @agent = Puppet::Configurer.new
+ @agent.stubs(:prepare)
+ @agent.stubs(:facts_for_uploading).returns({})
+ @catalog = Puppet::Resource::Catalog.new
+ @catalog.stubs(:apply)
+ @agent.stubs(:retrieve_catalog).returns @catalog
- it "should prepare for the run" do
- @agent.expects(:prepare)
+ Puppet::Util::Log.stubs(:newdestination)
+ Puppet::Util::Log.stubs(:close)
+ end
- @agent.run
- end
+ it "should prepare for the run" do
+ @agent.expects(:prepare)
- it "should initialize a transaction report if one is not provided" do
- report = stub 'report'
- @agent.expects(:initialize_report).returns report
+ @agent.run
+ end
- @agent.run
- end
+ it "should initialize a transaction report if one is not provided" do
+ report = stub 'report'
+ @agent.expects(:initialize_report).returns report
- it "should pass the new report to the catalog" do
- report = stub 'report'
- @agent.stubs(:initialize_report).returns report
- @catalog.expects(:apply).with{|options| options[:report] == report}
+ @agent.run
+ end
- @agent.run
- end
+ it "should pass the new report to the catalog" do
+ report = stub 'report'
+ @agent.stubs(:initialize_report).returns report
+ @catalog.expects(:apply).with{|options| options[:report] == report}
- it "should use the provided report if it was passed one" do
- report = stub 'report'
- @agent.expects(:initialize_report).never
- @catalog.expects(:apply).with{|options| options[:report] == report}
+ @agent.run
+ end
- @agent.run(:report => report)
- end
+ it "should use the provided report if it was passed one" do
+ report = stub 'report'
+ @agent.expects(:initialize_report).never
+ @catalog.expects(:apply).with{|options| options[:report] == report}
- it "should set the report as a log destination" do
- report = stub 'report'
- @agent.expects(:initialize_report).returns report
+ @agent.run(:report => report)
+ end
- Puppet::Util::Log.expects(:newdestination).with(report)
+ it "should set the report as a log destination" do
+ report = stub 'report'
+ @agent.expects(:initialize_report).returns report
- @agent.run
- end
+ Puppet::Util::Log.expects(:newdestination).with(report)
- it "should retrieve the catalog" do
- @agent.expects(:retrieve_catalog)
+ @agent.run
+ end
- @agent.run
- end
+ it "should retrieve the catalog" do
+ @agent.expects(:retrieve_catalog)
- it "should log a failure and do nothing if no catalog can be retrieved" do
- @agent.expects(:retrieve_catalog).returns nil
+ @agent.run
+ end
- Puppet.expects(:err).with "Could not retrieve catalog; skipping run"
+ it "should log a failure and do nothing if no catalog can be retrieved" do
+ @agent.expects(:retrieve_catalog).returns nil
- @agent.run
- end
+ Puppet.expects(:err).with "Could not retrieve catalog; skipping run"
- it "should apply the catalog with all options to :run" do
- @agent.expects(:retrieve_catalog).returns @catalog
+ @agent.run
+ end
- @catalog.expects(:apply).with { |args| args[:one] == true }
- @agent.run :one => true
- end
+ it "should apply the catalog with all options to :run" do
+ @agent.expects(:retrieve_catalog).returns @catalog
- it "should accept a catalog and use it instead of retrieving a different one" do
- @agent.expects(:retrieve_catalog).never
+ @catalog.expects(:apply).with { |args| args[:one] == true }
+ @agent.run :one => true
+ end
- @catalog.expects(:apply)
- @agent.run :one => true, :catalog => @catalog
- end
+ it "should accept a catalog and use it instead of retrieving a different one" do
+ @agent.expects(:retrieve_catalog).never
- it "should benchmark how long it takes to apply the catalog" do
- @agent.expects(:benchmark).with(:notice, "Finished catalog run")
+ @catalog.expects(:apply)
+ @agent.run :one => true, :catalog => @catalog
+ end
- @agent.expects(:retrieve_catalog).returns @catalog
+ it "should benchmark how long it takes to apply the catalog" do
+ @agent.expects(:benchmark).with(:notice, "Finished catalog run")
- @catalog.expects(:apply).never # because we're not yielding
- @agent.run
- end
+ @agent.expects(:retrieve_catalog).returns @catalog
- it "should execute post-run hooks after the run" do
- @agent.expects(:execute_postrun_command)
+ @catalog.expects(:apply).never # because we're not yielding
+ @agent.run
+ end
- @agent.run
- end
+ it "should execute post-run hooks after the run" do
+ @agent.expects(:execute_postrun_command)
- it "should send the report" do
- report = stub 'report'
- @agent.expects(:initialize_report).returns report
- @agent.expects(:send_report).with { |r, trans| r == report }
+ @agent.run
+ end
- @agent.run
- end
+ it "should send the report" do
+ report = stub 'report'
+ @agent.expects(:initialize_report).returns report
+ @agent.expects(:send_report).with { |r, trans| r == report }
- it "should send the transaction report with a reference to the transaction if a run was actually made" do
- report = stub 'report'
- @agent.expects(:initialize_report).returns report
+ @agent.run
+ end
- trans = stub 'transaction'
- @catalog.expects(:apply).returns trans
+ it "should send the transaction report with a reference to the transaction if a run was actually made" do
+ report = stub 'report'
+ @agent.expects(:initialize_report).returns report
- @agent.expects(:send_report).with { |r, t| t == trans }
+ trans = stub 'transaction'
+ @catalog.expects(:apply).returns trans
- @agent.run :catalog => @catalog
- end
+ @agent.expects(:send_report).with { |r, t| t == trans }
- it "should send the transaction report even if the catalog could not be retrieved" do
- @agent.expects(:retrieve_catalog).returns nil
+ @agent.run :catalog => @catalog
+ end
- report = stub 'report'
- @agent.expects(:initialize_report).returns report
- @agent.expects(:send_report)
+ it "should send the transaction report even if the catalog could not be retrieved" do
+ @agent.expects(:retrieve_catalog).returns nil
- @agent.run
- end
+ report = stub 'report'
+ @agent.expects(:initialize_report).returns report
+ @agent.expects(:send_report)
- it "should send the transaction report even if there is a failure" do
- @agent.expects(:retrieve_catalog).raises "whatever"
+ @agent.run
+ end
- report = stub 'report'
- @agent.expects(:initialize_report).returns report
- @agent.expects(:send_report)
+ it "should send the transaction report even if there is a failure" do
+ @agent.expects(:retrieve_catalog).raises "whatever"
- lambda { @agent.run }.should raise_error
- end
+ report = stub 'report'
+ @agent.expects(:initialize_report).returns report
+ @agent.expects(:send_report)
- it "should remove the report as a log destination when the run is finished" do
- report = stub 'report'
- @agent.expects(:initialize_report).returns report
+ lambda { @agent.run }.should raise_error
+ end
- Puppet::Util::Log.expects(:close).with(report)
+ it "should remove the report as a log destination when the run is finished" do
+ report = stub 'report'
+ @agent.expects(:initialize_report).returns report
- @agent.run
- end
+ Puppet::Util::Log.expects(:close).with(report)
- it "should return the report as the result of the run" do
- report = stub 'report'
- @agent.expects(:initialize_report).returns report
+ @agent.run
+ end
- @agent.run.should equal(report)
- end
+ it "should return the report as the result of the run" do
+ report = stub 'report'
+ @agent.expects(:initialize_report).returns report
+
+ @agent.run.should equal(report)
+ end
end
describe Puppet::Configurer, "when sending a report" do
- before do
- Puppet.settings.stubs(:use).returns(true)
- @configurer = Puppet::Configurer.new
+ before do
+ Puppet.settings.stubs(:use).returns(true)
+ @configurer = Puppet::Configurer.new
- @report = stub 'report'
- @trans = stub 'transaction'
- end
+ @report = stub 'report'
+ @trans = stub 'transaction'
+ end
- it "should require a report" do
- lambda { @configurer.send_report }.should raise_error(ArgumentError)
- end
+ it "should require a report" do
+ lambda { @configurer.send_report }.should raise_error(ArgumentError)
+ end
- it "should allow specification of a transaction" do
- lambda { @configurer.send_report(@report, @trans) }.should_not raise_error(ArgumentError)
- end
+ it "should allow specification of a transaction" do
+ lambda { @configurer.send_report(@report, @trans) }.should_not raise_error(ArgumentError)
+ end
- it "should use any provided transaction to add metrics to the report" do
- @trans.expects(:generate_report)
- @configurer.send_report(@report, @trans)
- end
+ it "should use any provided transaction to add metrics to the report" do
+ @trans.expects(:generate_report)
+ @configurer.send_report(@report, @trans)
+ end
- it "should print a report summary if configured to do so" do
- Puppet.settings[:summarize] = true
+ it "should print a report summary if configured to do so" do
+ Puppet.settings[:summarize] = true
- @report.expects(:summary).returns "stuff"
+ @report.expects(:summary).returns "stuff"
- @configurer.expects(:puts).with("stuff")
- @configurer.send_report(@report)
- end
+ @configurer.expects(:puts).with("stuff")
+ @configurer.send_report(@report)
+ end
- it "should not print a report summary if not configured to do so" do
- Puppet.settings[:summarize] = false
+ it "should not print a report summary if not configured to do so" do
+ Puppet.settings[:summarize] = false
- @configurer.expects(:puts).never
- @configurer.send_report(@report)
- end
+ @configurer.expects(:puts).never
+ @configurer.send_report(@report)
+ end
- it "should save the report if reporting is enabled" do
- Puppet.settings[:report] = true
+ it "should save the report if reporting is enabled" do
+ Puppet.settings[:report] = true
- @report.expects(:save)
- @configurer.send_report(@report)
- end
+ @report.expects(:save)
+ @configurer.send_report(@report)
+ end
- it "should not save the report if reporting is disabled" do
- Puppet.settings[:report] = false
+ it "should not save the report if reporting is disabled" do
+ Puppet.settings[:report] = false
- @report.expects(:save).never
- @configurer.send_report(@report)
- end
+ @report.expects(:save).never
+ @configurer.send_report(@report)
+ end
- it "should log but not fail if saving the report fails" do
- Puppet.settings[:report] = true
+ it "should log but not fail if saving the report fails" do
+ Puppet.settings[:report] = true
- @report.expects(:save).raises "whatever"
+ @report.expects(:save).raises "whatever"
- Puppet.expects(:err)
- lambda { @configurer.send_report(@report) }.should_not raise_error
- end
+ Puppet.expects(:err)
+ lambda { @configurer.send_report(@report) }.should_not raise_error
+ end
end
describe Puppet::Configurer, "when retrieving a catalog" do
- before do
- Puppet.settings.stubs(:use).returns(true)
- @agent = Puppet::Configurer.new
- @agent.stubs(:facts_for_uploading).returns({})
+ before do
+ Puppet.settings.stubs(:use).returns(true)
+ @agent = Puppet::Configurer.new
+ @agent.stubs(:facts_for_uploading).returns({})
- @catalog = Puppet::Resource::Catalog.new
+ @catalog = Puppet::Resource::Catalog.new
- # this is the default when using a Configurer instance
- Puppet::Resource::Catalog.indirection.stubs(:terminus_class).returns :rest
+ # this is the default when using a Configurer instance
+ Puppet::Resource::Catalog.indirection.stubs(:terminus_class).returns :rest
- @agent.stubs(:convert_catalog).returns @catalog
- end
+ @agent.stubs(:convert_catalog).returns @catalog
+ end
- describe "and configured to only retrieve a catalog from the cache" do
- before do
- Puppet.settings[:use_cached_catalog] = true
- end
+ describe "and configured to only retrieve a catalog from the cache" do
+ before do
+ Puppet.settings[:use_cached_catalog] = true
+ end
- it "should first look in the cache for a catalog" do
- Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns @catalog
- Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.never
+ it "should first look in the cache for a catalog" do
+ Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns @catalog
+ Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.never
- @agent.retrieve_catalog.should == @catalog
- end
+ @agent.retrieve_catalog.should == @catalog
+ end
- it "should compile a new catalog if none is found in the cache" do
- Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns nil
- Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns @catalog
+ it "should compile a new catalog if none is found in the cache" do
+ Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns nil
+ Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns @catalog
- @agent.retrieve_catalog.should == @catalog
- end
+ @agent.retrieve_catalog.should == @catalog
end
+ end
- describe "when not using a REST terminus for catalogs" do
- it "should not pass any facts when retrieving the catalog" do
- @agent.expects(:facts_for_uploading).never
- Puppet::Resource::Catalog.expects(:find).with { |name, options|
- options[:facts].nil?
- }.returns @catalog
+ describe "when not using a REST terminus for catalogs" do
+ it "should not pass any facts when retrieving the catalog" do
+ @agent.expects(:facts_for_uploading).never
+ Puppet::Resource::Catalog.expects(:find).with { |name, options|
+ options[:facts].nil?
+ }.returns @catalog
- @agent.retrieve_catalog
- end
+ @agent.retrieve_catalog
end
+ end
- describe "when using a REST terminus for catalogs" do
- it "should pass the prepared facts and the facts format as arguments when retrieving the catalog" do
- @agent.expects(:facts_for_uploading).returns(:facts => "myfacts", :facts_format => :foo)
- Puppet::Resource::Catalog.expects(:find).with { |name, options|
- options[:facts] == "myfacts" and options[:facts_format] == :foo
- }.returns @catalog
+ describe "when using a REST terminus for catalogs" do
+ it "should pass the prepared facts and the facts format as arguments when retrieving the catalog" do
+ @agent.expects(:facts_for_uploading).returns(:facts => "myfacts", :facts_format => :foo)
+ Puppet::Resource::Catalog.expects(:find).with { |name, options|
+ options[:facts] == "myfacts" and options[:facts_format] == :foo
+ }.returns @catalog
- @agent.retrieve_catalog
- end
+ @agent.retrieve_catalog
end
+ end
- it "should use the Catalog class to get its catalog" do
- Puppet::Resource::Catalog.expects(:find).returns @catalog
+ it "should use the Catalog class to get its catalog" do
+ Puppet::Resource::Catalog.expects(:find).returns @catalog
- @agent.retrieve_catalog
- end
+ @agent.retrieve_catalog
+ end
- it "should use its certname to retrieve the catalog" do
- Facter.stubs(:value).returns "eh"
- Puppet.settings[:certname] = "myhost.domain.com"
- Puppet::Resource::Catalog.expects(:find).with { |name, options| name == "myhost.domain.com" }.returns @catalog
+ it "should use its certname to retrieve the catalog" do
+ Facter.stubs(:value).returns "eh"
+ Puppet.settings[:certname] = "myhost.domain.com"
+ Puppet::Resource::Catalog.expects(:find).with { |name, options| name == "myhost.domain.com" }.returns @catalog
- @agent.retrieve_catalog
- end
+ @agent.retrieve_catalog
+ end
- it "should default to returning a catalog retrieved directly from the server, skipping the cache" do
- Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns @catalog
+ it "should default to returning a catalog retrieved directly from the server, skipping the cache" do
+ Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns @catalog
- @agent.retrieve_catalog.should == @catalog
- end
+ @agent.retrieve_catalog.should == @catalog
+ end
- it "should log and return the cached catalog when no catalog can be retrieved from the server" do
- Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns nil
- Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns @catalog
+ it "should log and return the cached catalog when no catalog can be retrieved from the server" do
+ Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns nil
+ Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns @catalog
- Puppet.expects(:notice)
+ Puppet.expects(:notice)
- @agent.retrieve_catalog.should == @catalog
- end
+ @agent.retrieve_catalog.should == @catalog
+ end
- it "should not look in the cache for a catalog if one is returned from the server" do
- Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns @catalog
- Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.never
+ it "should not look in the cache for a catalog if one is returned from the server" do
+ Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns @catalog
+ Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.never
- @agent.retrieve_catalog.should == @catalog
- end
+ @agent.retrieve_catalog.should == @catalog
+ end
- it "should return the cached catalog when retrieving the remote catalog throws an exception" do
- Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.raises "eh"
- Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns @catalog
+ it "should return the cached catalog when retrieving the remote catalog throws an exception" do
+ Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.raises "eh"
+ Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns @catalog
- @agent.retrieve_catalog.should == @catalog
- end
+ @agent.retrieve_catalog.should == @catalog
+ end
- it "should log and return nil if no catalog can be retrieved from the server and :usecacheonfailure is disabled" do
- Puppet.stubs(:[])
- Puppet.expects(:[]).with(:usecacheonfailure).returns false
- Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns nil
+ it "should log and return nil if no catalog can be retrieved from the server and :usecacheonfailure is disabled" do
+ Puppet.stubs(:[])
+ Puppet.expects(:[]).with(:usecacheonfailure).returns false
+ Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns nil
- Puppet.expects(:warning)
+ Puppet.expects(:warning)
- @agent.retrieve_catalog.should be_nil
- end
+ @agent.retrieve_catalog.should be_nil
+ end
- it "should return nil if no cached catalog is available and no catalog can be retrieved from the server" do
- Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns nil
- Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns nil
+ it "should return nil if no cached catalog is available and no catalog can be retrieved from the server" do
+ Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns nil
+ Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns nil
- @agent.retrieve_catalog.should be_nil
- end
+ @agent.retrieve_catalog.should be_nil
+ end
- it "should convert the catalog before returning" do
- Puppet::Resource::Catalog.stubs(:find).returns @catalog
+ it "should convert the catalog before returning" do
+ Puppet::Resource::Catalog.stubs(:find).returns @catalog
- @agent.expects(:convert_catalog).with { |cat, dur| cat == @catalog }.returns "converted catalog"
- @agent.retrieve_catalog.should == "converted catalog"
- end
+ @agent.expects(:convert_catalog).with { |cat, dur| cat == @catalog }.returns "converted catalog"
+ @agent.retrieve_catalog.should == "converted catalog"
+ end
- it "should return nil if there is an error while retrieving the catalog" do
- Puppet::Resource::Catalog.expects(:find).raises "eh"
+ it "should return nil if there is an error while retrieving the catalog" do
+ Puppet::Resource::Catalog.expects(:find).raises "eh"
- @agent.retrieve_catalog.should be_nil
- end
+ @agent.retrieve_catalog.should be_nil
+ end
end
describe Puppet::Configurer, "when converting the catalog" do
- before do
- Puppet.settings.stubs(:use).returns(true)
- @agent = Puppet::Configurer.new
+ before do
+ Puppet.settings.stubs(:use).returns(true)
+ @agent = Puppet::Configurer.new
- @catalog = Puppet::Resource::Catalog.new
- @oldcatalog = stub 'old_catalog', :to_ral => @catalog
- end
+ @catalog = Puppet::Resource::Catalog.new
+ @oldcatalog = stub 'old_catalog', :to_ral => @catalog
+ end
- it "should convert the catalog to a RAL-formed catalog" do
- @oldcatalog.expects(:to_ral).returns @catalog
+ it "should convert the catalog to a RAL-formed catalog" do
+ @oldcatalog.expects(:to_ral).returns @catalog
- @agent.convert_catalog(@oldcatalog, 10).should equal(@catalog)
- end
+ @agent.convert_catalog(@oldcatalog, 10).should equal(@catalog)
+ end
- it "should finalize the catalog" do
- @catalog.expects(:finalize)
+ it "should finalize the catalog" do
+ @catalog.expects(:finalize)
- @agent.convert_catalog(@oldcatalog, 10)
- end
+ @agent.convert_catalog(@oldcatalog, 10)
+ end
- it "should record the passed retrieval time with the RAL catalog" do
- @catalog.expects(:retrieval_duration=).with 10
+ it "should record the passed retrieval time with the RAL catalog" do
+ @catalog.expects(:retrieval_duration=).with 10
- @agent.convert_catalog(@oldcatalog, 10)
- end
+ @agent.convert_catalog(@oldcatalog, 10)
+ end
- it "should write the RAL catalog's class file" do
- @catalog.expects(:write_class_file)
+ it "should write the RAL catalog's class file" do
+ @catalog.expects(:write_class_file)
- @agent.convert_catalog(@oldcatalog, 10)
- end
+ @agent.convert_catalog(@oldcatalog, 10)
+ end
end
describe Puppet::Configurer, "when preparing for a run" do
- before do
- Puppet.settings.stubs(:use).returns(true)
- @agent = Puppet::Configurer.new
- @agent.stubs(:dostorage)
- @agent.stubs(:download_fact_plugins)
- @agent.stubs(:download_plugins)
- @agent.stubs(:execute_prerun_command)
- @facts = {"one" => "two", "three" => "four"}
- end
-
- it "should initialize the metadata store" do
- @agent.class.stubs(:facts).returns(@facts)
- @agent.expects(:dostorage)
- @agent.prepare
- end
-
- it "should download fact plugins" do
- @agent.expects(:download_fact_plugins)
-
- @agent.prepare
- end
-
- it "should download plugins" do
- @agent.expects(:download_plugins)
-
- @agent.prepare
- end
-
- it "should perform the pre-run commands" do
- @agent.expects(:execute_prerun_command)
- @agent.prepare
- end
+ before do
+ Puppet.settings.stubs(:use).returns(true)
+ @agent = Puppet::Configurer.new
+ @agent.stubs(:dostorage)
+ @agent.stubs(:download_fact_plugins)
+ @agent.stubs(:download_plugins)
+ @agent.stubs(:execute_prerun_command)
+ @facts = {"one" => "two", "three" => "four"}
+ end
+
+ it "should initialize the metadata store" do
+ @agent.class.stubs(:facts).returns(@facts)
+ @agent.expects(:dostorage)
+ @agent.prepare
+ end
+
+ it "should download fact plugins" do
+ @agent.expects(:download_fact_plugins)
+
+ @agent.prepare
+ end
+
+ it "should download plugins" do
+ @agent.expects(:download_plugins)
+
+ @agent.prepare
+ end
+
+ it "should perform the pre-run commands" do
+ @agent.expects(:execute_prerun_command)
+ @agent.prepare
+ end
end
diff --git a/spec/unit/daemon_spec.rb b/spec/unit/daemon_spec.rb
index a4fa644..1532073 100755
--- a/spec/unit/daemon_spec.rb
+++ b/spec/unit/daemon_spec.rb
@@ -4,303 +4,303 @@ require File.dirname(__FILE__) + '/../spec_helper'
require 'puppet/daemon'
def without_warnings
- flag = $VERBOSE
- $VERBOSE = nil
- yield
- $VERBOSE = flag
+ flag = $VERBOSE
+ $VERBOSE = nil
+ yield
+ $VERBOSE = flag
end
describe Puppet::Daemon do
- before do
- @daemon = Puppet::Daemon.new
- end
+ before do
+ @daemon = Puppet::Daemon.new
+ end
- it "should be able to manage an agent" do
- @daemon.should respond_to(:agent)
- end
+ it "should be able to manage an agent" do
+ @daemon.should respond_to(:agent)
+ end
- it "should be able to manage a network server" do
- @daemon.should respond_to(:server)
- end
+ it "should be able to manage a network server" do
+ @daemon.should respond_to(:server)
+ end
- it "should reopen the Log logs when told to reopen logs" do
- Puppet::Util::Log.expects(:reopen)
- @daemon.reopen_logs
- end
+ it "should reopen the Log logs when told to reopen logs" do
+ Puppet::Util::Log.expects(:reopen)
+ @daemon.reopen_logs
+ end
- describe "when setting signal traps" do
- before do
- @daemon.stubs(:trap)
- end
+ describe "when setting signal traps" do
+ before do
+ @daemon.stubs(:trap)
+ end
- {:INT => :stop, :TERM => :stop, :HUP => :restart, :USR1 => :reload, :USR2 => :reopen_logs}.each do |signal, method|
- it "should log and call #{method} when it receives #{signal}" do
- @daemon.expects(:trap).with(signal).yields
+ {:INT => :stop, :TERM => :stop, :HUP => :restart, :USR1 => :reload, :USR2 => :reopen_logs}.each do |signal, method|
+ it "should log and call #{method} when it receives #{signal}" do
+ @daemon.expects(:trap).with(signal).yields
- Puppet.expects(:notice)
+ Puppet.expects(:notice)
- @daemon.expects(method)
+ @daemon.expects(method)
- @daemon.set_signal_traps
- end
- end
+ @daemon.set_signal_traps
+ end
end
+ end
- describe "when starting" do
- before do
- @daemon.stubs(:create_pidfile)
- @daemon.stubs(:set_signal_traps)
- EventLoop.current.stubs(:run)
- end
+ describe "when starting" do
+ before do
+ @daemon.stubs(:create_pidfile)
+ @daemon.stubs(:set_signal_traps)
+ EventLoop.current.stubs(:run)
+ end
- it "should fail if it has neither agent nor server" do
- lambda { @daemon.start }.should raise_error(Puppet::DevError)
- end
+ it "should fail if it has neither agent nor server" do
+ lambda { @daemon.start }.should raise_error(Puppet::DevError)
+ end
- it "should create its pidfile" do
- @daemon.stubs(:agent).returns stub('agent', :start => nil)
+ it "should create its pidfile" do
+ @daemon.stubs(:agent).returns stub('agent', :start => nil)
- @daemon.expects(:create_pidfile)
- @daemon.start
- end
+ @daemon.expects(:create_pidfile)
+ @daemon.start
+ end
- it "should start the agent if the agent is configured" do
- agent = mock 'agent'
- agent.expects(:start)
- @daemon.stubs(:agent).returns agent
+ it "should start the agent if the agent is configured" do
+ agent = mock 'agent'
+ agent.expects(:start)
+ @daemon.stubs(:agent).returns agent
- @daemon.start
- end
+ @daemon.start
+ end
- it "should start its server if one is configured" do
- server = mock 'server'
- server.expects(:start)
- @daemon.stubs(:server).returns server
+ it "should start its server if one is configured" do
+ server = mock 'server'
+ server.expects(:start)
+ @daemon.stubs(:server).returns server
- @daemon.start
- end
+ @daemon.start
+ end
- it "should let the current EventLoop run" do
- @daemon.stubs(:agent).returns stub('agent', :start => nil)
- EventLoop.current.expects(:run)
+ it "should let the current EventLoop run" do
+ @daemon.stubs(:agent).returns stub('agent', :start => nil)
+ EventLoop.current.expects(:run)
- @daemon.start
- end
+ @daemon.start
end
+ end
- describe "when stopping" do
- before do
- @daemon.stubs(:remove_pidfile)
- @daemon.stubs(:exit)
- Puppet::Util::Log.stubs(:close_all)
- # to make the global safe to mock, set it to a subclass of itself,
- # then restore it in an after pass
- without_warnings { Puppet::Application = Class.new(Puppet::Application) }
- end
+ describe "when stopping" do
+ before do
+ @daemon.stubs(:remove_pidfile)
+ @daemon.stubs(:exit)
+ Puppet::Util::Log.stubs(:close_all)
+ # to make the global safe to mock, set it to a subclass of itself,
+ # then restore it in an after pass
+ without_warnings { Puppet::Application = Class.new(Puppet::Application) }
+ end
- after do
- # restore from the superclass so we lose the stub garbage
- without_warnings { Puppet::Application = Puppet::Application.superclass }
- end
+ after do
+ # restore from the superclass so we lose the stub garbage
+ without_warnings { Puppet::Application = Puppet::Application.superclass }
+ end
- it "should stop its server if one is configured" do
- server = mock 'server'
- server.expects(:stop)
- @daemon.stubs(:server).returns server
+ it "should stop its server if one is configured" do
+ server = mock 'server'
+ server.expects(:stop)
+ @daemon.stubs(:server).returns server
- @daemon.stop
- end
+ @daemon.stop
+ end
- it 'should request a stop from Puppet::Application' do
- Puppet::Application.expects(:stop!)
- @daemon.stop
- end
+ it 'should request a stop from Puppet::Application' do
+ Puppet::Application.expects(:stop!)
+ @daemon.stop
+ end
- it "should remove its pidfile" do
- @daemon.expects(:remove_pidfile)
+ it "should remove its pidfile" do
+ @daemon.expects(:remove_pidfile)
- @daemon.stop
- end
+ @daemon.stop
+ end
- it "should close all logs" do
- Puppet::Util::Log.expects(:close_all)
+ it "should close all logs" do
+ Puppet::Util::Log.expects(:close_all)
- @daemon.stop
- end
+ @daemon.stop
+ end
- it "should exit unless called with ':exit => false'" do
- @daemon.expects(:exit)
- @daemon.stop
- end
+ it "should exit unless called with ':exit => false'" do
+ @daemon.expects(:exit)
+ @daemon.stop
+ end
- it "should not exit if called with ':exit => false'" do
- @daemon.expects(:exit).never
- @daemon.stop :exit => false
- end
+ it "should not exit if called with ':exit => false'" do
+ @daemon.expects(:exit).never
+ @daemon.stop :exit => false
end
+ end
- describe "when creating its pidfile" do
- it "should use an exclusive mutex" do
- Puppet.settings.expects(:value).with(:name).returns "me"
+ describe "when creating its pidfile" do
+ it "should use an exclusive mutex" do
+ Puppet.settings.expects(:value).with(:name).returns "me"
- sync = mock 'sync'
- Puppet::Util.expects(:sync).with("me").returns sync
+ sync = mock 'sync'
+ Puppet::Util.expects(:sync).with("me").returns sync
- sync.expects(:synchronize).with(Sync::EX)
- @daemon.create_pidfile
- end
+ sync.expects(:synchronize).with(Sync::EX)
+ @daemon.create_pidfile
+ end
- it "should lock the pidfile using the Pidlock class" do
- pidfile = mock 'pidfile'
+ it "should lock the pidfile using the Pidlock class" do
+ pidfile = mock 'pidfile'
- Puppet.settings.stubs(:value).with(:name).returns "eh"
- Puppet.settings.expects(:value).with(:pidfile).returns "/my/file"
+ Puppet.settings.stubs(:value).with(:name).returns "eh"
+ Puppet.settings.expects(:value).with(:pidfile).returns "/my/file"
- Puppet::Util::Pidlock.expects(:new).with("/my/file").returns pidfile
+ Puppet::Util::Pidlock.expects(:new).with("/my/file").returns pidfile
- pidfile.expects(:lock).returns true
- @daemon.create_pidfile
- end
+ pidfile.expects(:lock).returns true
+ @daemon.create_pidfile
+ end
- it "should fail if it cannot lock" do
- pidfile = mock 'pidfile'
+ it "should fail if it cannot lock" do
+ pidfile = mock 'pidfile'
- Puppet.settings.stubs(:value).with(:name).returns "eh"
- Puppet.settings.stubs(:value).with(:pidfile).returns "/my/file"
+ Puppet.settings.stubs(:value).with(:name).returns "eh"
+ Puppet.settings.stubs(:value).with(:pidfile).returns "/my/file"
- Puppet::Util::Pidlock.expects(:new).with("/my/file").returns pidfile
+ Puppet::Util::Pidlock.expects(:new).with("/my/file").returns pidfile
- pidfile.expects(:lock).returns false
+ pidfile.expects(:lock).returns false
- lambda { @daemon.create_pidfile }.should raise_error
- end
+ lambda { @daemon.create_pidfile }.should raise_error
end
+ end
- describe "when removing its pidfile" do
- it "should use an exclusive mutex" do
- Puppet.settings.expects(:value).with(:name).returns "me"
+ describe "when removing its pidfile" do
+ it "should use an exclusive mutex" do
+ Puppet.settings.expects(:value).with(:name).returns "me"
- sync = mock 'sync'
- Puppet::Util.expects(:sync).with("me").returns sync
+ sync = mock 'sync'
+ Puppet::Util.expects(:sync).with("me").returns sync
- sync.expects(:synchronize).with(Sync::EX)
- @daemon.remove_pidfile
- end
+ sync.expects(:synchronize).with(Sync::EX)
+ @daemon.remove_pidfile
+ end
- it "should do nothing if the pidfile is not present" do
- pidfile = mock 'pidfile', :locked? => false
- Puppet::Util::Pidlock.expects(:new).with("/my/file").returns pidfile
+ it "should do nothing if the pidfile is not present" do
+ pidfile = mock 'pidfile', :locked? => false
+ Puppet::Util::Pidlock.expects(:new).with("/my/file").returns pidfile
- Puppet.settings.stubs(:value).with(:name).returns "eh"
- Puppet.settings.stubs(:value).with(:pidfile).returns "/my/file"
+ Puppet.settings.stubs(:value).with(:name).returns "eh"
+ Puppet.settings.stubs(:value).with(:pidfile).returns "/my/file"
- pidfile.expects(:unlock).never
- @daemon.remove_pidfile
- end
+ pidfile.expects(:unlock).never
+ @daemon.remove_pidfile
+ end
- it "should unlock the pidfile using the Pidlock class" do
- pidfile = mock 'pidfile', :locked? => true
- Puppet::Util::Pidlock.expects(:new).with("/my/file").returns pidfile
- pidfile.expects(:unlock).returns true
+ it "should unlock the pidfile using the Pidlock class" do
+ pidfile = mock 'pidfile', :locked? => true
+ Puppet::Util::Pidlock.expects(:new).with("/my/file").returns pidfile
+ pidfile.expects(:unlock).returns true
- Puppet.settings.stubs(:value).with(:name).returns "eh"
- Puppet.settings.stubs(:value).with(:pidfile).returns "/my/file"
+ Puppet.settings.stubs(:value).with(:name).returns "eh"
+ Puppet.settings.stubs(:value).with(:pidfile).returns "/my/file"
- @daemon.remove_pidfile
- end
+ @daemon.remove_pidfile
+ end
- it "should warn if it cannot remove the pidfile" do
- pidfile = mock 'pidfile', :locked? => true
- Puppet::Util::Pidlock.expects(:new).with("/my/file").returns pidfile
- pidfile.expects(:unlock).returns false
+ it "should warn if it cannot remove the pidfile" do
+ pidfile = mock 'pidfile', :locked? => true
+ Puppet::Util::Pidlock.expects(:new).with("/my/file").returns pidfile
+ pidfile.expects(:unlock).returns false
- Puppet.settings.stubs(:value).with(:name).returns "eh"
- Puppet.settings.stubs(:value).with(:pidfile).returns "/my/file"
+ Puppet.settings.stubs(:value).with(:name).returns "eh"
+ Puppet.settings.stubs(:value).with(:pidfile).returns "/my/file"
- Puppet.expects :err
- @daemon.remove_pidfile
- end
+ Puppet.expects :err
+ @daemon.remove_pidfile
end
+ end
- describe "when reloading" do
- it "should do nothing if no agent is configured" do
- @daemon.reload
- end
+ describe "when reloading" do
+ it "should do nothing if no agent is configured" do
+ @daemon.reload
+ end
- it "should do nothing if the agent is running" do
- agent = mock 'agent'
- agent.expects(:running?).returns true
+ it "should do nothing if the agent is running" do
+ agent = mock 'agent'
+ agent.expects(:running?).returns true
- @daemon.stubs(:agent).returns agent
+ @daemon.stubs(:agent).returns agent
- @daemon.reload
- end
+ @daemon.reload
+ end
- it "should run the agent if one is available and it is not running" do
- agent = mock 'agent'
- agent.expects(:running?).returns false
- agent.expects :run
+ it "should run the agent if one is available and it is not running" do
+ agent = mock 'agent'
+ agent.expects(:running?).returns false
+ agent.expects :run
- @daemon.stubs(:agent).returns agent
+ @daemon.stubs(:agent).returns agent
- @daemon.reload
- end
+ @daemon.reload
end
+ end
- describe "when restarting" do
- before do
- without_warnings { Puppet::Application = Class.new(Puppet::Application) }
- end
+ describe "when restarting" do
+ before do
+ without_warnings { Puppet::Application = Class.new(Puppet::Application) }
+ end
- after do
- without_warnings { Puppet::Application = Puppet::Application.superclass }
- end
+ after do
+ without_warnings { Puppet::Application = Puppet::Application.superclass }
+ end
- it 'should set Puppet::Application.restart!' do
- Puppet::Application.expects(:restart!)
- @daemon.stubs(:reexec)
- @daemon.restart
- end
+ it 'should set Puppet::Application.restart!' do
+ Puppet::Application.expects(:restart!)
+ @daemon.stubs(:reexec)
+ @daemon.restart
+ end
- it "should reexec itself if no agent is available" do
- @daemon.expects(:reexec)
+ it "should reexec itself if no agent is available" do
+ @daemon.expects(:reexec)
- @daemon.restart
- end
+ @daemon.restart
+ end
- it "should reexec itself if the agent is not running" do
- agent = mock 'agent'
- agent.expects(:running?).returns false
- @daemon.stubs(:agent).returns agent
- @daemon.expects(:reexec)
+ it "should reexec itself if the agent is not running" do
+ agent = mock 'agent'
+ agent.expects(:running?).returns false
+ @daemon.stubs(:agent).returns agent
+ @daemon.expects(:reexec)
- @daemon.restart
- end
+ @daemon.restart
end
+ end
- describe "when reexecing it self" do
- before do
- @daemon.stubs(:exec)
- @daemon.stubs(:stop)
- end
+ describe "when reexecing it self" do
+ before do
+ @daemon.stubs(:exec)
+ @daemon.stubs(:stop)
+ end
- it "should fail if no argv values are available" do
- @daemon.expects(:argv).returns nil
- lambda { @daemon.reexec }.should raise_error(Puppet::DevError)
- end
+ it "should fail if no argv values are available" do
+ @daemon.expects(:argv).returns nil
+ lambda { @daemon.reexec }.should raise_error(Puppet::DevError)
+ end
- it "should shut down without exiting" do
- @daemon.argv = %w{foo}
- @daemon.expects(:stop).with(:exit => false)
+ it "should shut down without exiting" do
+ @daemon.argv = %w{foo}
+ @daemon.expects(:stop).with(:exit => false)
- @daemon.reexec
- end
+ @daemon.reexec
+ end
- it "should call 'exec' with the original executable and arguments" do
- @daemon.argv = %w{foo}
- @daemon.expects(:exec).with($0 + " foo")
+ it "should call 'exec' with the original executable and arguments" do
+ @daemon.argv = %w{foo}
+ @daemon.expects(:exec).with($0 + " foo")
- @daemon.reexec
- end
+ @daemon.reexec
end
+ end
end
diff --git a/spec/unit/dsl/resource_api_spec.rb b/spec/unit/dsl/resource_api_spec.rb
index 628e8c8..b36a67f 100755
--- a/spec/unit/dsl/resource_api_spec.rb
+++ b/spec/unit/dsl/resource_api_spec.rb
@@ -5,177 +5,177 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/dsl/resource_api'
describe Puppet::DSL::ResourceAPI do
- before do
- @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("foo"))
- @scope = Puppet::Parser::Scope.new(:compiler => @compiler, :source => "foo")
- @resource = Puppet::Parser::Resource.new(:mytype, "myresource", :scope => @scope)
- @api = Puppet::DSL::ResourceAPI.new(@resource, @scope, proc { })
- end
-
- it "should include the resource type collection helper" do
- Puppet::DSL::ResourceAPI.ancestors.should be_include(Puppet::Resource::TypeCollectionHelper)
- end
-
- it "should use the scope's environment as its environment" do
- @scope.expects(:environment).returns "myenv"
- @api.environment.should == "myenv"
- end
-
- it "should be able to set all of its parameters as instance variables" do
- @resource["foo"] = "myval"
- @api.set_instance_variables
- @api.instance_variable_get("@foo").should == "myval"
- end
-
- describe "when calling a function" do
- it "should return false if the function does not exist" do
- Puppet::Parser::Functions.expects(:function).with("myfunc").returns nil
- @api.call_function("myfunc", "foo").should be_false
- end
-
- it "should use the scope the call the provided function with the provided arguments and return the results" do
- scope = stub 'scope'
- @api.stubs(:scope).returns scope
- Puppet::Parser::Functions.expects(:function).with("myfunc").returns "myfunc_method"
-
- scope.expects(:myfunc_method).with("one", "two")
- @api.call_function("myfunc", ["one", "two"])
- end
-
- it "should call 'include' when asked to call 'acquire'" do
- scope = stub 'scope'
- @api.stubs(:scope).returns scope
- @api.stubs(:valid_type?).returns false
-
- scope.expects(:function_include).with("one", "two")
- @api.acquire("one", "two")
- end
+ before do
+ @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("foo"))
+ @scope = Puppet::Parser::Scope.new(:compiler => @compiler, :source => "foo")
+ @resource = Puppet::Parser::Resource.new(:mytype, "myresource", :scope => @scope)
+ @api = Puppet::DSL::ResourceAPI.new(@resource, @scope, proc { })
+ end
+
+ it "should include the resource type collection helper" do
+ Puppet::DSL::ResourceAPI.ancestors.should be_include(Puppet::Resource::TypeCollectionHelper)
+ end
+
+ it "should use the scope's environment as its environment" do
+ @scope.expects(:environment).returns "myenv"
+ @api.environment.should == "myenv"
+ end
+
+ it "should be able to set all of its parameters as instance variables" do
+ @resource["foo"] = "myval"
+ @api.set_instance_variables
+ @api.instance_variable_get("@foo").should == "myval"
+ end
+
+ describe "when calling a function" do
+ it "should return false if the function does not exist" do
+ Puppet::Parser::Functions.expects(:function).with("myfunc").returns nil
+ @api.call_function("myfunc", "foo").should be_false
end
- describe "when determining if a provided name is a valid type" do
- it "should be valid if it's :class" do
- @api.should be_valid_type(:class)
- end
+ it "should use the scope the call the provided function with the provided arguments and return the results" do
+ scope = stub 'scope'
+ @api.stubs(:scope).returns scope
+ Puppet::Parser::Functions.expects(:function).with("myfunc").returns "myfunc_method"
- it "should be valid if it's :node" do
- @api.should be_valid_type(:node)
- end
+ scope.expects(:myfunc_method).with("one", "two")
+ @api.call_function("myfunc", ["one", "two"])
+ end
- it "should be valid if it's a builtin type" do
- Puppet::Type.expects(:type).with(:mytype).returns "whatever"
- @api.should be_valid_type(:mytype)
- end
+ it "should call 'include' when asked to call 'acquire'" do
+ scope = stub 'scope'
+ @api.stubs(:scope).returns scope
+ @api.stubs(:valid_type?).returns false
- it "should be valid if it's a defined resource type in the environment's known resource types" do
- collection = stub 'collection'
- @api.stubs(:known_resource_types).returns collection
- collection.expects(:definition).with(:mytype).returns "whatever"
- @api.should be_valid_type(:mytype)
- end
+ scope.expects(:function_include).with("one", "two")
+ @api.acquire("one", "two")
+ end
+ end
- it "should not be valid unless it's a node, class, builtin type, or defined resource" do
- collection = stub 'collection'
- @api.stubs(:known_resource_types).returns collection
- collection.expects(:definition).returns nil
- Puppet::Type.expects(:type).returns nil
- @api.should_not be_valid_type(:mytype)
- end
+ describe "when determining if a provided name is a valid type" do
+ it "should be valid if it's :class" do
+ @api.should be_valid_type(:class)
end
- describe "when creating a resource" do
- before do
- @api.scope.stubs(:source).returns stub("source")
- @api.scope.compiler.stubs(:add_resource)
- @created_resource = Puppet::Parser::Resource.new("yay", "eh", :scope => @api.scope)
- end
+ it "should be valid if it's :node" do
+ @api.should be_valid_type(:node)
+ end
- it "should create and return a resource of the type specified" do
- Puppet::Parser::Resource.expects(:new).with { |type, title, args| type == "mytype" }.returns @created_resource
- @api.create_resource("mytype", "myname", {:foo => "bar"}).should == [@created_resource]
- end
+ it "should be valid if it's a builtin type" do
+ Puppet::Type.expects(:type).with(:mytype).returns "whatever"
+ @api.should be_valid_type(:mytype)
+ end
- it "should use the name from the first element of the provided argument array" do
- Puppet::Parser::Resource.expects(:new).with { |type, title, args| title == "myname" }.returns @created_resource
- @api.create_resource("mytype", "myname", {:foo => "bar"})
- end
+ it "should be valid if it's a defined resource type in the environment's known resource types" do
+ collection = stub 'collection'
+ @api.stubs(:known_resource_types).returns collection
+ collection.expects(:definition).with(:mytype).returns "whatever"
+ @api.should be_valid_type(:mytype)
+ end
- it "should create multiple resources if the first element of the argument array is an array" do
- second_resource = Puppet::Parser::Resource.new('yay', "eh", :scope => @api.scope)
- Puppet::Parser::Resource.expects(:new).with { |type, title, args| title == "first" }.returns @created_resource
- Puppet::Parser::Resource.expects(:new).with { |type, title, args| title == "second" }.returns @created_resource
- @api.create_resource("mytype", ["first", "second"], {:foo => "bar"})
- end
+ it "should not be valid unless it's a node, class, builtin type, or defined resource" do
+ collection = stub 'collection'
+ @api.stubs(:known_resource_types).returns collection
+ collection.expects(:definition).returns nil
+ Puppet::Type.expects(:type).returns nil
+ @api.should_not be_valid_type(:mytype)
+ end
+ end
- it "should provide its scope as the scope" do
- Puppet::Parser::Resource.expects(:new).with { |type, title, args| args[:scope] == @api.scope }.returns @created_resource
- @api.create_resource("mytype", "myname", {:foo => "bar"})
- end
+ describe "when creating a resource" do
+ before do
+ @api.scope.stubs(:source).returns stub("source")
+ @api.scope.compiler.stubs(:add_resource)
+ @created_resource = Puppet::Parser::Resource.new("yay", "eh", :scope => @api.scope)
+ end
- it "should set each provided argument as a parameter on the created resource" do
- result = @api.create_resource("mytype", "myname", {"foo" => "bar", "biz" => "baz"}).shift
- result["foo"].should == "bar"
- result["biz"].should == "baz"
- end
+ it "should create and return a resource of the type specified" do
+ Puppet::Parser::Resource.expects(:new).with { |type, title, args| type == "mytype" }.returns @created_resource
+ @api.create_resource("mytype", "myname", {:foo => "bar"}).should == [@created_resource]
+ end
- it "should add the resource to the scope's copmiler" do
- Puppet::Parser::Resource.expects(:new).returns @created_resource
- @api.scope.compiler.expects(:add_resource).with(@api.scope, @created_resource)
- @api.create_resource("mytype", "myname", {:foo => "bar"})
- end
+ it "should use the name from the first element of the provided argument array" do
+ Puppet::Parser::Resource.expects(:new).with { |type, title, args| title == "myname" }.returns @created_resource
+ @api.create_resource("mytype", "myname", {:foo => "bar"})
+ end
- it "should fail if the resource parameters are not a hash" do
- lambda { @api.create_resource("mytype", "myname", %w{foo bar}) }.should raise_error(ArgumentError)
- end
+ it "should create multiple resources if the first element of the argument array is an array" do
+ second_resource = Puppet::Parser::Resource.new('yay', "eh", :scope => @api.scope)
+ Puppet::Parser::Resource.expects(:new).with { |type, title, args| title == "first" }.returns @created_resource
+ Puppet::Parser::Resource.expects(:new).with { |type, title, args| title == "second" }.returns @created_resource
+ @api.create_resource("mytype", ["first", "second"], {:foo => "bar"})
end
- describe "when an unknown method is called" do
- it "should create a resource if the method name is a valid type" do
- @api.expects(:valid_type?).with(:mytype).returns true
- @api.expects(:create_resource).with(:mytype, "myname", {:foo => "bar"}).returns true
+ it "should provide its scope as the scope" do
+ Puppet::Parser::Resource.expects(:new).with { |type, title, args| args[:scope] == @api.scope }.returns @created_resource
+ @api.create_resource("mytype", "myname", {:foo => "bar"})
+ end
- @api.mytype("myname", :foo => "bar")
- end
+ it "should set each provided argument as a parameter on the created resource" do
+ result = @api.create_resource("mytype", "myname", {"foo" => "bar", "biz" => "baz"}).shift
+ result["foo"].should == "bar"
+ result["biz"].should == "baz"
+ end
- it "should call any function whose name matches the undefined method if the name is not a valid type" do
- @api.expects(:valid_type?).with(:myfunc).returns false
- @api.expects(:create_resource).never
+ it "should add the resource to the scope's copmiler" do
+ Puppet::Parser::Resource.expects(:new).returns @created_resource
+ @api.scope.compiler.expects(:add_resource).with(@api.scope, @created_resource)
+ @api.create_resource("mytype", "myname", {:foo => "bar"})
+ end
- Puppet::Parser::Functions.expects(:function).with(:myfunc).returns true
+ it "should fail if the resource parameters are not a hash" do
+ lambda { @api.create_resource("mytype", "myname", %w{foo bar}) }.should raise_error(ArgumentError)
+ end
+ end
- @api.expects(:call_function).with(:myfunc, %w{foo bar})
+ describe "when an unknown method is called" do
+ it "should create a resource if the method name is a valid type" do
+ @api.expects(:valid_type?).with(:mytype).returns true
+ @api.expects(:create_resource).with(:mytype, "myname", {:foo => "bar"}).returns true
- @api.myfunc("foo", "bar")
- end
+ @api.mytype("myname", :foo => "bar")
+ end
- it "should raise a method missing error if the method is neither a type nor a function" do
- @api.expects(:valid_type?).with(:myfunc).returns false
- @api.expects(:create_resource).never
+ it "should call any function whose name matches the undefined method if the name is not a valid type" do
+ @api.expects(:valid_type?).with(:myfunc).returns false
+ @api.expects(:create_resource).never
- Puppet::Parser::Functions.expects(:function).with(:myfunc).returns false
+ Puppet::Parser::Functions.expects(:function).with(:myfunc).returns true
- @api.expects(:call_function).never
+ @api.expects(:call_function).with(:myfunc, %w{foo bar})
- lambda { @api.myfunc("foo", "bar") }.should raise_error(NoMethodError)
- end
+ @api.myfunc("foo", "bar")
end
- it "should mark the specified resource as exported when creating a single exported resource" do
- resources = @api.export @api.file("/my/file", :ensure => :present)
- resources[0].should be_exported
- end
+ it "should raise a method missing error if the method is neither a type nor a function" do
+ @api.expects(:valid_type?).with(:myfunc).returns false
+ @api.expects(:create_resource).never
- it "should mark all created resources as exported when creating exported resources using a block" do
- @compiler.expects(:add_resource).with { |s, res| res.exported == true }
- @api.export { file "/my/file", :ensure => :present }
- end
+ Puppet::Parser::Functions.expects(:function).with(:myfunc).returns false
- it "should mark the specified resource as virtual when creating a single virtual resource" do
- resources = @api.virtual @api.file("/my/file", :ensure => :present)
- resources[0].should be_virtual
- end
+ @api.expects(:call_function).never
- it "should mark all created resources as virtual when creating virtual resources using a block" do
- @compiler.expects(:add_resource).with { |s, res| res.virtual == true }
- @api.virtual { file "/my/file", :ensure => :present }
+ lambda { @api.myfunc("foo", "bar") }.should raise_error(NoMethodError)
end
+ end
+
+ it "should mark the specified resource as exported when creating a single exported resource" do
+ resources = @api.export @api.file("/my/file", :ensure => :present)
+ resources[0].should be_exported
+ end
+
+ it "should mark all created resources as exported when creating exported resources using a block" do
+ @compiler.expects(:add_resource).with { |s, res| res.exported == true }
+ @api.export { file "/my/file", :ensure => :present }
+ end
+
+ it "should mark the specified resource as virtual when creating a single virtual resource" do
+ resources = @api.virtual @api.file("/my/file", :ensure => :present)
+ resources[0].should be_virtual
+ end
+
+ it "should mark all created resources as virtual when creating virtual resources using a block" do
+ @compiler.expects(:add_resource).with { |s, res| res.virtual == true }
+ @api.virtual { file "/my/file", :ensure => :present }
+ end
end
diff --git a/spec/unit/dsl/resource_type_api_spec.rb b/spec/unit/dsl/resource_type_api_spec.rb
index e9b52ee..5abe79e 100755
--- a/spec/unit/dsl/resource_type_api_spec.rb
+++ b/spec/unit/dsl/resource_type_api_spec.rb
@@ -5,42 +5,42 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/dsl/resource_type_api'
class DSLAPITester
- include Puppet::DSL::ResourceTypeAPI
+ include Puppet::DSL::ResourceTypeAPI
end
describe Puppet::DSL::ResourceTypeAPI do
- before do
- @api = DSLAPITester.new
+ before do
+ @api = DSLAPITester.new
+ end
+
+ [:definition, :node, :hostclass].each do |type|
+ method = type == :definition ? "define" : type
+ it "should be able to create a #{type}" do
+ newtype = Puppet::Resource::Type.new(:hostclass, "foo")
+ Puppet::Resource::Type.expects(:new).with { |t, n, args| t == type }.returns newtype
+ @api.send(method, "myname")
end
- [:definition, :node, :hostclass].each do |type|
- method = type == :definition ? "define" : type
- it "should be able to create a #{type}" do
- newtype = Puppet::Resource::Type.new(:hostclass, "foo")
- Puppet::Resource::Type.expects(:new).with { |t, n, args| t == type }.returns newtype
- @api.send(method, "myname")
- end
-
- it "should use the provided name when creating a #{type}" do
- type = Puppet::Resource::Type.new(:hostclass, "foo")
- Puppet::Resource::Type.expects(:new).with { |t, n, args| n == "myname" }.returns type
- @api.send(method, "myname")
- end
-
- unless type == :definition
- it "should pass in any provided options" do
- type = Puppet::Resource::Type.new(:hostclass, "foo")
- Puppet::Resource::Type.expects(:new).with { |t, n, args| args == {:myarg => :myvalue} }.returns type
- @api.send(method, "myname", :myarg => :myvalue)
- end
- end
-
- it "should set any provided block as the type's ruby code"
-
- it "should add the type to the current environment's known resource types"
+ it "should use the provided name when creating a #{type}" do
+ type = Puppet::Resource::Type.new(:hostclass, "foo")
+ Puppet::Resource::Type.expects(:new).with { |t, n, args| n == "myname" }.returns type
+ @api.send(method, "myname")
end
- describe "when creating a definition" do
- it "should use the provided options to define valid arguments for the resource type"
+ unless type == :definition
+ it "should pass in any provided options" do
+ type = Puppet::Resource::Type.new(:hostclass, "foo")
+ Puppet::Resource::Type.expects(:new).with { |t, n, args| args == {:myarg => :myvalue} }.returns type
+ @api.send(method, "myname", :myarg => :myvalue)
+ end
end
+
+ it "should set any provided block as the type's ruby code"
+
+ it "should add the type to the current environment's known resource types"
+ end
+
+ describe "when creating a definition" do
+ it "should use the provided options to define valid arguments for the resource type"
+ end
end
diff --git a/spec/unit/file_bucket/dipper_spec.rb b/spec/unit/file_bucket/dipper_spec.rb
index 08ca79c..799e899 100755
--- a/spec/unit/file_bucket/dipper_spec.rb
+++ b/spec/unit/file_bucket/dipper_spec.rb
@@ -4,119 +4,119 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/file_bucket/dipper'
describe Puppet::FileBucket::Dipper do
- before do
- ['/my/file'].each do |x|
- Puppet::FileBucket::Dipper.any_instance.stubs(:absolutize_path).with(x).returns(x)
- end
+ before do
+ ['/my/file'].each do |x|
+ Puppet::FileBucket::Dipper.any_instance.stubs(:absolutize_path).with(x).returns(x)
end
+ end
- it "should fail in an informative way when there are failures backing up to the server" do
- File.stubs(:exist?).returns true
- File.stubs(:read).returns "content"
+ it "should fail in an informative way when there are failures backing up to the server" do
+ File.stubs(:exist?).returns true
+ File.stubs(:read).returns "content"
- @dipper = Puppet::FileBucket::Dipper.new(:Path => "/my/bucket")
+ @dipper = Puppet::FileBucket::Dipper.new(:Path => "/my/bucket")
- filemock = stub "bucketfile"
- Puppet::FileBucket::File.stubs(:new).returns(filemock)
- filemock.expects(:name).returns "name"
- filemock.expects(:save).raises ArgumentError
+ filemock = stub "bucketfile"
+ Puppet::FileBucket::File.stubs(:new).returns(filemock)
+ filemock.expects(:name).returns "name"
+ filemock.expects(:save).raises ArgumentError
- lambda { @dipper.backup("/my/file") }.should raise_error(Puppet::Error)
- end
+ lambda { @dipper.backup("/my/file") }.should raise_error(Puppet::Error)
+ end
- it "should backup files to a local bucket" do
- @dipper = Puppet::FileBucket::Dipper.new(
- :Path => "/my/bucket"
- )
+ it "should backup files to a local bucket" do
+ @dipper = Puppet::FileBucket::Dipper.new(
+ :Path => "/my/bucket"
+ )
- File.stubs(:exist?).returns true
- File.stubs(:read).with("/my/file").returns "my contents"
+ File.stubs(:exist?).returns true
+ File.stubs(:read).with("/my/file").returns "my contents"
- bucketfile = stub "bucketfile"
- bucketfile.stubs(:name).returns('md5/DIGEST123')
- bucketfile.stubs(:checksum_data).returns("DIGEST123")
- bucketfile.expects(:save).with('md5/DIGEST123')
+ bucketfile = stub "bucketfile"
+ bucketfile.stubs(:name).returns('md5/DIGEST123')
+ bucketfile.stubs(:checksum_data).returns("DIGEST123")
+ bucketfile.expects(:save).with('md5/DIGEST123')
- Puppet::FileBucket::File.stubs(:new).with(
+ Puppet::FileBucket::File.stubs(:new).with(
- "my contents",
- :bucket_path => '/my/bucket',
+ "my contents",
+ :bucket_path => '/my/bucket',
- :path => '/my/file'
- ).returns(bucketfile)
+ :path => '/my/file'
+ ).returns(bucketfile)
- @dipper.backup("/my/file").should == "DIGEST123"
- end
+ @dipper.backup("/my/file").should == "DIGEST123"
+ end
- it "should retrieve files from a local bucket" do
- @dipper = Puppet::FileBucket::Dipper.new(
- :Path => "/my/bucket"
- )
+ it "should retrieve files from a local bucket" do
+ @dipper = Puppet::FileBucket::Dipper.new(
+ :Path => "/my/bucket"
+ )
- File.stubs(:exist?).returns true
- File.stubs(:read).with("/my/file").returns "my contents"
+ File.stubs(:exist?).returns true
+ File.stubs(:read).with("/my/file").returns "my contents"
- bucketfile = stub "bucketfile"
- bucketfile.stubs(:to_s).returns "Content"
+ bucketfile = stub "bucketfile"
+ bucketfile.stubs(:to_s).returns "Content"
- Puppet::FileBucket::File.expects(:find).with{|x,opts|
- x == 'md5/DIGEST123'
- }.returns(bucketfile)
+ Puppet::FileBucket::File.expects(:find).with{|x,opts|
+ x == 'md5/DIGEST123'
+ }.returns(bucketfile)
- @dipper.getfile("DIGEST123").should == "Content"
- end
+ @dipper.getfile("DIGEST123").should == "Content"
+ end
- it "should backup files to a remote server" do
+ it "should backup files to a remote server" do
- @dipper = Puppet::FileBucket::Dipper.new(
+ @dipper = Puppet::FileBucket::Dipper.new(
- :Server => "puppetmaster",
+ :Server => "puppetmaster",
- :Port => "31337"
- )
+ :Port => "31337"
+ )
- File.stubs(:exist?).returns true
- File.stubs(:read).with("/my/file").returns "my contents"
+ File.stubs(:exist?).returns true
+ File.stubs(:read).with("/my/file").returns "my contents"
- bucketfile = stub "bucketfile"
- bucketfile.stubs(:name).returns('md5/DIGEST123')
- bucketfile.stubs(:checksum_data).returns("DIGEST123")
- bucketfile.expects(:save).with('https://puppetmaster:31337/production/file_bucket_file/md5/DIGEST123')
+ bucketfile = stub "bucketfile"
+ bucketfile.stubs(:name).returns('md5/DIGEST123')
+ bucketfile.stubs(:checksum_data).returns("DIGEST123")
+ bucketfile.expects(:save).with('https://puppetmaster:31337/production/file_bucket_file/md5/DIGEST123')
- Puppet::FileBucket::File.stubs(:new).with(
+ Puppet::FileBucket::File.stubs(:new).with(
- "my contents",
- :bucket_path => nil,
+ "my contents",
+ :bucket_path => nil,
- :path => '/my/file'
- ).returns(bucketfile)
+ :path => '/my/file'
+ ).returns(bucketfile)
- @dipper.backup("/my/file").should == "DIGEST123"
- end
+ @dipper.backup("/my/file").should == "DIGEST123"
+ end
- it "should retrieve files from a remote server" do
+ it "should retrieve files from a remote server" do
- @dipper = Puppet::FileBucket::Dipper.new(
+ @dipper = Puppet::FileBucket::Dipper.new(
- :Server => "puppetmaster",
+ :Server => "puppetmaster",
- :Port => "31337"
- )
+ :Port => "31337"
+ )
- File.stubs(:exist?).returns true
- File.stubs(:read).with("/my/file").returns "my contents"
+ File.stubs(:exist?).returns true
+ File.stubs(:read).with("/my/file").returns "my contents"
- bucketfile = stub "bucketfile"
- bucketfile.stubs(:to_s).returns "Content"
+ bucketfile = stub "bucketfile"
+ bucketfile.stubs(:to_s).returns "Content"
- Puppet::FileBucket::File.expects(:find).with{|x,opts|
- x == 'https://puppetmaster:31337/production/file_bucket_file/md5/DIGEST123'
- }.returns(bucketfile)
+ Puppet::FileBucket::File.expects(:find).with{|x,opts|
+ x == 'https://puppetmaster:31337/production/file_bucket_file/md5/DIGEST123'
+ }.returns(bucketfile)
- @dipper.getfile("DIGEST123").should == "Content"
- end
+ @dipper.getfile("DIGEST123").should == "Content"
+ end
end
diff --git a/spec/unit/file_bucket/file_spec.rb b/spec/unit/file_bucket/file_spec.rb
index 7358765..3ad70c2 100644
--- a/spec/unit/file_bucket/file_spec.rb
+++ b/spec/unit/file_bucket/file_spec.rb
@@ -7,224 +7,224 @@ require 'digest/md5'
require 'digest/sha1'
describe Puppet::FileBucket::File do
- before do
- # this is the default from spec_helper, but it keeps getting reset at odd times
- Puppet[:bucketdir] = "/dev/null/bucket"
+ before do
+ # this is the default from spec_helper, but it keeps getting reset at odd times
+ Puppet[:bucketdir] = "/dev/null/bucket"
- @digest = "4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
- @checksum = "{md5}4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
- @dir = '/dev/null/bucket/4/a/8/e/c/4/f/a/4a8ec4fa5f01b4ab1a0ab8cbccb709f0'
+ @digest = "4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
+ @checksum = "{md5}4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
+ @dir = '/dev/null/bucket/4/a/8/e/c/4/f/a/4a8ec4fa5f01b4ab1a0ab8cbccb709f0'
- @contents = "file contents"
- end
+ @contents = "file contents"
+ end
- it "should have a to_s method to return the contents" do
- Puppet::FileBucket::File.new(@contents).to_s.should == @contents
- end
+ it "should have a to_s method to return the contents" do
+ Puppet::FileBucket::File.new(@contents).to_s.should == @contents
+ end
- it "should calculate the checksum type from the passed in checksum" do
- Puppet::FileBucket::File.new(@contents, :checksum => @checksum).checksum_type.should == "md5"
- end
+ it "should calculate the checksum type from the passed in checksum" do
+ Puppet::FileBucket::File.new(@contents, :checksum => @checksum).checksum_type.should == "md5"
+ end
- it "should allow contents to be specified in a block" do
- bucket = Puppet::FileBucket::File.new(nil) do |fb|
- fb.contents = "content"
- end
- bucket.contents.should == "content"
+ it "should allow contents to be specified in a block" do
+ bucket = Puppet::FileBucket::File.new(nil) do |fb|
+ fb.contents = "content"
end
+ bucket.contents.should == "content"
+ end
- it "should raise an error if changing content" do
- x = Puppet::FileBucket::File.new("first")
- proc { x.contents = "new" }.should raise_error
- end
+ it "should raise an error if changing content" do
+ x = Puppet::FileBucket::File.new("first")
+ proc { x.contents = "new" }.should raise_error
+ end
- it "should require contents to be a string" do
- proc { Puppet::FileBucket::File.new(5) }.should raise_error(ArgumentError)
- end
+ it "should require contents to be a string" do
+ proc { Puppet::FileBucket::File.new(5) }.should raise_error(ArgumentError)
+ end
- it "should raise an error if setting contents to a non-string" do
- proc do
- Puppet::FileBucket::File.new(nil) do |x|
- x.contents = 5
- end
- end.should raise_error(ArgumentError)
- end
+ it "should raise an error if setting contents to a non-string" do
+ proc do
+ Puppet::FileBucket::File.new(nil) do |x|
+ x.contents = 5
+ end
+ end.should raise_error(ArgumentError)
+ end
- it "should set the contents appropriately" do
- Puppet::FileBucket::File.new(@contents).contents.should == @contents
- end
+ it "should set the contents appropriately" do
+ Puppet::FileBucket::File.new(@contents).contents.should == @contents
+ end
- it "should default to 'md5' as the checksum algorithm if the algorithm is not in the name" do
- Puppet::FileBucket::File.new(@contents).checksum_type.should == "md5"
- end
+ it "should default to 'md5' as the checksum algorithm if the algorithm is not in the name" do
+ Puppet::FileBucket::File.new(@contents).checksum_type.should == "md5"
+ end
- it "should calculate the checksum" do
- Puppet::FileBucket::File.new(@contents).checksum.should == @checksum
- end
+ it "should calculate the checksum" do
+ Puppet::FileBucket::File.new(@contents).checksum.should == @checksum
+ end
- it "should remove the old checksum value if the algorithm is changed" do
- sum = Puppet::FileBucket::File.new(@contents)
- sum.checksum.should_not be_nil
+ it "should remove the old checksum value if the algorithm is changed" do
+ sum = Puppet::FileBucket::File.new(@contents)
+ sum.checksum.should_not be_nil
- newsum = Digest::SHA1.hexdigest(@contents).to_s
- sum.checksum_type = :sha1
- sum.checksum.should == "{sha1}#{newsum}"
- end
+ newsum = Digest::SHA1.hexdigest(@contents).to_s
+ sum.checksum_type = :sha1
+ sum.checksum.should == "{sha1}#{newsum}"
+ end
- it "should support specifying the checksum_type during initialization" do
- sum = Puppet::FileBucket::File.new(@contents, :checksum_type => :sha1)
- sum.checksum_type.should == :sha1
- end
+ it "should support specifying the checksum_type during initialization" do
+ sum = Puppet::FileBucket::File.new(@contents, :checksum_type => :sha1)
+ sum.checksum_type.should == :sha1
+ end
- it "should fail when an unsupported checksum_type is used" do
- proc { Puppet::FileBucket::File.new(@contents, :checksum_type => :nope) }.should raise_error(ArgumentError)
- end
+ it "should fail when an unsupported checksum_type is used" do
+ proc { Puppet::FileBucket::File.new(@contents, :checksum_type => :nope) }.should raise_error(ArgumentError)
+ end
- it "should fail if given an checksum at initialization that does not match the contents" do
- proc { Puppet::FileBucket::File.new(@contents, :checksum => "{md5}00000000000000000000000000000000") }.should raise_error(RuntimeError)
- end
+ it "should fail if given an checksum at initialization that does not match the contents" do
+ proc { Puppet::FileBucket::File.new(@contents, :checksum => "{md5}00000000000000000000000000000000") }.should raise_error(RuntimeError)
+ end
- it "should fail if assigned a checksum that does not match the contents" do
- bucket = Puppet::FileBucket::File.new(@contents)
- proc { bucket.checksum = "{md5}00000000000000000000000000000000" }.should raise_error(RuntimeError)
- end
+ it "should fail if assigned a checksum that does not match the contents" do
+ bucket = Puppet::FileBucket::File.new(@contents)
+ proc { bucket.checksum = "{md5}00000000000000000000000000000000" }.should raise_error(RuntimeError)
+ end
- describe "when using back-ends" do
- it "should redirect using Puppet::Indirector" do
- Puppet::Indirector::Indirection.instance(:file_bucket_file).model.should equal(Puppet::FileBucket::File)
- end
+ describe "when using back-ends" do
+ it "should redirect using Puppet::Indirector" do
+ Puppet::Indirector::Indirection.instance(:file_bucket_file).model.should equal(Puppet::FileBucket::File)
+ end
- it "should have a :save instance method" do
- Puppet::FileBucket::File.new("mysum").should respond_to(:save)
- end
+ it "should have a :save instance method" do
+ Puppet::FileBucket::File.new("mysum").should respond_to(:save)
+ end
- it "should respond to :find" do
- Puppet::FileBucket::File.should respond_to(:find)
- end
+ it "should respond to :find" do
+ Puppet::FileBucket::File.should respond_to(:find)
+ end
- it "should respond to :destroy" do
- Puppet::FileBucket::File.should respond_to(:destroy)
- end
+ it "should respond to :destroy" do
+ Puppet::FileBucket::File.should respond_to(:destroy)
end
+ end
- describe "when saving files" do
- it "should save the contents to the calculated path" do
- ::File.stubs(:directory?).with(@dir).returns(true)
- ::File.expects(:exist?).with("#{@dir}/contents").returns false
+ describe "when saving files" do
+ it "should save the contents to the calculated path" do
+ ::File.stubs(:directory?).with(@dir).returns(true)
+ ::File.expects(:exist?).with("#{@dir}/contents").returns false
- mockfile = mock "file"
- mockfile.expects(:print).with(@contents)
- ::File.expects(:open).with("#{@dir}/contents", ::File::WRONLY|::File::CREAT, 0440).yields(mockfile)
+ mockfile = mock "file"
+ mockfile.expects(:print).with(@contents)
+ ::File.expects(:open).with("#{@dir}/contents", ::File::WRONLY|::File::CREAT, 0440).yields(mockfile)
- Puppet::FileBucket::File.new(@contents).save
- end
+ Puppet::FileBucket::File.new(@contents).save
+ end
- it "should make any directories necessary for storage" do
- FileUtils.expects(:mkdir_p).with do |arg|
- ::File.umask == 0007 and arg == @dir
- end
- ::File.expects(:directory?).with(@dir).returns(false)
- ::File.expects(:open).with("#{@dir}/contents", ::File::WRONLY|::File::CREAT, 0440)
- ::File.expects(:exist?).with("#{@dir}/contents").returns false
+ it "should make any directories necessary for storage" do
+ FileUtils.expects(:mkdir_p).with do |arg|
+ ::File.umask == 0007 and arg == @dir
+ end
+ ::File.expects(:directory?).with(@dir).returns(false)
+ ::File.expects(:open).with("#{@dir}/contents", ::File::WRONLY|::File::CREAT, 0440)
+ ::File.expects(:exist?).with("#{@dir}/contents").returns false
- Puppet::FileBucket::File.new(@contents).save
- end
+ Puppet::FileBucket::File.new(@contents).save
+ end
- it "should append the path to the paths file" do
- remote_path = '/path/on/the/remote/box'
+ it "should append the path to the paths file" do
+ remote_path = '/path/on/the/remote/box'
- ::File.expects(:directory?).with(@dir).returns(true)
- ::File.expects(:open).with("#{@dir}/contents", ::File::WRONLY|::File::CREAT, 0440)
- ::File.expects(:exist?).with("#{@dir}/contents").returns false
+ ::File.expects(:directory?).with(@dir).returns(true)
+ ::File.expects(:open).with("#{@dir}/contents", ::File::WRONLY|::File::CREAT, 0440)
+ ::File.expects(:exist?).with("#{@dir}/contents").returns false
- mockfile = mock "file"
- mockfile.expects(:puts).with('/path/on/the/remote/box')
- ::File.expects(:exist?).with("#{@dir}/paths").returns false
- ::File.expects(:open).with("#{@dir}/paths", ::File::WRONLY|::File::CREAT|::File::APPEND).yields mockfile
- Puppet::FileBucket::File.new(@contents, :path => remote_path).save
+ mockfile = mock "file"
+ mockfile.expects(:puts).with('/path/on/the/remote/box')
+ ::File.expects(:exist?).with("#{@dir}/paths").returns false
+ ::File.expects(:open).with("#{@dir}/paths", ::File::WRONLY|::File::CREAT|::File::APPEND).yields mockfile
+ Puppet::FileBucket::File.new(@contents, :path => remote_path).save
- end
end
+ end
- it "should accept a path" do
- remote_path = '/path/on/the/remote/box'
- Puppet::FileBucket::File.new(@contents, :path => remote_path).path.should == remote_path
- end
+ it "should accept a path" do
+ remote_path = '/path/on/the/remote/box'
+ Puppet::FileBucket::File.new(@contents, :path => remote_path).path.should == remote_path
+ end
- it "should return a url-ish name" do
- Puppet::FileBucket::File.new(@contents).name.should == "md5/4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
- end
+ it "should return a url-ish name" do
+ Puppet::FileBucket::File.new(@contents).name.should == "md5/4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
+ end
- it "should reject a url-ish name with an invalid checksum" do
- bucket = Puppet::FileBucket::File.new(@contents)
- lambda { bucket.name = "sha1/4a8ec4fa5f01b4ab1a0ab8cbccb709f0/new/path" }.should raise_error
- end
+ it "should reject a url-ish name with an invalid checksum" do
+ bucket = Puppet::FileBucket::File.new(@contents)
+ lambda { bucket.name = "sha1/4a8ec4fa5f01b4ab1a0ab8cbccb709f0/new/path" }.should raise_error
+ end
- it "should accept a url-ish name" do
- bucket = Puppet::FileBucket::File.new(@contents)
- lambda { bucket.name = "sha1/034fa2ed8e211e4d20f20e792d777f4a30af1a93/new/path" }.should_not raise_error
- bucket.checksum_type.should == "sha1"
- bucket.checksum_data.should == '034fa2ed8e211e4d20f20e792d777f4a30af1a93'
- bucket.path.should == "new/path"
- end
+ it "should accept a url-ish name" do
+ bucket = Puppet::FileBucket::File.new(@contents)
+ lambda { bucket.name = "sha1/034fa2ed8e211e4d20f20e792d777f4a30af1a93/new/path" }.should_not raise_error
+ bucket.checksum_type.should == "sha1"
+ bucket.checksum_data.should == '034fa2ed8e211e4d20f20e792d777f4a30af1a93'
+ bucket.path.should == "new/path"
+ end
- it "should return a url-ish name with a path" do
- Puppet::FileBucket::File.new(@contents, :path => 'my/path').name.should == "md5/4a8ec4fa5f01b4ab1a0ab8cbccb709f0/my/path"
- end
+ it "should return a url-ish name with a path" do
+ Puppet::FileBucket::File.new(@contents, :path => 'my/path').name.should == "md5/4a8ec4fa5f01b4ab1a0ab8cbccb709f0/my/path"
+ end
- it "should convert the contents to PSON" do
- Puppet::FileBucket::File.new(@contents).to_pson.should == '{"contents":"file contents"}'
- end
+ it "should convert the contents to PSON" do
+ Puppet::FileBucket::File.new(@contents).to_pson.should == '{"contents":"file contents"}'
+ end
- it "should load from PSON" do
- Puppet::FileBucket::File.from_pson({"contents"=>"file contents"}).contents.should == "file contents"
- end
+ it "should load from PSON" do
+ Puppet::FileBucket::File.from_pson({"contents"=>"file contents"}).contents.should == "file contents"
+ end
- it "should save a file" do
- ::File.expects(:exist?).with("#{@dir}/contents").returns false
- ::File.expects(:directory?).with(@dir).returns false
- ::FileUtils.expects(:mkdir_p).with(@dir)
- ::File.expects(:open).with("#{@dir}/contents", ::File::WRONLY|::File::CREAT, 0440)
+ it "should save a file" do
+ ::File.expects(:exist?).with("#{@dir}/contents").returns false
+ ::File.expects(:directory?).with(@dir).returns false
+ ::FileUtils.expects(:mkdir_p).with(@dir)
+ ::File.expects(:open).with("#{@dir}/contents", ::File::WRONLY|::File::CREAT, 0440)
- bucketfile = Puppet::FileBucket::File.new(@contents)
- bucketfile.save
+ bucketfile = Puppet::FileBucket::File.new(@contents)
+ bucketfile.save
- end
+ end
- describe "using the indirector's find method" do
- it "should return nil if a file doesn't exist" do
- ::File.expects(:exist?).with("#{@dir}/contents").returns false
+ describe "using the indirector's find method" do
+ it "should return nil if a file doesn't exist" do
+ ::File.expects(:exist?).with("#{@dir}/contents").returns false
- bucketfile = Puppet::FileBucket::File.find("{md5}#{@digest}")
- bucketfile.should == nil
- end
+ bucketfile = Puppet::FileBucket::File.find("{md5}#{@digest}")
+ bucketfile.should == nil
+ end
- it "should find a filebucket if the file exists" do
- ::File.expects(:exist?).with("#{@dir}/contents").returns true
- ::File.expects(:exist?).with("#{@dir}/paths").returns false
- ::File.expects(:read).with("#{@dir}/contents").returns @contents
+ it "should find a filebucket if the file exists" do
+ ::File.expects(:exist?).with("#{@dir}/contents").returns true
+ ::File.expects(:exist?).with("#{@dir}/paths").returns false
+ ::File.expects(:read).with("#{@dir}/contents").returns @contents
- bucketfile = Puppet::FileBucket::File.find("{md5}#{@digest}")
- bucketfile.should_not == nil
- end
+ bucketfile = Puppet::FileBucket::File.find("{md5}#{@digest}")
+ bucketfile.should_not == nil
+ end
- describe "using RESTish digest notation" do
- it "should return nil if a file doesn't exist" do
- ::File.expects(:exist?).with("#{@dir}/contents").returns false
+ describe "using RESTish digest notation" do
+ it "should return nil if a file doesn't exist" do
+ ::File.expects(:exist?).with("#{@dir}/contents").returns false
- bucketfile = Puppet::FileBucket::File.find("md5/#{@digest}")
- bucketfile.should == nil
- end
+ bucketfile = Puppet::FileBucket::File.find("md5/#{@digest}")
+ bucketfile.should == nil
+ end
- it "should find a filebucket if the file exists" do
- ::File.expects(:exist?).with("#{@dir}/contents").returns true
- ::File.expects(:exist?).with("#{@dir}/paths").returns false
- ::File.expects(:read).with("#{@dir}/contents").returns @contents
+ it "should find a filebucket if the file exists" do
+ ::File.expects(:exist?).with("#{@dir}/contents").returns true
+ ::File.expects(:exist?).with("#{@dir}/paths").returns false
+ ::File.expects(:read).with("#{@dir}/contents").returns @contents
- bucketfile = Puppet::FileBucket::File.find("md5/#{@digest}")
- bucketfile.should_not == nil
- end
+ bucketfile = Puppet::FileBucket::File.find("md5/#{@digest}")
+ bucketfile.should_not == nil
+ end
- end
end
+ end
end
diff --git a/spec/unit/file_collection/lookup_spec.rb b/spec/unit/file_collection/lookup_spec.rb
index 81cc618..2454cc8 100755
--- a/spec/unit/file_collection/lookup_spec.rb
+++ b/spec/unit/file_collection/lookup_spec.rb
@@ -4,43 +4,43 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/file_collection/lookup'
class LookupTester
- include Puppet::FileCollection::Lookup
+ include Puppet::FileCollection::Lookup
end
describe Puppet::FileCollection::Lookup do
- before do
- @tester = LookupTester.new
+ before do
+ @tester = LookupTester.new
- @file_collection = mock 'file_collection'
- Puppet::FileCollection.stubs(:collection).returns @file_collection
- end
+ @file_collection = mock 'file_collection'
+ Puppet::FileCollection.stubs(:collection).returns @file_collection
+ end
- it "should use the file collection to determine the index of the file name" do
- @file_collection.expects(:index).with("/my/file").returns 50
+ it "should use the file collection to determine the index of the file name" do
+ @file_collection.expects(:index).with("/my/file").returns 50
- @tester.file = "/my/file"
- @tester.file_index.should == 50
- end
+ @tester.file = "/my/file"
+ @tester.file_index.should == 50
+ end
- it "should return nil as the file name if no index is set" do
- @tester.file.should be_nil
- end
+ it "should return nil as the file name if no index is set" do
+ @tester.file.should be_nil
+ end
- it "should use the file collection to convert the index to a file name" do
- @file_collection.expects(:path).with(25).returns "/path/to/file"
+ it "should use the file collection to convert the index to a file name" do
+ @file_collection.expects(:path).with(25).returns "/path/to/file"
- @tester.file_index = 25
+ @tester.file_index = 25
- @tester.file.should == "/path/to/file"
- end
+ @tester.file.should == "/path/to/file"
+ end
- it "should support a line attribute" do
- @tester.line = 50
- @tester.line.should == 50
- end
+ it "should support a line attribute" do
+ @tester.line = 50
+ @tester.line.should == 50
+ end
- it "should default to the global file collection" do
- Puppet::FileCollection.expects(:collection).returns "collection"
- @tester.file_collection.should == "collection"
- end
+ it "should default to the global file collection" do
+ Puppet::FileCollection.expects(:collection).returns "collection"
+ @tester.file_collection.should == "collection"
+ end
end
diff --git a/spec/unit/file_collection_spec.rb b/spec/unit/file_collection_spec.rb
index 5e8e2ec..08621cc 100755
--- a/spec/unit/file_collection_spec.rb
+++ b/spec/unit/file_collection_spec.rb
@@ -5,49 +5,49 @@ require File.dirname(__FILE__) + '/../spec_helper'
require 'puppet/file_collection'
describe Puppet::FileCollection do
- before do
- @collection = Puppet::FileCollection.new
- end
+ before do
+ @collection = Puppet::FileCollection.new
+ end
- it "should be able to convert a file name into an index" do
- @collection.index("/my/file").should be_instance_of(Fixnum)
- end
+ it "should be able to convert a file name into an index" do
+ @collection.index("/my/file").should be_instance_of(Fixnum)
+ end
- it "should be able to convert an index into a file name" do
- index = @collection.index("/path/to/file")
- @collection.path(index).should == "/path/to/file"
- end
+ it "should be able to convert an index into a file name" do
+ index = @collection.index("/path/to/file")
+ @collection.path(index).should == "/path/to/file"
+ end
- it "should always give the same file name for a given index" do
- index = @collection.index("/path/to/file")
- @collection.path(index).should == @collection.path(index)
- end
+ it "should always give the same file name for a given index" do
+ index = @collection.index("/path/to/file")
+ @collection.path(index).should == @collection.path(index)
+ end
- it "should always give the same index for a given file name" do
- @collection.index("/my/file").should == @collection.index("/my/file")
- end
+ it "should always give the same index for a given file name" do
+ @collection.index("/my/file").should == @collection.index("/my/file")
+ end
- it "should always correctly relate a file name and its index even when multiple files are in the collection" do
- indexes = %w{a b c d e f}.inject({}) do |hash, letter|
- hash[letter] = @collection.index("/path/to/file/#{letter}")
- hash
- end
-
- indexes.each do |letter, index|
- @collection.index("/path/to/file/#{letter}").should == indexes[letter]
- @collection.path(index).should == @collection.path(index)
- end
+ it "should always correctly relate a file name and its index even when multiple files are in the collection" do
+ indexes = %w{a b c d e f}.inject({}) do |hash, letter|
+ hash[letter] = @collection.index("/path/to/file/#{letter}")
+ hash
end
- it "should return nil as the file name when an unknown index is provided" do
- @collection.path(50).should be_nil
+ indexes.each do |letter, index|
+ @collection.index("/path/to/file/#{letter}").should == indexes[letter]
+ @collection.path(index).should == @collection.path(index)
end
+ end
- it "should provide a global collection" do
- Puppet::FileCollection.collection.should be_instance_of(Puppet::FileCollection)
- end
+ it "should return nil as the file name when an unknown index is provided" do
+ @collection.path(50).should be_nil
+ end
- it "should reuse the global collection" do
- Puppet::FileCollection.collection.should equal(Puppet::FileCollection.collection)
- end
+ it "should provide a global collection" do
+ Puppet::FileCollection.collection.should be_instance_of(Puppet::FileCollection)
+ end
+
+ it "should reuse the global collection" do
+ Puppet::FileCollection.collection.should equal(Puppet::FileCollection.collection)
+ end
end
diff --git a/spec/unit/file_serving/base_spec.rb b/spec/unit/file_serving/base_spec.rb
index de7ea47..b939bca 100755
--- a/spec/unit/file_serving/base_spec.rb
+++ b/spec/unit/file_serving/base_spec.rb
@@ -5,128 +5,128 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/file_serving/base'
describe Puppet::FileServing::Base do
- it "should accept a path" do
- Puppet::FileServing::Base.new("/module/dir/file").path.should == "/module/dir/file"
- end
+ it "should accept a path" do
+ Puppet::FileServing::Base.new("/module/dir/file").path.should == "/module/dir/file"
+ end
- it "should require that paths be fully qualified" do
- lambda { Puppet::FileServing::Base.new("module/dir/file") }.should raise_error(ArgumentError)
- end
+ it "should require that paths be fully qualified" do
+ lambda { Puppet::FileServing::Base.new("module/dir/file") }.should raise_error(ArgumentError)
+ end
- it "should allow specification of whether links should be managed" do
- Puppet::FileServing::Base.new("/module/dir/file", :links => :manage).links.should == :manage
- end
+ it "should allow specification of whether links should be managed" do
+ Puppet::FileServing::Base.new("/module/dir/file", :links => :manage).links.should == :manage
+ end
- it "should have a :source attribute" do
- file = Puppet::FileServing::Base.new("/module/dir/file")
- file.should respond_to(:source)
- file.should respond_to(:source=)
- end
+ it "should have a :source attribute" do
+ file = Puppet::FileServing::Base.new("/module/dir/file")
+ file.should respond_to(:source)
+ file.should respond_to(:source=)
+ end
+
+ it "should consider :ignore links equivalent to :manage links" do
+ Puppet::FileServing::Base.new("/module/dir/file", :links => :ignore).links.should == :manage
+ end
+
+ it "should fail if :links is set to anything other than :manage, :follow, or :ignore" do
+ proc { Puppet::FileServing::Base.new("/module/dir/file", :links => :else) }.should raise_error(ArgumentError)
+ end
+
+ it "should allow links values to be set as strings" do
+ Puppet::FileServing::Base.new("/module/dir/file", :links => "follow").links.should == :follow
+ end
+
+ it "should default to :manage for :links" do
+ Puppet::FileServing::Base.new("/module/dir/file").links.should == :manage
+ end
+
+ it "should allow specification of a path" do
+ FileTest.stubs(:exists?).returns(true)
+ Puppet::FileServing::Base.new("/module/dir/file", :path => "/my/file").path.should == "/my/file"
+ end
+
+ it "should allow specification of a relative path" do
+ FileTest.stubs(:exists?).returns(true)
+ Puppet::FileServing::Base.new("/module/dir/file", :relative_path => "my/file").relative_path.should == "my/file"
+ end
+
+ it "should have a means of determining if the file exists" do
+ Puppet::FileServing::Base.new("/blah").should respond_to(:exist?)
+ end
+
+ it "should correctly indicate if the file is present" do
+ File.expects(:lstat).with("/my/file").returns(mock("stat"))
+ Puppet::FileServing::Base.new("/my/file").exist?.should be_true
+ end
+
+ it "should correctly indicate if the file is absent" do
+ File.expects(:lstat).with("/my/file").raises RuntimeError
+ Puppet::FileServing::Base.new("/my/file").exist?.should be_false
+ end
- it "should consider :ignore links equivalent to :manage links" do
- Puppet::FileServing::Base.new("/module/dir/file", :links => :ignore).links.should == :manage
+ describe "when setting the relative path" do
+ it "should require that the relative path be unqualified" do
+ @file = Puppet::FileServing::Base.new("/module/dir/file")
+ FileTest.stubs(:exists?).returns(true)
+ proc { @file.relative_path = "/qualified/file" }.should raise_error(ArgumentError)
end
+ end
- it "should fail if :links is set to anything other than :manage, :follow, or :ignore" do
- proc { Puppet::FileServing::Base.new("/module/dir/file", :links => :else) }.should raise_error(ArgumentError)
+ describe "when determining the full file path" do
+ before do
+ @file = Puppet::FileServing::Base.new("/this/file")
end
- it "should allow links values to be set as strings" do
- Puppet::FileServing::Base.new("/module/dir/file", :links => "follow").links.should == :follow
+ it "should return the path if there is no relative path" do
+ @file.full_path.should == "/this/file"
end
- it "should default to :manage for :links" do
- Puppet::FileServing::Base.new("/module/dir/file").links.should == :manage
+ it "should return the path if the relative_path is set to ''" do
+ @file.relative_path = ""
+ @file.full_path.should == "/this/file"
end
- it "should allow specification of a path" do
- FileTest.stubs(:exists?).returns(true)
- Puppet::FileServing::Base.new("/module/dir/file", :path => "/my/file").path.should == "/my/file"
+ it "should return the path if the relative_path is set to '.'" do
+ @file.relative_path = "."
+ @file.full_path.should == "/this/file"
end
- it "should allow specification of a relative path" do
- FileTest.stubs(:exists?).returns(true)
- Puppet::FileServing::Base.new("/module/dir/file", :relative_path => "my/file").relative_path.should == "my/file"
+ it "should return the path joined with the relative path if there is a relative path and it is not set to '/' or ''" do
+ @file.relative_path = "not/qualified"
+ @file.full_path.should == "/this/file/not/qualified"
end
- it "should have a means of determining if the file exists" do
- Puppet::FileServing::Base.new("/blah").should respond_to(:exist?)
+ it "should strip extra slashes" do
+ file = Puppet::FileServing::Base.new("//this//file")
+ file.full_path.should == "/this/file"
end
+ end
- it "should correctly indicate if the file is present" do
- File.expects(:lstat).with("/my/file").returns(mock("stat"))
- Puppet::FileServing::Base.new("/my/file").exist?.should be_true
+ describe "when stat'ing files" do
+ before do
+ @file = Puppet::FileServing::Base.new("/this/file")
end
- it "should correctly indicate if the file is absent" do
- File.expects(:lstat).with("/my/file").raises RuntimeError
- Puppet::FileServing::Base.new("/my/file").exist?.should be_false
+ it "should stat the file's full path" do
+ @file.stubs(:full_path).returns("/this/file")
+ File.expects(:lstat).with("/this/file").returns stub("stat", :ftype => "file")
+ @file.stat
end
- describe "when setting the relative path" do
- it "should require that the relative path be unqualified" do
- @file = Puppet::FileServing::Base.new("/module/dir/file")
- FileTest.stubs(:exists?).returns(true)
- proc { @file.relative_path = "/qualified/file" }.should raise_error(ArgumentError)
- end
+ it "should fail if the file does not exist" do
+ @file.stubs(:full_path).returns("/this/file")
+ File.expects(:lstat).with("/this/file").raises(Errno::ENOENT)
+ proc { @file.stat }.should raise_error(Errno::ENOENT)
end
- describe "when determining the full file path" do
- before do
- @file = Puppet::FileServing::Base.new("/this/file")
- end
-
- it "should return the path if there is no relative path" do
- @file.full_path.should == "/this/file"
- end
-
- it "should return the path if the relative_path is set to ''" do
- @file.relative_path = ""
- @file.full_path.should == "/this/file"
- end
-
- it "should return the path if the relative_path is set to '.'" do
- @file.relative_path = "."
- @file.full_path.should == "/this/file"
- end
-
- it "should return the path joined with the relative path if there is a relative path and it is not set to '/' or ''" do
- @file.relative_path = "not/qualified"
- @file.full_path.should == "/this/file/not/qualified"
- end
-
- it "should strip extra slashes" do
- file = Puppet::FileServing::Base.new("//this//file")
- file.full_path.should == "/this/file"
- end
+ it "should use :lstat if :links is set to :manage" do
+ File.expects(:lstat).with("/this/file").returns stub("stat", :ftype => "file")
+ @file.stat
end
- describe "when stat'ing files" do
- before do
- @file = Puppet::FileServing::Base.new("/this/file")
- end
-
- it "should stat the file's full path" do
- @file.stubs(:full_path).returns("/this/file")
- File.expects(:lstat).with("/this/file").returns stub("stat", :ftype => "file")
- @file.stat
- end
-
- it "should fail if the file does not exist" do
- @file.stubs(:full_path).returns("/this/file")
- File.expects(:lstat).with("/this/file").raises(Errno::ENOENT)
- proc { @file.stat }.should raise_error(Errno::ENOENT)
- end
-
- it "should use :lstat if :links is set to :manage" do
- File.expects(:lstat).with("/this/file").returns stub("stat", :ftype => "file")
- @file.stat
- end
-
- it "should use :stat if :links is set to :follow" do
- File.expects(:stat).with("/this/file").returns stub("stat", :ftype => "file")
- @file.links = :follow
- @file.stat
- end
+ it "should use :stat if :links is set to :follow" do
+ File.expects(:stat).with("/this/file").returns stub("stat", :ftype => "file")
+ @file.links = :follow
+ @file.stat
end
+ end
end
diff --git a/spec/unit/file_serving/configuration/parser_spec.rb b/spec/unit/file_serving/configuration/parser_spec.rb
index 6faf81b..36e7218 100755
--- a/spec/unit/file_serving/configuration/parser_spec.rb
+++ b/spec/unit/file_serving/configuration/parser_spec.rb
@@ -5,177 +5,177 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/file_serving/configuration/parser'
describe Puppet::FileServing::Configuration::Parser do
- it "should subclass the LoadedFile class" do
- Puppet::FileServing::Configuration::Parser.superclass.should equal(Puppet::Util::LoadedFile)
- end
+ it "should subclass the LoadedFile class" do
+ Puppet::FileServing::Configuration::Parser.superclass.should equal(Puppet::Util::LoadedFile)
+ end
end
module FSConfigurationParserTesting
- def mock_file_content(content)
- # We want an array, but we actually want our carriage returns on all of it.
- lines = content.split("\n").collect { |l| l + "\n" }
- @filehandle.stubs(:each).multiple_yields(*lines)
- end
+ def mock_file_content(content)
+ # We want an array, but we actually want our carriage returns on all of it.
+ lines = content.split("\n").collect { |l| l + "\n" }
+ @filehandle.stubs(:each).multiple_yields(*lines)
+ end
end
describe Puppet::FileServing::Configuration::Parser do
- before :each do
- @path = "/my/config.conf"
- FileTest.stubs(:exists?).with(@path).returns(true)
- FileTest.stubs(:readable?).with(@path).returns(true)
- @filehandle = mock 'filehandle'
- File.expects(:open).with(@path).yields(@filehandle)
- @parser = Puppet::FileServing::Configuration::Parser.new(@path)
- end
-
- describe Puppet::FileServing::Configuration::Parser, " when parsing" do
- include FSConfigurationParserTesting
-
- it "should allow comments" do
- @filehandle.expects(:each).yields("# this is a comment\n")
- proc { @parser.parse }.should_not raise_error
- end
-
- it "should allow blank lines" do
- @filehandle.expects(:each).yields("\n")
- proc { @parser.parse }.should_not raise_error
- end
+ before :each do
+ @path = "/my/config.conf"
+ FileTest.stubs(:exists?).with(@path).returns(true)
+ FileTest.stubs(:readable?).with(@path).returns(true)
+ @filehandle = mock 'filehandle'
+ File.expects(:open).with(@path).yields(@filehandle)
+ @parser = Puppet::FileServing::Configuration::Parser.new(@path)
+ end
+
+ describe Puppet::FileServing::Configuration::Parser, " when parsing" do
+ include FSConfigurationParserTesting
+
+ it "should allow comments" do
+ @filehandle.expects(:each).yields("# this is a comment\n")
+ proc { @parser.parse }.should_not raise_error
+ end
- it "should create a new mount for each section in the configuration" do
- mount1 = mock 'one', :validate => true
- mount2 = mock 'two', :validate => true
- Puppet::FileServing::Mount::File.expects(:new).with("one").returns(mount1)
- Puppet::FileServing::Mount::File.expects(:new).with("two").returns(mount2)
- mock_file_content "[one]\n[two]\n"
- @parser.parse
- end
+ it "should allow blank lines" do
+ @filehandle.expects(:each).yields("\n")
+ proc { @parser.parse }.should_not raise_error
+ end
- # This test is almost the exact same as the previous one.
- it "should return a hash of the created mounts" do
- mount1 = mock 'one', :validate => true
- mount2 = mock 'two', :validate => true
- Puppet::FileServing::Mount::File.expects(:new).with("one").returns(mount1)
- Puppet::FileServing::Mount::File.expects(:new).with("two").returns(mount2)
- mock_file_content "[one]\n[two]\n"
+ it "should create a new mount for each section in the configuration" do
+ mount1 = mock 'one', :validate => true
+ mount2 = mock 'two', :validate => true
+ Puppet::FileServing::Mount::File.expects(:new).with("one").returns(mount1)
+ Puppet::FileServing::Mount::File.expects(:new).with("two").returns(mount2)
+ mock_file_content "[one]\n[two]\n"
+ @parser.parse
+ end
- result = @parser.parse
- result["one"].should equal(mount1)
- result["two"].should equal(mount2)
- end
+ # This test is almost the exact same as the previous one.
+ it "should return a hash of the created mounts" do
+ mount1 = mock 'one', :validate => true
+ mount2 = mock 'two', :validate => true
+ Puppet::FileServing::Mount::File.expects(:new).with("one").returns(mount1)
+ Puppet::FileServing::Mount::File.expects(:new).with("two").returns(mount2)
+ mock_file_content "[one]\n[two]\n"
+
+ result = @parser.parse
+ result["one"].should equal(mount1)
+ result["two"].should equal(mount2)
+ end
- it "should only allow mount names that are alphanumeric plus dashes" do
- mock_file_content "[a*b]\n"
- proc { @parser.parse }.should raise_error(ArgumentError)
- end
+ it "should only allow mount names that are alphanumeric plus dashes" do
+ mock_file_content "[a*b]\n"
+ proc { @parser.parse }.should raise_error(ArgumentError)
+ end
- it "should fail if the value for path/allow/deny starts with an equals sign" do
- mock_file_content "[one]\npath = /testing"
- proc { @parser.parse }.should raise_error(ArgumentError)
- end
+ it "should fail if the value for path/allow/deny starts with an equals sign" do
+ mock_file_content "[one]\npath = /testing"
+ proc { @parser.parse }.should raise_error(ArgumentError)
+ end
- it "should validate each created mount" do
- mount1 = mock 'one'
- Puppet::FileServing::Mount::File.expects(:new).with("one").returns(mount1)
- mock_file_content "[one]\n"
+ it "should validate each created mount" do
+ mount1 = mock 'one'
+ Puppet::FileServing::Mount::File.expects(:new).with("one").returns(mount1)
+ mock_file_content "[one]\n"
- mount1.expects(:validate)
+ mount1.expects(:validate)
- @parser.parse
- end
+ @parser.parse
+ end
- it "should fail if any mount does not pass validation" do
- mount1 = mock 'one'
- Puppet::FileServing::Mount::File.expects(:new).with("one").returns(mount1)
- mock_file_content "[one]\n"
+ it "should fail if any mount does not pass validation" do
+ mount1 = mock 'one'
+ Puppet::FileServing::Mount::File.expects(:new).with("one").returns(mount1)
+ mock_file_content "[one]\n"
- mount1.expects(:validate).raises RuntimeError
+ mount1.expects(:validate).raises RuntimeError
- lambda { @parser.parse }.should raise_error(RuntimeError)
- end
+ lambda { @parser.parse }.should raise_error(RuntimeError)
end
+ end
- describe Puppet::FileServing::Configuration::Parser, " when parsing mount attributes" do
- include FSConfigurationParserTesting
+ describe Puppet::FileServing::Configuration::Parser, " when parsing mount attributes" do
+ include FSConfigurationParserTesting
- before do
- @mount = stub 'testmount', :name => "one", :validate => true
- Puppet::FileServing::Mount::File.expects(:new).with("one").returns(@mount)
- @parser.stubs(:add_modules_mount)
- end
+ before do
+ @mount = stub 'testmount', :name => "one", :validate => true
+ Puppet::FileServing::Mount::File.expects(:new).with("one").returns(@mount)
+ @parser.stubs(:add_modules_mount)
+ end
- it "should set the mount path to the path attribute from that section" do
- mock_file_content "[one]\npath /some/path\n"
+ it "should set the mount path to the path attribute from that section" do
+ mock_file_content "[one]\npath /some/path\n"
- @mount.expects(:path=).with("/some/path")
- @parser.parse
- end
+ @mount.expects(:path=).with("/some/path")
+ @parser.parse
+ end
- it "should tell the mount to allow any allow values from the section" do
- mock_file_content "[one]\nallow something\n"
+ it "should tell the mount to allow any allow values from the section" do
+ mock_file_content "[one]\nallow something\n"
- @mount.expects(:info)
- @mount.expects(:allow).with("something")
- @parser.parse
- end
+ @mount.expects(:info)
+ @mount.expects(:allow).with("something")
+ @parser.parse
+ end
- it "should tell the mount to deny any deny values from the section" do
- mock_file_content "[one]\ndeny something\n"
+ it "should tell the mount to deny any deny values from the section" do
+ mock_file_content "[one]\ndeny something\n"
- @mount.expects(:info)
- @mount.expects(:deny).with("something")
- @parser.parse
- end
+ @mount.expects(:info)
+ @mount.expects(:deny).with("something")
+ @parser.parse
+ end
- it "should fail on any attributes other than path, allow, and deny" do
- mock_file_content "[one]\ndo something\n"
+ it "should fail on any attributes other than path, allow, and deny" do
+ mock_file_content "[one]\ndo something\n"
- proc { @parser.parse }.should raise_error(ArgumentError)
- end
+ proc { @parser.parse }.should raise_error(ArgumentError)
end
+ end
- describe Puppet::FileServing::Configuration::Parser, " when parsing the modules mount" do
- include FSConfigurationParserTesting
+ describe Puppet::FileServing::Configuration::Parser, " when parsing the modules mount" do
+ include FSConfigurationParserTesting
- before do
- @mount = stub 'modulesmount', :name => "modules", :validate => true
- end
+ before do
+ @mount = stub 'modulesmount', :name => "modules", :validate => true
+ end
- it "should create an instance of the Modules Mount class" do
- mock_file_content "[modules]\n"
+ it "should create an instance of the Modules Mount class" do
+ mock_file_content "[modules]\n"
- Puppet::FileServing::Mount::Modules.expects(:new).with("modules").returns @mount
- @parser.parse
- end
+ Puppet::FileServing::Mount::Modules.expects(:new).with("modules").returns @mount
+ @parser.parse
+ end
- it "should warn if a path is set" do
- mock_file_content "[modules]\npath /some/path\n"
- Puppet::FileServing::Mount::Modules.expects(:new).with("modules").returns(@mount)
+ it "should warn if a path is set" do
+ mock_file_content "[modules]\npath /some/path\n"
+ Puppet::FileServing::Mount::Modules.expects(:new).with("modules").returns(@mount)
- Puppet.expects(:warning)
- @parser.parse
- end
+ Puppet.expects(:warning)
+ @parser.parse
end
+ end
- describe Puppet::FileServing::Configuration::Parser, " when parsing the plugins mount" do
- include FSConfigurationParserTesting
+ describe Puppet::FileServing::Configuration::Parser, " when parsing the plugins mount" do
+ include FSConfigurationParserTesting
- before do
- @mount = stub 'pluginsmount', :name => "plugins", :validate => true
- end
+ before do
+ @mount = stub 'pluginsmount', :name => "plugins", :validate => true
+ end
- it "should create an instance of the Plugins Mount class" do
- mock_file_content "[plugins]\n"
+ it "should create an instance of the Plugins Mount class" do
+ mock_file_content "[plugins]\n"
- Puppet::FileServing::Mount::Plugins.expects(:new).with("plugins").returns @mount
- @parser.parse
- end
+ Puppet::FileServing::Mount::Plugins.expects(:new).with("plugins").returns @mount
+ @parser.parse
+ end
- it "should warn if a path is set" do
- mock_file_content "[plugins]\npath /some/path\n"
+ it "should warn if a path is set" do
+ mock_file_content "[plugins]\npath /some/path\n"
- Puppet.expects(:warning)
- @parser.parse
- end
+ Puppet.expects(:warning)
+ @parser.parse
end
+ end
end
diff --git a/spec/unit/file_serving/configuration_spec.rb b/spec/unit/file_serving/configuration_spec.rb
index 4621a0c..3e11caa 100755
--- a/spec/unit/file_serving/configuration_spec.rb
+++ b/spec/unit/file_serving/configuration_spec.rb
@@ -5,245 +5,245 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/file_serving/configuration'
describe Puppet::FileServing::Configuration do
- it "should make :new a private method" do
- proc { Puppet::FileServing::Configuration.new }.should raise_error
+ it "should make :new a private method" do
+ proc { Puppet::FileServing::Configuration.new }.should raise_error
+ end
+
+ it "should return the same configuration each time :create is called" do
+ Puppet::FileServing::Configuration.create.should equal(Puppet::FileServing::Configuration.create)
+ end
+
+ it "should have a method for removing the current configuration instance" do
+ old = Puppet::FileServing::Configuration.create
+ Puppet::Util::Cacher.expire
+ Puppet::FileServing::Configuration.create.should_not equal(old)
+ end
+
+ after do
+ Puppet::Util::Cacher.expire
+ end
+end
+
+describe Puppet::FileServing::Configuration do
+
+ before :each do
+ @path = "/path/to/configuration/file.conf"
+ Puppet.settings.stubs(:value).with(:trace).returns(false)
+ Puppet.settings.stubs(:value).with(:fileserverconfig).returns(@path)
+ end
+
+ after :each do
+ Puppet::Util::Cacher.expire
+ end
+
+ describe "when initializing" do
+
+ it "should work without a configuration file" do
+ FileTest.stubs(:exists?).with(@path).returns(false)
+ proc { Puppet::FileServing::Configuration.create }.should_not raise_error
end
- it "should return the same configuration each time :create is called" do
- Puppet::FileServing::Configuration.create.should equal(Puppet::FileServing::Configuration.create)
+ it "should parse the configuration file if present" do
+ FileTest.stubs(:exists?).with(@path).returns(true)
+ @parser = mock 'parser'
+ @parser.expects(:parse).returns({})
+ Puppet::FileServing::Configuration::Parser.stubs(:new).returns(@parser)
+ Puppet::FileServing::Configuration.create
end
- it "should have a method for removing the current configuration instance" do
- old = Puppet::FileServing::Configuration.create
- Puppet::Util::Cacher.expire
- Puppet::FileServing::Configuration.create.should_not equal(old)
+ it "should determine the path to the configuration file from the Puppet settings" do
+ Puppet::FileServing::Configuration.create
end
+ end
+
+ describe "when parsing the configuration file" do
- after do
- Puppet::Util::Cacher.expire
+ before do
+ FileTest.stubs(:exists?).with(@path).returns(true)
+ @parser = mock 'parser'
+ Puppet::FileServing::Configuration::Parser.stubs(:new).returns(@parser)
end
-end
-describe Puppet::FileServing::Configuration do
+ it "should set the mount list to the results of parsing" do
+ @parser.expects(:parse).returns("one" => mock("mount"))
+ config = Puppet::FileServing::Configuration.create
+ config.mounted?("one").should be_true
+ end
- before :each do
- @path = "/path/to/configuration/file.conf"
- Puppet.settings.stubs(:value).with(:trace).returns(false)
- Puppet.settings.stubs(:value).with(:fileserverconfig).returns(@path)
- end
-
- after :each do
- Puppet::Util::Cacher.expire
- end
-
- describe "when initializing" do
-
- it "should work without a configuration file" do
- FileTest.stubs(:exists?).with(@path).returns(false)
- proc { Puppet::FileServing::Configuration.create }.should_not raise_error
- end
-
- it "should parse the configuration file if present" do
- FileTest.stubs(:exists?).with(@path).returns(true)
- @parser = mock 'parser'
- @parser.expects(:parse).returns({})
- Puppet::FileServing::Configuration::Parser.stubs(:new).returns(@parser)
- Puppet::FileServing::Configuration.create
- end
-
- it "should determine the path to the configuration file from the Puppet settings" do
- Puppet::FileServing::Configuration.create
- end
- end
-
- describe "when parsing the configuration file" do
-
- before do
- FileTest.stubs(:exists?).with(@path).returns(true)
- @parser = mock 'parser'
- Puppet::FileServing::Configuration::Parser.stubs(:new).returns(@parser)
- end
-
- it "should set the mount list to the results of parsing" do
- @parser.expects(:parse).returns("one" => mock("mount"))
- config = Puppet::FileServing::Configuration.create
- config.mounted?("one").should be_true
- end
-
- it "should not raise exceptions" do
- @parser.expects(:parse).raises(ArgumentError)
- proc { Puppet::FileServing::Configuration.create }.should_not raise_error
- end
-
- it "should replace the existing mount list with the results of reparsing" do
- @parser.expects(:parse).returns("one" => mock("mount"))
- config = Puppet::FileServing::Configuration.create
- config.mounted?("one").should be_true
- # Now parse again
- @parser.expects(:parse).returns("two" => mock('other'))
- config.send(:readconfig, false)
- config.mounted?("one").should be_false
- config.mounted?("two").should be_true
- end
-
- it "should not replace the mount list until the file is entirely parsed successfully" do
- @parser.expects(:parse).returns("one" => mock("mount"))
- @parser.expects(:parse).raises(ArgumentError)
- config = Puppet::FileServing::Configuration.create
- # Now parse again, so the exception gets thrown
- config.send(:readconfig, false)
- config.mounted?("one").should be_true
- end
-
- it "should add modules and plugins mounts even if the file does not exist" do
- FileTest.expects(:exists?).returns false # the file doesn't exist
- config = Puppet::FileServing::Configuration.create
- config.mounted?("modules").should be_true
- config.mounted?("plugins").should be_true
- end
+ it "should not raise exceptions" do
+ @parser.expects(:parse).raises(ArgumentError)
+ proc { Puppet::FileServing::Configuration.create }.should_not raise_error
+ end
- it "should allow all access to modules and plugins if no fileserver.conf exists" do
- FileTest.expects(:exists?).returns false # the file doesn't exist
- modules = stub 'modules', :empty? => true
- Puppet::FileServing::Mount::Modules.stubs(:new).returns(modules)
- modules.expects(:allow).with('*')
+ it "should replace the existing mount list with the results of reparsing" do
+ @parser.expects(:parse).returns("one" => mock("mount"))
+ config = Puppet::FileServing::Configuration.create
+ config.mounted?("one").should be_true
+ # Now parse again
+ @parser.expects(:parse).returns("two" => mock('other'))
+ config.send(:readconfig, false)
+ config.mounted?("one").should be_false
+ config.mounted?("two").should be_true
+ end
- plugins = stub 'plugins', :empty? => true
- Puppet::FileServing::Mount::Plugins.stubs(:new).returns(plugins)
- plugins.expects(:allow).with('*')
+ it "should not replace the mount list until the file is entirely parsed successfully" do
+ @parser.expects(:parse).returns("one" => mock("mount"))
+ @parser.expects(:parse).raises(ArgumentError)
+ config = Puppet::FileServing::Configuration.create
+ # Now parse again, so the exception gets thrown
+ config.send(:readconfig, false)
+ config.mounted?("one").should be_true
+ end
- Puppet::FileServing::Configuration.create
- end
+ it "should add modules and plugins mounts even if the file does not exist" do
+ FileTest.expects(:exists?).returns false # the file doesn't exist
+ config = Puppet::FileServing::Configuration.create
+ config.mounted?("modules").should be_true
+ config.mounted?("plugins").should be_true
+ end
- it "should not allow access from all to modules and plugins if the fileserver.conf provided some rules" do
- FileTest.expects(:exists?).returns false # the file doesn't exist
+ it "should allow all access to modules and plugins if no fileserver.conf exists" do
+ FileTest.expects(:exists?).returns false # the file doesn't exist
+ modules = stub 'modules', :empty? => true
+ Puppet::FileServing::Mount::Modules.stubs(:new).returns(modules)
+ modules.expects(:allow).with('*')
- modules = stub 'modules', :empty? => false
- Puppet::FileServing::Mount::Modules.stubs(:new).returns(modules)
- modules.expects(:allow).with('*').never
+ plugins = stub 'plugins', :empty? => true
+ Puppet::FileServing::Mount::Plugins.stubs(:new).returns(plugins)
+ plugins.expects(:allow).with('*')
- plugins = stub 'plugins', :empty? => false
- Puppet::FileServing::Mount::Plugins.stubs(:new).returns(plugins)
- plugins.expects(:allow).with('*').never
+ Puppet::FileServing::Configuration.create
+ end
- Puppet::FileServing::Configuration.create
- end
+ it "should not allow access from all to modules and plugins if the fileserver.conf provided some rules" do
+ FileTest.expects(:exists?).returns false # the file doesn't exist
- it "should add modules and plugins mounts even if they are not returned by the parser" do
- @parser.expects(:parse).returns("one" => mock("mount"))
- FileTest.expects(:exists?).returns true # the file doesn't exist
- config = Puppet::FileServing::Configuration.create
- config.mounted?("modules").should be_true
- config.mounted?("plugins").should be_true
- end
- end
-
- describe "when finding the specified mount" do
- it "should choose the named mount if one exists" do
- config = Puppet::FileServing::Configuration.create
- config.expects(:mounts).returns("one" => "foo")
- config.find_mount("one", mock('env')).should == "foo"
- end
-
- it "should use the provided environment to find a matching module if the named module cannot be found" do
- config = Puppet::FileServing::Configuration.create
+ modules = stub 'modules', :empty? => false
+ Puppet::FileServing::Mount::Modules.stubs(:new).returns(modules)
+ modules.expects(:allow).with('*').never
- mod = mock 'module'
- env = mock 'environment'
- env.expects(:module).with("foo").returns mod
- mount = mock 'mount'
+ plugins = stub 'plugins', :empty? => false
+ Puppet::FileServing::Mount::Plugins.stubs(:new).returns(plugins)
+ plugins.expects(:allow).with('*').never
- config.stubs(:mounts).returns("modules" => mount)
- Puppet::Util::Warnings.expects(:notice_once)
- config.find_mount("foo", env).should equal(mount)
- end
-
- it "should return nil if there is no such named mount and no module with the same name exists" do
- config = Puppet::FileServing::Configuration.create
-
- env = mock 'environment'
- env.expects(:module).with("foo").returns nil
+ Puppet::FileServing::Configuration.create
+ end
- mount = mock 'mount'
- config.stubs(:mounts).returns("modules" => mount)
- config.find_mount("foo", env).should be_nil
- end
+ it "should add modules and plugins mounts even if they are not returned by the parser" do
+ @parser.expects(:parse).returns("one" => mock("mount"))
+ FileTest.expects(:exists?).returns true # the file doesn't exist
+ config = Puppet::FileServing::Configuration.create
+ config.mounted?("modules").should be_true
+ config.mounted?("plugins").should be_true
end
+ end
- describe "when finding the mount name and relative path in a request key" do
- before do
- @config = Puppet::FileServing::Configuration.create
- @config.stubs(:find_mount)
+ describe "when finding the specified mount" do
+ it "should choose the named mount if one exists" do
+ config = Puppet::FileServing::Configuration.create
+ config.expects(:mounts).returns("one" => "foo")
+ config.find_mount("one", mock('env')).should == "foo"
+ end
- @request = stub 'request', :key => "foo/bar/baz", :options => {}, :node => nil, :environment => mock("env")
- end
+ it "should use the provided environment to find a matching module if the named module cannot be found" do
+ config = Puppet::FileServing::Configuration.create
- it "should reread the configuration" do
- @config.expects(:readconfig)
+ mod = mock 'module'
+ env = mock 'environment'
+ env.expects(:module).with("foo").returns mod
+ mount = mock 'mount'
- @config.split_path(@request)
- end
+ config.stubs(:mounts).returns("modules" => mount)
+ Puppet::Util::Warnings.expects(:notice_once)
+ config.find_mount("foo", env).should equal(mount)
+ end
- it "should treat the first field of the URI path as the mount name" do
- @config.expects(:find_mount).with { |name, node| name == "foo" }
+ it "should return nil if there is no such named mount and no module with the same name exists" do
+ config = Puppet::FileServing::Configuration.create
- @config.split_path(@request)
- end
+ env = mock 'environment'
+ env.expects(:module).with("foo").returns nil
- it "should fail if the mount name is not alpha-numeric" do
- @request.expects(:key).returns "foo&bar/asdf"
+ mount = mock 'mount'
+ config.stubs(:mounts).returns("modules" => mount)
+ config.find_mount("foo", env).should be_nil
+ end
+ end
+
+ describe "when finding the mount name and relative path in a request key" do
+ before do
+ @config = Puppet::FileServing::Configuration.create
+ @config.stubs(:find_mount)
+
+ @request = stub 'request', :key => "foo/bar/baz", :options => {}, :node => nil, :environment => mock("env")
+ end
+
+ it "should reread the configuration" do
+ @config.expects(:readconfig)
+
+ @config.split_path(@request)
+ end
+
+ it "should treat the first field of the URI path as the mount name" do
+ @config.expects(:find_mount).with { |name, node| name == "foo" }
+
+ @config.split_path(@request)
+ end
- lambda { @config.split_path(@request) }.should raise_error(ArgumentError)
- end
+ it "should fail if the mount name is not alpha-numeric" do
+ @request.expects(:key).returns "foo&bar/asdf"
- it "should support dashes in the mount name" do
- @request.expects(:key).returns "foo-bar/asdf"
+ lambda { @config.split_path(@request) }.should raise_error(ArgumentError)
+ end
- lambda { @config.split_path(@request) }.should_not raise_error(ArgumentError)
- end
+ it "should support dashes in the mount name" do
+ @request.expects(:key).returns "foo-bar/asdf"
- it "should use the mount name and environment to find the mount" do
- @config.expects(:find_mount).with { |name, env| name == "foo" and env == @request.environment }
- @request.stubs(:node).returns("mynode")
+ lambda { @config.split_path(@request) }.should_not raise_error(ArgumentError)
+ end
- @config.split_path(@request)
- end
+ it "should use the mount name and environment to find the mount" do
+ @config.expects(:find_mount).with { |name, env| name == "foo" and env == @request.environment }
+ @request.stubs(:node).returns("mynode")
- it "should return nil if the mount cannot be found" do
- @config.expects(:find_mount).returns nil
+ @config.split_path(@request)
+ end
- @config.split_path(@request).should be_nil
- end
+ it "should return nil if the mount cannot be found" do
+ @config.expects(:find_mount).returns nil
- it "should return the mount and the relative path if the mount is found" do
- mount = stub 'mount', :name => "foo"
- @config.expects(:find_mount).returns mount
+ @config.split_path(@request).should be_nil
+ end
- @config.split_path(@request).should == [mount, "bar/baz"]
- end
+ it "should return the mount and the relative path if the mount is found" do
+ mount = stub 'mount', :name => "foo"
+ @config.expects(:find_mount).returns mount
- it "should remove any double slashes" do
- @request.stubs(:key).returns "foo/bar//baz"
- mount = stub 'mount', :name => "foo"
- @config.expects(:find_mount).returns mount
+ @config.split_path(@request).should == [mount, "bar/baz"]
+ end
+
+ it "should remove any double slashes" do
+ @request.stubs(:key).returns "foo/bar//baz"
+ mount = stub 'mount', :name => "foo"
+ @config.expects(:find_mount).returns mount
- @config.split_path(@request).should == [mount, "bar/baz"]
- end
+ @config.split_path(@request).should == [mount, "bar/baz"]
+ end
- it "should return the relative path as nil if it is an empty string" do
- @request.expects(:key).returns "foo"
- mount = stub 'mount', :name => "foo"
- @config.expects(:find_mount).returns mount
+ it "should return the relative path as nil if it is an empty string" do
+ @request.expects(:key).returns "foo"
+ mount = stub 'mount', :name => "foo"
+ @config.expects(:find_mount).returns mount
- @config.split_path(@request).should == [mount, nil]
- end
+ @config.split_path(@request).should == [mount, nil]
+ end
- it "should add 'modules/' to the relative path if the modules mount is used but not specified, for backward compatibility" do
- @request.expects(:key).returns "foo/bar"
- mount = stub 'mount', :name => "modules"
- @config.expects(:find_mount).returns mount
+ it "should add 'modules/' to the relative path if the modules mount is used but not specified, for backward compatibility" do
+ @request.expects(:key).returns "foo/bar"
+ mount = stub 'mount', :name => "modules"
+ @config.expects(:find_mount).returns mount
- @config.split_path(@request).should == [mount, "foo/bar"]
- end
+ @config.split_path(@request).should == [mount, "foo/bar"]
end
+ end
end
diff --git a/spec/unit/file_serving/content_spec.rb b/spec/unit/file_serving/content_spec.rb
index e86e26a..92b7474 100755
--- a/spec/unit/file_serving/content_spec.rb
+++ b/spec/unit/file_serving/content_spec.rb
@@ -5,114 +5,114 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/file_serving/content'
describe Puppet::FileServing::Content do
- it "should should be a subclass of Base" do
- Puppet::FileServing::Content.superclass.should equal(Puppet::FileServing::Base)
- end
+ it "should should be a subclass of Base" do
+ Puppet::FileServing::Content.superclass.should equal(Puppet::FileServing::Base)
+ end
- it "should indirect file_content" do
- Puppet::FileServing::Content.indirection.name.should == :file_content
- end
+ it "should indirect file_content" do
+ Puppet::FileServing::Content.indirection.name.should == :file_content
+ end
- it "should should include the IndirectionHooks module in its indirection" do
- Puppet::FileServing::Content.indirection.singleton_class.included_modules.should include(Puppet::FileServing::IndirectionHooks)
- end
+ it "should should include the IndirectionHooks module in its indirection" do
+ Puppet::FileServing::Content.indirection.singleton_class.included_modules.should include(Puppet::FileServing::IndirectionHooks)
+ end
- it "should only support the raw format" do
- Puppet::FileServing::Content.supported_formats.should == [:raw]
- end
+ it "should only support the raw format" do
+ Puppet::FileServing::Content.supported_formats.should == [:raw]
+ end
- it "should have a method for collecting its attributes" do
- Puppet::FileServing::Content.new("/path").should respond_to(:collect)
- end
+ it "should have a method for collecting its attributes" do
+ Puppet::FileServing::Content.new("/path").should respond_to(:collect)
+ end
- it "should not retrieve and store its contents when its attributes are collected if the file is a normal file" do
- content = Puppet::FileServing::Content.new("/path")
+ it "should not retrieve and store its contents when its attributes are collected if the file is a normal file" do
+ content = Puppet::FileServing::Content.new("/path")
- result = "foo"
- File.stubs(:lstat).returns(stub("stat", :ftype => "file"))
- File.expects(:read).with("/path").never
- content.collect
+ result = "foo"
+ File.stubs(:lstat).returns(stub("stat", :ftype => "file"))
+ File.expects(:read).with("/path").never
+ content.collect
- content.instance_variable_get("@content").should be_nil
- end
+ content.instance_variable_get("@content").should be_nil
+ end
- it "should not attempt to retrieve its contents if the file is a directory" do
- content = Puppet::FileServing::Content.new("/path")
+ it "should not attempt to retrieve its contents if the file is a directory" do
+ content = Puppet::FileServing::Content.new("/path")
- result = "foo"
- File.stubs(:lstat).returns(stub("stat", :ftype => "directory"))
- File.expects(:read).with("/path").never
- content.collect
+ result = "foo"
+ File.stubs(:lstat).returns(stub("stat", :ftype => "directory"))
+ File.expects(:read).with("/path").never
+ content.collect
- content.instance_variable_get("@content").should be_nil
- end
+ content.instance_variable_get("@content").should be_nil
+ end
- it "should have a method for setting its content" do
- content = Puppet::FileServing::Content.new("/path")
- content.should respond_to(:content=)
- end
+ it "should have a method for setting its content" do
+ content = Puppet::FileServing::Content.new("/path")
+ content.should respond_to(:content=)
+ end
- it "should make content available when set externally" do
- content = Puppet::FileServing::Content.new("/path")
- content.content = "foo/bar"
- content.content.should == "foo/bar"
- end
+ it "should make content available when set externally" do
+ content = Puppet::FileServing::Content.new("/path")
+ content.content = "foo/bar"
+ content.content.should == "foo/bar"
+ end
- it "should be able to create a content instance from raw file contents" do
- Puppet::FileServing::Content.should respond_to(:from_raw)
- end
+ it "should be able to create a content instance from raw file contents" do
+ Puppet::FileServing::Content.should respond_to(:from_raw)
+ end
- it "should create an instance with a fake file name and correct content when converting from raw" do
- instance = mock 'instance'
- Puppet::FileServing::Content.expects(:new).with("/this/is/a/fake/path").returns instance
+ it "should create an instance with a fake file name and correct content when converting from raw" do
+ instance = mock 'instance'
+ Puppet::FileServing::Content.expects(:new).with("/this/is/a/fake/path").returns instance
- instance.expects(:content=).with "foo/bar"
+ instance.expects(:content=).with "foo/bar"
- Puppet::FileServing::Content.from_raw("foo/bar").should equal(instance)
- end
+ Puppet::FileServing::Content.from_raw("foo/bar").should equal(instance)
+ end
- it "should return an opened File when converted to raw" do
- content = Puppet::FileServing::Content.new("/path")
+ it "should return an opened File when converted to raw" do
+ content = Puppet::FileServing::Content.new("/path")
- File.expects(:new).with("/path","r").returns :file
+ File.expects(:new).with("/path","r").returns :file
- content.to_raw.should == :file
- end
+ content.to_raw.should == :file
+ end
end
describe Puppet::FileServing::Content, "when returning the contents" do
- before do
- @path = "/my/path"
- @content = Puppet::FileServing::Content.new(@path, :links => :follow)
- end
-
- it "should fail if the file is a symlink and links are set to :manage" do
- @content.links = :manage
- File.expects(:lstat).with(@path).returns stub("stat", :ftype => "symlink")
- proc { @content.content }.should raise_error(ArgumentError)
- end
-
- it "should fail if a path is not set" do
- proc { @content.content }.should raise_error(Errno::ENOENT)
- end
-
- it "should raise Errno::ENOENT if the file is absent" do
- @content.path = "/there/is/absolutely/no/chance/that/this/path/exists"
- proc { @content.content }.should raise_error(Errno::ENOENT)
- end
-
- it "should return the contents of the path if the file exists" do
- File.expects(:stat).with(@path).returns stub("stat", :ftype => "file")
- File.expects(:read).with(@path).returns(:mycontent)
- @content.content.should == :mycontent
- end
-
- it "should cache the returned contents" do
- File.expects(:stat).with(@path).returns stub("stat", :ftype => "file")
- File.expects(:read).with(@path).returns(:mycontent)
- @content.content
-
- # The second run would throw a failure if the content weren't being cached.
- @content.content
- end
+ before do
+ @path = "/my/path"
+ @content = Puppet::FileServing::Content.new(@path, :links => :follow)
+ end
+
+ it "should fail if the file is a symlink and links are set to :manage" do
+ @content.links = :manage
+ File.expects(:lstat).with(@path).returns stub("stat", :ftype => "symlink")
+ proc { @content.content }.should raise_error(ArgumentError)
+ end
+
+ it "should fail if a path is not set" do
+ proc { @content.content }.should raise_error(Errno::ENOENT)
+ end
+
+ it "should raise Errno::ENOENT if the file is absent" do
+ @content.path = "/there/is/absolutely/no/chance/that/this/path/exists"
+ proc { @content.content }.should raise_error(Errno::ENOENT)
+ end
+
+ it "should return the contents of the path if the file exists" do
+ File.expects(:stat).with(@path).returns stub("stat", :ftype => "file")
+ File.expects(:read).with(@path).returns(:mycontent)
+ @content.content.should == :mycontent
+ end
+
+ it "should cache the returned contents" do
+ File.expects(:stat).with(@path).returns stub("stat", :ftype => "file")
+ File.expects(:read).with(@path).returns(:mycontent)
+ @content.content
+
+ # The second run would throw a failure if the content weren't being cached.
+ @content.content
+ end
end
diff --git a/spec/unit/file_serving/fileset_spec.rb b/spec/unit/file_serving/fileset_spec.rb
index c03522d..9a90cff 100755
--- a/spec/unit/file_serving/fileset_spec.rb
+++ b/spec/unit/file_serving/fileset_spec.rb
@@ -5,343 +5,343 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/file_serving/fileset'
describe Puppet::FileServing::Fileset, " when initializing" do
- it "should require a path" do
- proc { Puppet::FileServing::Fileset.new }.should raise_error(ArgumentError)
- end
-
- it "should fail if its path is not fully qualified" do
- proc { Puppet::FileServing::Fileset.new("some/file") }.should raise_error(ArgumentError)
- end
-
- it "should fail if its path does not exist" do
- File.expects(:lstat).with("/some/file").returns nil
- proc { Puppet::FileServing::Fileset.new("/some/file") }.should raise_error(ArgumentError)
- end
-
- it "should accept a 'recurse' option" do
- File.expects(:lstat).with("/some/file").returns stub("stat")
- set = Puppet::FileServing::Fileset.new("/some/file", :recurse => true)
- set.recurse.should be_true
- end
-
- it "should accept a 'recurselimit' option" do
- File.expects(:lstat).with("/some/file").returns stub("stat")
- set = Puppet::FileServing::Fileset.new("/some/file", :recurselimit => 3)
- set.recurselimit.should == 3
- end
-
- it "should accept an 'ignore' option" do
- File.expects(:lstat).with("/some/file").returns stub("stat")
- set = Puppet::FileServing::Fileset.new("/some/file", :ignore => ".svn")
- set.ignore.should == [".svn"]
- end
-
- it "should accept a 'links' option" do
- File.expects(:lstat).with("/some/file").returns stub("stat")
- set = Puppet::FileServing::Fileset.new("/some/file", :links => :manage)
- set.links.should == :manage
- end
-
- it "should accept a 'checksum_type' option" do
- File.expects(:lstat).with("/some/file").returns stub("stat")
- set = Puppet::FileServing::Fileset.new("/some/file", :checksum_type => :test)
- set.checksum_type.should == :test
- end
-
- it "should fail if 'links' is set to anything other than :manage or :follow" do
- proc { Puppet::FileServing::Fileset.new("/some/file", :links => :whatever) }.should raise_error(ArgumentError)
- end
-
- it "should default to 'false' for recurse" do
- File.expects(:lstat).with("/some/file").returns stub("stat")
- Puppet::FileServing::Fileset.new("/some/file").recurse.should == false
+ it "should require a path" do
+ proc { Puppet::FileServing::Fileset.new }.should raise_error(ArgumentError)
+ end
+
+ it "should fail if its path is not fully qualified" do
+ proc { Puppet::FileServing::Fileset.new("some/file") }.should raise_error(ArgumentError)
+ end
+
+ it "should fail if its path does not exist" do
+ File.expects(:lstat).with("/some/file").returns nil
+ proc { Puppet::FileServing::Fileset.new("/some/file") }.should raise_error(ArgumentError)
+ end
+
+ it "should accept a 'recurse' option" do
+ File.expects(:lstat).with("/some/file").returns stub("stat")
+ set = Puppet::FileServing::Fileset.new("/some/file", :recurse => true)
+ set.recurse.should be_true
+ end
+
+ it "should accept a 'recurselimit' option" do
+ File.expects(:lstat).with("/some/file").returns stub("stat")
+ set = Puppet::FileServing::Fileset.new("/some/file", :recurselimit => 3)
+ set.recurselimit.should == 3
+ end
+
+ it "should accept an 'ignore' option" do
+ File.expects(:lstat).with("/some/file").returns stub("stat")
+ set = Puppet::FileServing::Fileset.new("/some/file", :ignore => ".svn")
+ set.ignore.should == [".svn"]
+ end
+
+ it "should accept a 'links' option" do
+ File.expects(:lstat).with("/some/file").returns stub("stat")
+ set = Puppet::FileServing::Fileset.new("/some/file", :links => :manage)
+ set.links.should == :manage
+ end
+
+ it "should accept a 'checksum_type' option" do
+ File.expects(:lstat).with("/some/file").returns stub("stat")
+ set = Puppet::FileServing::Fileset.new("/some/file", :checksum_type => :test)
+ set.checksum_type.should == :test
+ end
+
+ it "should fail if 'links' is set to anything other than :manage or :follow" do
+ proc { Puppet::FileServing::Fileset.new("/some/file", :links => :whatever) }.should raise_error(ArgumentError)
+ end
+
+ it "should default to 'false' for recurse" do
+ File.expects(:lstat).with("/some/file").returns stub("stat")
+ Puppet::FileServing::Fileset.new("/some/file").recurse.should == false
+ end
+
+ it "should default to :infinite for recurselimit" do
+ File.expects(:lstat).with("/some/file").returns stub("stat")
+ Puppet::FileServing::Fileset.new("/some/file").recurselimit.should == :infinite
+ end
+
+ it "should default to an empty ignore list" do
+ File.expects(:lstat).with("/some/file").returns stub("stat")
+ Puppet::FileServing::Fileset.new("/some/file").ignore.should == []
+ end
+
+ it "should default to :manage for links" do
+ File.expects(:lstat).with("/some/file").returns stub("stat")
+ Puppet::FileServing::Fileset.new("/some/file").links.should == :manage
+ end
+
+ it "should support using an Indirector Request for its options" do
+ File.expects(:lstat).with("/some/file").returns stub("stat")
+ request = Puppet::Indirector::Request.new(:file_serving, :find, "foo")
+ lambda { Puppet::FileServing::Fileset.new("/some/file", request) }.should_not raise_error
+ end
+
+ describe "using an indirector request" do
+ before do
+ File.stubs(:lstat).returns stub("stat")
+ @values = {:links => :manage, :ignore => %w{a b}, :recurse => true, :recurselimit => 1234}
+ @request = Puppet::Indirector::Request.new(:file_serving, :find, "foo")
end
- it "should default to :infinite for recurselimit" do
- File.expects(:lstat).with("/some/file").returns stub("stat")
- Puppet::FileServing::Fileset.new("/some/file").recurselimit.should == :infinite
- end
+ [:recurse, :recurselimit, :ignore, :links].each do |option|
+ it "should pass :recurse, :recurselimit, :ignore, and :links settings on to the fileset if present" do
+ @request.stubs(:options).returns(option => @values[option])
+ Puppet::FileServing::Fileset.new("/my/file", @request).send(option).should == @values[option]
+ end
- it "should default to an empty ignore list" do
- File.expects(:lstat).with("/some/file").returns stub("stat")
- Puppet::FileServing::Fileset.new("/some/file").ignore.should == []
+ it "should pass :recurse, :recurselimit, :ignore, and :links settings on to the fileset if present with the keys stored as strings" do
+ @request.stubs(:options).returns(option.to_s => @values[option])
+ Puppet::FileServing::Fileset.new("/my/file", @request).send(option).should == @values[option]
+ end
end
- it "should default to :manage for links" do
- File.expects(:lstat).with("/some/file").returns stub("stat")
- Puppet::FileServing::Fileset.new("/some/file").links.should == :manage
+ it "should convert the integer as a string to their integer counterpart when setting options" do
+ @request.stubs(:options).returns(:recurselimit => "1234")
+ Puppet::FileServing::Fileset.new("/my/file", @request).recurselimit.should == 1234
end
- it "should support using an Indirector Request for its options" do
- File.expects(:lstat).with("/some/file").returns stub("stat")
- request = Puppet::Indirector::Request.new(:file_serving, :find, "foo")
- lambda { Puppet::FileServing::Fileset.new("/some/file", request) }.should_not raise_error
+ it "should convert the string 'true' to the boolean true when setting options" do
+ @request.stubs(:options).returns(:recurse => "true")
+ Puppet::FileServing::Fileset.new("/my/file", @request).recurse.should == true
end
- describe "using an indirector request" do
- before do
- File.stubs(:lstat).returns stub("stat")
- @values = {:links => :manage, :ignore => %w{a b}, :recurse => true, :recurselimit => 1234}
- @request = Puppet::Indirector::Request.new(:file_serving, :find, "foo")
- end
-
- [:recurse, :recurselimit, :ignore, :links].each do |option|
- it "should pass :recurse, :recurselimit, :ignore, and :links settings on to the fileset if present" do
- @request.stubs(:options).returns(option => @values[option])
- Puppet::FileServing::Fileset.new("/my/file", @request).send(option).should == @values[option]
- end
-
- it "should pass :recurse, :recurselimit, :ignore, and :links settings on to the fileset if present with the keys stored as strings" do
- @request.stubs(:options).returns(option.to_s => @values[option])
- Puppet::FileServing::Fileset.new("/my/file", @request).send(option).should == @values[option]
- end
- end
-
- it "should convert the integer as a string to their integer counterpart when setting options" do
- @request.stubs(:options).returns(:recurselimit => "1234")
- Puppet::FileServing::Fileset.new("/my/file", @request).recurselimit.should == 1234
- end
-
- it "should convert the string 'true' to the boolean true when setting options" do
- @request.stubs(:options).returns(:recurse => "true")
- Puppet::FileServing::Fileset.new("/my/file", @request).recurse.should == true
- end
-
- it "should convert the string 'false' to the boolean false when setting options" do
- @request.stubs(:options).returns(:recurse => "false")
- Puppet::FileServing::Fileset.new("/my/file", @request).recurse.should == false
- end
+ it "should convert the string 'false' to the boolean false when setting options" do
+ @request.stubs(:options).returns(:recurse => "false")
+ Puppet::FileServing::Fileset.new("/my/file", @request).recurse.should == false
end
+ end
end
describe Puppet::FileServing::Fileset, " when determining whether to recurse" do
- before do
- @path = "/my/path"
- File.expects(:lstat).with(@path).returns stub("stat")
- @fileset = Puppet::FileServing::Fileset.new(@path)
- end
-
- it "should always recurse if :recurse is set to 'true' and with infinite recursion" do
- @fileset.recurse = true
- @fileset.recurselimit = :infinite
- @fileset.recurse?(0).should be_true
- end
-
- it "should never recurse if :recurse is set to 'false'" do
- @fileset.recurse = false
- @fileset.recurse?(-1).should be_false
- end
-
- it "should recurse if :recurse is set to true, :recurselimit is set to an integer and the current depth is less than that integer" do
- @fileset.recurse = true
- @fileset.recurselimit = 1
- @fileset.recurse?(0).should be_true
- end
-
- it "should recurse if :recurse is set to true, :recurselimit is set to an integer and the current depth is equal to that integer" do
- @fileset.recurse = true
- @fileset.recurselimit = 1
- @fileset.recurse?(1).should be_true
- end
-
- it "should not recurse if :recurse is set to true, :recurselimit is set to an integer and the current depth is greater than that integer" do
- @fileset.recurse = true
- @fileset.recurselimit = 1
- @fileset.recurse?(2).should be_false
- end
+ before do
+ @path = "/my/path"
+ File.expects(:lstat).with(@path).returns stub("stat")
+ @fileset = Puppet::FileServing::Fileset.new(@path)
+ end
+
+ it "should always recurse if :recurse is set to 'true' and with infinite recursion" do
+ @fileset.recurse = true
+ @fileset.recurselimit = :infinite
+ @fileset.recurse?(0).should be_true
+ end
+
+ it "should never recurse if :recurse is set to 'false'" do
+ @fileset.recurse = false
+ @fileset.recurse?(-1).should be_false
+ end
+
+ it "should recurse if :recurse is set to true, :recurselimit is set to an integer and the current depth is less than that integer" do
+ @fileset.recurse = true
+ @fileset.recurselimit = 1
+ @fileset.recurse?(0).should be_true
+ end
+
+ it "should recurse if :recurse is set to true, :recurselimit is set to an integer and the current depth is equal to that integer" do
+ @fileset.recurse = true
+ @fileset.recurselimit = 1
+ @fileset.recurse?(1).should be_true
+ end
+
+ it "should not recurse if :recurse is set to true, :recurselimit is set to an integer and the current depth is greater than that integer" do
+ @fileset.recurse = true
+ @fileset.recurselimit = 1
+ @fileset.recurse?(2).should be_false
+ end
end
describe Puppet::FileServing::Fileset, " when recursing" do
- before do
- @path = "/my/path"
- File.expects(:lstat).with(@path).returns stub("stat", :directory? => true)
- @fileset = Puppet::FileServing::Fileset.new(@path)
-
- @dirstat = stub 'dirstat', :directory? => true
- @filestat = stub 'filestat', :directory? => false
- end
-
- def mock_dir_structure(path, stat_method = :lstat)
- File.stubs(stat_method).with(path).returns(@dirstat)
- Dir.stubs(:entries).with(path).returns(%w{one two .svn CVS})
-
- # Keep track of the files we're stubbing.
- @files = %w{.}
-
- %w{one two .svn CVS}.each do |subdir|
- @files << subdir # relative path
- subpath = File.join(path, subdir)
- File.stubs(stat_method).with(subpath).returns(@dirstat)
- Dir.stubs(:entries).with(subpath).returns(%w{.svn CVS file1 file2})
- %w{file1 file2 .svn CVS}.each do |file|
- @files << File.join(subdir, file) # relative path
- File.stubs(stat_method).with(File.join(subpath, file)).returns(@filestat)
- end
- end
- end
-
- it "should recurse through the whole file tree if :recurse is set to 'true'" do
- mock_dir_structure(@path)
- @fileset.stubs(:recurse?).returns(true)
- @fileset.files.sort.should == @files.sort
- end
-
- it "should not recurse if :recurse is set to 'false'" do
- mock_dir_structure(@path)
- @fileset.stubs(:recurse?).returns(false)
- @fileset.files.should == %w{.}
- end
-
- # It seems like I should stub :recurse? here, or that I shouldn't stub the
- # examples above, but...
- it "should recurse to the level set if :recurselimit is set to an integer" do
- mock_dir_structure(@path)
- @fileset.recurse = true
- @fileset.recurselimit = 1
- @fileset.files.should == %w{. one two .svn CVS}
- end
-
- it "should ignore the '.' and '..' directories in subdirectories" do
- mock_dir_structure(@path)
- @fileset.recurse = true
- @fileset.files.sort.should == @files.sort
- end
-
- it "should function if the :ignore value provided is nil" do
- mock_dir_structure(@path)
- @fileset.recurse = true
- @fileset.ignore = nil
- lambda { @fileset.files }.should_not raise_error
- end
-
- it "should ignore files that match a single pattern in the ignore list" do
- mock_dir_structure(@path)
- @fileset.recurse = true
- @fileset.ignore = ".svn"
- @fileset.files.find { |file| file.include?(".svn") }.should be_nil
- end
-
- it "should ignore files that match any of multiple patterns in the ignore list" do
- mock_dir_structure(@path)
- @fileset.recurse = true
- @fileset.ignore = %w{.svn CVS}
- @fileset.files.find { |file| file.include?(".svn") or file.include?("CVS") }.should be_nil
- end
-
- it "should use File.stat if :links is set to :follow" do
- mock_dir_structure(@path, :stat)
- @fileset.recurse = true
- @fileset.links = :follow
- @fileset.files.sort.should == @files.sort
- end
-
- it "should use File.lstat if :links is set to :manage" do
- mock_dir_structure(@path, :lstat)
- @fileset.recurse = true
- @fileset.links = :manage
- @fileset.files.sort.should == @files.sort
- end
-
- it "should succeed when paths have regexp significant characters" do
- @path = "/my/path/rV1x2DafFr0R6tGG+1bbk++++TM"
- File.expects(:lstat).with(@path).returns stub("stat", :directory? => true)
- @fileset = Puppet::FileServing::Fileset.new(@path)
- mock_dir_structure(@path)
- @fileset.recurse = true
- @fileset.files.sort.should == @files.sort
- end
+ before do
+ @path = "/my/path"
+ File.expects(:lstat).with(@path).returns stub("stat", :directory? => true)
+ @fileset = Puppet::FileServing::Fileset.new(@path)
+
+ @dirstat = stub 'dirstat', :directory? => true
+ @filestat = stub 'filestat', :directory? => false
+ end
+
+ def mock_dir_structure(path, stat_method = :lstat)
+ File.stubs(stat_method).with(path).returns(@dirstat)
+ Dir.stubs(:entries).with(path).returns(%w{one two .svn CVS})
+
+ # Keep track of the files we're stubbing.
+ @files = %w{.}
+
+ %w{one two .svn CVS}.each do |subdir|
+ @files << subdir # relative path
+ subpath = File.join(path, subdir)
+ File.stubs(stat_method).with(subpath).returns(@dirstat)
+ Dir.stubs(:entries).with(subpath).returns(%w{.svn CVS file1 file2})
+ %w{file1 file2 .svn CVS}.each do |file|
+ @files << File.join(subdir, file) # relative path
+ File.stubs(stat_method).with(File.join(subpath, file)).returns(@filestat)
+ end
+ end
+ end
+
+ it "should recurse through the whole file tree if :recurse is set to 'true'" do
+ mock_dir_structure(@path)
+ @fileset.stubs(:recurse?).returns(true)
+ @fileset.files.sort.should == @files.sort
+ end
+
+ it "should not recurse if :recurse is set to 'false'" do
+ mock_dir_structure(@path)
+ @fileset.stubs(:recurse?).returns(false)
+ @fileset.files.should == %w{.}
+ end
+
+ # It seems like I should stub :recurse? here, or that I shouldn't stub the
+ # examples above, but...
+ it "should recurse to the level set if :recurselimit is set to an integer" do
+ mock_dir_structure(@path)
+ @fileset.recurse = true
+ @fileset.recurselimit = 1
+ @fileset.files.should == %w{. one two .svn CVS}
+ end
+
+ it "should ignore the '.' and '..' directories in subdirectories" do
+ mock_dir_structure(@path)
+ @fileset.recurse = true
+ @fileset.files.sort.should == @files.sort
+ end
+
+ it "should function if the :ignore value provided is nil" do
+ mock_dir_structure(@path)
+ @fileset.recurse = true
+ @fileset.ignore = nil
+ lambda { @fileset.files }.should_not raise_error
+ end
+
+ it "should ignore files that match a single pattern in the ignore list" do
+ mock_dir_structure(@path)
+ @fileset.recurse = true
+ @fileset.ignore = ".svn"
+ @fileset.files.find { |file| file.include?(".svn") }.should be_nil
+ end
+
+ it "should ignore files that match any of multiple patterns in the ignore list" do
+ mock_dir_structure(@path)
+ @fileset.recurse = true
+ @fileset.ignore = %w{.svn CVS}
+ @fileset.files.find { |file| file.include?(".svn") or file.include?("CVS") }.should be_nil
+ end
+
+ it "should use File.stat if :links is set to :follow" do
+ mock_dir_structure(@path, :stat)
+ @fileset.recurse = true
+ @fileset.links = :follow
+ @fileset.files.sort.should == @files.sort
+ end
+
+ it "should use File.lstat if :links is set to :manage" do
+ mock_dir_structure(@path, :lstat)
+ @fileset.recurse = true
+ @fileset.links = :manage
+ @fileset.files.sort.should == @files.sort
+ end
+
+ it "should succeed when paths have regexp significant characters" do
+ @path = "/my/path/rV1x2DafFr0R6tGG+1bbk++++TM"
+ File.expects(:lstat).with(@path).returns stub("stat", :directory? => true)
+ @fileset = Puppet::FileServing::Fileset.new(@path)
+ mock_dir_structure(@path)
+ @fileset.recurse = true
+ @fileset.files.sort.should == @files.sort
+ end
end
describe Puppet::FileServing::Fileset, " when following links that point to missing files" do
- before do
- @path = "/my/path"
- File.expects(:lstat).with(@path).returns stub("stat", :directory? => true)
- @fileset = Puppet::FileServing::Fileset.new(@path)
- @fileset.links = :follow
- @fileset.recurse = true
-
- @stat = stub 'stat', :directory? => true
-
- File.expects(:stat).with(@path).returns(@stat)
- File.expects(:stat).with(File.join(@path, "mylink")).raises(Errno::ENOENT)
- Dir.stubs(:entries).with(@path).returns(["mylink"])
- end
-
- it "should not fail" do
- proc { @fileset.files }.should_not raise_error
- end
-
- it "should still manage the link" do
- @fileset.files.sort.should == %w{. mylink}.sort
- end
+ before do
+ @path = "/my/path"
+ File.expects(:lstat).with(@path).returns stub("stat", :directory? => true)
+ @fileset = Puppet::FileServing::Fileset.new(@path)
+ @fileset.links = :follow
+ @fileset.recurse = true
+
+ @stat = stub 'stat', :directory? => true
+
+ File.expects(:stat).with(@path).returns(@stat)
+ File.expects(:stat).with(File.join(@path, "mylink")).raises(Errno::ENOENT)
+ Dir.stubs(:entries).with(@path).returns(["mylink"])
+ end
+
+ it "should not fail" do
+ proc { @fileset.files }.should_not raise_error
+ end
+
+ it "should still manage the link" do
+ @fileset.files.sort.should == %w{. mylink}.sort
+ end
end
describe Puppet::FileServing::Fileset, " when ignoring" do
- before do
- @path = "/my/path"
- File.expects(:lstat).with(@path).returns stub("stat", :directory? => true)
- @fileset = Puppet::FileServing::Fileset.new(@path)
- end
-
- it "should use ruby's globbing to determine what files should be ignored" do
- @fileset.ignore = ".svn"
- File.expects(:fnmatch?).with(".svn", "my_file")
- @fileset.ignore?("my_file")
- end
-
- it "should ignore files whose paths match a single provided ignore value" do
- @fileset.ignore = ".svn"
- File.stubs(:fnmatch?).with(".svn", "my_file").returns true
- @fileset.ignore?("my_file").should be_true
- end
-
- it "should ignore files whose paths match any of multiple provided ignore values" do
- @fileset.ignore = [".svn", "CVS"]
- File.stubs(:fnmatch?).with(".svn", "my_file").returns false
- File.stubs(:fnmatch?).with("CVS", "my_file").returns true
- @fileset.ignore?("my_file").should be_true
- end
+ before do
+ @path = "/my/path"
+ File.expects(:lstat).with(@path).returns stub("stat", :directory? => true)
+ @fileset = Puppet::FileServing::Fileset.new(@path)
+ end
+
+ it "should use ruby's globbing to determine what files should be ignored" do
+ @fileset.ignore = ".svn"
+ File.expects(:fnmatch?).with(".svn", "my_file")
+ @fileset.ignore?("my_file")
+ end
+
+ it "should ignore files whose paths match a single provided ignore value" do
+ @fileset.ignore = ".svn"
+ File.stubs(:fnmatch?).with(".svn", "my_file").returns true
+ @fileset.ignore?("my_file").should be_true
+ end
+
+ it "should ignore files whose paths match any of multiple provided ignore values" do
+ @fileset.ignore = [".svn", "CVS"]
+ File.stubs(:fnmatch?).with(".svn", "my_file").returns false
+ File.stubs(:fnmatch?).with("CVS", "my_file").returns true
+ @fileset.ignore?("my_file").should be_true
+ end
end
describe Puppet::FileServing::Fileset, "when merging other filesets" do
- before do
- @paths = %w{/first/path /second/path /third/path}
-
- @filesets = @paths.collect do |path|
- File.stubs(:lstat).with(path).returns stub("stat", :directory? => true)
- Puppet::FileServing::Fileset.new(path, :recurse => true)
- end
-
- Dir.stubs(:entries).returns []
- end
-
- it "should return a hash of all files in each fileset with the value being the base path" do
- Dir.expects(:entries).with("/first/path").returns(%w{one uno})
- Dir.expects(:entries).with("/second/path").returns(%w{two dos})
- Dir.expects(:entries).with("/third/path").returns(%w{three tres})
-
- Puppet::FileServing::Fileset.merge(*@filesets).should == {
- "." => "/first/path",
- "one" => "/first/path",
- "uno" => "/first/path",
- "two" => "/second/path",
- "dos" => "/second/path",
- "three" => "/third/path",
- "tres" => "/third/path",
- }
- end
-
- it "should include the base directory from the first fileset" do
- Dir.expects(:entries).with("/first/path").returns(%w{one})
- Dir.expects(:entries).with("/second/path").returns(%w{two})
-
- Puppet::FileServing::Fileset.merge(*@filesets)["."].should == "/first/path"
- end
-
- it "should use the base path of the first found file when relative file paths conflict" do
- Dir.expects(:entries).with("/first/path").returns(%w{one})
- Dir.expects(:entries).with("/second/path").returns(%w{one})
-
- Puppet::FileServing::Fileset.merge(*@filesets)["one"].should == "/first/path"
- end
+ before do
+ @paths = %w{/first/path /second/path /third/path}
+
+ @filesets = @paths.collect do |path|
+ File.stubs(:lstat).with(path).returns stub("stat", :directory? => true)
+ Puppet::FileServing::Fileset.new(path, :recurse => true)
+ end
+
+ Dir.stubs(:entries).returns []
+ end
+
+ it "should return a hash of all files in each fileset with the value being the base path" do
+ Dir.expects(:entries).with("/first/path").returns(%w{one uno})
+ Dir.expects(:entries).with("/second/path").returns(%w{two dos})
+ Dir.expects(:entries).with("/third/path").returns(%w{three tres})
+
+ Puppet::FileServing::Fileset.merge(*@filesets).should == {
+ "." => "/first/path",
+ "one" => "/first/path",
+ "uno" => "/first/path",
+ "two" => "/second/path",
+ "dos" => "/second/path",
+ "three" => "/third/path",
+ "tres" => "/third/path",
+ }
+ end
+
+ it "should include the base directory from the first fileset" do
+ Dir.expects(:entries).with("/first/path").returns(%w{one})
+ Dir.expects(:entries).with("/second/path").returns(%w{two})
+
+ Puppet::FileServing::Fileset.merge(*@filesets)["."].should == "/first/path"
+ end
+
+ it "should use the base path of the first found file when relative file paths conflict" do
+ Dir.expects(:entries).with("/first/path").returns(%w{one})
+ Dir.expects(:entries).with("/second/path").returns(%w{one})
+
+ Puppet::FileServing::Fileset.merge(*@filesets)["one"].should == "/first/path"
+ end
end
diff --git a/spec/unit/file_serving/indirection_hooks_spec.rb b/spec/unit/file_serving/indirection_hooks_spec.rb
index fee504b..683efa7 100755
--- a/spec/unit/file_serving/indirection_hooks_spec.rb
+++ b/spec/unit/file_serving/indirection_hooks_spec.rb
@@ -8,56 +8,56 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/file_serving/indirection_hooks'
describe Puppet::FileServing::IndirectionHooks do
- before do
- @object = Object.new
- @object.extend(Puppet::FileServing::IndirectionHooks)
+ before do
+ @object = Object.new
+ @object.extend(Puppet::FileServing::IndirectionHooks)
- @request = stub 'request', :key => "mymod/myfile", :options => {:node => "whatever"}, :server => nil, :protocol => nil
+ @request = stub 'request', :key => "mymod/myfile", :options => {:node => "whatever"}, :server => nil, :protocol => nil
+ end
+
+ describe "when being used to select termini" do
+ it "should return :file if the request key is fully qualified" do
+ @request.expects(:key).returns "#{File::SEPARATOR}foo"
+ @object.select_terminus(@request).should == :file
+ end
+
+ it "should return :file if the URI protocol is set to 'file'" do
+ @request.expects(:protocol).returns "file"
+ @object.select_terminus(@request).should == :file
+ end
+
+ it "should fail when a protocol other than :puppet or :file is used" do
+ @request.stubs(:protocol).returns "http"
+ proc { @object.select_terminus(@request) }.should raise_error(ArgumentError)
end
- describe "when being used to select termini" do
- it "should return :file if the request key is fully qualified" do
- @request.expects(:key).returns "#{File::SEPARATOR}foo"
- @object.select_terminus(@request).should == :file
- end
-
- it "should return :file if the URI protocol is set to 'file'" do
- @request.expects(:protocol).returns "file"
- @object.select_terminus(@request).should == :file
- end
-
- it "should fail when a protocol other than :puppet or :file is used" do
- @request.stubs(:protocol).returns "http"
- proc { @object.select_terminus(@request) }.should raise_error(ArgumentError)
- end
-
- describe "and the protocol is 'puppet'" do
- before do
- @request.stubs(:protocol).returns "puppet"
- end
-
- it "should choose :rest when a server is specified" do
- @request.stubs(:protocol).returns "puppet"
- @request.expects(:server).returns "foo"
- @object.select_terminus(@request).should == :rest
- end
-
- # This is so a given file location works when bootstrapping with no server.
- it "should choose :rest when the Settings name isn't 'puppet'" do
- @request.stubs(:protocol).returns "puppet"
- @request.stubs(:server).returns "foo"
- Puppet.settings.stubs(:value).with(:name).returns "foo"
- @object.select_terminus(@request).should == :rest
- end
-
- it "should choose :file_server when the settings name is 'puppet' and no server is specified" do
- modules = mock 'modules'
-
- @request.expects(:protocol).returns "puppet"
- @request.expects(:server).returns nil
- Puppet.settings.expects(:value).with(:name).returns "puppet"
- @object.select_terminus(@request).should == :file_server
- end
- end
+ describe "and the protocol is 'puppet'" do
+ before do
+ @request.stubs(:protocol).returns "puppet"
+ end
+
+ it "should choose :rest when a server is specified" do
+ @request.stubs(:protocol).returns "puppet"
+ @request.expects(:server).returns "foo"
+ @object.select_terminus(@request).should == :rest
+ end
+
+ # This is so a given file location works when bootstrapping with no server.
+ it "should choose :rest when the Settings name isn't 'puppet'" do
+ @request.stubs(:protocol).returns "puppet"
+ @request.stubs(:server).returns "foo"
+ Puppet.settings.stubs(:value).with(:name).returns "foo"
+ @object.select_terminus(@request).should == :rest
+ end
+
+ it "should choose :file_server when the settings name is 'puppet' and no server is specified" do
+ modules = mock 'modules'
+
+ @request.expects(:protocol).returns "puppet"
+ @request.expects(:server).returns nil
+ Puppet.settings.expects(:value).with(:name).returns "puppet"
+ @object.select_terminus(@request).should == :file_server
+ end
end
+ end
end
diff --git a/spec/unit/file_serving/metadata_spec.rb b/spec/unit/file_serving/metadata_spec.rb
index 42bbf3b..aa0dcd5 100755
--- a/spec/unit/file_serving/metadata_spec.rb
+++ b/spec/unit/file_serving/metadata_spec.rb
@@ -5,282 +5,282 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/file_serving/metadata'
describe Puppet::FileServing::Metadata do
- it "should should be a subclass of Base" do
- Puppet::FileServing::Metadata.superclass.should equal(Puppet::FileServing::Base)
- end
+ it "should should be a subclass of Base" do
+ Puppet::FileServing::Metadata.superclass.should equal(Puppet::FileServing::Base)
+ end
- it "should indirect file_metadata" do
- Puppet::FileServing::Metadata.indirection.name.should == :file_metadata
- end
+ it "should indirect file_metadata" do
+ Puppet::FileServing::Metadata.indirection.name.should == :file_metadata
+ end
- it "should should include the IndirectionHooks module in its indirection" do
- Puppet::FileServing::Metadata.indirection.singleton_class.included_modules.should include(Puppet::FileServing::IndirectionHooks)
- end
+ it "should should include the IndirectionHooks module in its indirection" do
+ Puppet::FileServing::Metadata.indirection.singleton_class.included_modules.should include(Puppet::FileServing::IndirectionHooks)
+ end
- it "should have a method that triggers attribute collection" do
- Puppet::FileServing::Metadata.new("/foo/bar").should respond_to(:collect)
- end
+ it "should have a method that triggers attribute collection" do
+ Puppet::FileServing::Metadata.new("/foo/bar").should respond_to(:collect)
+ end
- it "should support pson serialization" do
- Puppet::FileServing::Metadata.new("/foo/bar").should respond_to(:to_pson)
- end
-
- it "should support to_pson_data_hash" do
- Puppet::FileServing::Metadata.new("/foo/bar").should respond_to(:to_pson_data_hash)
- end
+ it "should support pson serialization" do
+ Puppet::FileServing::Metadata.new("/foo/bar").should respond_to(:to_pson)
+ end
- it "should support pson deserialization" do
- Puppet::FileServing::Metadata.should respond_to(:from_pson)
- end
+ it "should support to_pson_data_hash" do
+ Puppet::FileServing::Metadata.new("/foo/bar").should respond_to(:to_pson_data_hash)
+ end
- describe "when serializing" do
- before do
- @metadata = Puppet::FileServing::Metadata.new("/foo/bar")
- end
- it "should perform pson serialization by calling to_pson on it's pson_data_hash" do
- pdh = mock "data hash"
- pdh_as_pson = mock "data as pson"
- @metadata.expects(:to_pson_data_hash).returns pdh
- pdh.expects(:to_pson).returns pdh_as_pson
- @metadata.to_pson.should == pdh_as_pson
- end
+ it "should support pson deserialization" do
+ Puppet::FileServing::Metadata.should respond_to(:from_pson)
+ end
- it "should serialize as FileMetadata" do
- @metadata.to_pson_data_hash['document_type'].should == "FileMetadata"
- end
+ describe "when serializing" do
+ before do
+ @metadata = Puppet::FileServing::Metadata.new("/foo/bar")
+ end
+ it "should perform pson serialization by calling to_pson on it's pson_data_hash" do
+ pdh = mock "data hash"
+ pdh_as_pson = mock "data as pson"
+ @metadata.expects(:to_pson_data_hash).returns pdh
+ pdh.expects(:to_pson).returns pdh_as_pson
+ @metadata.to_pson.should == pdh_as_pson
+ end
- it "the data should include the path, relative_path, links, owner, group, mode, checksum, type, and destination" do
- @metadata.to_pson_data_hash['data'].keys.sort.should == %w{ path relative_path links owner group mode checksum type destination }.sort
- end
+ it "should serialize as FileMetadata" do
+ @metadata.to_pson_data_hash['document_type'].should == "FileMetadata"
+ end
- it "should pass the path in the hash verbatum" do
- @metadata.to_pson_data_hash['data']['path'] == @metadata.path
- end
+ it "the data should include the path, relative_path, links, owner, group, mode, checksum, type, and destination" do
+ @metadata.to_pson_data_hash['data'].keys.sort.should == %w{ path relative_path links owner group mode checksum type destination }.sort
+ end
- it "should pass the relative_path in the hash verbatum" do
- @metadata.to_pson_data_hash['data']['relative_path'] == @metadata.relative_path
- end
+ it "should pass the path in the hash verbatum" do
+ @metadata.to_pson_data_hash['data']['path'] == @metadata.path
+ end
- it "should pass the links in the hash verbatum" do
- @metadata.to_pson_data_hash['data']['links'] == @metadata.links
- end
+ it "should pass the relative_path in the hash verbatum" do
+ @metadata.to_pson_data_hash['data']['relative_path'] == @metadata.relative_path
+ end
- it "should pass the path owner in the hash verbatum" do
- @metadata.to_pson_data_hash['data']['owner'] == @metadata.owner
- end
+ it "should pass the links in the hash verbatum" do
+ @metadata.to_pson_data_hash['data']['links'] == @metadata.links
+ end
- it "should pass the group in the hash verbatum" do
- @metadata.to_pson_data_hash['data']['group'] == @metadata.group
- end
+ it "should pass the path owner in the hash verbatum" do
+ @metadata.to_pson_data_hash['data']['owner'] == @metadata.owner
+ end
- it "should pass the mode in the hash verbatum" do
- @metadata.to_pson_data_hash['data']['mode'] == @metadata.mode
- end
+ it "should pass the group in the hash verbatum" do
+ @metadata.to_pson_data_hash['data']['group'] == @metadata.group
+ end
- it "should pass the ftype in the hash verbatum as the 'type'" do
- @metadata.to_pson_data_hash['data']['type'] == @metadata.ftype
- end
+ it "should pass the mode in the hash verbatum" do
+ @metadata.to_pson_data_hash['data']['mode'] == @metadata.mode
+ end
- it "should pass the destination verbatum" do
- @metadata.to_pson_data_hash['data']['destination'] == @metadata.destination
- end
+ it "should pass the ftype in the hash verbatum as the 'type'" do
+ @metadata.to_pson_data_hash['data']['type'] == @metadata.ftype
+ end
- it "should pass the checksum in the hash as a nested hash" do
- @metadata.to_pson_data_hash['data']['checksum'].should be_is_a(Hash)
- end
+ it "should pass the destination verbatum" do
+ @metadata.to_pson_data_hash['data']['destination'] == @metadata.destination
+ end
- it "should pass the checksum_type in the hash verbatum as the checksum's type" do
- @metadata.to_pson_data_hash['data']['checksum']['type'] == @metadata.checksum_type
- end
+ it "should pass the checksum in the hash as a nested hash" do
+ @metadata.to_pson_data_hash['data']['checksum'].should be_is_a(Hash)
+ end
- it "should pass the checksum in the hash verbatum as the checksum's value" do
- @metadata.to_pson_data_hash['data']['checksum']['value'] == @metadata.checksum
- end
+ it "should pass the checksum_type in the hash verbatum as the checksum's type" do
+ @metadata.to_pson_data_hash['data']['checksum']['type'] == @metadata.checksum_type
+ end
+ it "should pass the checksum in the hash verbatum as the checksum's value" do
+ @metadata.to_pson_data_hash['data']['checksum']['value'] == @metadata.checksum
end
+
+ end
end
describe Puppet::FileServing::Metadata, " when finding the file to use for setting attributes" do
- before do
- @path = "/my/path"
- @metadata = Puppet::FileServing::Metadata.new(@path)
-
- # Use a link because it's easier to test -- no checksumming
- @stat = stub "stat", :uid => 10, :gid => 20, :mode => 0755, :ftype => "link"
-
- # Not quite. We don't want to checksum links, but we must because they might be being followed.
- @checksum = Digest::MD5.hexdigest("some content\n") # Remove these when :managed links are no longer checksumed.
- @metadata.stubs(:md5_file).returns(@checksum) #
- end
+ before do
+ @path = "/my/path"
+ @metadata = Puppet::FileServing::Metadata.new(@path)
+
+ # Use a link because it's easier to test -- no checksumming
+ @stat = stub "stat", :uid => 10, :gid => 20, :mode => 0755, :ftype => "link"
+
+ # Not quite. We don't want to checksum links, but we must because they might be being followed.
+ @checksum = Digest::MD5.hexdigest("some content\n") # Remove these when :managed links are no longer checksumed.
+ @metadata.stubs(:md5_file).returns(@checksum) #
+ end
+
+ it "should accept a base path path to which the file should be relative" do
+ File.expects(:lstat).with(@path).returns @stat
+ File.expects(:readlink).with(@path).returns "/what/ever"
+ @metadata.collect
+ end
+
+ it "should use the set base path if one is not provided" do
+ File.expects(:lstat).with(@path).returns @stat
+ File.expects(:readlink).with(@path).returns "/what/ever"
+ @metadata.collect
+ end
+
+ it "should raise an exception if the file does not exist" do
+ File.expects(:lstat).with(@path).raises(Errno::ENOENT)
+ proc { @metadata.collect}.should raise_error(Errno::ENOENT)
+ end
+end
- it "should accept a base path path to which the file should be relative" do
- File.expects(:lstat).with(@path).returns @stat
- File.expects(:readlink).with(@path).returns "/what/ever"
- @metadata.collect
+describe Puppet::FileServing::Metadata, " when collecting attributes" do
+ before do
+ @path = "/my/file"
+ # Use a real file mode, so we can validate the masking is done.
+ @stat = stub 'stat', :uid => 10, :gid => 20, :mode => 33261, :ftype => "file"
+ File.stubs(:lstat).returns(@stat)
+ @checksum = Digest::MD5.hexdigest("some content\n")
+ @metadata = Puppet::FileServing::Metadata.new("/my/file")
+ @metadata.stubs(:md5_file).returns(@checksum)
+ @metadata.collect
+ end
+
+ it "should be able to produce xmlrpc-style attribute information" do
+ @metadata.should respond_to(:attributes_with_tabs)
+ end
+
+ # LAK:FIXME This should actually change at some point
+ it "should set the owner by id" do
+ @metadata.owner.should be_instance_of(Fixnum)
+ end
+
+ # LAK:FIXME This should actually change at some point
+ it "should set the group by id" do
+ @metadata.group.should be_instance_of(Fixnum)
+ end
+
+ it "should set the owner to the file's current owner" do
+ @metadata.owner.should == 10
+ end
+
+ it "should set the group to the file's current group" do
+ @metadata.group.should == 20
+ end
+
+ it "should set the mode to the file's masked mode" do
+ @metadata.mode.should == 0755
+ end
+
+ it "should set the checksum to the file's current checksum" do
+ @metadata.checksum.should == "{md5}#{@checksum}"
+ end
+
+ describe "when managing files" do
+ it "should default to a checksum of type MD5" do
+ @metadata.checksum.should == "{md5}#{@checksum}"
end
- it "should use the set base path if one is not provided" do
- File.expects(:lstat).with(@path).returns @stat
- File.expects(:readlink).with(@path).returns "/what/ever"
- @metadata.collect
+ it "should give a mtime checksum when checksum_type is set" do
+ time = Time.now
+ @metadata.checksum_type = "mtime"
+ @metadata.expects(:mtime_file).returns(@time)
+ @metadata.collect
+ @metadata.checksum.should == "{mtime}#{@time}"
end
- it "should raise an exception if the file does not exist" do
- File.expects(:lstat).with(@path).raises(Errno::ENOENT)
- proc { @metadata.collect}.should raise_error(Errno::ENOENT)
+ it "should produce tab-separated mode, type, owner, group, and checksum for xmlrpc" do
+ @metadata.attributes_with_tabs.should == "#{0755.to_s}\tfile\t10\t20\t{md5}#{@checksum}"
end
-end
+ end
-describe Puppet::FileServing::Metadata, " when collecting attributes" do
+ describe "when managing directories" do
before do
- @path = "/my/file"
- # Use a real file mode, so we can validate the masking is done.
- @stat = stub 'stat', :uid => 10, :gid => 20, :mode => 33261, :ftype => "file"
- File.stubs(:lstat).returns(@stat)
- @checksum = Digest::MD5.hexdigest("some content\n")
- @metadata = Puppet::FileServing::Metadata.new("/my/file")
- @metadata.stubs(:md5_file).returns(@checksum)
- @metadata.collect
+ @stat.stubs(:ftype).returns("directory")
+ @time = Time.now
+ @metadata.expects(:ctime_file).returns(@time)
end
- it "should be able to produce xmlrpc-style attribute information" do
- @metadata.should respond_to(:attributes_with_tabs)
+ it "should only use checksums of type 'ctime' for directories" do
+ @metadata.collect
+ @metadata.checksum.should == "{ctime}#{@time}"
end
- # LAK:FIXME This should actually change at some point
- it "should set the owner by id" do
- @metadata.owner.should be_instance_of(Fixnum)
+ it "should only use checksums of type 'ctime' for directories even if checksum_type set" do
+ @metadata.checksum_type = "mtime"
+ @metadata.expects(:mtime_file).never
+ @metadata.collect
+ @metadata.checksum.should == "{ctime}#{@time}"
end
- # LAK:FIXME This should actually change at some point
- it "should set the group by id" do
- @metadata.group.should be_instance_of(Fixnum)
+ it "should produce tab-separated mode, type, owner, group, and checksum for xmlrpc" do
+ @metadata.collect
+ @metadata.attributes_with_tabs.should == "#{0755.to_s}\tdirectory\t10\t20\t{ctime}#{@time.to_s}"
end
+ end
- it "should set the owner to the file's current owner" do
- @metadata.owner.should == 10
- end
+ describe "when managing links" do
+ before do
+ @stat.stubs(:ftype).returns("link")
+ File.expects(:readlink).with("/my/file").returns("/path/to/link")
+ @metadata.collect
- it "should set the group to the file's current group" do
- @metadata.group.should == 20
+ @checksum = Digest::MD5.hexdigest("some content\n") # Remove these when :managed links are no longer checksumed.
+ @file.stubs(:md5_file).returns(@checksum) #
end
- it "should set the mode to the file's masked mode" do
- @metadata.mode.should == 0755
+ it "should read links instead of returning their checksums" do
+ @metadata.destination.should == "/path/to/link"
end
- it "should set the checksum to the file's current checksum" do
- @metadata.checksum.should == "{md5}#{@checksum}"
+ it "should produce tab-separated mode, type, owner, group, and destination for xmlrpc" do
+ pending "We'd like this to be true, but we need to always collect the checksum because in the server/client/server round trip we lose the distintion between manage and follow."
+ @metadata.attributes_with_tabs.should == "#{0755}\tlink\t10\t20\t/path/to/link"
end
- describe "when managing files" do
- it "should default to a checksum of type MD5" do
- @metadata.checksum.should == "{md5}#{@checksum}"
- end
-
- it "should give a mtime checksum when checksum_type is set" do
- time = Time.now
- @metadata.checksum_type = "mtime"
- @metadata.expects(:mtime_file).returns(@time)
- @metadata.collect
- @metadata.checksum.should == "{mtime}#{@time}"
- end
-
- it "should produce tab-separated mode, type, owner, group, and checksum for xmlrpc" do
- @metadata.attributes_with_tabs.should == "#{0755.to_s}\tfile\t10\t20\t{md5}#{@checksum}"
- end
+ it "should produce tab-separated mode, type, owner, group, checksum, and destination for xmlrpc" do
+ @metadata.attributes_with_tabs.should == "#{0755}\tlink\t10\t20\t{md5}eb9c2bf0eb63f3a7bc0ea37ef18aeba5\t/path/to/link"
end
+ end
+end
- describe "when managing directories" do
- before do
- @stat.stubs(:ftype).returns("directory")
- @time = Time.now
- @metadata.expects(:ctime_file).returns(@time)
- end
-
- it "should only use checksums of type 'ctime' for directories" do
- @metadata.collect
- @metadata.checksum.should == "{ctime}#{@time}"
- end
-
- it "should only use checksums of type 'ctime' for directories even if checksum_type set" do
- @metadata.checksum_type = "mtime"
- @metadata.expects(:mtime_file).never
- @metadata.collect
- @metadata.checksum.should == "{ctime}#{@time}"
- end
+describe Puppet::FileServing::Metadata, " when pointing to a link" do
+ describe "when links are managed" do
+ before do
+ @file = Puppet::FileServing::Metadata.new("/base/path/my/file", :links => :manage)
+ File.expects(:lstat).with("/base/path/my/file").returns stub("stat", :uid => 1, :gid => 2, :ftype => "link", :mode => 0755)
+ File.expects(:readlink).with("/base/path/my/file").returns "/some/other/path"
- it "should produce tab-separated mode, type, owner, group, and checksum for xmlrpc" do
- @metadata.collect
- @metadata.attributes_with_tabs.should == "#{0755.to_s}\tdirectory\t10\t20\t{ctime}#{@time.to_s}"
- end
+ @checksum = Digest::MD5.hexdigest("some content\n") # Remove these when :managed links are no longer checksumed.
+ @file.stubs(:md5_file).returns(@checksum) #
end
-
- describe "when managing links" do
- before do
- @stat.stubs(:ftype).returns("link")
- File.expects(:readlink).with("/my/file").returns("/path/to/link")
- @metadata.collect
-
- @checksum = Digest::MD5.hexdigest("some content\n") # Remove these when :managed links are no longer checksumed.
- @file.stubs(:md5_file).returns(@checksum) #
- end
-
- it "should read links instead of returning their checksums" do
- @metadata.destination.should == "/path/to/link"
- end
-
- it "should produce tab-separated mode, type, owner, group, and destination for xmlrpc" do
- pending "We'd like this to be true, but we need to always collect the checksum because in the server/client/server round trip we lose the distintion between manage and follow."
- @metadata.attributes_with_tabs.should == "#{0755}\tlink\t10\t20\t/path/to/link"
- end
-
- it "should produce tab-separated mode, type, owner, group, checksum, and destination for xmlrpc" do
- @metadata.attributes_with_tabs.should == "#{0755}\tlink\t10\t20\t{md5}eb9c2bf0eb63f3a7bc0ea37ef18aeba5\t/path/to/link"
- end
+ it "should store the destination of the link in :destination if links are :manage" do
+ @file.collect
+ @file.destination.should == "/some/other/path"
end
-end
+ it "should not collect the checksum if links are :manage" do
+ pending "We'd like this to be true, but we need to always collect the checksum because in the server/client/server round trip we lose the distintion between manage and follow."
+ @file.collect
+ @file.checksum.should be_nil
+ end
+ it "should collect the checksum if links are :manage" do # see pending note above
+ @file.collect
+ @file.checksum.should == "{md5}#{@checksum}"
+ end
+ end
-describe Puppet::FileServing::Metadata, " when pointing to a link" do
- describe "when links are managed" do
- before do
- @file = Puppet::FileServing::Metadata.new("/base/path/my/file", :links => :manage)
- File.expects(:lstat).with("/base/path/my/file").returns stub("stat", :uid => 1, :gid => 2, :ftype => "link", :mode => 0755)
- File.expects(:readlink).with("/base/path/my/file").returns "/some/other/path"
-
- @checksum = Digest::MD5.hexdigest("some content\n") # Remove these when :managed links are no longer checksumed.
- @file.stubs(:md5_file).returns(@checksum) #
- end
- it "should store the destination of the link in :destination if links are :manage" do
- @file.collect
- @file.destination.should == "/some/other/path"
- end
- it "should not collect the checksum if links are :manage" do
- pending "We'd like this to be true, but we need to always collect the checksum because in the server/client/server round trip we lose the distintion between manage and follow."
- @file.collect
- @file.checksum.should be_nil
- end
- it "should collect the checksum if links are :manage" do # see pending note above
- @file.collect
- @file.checksum.should == "{md5}#{@checksum}"
- end
- end
-
- describe "when links are followed" do
- before do
- @file = Puppet::FileServing::Metadata.new("/base/path/my/file", :links => :follow)
- File.expects(:stat).with("/base/path/my/file").returns stub("stat", :uid => 1, :gid => 2, :ftype => "file", :mode => 0755)
- File.expects(:readlink).with("/base/path/my/file").never
- @checksum = Digest::MD5.hexdigest("some content\n")
- @file.stubs(:md5_file).returns(@checksum)
- end
- it "should not store the destination of the link in :destination if links are :follow" do
- @file.collect
- @file.destination.should be_nil
- end
- it "should collect the checksum if links are :follow" do
- @file.collect
- @file.checksum.should == "{md5}#{@checksum}"
- end
+ describe "when links are followed" do
+ before do
+ @file = Puppet::FileServing::Metadata.new("/base/path/my/file", :links => :follow)
+ File.expects(:stat).with("/base/path/my/file").returns stub("stat", :uid => 1, :gid => 2, :ftype => "file", :mode => 0755)
+ File.expects(:readlink).with("/base/path/my/file").never
+ @checksum = Digest::MD5.hexdigest("some content\n")
+ @file.stubs(:md5_file).returns(@checksum)
+ end
+ it "should not store the destination of the link in :destination if links are :follow" do
+ @file.collect
+ @file.destination.should be_nil
+ end
+ it "should collect the checksum if links are :follow" do
+ @file.collect
+ @file.checksum.should == "{md5}#{@checksum}"
end
+ end
end
diff --git a/spec/unit/file_serving/mount/file_spec.rb b/spec/unit/file_serving/mount/file_spec.rb
index e77523f..56b4f54 100755
--- a/spec/unit/file_serving/mount/file_spec.rb
+++ b/spec/unit/file_serving/mount/file_spec.rb
@@ -4,193 +4,193 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/file_serving/mount/file'
module FileServingMountTesting
- def stub_facter(hostname)
- Facter.stubs(:value).with("hostname").returns(hostname.sub(/\..+/, ''))
- Facter.stubs(:value).with("domain").returns(hostname.sub(/^[^.]+\./, ''))
- end
+ def stub_facter(hostname)
+ Facter.stubs(:value).with("hostname").returns(hostname.sub(/\..+/, ''))
+ Facter.stubs(:value).with("domain").returns(hostname.sub(/^[^.]+\./, ''))
+ end
end
describe Puppet::FileServing::Mount::File do
- it "should provide a method for clearing its cached host information" do
- old = Puppet::FileServing::Mount::File.localmap
- Puppet::Util::Cacher.expire
- Puppet::FileServing::Mount::File.localmap.should_not equal(old)
- end
-
- it "should be invalid if it does not have a path" do
- lambda { Puppet::FileServing::Mount::File.new("foo").validate }.should raise_error(ArgumentError)
- end
-
- it "should be valid if it has a path" do
- FileTest.stubs(:directory?).returns true
- FileTest.stubs(:readable?).returns true
- mount = Puppet::FileServing::Mount::File.new("foo")
- mount.path = "/foo"
- lambda { mount.validate }.should_not raise_error(ArgumentError)
- end
+ it "should provide a method for clearing its cached host information" do
+ old = Puppet::FileServing::Mount::File.localmap
+ Puppet::Util::Cacher.expire
+ Puppet::FileServing::Mount::File.localmap.should_not equal(old)
+ end
+
+ it "should be invalid if it does not have a path" do
+ lambda { Puppet::FileServing::Mount::File.new("foo").validate }.should raise_error(ArgumentError)
+ end
+
+ it "should be valid if it has a path" do
+ FileTest.stubs(:directory?).returns true
+ FileTest.stubs(:readable?).returns true
+ mount = Puppet::FileServing::Mount::File.new("foo")
+ mount.path = "/foo"
+ lambda { mount.validate }.should_not raise_error(ArgumentError)
+ end
end
describe Puppet::FileServing::Mount::File, " when setting the path" do
- before do
- @mount = Puppet::FileServing::Mount::File.new("test")
- @dir = "/this/path/does/not/exist"
- end
-
- it "should fail if the path is not a directory" do
- FileTest.expects(:directory?).returns(false)
- proc { @mount.path = @dir }.should raise_error(ArgumentError)
- end
-
- it "should fail if the path is not readable" do
- FileTest.expects(:directory?).returns(true)
- FileTest.expects(:readable?).returns(false)
- proc { @mount.path = @dir }.should raise_error(ArgumentError)
- end
+ before do
+ @mount = Puppet::FileServing::Mount::File.new("test")
+ @dir = "/this/path/does/not/exist"
+ end
+
+ it "should fail if the path is not a directory" do
+ FileTest.expects(:directory?).returns(false)
+ proc { @mount.path = @dir }.should raise_error(ArgumentError)
+ end
+
+ it "should fail if the path is not readable" do
+ FileTest.expects(:directory?).returns(true)
+ FileTest.expects(:readable?).returns(false)
+ proc { @mount.path = @dir }.should raise_error(ArgumentError)
+ end
end
describe Puppet::FileServing::Mount::File, " when substituting hostnames and ip addresses into file paths" do
- include FileServingMountTesting
-
- before do
- FileTest.stubs(:directory?).returns(true)
- FileTest.stubs(:readable?).returns(true)
- @mount = Puppet::FileServing::Mount::File.new("test")
- @host = "host.domain.com"
- end
-
- it "should replace incidences of %h in the path with the client's short name" do
- @mount.path = "/dir/%h/yay"
- @mount.path(@host).should == "/dir/host/yay"
- end
-
- it "should replace incidences of %H in the path with the client's fully qualified name" do
- @mount.path = "/dir/%H/yay"
- @mount.path(@host).should == "/dir/host.domain.com/yay"
- end
-
- it "should replace incidences of %d in the path with the client's domain name" do
- @mount.path = "/dir/%d/yay"
- @mount.path(@host).should == "/dir/domain.com/yay"
- end
-
- it "should perform all necessary replacements" do
- @mount.path = "/%h/%d/%H"
- @mount.path(@host).should == "/host/domain.com/host.domain.com"
- end
-
- it "should use local host information if no client data is provided" do
- stub_facter("myhost.mydomain.com")
- @mount.path = "/%h/%d/%H"
- @mount.path.should == "/myhost/mydomain.com/myhost.mydomain.com"
- end
-
- after do
- Puppet::Util::Cacher.expire
- end
+ include FileServingMountTesting
+
+ before do
+ FileTest.stubs(:directory?).returns(true)
+ FileTest.stubs(:readable?).returns(true)
+ @mount = Puppet::FileServing::Mount::File.new("test")
+ @host = "host.domain.com"
+ end
+
+ it "should replace incidences of %h in the path with the client's short name" do
+ @mount.path = "/dir/%h/yay"
+ @mount.path(@host).should == "/dir/host/yay"
+ end
+
+ it "should replace incidences of %H in the path with the client's fully qualified name" do
+ @mount.path = "/dir/%H/yay"
+ @mount.path(@host).should == "/dir/host.domain.com/yay"
+ end
+
+ it "should replace incidences of %d in the path with the client's domain name" do
+ @mount.path = "/dir/%d/yay"
+ @mount.path(@host).should == "/dir/domain.com/yay"
+ end
+
+ it "should perform all necessary replacements" do
+ @mount.path = "/%h/%d/%H"
+ @mount.path(@host).should == "/host/domain.com/host.domain.com"
+ end
+
+ it "should use local host information if no client data is provided" do
+ stub_facter("myhost.mydomain.com")
+ @mount.path = "/%h/%d/%H"
+ @mount.path.should == "/myhost/mydomain.com/myhost.mydomain.com"
+ end
+
+ after do
+ Puppet::Util::Cacher.expire
+ end
end
describe Puppet::FileServing::Mount::File, "when determining the complete file path" do
- include FileServingMountTesting
-
- before do
- FileTest.stubs(:exist?).returns(true)
- FileTest.stubs(:directory?).returns(true)
- FileTest.stubs(:readable?).returns(true)
- @mount = Puppet::FileServing::Mount::File.new("test")
- @mount.path = "/mount"
- stub_facter("myhost.mydomain.com")
- @host = "host.domain.com"
- end
-
- it "should return nil if the file is absent" do
- FileTest.stubs(:exist?).returns(false)
- @mount.complete_path("/my/path", nil).should be_nil
- end
-
- it "should write a log message if the file is absent" do
- FileTest.stubs(:exist?).returns(false)
-
- Puppet.expects(:info).with("File does not exist or is not accessible: /mount/my/path")
-
- @mount.complete_path("/my/path", nil)
- end
-
- it "should return the file path if the file is present" do
- FileTest.stubs(:exist?).with("/my/path").returns(true)
- @mount.complete_path("/my/path", nil).should == "/mount/my/path"
- end
-
- it "should treat a nil file name as the path to the mount itself" do
- FileTest.stubs(:exist?).returns(true)
- @mount.complete_path(nil, nil).should == "/mount"
- end
-
- it "should use the client host name if provided in the options" do
- @mount.path = "/mount/%h"
- @mount.complete_path("/my/path", @host).should == "/mount/host/my/path"
- end
-
- it "should perform replacements on the base path" do
- @mount.path = "/blah/%h"
- @mount.complete_path("/my/stuff", @host).should == "/blah/host/my/stuff"
- end
-
- it "should not perform replacements on the per-file path" do
- @mount.path = "/blah"
- @mount.complete_path("/%h/stuff", @host).should == "/blah/%h/stuff"
- end
-
- it "should look for files relative to its base directory" do
- @mount.complete_path("/my/stuff", @host).should == "/mount/my/stuff"
- end
+ include FileServingMountTesting
+
+ before do
+ FileTest.stubs(:exist?).returns(true)
+ FileTest.stubs(:directory?).returns(true)
+ FileTest.stubs(:readable?).returns(true)
+ @mount = Puppet::FileServing::Mount::File.new("test")
+ @mount.path = "/mount"
+ stub_facter("myhost.mydomain.com")
+ @host = "host.domain.com"
+ end
+
+ it "should return nil if the file is absent" do
+ FileTest.stubs(:exist?).returns(false)
+ @mount.complete_path("/my/path", nil).should be_nil
+ end
+
+ it "should write a log message if the file is absent" do
+ FileTest.stubs(:exist?).returns(false)
+
+ Puppet.expects(:info).with("File does not exist or is not accessible: /mount/my/path")
+
+ @mount.complete_path("/my/path", nil)
+ end
+
+ it "should return the file path if the file is present" do
+ FileTest.stubs(:exist?).with("/my/path").returns(true)
+ @mount.complete_path("/my/path", nil).should == "/mount/my/path"
+ end
+
+ it "should treat a nil file name as the path to the mount itself" do
+ FileTest.stubs(:exist?).returns(true)
+ @mount.complete_path(nil, nil).should == "/mount"
+ end
+
+ it "should use the client host name if provided in the options" do
+ @mount.path = "/mount/%h"
+ @mount.complete_path("/my/path", @host).should == "/mount/host/my/path"
+ end
+
+ it "should perform replacements on the base path" do
+ @mount.path = "/blah/%h"
+ @mount.complete_path("/my/stuff", @host).should == "/blah/host/my/stuff"
+ end
+
+ it "should not perform replacements on the per-file path" do
+ @mount.path = "/blah"
+ @mount.complete_path("/%h/stuff", @host).should == "/blah/%h/stuff"
+ end
+
+ it "should look for files relative to its base directory" do
+ @mount.complete_path("/my/stuff", @host).should == "/mount/my/stuff"
+ end
end
describe Puppet::FileServing::Mount::File, "when finding files" do
- include FileServingMountTesting
-
- before do
- FileTest.stubs(:exist?).returns(true)
- FileTest.stubs(:directory?).returns(true)
- FileTest.stubs(:readable?).returns(true)
- @mount = Puppet::FileServing::Mount::File.new("test")
- @mount.path = "/mount"
- stub_facter("myhost.mydomain.com")
- @host = "host.domain.com"
-
- @request = stub 'request', :node => "foo"
- end
-
- it "should return the results of the complete file path" do
- FileTest.stubs(:exist?).returns(false)
- @mount.expects(:complete_path).with("/my/path", "foo").returns "eh"
- @mount.find("/my/path", @request).should == "eh"
- end
+ include FileServingMountTesting
+
+ before do
+ FileTest.stubs(:exist?).returns(true)
+ FileTest.stubs(:directory?).returns(true)
+ FileTest.stubs(:readable?).returns(true)
+ @mount = Puppet::FileServing::Mount::File.new("test")
+ @mount.path = "/mount"
+ stub_facter("myhost.mydomain.com")
+ @host = "host.domain.com"
+
+ @request = stub 'request', :node => "foo"
+ end
+
+ it "should return the results of the complete file path" do
+ FileTest.stubs(:exist?).returns(false)
+ @mount.expects(:complete_path).with("/my/path", "foo").returns "eh"
+ @mount.find("/my/path", @request).should == "eh"
+ end
end
describe Puppet::FileServing::Mount::File, "when searching for files" do
- include FileServingMountTesting
-
- before do
- FileTest.stubs(:exist?).returns(true)
- FileTest.stubs(:directory?).returns(true)
- FileTest.stubs(:readable?).returns(true)
- @mount = Puppet::FileServing::Mount::File.new("test")
- @mount.path = "/mount"
- stub_facter("myhost.mydomain.com")
- @host = "host.domain.com"
-
- @request = stub 'request', :node => "foo"
- end
-
- it "should return the results of the complete file path as an array" do
- FileTest.stubs(:exist?).returns(false)
- @mount.expects(:complete_path).with("/my/path", "foo").returns "eh"
- @mount.search("/my/path", @request).should == ["eh"]
- end
-
- it "should return nil if the complete path is nil" do
- FileTest.stubs(:exist?).returns(false)
- @mount.expects(:complete_path).with("/my/path", "foo").returns nil
- @mount.search("/my/path", @request).should be_nil
- end
+ include FileServingMountTesting
+
+ before do
+ FileTest.stubs(:exist?).returns(true)
+ FileTest.stubs(:directory?).returns(true)
+ FileTest.stubs(:readable?).returns(true)
+ @mount = Puppet::FileServing::Mount::File.new("test")
+ @mount.path = "/mount"
+ stub_facter("myhost.mydomain.com")
+ @host = "host.domain.com"
+
+ @request = stub 'request', :node => "foo"
+ end
+
+ it "should return the results of the complete file path as an array" do
+ FileTest.stubs(:exist?).returns(false)
+ @mount.expects(:complete_path).with("/my/path", "foo").returns "eh"
+ @mount.search("/my/path", @request).should == ["eh"]
+ end
+
+ it "should return nil if the complete path is nil" do
+ FileTest.stubs(:exist?).returns(false)
+ @mount.expects(:complete_path).with("/my/path", "foo").returns nil
+ @mount.search("/my/path", @request).should be_nil
+ end
end
diff --git a/spec/unit/file_serving/mount/modules_spec.rb b/spec/unit/file_serving/mount/modules_spec.rb
index eeecc9a..5450b85 100755
--- a/spec/unit/file_serving/mount/modules_spec.rb
+++ b/spec/unit/file_serving/mount/modules_spec.rb
@@ -4,60 +4,60 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/file_serving/mount/modules'
describe Puppet::FileServing::Mount::Modules do
- before do
- @mount = Puppet::FileServing::Mount::Modules.new("modules")
+ before do
+ @mount = Puppet::FileServing::Mount::Modules.new("modules")
- @environment = stub 'environment', :module => nil
- @request = stub 'request', :environment => @environment
- end
+ @environment = stub 'environment', :module => nil
+ @request = stub 'request', :environment => @environment
+ end
- describe "when finding files" do
- it "should use the provided environment to find the module" do
- @environment.expects(:module)
+ describe "when finding files" do
+ it "should use the provided environment to find the module" do
+ @environment.expects(:module)
- @mount.find("foo", @request)
- end
+ @mount.find("foo", @request)
+ end
- it "should treat the first field of the relative path as the module name" do
- @environment.expects(:module).with("foo")
- @mount.find("foo/bar/baz", @request)
- end
+ it "should treat the first field of the relative path as the module name" do
+ @environment.expects(:module).with("foo")
+ @mount.find("foo/bar/baz", @request)
+ end
- it "should return nil if the specified module does not exist" do
- @environment.expects(:module).with("foo").returns nil
- @mount.find("foo/bar/baz", @request)
- end
+ it "should return nil if the specified module does not exist" do
+ @environment.expects(:module).with("foo").returns nil
+ @mount.find("foo/bar/baz", @request)
+ end
- it "should return the file path from the module" do
- mod = mock 'module'
- mod.expects(:file).with("bar/baz").returns "eh"
- @environment.expects(:module).with("foo").returns mod
- @mount.find("foo/bar/baz", @request).should == "eh"
- end
+ it "should return the file path from the module" do
+ mod = mock 'module'
+ mod.expects(:file).with("bar/baz").returns "eh"
+ @environment.expects(:module).with("foo").returns mod
+ @mount.find("foo/bar/baz", @request).should == "eh"
end
+ end
- describe "when searching for files" do
- it "should use the node's environment to search the module" do
- @environment.expects(:module)
+ describe "when searching for files" do
+ it "should use the node's environment to search the module" do
+ @environment.expects(:module)
- @mount.search("foo", @request)
- end
+ @mount.search("foo", @request)
+ end
- it "should treat the first field of the relative path as the module name" do
- @environment.expects(:module).with("foo")
- @mount.search("foo/bar/baz", @request)
- end
+ it "should treat the first field of the relative path as the module name" do
+ @environment.expects(:module).with("foo")
+ @mount.search("foo/bar/baz", @request)
+ end
- it "should return nil if the specified module does not exist" do
- @environment.expects(:module).with("foo").returns nil
- @mount.search("foo/bar/baz", @request)
- end
+ it "should return nil if the specified module does not exist" do
+ @environment.expects(:module).with("foo").returns nil
+ @mount.search("foo/bar/baz", @request)
+ end
- it "should return the file path as an array from the module" do
- mod = mock 'module'
- mod.expects(:file).with("bar/baz").returns "eh"
- @environment.expects(:module).with("foo").returns mod
- @mount.search("foo/bar/baz", @request).should == ["eh"]
- end
+ it "should return the file path as an array from the module" do
+ mod = mock 'module'
+ mod.expects(:file).with("bar/baz").returns "eh"
+ @environment.expects(:module).with("foo").returns mod
+ @mount.search("foo/bar/baz", @request).should == ["eh"]
end
+ end
end
diff --git a/spec/unit/file_serving/mount/plugins_spec.rb b/spec/unit/file_serving/mount/plugins_spec.rb
index d8c05a2..b48b525 100755
--- a/spec/unit/file_serving/mount/plugins_spec.rb
+++ b/spec/unit/file_serving/mount/plugins_spec.rb
@@ -4,58 +4,58 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/file_serving/mount/plugins'
describe Puppet::FileServing::Mount::Plugins do
- before do
- @mount = Puppet::FileServing::Mount::Plugins.new("plugins")
+ before do
+ @mount = Puppet::FileServing::Mount::Plugins.new("plugins")
- @environment = stub 'environment', :module => nil
- @request = stub 'request', :environment => @environment
- end
+ @environment = stub 'environment', :module => nil
+ @request = stub 'request', :environment => @environment
+ end
- describe "when finding files" do
- it "should use the provided environment to find the modules" do
- @environment.expects(:modules).returns []
+ describe "when finding files" do
+ it "should use the provided environment to find the modules" do
+ @environment.expects(:modules).returns []
- @mount.find("foo", @request)
- end
+ @mount.find("foo", @request)
+ end
- it "should return nil if no module can be found with a matching plugin" do
- mod = mock 'module'
- mod.stubs(:plugin).with("foo/bar").returns nil
+ it "should return nil if no module can be found with a matching plugin" do
+ mod = mock 'module'
+ mod.stubs(:plugin).with("foo/bar").returns nil
- @environment.stubs(:modules).returns [mod]
- @mount.find("foo/bar", @request).should be_nil
- end
+ @environment.stubs(:modules).returns [mod]
+ @mount.find("foo/bar", @request).should be_nil
+ end
- it "should return the file path from the module" do
- mod = mock 'module'
- mod.stubs(:plugin).with("foo/bar").returns "eh"
+ it "should return the file path from the module" do
+ mod = mock 'module'
+ mod.stubs(:plugin).with("foo/bar").returns "eh"
- @environment.stubs(:modules).returns [mod]
- @mount.find("foo/bar", @request).should == "eh"
- end
+ @environment.stubs(:modules).returns [mod]
+ @mount.find("foo/bar", @request).should == "eh"
end
+ end
- describe "when searching for files" do
- it "should use the node's environment to find the modules" do
- @environment.expects(:modules).returns []
+ describe "when searching for files" do
+ it "should use the node's environment to find the modules" do
+ @environment.expects(:modules).returns []
- @mount.search("foo", @request)
- end
+ @mount.search("foo", @request)
+ end
- it "should return nil if no modules can be found that have plugins" do
- mod = mock 'module'
- mod.stubs(:plugins?).returns false
+ it "should return nil if no modules can be found that have plugins" do
+ mod = mock 'module'
+ mod.stubs(:plugins?).returns false
- @environment.stubs(:modules).returns []
- @mount.search("foo/bar", @request).should be_nil
- end
+ @environment.stubs(:modules).returns []
+ @mount.search("foo/bar", @request).should be_nil
+ end
- it "should return the plugin paths for each module that has plugins" do
- one = stub 'module', :plugins? => true, :plugin_directory => "/one"
- two = stub 'module', :plugins? => true, :plugin_directory => "/two"
+ it "should return the plugin paths for each module that has plugins" do
+ one = stub 'module', :plugins? => true, :plugin_directory => "/one"
+ two = stub 'module', :plugins? => true, :plugin_directory => "/two"
- @environment.stubs(:modules).returns [one, two]
- @mount.search("foo/bar", @request).should == %w{/one /two}
- end
+ @environment.stubs(:modules).returns [one, two]
+ @mount.search("foo/bar", @request).should == %w{/one /two}
end
+ end
end
diff --git a/spec/unit/file_serving/mount_spec.rb b/spec/unit/file_serving/mount_spec.rb
index cbb97b0..6eb0d4d 100755
--- a/spec/unit/file_serving/mount_spec.rb
+++ b/spec/unit/file_serving/mount_spec.rb
@@ -4,29 +4,29 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/file_serving/mount'
describe Puppet::FileServing::Mount do
- it "should use 'mount[$name]' as its string form" do
- Puppet::FileServing::Mount.new("foo").to_s.should == "mount[foo]"
- end
+ it "should use 'mount[$name]' as its string form" do
+ Puppet::FileServing::Mount.new("foo").to_s.should == "mount[foo]"
+ end
end
describe Puppet::FileServing::Mount, " when initializing" do
- it "should fail on non-alphanumeric name" do
- proc { Puppet::FileServing::Mount.new("non alpha") }.should raise_error(ArgumentError)
- end
+ it "should fail on non-alphanumeric name" do
+ proc { Puppet::FileServing::Mount.new("non alpha") }.should raise_error(ArgumentError)
+ end
- it "should allow dashes in its name" do
- Puppet::FileServing::Mount.new("non-alpha").name.should == "non-alpha"
- end
+ it "should allow dashes in its name" do
+ Puppet::FileServing::Mount.new("non-alpha").name.should == "non-alpha"
+ end
end
describe Puppet::FileServing::Mount, " when finding files" do
- it "should fail" do
- lambda { Puppet::FileServing::Mount.new("test").find("foo", :one => "two") }.should raise_error(NotImplementedError)
- end
+ it "should fail" do
+ lambda { Puppet::FileServing::Mount.new("test").find("foo", :one => "two") }.should raise_error(NotImplementedError)
+ end
end
describe Puppet::FileServing::Mount, " when searching for files" do
- it "should fail" do
- lambda { Puppet::FileServing::Mount.new("test").search("foo", :one => "two") }.should raise_error(NotImplementedError)
- end
+ it "should fail" do
+ lambda { Puppet::FileServing::Mount.new("test").search("foo", :one => "two") }.should raise_error(NotImplementedError)
+ end
end
diff --git a/spec/unit/file_serving/terminus_helper_spec.rb b/spec/unit/file_serving/terminus_helper_spec.rb
index 98c64b7..f46da1e 100755
--- a/spec/unit/file_serving/terminus_helper_spec.rb
+++ b/spec/unit/file_serving/terminus_helper_spec.rb
@@ -8,91 +8,91 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/file_serving/terminus_helper'
describe Puppet::FileServing::TerminusHelper do
- before do
- @helper = Object.new
- @helper.extend(Puppet::FileServing::TerminusHelper)
+ before do
+ @helper = Object.new
+ @helper.extend(Puppet::FileServing::TerminusHelper)
+
+ @model = mock 'model'
+ @helper.stubs(:model).returns(@model)
+
+ @request = stub 'request', :key => "url", :options => {}
+
+ @fileset = stub 'fileset', :files => [], :path => "/my/file"
+ Puppet::FileServing::Fileset.stubs(:new).with("/my/file", {}).returns(@fileset)
+ end
+
+ it "should use a fileset to find paths" do
+ @fileset = stub 'fileset', :files => [], :path => "/my/files"
+ Puppet::FileServing::Fileset.expects(:new).with { |key, options| key == "/my/file" }.returns(@fileset)
+ @helper.path2instances(@request, "/my/file")
+ end
+
+ it "should support finding across multiple paths by merging the filesets" do
+ first = stub 'fileset', :files => [], :path => "/first/file"
+ Puppet::FileServing::Fileset.expects(:new).with { |path, options| path == "/first/file" }.returns(first)
+ second = stub 'fileset', :files => [], :path => "/second/file"
+ Puppet::FileServing::Fileset.expects(:new).with { |path, options| path == "/second/file" }.returns(second)
+
+ Puppet::FileServing::Fileset.expects(:merge).with(first, second).returns({})
- @model = mock 'model'
- @helper.stubs(:model).returns(@model)
+ @helper.path2instances(@request, "/first/file", "/second/file")
+ end
- @request = stub 'request', :key => "url", :options => {}
+ it "should pass the indirection request to the Fileset at initialization" do
+ Puppet::FileServing::Fileset.expects(:new).with { |path, options| options == @request }.returns @fileset
+ @helper.path2instances(@request, "/my/file")
+ end
- @fileset = stub 'fileset', :files => [], :path => "/my/file"
- Puppet::FileServing::Fileset.stubs(:new).with("/my/file", {}).returns(@fileset)
+ describe "when creating instances" do
+ before do
+ @request.stubs(:key).returns "puppet://host/mount/dir"
+
+ @one = stub 'one', :links= => nil, :collect => nil
+ @two = stub 'two', :links= => nil, :collect => nil
+
+ @fileset = stub 'fileset', :files => %w{one two}, :path => "/my/file"
+ Puppet::FileServing::Fileset.stubs(:new).returns(@fileset)
end
- it "should use a fileset to find paths" do
- @fileset = stub 'fileset', :files => [], :path => "/my/files"
- Puppet::FileServing::Fileset.expects(:new).with { |key, options| key == "/my/file" }.returns(@fileset)
- @helper.path2instances(@request, "/my/file")
+ it "should set each returned instance's path to the original path" do
+ @model.expects(:new).with { |key, options| key == "/my/file" }.returns(@one)
+ @model.expects(:new).with { |key, options| key == "/my/file" }.returns(@two)
+ @helper.path2instances(@request, "/my/file")
end
- it "should support finding across multiple paths by merging the filesets" do
- first = stub 'fileset', :files => [], :path => "/first/file"
- Puppet::FileServing::Fileset.expects(:new).with { |path, options| path == "/first/file" }.returns(first)
- second = stub 'fileset', :files => [], :path => "/second/file"
- Puppet::FileServing::Fileset.expects(:new).with { |path, options| path == "/second/file" }.returns(second)
+ it "should set each returned instance's relative path to the file-specific path" do
+ @model.expects(:new).with { |key, options| options[:relative_path] == "one" }.returns(@one)
+ @model.expects(:new).with { |key, options| options[:relative_path] == "two" }.returns(@two)
+ @helper.path2instances(@request, "/my/file")
+ end
- Puppet::FileServing::Fileset.expects(:merge).with(first, second).returns({})
+ it "should set the links value on each instance if one is provided" do
+ @one.expects(:links=).with :manage
+ @two.expects(:links=).with :manage
+ @model.expects(:new).returns(@one)
+ @model.expects(:new).returns(@two)
- @helper.path2instances(@request, "/first/file", "/second/file")
+ @request.options[:links] = :manage
+ @helper.path2instances(@request, "/my/file")
end
- it "should pass the indirection request to the Fileset at initialization" do
- Puppet::FileServing::Fileset.expects(:new).with { |path, options| options == @request }.returns @fileset
- @helper.path2instances(@request, "/my/file")
+ it "should set the request checksum_type if one is provided" do
+ @one.expects(:checksum_type=).with :test
+ @two.expects(:checksum_type=).with :test
+ @model.expects(:new).returns(@one)
+ @model.expects(:new).returns(@two)
+
+ @request.options[:checksum_type] = :test
+ @helper.path2instances(@request, "/my/file")
end
- describe "when creating instances" do
- before do
- @request.stubs(:key).returns "puppet://host/mount/dir"
-
- @one = stub 'one', :links= => nil, :collect => nil
- @two = stub 'two', :links= => nil, :collect => nil
-
- @fileset = stub 'fileset', :files => %w{one two}, :path => "/my/file"
- Puppet::FileServing::Fileset.stubs(:new).returns(@fileset)
- end
-
- it "should set each returned instance's path to the original path" do
- @model.expects(:new).with { |key, options| key == "/my/file" }.returns(@one)
- @model.expects(:new).with { |key, options| key == "/my/file" }.returns(@two)
- @helper.path2instances(@request, "/my/file")
- end
-
- it "should set each returned instance's relative path to the file-specific path" do
- @model.expects(:new).with { |key, options| options[:relative_path] == "one" }.returns(@one)
- @model.expects(:new).with { |key, options| options[:relative_path] == "two" }.returns(@two)
- @helper.path2instances(@request, "/my/file")
- end
-
- it "should set the links value on each instance if one is provided" do
- @one.expects(:links=).with :manage
- @two.expects(:links=).with :manage
- @model.expects(:new).returns(@one)
- @model.expects(:new).returns(@two)
-
- @request.options[:links] = :manage
- @helper.path2instances(@request, "/my/file")
- end
-
- it "should set the request checksum_type if one is provided" do
- @one.expects(:checksum_type=).with :test
- @two.expects(:checksum_type=).with :test
- @model.expects(:new).returns(@one)
- @model.expects(:new).returns(@two)
-
- @request.options[:checksum_type] = :test
- @helper.path2instances(@request, "/my/file")
- end
-
- it "should collect the instance's attributes" do
- @one.expects(:collect)
- @two.expects(:collect)
- @model.expects(:new).returns(@one)
- @model.expects(:new).returns(@two)
-
- @helper.path2instances(@request, "/my/file")
- end
+ it "should collect the instance's attributes" do
+ @one.expects(:collect)
+ @two.expects(:collect)
+ @model.expects(:new).returns(@one)
+ @model.expects(:new).returns(@two)
+
+ @helper.path2instances(@request, "/my/file")
end
+ end
end
diff --git a/spec/unit/indirector/active_record_spec.rb b/spec/unit/indirector/active_record_spec.rb
index f0bf07f..258c4e7 100755
--- a/spec/unit/indirector/active_record_spec.rb
+++ b/spec/unit/indirector/active_record_spec.rb
@@ -5,72 +5,72 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector/active_record'
describe Puppet::Indirector::ActiveRecord do
- before do
- Puppet::Rails.stubs(:init)
+ before do
+ Puppet::Rails.stubs(:init)
+
+ Puppet::Indirector::Terminus.stubs(:register_terminus_class)
+ @model = mock 'model'
+ @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model
+ Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
+
+ @active_record_class = Class.new(Puppet::Indirector::ActiveRecord) do
+ def self.to_s
+ "Mystuff::Testing"
+ end
+ end
- Puppet::Indirector::Terminus.stubs(:register_terminus_class)
- @model = mock 'model'
- @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model
- Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
+ @ar_model = mock 'ar_model'
- @active_record_class = Class.new(Puppet::Indirector::ActiveRecord) do
- def self.to_s
- "Mystuff::Testing"
- end
- end
+ @active_record_class.use_ar_model @ar_model
+ @terminus = @active_record_class.new
- @ar_model = mock 'ar_model'
+ @name = "me"
+ @instance = stub 'instance', :name => @name
- @active_record_class.use_ar_model @ar_model
- @terminus = @active_record_class.new
+ @request = stub 'request', :key => @name, :instance => @instance
+ end
- @name = "me"
- @instance = stub 'instance', :name => @name
+ it "should allow declaration of an ActiveRecord model to use" do
+ @active_record_class.use_ar_model "foo"
+ @active_record_class.ar_model.should == "foo"
+ end
- @request = stub 'request', :key => @name, :instance => @instance
+ describe "when initializing" do
+ it "should init Rails" do
+ Puppet::Rails.expects(:init)
+ @active_record_class.new
end
+ end
- it "should allow declaration of an ActiveRecord model to use" do
- @active_record_class.use_ar_model "foo"
- @active_record_class.ar_model.should == "foo"
- end
+ describe "when finding an instance" do
+ it "should use the ActiveRecord model to find the instance" do
+ @ar_model.expects(:find_by_name).with(@name)
- describe "when initializing" do
- it "should init Rails" do
- Puppet::Rails.expects(:init)
- @active_record_class.new
- end
+ @terminus.find(@request)
end
- describe "when finding an instance" do
- it "should use the ActiveRecord model to find the instance" do
- @ar_model.expects(:find_by_name).with(@name)
-
- @terminus.find(@request)
- end
-
- it "should return nil if no instance is found" do
- @ar_model.expects(:find_by_name).with(@name).returns nil
- @terminus.find(@request).should be_nil
- end
+ it "should return nil if no instance is found" do
+ @ar_model.expects(:find_by_name).with(@name).returns nil
+ @terminus.find(@request).should be_nil
+ end
- it "should convert the instance to a Puppet object if it is found" do
- instance = mock 'rails_instance'
- instance.expects(:to_puppet).returns "mypuppet"
+ it "should convert the instance to a Puppet object if it is found" do
+ instance = mock 'rails_instance'
+ instance.expects(:to_puppet).returns "mypuppet"
- @ar_model.expects(:find_by_name).with(@name).returns instance
- @terminus.find(@request).should == "mypuppet"
- end
+ @ar_model.expects(:find_by_name).with(@name).returns instance
+ @terminus.find(@request).should == "mypuppet"
end
+ end
- describe "when saving an instance" do
- it "should use the ActiveRecord model to convert the instance into a Rails object and then save that rails object" do
- rails_object = mock 'rails_object'
- @ar_model.expects(:from_puppet).with(@instance).returns rails_object
+ describe "when saving an instance" do
+ it "should use the ActiveRecord model to convert the instance into a Rails object and then save that rails object" do
+ rails_object = mock 'rails_object'
+ @ar_model.expects(:from_puppet).with(@instance).returns rails_object
- rails_object.expects(:save)
+ rails_object.expects(:save)
- @terminus.save(@request)
- end
+ @terminus.save(@request)
end
+ end
end
diff --git a/spec/unit/indirector/catalog/active_record_spec.rb b/spec/unit/indirector/catalog/active_record_spec.rb
index 8678dd6..4e9d049 100755
--- a/spec/unit/indirector/catalog/active_record_spec.rb
+++ b/spec/unit/indirector/catalog/active_record_spec.rb
@@ -4,138 +4,138 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe "Puppet::Resource::Catalog::ActiveRecord" do
- confine "Missing Rails" => Puppet.features.rails?
+ confine "Missing Rails" => Puppet.features.rails?
+ before do
+ require 'puppet/indirector/catalog/active_record'
+ Puppet.features.stubs(:rails?).returns true
+ Puppet::Rails.stubs(:init)
+ @terminus = Puppet::Resource::Catalog::ActiveRecord.new
+ end
+
+ it "should be a subclass of the ActiveRecord terminus class" do
+ Puppet::Resource::Catalog::ActiveRecord.ancestors.should be_include(Puppet::Indirector::ActiveRecord)
+ end
+
+ it "should use Puppet::Rails::Host as its ActiveRecord model" do
+ Puppet::Resource::Catalog::ActiveRecord.ar_model.should equal(Puppet::Rails::Host)
+ end
+
+ describe "when finding an instance" do
before do
- require 'puppet/indirector/catalog/active_record'
- Puppet.features.stubs(:rails?).returns true
- Puppet::Rails.stubs(:init)
- @terminus = Puppet::Resource::Catalog::ActiveRecord.new
+ @request = stub 'request', :key => "foo", :options => {:cache_integration_hack => true}
end
- it "should be a subclass of the ActiveRecord terminus class" do
- Puppet::Resource::Catalog::ActiveRecord.ancestors.should be_include(Puppet::Indirector::ActiveRecord)
+ # This hack is here because we don't want to look in the db unless we actually want
+ # to look in the db, but our indirection architecture in 0.24.x isn't flexible
+ # enough to tune that via configuration.
+ it "should return nil unless ':cache_integration_hack' is set to true" do
+ @request.options[:cache_integration_hack] = false
+ Puppet::Rails::Host.expects(:find_by_name).never
+ @terminus.find(@request).should be_nil
end
- it "should use Puppet::Rails::Host as its ActiveRecord model" do
- Puppet::Resource::Catalog::ActiveRecord.ar_model.should equal(Puppet::Rails::Host)
+ it "should use the Hosts ActiveRecord class to find the host" do
+ Puppet::Rails::Host.expects(:find_by_name).with { |key, args| key == "foo" }
+ @terminus.find(@request)
end
- describe "when finding an instance" do
- before do
- @request = stub 'request', :key => "foo", :options => {:cache_integration_hack => true}
- end
-
- # This hack is here because we don't want to look in the db unless we actually want
- # to look in the db, but our indirection architecture in 0.24.x isn't flexible
- # enough to tune that via configuration.
- it "should return nil unless ':cache_integration_hack' is set to true" do
- @request.options[:cache_integration_hack] = false
- Puppet::Rails::Host.expects(:find_by_name).never
- @terminus.find(@request).should be_nil
- end
+ it "should return nil if no host instance can be found" do
+ Puppet::Rails::Host.expects(:find_by_name).returns nil
- it "should use the Hosts ActiveRecord class to find the host" do
- Puppet::Rails::Host.expects(:find_by_name).with { |key, args| key == "foo" }
- @terminus.find(@request)
- end
-
- it "should return nil if no host instance can be found" do
- Puppet::Rails::Host.expects(:find_by_name).returns nil
-
- @terminus.find(@request).should be_nil
- end
+ @terminus.find(@request).should be_nil
+ end
- it "should return a catalog with the same name as the host if the host can be found" do
- host = stub 'host', :name => "foo", :resources => []
- Puppet::Rails::Host.expects(:find_by_name).returns host
+ it "should return a catalog with the same name as the host if the host can be found" do
+ host = stub 'host', :name => "foo", :resources => []
+ Puppet::Rails::Host.expects(:find_by_name).returns host
- result = @terminus.find(@request)
- result.should be_instance_of(Puppet::Resource::Catalog)
- result.name.should == "foo"
- end
+ result = @terminus.find(@request)
+ result.should be_instance_of(Puppet::Resource::Catalog)
+ result.name.should == "foo"
+ end
- it "should set each of the host's resources as a transportable resource within the catalog" do
- host = stub 'host', :name => "foo"
- Puppet::Rails::Host.expects(:find_by_name).returns host
+ it "should set each of the host's resources as a transportable resource within the catalog" do
+ host = stub 'host', :name => "foo"
+ Puppet::Rails::Host.expects(:find_by_name).returns host
- res1 = mock 'res1', :to_transportable => "trans_res1"
- res2 = mock 'res2', :to_transportable => "trans_res2"
+ res1 = mock 'res1', :to_transportable => "trans_res1"
+ res2 = mock 'res2', :to_transportable => "trans_res2"
- host.expects(:resources).returns [res1, res2]
+ host.expects(:resources).returns [res1, res2]
- catalog = stub 'catalog'
- Puppet::Resource::Catalog.expects(:new).returns catalog
+ catalog = stub 'catalog'
+ Puppet::Resource::Catalog.expects(:new).returns catalog
- catalog.expects(:add_resource).with "trans_res1"
- catalog.expects(:add_resource).with "trans_res2"
+ catalog.expects(:add_resource).with "trans_res1"
+ catalog.expects(:add_resource).with "trans_res2"
- @terminus.find(@request)
- end
+ @terminus.find(@request)
end
+ end
- describe "when saving an instance" do
- before do
- @host = stub 'host', :name => "foo", :save => nil, :merge_resources => nil, :last_compile= => nil, :ip= => nil, :environment= => nil
- @host.stubs(:railsmark).yields
+ describe "when saving an instance" do
+ before do
+ @host = stub 'host', :name => "foo", :save => nil, :merge_resources => nil, :last_compile= => nil, :ip= => nil, :environment= => nil
+ @host.stubs(:railsmark).yields
- @node = stub_everything 'node', :parameters => {}
- Puppet::Node.stubs(:find).returns(@node)
+ @node = stub_everything 'node', :parameters => {}
+ Puppet::Node.stubs(:find).returns(@node)
- Puppet::Rails::Host.stubs(:find_by_name).returns @host
- @catalog = Puppet::Resource::Catalog.new("foo")
- @request = stub 'request', :key => "foo", :instance => @catalog
- end
+ Puppet::Rails::Host.stubs(:find_by_name).returns @host
+ @catalog = Puppet::Resource::Catalog.new("foo")
+ @request = stub 'request', :key => "foo", :instance => @catalog
+ end
- it "should find the Rails host with the same name" do
- Puppet::Rails::Host.expects(:find_by_name).with("foo").returns @host
+ it "should find the Rails host with the same name" do
+ Puppet::Rails::Host.expects(:find_by_name).with("foo").returns @host
- @terminus.save(@request)
- end
+ @terminus.save(@request)
+ end
- it "should create a new Rails host if none can be found" do
- Puppet::Rails::Host.expects(:find_by_name).with("foo").returns nil
+ it "should create a new Rails host if none can be found" do
+ Puppet::Rails::Host.expects(:find_by_name).with("foo").returns nil
- Puppet::Rails::Host.expects(:create).with(:name => "foo").returns @host
+ Puppet::Rails::Host.expects(:create).with(:name => "foo").returns @host
- @terminus.save(@request)
- end
+ @terminus.save(@request)
+ end
- it "should set the catalog vertices as resources on the Rails host instance" do
- @catalog.expects(:vertices).returns "foo"
- @host.expects(:merge_resources).with("foo")
+ it "should set the catalog vertices as resources on the Rails host instance" do
+ @catalog.expects(:vertices).returns "foo"
+ @host.expects(:merge_resources).with("foo")
- @terminus.save(@request)
- end
+ @terminus.save(@request)
+ end
- it "should set host ip if we could find a matching node" do
- @node.stubs(:parameters).returns({"ipaddress" => "192.168.0.1"})
+ it "should set host ip if we could find a matching node" do
+ @node.stubs(:parameters).returns({"ipaddress" => "192.168.0.1"})
- @host.expects(:ip=).with '192.168.0.1'
+ @host.expects(:ip=).with '192.168.0.1'
- @terminus.save(@request)
- end
+ @terminus.save(@request)
+ end
- it "should set host environment if we could find a matching node" do
- @node.stubs(:environment).returns("myenv")
+ it "should set host environment if we could find a matching node" do
+ @node.stubs(:environment).returns("myenv")
- @host.expects(:environment=).with 'myenv'
+ @host.expects(:environment=).with 'myenv'
- @terminus.save(@request)
- end
+ @terminus.save(@request)
+ end
- it "should set the last compile time on the host" do
- now = Time.now
- Time.expects(:now).returns now
- @host.expects(:last_compile=).with now
+ it "should set the last compile time on the host" do
+ now = Time.now
+ Time.expects(:now).returns now
+ @host.expects(:last_compile=).with now
- @terminus.save(@request)
- end
+ @terminus.save(@request)
+ end
- it "should save the Rails host instance" do
- @host.expects(:save)
+ it "should save the Rails host instance" do
+ @host.expects(:save)
- @terminus.save(@request)
- end
+ @terminus.save(@request)
end
+ end
end
diff --git a/spec/unit/indirector/catalog/compiler_spec.rb b/spec/unit/indirector/catalog/compiler_spec.rb
index 8339d18..755509f 100755
--- a/spec/unit/indirector/catalog/compiler_spec.rb
+++ b/spec/unit/indirector/catalog/compiler_spec.rb
@@ -8,258 +8,258 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/catalog/compiler'
describe Puppet::Resource::Catalog::Compiler do
+ before do
+ Puppet::Rails.stubs(:init)
+ Facter.stubs(:to_hash).returns({})
+ Facter.stubs(:value).returns(Facter::Util::Fact.new("something"))
+ end
+
+ describe "when initializing" do
before do
- Puppet::Rails.stubs(:init)
- Facter.stubs(:to_hash).returns({})
- Facter.stubs(:value).returns(Facter::Util::Fact.new("something"))
+ Puppet.expects(:version).returns(1)
+ Facter.expects(:value).with('fqdn').returns("my.server.com")
+ Facter.expects(:value).with('ipaddress').returns("my.ip.address")
+ end
+
+ it "should gather data about itself" do
+ Puppet::Resource::Catalog::Compiler.new
+ end
+
+ it "should cache the server metadata and reuse it" do
+ compiler = Puppet::Resource::Catalog::Compiler.new
+ node1 = stub 'node1', :merge => nil
+ node2 = stub 'node2', :merge => nil
+ compiler.stubs(:compile)
+ Puppet::Node.stubs(:find).with('node1').returns(node1)
+ Puppet::Node.stubs(:find).with('node2').returns(node2)
+
+ compiler.find(stub('request', :node => 'node1', :options => {}))
+ compiler.find(stub('node2request', :node => 'node2', :options => {}))
end
- describe "when initializing" do
- before do
- Puppet.expects(:version).returns(1)
- Facter.expects(:value).with('fqdn').returns("my.server.com")
- Facter.expects(:value).with('ipaddress').returns("my.ip.address")
- end
-
- it "should gather data about itself" do
- Puppet::Resource::Catalog::Compiler.new
- end
-
- it "should cache the server metadata and reuse it" do
- compiler = Puppet::Resource::Catalog::Compiler.new
- node1 = stub 'node1', :merge => nil
- node2 = stub 'node2', :merge => nil
- compiler.stubs(:compile)
- Puppet::Node.stubs(:find).with('node1').returns(node1)
- Puppet::Node.stubs(:find).with('node2').returns(node2)
-
- compiler.find(stub('request', :node => 'node1', :options => {}))
- compiler.find(stub('node2request', :node => 'node2', :options => {}))
- end
-
- it "should provide a method for determining if the catalog is networked" do
- compiler = Puppet::Resource::Catalog::Compiler.new
- compiler.should respond_to(:networked?)
- end
-
- describe "and storeconfigs is enabled" do
- before do
- Puppet.settings.expects(:value).with(:storeconfigs).returns true
- end
-
- it "should initialize Rails if it is available" do
- Puppet.features.expects(:rails?).returns true
- Puppet::Rails.expects(:init)
- Puppet::Resource::Catalog::Compiler.new
- end
-
- it "should fail if Rails is unavailable" do
- Puppet.features.expects(:rails?).returns false
- Puppet::Rails.expects(:init).never
- lambda { Puppet::Resource::Catalog::Compiler.new }.should raise_error(Puppet::Error)
- end
- end
+ it "should provide a method for determining if the catalog is networked" do
+ compiler = Puppet::Resource::Catalog::Compiler.new
+ compiler.should respond_to(:networked?)
end
- describe "when finding catalogs" do
- before do
- Facter.stubs(:value).returns("whatever")
-
- @compiler = Puppet::Resource::Catalog::Compiler.new
- @name = "me"
- @node = Puppet::Node.new @name
- @node.stubs(:merge)
- Puppet::Node.stubs(:find).returns @node
- @request = stub 'request', :key => "does not matter", :node => @name, :options => {}
- end
-
- it "should directly use provided nodes" do
- Puppet::Node.expects(:find).never
- @compiler.expects(:compile).with(@node)
- @request.stubs(:options).returns(:use_node => @node)
- @compiler.find(@request)
- end
-
- it "should use the request's node name if no explicit node is provided" do
- Puppet::Node.expects(:find).with(@name).returns(@node)
- @compiler.expects(:compile).with(@node)
- @compiler.find(@request)
- end
-
- it "should use the provided node name if no explicit node is provided and no authenticated node information is available" do
- @request.expects(:node).returns nil
- @request.expects(:key).returns "my_node"
-
- Puppet::Node.expects(:find).with("my_node").returns @node
- @compiler.expects(:compile).with(@node)
- @compiler.find(@request)
- end
-
- it "should fail if no node is passed and none can be found" do
- Puppet::Node.stubs(:find).with(@name).returns(nil)
- proc { @compiler.find(@request) }.should raise_error(ArgumentError)
- end
-
- it "should fail intelligently when searching for a node raises an exception" do
- Puppet::Node.stubs(:find).with(@name).raises "eh"
- proc { @compiler.find(@request) }.should raise_error(Puppet::Error)
- end
-
- it "should pass the found node to the compiler for compiling" do
- Puppet::Node.expects(:find).with(@name).returns(@node)
- config = mock 'config'
- Puppet::Parser::Compiler.expects(:compile).with(@node)
- @compiler.find(@request)
- end
-
- it "should extract and save any facts from the request" do
- Puppet::Node.expects(:find).with(@name).returns @node
- @compiler.expects(:extract_facts_from_request).with(@request)
- Puppet::Parser::Compiler.stubs(:compile)
- @compiler.find(@request)
- end
-
- it "should return the results of compiling as the catalog" do
- Puppet::Node.stubs(:find).returns(@node)
- config = mock 'config'
- result = mock 'result'
-
- Puppet::Parser::Compiler.expects(:compile).returns result
- @compiler.find(@request).should equal(result)
- end
-
- it "should benchmark the compile process" do
- Puppet::Node.stubs(:find).returns(@node)
- @compiler.stubs(:networked?).returns(true)
- @compiler.expects(:benchmark).with do |level, message|
- level == :notice and message =~ /^Compiled catalog/
- end
- Puppet::Parser::Compiler.stubs(:compile)
- @compiler.find(@request)
- end
+ describe "and storeconfigs is enabled" do
+ before do
+ Puppet.settings.expects(:value).with(:storeconfigs).returns true
+ end
+
+ it "should initialize Rails if it is available" do
+ Puppet.features.expects(:rails?).returns true
+ Puppet::Rails.expects(:init)
+ Puppet::Resource::Catalog::Compiler.new
+ end
+
+ it "should fail if Rails is unavailable" do
+ Puppet.features.expects(:rails?).returns false
+ Puppet::Rails.expects(:init).never
+ lambda { Puppet::Resource::Catalog::Compiler.new }.should raise_error(Puppet::Error)
+ end
end
+ end
- describe "when extracting facts from the request" do
- before do
- Facter.stubs(:value).returns "something"
- @compiler = Puppet::Resource::Catalog::Compiler.new
- @request = stub 'request', :options => {}
+ describe "when finding catalogs" do
+ before do
+ Facter.stubs(:value).returns("whatever")
+
+ @compiler = Puppet::Resource::Catalog::Compiler.new
+ @name = "me"
+ @node = Puppet::Node.new @name
+ @node.stubs(:merge)
+ Puppet::Node.stubs(:find).returns @node
+ @request = stub 'request', :key => "does not matter", :node => @name, :options => {}
+ end
- @facts = stub 'facts', :save => nil
- end
+ it "should directly use provided nodes" do
+ Puppet::Node.expects(:find).never
+ @compiler.expects(:compile).with(@node)
+ @request.stubs(:options).returns(:use_node => @node)
+ @compiler.find(@request)
+ end
- it "should do nothing if no facts are provided" do
- Puppet::Node::Facts.expects(:convert_from).never
- @request.options[:facts] = nil
+ it "should use the request's node name if no explicit node is provided" do
+ Puppet::Node.expects(:find).with(@name).returns(@node)
+ @compiler.expects(:compile).with(@node)
+ @compiler.find(@request)
+ end
- @compiler.extract_facts_from_request(@request)
- end
+ it "should use the provided node name if no explicit node is provided and no authenticated node information is available" do
+ @request.expects(:node).returns nil
+ @request.expects(:key).returns "my_node"
- it "should use the Facts class to deserialize the provided facts" do
- @request.options[:facts_format] = "foo"
- @request.options[:facts] = "bar"
- Puppet::Node::Facts.expects(:convert_from).returns @facts
+ Puppet::Node.expects(:find).with("my_node").returns @node
+ @compiler.expects(:compile).with(@node)
+ @compiler.find(@request)
+ end
- @compiler.extract_facts_from_request(@request)
- end
+ it "should fail if no node is passed and none can be found" do
+ Puppet::Node.stubs(:find).with(@name).returns(nil)
+ proc { @compiler.find(@request) }.should raise_error(ArgumentError)
+ end
- it "should use the provided fact format" do
- @request.options[:facts_format] = "foo"
- @request.options[:facts] = "bar"
- Puppet::Node::Facts.expects(:convert_from).with { |format, text| format == "foo" }.returns @facts
+ it "should fail intelligently when searching for a node raises an exception" do
+ Puppet::Node.stubs(:find).with(@name).raises "eh"
+ proc { @compiler.find(@request) }.should raise_error(Puppet::Error)
+ end
- @compiler.extract_facts_from_request(@request)
- end
+ it "should pass the found node to the compiler for compiling" do
+ Puppet::Node.expects(:find).with(@name).returns(@node)
+ config = mock 'config'
+ Puppet::Parser::Compiler.expects(:compile).with(@node)
+ @compiler.find(@request)
+ end
- it "should convert the facts into a fact instance and save it" do
- @request.options[:facts_format] = "foo"
- @request.options[:facts] = "bar"
- Puppet::Node::Facts.expects(:convert_from).returns @facts
+ it "should extract and save any facts from the request" do
+ Puppet::Node.expects(:find).with(@name).returns @node
+ @compiler.expects(:extract_facts_from_request).with(@request)
+ Puppet::Parser::Compiler.stubs(:compile)
+ @compiler.find(@request)
+ end
- @facts.expects(:save)
+ it "should return the results of compiling as the catalog" do
+ Puppet::Node.stubs(:find).returns(@node)
+ config = mock 'config'
+ result = mock 'result'
- @compiler.extract_facts_from_request(@request)
- end
+ Puppet::Parser::Compiler.expects(:compile).returns result
+ @compiler.find(@request).should equal(result)
end
- describe "when finding nodes" do
- before do
- Facter.stubs(:value).returns("whatever")
- @compiler = Puppet::Resource::Catalog::Compiler.new
- @name = "me"
- @node = mock 'node'
- @request = stub 'request', :node => @name, :options => {}
- @compiler.stubs(:compile)
- end
-
- it "should look node information up via the Node class with the provided key" do
- @node.stubs :merge
- Puppet::Node.expects(:find).with(@name).returns(@node)
- @compiler.find(@request)
- end
+ it "should benchmark the compile process" do
+ Puppet::Node.stubs(:find).returns(@node)
+ @compiler.stubs(:networked?).returns(true)
+ @compiler.expects(:benchmark).with do |level, message|
+ level == :notice and message =~ /^Compiled catalog/
+ end
+ Puppet::Parser::Compiler.stubs(:compile)
+ @compiler.find(@request)
end
+ end
- describe "after finding nodes" do
- before do
- Puppet.expects(:version).returns(1)
- Facter.expects(:value).with('fqdn').returns("my.server.com")
- Facter.expects(:value).with('ipaddress').returns("my.ip.address")
- @compiler = Puppet::Resource::Catalog::Compiler.new
- @name = "me"
- @node = mock 'node'
- @request = stub 'request', :node => @name, :options => {}
- @compiler.stubs(:compile)
- Puppet::Node.stubs(:find).with(@name).returns(@node)
- end
-
- it "should add the server's Puppet version to the node's parameters as 'serverversion'" do
- @node.expects(:merge).with { |args| args["serverversion"] == "1" }
- @compiler.find(@request)
- end
-
- it "should add the server's fqdn to the node's parameters as 'servername'" do
- @node.expects(:merge).with { |args| args["servername"] == "my.server.com" }
- @compiler.find(@request)
- end
-
- it "should add the server's IP address to the node's parameters as 'serverip'" do
- @node.expects(:merge).with { |args| args["serverip"] == "my.ip.address" }
- @compiler.find(@request)
- end
+ describe "when extracting facts from the request" do
+ before do
+ Facter.stubs(:value).returns "something"
+ @compiler = Puppet::Resource::Catalog::Compiler.new
+ @request = stub 'request', :options => {}
+
+ @facts = stub 'facts', :save => nil
end
- describe "when filtering resources" do
- before :each do
- Facter.stubs(:value)
- @compiler = Puppet::Resource::Catalog::Compiler.new
- @catalog = stub_everything 'catalog'
- @catalog.stubs(:respond_to?).with(:filter).returns(true)
- end
+ it "should do nothing if no facts are provided" do
+ Puppet::Node::Facts.expects(:convert_from).never
+ @request.options[:facts] = nil
+
+ @compiler.extract_facts_from_request(@request)
+ end
- it "should delegate to the catalog instance filtering" do
- @catalog.expects(:filter)
- @compiler.filter(@catalog)
- end
+ it "should use the Facts class to deserialize the provided facts" do
+ @request.options[:facts_format] = "foo"
+ @request.options[:facts] = "bar"
+ Puppet::Node::Facts.expects(:convert_from).returns @facts
- it "should filter out virtual resources" do
- resource = mock 'resource', :virtual? => true
- @catalog.stubs(:filter).yields(resource)
+ @compiler.extract_facts_from_request(@request)
+ end
- @compiler.filter(@catalog)
- end
+ it "should use the provided fact format" do
+ @request.options[:facts_format] = "foo"
+ @request.options[:facts] = "bar"
+ Puppet::Node::Facts.expects(:convert_from).with { |format, text| format == "foo" }.returns @facts
- it "should return the same catalog if it doesn't support filtering" do
- @catalog.stubs(:respond_to?).with(:filter).returns(false)
+ @compiler.extract_facts_from_request(@request)
+ end
- @compiler.filter(@catalog).should == @catalog
- end
+ it "should convert the facts into a fact instance and save it" do
+ @request.options[:facts_format] = "foo"
+ @request.options[:facts] = "bar"
+ Puppet::Node::Facts.expects(:convert_from).returns @facts
- it "should return the filtered catalog" do
- catalog = stub 'filtered catalog'
- @catalog.stubs(:filter).returns(catalog)
+ @facts.expects(:save)
- @compiler.filter(@catalog).should == catalog
- end
+ @compiler.extract_facts_from_request(@request)
+ end
+ end
+ describe "when finding nodes" do
+ before do
+ Facter.stubs(:value).returns("whatever")
+ @compiler = Puppet::Resource::Catalog::Compiler.new
+ @name = "me"
+ @node = mock 'node'
+ @request = stub 'request', :node => @name, :options => {}
+ @compiler.stubs(:compile)
end
+
+ it "should look node information up via the Node class with the provided key" do
+ @node.stubs :merge
+ Puppet::Node.expects(:find).with(@name).returns(@node)
+ @compiler.find(@request)
+ end
+ end
+
+ describe "after finding nodes" do
+ before do
+ Puppet.expects(:version).returns(1)
+ Facter.expects(:value).with('fqdn').returns("my.server.com")
+ Facter.expects(:value).with('ipaddress').returns("my.ip.address")
+ @compiler = Puppet::Resource::Catalog::Compiler.new
+ @name = "me"
+ @node = mock 'node'
+ @request = stub 'request', :node => @name, :options => {}
+ @compiler.stubs(:compile)
+ Puppet::Node.stubs(:find).with(@name).returns(@node)
+ end
+
+ it "should add the server's Puppet version to the node's parameters as 'serverversion'" do
+ @node.expects(:merge).with { |args| args["serverversion"] == "1" }
+ @compiler.find(@request)
+ end
+
+ it "should add the server's fqdn to the node's parameters as 'servername'" do
+ @node.expects(:merge).with { |args| args["servername"] == "my.server.com" }
+ @compiler.find(@request)
+ end
+
+ it "should add the server's IP address to the node's parameters as 'serverip'" do
+ @node.expects(:merge).with { |args| args["serverip"] == "my.ip.address" }
+ @compiler.find(@request)
+ end
+ end
+
+ describe "when filtering resources" do
+ before :each do
+ Facter.stubs(:value)
+ @compiler = Puppet::Resource::Catalog::Compiler.new
+ @catalog = stub_everything 'catalog'
+ @catalog.stubs(:respond_to?).with(:filter).returns(true)
+ end
+
+ it "should delegate to the catalog instance filtering" do
+ @catalog.expects(:filter)
+ @compiler.filter(@catalog)
+ end
+
+ it "should filter out virtual resources" do
+ resource = mock 'resource', :virtual? => true
+ @catalog.stubs(:filter).yields(resource)
+
+ @compiler.filter(@catalog)
+ end
+
+ it "should return the same catalog if it doesn't support filtering" do
+ @catalog.stubs(:respond_to?).with(:filter).returns(false)
+
+ @compiler.filter(@catalog).should == @catalog
+ end
+
+ it "should return the filtered catalog" do
+ catalog = stub 'filtered catalog'
+ @catalog.stubs(:filter).returns(catalog)
+
+ @compiler.filter(@catalog).should == catalog
+ end
+
+ end
end
diff --git a/spec/unit/indirector/catalog/queue_spec.rb b/spec/unit/indirector/catalog/queue_spec.rb
index 66a30c0..38d40c9 100755
--- a/spec/unit/indirector/catalog/queue_spec.rb
+++ b/spec/unit/indirector/catalog/queue_spec.rb
@@ -5,16 +5,16 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/catalog/queue'
describe Puppet::Resource::Catalog::Queue do
- it 'should be a subclass of the Queue terminus' do
- Puppet::Resource::Catalog::Queue.superclass.should equal(Puppet::Indirector::Queue)
- end
+ it 'should be a subclass of the Queue terminus' do
+ Puppet::Resource::Catalog::Queue.superclass.should equal(Puppet::Indirector::Queue)
+ end
- it 'should be registered with the catalog store indirection' do
- indirection = Puppet::Indirector::Indirection.instance(:catalog)
- Puppet::Resource::Catalog::Queue.indirection.should equal(indirection)
- end
+ it 'should be registered with the catalog store indirection' do
+ indirection = Puppet::Indirector::Indirection.instance(:catalog)
+ Puppet::Resource::Catalog::Queue.indirection.should equal(indirection)
+ end
- it 'shall be dubbed ":queue"' do
- Puppet::Resource::Catalog::Queue.name.should == :queue
- end
+ it 'shall be dubbed ":queue"' do
+ Puppet::Resource::Catalog::Queue.name.should == :queue
+ end
end
diff --git a/spec/unit/indirector/catalog/rest_spec.rb b/spec/unit/indirector/catalog/rest_spec.rb
index 909e0a8..d61054e 100755
--- a/spec/unit/indirector/catalog/rest_spec.rb
+++ b/spec/unit/indirector/catalog/rest_spec.rb
@@ -5,7 +5,7 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/catalog/rest'
describe Puppet::Resource::Catalog::Rest do
- it "should be a sublcass of Puppet::Indirector::REST" do
- Puppet::Resource::Catalog::Rest.superclass.should equal(Puppet::Indirector::REST)
- end
+ it "should be a sublcass of Puppet::Indirector::REST" do
+ Puppet::Resource::Catalog::Rest.superclass.should equal(Puppet::Indirector::REST)
+ end
end
diff --git a/spec/unit/indirector/catalog/yaml_spec.rb b/spec/unit/indirector/catalog/yaml_spec.rb
index 5f233c9..5a30b82 100755
--- a/spec/unit/indirector/catalog/yaml_spec.rb
+++ b/spec/unit/indirector/catalog/yaml_spec.rb
@@ -6,20 +6,20 @@ require 'puppet/resource/catalog'
require 'puppet/indirector/catalog/yaml'
describe Puppet::Resource::Catalog::Yaml do
- it "should be a subclass of the Yaml terminus" do
- Puppet::Resource::Catalog::Yaml.superclass.should equal(Puppet::Indirector::Yaml)
- end
+ it "should be a subclass of the Yaml terminus" do
+ Puppet::Resource::Catalog::Yaml.superclass.should equal(Puppet::Indirector::Yaml)
+ end
- it "should have documentation" do
- Puppet::Resource::Catalog::Yaml.doc.should_not be_nil
- end
+ it "should have documentation" do
+ Puppet::Resource::Catalog::Yaml.doc.should_not be_nil
+ end
- it "should be registered with the catalog store indirection" do
- indirection = Puppet::Indirector::Indirection.instance(:catalog)
- Puppet::Resource::Catalog::Yaml.indirection.should equal(indirection)
- end
+ it "should be registered with the catalog store indirection" do
+ indirection = Puppet::Indirector::Indirection.instance(:catalog)
+ Puppet::Resource::Catalog::Yaml.indirection.should equal(indirection)
+ end
- it "should have its name set to :yaml" do
- Puppet::Resource::Catalog::Yaml.name.should == :yaml
- end
+ it "should have its name set to :yaml" do
+ Puppet::Resource::Catalog::Yaml.name.should == :yaml
+ end
end
diff --git a/spec/unit/indirector/certificate/ca_spec.rb b/spec/unit/indirector/certificate/ca_spec.rb
index 0158a8d..6bf3e26 100755
--- a/spec/unit/indirector/certificate/ca_spec.rb
+++ b/spec/unit/indirector/certificate/ca_spec.rb
@@ -8,21 +8,21 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/certificate/ca'
describe Puppet::SSL::Certificate::Ca do
- it "should have documentation" do
- Puppet::SSL::Certificate::Ca.doc.should be_instance_of(String)
- end
+ it "should have documentation" do
+ Puppet::SSL::Certificate::Ca.doc.should be_instance_of(String)
+ end
- it "should use the :signeddir as the collection directory" do
- Puppet.settings.expects(:value).with(:signeddir).returns "/cert/dir"
- Puppet::SSL::Certificate::Ca.collection_directory.should == "/cert/dir"
- end
+ it "should use the :signeddir as the collection directory" do
+ Puppet.settings.expects(:value).with(:signeddir).returns "/cert/dir"
+ Puppet::SSL::Certificate::Ca.collection_directory.should == "/cert/dir"
+ end
- it "should store the ca certificate at the :cacert location" do
- Puppet.settings.stubs(:use)
- Puppet.settings.stubs(:value).returns "whatever"
- Puppet.settings.stubs(:value).with(:cacert).returns "/ca/cert"
- file = Puppet::SSL::Certificate::Ca.new
- file.stubs(:ca?).returns true
- file.path("whatever").should == "/ca/cert"
- end
+ it "should store the ca certificate at the :cacert location" do
+ Puppet.settings.stubs(:use)
+ Puppet.settings.stubs(:value).returns "whatever"
+ Puppet.settings.stubs(:value).with(:cacert).returns "/ca/cert"
+ file = Puppet::SSL::Certificate::Ca.new
+ file.stubs(:ca?).returns true
+ file.path("whatever").should == "/ca/cert"
+ end
end
diff --git a/spec/unit/indirector/certificate/file_spec.rb b/spec/unit/indirector/certificate/file_spec.rb
index 6fb00f1..6a8e7d8 100755
--- a/spec/unit/indirector/certificate/file_spec.rb
+++ b/spec/unit/indirector/certificate/file_spec.rb
@@ -8,21 +8,21 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/certificate/file'
describe Puppet::SSL::Certificate::File do
- it "should have documentation" do
- Puppet::SSL::Certificate::File.doc.should be_instance_of(String)
- end
+ it "should have documentation" do
+ Puppet::SSL::Certificate::File.doc.should be_instance_of(String)
+ end
- it "should use the :certdir as the collection directory" do
- Puppet.settings.expects(:value).with(:certdir).returns "/cert/dir"
- Puppet::SSL::Certificate::File.collection_directory.should == "/cert/dir"
- end
+ it "should use the :certdir as the collection directory" do
+ Puppet.settings.expects(:value).with(:certdir).returns "/cert/dir"
+ Puppet::SSL::Certificate::File.collection_directory.should == "/cert/dir"
+ end
- it "should store the ca certificate at the :localcacert location" do
- Puppet.settings.stubs(:use)
- Puppet.settings.stubs(:value).returns "whatever"
- Puppet.settings.stubs(:value).with(:localcacert).returns "/ca/cert"
- file = Puppet::SSL::Certificate::File.new
- file.stubs(:ca?).returns true
- file.path("whatever").should == "/ca/cert"
- end
+ it "should store the ca certificate at the :localcacert location" do
+ Puppet.settings.stubs(:use)
+ Puppet.settings.stubs(:value).returns "whatever"
+ Puppet.settings.stubs(:value).with(:localcacert).returns "/ca/cert"
+ file = Puppet::SSL::Certificate::File.new
+ file.stubs(:ca?).returns true
+ file.path("whatever").should == "/ca/cert"
+ end
end
diff --git a/spec/unit/indirector/certificate/rest_spec.rb b/spec/unit/indirector/certificate/rest_spec.rb
index 9f272fb..77b2a67 100755
--- a/spec/unit/indirector/certificate/rest_spec.rb
+++ b/spec/unit/indirector/certificate/rest_spec.rb
@@ -5,27 +5,27 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/certificate/rest'
describe Puppet::SSL::Certificate::Rest do
- before do
- @searcher = Puppet::SSL::Certificate::Rest.new
- end
+ before do
+ @searcher = Puppet::SSL::Certificate::Rest.new
+ end
- it "should be a sublcass of Puppet::Indirector::REST" do
- Puppet::SSL::Certificate::Rest.superclass.should equal(Puppet::Indirector::REST)
- end
+ it "should be a sublcass of Puppet::Indirector::REST" do
+ Puppet::SSL::Certificate::Rest.superclass.should equal(Puppet::Indirector::REST)
+ end
- it "should set server_setting to :ca_server" do
- Puppet::SSL::Certificate::Rest.server_setting.should == :ca_server
- end
+ it "should set server_setting to :ca_server" do
+ Puppet::SSL::Certificate::Rest.server_setting.should == :ca_server
+ end
- it "should set port_setting to :ca_port" do
- Puppet::SSL::Certificate::Rest.port_setting.should == :ca_port
- end
+ it "should set port_setting to :ca_port" do
+ Puppet::SSL::Certificate::Rest.port_setting.should == :ca_port
+ end
- it "should make sure found certificates have their names set to the search string" do
- terminus = Puppet::SSL::Certificate::Rest.new
+ it "should make sure found certificates have their names set to the search string" do
+ terminus = Puppet::SSL::Certificate::Rest.new
- # This has 'boo.com' in the CN
- cert_string = "-----BEGIN CERTIFICATE-----
+ # This has 'boo.com' in the CN
+ cert_string = "-----BEGIN CERTIFICATE-----
MIICPzCCAaigAwIBAgIBBDANBgkqhkiG9w0BAQUFADAWMRQwEgYDVQQDDAtidWNr
eS5sb2NhbDAeFw0wOTA5MTcxNzI1MzJaFw0xNDA5MTYxNzI1MzJaMBIxEDAOBgNV
BAMMB2Jvby5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKG9B+DkTCNh
@@ -42,17 +42,17 @@ rn/G
-----END CERTIFICATE-----
"
- network = stub 'network'
- terminus.stubs(:network).returns network
+ network = stub 'network'
+ terminus.stubs(:network).returns network
- response = stub 'response', :code => "200", :body => cert_string
- response.stubs(:[]).with('content-type').returns "text/plain"
- response.stubs(:[]).with('content-encoding')
- network.expects(:get).returns response
+ response = stub 'response', :code => "200", :body => cert_string
+ response.stubs(:[]).with('content-type').returns "text/plain"
+ response.stubs(:[]).with('content-encoding')
+ network.expects(:get).returns response
- request = Puppet::Indirector::Request.new(:certificate, :find, "foo.com")
- result = terminus.find(request)
- result.should_not be_nil
- result.name.should == "foo.com"
- end
+ request = Puppet::Indirector::Request.new(:certificate, :find, "foo.com")
+ result = terminus.find(request)
+ result.should_not be_nil
+ result.name.should == "foo.com"
+ end
end
diff --git a/spec/unit/indirector/certificate_request/ca_spec.rb b/spec/unit/indirector/certificate_request/ca_spec.rb
index b35d8b4..1bcbc46 100755
--- a/spec/unit/indirector/certificate_request/ca_spec.rb
+++ b/spec/unit/indirector/certificate_request/ca_spec.rb
@@ -8,12 +8,12 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/certificate_request/ca'
describe Puppet::SSL::CertificateRequest::Ca do
- it "should have documentation" do
- Puppet::SSL::CertificateRequest::Ca.doc.should be_instance_of(String)
- end
+ it "should have documentation" do
+ Puppet::SSL::CertificateRequest::Ca.doc.should be_instance_of(String)
+ end
- it "should use the :csrdir as the collection directory" do
- Puppet.settings.expects(:value).with(:csrdir).returns "/request/dir"
- Puppet::SSL::CertificateRequest::Ca.collection_directory.should == "/request/dir"
- end
+ it "should use the :csrdir as the collection directory" do
+ Puppet.settings.expects(:value).with(:csrdir).returns "/request/dir"
+ Puppet::SSL::CertificateRequest::Ca.collection_directory.should == "/request/dir"
+ end
end
diff --git a/spec/unit/indirector/certificate_request/file_spec.rb b/spec/unit/indirector/certificate_request/file_spec.rb
index e1f442e..f18ba2c 100755
--- a/spec/unit/indirector/certificate_request/file_spec.rb
+++ b/spec/unit/indirector/certificate_request/file_spec.rb
@@ -8,12 +8,12 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/certificate_request/file'
describe Puppet::SSL::CertificateRequest::File do
- it "should have documentation" do
- Puppet::SSL::CertificateRequest::File.doc.should be_instance_of(String)
- end
+ it "should have documentation" do
+ Puppet::SSL::CertificateRequest::File.doc.should be_instance_of(String)
+ end
- it "should use the :requestdir as the collection directory" do
- Puppet.settings.expects(:value).with(:requestdir).returns "/request/dir"
- Puppet::SSL::CertificateRequest::File.collection_directory.should == "/request/dir"
- end
+ it "should use the :requestdir as the collection directory" do
+ Puppet.settings.expects(:value).with(:requestdir).returns "/request/dir"
+ Puppet::SSL::CertificateRequest::File.collection_directory.should == "/request/dir"
+ end
end
diff --git a/spec/unit/indirector/certificate_request/rest_spec.rb b/spec/unit/indirector/certificate_request/rest_spec.rb
index a1492ac..8b90b46 100755
--- a/spec/unit/indirector/certificate_request/rest_spec.rb
+++ b/spec/unit/indirector/certificate_request/rest_spec.rb
@@ -5,19 +5,19 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/certificate_request/rest'
describe Puppet::SSL::CertificateRequest::Rest do
- before do
- @searcher = Puppet::SSL::CertificateRequest::Rest.new
- end
+ before do
+ @searcher = Puppet::SSL::CertificateRequest::Rest.new
+ end
- it "should be a sublcass of Puppet::Indirector::REST" do
- Puppet::SSL::CertificateRequest::Rest.superclass.should equal(Puppet::Indirector::REST)
- end
+ it "should be a sublcass of Puppet::Indirector::REST" do
+ Puppet::SSL::CertificateRequest::Rest.superclass.should equal(Puppet::Indirector::REST)
+ end
- it "should set server_setting to :ca_server" do
- Puppet::SSL::CertificateRequest::Rest.server_setting.should == :ca_server
- end
+ it "should set server_setting to :ca_server" do
+ Puppet::SSL::CertificateRequest::Rest.server_setting.should == :ca_server
+ end
- it "should set port_setting to :ca_port" do
- Puppet::SSL::CertificateRequest::Rest.port_setting.should == :ca_port
- end
+ it "should set port_setting to :ca_port" do
+ Puppet::SSL::CertificateRequest::Rest.port_setting.should == :ca_port
+ end
end
diff --git a/spec/unit/indirector/certificate_revocation_list/ca_spec.rb b/spec/unit/indirector/certificate_revocation_list/ca_spec.rb
index f6da868..756185d 100755
--- a/spec/unit/indirector/certificate_revocation_list/ca_spec.rb
+++ b/spec/unit/indirector/certificate_revocation_list/ca_spec.rb
@@ -8,14 +8,14 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/certificate_revocation_list/ca'
describe Puppet::SSL::CertificateRevocationList::Ca do
- it "should have documentation" do
- Puppet::SSL::CertificateRevocationList::Ca.doc.should be_instance_of(String)
- end
+ it "should have documentation" do
+ Puppet::SSL::CertificateRevocationList::Ca.doc.should be_instance_of(String)
+ end
- it "should use the :cacrl setting as the crl location" do
- Puppet.settings.stubs(:value).returns "whatever"
- Puppet.settings.stubs(:use)
- Puppet.settings.stubs(:value).with(:cacrl).returns "/request/dir"
- Puppet::SSL::CertificateRevocationList::Ca.new.path("whatever").should == "/request/dir"
- end
+ it "should use the :cacrl setting as the crl location" do
+ Puppet.settings.stubs(:value).returns "whatever"
+ Puppet.settings.stubs(:use)
+ Puppet.settings.stubs(:value).with(:cacrl).returns "/request/dir"
+ Puppet::SSL::CertificateRevocationList::Ca.new.path("whatever").should == "/request/dir"
+ end
end
diff --git a/spec/unit/indirector/certificate_revocation_list/file_spec.rb b/spec/unit/indirector/certificate_revocation_list/file_spec.rb
index 5db4f8c..507942a 100755
--- a/spec/unit/indirector/certificate_revocation_list/file_spec.rb
+++ b/spec/unit/indirector/certificate_revocation_list/file_spec.rb
@@ -8,13 +8,13 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/certificate_revocation_list/file'
describe Puppet::SSL::CertificateRevocationList::File do
- it "should have documentation" do
- Puppet::SSL::CertificateRevocationList::File.doc.should be_instance_of(String)
- end
+ it "should have documentation" do
+ Puppet::SSL::CertificateRevocationList::File.doc.should be_instance_of(String)
+ end
- it "should always store the file to :hostcrl location" do
- Puppet.settings.expects(:value).with(:hostcrl).returns "/host/crl"
- Puppet.settings.stubs(:use)
- Puppet::SSL::CertificateRevocationList::File.file_location.should == "/host/crl"
- end
+ it "should always store the file to :hostcrl location" do
+ Puppet.settings.expects(:value).with(:hostcrl).returns "/host/crl"
+ Puppet.settings.stubs(:use)
+ Puppet::SSL::CertificateRevocationList::File.file_location.should == "/host/crl"
+ end
end
diff --git a/spec/unit/indirector/certificate_revocation_list/rest_spec.rb b/spec/unit/indirector/certificate_revocation_list/rest_spec.rb
index 4c7cdc3..8cb3263 100755
--- a/spec/unit/indirector/certificate_revocation_list/rest_spec.rb
+++ b/spec/unit/indirector/certificate_revocation_list/rest_spec.rb
@@ -5,19 +5,19 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/certificate_revocation_list/rest'
describe Puppet::SSL::CertificateRevocationList::Rest do
- before do
- @searcher = Puppet::SSL::CertificateRevocationList::Rest.new
- end
+ before do
+ @searcher = Puppet::SSL::CertificateRevocationList::Rest.new
+ end
- it "should be a sublcass of Puppet::Indirector::REST" do
- Puppet::SSL::CertificateRevocationList::Rest.superclass.should equal(Puppet::Indirector::REST)
- end
+ it "should be a sublcass of Puppet::Indirector::REST" do
+ Puppet::SSL::CertificateRevocationList::Rest.superclass.should equal(Puppet::Indirector::REST)
+ end
- it "should set server_setting to :ca_server" do
- Puppet::SSL::CertificateRevocationList::Rest.server_setting.should == :ca_server
- end
+ it "should set server_setting to :ca_server" do
+ Puppet::SSL::CertificateRevocationList::Rest.server_setting.should == :ca_server
+ end
- it "should set port_setting to :ca_port" do
- Puppet::SSL::CertificateRevocationList::Rest.port_setting.should == :ca_port
- end
+ it "should set port_setting to :ca_port" do
+ Puppet::SSL::CertificateRevocationList::Rest.port_setting.should == :ca_port
+ end
end
diff --git a/spec/unit/indirector/code_spec.rb b/spec/unit/indirector/code_spec.rb
index 3eb7540..916469a 100755
--- a/spec/unit/indirector/code_spec.rb
+++ b/spec/unit/indirector/code_spec.rb
@@ -4,30 +4,30 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector/code'
describe Puppet::Indirector::Code do
- before do
- Puppet::Indirector::Terminus.stubs(:register_terminus_class)
- @model = mock 'model'
- @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model
- Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
+ before do
+ Puppet::Indirector::Terminus.stubs(:register_terminus_class)
+ @model = mock 'model'
+ @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model
+ Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
- @code_class = Class.new(Puppet::Indirector::Code) do
- def self.to_s
- "Mystuff::Testing"
- end
- end
-
- @searcher = @code_class.new
+ @code_class = Class.new(Puppet::Indirector::Code) do
+ def self.to_s
+ "Mystuff::Testing"
+ end
end
- it "should not have a find() method defined" do
- @searcher.should_not respond_to(:find)
- end
+ @searcher = @code_class.new
+ end
- it "should not have a save() method defined" do
- @searcher.should_not respond_to(:save)
- end
+ it "should not have a find() method defined" do
+ @searcher.should_not respond_to(:find)
+ end
- it "should not have a destroy() method defined" do
- @searcher.should_not respond_to(:destroy)
- end
+ it "should not have a save() method defined" do
+ @searcher.should_not respond_to(:save)
+ end
+
+ it "should not have a destroy() method defined" do
+ @searcher.should_not respond_to(:destroy)
+ end
end
diff --git a/spec/unit/indirector/direct_file_server_spec.rb b/spec/unit/indirector/direct_file_server_spec.rb
index e32fe66..0111b54 100755
--- a/spec/unit/indirector/direct_file_server_spec.rb
+++ b/spec/unit/indirector/direct_file_server_spec.rb
@@ -8,77 +8,77 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector/direct_file_server'
describe Puppet::Indirector::DirectFileServer do
- before :each do
- Puppet::Indirector::Terminus.stubs(:register_terminus_class)
- @model = mock 'model'
- @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model
- Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
+ before :each do
+ Puppet::Indirector::Terminus.stubs(:register_terminus_class)
+ @model = mock 'model'
+ @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model
+ Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
+
+ @direct_file_class = Class.new(Puppet::Indirector::DirectFileServer) do
+ def self.to_s
+ "Testing::Mytype"
+ end
+ end
+
+ @server = @direct_file_class.new
- @direct_file_class = Class.new(Puppet::Indirector::DirectFileServer) do
- def self.to_s
- "Testing::Mytype"
- end
- end
+ @uri = "file:///my/local"
- @server = @direct_file_class.new
+ @request = Puppet::Indirector::Request.new(:mytype, :find, @uri)
+ end
- @uri = "file:///my/local"
+ describe Puppet::Indirector::DirectFileServer, "when finding a single file" do
- @request = Puppet::Indirector::Request.new(:mytype, :find, @uri)
+ it "should return nil if the file does not exist" do
+ FileTest.expects(:exists?).with("/my/local").returns false
+ @server.find(@request).should be_nil
end
- describe Puppet::Indirector::DirectFileServer, "when finding a single file" do
+ it "should return a Content instance created with the full path to the file if the file exists" do
+ FileTest.expects(:exists?).with("/my/local").returns true
+ @model.expects(:new).returns(:mycontent)
+ @server.find(@request).should == :mycontent
+ end
+ end
- it "should return nil if the file does not exist" do
- FileTest.expects(:exists?).with("/my/local").returns false
- @server.find(@request).should be_nil
- end
+ describe Puppet::Indirector::DirectFileServer, "when creating the instance for a single found file" do
- it "should return a Content instance created with the full path to the file if the file exists" do
- FileTest.expects(:exists?).with("/my/local").returns true
- @model.expects(:new).returns(:mycontent)
- @server.find(@request).should == :mycontent
- end
+ before do
+ @data = mock 'content'
+ @data.stubs(:collect)
+ FileTest.expects(:exists?).with("/my/local").returns true
end
- describe Puppet::Indirector::DirectFileServer, "when creating the instance for a single found file" do
+ it "should pass the full path to the instance" do
+ @model.expects(:new).with { |key, options| key == "/my/local" }.returns(@data)
+ @server.find(@request)
+ end
- before do
- @data = mock 'content'
- @data.stubs(:collect)
- FileTest.expects(:exists?).with("/my/local").returns true
- end
+ it "should pass the :links setting on to the created Content instance if the file exists and there is a value for :links" do
+ @model.expects(:new).returns(@data)
+ @data.expects(:links=).with(:manage)
- it "should pass the full path to the instance" do
- @model.expects(:new).with { |key, options| key == "/my/local" }.returns(@data)
- @server.find(@request)
- end
+ @request.stubs(:options).returns(:links => :manage)
+ @server.find(@request)
+ end
+ end
- it "should pass the :links setting on to the created Content instance if the file exists and there is a value for :links" do
- @model.expects(:new).returns(@data)
- @data.expects(:links=).with(:manage)
+ describe Puppet::Indirector::DirectFileServer, "when searching for multiple files" do
+ it "should return nil if the file does not exist" do
+ FileTest.expects(:exists?).with("/my/local").returns false
+ @server.find(@request).should be_nil
+ end
- @request.stubs(:options).returns(:links => :manage)
- @server.find(@request)
- end
+ it "should use :path2instances from the terminus_helper to return instances if the file exists" do
+ FileTest.expects(:exists?).with("/my/local").returns true
+ @server.expects(:path2instances)
+ @server.search(@request)
end
- describe Puppet::Indirector::DirectFileServer, "when searching for multiple files" do
- it "should return nil if the file does not exist" do
- FileTest.expects(:exists?).with("/my/local").returns false
- @server.find(@request).should be_nil
- end
-
- it "should use :path2instances from the terminus_helper to return instances if the file exists" do
- FileTest.expects(:exists?).with("/my/local").returns true
- @server.expects(:path2instances)
- @server.search(@request)
- end
-
- it "should pass the original request to :path2instances" do
- FileTest.expects(:exists?).with("/my/local").returns true
- @server.expects(:path2instances).with(@request, "/my/local")
- @server.search(@request)
- end
+ it "should pass the original request to :path2instances" do
+ FileTest.expects(:exists?).with("/my/local").returns true
+ @server.expects(:path2instances).with(@request, "/my/local")
+ @server.search(@request)
end
+ end
end
diff --git a/spec/unit/indirector/envelope_spec.rb b/spec/unit/indirector/envelope_spec.rb
index 17c6202..fb80824 100755
--- a/spec/unit/indirector/envelope_spec.rb
+++ b/spec/unit/indirector/envelope_spec.rb
@@ -4,44 +4,44 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector/envelope'
describe Puppet::Indirector::Envelope do
- before do
- @instance = Object.new
- @instance.extend(Puppet::Indirector::Envelope)
+ before do
+ @instance = Object.new
+ @instance.extend(Puppet::Indirector::Envelope)
+ end
+
+ it "should have an expiration accessor" do
+ @instance.expiration = "testing"
+ @instance.expiration.should == "testing"
+ end
+
+ it "should have an expiration setter" do
+ @instance.should respond_to(:expiration=)
+ end
+
+ it "should have a means of testing whether it is expired" do
+ @instance.should respond_to(:expired?)
+ end
+
+ describe "when testing if it is expired" do
+ it "should return false if there is no expiration set" do
+ @instance.should_not be_expired
end
- it "should have an expiration accessor" do
- @instance.expiration = "testing"
- @instance.expiration.should == "testing"
+ it "should return true if the current date is after the expiration date" do
+ @instance.expiration = Time.now - 10
+ @instance.should be_expired
end
- it "should have an expiration setter" do
- @instance.should respond_to(:expiration=)
+ it "should return false if the current date is prior to the expiration date" do
+ @instance.expiration = Time.now + 10
+ @instance.should_not be_expired
end
- it "should have a means of testing whether it is expired" do
- @instance.should respond_to(:expired?)
- end
-
- describe "when testing if it is expired" do
- it "should return false if there is no expiration set" do
- @instance.should_not be_expired
- end
-
- it "should return true if the current date is after the expiration date" do
- @instance.expiration = Time.now - 10
- @instance.should be_expired
- end
-
- it "should return false if the current date is prior to the expiration date" do
- @instance.expiration = Time.now + 10
- @instance.should_not be_expired
- end
-
- it "should return false if the current date is equal to the expiration date" do
- now = Time.now
- Time.stubs(:now).returns(now)
- @instance.expiration = now
- @instance.should_not be_expired
- end
+ it "should return false if the current date is equal to the expiration date" do
+ now = Time.now
+ Time.stubs(:now).returns(now)
+ @instance.expiration = now
+ @instance.should_not be_expired
end
+ end
end
diff --git a/spec/unit/indirector/exec_spec.rb b/spec/unit/indirector/exec_spec.rb
index 4a7e2b5..acad1ea 100755
--- a/spec/unit/indirector/exec_spec.rb
+++ b/spec/unit/indirector/exec_spec.rb
@@ -5,52 +5,52 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector/exec'
describe Puppet::Indirector::Exec do
- before do
- @indirection = stub 'indirection', :name => :testing
- Puppet::Indirector::Indirection.expects(:instance).with(:testing).returns(@indirection)
- @exec_class = Class.new(Puppet::Indirector::Exec) do
- def self.to_s
- "Testing::Mytype"
- end
+ before do
+ @indirection = stub 'indirection', :name => :testing
+ Puppet::Indirector::Indirection.expects(:instance).with(:testing).returns(@indirection)
+ @exec_class = Class.new(Puppet::Indirector::Exec) do
+ def self.to_s
+ "Testing::Mytype"
+ end
+
+ attr_accessor :command
+ end
- attr_accessor :command
- end
+ @searcher = @exec_class.new
+ @searcher.command = ["/echo"]
- @searcher = @exec_class.new
- @searcher.command = ["/echo"]
+ @request = stub 'request', :key => "foo"
+ end
- @request = stub 'request', :key => "foo"
- end
+ it "should throw an exception if the command is not an array" do
+ @searcher.command = "/usr/bin/echo"
+ proc { @searcher.find(@request) }.should raise_error(Puppet::DevError)
+ end
- it "should throw an exception if the command is not an array" do
- @searcher.command = "/usr/bin/echo"
- proc { @searcher.find(@request) }.should raise_error(Puppet::DevError)
- end
+ it "should throw an exception if the command is not fully qualified" do
+ @searcher.command = ["mycommand"]
+ proc { @searcher.find(@request) }.should raise_error(ArgumentError)
+ end
- it "should throw an exception if the command is not fully qualified" do
- @searcher.command = ["mycommand"]
- proc { @searcher.find(@request) }.should raise_error(ArgumentError)
- end
+ it "should execute the command with the object name as the only argument" do
+ @searcher.expects(:execute).with(%w{/echo foo})
+ @searcher.find(@request)
+ end
- it "should execute the command with the object name as the only argument" do
- @searcher.expects(:execute).with(%w{/echo foo})
- @searcher.find(@request)
- end
+ it "should return the output of the script" do
+ @searcher.expects(:execute).with(%w{/echo foo}).returns("whatever")
+ @searcher.find(@request).should == "whatever"
+ end
- it "should return the output of the script" do
- @searcher.expects(:execute).with(%w{/echo foo}).returns("whatever")
- @searcher.find(@request).should == "whatever"
- end
-
- it "should return nil when the command produces no output" do
- @searcher.expects(:execute).with(%w{/echo foo}).returns(nil)
- @searcher.find(@request).should be_nil
- end
+ it "should return nil when the command produces no output" do
+ @searcher.expects(:execute).with(%w{/echo foo}).returns(nil)
+ @searcher.find(@request).should be_nil
+ end
- it "should return nil and log an error if there's an execution failure" do
- @searcher.expects(:execute).with(%w{/echo foo}).raises(Puppet::ExecutionFailure.new("message"))
+ it "should return nil and log an error if there's an execution failure" do
+ @searcher.expects(:execute).with(%w{/echo foo}).raises(Puppet::ExecutionFailure.new("message"))
- Puppet.expects(:err)
- @searcher.find(@request).should be_nil
- end
+ Puppet.expects(:err)
+ @searcher.find(@request).should be_nil
+ end
end
diff --git a/spec/unit/indirector/facts/active_record_spec.rb b/spec/unit/indirector/facts/active_record_spec.rb
index 1718311..0cdb70e 100755
--- a/spec/unit/indirector/facts/active_record_spec.rb
+++ b/spec/unit/indirector/facts/active_record_spec.rb
@@ -5,100 +5,100 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/node/facts'
describe "Puppet::Node::Facts::ActiveRecord" do
- confine "Missing Rails" => Puppet.features.rails?
+ confine "Missing Rails" => Puppet.features.rails?
+ before do
+ require 'puppet/indirector/facts/active_record'
+ Puppet.features.stubs(:rails?).returns true
+ Puppet::Rails.stubs(:init)
+ @terminus = Puppet::Node::Facts::ActiveRecord.new
+ end
+
+ it "should be a subclass of the ActiveRecord terminus class" do
+ Puppet::Node::Facts::ActiveRecord.ancestors.should be_include(Puppet::Indirector::ActiveRecord)
+ end
+
+ it "should use Puppet::Rails::Host as its ActiveRecord model" do
+ Puppet::Node::Facts::ActiveRecord.ar_model.should equal(Puppet::Rails::Host)
+ end
+
+ describe "when finding an instance" do
before do
- require 'puppet/indirector/facts/active_record'
- Puppet.features.stubs(:rails?).returns true
- Puppet::Rails.stubs(:init)
- @terminus = Puppet::Node::Facts::ActiveRecord.new
+ @request = stub 'request', :key => "foo"
end
- it "should be a subclass of the ActiveRecord terminus class" do
- Puppet::Node::Facts::ActiveRecord.ancestors.should be_include(Puppet::Indirector::ActiveRecord)
+ it "should use the Hosts ActiveRecord class to find the host" do
+ Puppet::Rails::Host.expects(:find_by_name).with { |key, args| key == "foo" }
+ @terminus.find(@request)
end
- it "should use Puppet::Rails::Host as its ActiveRecord model" do
- Puppet::Node::Facts::ActiveRecord.ar_model.should equal(Puppet::Rails::Host)
+ it "should include the fact names and values when finding the host" do
+ Puppet::Rails::Host.expects(:find_by_name).with { |key, args| args[:include] == {:fact_values => :fact_name} }
+ @terminus.find(@request)
end
- describe "when finding an instance" do
- before do
- @request = stub 'request', :key => "foo"
- end
-
- it "should use the Hosts ActiveRecord class to find the host" do
- Puppet::Rails::Host.expects(:find_by_name).with { |key, args| key == "foo" }
- @terminus.find(@request)
- end
+ it "should return nil if no host instance can be found" do
+ Puppet::Rails::Host.expects(:find_by_name).returns nil
- it "should include the fact names and values when finding the host" do
- Puppet::Rails::Host.expects(:find_by_name).with { |key, args| args[:include] == {:fact_values => :fact_name} }
- @terminus.find(@request)
- end
-
- it "should return nil if no host instance can be found" do
- Puppet::Rails::Host.expects(:find_by_name).returns nil
-
- @terminus.find(@request).should be_nil
- end
+ @terminus.find(@request).should be_nil
+ end
- it "should convert the node's parameters into a Facts instance if a host instance is found" do
- host = stub 'host', :name => "foo"
- host.expects(:get_facts_hash).returns("one" => [mock("two_value", :value => "two")], "three" => [mock("three_value", :value => "four")])
+ it "should convert the node's parameters into a Facts instance if a host instance is found" do
+ host = stub 'host', :name => "foo"
+ host.expects(:get_facts_hash).returns("one" => [mock("two_value", :value => "two")], "three" => [mock("three_value", :value => "four")])
- Puppet::Rails::Host.expects(:find_by_name).returns host
+ Puppet::Rails::Host.expects(:find_by_name).returns host
- result = @terminus.find(@request)
+ result = @terminus.find(@request)
- result.should be_instance_of(Puppet::Node::Facts)
- result.name.should == "foo"
- result.values.should == {"one" => "two", "three" => "four"}
- end
+ result.should be_instance_of(Puppet::Node::Facts)
+ result.name.should == "foo"
+ result.values.should == {"one" => "two", "three" => "four"}
+ end
- it "should convert all single-member arrays into non-arrays" do
- host = stub 'host', :name => "foo"
- host.expects(:get_facts_hash).returns("one" => [mock("two_value", :value => "two")])
+ it "should convert all single-member arrays into non-arrays" do
+ host = stub 'host', :name => "foo"
+ host.expects(:get_facts_hash).returns("one" => [mock("two_value", :value => "two")])
- Puppet::Rails::Host.expects(:find_by_name).returns host
+ Puppet::Rails::Host.expects(:find_by_name).returns host
- @terminus.find(@request).values["one"].should == "two"
- end
+ @terminus.find(@request).values["one"].should == "two"
end
+ end
- describe "when saving an instance" do
- before do
- @host = stub 'host', :name => "foo", :save => nil, :merge_facts => nil
- Puppet::Rails::Host.stubs(:find_by_name).returns @host
- @facts = Puppet::Node::Facts.new("foo", "one" => "two", "three" => "four")
- @request = stub 'request', :key => "foo", :instance => @facts
- end
+ describe "when saving an instance" do
+ before do
+ @host = stub 'host', :name => "foo", :save => nil, :merge_facts => nil
+ Puppet::Rails::Host.stubs(:find_by_name).returns @host
+ @facts = Puppet::Node::Facts.new("foo", "one" => "two", "three" => "four")
+ @request = stub 'request', :key => "foo", :instance => @facts
+ end
- it "should find the Rails host with the same name" do
- Puppet::Rails::Host.expects(:find_by_name).with("foo").returns @host
+ it "should find the Rails host with the same name" do
+ Puppet::Rails::Host.expects(:find_by_name).with("foo").returns @host
- @terminus.save(@request)
- end
+ @terminus.save(@request)
+ end
- it "should create a new Rails host if none can be found" do
- Puppet::Rails::Host.expects(:find_by_name).with("foo").returns nil
+ it "should create a new Rails host if none can be found" do
+ Puppet::Rails::Host.expects(:find_by_name).with("foo").returns nil
- Puppet::Rails::Host.expects(:create).with(:name => "foo").returns @host
+ Puppet::Rails::Host.expects(:create).with(:name => "foo").returns @host
- @terminus.save(@request)
- end
+ @terminus.save(@request)
+ end
- it "should set the facts as facts on the Rails host instance" do
- # There is other stuff added to the hash.
- @host.expects(:merge_facts).with { |args| args["one"] == "two" and args["three"] == "four" }
+ it "should set the facts as facts on the Rails host instance" do
+ # There is other stuff added to the hash.
+ @host.expects(:merge_facts).with { |args| args["one"] == "two" and args["three"] == "four" }
- @terminus.save(@request)
- end
+ @terminus.save(@request)
+ end
- it "should save the Rails host instance" do
- @host.expects(:save)
+ it "should save the Rails host instance" do
+ @host.expects(:save)
- @terminus.save(@request)
- end
+ @terminus.save(@request)
end
+ end
end
diff --git a/spec/unit/indirector/facts/couch_spec.rb b/spec/unit/indirector/facts/couch_spec.rb
index 0884012..c0dd54b 100644
--- a/spec/unit/indirector/facts/couch_spec.rb
+++ b/spec/unit/indirector/facts/couch_spec.rb
@@ -5,94 +5,94 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/node/facts'
describe "Puppet::Node::Facts::Couch" do
- confine "couchrest gem is missing; cannot test couch terminus" => Puppet.features.couchdb?
- require 'puppet/indirector/facts/couch' if Puppet.features.couchdb?
-
- before do
- @mock_db = mock('couch db')
- mock_document = CouchRest::Document.new(:_id => fake_request.key, :facts => fake_request.values)
- mock_document.stubs(:database).returns(@mock_db)
- @mock_db.stubs(:get).with(fake_request.key).returns(mock_document)
- Puppet::Node::Facts::Couch.stubs(:db).returns(@mock_db)
+ confine "couchrest gem is missing; cannot test couch terminus" => Puppet.features.couchdb?
+ require 'puppet/indirector/facts/couch' if Puppet.features.couchdb?
+
+ before do
+ @mock_db = mock('couch db')
+ mock_document = CouchRest::Document.new(:_id => fake_request.key, :facts => fake_request.values)
+ mock_document.stubs(:database).returns(@mock_db)
+ @mock_db.stubs(:get).with(fake_request.key).returns(mock_document)
+ Puppet::Node::Facts::Couch.stubs(:db).returns(@mock_db)
+ end
+
+ subject { Puppet::Node::Facts::Couch }
+
+ describe "#find" do
+ describe "when the node document exists" do
+ it "should find the request by key" do
+ @mock_db.expects(:get).with(fake_request.key).returns({'_id' => fake_request.key, 'facts' => fake_request.instance.values})
+ subject.new.find(fake_request).should == fake_request.instance
+ end
end
- subject { Puppet::Node::Facts::Couch }
-
- describe "#find" do
- describe "when the node document exists" do
- it "should find the request by key" do
- @mock_db.expects(:get).with(fake_request.key).returns({'_id' => fake_request.key, 'facts' => fake_request.instance.values})
- subject.new.find(fake_request).should == fake_request.instance
- end
- end
-
- describe "when the node document does not exist" do
- before do
- @mock_db.expects(:get).
- with(fake_request.key).
- raises(RestClient::ResourceNotFound)
- end
-
- it "should return nil" do
- subject.new.find(fake_request).should be_nil
- end
-
- it "should send Puppet a debug message" do
- Puppet.expects(:debug).with("No couchdb document with id: test.local")
- subject.new.find(fake_request).should be_nil
- end
-
- end
- end
-
- describe "#save" do
- describe "with options" do
- subject do
- lambda { Puppet::Node::Facts::Couch.new.save(fake_request([1])) }
- end
+ describe "when the node document does not exist" do
+ before do
+ @mock_db.expects(:get).
+ with(fake_request.key).
+ raises(RestClient::ResourceNotFound)
+ end
- it { should raise_error(ArgumentError, "PUT does not accept options") }
- end
+ it "should return nil" do
+ subject.new.find(fake_request).should be_nil
+ end
- it "should save the json to the CouchDB database" do
- @mock_db.expects(:save_doc).at_least_once.returns({'ok' => true })
- subject.new.save(fake_request)
- end
+ it "should send Puppet a debug message" do
+ Puppet.expects(:debug).with("No couchdb document with id: test.local")
+ subject.new.find(fake_request).should be_nil
+ end
- describe "when the document exists" do
- before do
- @doc = CouchRest::Document.new(:_id => fake_request.key, :facts => fake_request.instance.values)
- @mock_db.expects(:get).with(fake_request.key).returns(@doc)
- end
+ end
+ end
- it "saves the document" do
- @doc.expects(:save)
- subject.new.save(fake_request)
- end
+ describe "#save" do
+ describe "with options" do
+ subject do
+ lambda { Puppet::Node::Facts::Couch.new.save(fake_request([1])) }
+ end
- end
+ it { should raise_error(ArgumentError, "PUT does not accept options") }
+ end
- describe "when the document does not exist" do
- before do
- @mock_db.expects(:get).
- with(fake_request.key).
- raises(RestClient::ResourceNotFound)
- end
+ it "should save the json to the CouchDB database" do
+ @mock_db.expects(:save_doc).at_least_once.returns({'ok' => true })
+ subject.new.save(fake_request)
+ end
- it "saves the document" do
- @mock_db.expects(:save_doc)
- subject.new.save(fake_request)
- end
+ describe "when the document exists" do
+ before do
+ @doc = CouchRest::Document.new(:_id => fake_request.key, :facts => fake_request.instance.values)
+ @mock_db.expects(:get).with(fake_request.key).returns(@doc)
+ end
- end
+ it "saves the document" do
+ @doc.expects(:save)
+ subject.new.save(fake_request)
+ end
end
- def fake_request(options={})
- facts = YAML.load_file(File.join(PuppetSpec::FIXTURE_DIR, 'yaml', 'test.local.yaml'))
- Struct.new(:instance, :key, :options).new(facts, facts.name, options)
+ describe "when the document does not exist" do
+ before do
+ @mock_db.expects(:get).
+ with(fake_request.key).
+ raises(RestClient::ResourceNotFound)
+ end
+
+ it "saves the document" do
+ @mock_db.expects(:save_doc)
+ subject.new.save(fake_request)
+ end
+
end
- private :fake_request
+
+ end
+
+ def fake_request(options={})
+ facts = YAML.load_file(File.join(PuppetSpec::FIXTURE_DIR, 'yaml', 'test.local.yaml'))
+ Struct.new(:instance, :key, :options).new(facts, facts.name, options)
+ end
+ private :fake_request
end
diff --git a/spec/unit/indirector/facts/facter_spec.rb b/spec/unit/indirector/facts/facter_spec.rb
index 2b127ad..1694409 100755
--- a/spec/unit/indirector/facts/facter_spec.rb
+++ b/spec/unit/indirector/facts/facter_spec.rb
@@ -8,136 +8,136 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/facts/facter'
describe Puppet::Node::Facts::Facter do
- it "should be a subclass of the Code terminus" do
- Puppet::Node::Facts::Facter.superclass.should equal(Puppet::Indirector::Code)
- end
+ it "should be a subclass of the Code terminus" do
+ Puppet::Node::Facts::Facter.superclass.should equal(Puppet::Indirector::Code)
+ end
+
+ it "should have documentation" do
+ Puppet::Node::Facts::Facter.doc.should_not be_nil
+ end
+
+ it "should be registered with the configuration store indirection" do
+ indirection = Puppet::Indirector::Indirection.instance(:facts)
+ Puppet::Node::Facts::Facter.indirection.should equal(indirection)
+ end
+
+ it "should have its name set to :facter" do
+ Puppet::Node::Facts::Facter.name.should == :facter
+ end
+
+ it "should load facts on initialization" do
+ Puppet::Node::Facts::Facter.expects(:load_fact_plugins)
+ Puppet::Node::Facts::Facter.new
+ end
+end
- it "should have documentation" do
- Puppet::Node::Facts::Facter.doc.should_not be_nil
+describe Puppet::Node::Facts::Facter do
+ before :each do
+ @facter = Puppet::Node::Facts::Facter.new
+ Facter.stubs(:to_hash).returns({})
+ @name = "me"
+ @request = stub 'request', :key => @name
+ end
+
+ describe Puppet::Node::Facts::Facter, " when finding facts" do
+ it "should return a Facts instance" do
+ @facter.find(@request).should be_instance_of(Puppet::Node::Facts)
end
- it "should be registered with the configuration store indirection" do
- indirection = Puppet::Indirector::Indirection.instance(:facts)
- Puppet::Node::Facts::Facter.indirection.should equal(indirection)
+ it "should return a Facts instance with the provided key as the name" do
+ @facter.find(@request).name.should == @name
end
- it "should have its name set to :facter" do
- Puppet::Node::Facts::Facter.name.should == :facter
+ it "should return the Facter facts as the values in the Facts instance" do
+ Facter.expects(:to_hash).returns("one" => "two")
+ facts = @facter.find(@request)
+ facts.values["one"].should == "two"
end
- it "should load facts on initialization" do
- Puppet::Node::Facts::Facter.expects(:load_fact_plugins)
- Puppet::Node::Facts::Facter.new
- end
-end
+ it "should add local facts" do
+ facts = Puppet::Node::Facts.new("foo")
+ Puppet::Node::Facts.expects(:new).returns facts
+ facts.expects(:add_local_facts)
-describe Puppet::Node::Facts::Facter do
- before :each do
- @facter = Puppet::Node::Facts::Facter.new
- Facter.stubs(:to_hash).returns({})
- @name = "me"
- @request = stub 'request', :key => @name
+ @facter.find(@request)
end
- describe Puppet::Node::Facts::Facter, " when finding facts" do
- it "should return a Facts instance" do
- @facter.find(@request).should be_instance_of(Puppet::Node::Facts)
- end
-
- it "should return a Facts instance with the provided key as the name" do
- @facter.find(@request).name.should == @name
- end
-
- it "should return the Facter facts as the values in the Facts instance" do
- Facter.expects(:to_hash).returns("one" => "two")
- facts = @facter.find(@request)
- facts.values["one"].should == "two"
- end
+ it "should convert all facts into strings" do
+ facts = Puppet::Node::Facts.new("foo")
+ Puppet::Node::Facts.expects(:new).returns facts
+ facts.expects(:stringify)
- it "should add local facts" do
- facts = Puppet::Node::Facts.new("foo")
- Puppet::Node::Facts.expects(:new).returns facts
- facts.expects(:add_local_facts)
-
- @facter.find(@request)
- end
-
- it "should convert all facts into strings" do
- facts = Puppet::Node::Facts.new("foo")
- Puppet::Node::Facts.expects(:new).returns facts
- facts.expects(:stringify)
-
- @facter.find(@request)
- end
+ @facter.find(@request)
+ end
- it "should call the downcase hook" do
- facts = Puppet::Node::Facts.new("foo")
- Puppet::Node::Facts.expects(:new).returns facts
- facts.expects(:downcase_if_necessary)
+ it "should call the downcase hook" do
+ facts = Puppet::Node::Facts.new("foo")
+ Puppet::Node::Facts.expects(:new).returns facts
+ facts.expects(:downcase_if_necessary)
- @facter.find(@request)
- end
+ @facter.find(@request)
end
+ end
- describe Puppet::Node::Facts::Facter, " when saving facts" do
+ describe Puppet::Node::Facts::Facter, " when saving facts" do
- it "should fail" do
- proc { @facter.save(@facts) }.should raise_error(Puppet::DevError)
- end
+ it "should fail" do
+ proc { @facter.save(@facts) }.should raise_error(Puppet::DevError)
end
+ end
- describe Puppet::Node::Facts::Facter, " when destroying facts" do
+ describe Puppet::Node::Facts::Facter, " when destroying facts" do
- it "should fail" do
- proc { @facter.destroy(@facts) }.should raise_error(Puppet::DevError)
- end
+ it "should fail" do
+ proc { @facter.destroy(@facts) }.should raise_error(Puppet::DevError)
end
+ end
- it "should skip files when asked to load a directory" do
- FileTest.expects(:directory?).with("myfile").returns false
+ it "should skip files when asked to load a directory" do
+ FileTest.expects(:directory?).with("myfile").returns false
- Puppet::Node::Facts::Facter.load_facts_in_dir("myfile")
- end
+ Puppet::Node::Facts::Facter.load_facts_in_dir("myfile")
+ end
- it "should load each ruby file when asked to load a directory" do
- FileTest.expects(:directory?).with("mydir").returns true
- Dir.expects(:chdir).with("mydir").yields
+ it "should load each ruby file when asked to load a directory" do
+ FileTest.expects(:directory?).with("mydir").returns true
+ Dir.expects(:chdir).with("mydir").yields
- Dir.expects(:glob).with("*.rb").returns %w{a.rb b.rb}
+ Dir.expects(:glob).with("*.rb").returns %w{a.rb b.rb}
- Puppet::Node::Facts::Facter.expects(:load).with("a.rb")
- Puppet::Node::Facts::Facter.expects(:load).with("b.rb")
+ Puppet::Node::Facts::Facter.expects(:load).with("a.rb")
+ Puppet::Node::Facts::Facter.expects(:load).with("b.rb")
- Puppet::Node::Facts::Facter.load_facts_in_dir("mydir")
- end
+ Puppet::Node::Facts::Facter.load_facts_in_dir("mydir")
+ end
- describe Puppet::Node::Facts::Facter, "when loading fact plugins from disk" do
- it "should load each directory in the Fact path" do
- Puppet.settings.stubs(:value).returns "foo"
- Puppet.settings.expects(:value).with(:factpath).returns("one#{File::PATH_SEPARATOR}two")
+ describe Puppet::Node::Facts::Facter, "when loading fact plugins from disk" do
+ it "should load each directory in the Fact path" do
+ Puppet.settings.stubs(:value).returns "foo"
+ Puppet.settings.expects(:value).with(:factpath).returns("one#{File::PATH_SEPARATOR}two")
- Puppet::Node::Facts::Facter.expects(:load_facts_in_dir).with("one")
- Puppet::Node::Facts::Facter.expects(:load_facts_in_dir).with("two")
+ Puppet::Node::Facts::Facter.expects(:load_facts_in_dir).with("one")
+ Puppet::Node::Facts::Facter.expects(:load_facts_in_dir).with("two")
- Puppet::Node::Facts::Facter.load_fact_plugins
- end
+ Puppet::Node::Facts::Facter.load_fact_plugins
+ end
- it "should load all facts from the modules" do
- Puppet.settings.stubs(:value).returns "foo"
- Puppet::Node::Facts::Facter.stubs(:load_facts_in_dir)
+ it "should load all facts from the modules" do
+ Puppet.settings.stubs(:value).returns "foo"
+ Puppet::Node::Facts::Facter.stubs(:load_facts_in_dir)
- Puppet.settings.expects(:value).with(:modulepath).returns("one#{File::PATH_SEPARATOR}two")
+ Puppet.settings.expects(:value).with(:modulepath).returns("one#{File::PATH_SEPARATOR}two")
- Dir.stubs(:glob).returns []
- Dir.expects(:glob).with("one/*/lib/facter").returns %w{oneA oneB}
- Dir.expects(:glob).with("two/*/lib/facter").returns %w{twoA twoB}
+ Dir.stubs(:glob).returns []
+ Dir.expects(:glob).with("one/*/lib/facter").returns %w{oneA oneB}
+ Dir.expects(:glob).with("two/*/lib/facter").returns %w{twoA twoB}
- Puppet::Node::Facts::Facter.expects(:load_facts_in_dir).with("oneA")
- Puppet::Node::Facts::Facter.expects(:load_facts_in_dir).with("oneB")
- Puppet::Node::Facts::Facter.expects(:load_facts_in_dir).with("twoA")
- Puppet::Node::Facts::Facter.expects(:load_facts_in_dir).with("twoB")
+ Puppet::Node::Facts::Facter.expects(:load_facts_in_dir).with("oneA")
+ Puppet::Node::Facts::Facter.expects(:load_facts_in_dir).with("oneB")
+ Puppet::Node::Facts::Facter.expects(:load_facts_in_dir).with("twoA")
+ Puppet::Node::Facts::Facter.expects(:load_facts_in_dir).with("twoB")
- Puppet::Node::Facts::Facter.load_fact_plugins
- end
+ Puppet::Node::Facts::Facter.load_fact_plugins
end
+ end
end
diff --git a/spec/unit/indirector/facts/rest_spec.rb b/spec/unit/indirector/facts/rest_spec.rb
index db46db0..19a5692 100755
--- a/spec/unit/indirector/facts/rest_spec.rb
+++ b/spec/unit/indirector/facts/rest_spec.rb
@@ -5,7 +5,7 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/facts/rest'
describe Puppet::Node::Facts::Rest do
- it "should be a sublcass of Puppet::Indirector::REST" do
- Puppet::Node::Facts::Rest.superclass.should equal(Puppet::Indirector::REST)
- end
+ it "should be a sublcass of Puppet::Indirector::REST" do
+ Puppet::Node::Facts::Rest.superclass.should equal(Puppet::Indirector::REST)
+ end
end
diff --git a/spec/unit/indirector/facts/yaml_spec.rb b/spec/unit/indirector/facts/yaml_spec.rb
index 8b49fa3..e7bac34 100755
--- a/spec/unit/indirector/facts/yaml_spec.rb
+++ b/spec/unit/indirector/facts/yaml_spec.rb
@@ -6,21 +6,21 @@ require 'puppet/node/facts'
require 'puppet/indirector/facts/yaml'
describe Puppet::Node::Facts::Yaml do
- it "should be a subclass of the Yaml terminus" do
- Puppet::Node::Facts::Yaml.superclass.should equal(Puppet::Indirector::Yaml)
- end
+ it "should be a subclass of the Yaml terminus" do
+ Puppet::Node::Facts::Yaml.superclass.should equal(Puppet::Indirector::Yaml)
+ end
- it "should have documentation" do
- Puppet::Node::Facts::Yaml.doc.should_not be_nil
- end
+ it "should have documentation" do
+ Puppet::Node::Facts::Yaml.doc.should_not be_nil
+ end
- it "should be registered with the facts indirection" do
- indirection = Puppet::Indirector::Indirection.instance(:facts)
- Puppet::Node::Facts::Yaml.indirection.should equal(indirection)
- end
+ it "should be registered with the facts indirection" do
+ indirection = Puppet::Indirector::Indirection.instance(:facts)
+ Puppet::Node::Facts::Yaml.indirection.should equal(indirection)
+ end
- it "should have its name set to :facts" do
- Puppet::Node::Facts::Yaml.name.should == :yaml
- end
+ it "should have its name set to :facts" do
+ Puppet::Node::Facts::Yaml.name.should == :yaml
+ end
end
diff --git a/spec/unit/indirector/file_bucket_file/file_spec.rb b/spec/unit/indirector/file_bucket_file/file_spec.rb
index 652da3d..aa3ade6 100755
--- a/spec/unit/indirector/file_bucket_file/file_spec.rb
+++ b/spec/unit/indirector/file_bucket_file/file_spec.rb
@@ -5,286 +5,286 @@ require ::File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/file_bucket_file/file'
describe Puppet::FileBucketFile::File do
- it "should be a subclass of the Code terminus class" do
- Puppet::FileBucketFile::File.superclass.should equal(Puppet::Indirector::Code)
+ it "should be a subclass of the Code terminus class" do
+ Puppet::FileBucketFile::File.superclass.should equal(Puppet::Indirector::Code)
+ end
+
+ it "should have documentation" do
+ Puppet::FileBucketFile::File.doc.should be_instance_of(String)
+ end
+
+ describe "when initializing" do
+ it "should use the filebucket settings section" do
+ Puppet.settings.expects(:use).with(:filebucket)
+ Puppet::FileBucketFile::File.new
end
+ end
- it "should have documentation" do
- Puppet::FileBucketFile::File.doc.should be_instance_of(String)
+
+ describe "the find_by_checksum method" do
+ before do
+ # this is the default from spec_helper, but it keeps getting reset at odd times
+ Puppet[:bucketdir] = "/dev/null/bucket"
+
+ @digest = "4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
+ @checksum = "{md5}4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
+ @dir = '/dev/null/bucket/4/a/8/e/c/4/f/a/4a8ec4fa5f01b4ab1a0ab8cbccb709f0'
+
+ @contents = "file contents"
end
- describe "when initializing" do
- it "should use the filebucket settings section" do
- Puppet.settings.expects(:use).with(:filebucket)
- Puppet::FileBucketFile::File.new
- end
+ it "should return nil if a file doesn't exist" do
+ ::File.expects(:exist?).with("#{@dir}/contents").returns false
+
+ bucketfile = Puppet::FileBucketFile::File.new.send(:find_by_checksum, "{md5}#{@digest}", {})
+ bucketfile.should == nil
end
+ it "should find a filebucket if the file exists" do
+ ::File.expects(:exist?).with("#{@dir}/contents").returns true
+ ::File.expects(:exist?).with("#{@dir}/paths").returns false
+ ::File.expects(:read).with("#{@dir}/contents").returns @contents
- describe "the find_by_checksum method" do
- before do
- # this is the default from spec_helper, but it keeps getting reset at odd times
- Puppet[:bucketdir] = "/dev/null/bucket"
+ bucketfile = Puppet::FileBucketFile::File.new.send(:find_by_checksum, "{md5}#{@digest}", {})
+ bucketfile.should_not == nil
+ end
- @digest = "4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
- @checksum = "{md5}4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
- @dir = '/dev/null/bucket/4/a/8/e/c/4/f/a/4a8ec4fa5f01b4ab1a0ab8cbccb709f0'
+ it "should load the paths" do
+ paths = ["path1", "path2"]
+ ::File.expects(:exist?).with("#{@dir}/contents").returns true
+ ::File.expects(:exist?).with("#{@dir}/paths").returns true
+ ::File.expects(:read).with("#{@dir}/contents").returns @contents
- @contents = "file contents"
- end
+ mockfile = mock "file"
+ mockfile.expects(:readlines).returns( paths )
+ ::File.expects(:open).with("#{@dir}/paths").yields mockfile
- it "should return nil if a file doesn't exist" do
- ::File.expects(:exist?).with("#{@dir}/contents").returns false
+ Puppet::FileBucketFile::File.new.send(:find_by_checksum, "{md5}#{@digest}", {}).paths.should == paths
+ end
- bucketfile = Puppet::FileBucketFile::File.new.send(:find_by_checksum, "{md5}#{@digest}", {})
- bucketfile.should == nil
- end
+ end
- it "should find a filebucket if the file exists" do
- ::File.expects(:exist?).with("#{@dir}/contents").returns true
- ::File.expects(:exist?).with("#{@dir}/paths").returns false
- ::File.expects(:read).with("#{@dir}/contents").returns @contents
+ describe "when retrieving files" do
+ before :each do
+ Puppet.settings.stubs(:use)
+ @store = Puppet::FileBucketFile::File.new
- bucketfile = Puppet::FileBucketFile::File.new.send(:find_by_checksum, "{md5}#{@digest}", {})
- bucketfile.should_not == nil
- end
+ @digest = "70924d6fa4b2d745185fa4660703a5c0"
+ @sum = stub 'sum', :name => @digest
- it "should load the paths" do
- paths = ["path1", "path2"]
- ::File.expects(:exist?).with("#{@dir}/contents").returns true
- ::File.expects(:exist?).with("#{@dir}/paths").returns true
- ::File.expects(:read).with("#{@dir}/contents").returns @contents
+ @dir = "/what/ever"
- mockfile = mock "file"
- mockfile.expects(:readlines).returns( paths )
- ::File.expects(:open).with("#{@dir}/paths").yields mockfile
+ Puppet.stubs(:[]).with(:bucketdir).returns(@dir)
- Puppet::FileBucketFile::File.new.send(:find_by_checksum, "{md5}#{@digest}", {}).paths.should == paths
- end
+ @contents_path = '/what/ever/7/0/9/2/4/d/6/f/70924d6fa4b2d745185fa4660703a5c0/contents'
+ @paths_path = '/what/ever/7/0/9/2/4/d/6/f/70924d6fa4b2d745185fa4660703a5c0/paths'
+ @request = stub 'request', :key => "md5/#{@digest}/remote/path", :options => {}
end
- describe "when retrieving files" do
- before :each do
- Puppet.settings.stubs(:use)
- @store = Puppet::FileBucketFile::File.new
+ it "should call find_by_checksum" do
+ @store.expects(:find_by_checksum).with{|x,opts| x == "{md5}#{@digest}"}.returns(false)
+ @store.find(@request)
+ end
- @digest = "70924d6fa4b2d745185fa4660703a5c0"
- @sum = stub 'sum', :name => @digest
+ it "should look for the calculated path" do
+ ::File.expects(:exist?).with(@contents_path).returns(false)
+ @store.find(@request)
+ end
- @dir = "/what/ever"
+ it "should return an instance of Puppet::FileBucket::File created with the content if the file exists" do
+ content = "my content"
+ bucketfile = stub 'bucketfile'
+ bucketfile.stubs(:bucket_path)
+ bucketfile.stubs(:bucket_path=)
+ bucketfile.stubs(:checksum_data).returns(@digest)
+ bucketfile.stubs(:checksum).returns(@checksum)
- Puppet.stubs(:[]).with(:bucketdir).returns(@dir)
+ bucketfile.expects(:contents=).with(content)
+ Puppet::FileBucket::File.expects(:new).with(nil, {:checksum => "{md5}#{@digest}"}).yields(bucketfile).returns(bucketfile)
- @contents_path = '/what/ever/7/0/9/2/4/d/6/f/70924d6fa4b2d745185fa4660703a5c0/contents'
- @paths_path = '/what/ever/7/0/9/2/4/d/6/f/70924d6fa4b2d745185fa4660703a5c0/paths'
+ ::File.expects(:exist?).with(@contents_path).returns(true)
+ ::File.expects(:exist?).with(@paths_path).returns(false)
+ ::File.expects(:read).with(@contents_path).returns(content)
- @request = stub 'request', :key => "md5/#{@digest}/remote/path", :options => {}
- end
+ @store.find(@request).should equal(bucketfile)
+ end
- it "should call find_by_checksum" do
- @store.expects(:find_by_checksum).with{|x,opts| x == "{md5}#{@digest}"}.returns(false)
- @store.find(@request)
- end
+ it "should return nil if no file is found" do
+ ::File.expects(:exist?).with(@contents_path).returns(false)
+ @store.find(@request).should be_nil
+ end
- it "should look for the calculated path" do
- ::File.expects(:exist?).with(@contents_path).returns(false)
- @store.find(@request)
- end
+ it "should fail intelligently if a found file cannot be read" do
+ ::File.expects(:exist?).with(@contents_path).returns(true)
+ ::File.expects(:read).with(@contents_path).raises(RuntimeError)
+ proc { @store.find(@request) }.should raise_error(Puppet::Error)
+ end
- it "should return an instance of Puppet::FileBucket::File created with the content if the file exists" do
- content = "my content"
- bucketfile = stub 'bucketfile'
- bucketfile.stubs(:bucket_path)
- bucketfile.stubs(:bucket_path=)
- bucketfile.stubs(:checksum_data).returns(@digest)
- bucketfile.stubs(:checksum).returns(@checksum)
+ end
- bucketfile.expects(:contents=).with(content)
- Puppet::FileBucket::File.expects(:new).with(nil, {:checksum => "{md5}#{@digest}"}).yields(bucketfile).returns(bucketfile)
+ describe "when determining file paths" do
+ before do
+ Puppet[:bucketdir] = '/dev/null/bucketdir'
+ @digest = 'DEADBEEFC0FFEE'
+ @bucket = stub_everything "bucket"
+ @bucket.expects(:checksum_data).returns(@digest)
+ end
- ::File.expects(:exist?).with(@contents_path).returns(true)
- ::File.expects(:exist?).with(@paths_path).returns(false)
- ::File.expects(:read).with(@contents_path).returns(content)
+ it "should use the value of the :bucketdir setting as the root directory" do
+ path = Puppet::FileBucketFile::File.new.send(:contents_path_for, @bucket)
+ path.should =~ %r{^/dev/null/bucketdir}
+ end
- @store.find(@request).should equal(bucketfile)
- end
+ it "should choose a path 8 directories deep with each directory name being the respective character in the filebucket" do
+ path = Puppet::FileBucketFile::File.new.send(:contents_path_for, @bucket)
+ dirs = @digest[0..7].split("").join(File::SEPARATOR)
+ path.should be_include(dirs)
+ end
- it "should return nil if no file is found" do
- ::File.expects(:exist?).with(@contents_path).returns(false)
- @store.find(@request).should be_nil
- end
+ it "should use the full filebucket as the final directory name" do
+ path = Puppet::FileBucketFile::File.new.send(:contents_path_for, @bucket)
+ ::File.basename(::File.dirname(path)).should == @digest
+ end
- it "should fail intelligently if a found file cannot be read" do
- ::File.expects(:exist?).with(@contents_path).returns(true)
- ::File.expects(:read).with(@contents_path).raises(RuntimeError)
- proc { @store.find(@request) }.should raise_error(Puppet::Error)
- end
+ it "should use 'contents' as the actual file name" do
+ path = Puppet::FileBucketFile::File.new.send(:contents_path_for, @bucket)
+ ::File.basename(path).should == "contents"
+ end
+ it "should use the bucketdir, the 8 sum character directories, the full filebucket, and 'contents' as the full file name" do
+ path = Puppet::FileBucketFile::File.new.send(:contents_path_for, @bucket)
+ path.should == ['/dev/null/bucketdir', @digest[0..7].split(""), @digest, "contents"].flatten.join(::File::SEPARATOR)
end
+ end
+
+ describe "when saving files" do
+ before do
+ # this is the default from spec_helper, but it keeps getting reset at odd times
+ Puppet[:bucketdir] = "/dev/null/bucket"
+
+ @digest = "4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
+ @checksum = "{md5}4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
+ @dir = '/dev/null/bucket/4/a/8/e/c/4/f/a/4a8ec4fa5f01b4ab1a0ab8cbccb709f0'
+
+ @contents = "file contents"
- describe "when determining file paths" do
- before do
- Puppet[:bucketdir] = '/dev/null/bucketdir'
- @digest = 'DEADBEEFC0FFEE'
- @bucket = stub_everything "bucket"
- @bucket.expects(:checksum_data).returns(@digest)
- end
-
- it "should use the value of the :bucketdir setting as the root directory" do
- path = Puppet::FileBucketFile::File.new.send(:contents_path_for, @bucket)
- path.should =~ %r{^/dev/null/bucketdir}
- end
-
- it "should choose a path 8 directories deep with each directory name being the respective character in the filebucket" do
- path = Puppet::FileBucketFile::File.new.send(:contents_path_for, @bucket)
- dirs = @digest[0..7].split("").join(File::SEPARATOR)
- path.should be_include(dirs)
- end
-
- it "should use the full filebucket as the final directory name" do
- path = Puppet::FileBucketFile::File.new.send(:contents_path_for, @bucket)
- ::File.basename(::File.dirname(path)).should == @digest
- end
-
- it "should use 'contents' as the actual file name" do
- path = Puppet::FileBucketFile::File.new.send(:contents_path_for, @bucket)
- ::File.basename(path).should == "contents"
- end
-
- it "should use the bucketdir, the 8 sum character directories, the full filebucket, and 'contents' as the full file name" do
- path = Puppet::FileBucketFile::File.new.send(:contents_path_for, @bucket)
- path.should == ['/dev/null/bucketdir', @digest[0..7].split(""), @digest, "contents"].flatten.join(::File::SEPARATOR)
- end
+ @bucket = stub "bucket file"
+ @bucket.stubs(:bucket_path)
+ @bucket.stubs(:checksum_data).returns(@digest)
+ @bucket.stubs(:path).returns(nil)
+ @bucket.stubs(:checksum).returns(nil)
+ @bucket.stubs(:contents).returns("file contents")
end
- describe "when saving files" do
- before do
- # this is the default from spec_helper, but it keeps getting reset at odd times
- Puppet[:bucketdir] = "/dev/null/bucket"
-
- @digest = "4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
- @checksum = "{md5}4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
- @dir = '/dev/null/bucket/4/a/8/e/c/4/f/a/4a8ec4fa5f01b4ab1a0ab8cbccb709f0'
-
- @contents = "file contents"
-
- @bucket = stub "bucket file"
- @bucket.stubs(:bucket_path)
- @bucket.stubs(:checksum_data).returns(@digest)
- @bucket.stubs(:path).returns(nil)
- @bucket.stubs(:checksum).returns(nil)
- @bucket.stubs(:contents).returns("file contents")
- end
-
- it "should save the contents to the calculated path" do
- ::File.stubs(:directory?).with(@dir).returns(true)
- ::File.expects(:exist?).with("#{@dir}/contents").returns false
-
- mockfile = mock "file"
- mockfile.expects(:print).with(@contents)
- ::File.expects(:open).with("#{@dir}/contents", ::File::WRONLY|::File::CREAT, 0440).yields(mockfile)
-
- Puppet::FileBucketFile::File.new.send(:save_to_disk, @bucket)
- end
-
- it "should make any directories necessary for storage" do
- FileUtils.expects(:mkdir_p).with do |arg|
- ::File.umask == 0007 and arg == @dir
- end
- ::File.expects(:directory?).with(@dir).returns(false)
- ::File.expects(:open).with("#{@dir}/contents", ::File::WRONLY|::File::CREAT, 0440)
- ::File.expects(:exist?).with("#{@dir}/contents").returns false
-
- Puppet::FileBucketFile::File.new.send(:save_to_disk, @bucket)
- end
+ it "should save the contents to the calculated path" do
+ ::File.stubs(:directory?).with(@dir).returns(true)
+ ::File.expects(:exist?).with("#{@dir}/contents").returns false
+
+ mockfile = mock "file"
+ mockfile.expects(:print).with(@contents)
+ ::File.expects(:open).with("#{@dir}/contents", ::File::WRONLY|::File::CREAT, 0440).yields(mockfile)
+
+ Puppet::FileBucketFile::File.new.send(:save_to_disk, @bucket)
end
+ it "should make any directories necessary for storage" do
+ FileUtils.expects(:mkdir_p).with do |arg|
+ ::File.umask == 0007 and arg == @dir
+ end
+ ::File.expects(:directory?).with(@dir).returns(false)
+ ::File.expects(:open).with("#{@dir}/contents", ::File::WRONLY|::File::CREAT, 0440)
+ ::File.expects(:exist?).with("#{@dir}/contents").returns false
- describe "when verifying identical files" do
- before do
- # this is the default from spec_helper, but it keeps getting reset at odd times
- Puppet[:bucketdir] = "/dev/null/bucket"
+ Puppet::FileBucketFile::File.new.send(:save_to_disk, @bucket)
+ end
+ end
- @digest = "4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
- @checksum = "{md5}4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
- @dir = '/dev/null/bucket/4/a/8/e/c/4/f/a/4a8ec4fa5f01b4ab1a0ab8cbccb709f0'
- @contents = "file contents"
+ describe "when verifying identical files" do
+ before do
+ # this is the default from spec_helper, but it keeps getting reset at odd times
+ Puppet[:bucketdir] = "/dev/null/bucket"
- @bucket = stub "bucket file"
- @bucket.stubs(:bucket_path)
- @bucket.stubs(:checksum).returns(@checksum)
- @bucket.stubs(:checksum_data).returns(@digest)
- @bucket.stubs(:path).returns(nil)
- @bucket.stubs(:contents).returns("file contents")
- end
+ @digest = "4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
+ @checksum = "{md5}4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
+ @dir = '/dev/null/bucket/4/a/8/e/c/4/f/a/4a8ec4fa5f01b4ab1a0ab8cbccb709f0'
- it "should raise an error if the files don't match" do
- File.expects(:read).with("#{@dir}/contents").returns("corrupt contents")
- lambda{ Puppet::FileBucketFile::File.new.send(:verify_identical_file!, @bucket) }.should raise_error(Puppet::FileBucket::BucketError)
- end
+ @contents = "file contents"
- it "should do nothing if the files match" do
- File.expects(:read).with("#{@dir}/contents").returns("file contents")
- Puppet::FileBucketFile::File.new.send(:verify_identical_file!, @bucket)
- end
+ @bucket = stub "bucket file"
+ @bucket.stubs(:bucket_path)
+ @bucket.stubs(:checksum).returns(@checksum)
+ @bucket.stubs(:checksum_data).returns(@digest)
+ @bucket.stubs(:path).returns(nil)
+ @bucket.stubs(:contents).returns("file contents")
+ end
+ it "should raise an error if the files don't match" do
+ File.expects(:read).with("#{@dir}/contents").returns("corrupt contents")
+ lambda{ Puppet::FileBucketFile::File.new.send(:verify_identical_file!, @bucket) }.should raise_error(Puppet::FileBucket::BucketError)
end
+ it "should do nothing if the files match" do
+ File.expects(:read).with("#{@dir}/contents").returns("file contents")
+ Puppet::FileBucketFile::File.new.send(:verify_identical_file!, @bucket)
+ end
- describe "when writing to the paths file" do
- before do
- Puppet[:bucketdir] = '/dev/null/bucketdir'
- @digest = '70924d6fa4b2d745185fa4660703a5c0'
- @bucket = stub_everything "bucket"
+ end
- @paths_path = '/dev/null/bucketdir/7/0/9/2/4/d/6/f/70924d6fa4b2d745185fa4660703a5c0/paths'
- @paths = []
- @bucket.stubs(:paths).returns(@paths)
- @bucket.stubs(:checksum_data).returns(@digest)
- end
+ describe "when writing to the paths file" do
+ before do
+ Puppet[:bucketdir] = '/dev/null/bucketdir'
+ @digest = '70924d6fa4b2d745185fa4660703a5c0'
+ @bucket = stub_everything "bucket"
- it "should create a file if it doesn't exist" do
- @bucket.expects(:path).returns('path/to/save').at_least_once
- File.expects(:exist?).with(@paths_path).returns(false)
- file = stub "file"
- file.expects(:puts).with('path/to/save')
- File.expects(:open).with(@paths_path, ::File::WRONLY|::File::CREAT|::File::APPEND).yields(file)
+ @paths_path = '/dev/null/bucketdir/7/0/9/2/4/d/6/f/70924d6fa4b2d745185fa4660703a5c0/paths'
- Puppet::FileBucketFile::File.new.send(:save_path_to_paths_file, @bucket)
- end
+ @paths = []
+ @bucket.stubs(:paths).returns(@paths)
+ @bucket.stubs(:checksum_data).returns(@digest)
+ end
- it "should append to a file if it exists" do
- @bucket.expects(:path).returns('path/to/save').at_least_once
- File.expects(:exist?).with(@paths_path).returns(true)
- old_file = stub "file"
- old_file.stubs(:readlines).returns []
- File.expects(:open).with(@paths_path).yields(old_file)
+ it "should create a file if it doesn't exist" do
+ @bucket.expects(:path).returns('path/to/save').at_least_once
+ File.expects(:exist?).with(@paths_path).returns(false)
+ file = stub "file"
+ file.expects(:puts).with('path/to/save')
+ File.expects(:open).with(@paths_path, ::File::WRONLY|::File::CREAT|::File::APPEND).yields(file)
- file = stub "file"
- file.expects(:puts).with('path/to/save')
- File.expects(:open).with(@paths_path, ::File::WRONLY|::File::CREAT|::File::APPEND).yields(file)
+ Puppet::FileBucketFile::File.new.send(:save_path_to_paths_file, @bucket)
+ end
- Puppet::FileBucketFile::File.new.send(:save_path_to_paths_file, @bucket)
- end
+ it "should append to a file if it exists" do
+ @bucket.expects(:path).returns('path/to/save').at_least_once
+ File.expects(:exist?).with(@paths_path).returns(true)
+ old_file = stub "file"
+ old_file.stubs(:readlines).returns []
+ File.expects(:open).with(@paths_path).yields(old_file)
- it "should not alter a file if it already contains the path" do
- @bucket.expects(:path).returns('path/to/save').at_least_once
- File.expects(:exist?).with(@paths_path).returns(true)
- old_file = stub "file"
- old_file.stubs(:readlines).returns ["path/to/save\n"]
- File.expects(:open).with(@paths_path).yields(old_file)
+ file = stub "file"
+ file.expects(:puts).with('path/to/save')
+ File.expects(:open).with(@paths_path, ::File::WRONLY|::File::CREAT|::File::APPEND).yields(file)
- Puppet::FileBucketFile::File.new.send(:save_path_to_paths_file, @bucket)
- end
+ Puppet::FileBucketFile::File.new.send(:save_path_to_paths_file, @bucket)
+ end
+
+ it "should not alter a file if it already contains the path" do
+ @bucket.expects(:path).returns('path/to/save').at_least_once
+ File.expects(:exist?).with(@paths_path).returns(true)
+ old_file = stub "file"
+ old_file.stubs(:readlines).returns ["path/to/save\n"]
+ File.expects(:open).with(@paths_path).yields(old_file)
+
+ Puppet::FileBucketFile::File.new.send(:save_path_to_paths_file, @bucket)
+ end
- it "should do nothing if there is no path" do
- @bucket.expects(:path).returns(nil).at_least_once
+ it "should do nothing if there is no path" do
+ @bucket.expects(:path).returns(nil).at_least_once
- Puppet::FileBucketFile::File.new.send(:save_path_to_paths_file, @bucket)
- end
+ Puppet::FileBucketFile::File.new.send(:save_path_to_paths_file, @bucket)
end
+ end
end
diff --git a/spec/unit/indirector/file_bucket_file/rest_spec.rb b/spec/unit/indirector/file_bucket_file/rest_spec.rb
index 3aacd3c..960f60a 100755
--- a/spec/unit/indirector/file_bucket_file/rest_spec.rb
+++ b/spec/unit/indirector/file_bucket_file/rest_spec.rb
@@ -5,7 +5,7 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
require 'puppet/indirector/file_bucket_file/rest'
describe Puppet::FileBucketFile::Rest do
- it "should be a sublcass of Puppet::Indirector::REST" do
- Puppet::FileBucketFile::Rest.superclass.should equal(Puppet::Indirector::REST)
- end
+ it "should be a sublcass of Puppet::Indirector::REST" do
+ Puppet::FileBucketFile::Rest.superclass.should equal(Puppet::Indirector::REST)
+ end
end
diff --git a/spec/unit/indirector/file_content/file_server_spec.rb b/spec/unit/indirector/file_content/file_server_spec.rb
index a09c7e2..326a8c8 100755
--- a/spec/unit/indirector/file_content/file_server_spec.rb
+++ b/spec/unit/indirector/file_content/file_server_spec.rb
@@ -8,11 +8,11 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/file_content/file_server'
describe Puppet::Indirector::FileContent::FileServer do
- it "should be registered with the file_content indirection" do
- Puppet::Indirector::Terminus.terminus_class(:file_content, :file_server).should equal(Puppet::Indirector::FileContent::FileServer)
- end
+ it "should be registered with the file_content indirection" do
+ Puppet::Indirector::Terminus.terminus_class(:file_content, :file_server).should equal(Puppet::Indirector::FileContent::FileServer)
+ end
- it "should be a subclass of the FileServer terminus" do
- Puppet::Indirector::FileContent::FileServer.superclass.should equal(Puppet::Indirector::FileServer)
- end
+ it "should be a subclass of the FileServer terminus" do
+ Puppet::Indirector::FileContent::FileServer.superclass.should equal(Puppet::Indirector::FileServer)
+ end
end
diff --git a/spec/unit/indirector/file_content/file_spec.rb b/spec/unit/indirector/file_content/file_spec.rb
index 04656e0..62c2863 100755
--- a/spec/unit/indirector/file_content/file_spec.rb
+++ b/spec/unit/indirector/file_content/file_spec.rb
@@ -8,11 +8,11 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/file_content/file'
describe Puppet::Indirector::FileContent::File do
- it "should be registered with the file_content indirection" do
- Puppet::Indirector::Terminus.terminus_class(:file_content, :file).should equal(Puppet::Indirector::FileContent::File)
- end
+ it "should be registered with the file_content indirection" do
+ Puppet::Indirector::Terminus.terminus_class(:file_content, :file).should equal(Puppet::Indirector::FileContent::File)
+ end
- it "should be a subclass of the DirectFileServer terminus" do
- Puppet::Indirector::FileContent::File.superclass.should equal(Puppet::Indirector::DirectFileServer)
- end
+ it "should be a subclass of the DirectFileServer terminus" do
+ Puppet::Indirector::FileContent::File.superclass.should equal(Puppet::Indirector::DirectFileServer)
+ end
end
diff --git a/spec/unit/indirector/file_content/rest_spec.rb b/spec/unit/indirector/file_content/rest_spec.rb
index afb674e..3b2f43f 100755
--- a/spec/unit/indirector/file_content/rest_spec.rb
+++ b/spec/unit/indirector/file_content/rest_spec.rb
@@ -5,7 +5,7 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/file_content'
describe "Puppet::Indirector::Content::Rest" do
- it "should add the node's cert name to the arguments"
+ it "should add the node's cert name to the arguments"
- it "should set the content type to text/plain"
+ it "should set the content type to text/plain"
end
diff --git a/spec/unit/indirector/file_metadata/file_server_spec.rb b/spec/unit/indirector/file_metadata/file_server_spec.rb
index 40232a1..98f89c5 100755
--- a/spec/unit/indirector/file_metadata/file_server_spec.rb
+++ b/spec/unit/indirector/file_metadata/file_server_spec.rb
@@ -8,11 +8,11 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/file_metadata/file_server'
describe Puppet::Indirector::FileMetadata::FileServer do
- it "should be registered with the file_metadata indirection" do
- Puppet::Indirector::Terminus.terminus_class(:file_metadata, :file_server).should equal(Puppet::Indirector::FileMetadata::FileServer)
- end
+ it "should be registered with the file_metadata indirection" do
+ Puppet::Indirector::Terminus.terminus_class(:file_metadata, :file_server).should equal(Puppet::Indirector::FileMetadata::FileServer)
+ end
- it "should be a subclass of the FileServer terminus" do
- Puppet::Indirector::FileMetadata::FileServer.superclass.should equal(Puppet::Indirector::FileServer)
- end
+ it "should be a subclass of the FileServer terminus" do
+ Puppet::Indirector::FileMetadata::FileServer.superclass.should equal(Puppet::Indirector::FileServer)
+ end
end
diff --git a/spec/unit/indirector/file_metadata/file_spec.rb b/spec/unit/indirector/file_metadata/file_spec.rb
index a096d46..906b24b 100755
--- a/spec/unit/indirector/file_metadata/file_spec.rb
+++ b/spec/unit/indirector/file_metadata/file_spec.rb
@@ -8,45 +8,45 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/file_metadata/file'
describe Puppet::Indirector::FileMetadata::File do
- it "should be registered with the file_metadata indirection" do
- Puppet::Indirector::Terminus.terminus_class(:file_metadata, :file).should equal(Puppet::Indirector::FileMetadata::File)
+ it "should be registered with the file_metadata indirection" do
+ Puppet::Indirector::Terminus.terminus_class(:file_metadata, :file).should equal(Puppet::Indirector::FileMetadata::File)
+ end
+
+ it "should be a subclass of the DirectFileServer terminus" do
+ Puppet::Indirector::FileMetadata::File.superclass.should equal(Puppet::Indirector::DirectFileServer)
+ end
+
+ describe "when creating the instance for a single found file" do
+ before do
+ @metadata = Puppet::Indirector::FileMetadata::File.new
+ @uri = "file:///my/local"
+ @data = mock 'metadata'
+ @data.stubs(:collect)
+ FileTest.expects(:exists?).with("/my/local").returns true
+
+ @request = Puppet::Indirector::Request.new(:file_metadata, :find, @uri)
end
- it "should be a subclass of the DirectFileServer terminus" do
- Puppet::Indirector::FileMetadata::File.superclass.should equal(Puppet::Indirector::DirectFileServer)
- end
-
- describe "when creating the instance for a single found file" do
- before do
- @metadata = Puppet::Indirector::FileMetadata::File.new
- @uri = "file:///my/local"
- @data = mock 'metadata'
- @data.stubs(:collect)
- FileTest.expects(:exists?).with("/my/local").returns true
-
- @request = Puppet::Indirector::Request.new(:file_metadata, :find, @uri)
- end
+ it "should collect its attributes when a file is found" do
+ @data.expects(:collect)
- it "should collect its attributes when a file is found" do
- @data.expects(:collect)
-
- Puppet::FileServing::Metadata.expects(:new).returns(@data)
- @metadata.find(@request).should == @data
- end
+ Puppet::FileServing::Metadata.expects(:new).returns(@data)
+ @metadata.find(@request).should == @data
end
+ end
- describe "when searching for multiple files" do
- before do
- @metadata = Puppet::Indirector::FileMetadata::File.new
- @uri = "file:///my/local"
+ describe "when searching for multiple files" do
+ before do
+ @metadata = Puppet::Indirector::FileMetadata::File.new
+ @uri = "file:///my/local"
- @request = Puppet::Indirector::Request.new(:file_metadata, :find, @uri)
- end
+ @request = Puppet::Indirector::Request.new(:file_metadata, :find, @uri)
+ end
- it "should collect the attributes of the instances returned" do
- FileTest.expects(:exists?).with("/my/local").returns true
- @metadata.expects(:path2instances).returns( [mock("one", :collect => nil), mock("two", :collect => nil)] )
- @metadata.search(@request)
- end
+ it "should collect the attributes of the instances returned" do
+ FileTest.expects(:exists?).with("/my/local").returns true
+ @metadata.expects(:path2instances).returns( [mock("one", :collect => nil), mock("two", :collect => nil)] )
+ @metadata.search(@request)
end
+ end
end
diff --git a/spec/unit/indirector/file_metadata/rest_spec.rb b/spec/unit/indirector/file_metadata/rest_spec.rb
index e93406f..f6e9983 100755
--- a/spec/unit/indirector/file_metadata/rest_spec.rb
+++ b/spec/unit/indirector/file_metadata/rest_spec.rb
@@ -5,5 +5,5 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/file_metadata'
describe "Puppet::Indirector::Metadata::Rest" do
- it "should add the node's cert name to the arguments"
+ it "should add the node's cert name to the arguments"
end
diff --git a/spec/unit/indirector/file_server_spec.rb b/spec/unit/indirector/file_server_spec.rb
index 912695e..686f79a 100755
--- a/spec/unit/indirector/file_server_spec.rb
+++ b/spec/unit/indirector/file_server_spec.rb
@@ -10,258 +10,258 @@ require 'puppet/file_serving/configuration'
describe Puppet::Indirector::FileServer do
- before :each do
- Puppet::Indirector::Terminus.stubs(:register_terminus_class)
- @model = mock 'model'
- @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model
- Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
+ before :each do
+ Puppet::Indirector::Terminus.stubs(:register_terminus_class)
+ @model = mock 'model'
+ @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model
+ Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
+
+ @file_server_class = Class.new(Puppet::Indirector::FileServer) do
+ def self.to_s
+ "Testing::Mytype"
+ end
+ end
- @file_server_class = Class.new(Puppet::Indirector::FileServer) do
- def self.to_s
- "Testing::Mytype"
- end
- end
+ @file_server = @file_server_class.new
- @file_server = @file_server_class.new
+ @uri = "puppet://host/my/local/file"
+ @configuration = mock 'configuration'
+ Puppet::FileServing::Configuration.stubs(:create).returns(@configuration)
- @uri = "puppet://host/my/local/file"
- @configuration = mock 'configuration'
- Puppet::FileServing::Configuration.stubs(:create).returns(@configuration)
+ @request = Puppet::Indirector::Request.new(:myind, :mymethod, @uri, :environment => "myenv")
+ end
- @request = Puppet::Indirector::Request.new(:myind, :mymethod, @uri, :environment => "myenv")
+ describe "when finding files" do
+ before do
+ @mount = stub 'mount', :find => nil
+ @instance = stub('instance', :links= => nil, :collect => nil)
end
- describe "when finding files" do
- before do
- @mount = stub 'mount', :find => nil
- @instance = stub('instance', :links= => nil, :collect => nil)
- end
-
- it "should use the configuration to find the mount and relative path" do
- @configuration.expects(:split_path).with(@request)
+ it "should use the configuration to find the mount and relative path" do
+ @configuration.expects(:split_path).with(@request)
- @file_server.find(@request)
- end
+ @file_server.find(@request)
+ end
- it "should return nil if it cannot find the mount" do
- @configuration.expects(:split_path).with(@request).returns(nil, nil)
+ it "should return nil if it cannot find the mount" do
+ @configuration.expects(:split_path).with(@request).returns(nil, nil)
- @file_server.find(@request).should be_nil
- end
+ @file_server.find(@request).should be_nil
+ end
- it "should use the mount to find the full path" do
- @configuration.expects(:split_path).with(@request).returns([@mount, "rel/path"])
+ it "should use the mount to find the full path" do
+ @configuration.expects(:split_path).with(@request).returns([@mount, "rel/path"])
- @mount.expects(:find).with { |key, request| key == "rel/path" }
+ @mount.expects(:find).with { |key, request| key == "rel/path" }
- @file_server.find(@request)
- end
+ @file_server.find(@request)
+ end
- it "should pass the request when finding a file" do
- @configuration.expects(:split_path).with(@request).returns([@mount, "rel/path"])
+ it "should pass the request when finding a file" do
+ @configuration.expects(:split_path).with(@request).returns([@mount, "rel/path"])
- @mount.expects(:find).with { |key, request| request == @request }
+ @mount.expects(:find).with { |key, request| request == @request }
- @file_server.find(@request)
- end
+ @file_server.find(@request)
+ end
- it "should return nil if it cannot find a full path" do
- @configuration.expects(:split_path).with(@request).returns([@mount, "rel/path"])
+ it "should return nil if it cannot find a full path" do
+ @configuration.expects(:split_path).with(@request).returns([@mount, "rel/path"])
- @mount.expects(:find).with { |key, request| key == "rel/path" }.returns nil
+ @mount.expects(:find).with { |key, request| key == "rel/path" }.returns nil
- @file_server.find(@request).should be_nil
- end
+ @file_server.find(@request).should be_nil
+ end
- it "should create an instance with the found path" do
- @configuration.expects(:split_path).with(@request).returns([@mount, "rel/path"])
+ it "should create an instance with the found path" do
+ @configuration.expects(:split_path).with(@request).returns([@mount, "rel/path"])
- @mount.expects(:find).with { |key, request| key == "rel/path" }.returns "/my/file"
+ @mount.expects(:find).with { |key, request| key == "rel/path" }.returns "/my/file"
- @model.expects(:new).with("/my/file").returns @instance
+ @model.expects(:new).with("/my/file").returns @instance
- @file_server.find(@request).should equal(@instance)
- end
+ @file_server.find(@request).should equal(@instance)
+ end
- it "should set 'links' on the instance if it is set in the request options" do
- @request.options[:links] = true
- @configuration.expects(:split_path).with(@request).returns([@mount, "rel/path"])
+ it "should set 'links' on the instance if it is set in the request options" do
+ @request.options[:links] = true
+ @configuration.expects(:split_path).with(@request).returns([@mount, "rel/path"])
- @mount.expects(:find).with { |key, request| key == "rel/path" }.returns "/my/file"
+ @mount.expects(:find).with { |key, request| key == "rel/path" }.returns "/my/file"
- @model.expects(:new).with("/my/file").returns @instance
+ @model.expects(:new).with("/my/file").returns @instance
- @instance.expects(:links=).with(true)
+ @instance.expects(:links=).with(true)
- @file_server.find(@request).should equal(@instance)
- end
+ @file_server.find(@request).should equal(@instance)
+ end
- it "should collect the instance" do
- @request.options[:links] = true
- @configuration.expects(:split_path).with(@request).returns([@mount, "rel/path"])
+ it "should collect the instance" do
+ @request.options[:links] = true
+ @configuration.expects(:split_path).with(@request).returns([@mount, "rel/path"])
- @mount.expects(:find).with { |key, request| key == "rel/path" }.returns "/my/file"
+ @mount.expects(:find).with { |key, request| key == "rel/path" }.returns "/my/file"
- @model.expects(:new).with("/my/file").returns @instance
+ @model.expects(:new).with("/my/file").returns @instance
- @instance.expects(:collect)
+ @instance.expects(:collect)
- @file_server.find(@request).should equal(@instance)
- end
+ @file_server.find(@request).should equal(@instance)
end
+ end
- describe "when searching for instances" do
- before do
- @mount = stub 'mount', :search => nil
- @instance = stub('instance', :links= => nil, :collect => nil)
- end
+ describe "when searching for instances" do
+ before do
+ @mount = stub 'mount', :search => nil
+ @instance = stub('instance', :links= => nil, :collect => nil)
+ end
- it "should use the configuration to search the mount and relative path" do
- @configuration.expects(:split_path).with(@request)
+ it "should use the configuration to search the mount and relative path" do
+ @configuration.expects(:split_path).with(@request)
- @file_server.search(@request)
- end
+ @file_server.search(@request)
+ end
- it "should return nil if it cannot search the mount" do
- @configuration.expects(:split_path).with(@request).returns(nil, nil)
+ it "should return nil if it cannot search the mount" do
+ @configuration.expects(:split_path).with(@request).returns(nil, nil)
- @file_server.search(@request).should be_nil
- end
+ @file_server.search(@request).should be_nil
+ end
- it "should use the mount to search for the full paths" do
- @configuration.expects(:split_path).with(@request).returns([@mount, "rel/path"])
+ it "should use the mount to search for the full paths" do
+ @configuration.expects(:split_path).with(@request).returns([@mount, "rel/path"])
- @mount.expects(:search).with { |key, request| key == "rel/path" }
+ @mount.expects(:search).with { |key, request| key == "rel/path" }
- @file_server.search(@request)
- end
+ @file_server.search(@request)
+ end
- it "should pass the request" do
- @configuration.stubs(:split_path).returns([@mount, "rel/path"])
+ it "should pass the request" do
+ @configuration.stubs(:split_path).returns([@mount, "rel/path"])
- @mount.expects(:search).with { |key, request| request == @request }
+ @mount.expects(:search).with { |key, request| request == @request }
- @file_server.search(@request)
- end
+ @file_server.search(@request)
+ end
- it "should return nil if searching does not find any full paths" do
- @configuration.expects(:split_path).with(@request).returns([@mount, "rel/path"])
+ it "should return nil if searching does not find any full paths" do
+ @configuration.expects(:split_path).with(@request).returns([@mount, "rel/path"])
- @mount.expects(:search).with { |key, request| key == "rel/path" }.returns nil
+ @mount.expects(:search).with { |key, request| key == "rel/path" }.returns nil
- @file_server.search(@request).should be_nil
- end
+ @file_server.search(@request).should be_nil
+ end
- it "should create a fileset with each returned path and merge them" do
- @configuration.expects(:split_path).with(@request).returns([@mount, "rel/path"])
+ it "should create a fileset with each returned path and merge them" do
+ @configuration.expects(:split_path).with(@request).returns([@mount, "rel/path"])
- @mount.expects(:search).with { |key, request| key == "rel/path" }.returns %w{/one /two}
+ @mount.expects(:search).with { |key, request| key == "rel/path" }.returns %w{/one /two}
- FileTest.stubs(:exist?).returns true
+ FileTest.stubs(:exist?).returns true
- one = mock 'fileset_one'
- Puppet::FileServing::Fileset.expects(:new).with("/one", @request).returns(one)
- two = mock 'fileset_two'
- Puppet::FileServing::Fileset.expects(:new).with("/two", @request).returns(two)
+ one = mock 'fileset_one'
+ Puppet::FileServing::Fileset.expects(:new).with("/one", @request).returns(one)
+ two = mock 'fileset_two'
+ Puppet::FileServing::Fileset.expects(:new).with("/two", @request).returns(two)
- Puppet::FileServing::Fileset.expects(:merge).with(one, two).returns []
+ Puppet::FileServing::Fileset.expects(:merge).with(one, two).returns []
- @file_server.search(@request)
- end
+ @file_server.search(@request)
+ end
- it "should create an instance with each path resulting from the merger of the filesets" do
- @configuration.expects(:split_path).with(@request).returns([@mount, "rel/path"])
+ it "should create an instance with each path resulting from the merger of the filesets" do
+ @configuration.expects(:split_path).with(@request).returns([@mount, "rel/path"])
- @mount.expects(:search).with { |key, request| key == "rel/path" }.returns []
+ @mount.expects(:search).with { |key, request| key == "rel/path" }.returns []
- FileTest.stubs(:exist?).returns true
+ FileTest.stubs(:exist?).returns true
- Puppet::FileServing::Fileset.expects(:merge).returns("one" => "/one", "two" => "/two")
+ Puppet::FileServing::Fileset.expects(:merge).returns("one" => "/one", "two" => "/two")
- one = stub 'one', :collect => nil
- @model.expects(:new).with("/one", :relative_path => "one").returns one
+ one = stub 'one', :collect => nil
+ @model.expects(:new).with("/one", :relative_path => "one").returns one
- two = stub 'two', :collect => nil
- @model.expects(:new).with("/two", :relative_path => "two").returns two
+ two = stub 'two', :collect => nil
+ @model.expects(:new).with("/two", :relative_path => "two").returns two
- # order can't be guaranteed
- result = @file_server.search(@request)
- result.should be_include(one)
- result.should be_include(two)
- result.length.should == 2
- end
+ # order can't be guaranteed
+ result = @file_server.search(@request)
+ result.should be_include(one)
+ result.should be_include(two)
+ result.length.should == 2
+ end
- it "should set 'links' on the instances if it is set in the request options" do
- @configuration.expects(:split_path).with(@request).returns([@mount, "rel/path"])
+ it "should set 'links' on the instances if it is set in the request options" do
+ @configuration.expects(:split_path).with(@request).returns([@mount, "rel/path"])
- @mount.expects(:search).with { |key, request| key == "rel/path" }.returns []
+ @mount.expects(:search).with { |key, request| key == "rel/path" }.returns []
- FileTest.stubs(:exist?).returns true
+ FileTest.stubs(:exist?).returns true
- Puppet::FileServing::Fileset.expects(:merge).returns("one" => "/one")
+ Puppet::FileServing::Fileset.expects(:merge).returns("one" => "/one")
- one = stub 'one', :collect => nil
- @model.expects(:new).with("/one", :relative_path => "one").returns one
- one.expects(:links=).with true
+ one = stub 'one', :collect => nil
+ @model.expects(:new).with("/one", :relative_path => "one").returns one
+ one.expects(:links=).with true
- @request.options[:links] = true
+ @request.options[:links] = true
- @file_server.search(@request)
- end
+ @file_server.search(@request)
+ end
- it "should collect the instances" do
- @configuration.expects(:split_path).with(@request).returns([@mount, "rel/path"])
+ it "should collect the instances" do
+ @configuration.expects(:split_path).with(@request).returns([@mount, "rel/path"])
- @mount.expects(:search).with { |key, options| key == "rel/path" }.returns []
+ @mount.expects(:search).with { |key, options| key == "rel/path" }.returns []
- FileTest.stubs(:exist?).returns true
+ FileTest.stubs(:exist?).returns true
- Puppet::FileServing::Fileset.expects(:merge).returns("one" => "/one")
+ Puppet::FileServing::Fileset.expects(:merge).returns("one" => "/one")
- one = mock 'one'
- @model.expects(:new).with("/one", :relative_path => "one").returns one
- one.expects(:collect)
+ one = mock 'one'
+ @model.expects(:new).with("/one", :relative_path => "one").returns one
+ one.expects(:collect)
- @file_server.search(@request)
- end
+ @file_server.search(@request)
end
+ end
- describe "when checking authorization" do
- before do
- @request.method = :find
- end
+ describe "when checking authorization" do
+ before do
+ @request.method = :find
+ end
- it "should return false when destroying" do
- @request.method = :destroy
- @file_server.should_not be_authorized(@request)
- end
+ it "should return false when destroying" do
+ @request.method = :destroy
+ @file_server.should_not be_authorized(@request)
+ end
- it "should return false when saving" do
- @request.method = :save
- @file_server.should_not be_authorized(@request)
- end
+ it "should return false when saving" do
+ @request.method = :save
+ @file_server.should_not be_authorized(@request)
+ end
- it "should use the configuration to find the mount and relative path" do
- @configuration.expects(:split_path).with(@request)
+ it "should use the configuration to find the mount and relative path" do
+ @configuration.expects(:split_path).with(@request)
- @file_server.authorized?(@request)
- end
+ @file_server.authorized?(@request)
+ end
- it "should return false if it cannot find the mount" do
- @configuration.expects(:split_path).with(@request).returns(nil, nil)
+ it "should return false if it cannot find the mount" do
+ @configuration.expects(:split_path).with(@request).returns(nil, nil)
- @file_server.should_not be_authorized(@request)
- end
+ @file_server.should_not be_authorized(@request)
+ end
- it "should return the results of asking the mount whether the node and IP are authorized" do
- @mount = stub 'mount'
- @configuration.expects(:split_path).with(@request).returns([@mount, "rel/path"])
+ it "should return the results of asking the mount whether the node and IP are authorized" do
+ @mount = stub 'mount'
+ @configuration.expects(:split_path).with(@request).returns([@mount, "rel/path"])
- @request.stubs(:node).returns("mynode")
- @request.stubs(:ip).returns("myip")
- @mount.expects(:allowed?).with("mynode", "myip").returns "something"
+ @request.stubs(:node).returns("mynode")
+ @request.stubs(:ip).returns("myip")
+ @mount.expects(:allowed?).with("mynode", "myip").returns "something"
- @file_server.authorized?(@request).should == "something"
- end
+ @file_server.authorized?(@request).should == "something"
end
+ end
end
diff --git a/spec/unit/indirector/file_spec.rb b/spec/unit/indirector/file_spec.rb
index 2505a0c..86673f0 100755
--- a/spec/unit/indirector/file_spec.rb
+++ b/spec/unit/indirector/file_spec.rb
@@ -5,177 +5,177 @@ require 'puppet/indirector/file'
describe Puppet::Indirector::File do
- before :each do
- Puppet::Indirector::Terminus.stubs(:register_terminus_class)
- @model = mock 'model'
- @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model
- Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
+ before :each do
+ Puppet::Indirector::Terminus.stubs(:register_terminus_class)
+ @model = mock 'model'
+ @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model
+ Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
+
+ @file_class = Class.new(Puppet::Indirector::File) do
+ def self.to_s
+ "Testing::Mytype"
+ end
+ end
- @file_class = Class.new(Puppet::Indirector::File) do
- def self.to_s
- "Testing::Mytype"
- end
- end
+ @searcher = @file_class.new
- @searcher = @file_class.new
+ @path = "/my/file"
+ @dir = "/my"
- @path = "/my/file"
- @dir = "/my"
+ @request = stub 'request', :key => @path
+ end
- @request = stub 'request', :key => @path
+ describe "when finding files" do
+ it "should provide a method to return file contents at a specified path" do
+ @searcher.should respond_to(:find)
end
- describe "when finding files" do
- it "should provide a method to return file contents at a specified path" do
- @searcher.should respond_to(:find)
- end
-
- it "should use the server data directory plus the indirection name if the run_mode is master" do
- Puppet.run_mode.expects(:master?).returns true
- Puppet.settings.expects(:value).with(:server_datadir).returns "/my/dir"
+ it "should use the server data directory plus the indirection name if the run_mode is master" do
+ Puppet.run_mode.expects(:master?).returns true
+ Puppet.settings.expects(:value).with(:server_datadir).returns "/my/dir"
- @searcher.data_directory.should == File.join("/my/dir", "mystuff")
- end
+ @searcher.data_directory.should == File.join("/my/dir", "mystuff")
+ end
- it "should use the client data directory plus the indirection name if the run_mode is not master" do
- Puppet.run_mode.expects(:master?).returns false
- Puppet.settings.expects(:value).with(:client_datadir).returns "/my/dir"
+ it "should use the client data directory plus the indirection name if the run_mode is not master" do
+ Puppet.run_mode.expects(:master?).returns false
+ Puppet.settings.expects(:value).with(:client_datadir).returns "/my/dir"
- @searcher.data_directory.should == File.join("/my/dir", "mystuff")
- end
+ @searcher.data_directory.should == File.join("/my/dir", "mystuff")
+ end
- it "should use the newest file in the data directory matching the indirection key without extension" do
- @searcher.expects(:data_directory).returns "/data/dir"
- @request.stubs(:key).returns "foo"
- Dir.expects(:glob).with("/data/dir/foo.*").returns %w{/data1.stuff /data2.stuff}
+ it "should use the newest file in the data directory matching the indirection key without extension" do
+ @searcher.expects(:data_directory).returns "/data/dir"
+ @request.stubs(:key).returns "foo"
+ Dir.expects(:glob).with("/data/dir/foo.*").returns %w{/data1.stuff /data2.stuff}
- stat1 = stub 'data1', :mtime => (Time.now - 5)
- stat2 = stub 'data2', :mtime => Time.now
- File.expects(:stat).with("/data1.stuff").returns stat1
- File.expects(:stat).with("/data2.stuff").returns stat2
+ stat1 = stub 'data1', :mtime => (Time.now - 5)
+ stat2 = stub 'data2', :mtime => Time.now
+ File.expects(:stat).with("/data1.stuff").returns stat1
+ File.expects(:stat).with("/data2.stuff").returns stat2
- @searcher.latest_path(@request).should == "/data2.stuff"
- end
+ @searcher.latest_path(@request).should == "/data2.stuff"
+ end
- it "should return nil when no files are found" do
- @searcher.stubs(:latest_path).returns nil
+ it "should return nil when no files are found" do
+ @searcher.stubs(:latest_path).returns nil
- @searcher.find(@request).should be_nil
- end
+ @searcher.find(@request).should be_nil
+ end
- it "should determine the file format from the file extension" do
- @searcher.file_format("/data2.pson").should == "pson"
- end
+ it "should determine the file format from the file extension" do
+ @searcher.file_format("/data2.pson").should == "pson"
+ end
- it "should fail if the model does not support the file format" do
- @searcher.stubs(:latest_path).returns "/my/file.pson"
+ it "should fail if the model does not support the file format" do
+ @searcher.stubs(:latest_path).returns "/my/file.pson"
- @model.expects(:support_format?).with("pson").returns false
+ @model.expects(:support_format?).with("pson").returns false
- lambda { @searcher.find(@request) }.should raise_error(ArgumentError)
- end
+ lambda { @searcher.find(@request) }.should raise_error(ArgumentError)
end
+ end
- describe "when saving files" do
- before do
- @content = "my content"
- @file = stub 'file', :content => @content, :path => @path, :name => @path, :render => "mydata"
- @request.stubs(:instance).returns @file
- end
+ describe "when saving files" do
+ before do
+ @content = "my content"
+ @file = stub 'file', :content => @content, :path => @path, :name => @path, :render => "mydata"
+ @request.stubs(:instance).returns @file
+ end
- it "should provide a method to save file contents at a specified path" do
- @searcher.should respond_to(:save)
- end
+ it "should provide a method to save file contents at a specified path" do
+ @searcher.should respond_to(:save)
+ end
- it "should choose the file extension based on the default format of the model" do
- @model.expects(:default_format).returns "pson"
+ it "should choose the file extension based on the default format of the model" do
+ @model.expects(:default_format).returns "pson"
- @searcher.serialization_format.should == "pson"
- end
+ @searcher.serialization_format.should == "pson"
+ end
- it "should place the file in the data directory, named after the indirection, key, and format" do
- @searcher.stubs(:data_directory).returns "/my/dir"
- @searcher.stubs(:serialization_format).returns "pson"
+ it "should place the file in the data directory, named after the indirection, key, and format" do
+ @searcher.stubs(:data_directory).returns "/my/dir"
+ @searcher.stubs(:serialization_format).returns "pson"
- @request.stubs(:key).returns "foo"
- @searcher.file_path(@request).should == File.join("/my/dir", "foo.pson")
- end
+ @request.stubs(:key).returns "foo"
+ @searcher.file_path(@request).should == File.join("/my/dir", "foo.pson")
+ end
- it "should fail intelligently if the file's parent directory does not exist" do
- @searcher.stubs(:file_path).returns "/my/dir/file.pson"
- @searcher.stubs(:serialization_format).returns "pson"
+ it "should fail intelligently if the file's parent directory does not exist" do
+ @searcher.stubs(:file_path).returns "/my/dir/file.pson"
+ @searcher.stubs(:serialization_format).returns "pson"
- @request.stubs(:key).returns "foo"
- File.expects(:directory?).with(File.join("/my/dir")).returns(false)
+ @request.stubs(:key).returns "foo"
+ File.expects(:directory?).with(File.join("/my/dir")).returns(false)
- proc { @searcher.save(@request) }.should raise_error(Puppet::Error)
- end
+ proc { @searcher.save(@request) }.should raise_error(Puppet::Error)
+ end
- it "should render the instance using the file format and print it to the file path" do
- @searcher.stubs(:file_path).returns "/my/file.pson"
- @searcher.stubs(:serialization_format).returns "pson"
+ it "should render the instance using the file format and print it to the file path" do
+ @searcher.stubs(:file_path).returns "/my/file.pson"
+ @searcher.stubs(:serialization_format).returns "pson"
- File.stubs(:directory?).returns true
+ File.stubs(:directory?).returns true
- @request.instance.expects(:render).with("pson").returns "data"
+ @request.instance.expects(:render).with("pson").returns "data"
- fh = mock 'filehandle'
- File.expects(:open).with("/my/file.pson", "w").yields fh
- fh.expects(:print).with("data")
+ fh = mock 'filehandle'
+ File.expects(:open).with("/my/file.pson", "w").yields fh
+ fh.expects(:print).with("data")
- @searcher.save(@request)
- end
+ @searcher.save(@request)
+ end
- it "should fail intelligently if a file cannot be written" do
- filehandle = mock 'file'
- File.stubs(:directory?).returns(true)
- File.stubs(:open).yields(filehandle)
- filehandle.expects(:print).raises(ArgumentError)
+ it "should fail intelligently if a file cannot be written" do
+ filehandle = mock 'file'
+ File.stubs(:directory?).returns(true)
+ File.stubs(:open).yields(filehandle)
+ filehandle.expects(:print).raises(ArgumentError)
- @searcher.stubs(:file_path).returns "/my/file.pson"
- @model.stubs(:default_format).returns "pson"
+ @searcher.stubs(:file_path).returns "/my/file.pson"
+ @model.stubs(:default_format).returns "pson"
- @instance.stubs(:render).returns "stuff"
+ @instance.stubs(:render).returns "stuff"
- proc { @searcher.save(@request) }.should raise_error(Puppet::Error)
- end
+ proc { @searcher.save(@request) }.should raise_error(Puppet::Error)
end
+ end
- describe "when removing files" do
- it "should provide a method to remove files" do
- @searcher.should respond_to(:destroy)
- end
+ describe "when removing files" do
+ it "should provide a method to remove files" do
+ @searcher.should respond_to(:destroy)
+ end
- it "should remove files in all formats found in the data directory that match the request key" do
- @searcher.stubs(:data_directory).returns "/my/dir"
- @request.stubs(:key).returns "me"
+ it "should remove files in all formats found in the data directory that match the request key" do
+ @searcher.stubs(:data_directory).returns "/my/dir"
+ @request.stubs(:key).returns "me"
- Dir.expects(:glob).with(File.join("/my/dir", "me.*")).returns %w{/one /two}
+ Dir.expects(:glob).with(File.join("/my/dir", "me.*")).returns %w{/one /two}
- File.expects(:unlink).with("/one")
- File.expects(:unlink).with("/two")
+ File.expects(:unlink).with("/one")
+ File.expects(:unlink).with("/two")
- @searcher.destroy(@request)
- end
+ @searcher.destroy(@request)
+ end
- it "should throw an exception if no file is found" do
- @searcher.stubs(:data_directory).returns "/my/dir"
- @request.stubs(:key).returns "me"
+ it "should throw an exception if no file is found" do
+ @searcher.stubs(:data_directory).returns "/my/dir"
+ @request.stubs(:key).returns "me"
- Dir.expects(:glob).with(File.join("/my/dir", "me.*")).returns []
+ Dir.expects(:glob).with(File.join("/my/dir", "me.*")).returns []
- proc { @searcher.destroy(@request) }.should raise_error(Puppet::Error)
- end
+ proc { @searcher.destroy(@request) }.should raise_error(Puppet::Error)
+ end
- it "should fail intelligently if a file cannot be removed" do
- @searcher.stubs(:data_directory).returns "/my/dir"
- @request.stubs(:key).returns "me"
+ it "should fail intelligently if a file cannot be removed" do
+ @searcher.stubs(:data_directory).returns "/my/dir"
+ @request.stubs(:key).returns "me"
- Dir.expects(:glob).with(File.join("/my/dir", "me.*")).returns %w{/one}
+ Dir.expects(:glob).with(File.join("/my/dir", "me.*")).returns %w{/one}
- File.expects(:unlink).with("/one").raises ArgumentError
+ File.expects(:unlink).with("/one").raises ArgumentError
- proc { @searcher.destroy(@request) }.should raise_error(Puppet::Error)
- end
+ proc { @searcher.destroy(@request) }.should raise_error(Puppet::Error)
end
+ end
end
diff --git a/spec/unit/indirector/indirection_spec.rb b/spec/unit/indirector/indirection_spec.rb
index 8bcd9cd..b0e0f01 100755
--- a/spec/unit/indirector/indirection_spec.rb
+++ b/spec/unit/indirector/indirection_spec.rb
@@ -5,791 +5,791 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector/indirection'
describe "Indirection Delegator", :shared => true do
- it "should create a request object with the appropriate method name and all of the passed arguments" do
- request = Puppet::Indirector::Request.new(:indirection, :find, "me")
+ it "should create a request object with the appropriate method name and all of the passed arguments" do
+ request = Puppet::Indirector::Request.new(:indirection, :find, "me")
- @indirection.expects(:request).with(@method, "mystuff", :one => :two).returns request
+ @indirection.expects(:request).with(@method, "mystuff", :one => :two).returns request
- @terminus.stubs(@method)
+ @terminus.stubs(@method)
- @indirection.send(@method, "mystuff", :one => :two)
+ @indirection.send(@method, "mystuff", :one => :two)
+ end
+
+ it "should let the :select_terminus method choose the terminus using the created request if the :select_terminus method is available" do
+ # Define the method, so our respond_to? hook matches.
+ class << @indirection
+ def select_terminus(request)
+ end
end
- it "should let the :select_terminus method choose the terminus using the created request if the :select_terminus method is available" do
- # Define the method, so our respond_to? hook matches.
- class << @indirection
- def select_terminus(request)
- end
- end
+ request = Puppet::Indirector::Request.new(:indirection, :find, "me")
- request = Puppet::Indirector::Request.new(:indirection, :find, "me")
+ @indirection.stubs(:request).returns request
- @indirection.stubs(:request).returns request
+ @indirection.expects(:select_terminus).with(request).returns :test_terminus
- @indirection.expects(:select_terminus).with(request).returns :test_terminus
+ @indirection.stubs(:check_authorization)
+ @terminus.expects(@method)
- @indirection.stubs(:check_authorization)
- @terminus.expects(@method)
+ @indirection.send(@method, "me")
+ end
- @indirection.send(@method, "me")
+ it "should fail if the :select_terminus hook does not return a terminus name" do
+ # Define the method, so our respond_to? hook matches.
+ class << @indirection
+ def select_terminus(request)
+ end
end
- it "should fail if the :select_terminus hook does not return a terminus name" do
- # Define the method, so our respond_to? hook matches.
- class << @indirection
- def select_terminus(request)
- end
- end
-
- request = stub 'request', :key => "me", :options => {}
+ request = stub 'request', :key => "me", :options => {}
- @indirection.stubs(:request).returns request
+ @indirection.stubs(:request).returns request
- @indirection.expects(:select_terminus).with(request).returns nil
+ @indirection.expects(:select_terminus).with(request).returns nil
- lambda { @indirection.send(@method, "me") }.should raise_error(ArgumentError)
- end
+ lambda { @indirection.send(@method, "me") }.should raise_error(ArgumentError)
+ end
- it "should choose the terminus returned by the :terminus_class method if no :select_terminus method is available" do
- @indirection.expects(:terminus_class).returns :test_terminus
+ it "should choose the terminus returned by the :terminus_class method if no :select_terminus method is available" do
+ @indirection.expects(:terminus_class).returns :test_terminus
- @terminus.expects(@method)
+ @terminus.expects(@method)
- @indirection.send(@method, "me")
- end
+ @indirection.send(@method, "me")
+ end
- it "should let the appropriate terminus perform the lookup" do
- @terminus.expects(@method).with { |r| r.is_a?(Puppet::Indirector::Request) }
- @indirection.send(@method, "me")
- end
+ it "should let the appropriate terminus perform the lookup" do
+ @terminus.expects(@method).with { |r| r.is_a?(Puppet::Indirector::Request) }
+ @indirection.send(@method, "me")
+ end
end
describe "Delegation Authorizer", :shared => true do
- before do
- # So the :respond_to? turns out correctly.
- class << @terminus
- def authorized?
- end
- end
+ before do
+ # So the :respond_to? turns out correctly.
+ class << @terminus
+ def authorized?
+ end
end
+ end
+
+ it "should not check authorization if a node name is not provided" do
+ @terminus.expects(:authorized?).never
+ @terminus.stubs(@method)
+
+ # The quotes are necessary here, else it looks like a block.
+ @request.stubs(:options).returns({})
+ @indirection.send(@method, "/my/key")
+ end
+
+ it "should pass the request to the terminus's authorization method" do
+ @terminus.expects(:authorized?).with { |r| r.is_a?(Puppet::Indirector::Request) }.returns(true)
+ @terminus.stubs(@method)
+
+ @indirection.send(@method, "/my/key", :node => "mynode")
+ end
+
+ it "should fail if authorization returns false" do
+ @terminus.expects(:authorized?).returns(false)
+ @terminus.stubs(@method)
+ proc { @indirection.send(@method, "/my/key", :node => "mynode") }.should raise_error(ArgumentError)
+ end
+
+ it "should continue if authorization returns true" do
+ @terminus.expects(:authorized?).returns(true)
+ @terminus.stubs(@method)
+ @indirection.send(@method, "/my/key", :node => "mynode")
+ end
+end
- it "should not check authorization if a node name is not provided" do
- @terminus.expects(:authorized?).never
- @terminus.stubs(@method)
-
- # The quotes are necessary here, else it looks like a block.
- @request.stubs(:options).returns({})
- @indirection.send(@method, "/my/key")
+describe Puppet::Indirector::Indirection do
+ after do
+ Puppet::Util::Cacher.expire
+ end
+ describe "when initializing" do
+ # (LAK) I've no idea how to test this, really.
+ it "should store a reference to itself before it consumes its options" do
+ proc { @indirection = Puppet::Indirector::Indirection.new(Object.new, :testingness, :not_valid_option) }.should raise_error
+ Puppet::Indirector::Indirection.instance(:testingness).should be_instance_of(Puppet::Indirector::Indirection)
+ Puppet::Indirector::Indirection.instance(:testingness).delete
end
- it "should pass the request to the terminus's authorization method" do
- @terminus.expects(:authorized?).with { |r| r.is_a?(Puppet::Indirector::Request) }.returns(true)
- @terminus.stubs(@method)
+ it "should keep a reference to the indirecting model" do
+ model = mock 'model'
+ @indirection = Puppet::Indirector::Indirection.new(model, :myind)
+ @indirection.model.should equal(model)
+ end
- @indirection.send(@method, "/my/key", :node => "mynode")
+ it "should set the name" do
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :myind)
+ @indirection.name.should == :myind
end
- it "should fail if authorization returns false" do
- @terminus.expects(:authorized?).returns(false)
- @terminus.stubs(@method)
- proc { @indirection.send(@method, "/my/key", :node => "mynode") }.should raise_error(ArgumentError)
+ it "should require indirections to have unique names" do
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
+ proc { Puppet::Indirector::Indirection.new(:test) }.should raise_error(ArgumentError)
end
- it "should continue if authorization returns true" do
- @terminus.expects(:authorized?).returns(true)
- @terminus.stubs(@method)
- @indirection.send(@method, "/my/key", :node => "mynode")
+ it "should extend itself with any specified module" do
+ mod = Module.new
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test, :extend => mod)
+ @indirection.singleton_class.included_modules.should include(mod)
end
-end
-describe Puppet::Indirector::Indirection do
after do
- Puppet::Util::Cacher.expire
- end
- describe "when initializing" do
- # (LAK) I've no idea how to test this, really.
- it "should store a reference to itself before it consumes its options" do
- proc { @indirection = Puppet::Indirector::Indirection.new(Object.new, :testingness, :not_valid_option) }.should raise_error
- Puppet::Indirector::Indirection.instance(:testingness).should be_instance_of(Puppet::Indirector::Indirection)
- Puppet::Indirector::Indirection.instance(:testingness).delete
- end
-
- it "should keep a reference to the indirecting model" do
- model = mock 'model'
- @indirection = Puppet::Indirector::Indirection.new(model, :myind)
- @indirection.model.should equal(model)
- end
-
- it "should set the name" do
- @indirection = Puppet::Indirector::Indirection.new(mock('model'), :myind)
- @indirection.name.should == :myind
- end
-
- it "should require indirections to have unique names" do
- @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
- proc { Puppet::Indirector::Indirection.new(:test) }.should raise_error(ArgumentError)
- end
-
- it "should extend itself with any specified module" do
- mod = Module.new
- @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test, :extend => mod)
- @indirection.singleton_class.included_modules.should include(mod)
- end
-
- after do
- @indirection.delete if defined?(@indirection)
- end
+ @indirection.delete if defined?(@indirection)
+ end
+ end
+
+ describe "when an instance" do
+ before :each do
+ @terminus_class = mock 'terminus_class'
+ @terminus = mock 'terminus'
+ @terminus_class.stubs(:new).returns(@terminus)
+ @cache = stub 'cache', :name => "mycache"
+ @cache_class = mock 'cache_class'
+ Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :cache_terminus).returns(@cache_class)
+ Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :test_terminus).returns(@terminus_class)
+
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
+ @indirection.terminus_class = :test_terminus
+
+ @instance = stub 'instance', :expiration => nil, :expiration= => nil, :name => "whatever"
+ @name = :mything
+
+ #@request = stub 'instance', :key => "/my/key", :instance => @instance, :options => {}
+ @request = mock 'instance'
end
- describe "when an instance" do
- before :each do
- @terminus_class = mock 'terminus_class'
- @terminus = mock 'terminus'
- @terminus_class.stubs(:new).returns(@terminus)
- @cache = stub 'cache', :name => "mycache"
- @cache_class = mock 'cache_class'
- Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :cache_terminus).returns(@cache_class)
- Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :test_terminus).returns(@terminus_class)
-
- @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
- @indirection.terminus_class = :test_terminus
-
- @instance = stub 'instance', :expiration => nil, :expiration= => nil, :name => "whatever"
- @name = :mything
-
- #@request = stub 'instance', :key => "/my/key", :instance => @instance, :options => {}
- @request = mock 'instance'
- end
-
- it "should allow setting the ttl" do
- @indirection.ttl = 300
- @indirection.ttl.should == 300
- end
+ it "should allow setting the ttl" do
+ @indirection.ttl = 300
+ @indirection.ttl.should == 300
+ end
- it "should default to the :runinterval setting, converted to an integer, for its ttl" do
- Puppet.settings.expects(:value).returns "1800"
- @indirection.ttl.should == 1800
- end
+ it "should default to the :runinterval setting, converted to an integer, for its ttl" do
+ Puppet.settings.expects(:value).returns "1800"
+ @indirection.ttl.should == 1800
+ end
- it "should calculate the current expiration by adding the TTL to the current time" do
- @indirection.stubs(:ttl).returns(100)
- now = Time.now
- Time.stubs(:now).returns now
- @indirection.expiration.should == (Time.now + 100)
- end
+ it "should calculate the current expiration by adding the TTL to the current time" do
+ @indirection.stubs(:ttl).returns(100)
+ now = Time.now
+ Time.stubs(:now).returns now
+ @indirection.expiration.should == (Time.now + 100)
+ end
- it "should have a method for creating an indirection request instance" do
- @indirection.should respond_to(:request)
- end
+ it "should have a method for creating an indirection request instance" do
+ @indirection.should respond_to(:request)
+ end
- describe "creates a request" do
- it "should create it with its name as the request's indirection name" do
- Puppet::Indirector::Request.expects(:new).with { |name, *other| @indirection.name == name }
- @indirection.request(:funtest, "yayness")
- end
-
- it "should require a method and key" do
- Puppet::Indirector::Request.expects(:new).with { |name, method, key, *other| method == :funtest and key == "yayness" }
- @indirection.request(:funtest, "yayness")
- end
-
- it "should support optional arguments" do
- Puppet::Indirector::Request.expects(:new).with { |name, method, key, other| other == {:one => :two} }
- @indirection.request(:funtest, "yayness", :one => :two)
- end
-
- it "should not pass options if none are supplied" do
- Puppet::Indirector::Request.expects(:new).with { |*args| args.length < 4 }
- @indirection.request(:funtest, "yayness")
- end
-
- it "should return the request" do
- request = mock 'request'
- Puppet::Indirector::Request.expects(:new).returns request
- @indirection.request(:funtest, "yayness").should equal(request)
- end
- end
+ describe "creates a request" do
+ it "should create it with its name as the request's indirection name" do
+ Puppet::Indirector::Request.expects(:new).with { |name, *other| @indirection.name == name }
+ @indirection.request(:funtest, "yayness")
+ end
+
+ it "should require a method and key" do
+ Puppet::Indirector::Request.expects(:new).with { |name, method, key, *other| method == :funtest and key == "yayness" }
+ @indirection.request(:funtest, "yayness")
+ end
+
+ it "should support optional arguments" do
+ Puppet::Indirector::Request.expects(:new).with { |name, method, key, other| other == {:one => :two} }
+ @indirection.request(:funtest, "yayness", :one => :two)
+ end
+
+ it "should not pass options if none are supplied" do
+ Puppet::Indirector::Request.expects(:new).with { |*args| args.length < 4 }
+ @indirection.request(:funtest, "yayness")
+ end
+
+ it "should return the request" do
+ request = mock 'request'
+ Puppet::Indirector::Request.expects(:new).returns request
+ @indirection.request(:funtest, "yayness").should equal(request)
+ end
+ end
- describe "and looking for a model instance" do
- before { @method = :find }
+ describe "and looking for a model instance" do
+ before { @method = :find }
- it_should_behave_like "Indirection Delegator"
- it_should_behave_like "Delegation Authorizer"
+ it_should_behave_like "Indirection Delegator"
+ it_should_behave_like "Delegation Authorizer"
- it "should return the results of the delegation" do
- @terminus.expects(:find).returns(@instance)
- @indirection.find("me").should equal(@instance)
- end
+ it "should return the results of the delegation" do
+ @terminus.expects(:find).returns(@instance)
+ @indirection.find("me").should equal(@instance)
+ end
- it "should set the expiration date on any instances without one set" do
- @terminus.stubs(:find).returns(@instance)
+ it "should set the expiration date on any instances without one set" do
+ @terminus.stubs(:find).returns(@instance)
- @indirection.expects(:expiration).returns :yay
+ @indirection.expects(:expiration).returns :yay
- @instance.expects(:expiration).returns(nil)
- @instance.expects(:expiration=).with(:yay)
+ @instance.expects(:expiration).returns(nil)
+ @instance.expects(:expiration=).with(:yay)
- @indirection.find("/my/key")
- end
+ @indirection.find("/my/key")
+ end
- it "should not override an already-set expiration date on returned instances" do
- @terminus.stubs(:find).returns(@instance)
+ it "should not override an already-set expiration date on returned instances" do
+ @terminus.stubs(:find).returns(@instance)
- @indirection.expects(:expiration).never
+ @indirection.expects(:expiration).never
- @instance.expects(:expiration).returns(:yay)
- @instance.expects(:expiration=).never
+ @instance.expects(:expiration).returns(:yay)
+ @instance.expects(:expiration=).never
- @indirection.find("/my/key")
- end
+ @indirection.find("/my/key")
+ end
- it "should filter the result instance if the terminus supports it" do
- @terminus.stubs(:find).returns(@instance)
- @terminus.stubs(:respond_to?).with(:filter).returns(true)
+ it "should filter the result instance if the terminus supports it" do
+ @terminus.stubs(:find).returns(@instance)
+ @terminus.stubs(:respond_to?).with(:filter).returns(true)
- @terminus.expects(:filter).with(@instance)
+ @terminus.expects(:filter).with(@instance)
- @indirection.find("/my/key")
- end
- describe "when caching is enabled" do
- before do
- @indirection.cache_class = :cache_terminus
- @cache_class.stubs(:new).returns(@cache)
+ @indirection.find("/my/key")
+ end
+ describe "when caching is enabled" do
+ before do
+ @indirection.cache_class = :cache_terminus
+ @cache_class.stubs(:new).returns(@cache)
- @instance.stubs(:expired?).returns false
- end
+ @instance.stubs(:expired?).returns false
+ end
- it "should first look in the cache for an instance" do
- @terminus.stubs(:find).never
- @cache.expects(:find).returns @instance
+ it "should first look in the cache for an instance" do
+ @terminus.stubs(:find).never
+ @cache.expects(:find).returns @instance
- @indirection.find("/my/key")
- end
+ @indirection.find("/my/key")
+ end
- it "should not look in the cache if the request specifies not to use the cache" do
- @terminus.expects(:find).returns @instance
- @cache.expects(:find).never
- @cache.stubs(:save)
+ it "should not look in the cache if the request specifies not to use the cache" do
+ @terminus.expects(:find).returns @instance
+ @cache.expects(:find).never
+ @cache.stubs(:save)
- @indirection.find("/my/key", :ignore_cache => true)
- end
+ @indirection.find("/my/key", :ignore_cache => true)
+ end
- it "should still save to the cache even if the cache is being ignored during readin" do
- @terminus.expects(:find).returns @instance
- @cache.expects(:save)
+ it "should still save to the cache even if the cache is being ignored during readin" do
+ @terminus.expects(:find).returns @instance
+ @cache.expects(:save)
- @indirection.find("/my/key", :ignore_cache => true)
- end
+ @indirection.find("/my/key", :ignore_cache => true)
+ end
- it "should only look in the cache if the request specifies not to use the terminus" do
- @terminus.expects(:find).never
- @cache.expects(:find)
+ it "should only look in the cache if the request specifies not to use the terminus" do
+ @terminus.expects(:find).never
+ @cache.expects(:find)
- @indirection.find("/my/key", :ignore_terminus => true)
- end
+ @indirection.find("/my/key", :ignore_terminus => true)
+ end
- it "should use a request to look in the cache for cached objects" do
- @cache.expects(:find).with { |r| r.method == :find and r.key == "/my/key" }.returns @instance
+ it "should use a request to look in the cache for cached objects" do
+ @cache.expects(:find).with { |r| r.method == :find and r.key == "/my/key" }.returns @instance
- @cache.stubs(:save)
+ @cache.stubs(:save)
- @indirection.find("/my/key")
- end
+ @indirection.find("/my/key")
+ end
- it "should return the cached object if it is not expired" do
- @instance.stubs(:expired?).returns false
+ it "should return the cached object if it is not expired" do
+ @instance.stubs(:expired?).returns false
- @cache.stubs(:find).returns @instance
- @indirection.find("/my/key").should equal(@instance)
- end
+ @cache.stubs(:find).returns @instance
+ @indirection.find("/my/key").should equal(@instance)
+ end
- it "should not fail if the cache fails" do
- @terminus.stubs(:find).returns @instance
+ it "should not fail if the cache fails" do
+ @terminus.stubs(:find).returns @instance
- @cache.expects(:find).raises ArgumentError
- @cache.stubs(:save)
- lambda { @indirection.find("/my/key") }.should_not raise_error
- end
+ @cache.expects(:find).raises ArgumentError
+ @cache.stubs(:save)
+ lambda { @indirection.find("/my/key") }.should_not raise_error
+ end
- it "should look in the main terminus if the cache fails" do
- @terminus.expects(:find).returns @instance
- @cache.expects(:find).raises ArgumentError
- @cache.stubs(:save)
- @indirection.find("/my/key").should equal(@instance)
- end
+ it "should look in the main terminus if the cache fails" do
+ @terminus.expects(:find).returns @instance
+ @cache.expects(:find).raises ArgumentError
+ @cache.stubs(:save)
+ @indirection.find("/my/key").should equal(@instance)
+ end
- it "should send a debug log if it is using the cached object" do
- Puppet.expects(:debug)
- @cache.stubs(:find).returns @instance
+ it "should send a debug log if it is using the cached object" do
+ Puppet.expects(:debug)
+ @cache.stubs(:find).returns @instance
- @indirection.find("/my/key")
- end
+ @indirection.find("/my/key")
+ end
- it "should not return the cached object if it is expired" do
- @instance.stubs(:expired?).returns true
+ it "should not return the cached object if it is expired" do
+ @instance.stubs(:expired?).returns true
- @cache.stubs(:find).returns @instance
- @terminus.stubs(:find).returns nil
- @indirection.find("/my/key").should be_nil
- end
+ @cache.stubs(:find).returns @instance
+ @terminus.stubs(:find).returns nil
+ @indirection.find("/my/key").should be_nil
+ end
- it "should send an info log if it is using the cached object" do
- Puppet.expects(:info)
- @instance.stubs(:expired?).returns true
+ it "should send an info log if it is using the cached object" do
+ Puppet.expects(:info)
+ @instance.stubs(:expired?).returns true
- @cache.stubs(:find).returns @instance
- @terminus.stubs(:find).returns nil
- @indirection.find("/my/key")
- end
+ @cache.stubs(:find).returns @instance
+ @terminus.stubs(:find).returns nil
+ @indirection.find("/my/key")
+ end
- it "should cache any objects not retrieved from the cache" do
- @cache.expects(:find).returns nil
+ it "should cache any objects not retrieved from the cache" do
+ @cache.expects(:find).returns nil
- @terminus.expects(:find).returns(@instance)
- @cache.expects(:save)
+ @terminus.expects(:find).returns(@instance)
+ @cache.expects(:save)
- @indirection.find("/my/key")
- end
+ @indirection.find("/my/key")
+ end
- it "should use a request to look in the cache for cached objects" do
- @cache.expects(:find).with { |r| r.method == :find and r.key == "/my/key" }.returns nil
+ it "should use a request to look in the cache for cached objects" do
+ @cache.expects(:find).with { |r| r.method == :find and r.key == "/my/key" }.returns nil
- @terminus.stubs(:find).returns(@instance)
- @cache.stubs(:save)
+ @terminus.stubs(:find).returns(@instance)
+ @cache.stubs(:save)
- @indirection.find("/my/key")
- end
+ @indirection.find("/my/key")
+ end
- it "should cache the instance using a request with the instance set to the cached object" do
- @cache.stubs(:find).returns nil
+ it "should cache the instance using a request with the instance set to the cached object" do
+ @cache.stubs(:find).returns nil
- @terminus.stubs(:find).returns(@instance)
+ @terminus.stubs(:find).returns(@instance)
- @cache.expects(:save).with { |r| r.method == :save and r.instance == @instance }
+ @cache.expects(:save).with { |r| r.method == :save and r.instance == @instance }
- @indirection.find("/my/key")
- end
+ @indirection.find("/my/key")
+ end
- it "should send an info log that the object is being cached" do
- @cache.stubs(:find).returns nil
+ it "should send an info log that the object is being cached" do
+ @cache.stubs(:find).returns nil
- @terminus.stubs(:find).returns(@instance)
- @cache.stubs(:save)
+ @terminus.stubs(:find).returns(@instance)
+ @cache.stubs(:save)
- Puppet.expects(:info)
+ Puppet.expects(:info)
- @indirection.find("/my/key")
- end
- end
+ @indirection.find("/my/key")
end
+ end
+ end
- describe "and storing a model instance" do
- before { @method = :save }
+ describe "and storing a model instance" do
+ before { @method = :save }
- it_should_behave_like "Indirection Delegator"
- it_should_behave_like "Delegation Authorizer"
+ it_should_behave_like "Indirection Delegator"
+ it_should_behave_like "Delegation Authorizer"
- it "should return the result of the save" do
- @terminus.stubs(:save).returns "foo"
- @indirection.save(@instance).should == "foo"
- end
+ it "should return the result of the save" do
+ @terminus.stubs(:save).returns "foo"
+ @indirection.save(@instance).should == "foo"
+ end
- describe "when caching is enabled" do
- before do
- @indirection.cache_class = :cache_terminus
- @cache_class.stubs(:new).returns(@cache)
+ describe "when caching is enabled" do
+ before do
+ @indirection.cache_class = :cache_terminus
+ @cache_class.stubs(:new).returns(@cache)
- @instance.stubs(:expired?).returns false
- end
+ @instance.stubs(:expired?).returns false
+ end
- it "should return the result of saving to the terminus" do
- request = stub 'request', :instance => @instance, :node => nil
+ it "should return the result of saving to the terminus" do
+ request = stub 'request', :instance => @instance, :node => nil
- @indirection.expects(:request).returns request
+ @indirection.expects(:request).returns request
- @cache.stubs(:save)
- @terminus.stubs(:save).returns @instance
- @indirection.save(@instance).should equal(@instance)
- end
+ @cache.stubs(:save)
+ @terminus.stubs(:save).returns @instance
+ @indirection.save(@instance).should equal(@instance)
+ end
- it "should use a request to save the object to the cache" do
- request = stub 'request', :instance => @instance, :node => nil
+ it "should use a request to save the object to the cache" do
+ request = stub 'request', :instance => @instance, :node => nil
- @indirection.expects(:request).returns request
+ @indirection.expects(:request).returns request
- @cache.expects(:save).with(request)
- @terminus.stubs(:save)
- @indirection.save(@instance)
- end
+ @cache.expects(:save).with(request)
+ @terminus.stubs(:save)
+ @indirection.save(@instance)
+ end
- it "should not save to the cache if the normal save fails" do
- request = stub 'request', :instance => @instance, :node => nil
+ it "should not save to the cache if the normal save fails" do
+ request = stub 'request', :instance => @instance, :node => nil
- @indirection.expects(:request).returns request
+ @indirection.expects(:request).returns request
- @cache.expects(:save).never
- @terminus.expects(:save).raises "eh"
- lambda { @indirection.save(@instance) }.should raise_error
- end
- end
+ @cache.expects(:save).never
+ @terminus.expects(:save).raises "eh"
+ lambda { @indirection.save(@instance) }.should raise_error
end
+ end
+ end
- describe "and removing a model instance" do
- before { @method = :destroy }
+ describe "and removing a model instance" do
+ before { @method = :destroy }
- it_should_behave_like "Indirection Delegator"
- it_should_behave_like "Delegation Authorizer"
+ it_should_behave_like "Indirection Delegator"
+ it_should_behave_like "Delegation Authorizer"
- it "should return the result of removing the instance" do
- @terminus.stubs(:destroy).returns "yayness"
- @indirection.destroy("/my/key").should == "yayness"
- end
+ it "should return the result of removing the instance" do
+ @terminus.stubs(:destroy).returns "yayness"
+ @indirection.destroy("/my/key").should == "yayness"
+ end
- describe "when caching is enabled" do
- before do
- @indirection.cache_class = :cache_terminus
- @cache_class.expects(:new).returns(@cache)
+ describe "when caching is enabled" do
+ before do
+ @indirection.cache_class = :cache_terminus
+ @cache_class.expects(:new).returns(@cache)
- @instance.stubs(:expired?).returns false
- end
+ @instance.stubs(:expired?).returns false
+ end
- it "should use a request instance to search in and remove objects from the cache" do
- destroy = stub 'destroy_request', :key => "/my/key", :node => nil
- find = stub 'destroy_request', :key => "/my/key", :node => nil
+ it "should use a request instance to search in and remove objects from the cache" do
+ destroy = stub 'destroy_request', :key => "/my/key", :node => nil
+ find = stub 'destroy_request', :key => "/my/key", :node => nil
- @indirection.expects(:request).with(:destroy, "/my/key").returns destroy
- @indirection.expects(:request).with(:find, "/my/key").returns find
+ @indirection.expects(:request).with(:destroy, "/my/key").returns destroy
+ @indirection.expects(:request).with(:find, "/my/key").returns find
- cached = mock 'cache'
+ cached = mock 'cache'
- @cache.expects(:find).with(find).returns cached
- @cache.expects(:destroy).with(destroy)
+ @cache.expects(:find).with(find).returns cached
+ @cache.expects(:destroy).with(destroy)
- @terminus.stubs(:destroy)
+ @terminus.stubs(:destroy)
- @indirection.destroy("/my/key")
- end
- end
+ @indirection.destroy("/my/key")
end
+ end
+ end
- describe "and searching for multiple model instances" do
- before { @method = :search }
-
- it_should_behave_like "Indirection Delegator"
- it_should_behave_like "Delegation Authorizer"
+ describe "and searching for multiple model instances" do
+ before { @method = :search }
- it "should set the expiration date on any instances without one set" do
- @terminus.stubs(:search).returns([@instance])
+ it_should_behave_like "Indirection Delegator"
+ it_should_behave_like "Delegation Authorizer"
- @indirection.expects(:expiration).returns :yay
+ it "should set the expiration date on any instances without one set" do
+ @terminus.stubs(:search).returns([@instance])
- @instance.expects(:expiration).returns(nil)
- @instance.expects(:expiration=).with(:yay)
+ @indirection.expects(:expiration).returns :yay
- @indirection.search("/my/key")
- end
+ @instance.expects(:expiration).returns(nil)
+ @instance.expects(:expiration=).with(:yay)
- it "should not override an already-set expiration date on returned instances" do
- @terminus.stubs(:search).returns([@instance])
+ @indirection.search("/my/key")
+ end
- @indirection.expects(:expiration).never
+ it "should not override an already-set expiration date on returned instances" do
+ @terminus.stubs(:search).returns([@instance])
- @instance.expects(:expiration).returns(:yay)
- @instance.expects(:expiration=).never
+ @indirection.expects(:expiration).never
- @indirection.search("/my/key")
- end
+ @instance.expects(:expiration).returns(:yay)
+ @instance.expects(:expiration=).never
- it "should return the results of searching in the terminus" do
- @terminus.expects(:search).returns([@instance])
- @indirection.search("/my/key").should == [@instance]
- end
- end
+ @indirection.search("/my/key")
+ end
- describe "and expiring a model instance" do
- describe "when caching is not enabled" do
- it "should do nothing" do
- @cache_class.expects(:new).never
+ it "should return the results of searching in the terminus" do
+ @terminus.expects(:search).returns([@instance])
+ @indirection.search("/my/key").should == [@instance]
+ end
+ end
- @indirection.expire("/my/key")
- end
- end
+ describe "and expiring a model instance" do
+ describe "when caching is not enabled" do
+ it "should do nothing" do
+ @cache_class.expects(:new).never
- describe "when caching is enabled" do
- before do
- @indirection.cache_class = :cache_terminus
- @cache_class.expects(:new).returns(@cache)
+ @indirection.expire("/my/key")
+ end
+ end
- @instance.stubs(:expired?).returns false
+ describe "when caching is enabled" do
+ before do
+ @indirection.cache_class = :cache_terminus
+ @cache_class.expects(:new).returns(@cache)
- @cached = stub 'cached', :expiration= => nil, :name => "/my/key"
- end
+ @instance.stubs(:expired?).returns false
- it "should use a request to find within the cache" do
- @cache.expects(:find).with { |r| r.is_a?(Puppet::Indirector::Request) and r.method == :find }
- @indirection.expire("/my/key")
- end
+ @cached = stub 'cached', :expiration= => nil, :name => "/my/key"
+ end
- it "should do nothing if no such instance is cached" do
- @cache.expects(:find).returns nil
+ it "should use a request to find within the cache" do
+ @cache.expects(:find).with { |r| r.is_a?(Puppet::Indirector::Request) and r.method == :find }
+ @indirection.expire("/my/key")
+ end
- @indirection.expire("/my/key")
- end
+ it "should do nothing if no such instance is cached" do
+ @cache.expects(:find).returns nil
- it "should log when expiring a found instance" do
- @cache.expects(:find).returns @cached
- @cache.stubs(:save)
+ @indirection.expire("/my/key")
+ end
- Puppet.expects(:info)
+ it "should log when expiring a found instance" do
+ @cache.expects(:find).returns @cached
+ @cache.stubs(:save)
- @indirection.expire("/my/key")
- end
+ Puppet.expects(:info)
- it "should set the cached instance's expiration to a time in the past" do
- @cache.expects(:find).returns @cached
- @cache.stubs(:save)
+ @indirection.expire("/my/key")
+ end
- @cached.expects(:expiration=).with { |t| t < Time.now }
+ it "should set the cached instance's expiration to a time in the past" do
+ @cache.expects(:find).returns @cached
+ @cache.stubs(:save)
- @indirection.expire("/my/key")
- end
+ @cached.expects(:expiration=).with { |t| t < Time.now }
- it "should save the now expired instance back into the cache" do
- @cache.expects(:find).returns @cached
+ @indirection.expire("/my/key")
+ end
- @cached.expects(:expiration=).with { |t| t < Time.now }
+ it "should save the now expired instance back into the cache" do
+ @cache.expects(:find).returns @cached
- @cache.expects(:save)
+ @cached.expects(:expiration=).with { |t| t < Time.now }
- @indirection.expire("/my/key")
- end
+ @cache.expects(:save)
- it "should use a request to save the expired resource to the cache" do
- @cache.expects(:find).returns @cached
+ @indirection.expire("/my/key")
+ end
- @cached.expects(:expiration=).with { |t| t < Time.now }
+ it "should use a request to save the expired resource to the cache" do
+ @cache.expects(:find).returns @cached
- @cache.expects(:save).with { |r| r.is_a?(Puppet::Indirector::Request) and r.instance == @cached and r.method == :save }.returns(@cached)
+ @cached.expects(:expiration=).with { |t| t < Time.now }
- @indirection.expire("/my/key")
- end
- end
- end
+ @cache.expects(:save).with { |r| r.is_a?(Puppet::Indirector::Request) and r.instance == @cached and r.method == :save }.returns(@cached)
- after :each do
- @indirection.delete
- Puppet::Util::Cacher.expire
+ @indirection.expire("/my/key")
end
+ end
end
+ after :each do
+ @indirection.delete
+ Puppet::Util::Cacher.expire
+ end
+ end
- describe "when managing indirection instances" do
- it "should allow an indirection to be retrieved by name" do
- @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
- Puppet::Indirector::Indirection.instance(:test).should equal(@indirection)
- end
- it "should return nil when the named indirection has not been created" do
- Puppet::Indirector::Indirection.instance(:test).should be_nil
- end
+ describe "when managing indirection instances" do
+ it "should allow an indirection to be retrieved by name" do
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
+ Puppet::Indirector::Indirection.instance(:test).should equal(@indirection)
+ end
- it "should allow an indirection's model to be retrieved by name" do
- mock_model = mock('model')
- @indirection = Puppet::Indirector::Indirection.new(mock_model, :test)
- Puppet::Indirector::Indirection.model(:test).should equal(mock_model)
- end
+ it "should return nil when the named indirection has not been created" do
+ Puppet::Indirector::Indirection.instance(:test).should be_nil
+ end
- it "should return nil when no model matches the requested name" do
- Puppet::Indirector::Indirection.model(:test).should be_nil
- end
+ it "should allow an indirection's model to be retrieved by name" do
+ mock_model = mock('model')
+ @indirection = Puppet::Indirector::Indirection.new(mock_model, :test)
+ Puppet::Indirector::Indirection.model(:test).should equal(mock_model)
+ end
- after do
- @indirection.delete if defined?(@indirection)
- end
+ it "should return nil when no model matches the requested name" do
+ Puppet::Indirector::Indirection.model(:test).should be_nil
end
- describe "when routing to the correct the terminus class" do
- before do
- @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
- @terminus = mock 'terminus'
- @terminus_class = stub 'terminus class', :new => @terminus
- Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :default).returns(@terminus_class)
- end
+ after do
+ @indirection.delete if defined?(@indirection)
+ end
+ end
- it "should fail if no terminus class can be picked" do
- proc { @indirection.terminus_class }.should raise_error(Puppet::DevError)
- end
+ describe "when routing to the correct the terminus class" do
+ before do
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
+ @terminus = mock 'terminus'
+ @terminus_class = stub 'terminus class', :new => @terminus
+ Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :default).returns(@terminus_class)
+ end
- it "should choose the default terminus class if one is specified" do
- @indirection.terminus_class = :default
- @indirection.terminus_class.should equal(:default)
- end
+ it "should fail if no terminus class can be picked" do
+ proc { @indirection.terminus_class }.should raise_error(Puppet::DevError)
+ end
- it "should use the provided Puppet setting if told to do so" do
- Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :my_terminus).returns(mock("terminus_class2"))
- Puppet.settings.expects(:value).with(:my_setting).returns("my_terminus")
- @indirection.terminus_setting = :my_setting
- @indirection.terminus_class.should equal(:my_terminus)
- end
+ it "should choose the default terminus class if one is specified" do
+ @indirection.terminus_class = :default
+ @indirection.terminus_class.should equal(:default)
+ end
- it "should fail if the provided terminus class is not valid" do
- Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :nosuchclass).returns(nil)
- proc { @indirection.terminus_class = :nosuchclass }.should raise_error(ArgumentError)
- end
+ it "should use the provided Puppet setting if told to do so" do
+ Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :my_terminus).returns(mock("terminus_class2"))
+ Puppet.settings.expects(:value).with(:my_setting).returns("my_terminus")
+ @indirection.terminus_setting = :my_setting
+ @indirection.terminus_class.should equal(:my_terminus)
+ end
- after do
- @indirection.delete if defined?(@indirection)
- end
+ it "should fail if the provided terminus class is not valid" do
+ Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :nosuchclass).returns(nil)
+ proc { @indirection.terminus_class = :nosuchclass }.should raise_error(ArgumentError)
end
- describe "when specifying the terminus class to use" do
- before do
- @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
- @terminus = mock 'terminus'
- @terminus_class = stub 'terminus class', :new => @terminus
- end
+ after do
+ @indirection.delete if defined?(@indirection)
+ end
+ end
- it "should allow specification of a terminus type" do
- @indirection.should respond_to(:terminus_class=)
- end
+ describe "when specifying the terminus class to use" do
+ before do
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
+ @terminus = mock 'terminus'
+ @terminus_class = stub 'terminus class', :new => @terminus
+ end
- it "should fail to redirect if no terminus type has been specified" do
- proc { @indirection.find("blah") }.should raise_error(Puppet::DevError)
- end
+ it "should allow specification of a terminus type" do
+ @indirection.should respond_to(:terminus_class=)
+ end
- it "should fail when the terminus class name is an empty string" do
- proc { @indirection.terminus_class = "" }.should raise_error(ArgumentError)
- end
+ it "should fail to redirect if no terminus type has been specified" do
+ proc { @indirection.find("blah") }.should raise_error(Puppet::DevError)
+ end
- it "should fail when the terminus class name is nil" do
- proc { @indirection.terminus_class = nil }.should raise_error(ArgumentError)
- end
+ it "should fail when the terminus class name is an empty string" do
+ proc { @indirection.terminus_class = "" }.should raise_error(ArgumentError)
+ end
- it "should fail when the specified terminus class cannot be found" do
- Puppet::Indirector::Terminus.expects(:terminus_class).with(:test, :foo).returns(nil)
- proc { @indirection.terminus_class = :foo }.should raise_error(ArgumentError)
- end
+ it "should fail when the terminus class name is nil" do
+ proc { @indirection.terminus_class = nil }.should raise_error(ArgumentError)
+ end
- it "should select the specified terminus class if a terminus class name is provided" do
- Puppet::Indirector::Terminus.expects(:terminus_class).with(:test, :foo).returns(@terminus_class)
- @indirection.terminus(:foo).should equal(@terminus)
- end
+ it "should fail when the specified terminus class cannot be found" do
+ Puppet::Indirector::Terminus.expects(:terminus_class).with(:test, :foo).returns(nil)
+ proc { @indirection.terminus_class = :foo }.should raise_error(ArgumentError)
+ end
- it "should use the configured terminus class if no terminus name is specified" do
- Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :foo).returns(@terminus_class)
- @indirection.terminus_class = :foo
- @indirection.terminus.should equal(@terminus)
- end
+ it "should select the specified terminus class if a terminus class name is provided" do
+ Puppet::Indirector::Terminus.expects(:terminus_class).with(:test, :foo).returns(@terminus_class)
+ @indirection.terminus(:foo).should equal(@terminus)
+ end
- after do
- @indirection.delete if defined?(@indirection)
- end
+ it "should use the configured terminus class if no terminus name is specified" do
+ Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :foo).returns(@terminus_class)
+ @indirection.terminus_class = :foo
+ @indirection.terminus.should equal(@terminus)
end
- describe "when managing terminus instances" do
- before do
- @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
- @terminus = mock 'terminus'
- @terminus_class = mock 'terminus class'
- Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :foo).returns(@terminus_class)
- end
+ after do
+ @indirection.delete if defined?(@indirection)
+ end
+ end
- it "should create an instance of the chosen terminus class" do
- @terminus_class.stubs(:new).returns(@terminus)
- @indirection.terminus(:foo).should equal(@terminus)
- end
+ describe "when managing terminus instances" do
+ before do
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
+ @terminus = mock 'terminus'
+ @terminus_class = mock 'terminus class'
+ Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :foo).returns(@terminus_class)
+ end
- # Make sure it caches the terminus.
- it "should return the same terminus instance each time for a given name" do
- @terminus_class.stubs(:new).returns(@terminus)
- @indirection.terminus(:foo).should equal(@terminus)
- @indirection.terminus(:foo).should equal(@terminus)
- end
+ it "should create an instance of the chosen terminus class" do
+ @terminus_class.stubs(:new).returns(@terminus)
+ @indirection.terminus(:foo).should equal(@terminus)
+ end
- it "should not create a terminus instance until one is actually needed" do
- Puppet::Indirector.expects(:terminus).never
- indirection = Puppet::Indirector::Indirection.new(mock('model'), :lazytest)
- end
+ # Make sure it caches the terminus.
+ it "should return the same terminus instance each time for a given name" do
+ @terminus_class.stubs(:new).returns(@terminus)
+ @indirection.terminus(:foo).should equal(@terminus)
+ @indirection.terminus(:foo).should equal(@terminus)
+ end
- after do
- @indirection.delete
- end
+ it "should not create a terminus instance until one is actually needed" do
+ Puppet::Indirector.expects(:terminus).never
+ indirection = Puppet::Indirector::Indirection.new(mock('model'), :lazytest)
end
- describe "when deciding whether to cache" do
- before do
- @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
- @terminus = mock 'terminus'
- @terminus_class = mock 'terminus class'
- @terminus_class.stubs(:new).returns(@terminus)
- Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :foo).returns(@terminus_class)
- @indirection.terminus_class = :foo
- end
+ after do
+ @indirection.delete
+ end
+ end
- it "should provide a method for setting the cache terminus class" do
- @indirection.should respond_to(:cache_class=)
- end
+ describe "when deciding whether to cache" do
+ before do
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
+ @terminus = mock 'terminus'
+ @terminus_class = mock 'terminus class'
+ @terminus_class.stubs(:new).returns(@terminus)
+ Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :foo).returns(@terminus_class)
+ @indirection.terminus_class = :foo
+ end
- it "should fail to cache if no cache type has been specified" do
- proc { @indirection.cache }.should raise_error(Puppet::DevError)
- end
+ it "should provide a method for setting the cache terminus class" do
+ @indirection.should respond_to(:cache_class=)
+ end
- it "should fail to set the cache class when the cache class name is an empty string" do
- proc { @indirection.cache_class = "" }.should raise_error(ArgumentError)
- end
+ it "should fail to cache if no cache type has been specified" do
+ proc { @indirection.cache }.should raise_error(Puppet::DevError)
+ end
- it "should allow resetting the cache_class to nil" do
- @indirection.cache_class = nil
- @indirection.cache_class.should be_nil
- end
+ it "should fail to set the cache class when the cache class name is an empty string" do
+ proc { @indirection.cache_class = "" }.should raise_error(ArgumentError)
+ end
- it "should fail to set the cache class when the specified cache class cannot be found" do
- Puppet::Indirector::Terminus.expects(:terminus_class).with(:test, :foo).returns(nil)
- proc { @indirection.cache_class = :foo }.should raise_error(ArgumentError)
- end
+ it "should allow resetting the cache_class to nil" do
+ @indirection.cache_class = nil
+ @indirection.cache_class.should be_nil
+ end
- after do
- @indirection.delete
- end
+ it "should fail to set the cache class when the specified cache class cannot be found" do
+ Puppet::Indirector::Terminus.expects(:terminus_class).with(:test, :foo).returns(nil)
+ proc { @indirection.cache_class = :foo }.should raise_error(ArgumentError)
end
- describe "when using a cache" do
- before :each do
- Puppet.settings.stubs(:value).with("test_terminus").returns("test_terminus")
- @terminus_class = mock 'terminus_class'
- @terminus = mock 'terminus'
- @terminus_class.stubs(:new).returns(@terminus)
- @cache = mock 'cache'
- @cache_class = mock 'cache_class'
- Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :cache_terminus).returns(@cache_class)
- Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :test_terminus).returns(@terminus_class)
- @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
- @indirection.terminus_class = :test_terminus
- end
+ after do
+ @indirection.delete
+ end
+ end
+
+ describe "when using a cache" do
+ before :each do
+ Puppet.settings.stubs(:value).with("test_terminus").returns("test_terminus")
+ @terminus_class = mock 'terminus_class'
+ @terminus = mock 'terminus'
+ @terminus_class.stubs(:new).returns(@terminus)
+ @cache = mock 'cache'
+ @cache_class = mock 'cache_class'
+ Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :cache_terminus).returns(@cache_class)
+ Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :test_terminus).returns(@terminus_class)
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
+ @indirection.terminus_class = :test_terminus
+ end
- describe "and managing the cache terminus" do
- it "should not create a cache terminus at initialization" do
- # This is weird, because all of the code is in the setup. If we got
- # new called on the cache class, we'd get an exception here.
- end
-
- it "should reuse the cache terminus" do
- @cache_class.expects(:new).returns(@cache)
- Puppet.settings.stubs(:value).with("test_cache").returns("cache_terminus")
- @indirection.cache_class = :cache_terminus
- @indirection.cache.should equal(@cache)
- @indirection.cache.should equal(@cache)
- end
- end
+ describe "and managing the cache terminus" do
+ it "should not create a cache terminus at initialization" do
+ # This is weird, because all of the code is in the setup. If we got
+ # new called on the cache class, we'd get an exception here.
+ end
+
+ it "should reuse the cache terminus" do
+ @cache_class.expects(:new).returns(@cache)
+ Puppet.settings.stubs(:value).with("test_cache").returns("cache_terminus")
+ @indirection.cache_class = :cache_terminus
+ @indirection.cache.should equal(@cache)
+ @indirection.cache.should equal(@cache)
+ end
+ end
- describe "and saving" do
- end
+ describe "and saving" do
+ end
- describe "and finding" do
- end
+ describe "and finding" do
+ end
- after :each do
- @indirection.delete
- end
+ after :each do
+ @indirection.delete
end
+ end
end
diff --git a/spec/unit/indirector/key/ca_spec.rb b/spec/unit/indirector/key/ca_spec.rb
index 964b0b0..9ed5df6 100755
--- a/spec/unit/indirector/key/ca_spec.rb
+++ b/spec/unit/indirector/key/ca_spec.rb
@@ -8,21 +8,21 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/key/ca'
describe Puppet::SSL::Key::Ca do
- it "should have documentation" do
- Puppet::SSL::Key::Ca.doc.should be_instance_of(String)
- end
+ it "should have documentation" do
+ Puppet::SSL::Key::Ca.doc.should be_instance_of(String)
+ end
- it "should use the :privatekeydir as the collection directory" do
- Puppet.settings.expects(:value).with(:privatekeydir).returns "/key/dir"
- Puppet::SSL::Key::Ca.collection_directory.should == "/key/dir"
- end
+ it "should use the :privatekeydir as the collection directory" do
+ Puppet.settings.expects(:value).with(:privatekeydir).returns "/key/dir"
+ Puppet::SSL::Key::Ca.collection_directory.should == "/key/dir"
+ end
- it "should store the ca key at the :cakey location" do
- Puppet.settings.stubs(:use)
- Puppet.settings.stubs(:value).returns "whatever"
- Puppet.settings.stubs(:value).with(:cakey).returns "/ca/key"
- file = Puppet::SSL::Key::Ca.new
- file.stubs(:ca?).returns true
- file.path("whatever").should == "/ca/key"
- end
+ it "should store the ca key at the :cakey location" do
+ Puppet.settings.stubs(:use)
+ Puppet.settings.stubs(:value).returns "whatever"
+ Puppet.settings.stubs(:value).with(:cakey).returns "/ca/key"
+ file = Puppet::SSL::Key::Ca.new
+ file.stubs(:ca?).returns true
+ file.path("whatever").should == "/ca/key"
+ end
end
diff --git a/spec/unit/indirector/key/file_spec.rb b/spec/unit/indirector/key/file_spec.rb
index f365bfd..5037c7f 100755
--- a/spec/unit/indirector/key/file_spec.rb
+++ b/spec/unit/indirector/key/file_spec.rb
@@ -8,97 +8,97 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/key/file'
describe Puppet::SSL::Key::File do
- it "should have documentation" do
- Puppet::SSL::Key::File.doc.should be_instance_of(String)
+ it "should have documentation" do
+ Puppet::SSL::Key::File.doc.should be_instance_of(String)
+ end
+
+ it "should use the :privatekeydir as the collection directory" do
+ Puppet.settings.expects(:value).with(:privatekeydir).returns "/key/dir"
+ Puppet::SSL::Key::File.collection_directory.should == "/key/dir"
+ end
+
+ it "should store the ca key at the :cakey location" do
+ Puppet.settings.stubs(:use)
+ Puppet.settings.stubs(:value).returns "whatever"
+ Puppet.settings.stubs(:value).with(:cakey).returns "/ca/key"
+ file = Puppet::SSL::Key::File.new
+ file.stubs(:ca?).returns true
+ file.path("whatever").should == "/ca/key"
+ end
+
+ describe "when choosing the path for the public key" do
+ it "should use the :capub setting location if the key is for the certificate authority" do
+ Puppet.settings.stubs(:value).returns "/fake/dir"
+ Puppet.settings.stubs(:value).with(:capub).returns "/ca/pubkey"
+ Puppet.settings.stubs(:use)
+
+ @searcher = Puppet::SSL::Key::File.new
+ @searcher.stubs(:ca?).returns true
+ @searcher.public_key_path("whatever").should == "/ca/pubkey"
end
- it "should use the :privatekeydir as the collection directory" do
- Puppet.settings.expects(:value).with(:privatekeydir).returns "/key/dir"
- Puppet::SSL::Key::File.collection_directory.should == "/key/dir"
- end
-
- it "should store the ca key at the :cakey location" do
- Puppet.settings.stubs(:use)
- Puppet.settings.stubs(:value).returns "whatever"
- Puppet.settings.stubs(:value).with(:cakey).returns "/ca/key"
- file = Puppet::SSL::Key::File.new
- file.stubs(:ca?).returns true
- file.path("whatever").should == "/ca/key"
- end
+ it "should use the host name plus '.pem' in :publickeydir for normal hosts" do
+ Puppet.settings.stubs(:value).with(:privatekeydir).returns "/private/key/dir"
+ Puppet.settings.stubs(:value).with(:publickeydir).returns "/public/key/dir"
+ Puppet.settings.stubs(:use)
- describe "when choosing the path for the public key" do
- it "should use the :capub setting location if the key is for the certificate authority" do
- Puppet.settings.stubs(:value).returns "/fake/dir"
- Puppet.settings.stubs(:value).with(:capub).returns "/ca/pubkey"
- Puppet.settings.stubs(:use)
-
- @searcher = Puppet::SSL::Key::File.new
- @searcher.stubs(:ca?).returns true
- @searcher.public_key_path("whatever").should == "/ca/pubkey"
- end
-
- it "should use the host name plus '.pem' in :publickeydir for normal hosts" do
- Puppet.settings.stubs(:value).with(:privatekeydir).returns "/private/key/dir"
- Puppet.settings.stubs(:value).with(:publickeydir).returns "/public/key/dir"
- Puppet.settings.stubs(:use)
-
- @searcher = Puppet::SSL::Key::File.new
- @searcher.stubs(:ca?).returns false
- @searcher.public_key_path("whatever").should == "/public/key/dir/whatever.pem"
- end
+ @searcher = Puppet::SSL::Key::File.new
+ @searcher.stubs(:ca?).returns false
+ @searcher.public_key_path("whatever").should == "/public/key/dir/whatever.pem"
end
+ end
- describe "when managing private keys" do
- before do
- @searcher = Puppet::SSL::Key::File.new
+ describe "when managing private keys" do
+ before do
+ @searcher = Puppet::SSL::Key::File.new
- @private_key_path = File.join("/fake/key/path")
- @public_key_path = File.join("/other/fake/key/path")
+ @private_key_path = File.join("/fake/key/path")
+ @public_key_path = File.join("/other/fake/key/path")
- @searcher.stubs(:public_key_path).returns @public_key_path
- @searcher.stubs(:path).returns @private_key_path
+ @searcher.stubs(:public_key_path).returns @public_key_path
+ @searcher.stubs(:path).returns @private_key_path
- FileTest.stubs(:directory?).returns true
- FileTest.stubs(:writable?).returns true
+ FileTest.stubs(:directory?).returns true
+ FileTest.stubs(:writable?).returns true
- @public_key = stub 'public_key'
- @real_key = stub 'sslkey', :public_key => @public_key
+ @public_key = stub 'public_key'
+ @real_key = stub 'sslkey', :public_key => @public_key
- @key = stub 'key', :name => "myname", :content => @real_key
+ @key = stub 'key', :name => "myname", :content => @real_key
- @request = stub 'request', :key => "myname", :instance => @key
- end
+ @request = stub 'request', :key => "myname", :instance => @key
+ end
- it "should save the public key when saving the private key" do
- Puppet.settings.stubs(:writesub)
+ it "should save the public key when saving the private key" do
+ Puppet.settings.stubs(:writesub)
- fh = mock 'filehandle'
+ fh = mock 'filehandle'
- Puppet.settings.expects(:writesub).with(:publickeydir, @public_key_path).yields fh
- @public_key.expects(:to_pem).returns "my pem"
+ Puppet.settings.expects(:writesub).with(:publickeydir, @public_key_path).yields fh
+ @public_key.expects(:to_pem).returns "my pem"
- fh.expects(:print).with "my pem"
+ fh.expects(:print).with "my pem"
- @searcher.save(@request)
- end
+ @searcher.save(@request)
+ end
- it "should destroy the public key when destroying the private key" do
- File.stubs(:unlink).with(@private_key_path)
- FileTest.stubs(:exist?).with(@private_key_path).returns true
- FileTest.expects(:exist?).with(@public_key_path).returns true
- File.expects(:unlink).with(@public_key_path)
+ it "should destroy the public key when destroying the private key" do
+ File.stubs(:unlink).with(@private_key_path)
+ FileTest.stubs(:exist?).with(@private_key_path).returns true
+ FileTest.expects(:exist?).with(@public_key_path).returns true
+ File.expects(:unlink).with(@public_key_path)
- @searcher.destroy(@request)
- end
+ @searcher.destroy(@request)
+ end
- it "should not fail if the public key does not exist when deleting the private key" do
- File.stubs(:unlink).with(@private_key_path)
+ it "should not fail if the public key does not exist when deleting the private key" do
+ File.stubs(:unlink).with(@private_key_path)
- FileTest.stubs(:exist?).with(@private_key_path).returns true
- FileTest.expects(:exist?).with(@public_key_path).returns false
- File.expects(:unlink).with(@public_key_path).never
+ FileTest.stubs(:exist?).with(@private_key_path).returns true
+ FileTest.expects(:exist?).with(@public_key_path).returns false
+ File.expects(:unlink).with(@public_key_path).never
- @searcher.destroy(@request)
- end
+ @searcher.destroy(@request)
end
+ end
end
diff --git a/spec/unit/indirector/ldap_spec.rb b/spec/unit/indirector/ldap_spec.rb
index 44df2b5..31a3406 100755
--- a/spec/unit/indirector/ldap_spec.rb
+++ b/spec/unit/indirector/ldap_spec.rb
@@ -5,139 +5,139 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector/ldap'
describe Puppet::Indirector::Ldap do
- before do
- @indirection = stub 'indirection', :name => :testing
- Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
- @ldap_class = Class.new(Puppet::Indirector::Ldap) do
- def self.to_s
- "Testing::Mytype"
- end
- end
-
- @connection = mock 'ldap'
-
- @searcher = @ldap_class.new
+ before do
+ @indirection = stub 'indirection', :name => :testing
+ Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
+ @ldap_class = Class.new(Puppet::Indirector::Ldap) do
+ def self.to_s
+ "Testing::Mytype"
+ end
end
- describe "when searching ldap" do
- before do
- # Stub everything, and we can selectively replace with an expect as
- # we need to for testing.
- @searcher.stubs(:connection).returns(@connection)
- @searcher.stubs(:search_filter).returns(:filter)
- @searcher.stubs(:search_base).returns(:base)
- @searcher.stubs(:process)
+ @connection = mock 'ldap'
- @request = stub 'request', :key => "yay"
- end
+ @searcher = @ldap_class.new
+ end
- it "should call the ldapsearch method with the search filter" do
- @searcher.expects(:search_filter).with("yay").returns("yay's filter")
- @searcher.expects(:ldapsearch).with("yay's filter")
- @searcher.find @request
- end
+ describe "when searching ldap" do
+ before do
+ # Stub everything, and we can selectively replace with an expect as
+ # we need to for testing.
+ @searcher.stubs(:connection).returns(@connection)
+ @searcher.stubs(:search_filter).returns(:filter)
+ @searcher.stubs(:search_base).returns(:base)
+ @searcher.stubs(:process)
+
+ @request = stub 'request', :key => "yay"
+ end
- it "should fail if no block is passed to the ldapsearch method" do
- proc { @searcher.ldapsearch("blah") }.should raise_error(ArgumentError)
- end
+ it "should call the ldapsearch method with the search filter" do
+ @searcher.expects(:search_filter).with("yay").returns("yay's filter")
+ @searcher.expects(:ldapsearch).with("yay's filter")
+ @searcher.find @request
+ end
- it "should use the results of the ldapbase method as the ldap search base" do
- @searcher.stubs(:search_base).returns("mybase")
- @connection.expects(:search).with do |*args|
- args[0].should == "mybase"
- true
- end
- @searcher.find @request
- end
+ it "should fail if no block is passed to the ldapsearch method" do
+ proc { @searcher.ldapsearch("blah") }.should raise_error(ArgumentError)
+ end
- it "should default to the value of the :search_base setting as the result of the ldapbase method" do
- Puppet.expects(:[]).with(:ldapbase).returns("myldapbase")
- searcher = @ldap_class.new
- searcher.search_base.should == "myldapbase"
- end
+ it "should use the results of the ldapbase method as the ldap search base" do
+ @searcher.stubs(:search_base).returns("mybase")
+ @connection.expects(:search).with do |*args|
+ args[0].should == "mybase"
+ true
+ end
+ @searcher.find @request
+ end
- it "should use the results of the :search_attributes method as the list of attributes to return" do
- @searcher.stubs(:search_attributes).returns(:myattrs)
- @connection.expects(:search).with do |*args|
- args[3].should == :myattrs
- true
- end
- @searcher.find @request
- end
+ it "should default to the value of the :search_base setting as the result of the ldapbase method" do
+ Puppet.expects(:[]).with(:ldapbase).returns("myldapbase")
+ searcher = @ldap_class.new
+ searcher.search_base.should == "myldapbase"
+ end
- it "should use depth 2 when searching" do
- @connection.expects(:search).with do |*args|
- args[1].should == 2
- true
- end
- @searcher.find @request
- end
+ it "should use the results of the :search_attributes method as the list of attributes to return" do
+ @searcher.stubs(:search_attributes).returns(:myattrs)
+ @connection.expects(:search).with do |*args|
+ args[3].should == :myattrs
+ true
+ end
+ @searcher.find @request
+ end
- it "should call process() on the first found entry" do
- @connection.expects(:search).yields("myresult")
- @searcher.expects(:process).with("myresult")
- @searcher.find @request
- end
+ it "should use depth 2 when searching" do
+ @connection.expects(:search).with do |*args|
+ args[1].should == 2
+ true
+ end
+ @searcher.find @request
+ end
- it "should reconnect and retry the search if there is a failure" do
- run = false
- @connection.stubs(:search).with do |*args|
- if run
- true
- else
- run = true
- raise "failed"
- end
- end.yields("myresult")
- @searcher.expects(:process).with("myresult")
-
- @searcher.find @request
- end
+ it "should call process() on the first found entry" do
+ @connection.expects(:search).yields("myresult")
+ @searcher.expects(:process).with("myresult")
+ @searcher.find @request
+ end
- it "should not reconnect on failure more than once" do
- count = 0
- @connection.stubs(:search).with do |*args|
- count += 1
- raise ArgumentError, "yay"
- end
- proc { @searcher.find(@request) }.should raise_error(Puppet::Error)
- count.should == 2
+ it "should reconnect and retry the search if there is a failure" do
+ run = false
+ @connection.stubs(:search).with do |*args|
+ if run
+ true
+ else
+ run = true
+ raise "failed"
end
+ end.yields("myresult")
+ @searcher.expects(:process).with("myresult")
- it "should return true if an entry is found" do
- @connection.expects(:search).yields("result")
- @searcher.ldapsearch("whatever") { |r| }.should be_true
- end
+ @searcher.find @request
end
- describe "when connecting to ldap" do
- confine "LDAP is not available" => Puppet.features.ldap?
+ it "should not reconnect on failure more than once" do
+ count = 0
+ @connection.stubs(:search).with do |*args|
+ count += 1
+ raise ArgumentError, "yay"
+ end
+ proc { @searcher.find(@request) }.should raise_error(Puppet::Error)
+ count.should == 2
+ end
- it "should create and start a Util::Ldap::Connection instance" do
- conn = mock 'connection', :connection => "myconn", :start => nil
- Puppet::Util::Ldap::Connection.expects(:instance).returns conn
+ it "should return true if an entry is found" do
+ @connection.expects(:search).yields("result")
+ @searcher.ldapsearch("whatever") { |r| }.should be_true
+ end
+ end
- @searcher.connection.should == "myconn"
- end
+ describe "when connecting to ldap" do
+ confine "LDAP is not available" => Puppet.features.ldap?
- it "should only create the ldap connection when asked for it the first time" do
- conn = mock 'connection', :connection => "myconn", :start => nil
- Puppet::Util::Ldap::Connection.expects(:instance).returns conn
+ it "should create and start a Util::Ldap::Connection instance" do
+ conn = mock 'connection', :connection => "myconn", :start => nil
+ Puppet::Util::Ldap::Connection.expects(:instance).returns conn
- @searcher.connection
- end
+ @searcher.connection.should == "myconn"
+ end
- it "should cache the connection" do
- conn = mock 'connection', :connection => "myconn", :start => nil
- Puppet::Util::Ldap::Connection.expects(:instance).returns conn
+ it "should only create the ldap connection when asked for it the first time" do
+ conn = mock 'connection', :connection => "myconn", :start => nil
+ Puppet::Util::Ldap::Connection.expects(:instance).returns conn
- @searcher.connection.should equal(@searcher.connection)
- end
+ @searcher.connection
end
- describe "when reconnecting to ldap" do
- confine "Not running on culain as root" => (Puppet.features.root? and Facter.value("hostname") == "culain")
+ it "should cache the connection" do
+ conn = mock 'connection', :connection => "myconn", :start => nil
+ Puppet::Util::Ldap::Connection.expects(:instance).returns conn
- it "should reconnect to ldap when connections are lost"
+ @searcher.connection.should equal(@searcher.connection)
end
+ end
+
+ describe "when reconnecting to ldap" do
+ confine "Not running on culain as root" => (Puppet.features.root? and Facter.value("hostname") == "culain")
+
+ it "should reconnect to ldap when connections are lost"
+ end
end
diff --git a/spec/unit/indirector/memory_spec.rb b/spec/unit/indirector/memory_spec.rb
index 3b754a1..160b4f9 100755
--- a/spec/unit/indirector/memory_spec.rb
+++ b/spec/unit/indirector/memory_spec.rb
@@ -6,24 +6,24 @@ require 'puppet/indirector/memory'
require 'shared_behaviours/memory_terminus'
describe Puppet::Indirector::Memory do
- it_should_behave_like "A Memory Terminus"
+ it_should_behave_like "A Memory Terminus"
- before do
- Puppet::Indirector::Terminus.stubs(:register_terminus_class)
- @model = mock 'model'
- @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model
- Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
+ before do
+ Puppet::Indirector::Terminus.stubs(:register_terminus_class)
+ @model = mock 'model'
+ @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model
+ Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
- @memory_class = Class.new(Puppet::Indirector::Memory) do
- def self.to_s
- "Mystuff::Testing"
- end
- end
+ @memory_class = Class.new(Puppet::Indirector::Memory) do
+ def self.to_s
+ "Mystuff::Testing"
+ end
+ end
- @searcher = @memory_class.new
- @name = "me"
- @instance = stub 'instance', :name => @name
+ @searcher = @memory_class.new
+ @name = "me"
+ @instance = stub 'instance', :name => @name
- @request = stub 'request', :key => @name, :instance => @instance
- end
+ @request = stub 'request', :key => @name, :instance => @instance
+ end
end
diff --git a/spec/unit/indirector/node/active_record_spec.rb b/spec/unit/indirector/node/active_record_spec.rb
index 8e7d1d6..6cc3f51 100755
--- a/spec/unit/indirector/node/active_record_spec.rb
+++ b/spec/unit/indirector/node/active_record_spec.rb
@@ -6,36 +6,36 @@ require 'puppet/node'
require 'spec/lib/puppet_spec/files.rb'
describe "Puppet::Node::ActiveRecord" do
- include PuppetSpec::Files
+ include PuppetSpec::Files
- confine "Missing Rails" => Puppet.features.rails?
- confine "Missing sqlite" => Puppet.features.sqlite?
- before do
- require 'puppet/indirector/node/active_record'
- end
+ confine "Missing Rails" => Puppet.features.rails?
+ confine "Missing sqlite" => Puppet.features.sqlite?
+ before do
+ require 'puppet/indirector/node/active_record'
+ end
- it "should be a subclass of the ActiveRecord terminus class" do
- Puppet::Node::ActiveRecord.ancestors.should be_include(Puppet::Indirector::ActiveRecord)
- end
+ it "should be a subclass of the ActiveRecord terminus class" do
+ Puppet::Node::ActiveRecord.ancestors.should be_include(Puppet::Indirector::ActiveRecord)
+ end
- it "should use Puppet::Rails::Host as its ActiveRecord model" do
- Puppet::Node::ActiveRecord.ar_model.should equal(Puppet::Rails::Host)
- end
+ it "should use Puppet::Rails::Host as its ActiveRecord model" do
+ Puppet::Node::ActiveRecord.ar_model.should equal(Puppet::Rails::Host)
+ end
- it "should call fact_merge when a node is found" do
- db_instance = stub 'db_instance'
- Puppet::Node::ActiveRecord.ar_model.expects(:find_by_name).returns db_instance
+ it "should call fact_merge when a node is found" do
+ db_instance = stub 'db_instance'
+ Puppet::Node::ActiveRecord.ar_model.expects(:find_by_name).returns db_instance
- node = Puppet::Node.new("foo")
- db_instance.expects(:to_puppet).returns node
+ node = Puppet::Node.new("foo")
+ db_instance.expects(:to_puppet).returns node
- Puppet[:statedir] = tmpdir('active_record_tmp')
- Puppet[:railslog] = '$statedir/rails.log'
- ar = Puppet::Node::ActiveRecord.new
+ Puppet[:statedir] = tmpdir('active_record_tmp')
+ Puppet[:railslog] = '$statedir/rails.log'
+ ar = Puppet::Node::ActiveRecord.new
- node.expects(:fact_merge)
+ node.expects(:fact_merge)
- request = Puppet::Indirector::Request.new(:node, :find, "what.ever")
- ar.find(request)
- end
+ request = Puppet::Indirector::Request.new(:node, :find, "what.ever")
+ ar.find(request)
+ end
end
diff --git a/spec/unit/indirector/node/exec_spec.rb b/spec/unit/indirector/node/exec_spec.rb
index c4b3417..d5299ad 100755
--- a/spec/unit/indirector/node/exec_spec.rb
+++ b/spec/unit/indirector/node/exec_spec.rb
@@ -5,65 +5,65 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/node/exec'
describe Puppet::Node::Exec do
- before do
- @indirection = mock 'indirection'
- Puppet.settings.stubs(:value).with(:external_nodes).returns("/echo")
- @searcher = Puppet::Node::Exec.new
- end
+ before do
+ @indirection = mock 'indirection'
+ Puppet.settings.stubs(:value).with(:external_nodes).returns("/echo")
+ @searcher = Puppet::Node::Exec.new
+ end
- describe "when constructing the command to run" do
- it "should use the external_node script as the command" do
- Puppet.expects(:[]).with(:external_nodes).returns("/bin/echo")
- @searcher.command.should == %w{/bin/echo}
- end
+ describe "when constructing the command to run" do
+ it "should use the external_node script as the command" do
+ Puppet.expects(:[]).with(:external_nodes).returns("/bin/echo")
+ @searcher.command.should == %w{/bin/echo}
+ end
- it "should throw an exception if no external node command is set" do
- Puppet.expects(:[]).with(:external_nodes).returns("none")
- proc { @searcher.find(stub('request', :key => "foo")) }.should raise_error(ArgumentError)
- end
+ it "should throw an exception if no external node command is set" do
+ Puppet.expects(:[]).with(:external_nodes).returns("none")
+ proc { @searcher.find(stub('request', :key => "foo")) }.should raise_error(ArgumentError)
end
+ end
- describe "when handling the results of the command" do
- before do
- @node = stub 'node', :fact_merge => nil
- @name = "yay"
- Puppet::Node.expects(:new).with(@name).returns(@node)
- @result = {}
- # Use a local variable so the reference is usable in the execute definition.
- result = @result
- @searcher.meta_def(:execute) do |command|
- return YAML.dump(result)
- end
+ describe "when handling the results of the command" do
+ before do
+ @node = stub 'node', :fact_merge => nil
+ @name = "yay"
+ Puppet::Node.expects(:new).with(@name).returns(@node)
+ @result = {}
+ # Use a local variable so the reference is usable in the execute definition.
+ result = @result
+ @searcher.meta_def(:execute) do |command|
+ return YAML.dump(result)
+ end
- @request = stub 'request', :key => @name
- end
+ @request = stub 'request', :key => @name
+ end
- it "should translate the YAML into a Node instance" do
- # Use an empty hash
- @searcher.find(@request).should equal(@node)
- end
+ it "should translate the YAML into a Node instance" do
+ # Use an empty hash
+ @searcher.find(@request).should equal(@node)
+ end
- it "should set the resulting parameters as the node parameters" do
- @result[:parameters] = {"a" => "b", "c" => "d"}
- @node.expects(:parameters=).with "a" => "b", "c" => "d"
- @searcher.find(@request)
- end
+ it "should set the resulting parameters as the node parameters" do
+ @result[:parameters] = {"a" => "b", "c" => "d"}
+ @node.expects(:parameters=).with "a" => "b", "c" => "d"
+ @searcher.find(@request)
+ end
- it "should set the resulting classes as the node classes" do
- @result[:classes] = %w{one two}
- @node.expects(:classes=).with %w{one two}
- @searcher.find(@request)
- end
+ it "should set the resulting classes as the node classes" do
+ @result[:classes] = %w{one two}
+ @node.expects(:classes=).with %w{one two}
+ @searcher.find(@request)
+ end
- it "should merge the node's facts with its parameters" do
- @node.expects(:fact_merge)
- @searcher.find(@request)
- end
+ it "should merge the node's facts with its parameters" do
+ @node.expects(:fact_merge)
+ @searcher.find(@request)
+ end
- it "should set the node's environment if one is provided" do
- @result[:environment] = "yay"
- @node.expects(:environment=).with "yay"
- @searcher.find(@request)
- end
+ it "should set the node's environment if one is provided" do
+ @result[:environment] = "yay"
+ @node.expects(:environment=).with "yay"
+ @searcher.find(@request)
end
+ end
end
diff --git a/spec/unit/indirector/node/ldap_spec.rb b/spec/unit/indirector/node/ldap_spec.rb
index aef623f..f9c5efa 100755
--- a/spec/unit/indirector/node/ldap_spec.rb
+++ b/spec/unit/indirector/node/ldap_spec.rb
@@ -5,452 +5,452 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/node/ldap'
describe Puppet::Node::Ldap do
- before do
- Puppet::Node::Facts.stubs(:terminus_class).returns :yaml
- end
-
- describe "when searching for a single node" do
- before :each do
- @searcher = Puppet::Node::Ldap.new
-
- @name = "mynode.domain.com"
- @node = stub 'node', :name => @name, :name= => nil
- @node.stub_everything
-
- Puppet::Node.stubs(:new).returns(@node)
-
- @request = stub 'request', :key => @name
- end
-
- it "should convert the hostname into a search filter" do
- entry = stub 'entry', :dn => 'cn=mynode.domain.com,ou=hosts,dc=madstop,dc=com', :vals => %w{}, :to_hash => {"environment" => 'production'}
- @searcher.expects(:ldapsearch).with("(&(objectclass=puppetClient)(cn=#{@name}))").yields entry
- @searcher.name2hash(@name, 'production', 'parent')
- end
-
- it "should convert any found entry into a hash" do
- entry = stub 'entry', :dn => 'cn=mynode.domain.com,ou=hosts,dc=madstop,dc=com', :vals => %w{}, :to_hash => {"environment" => 'production'}
- @searcher.expects(:ldapsearch).with("(&(objectclass=puppetClient)(cn=#{@name}))").yields entry
- myhash = {"myhash" => true, :environment => 'production'}
- @searcher.expects(:entry2hash).with(entry).returns myhash
- @searcher.name2hash(@name, 'production', 'parent').should == myhash
- end
-
- # This heavily tests our entry2hash method, so we don't have to stub out the stupid entry information any more.
- describe "when an ldap entry is found" do
- before do
- @entry = stub 'entry', :dn => 'cn=mynode,ou=hosts,dc=madstop,dc=com', :vals => %w{}, :to_hash => {}
- @searcher.stubs(:ldapsearch).yields @entry
- end
-
- it "should convert the entry to a hash" do
- @searcher.entry2hash(@entry).should be_instance_of(Hash)
- end
-
- it "should add the entry's common name to the hash if fqdn if false" do
- @searcher.entry2hash(@entry,fqdn = false)[:name].should == "mynode"
- end
-
- it "should add the entry's fqdn name to the hash if fqdn if true" do
- @searcher.entry2hash(@entry,fqdn = true)[:name].should == "mynode.madstop.com"
- end
-
- it "should add all of the entry's classes to the hash" do
- @entry.stubs(:vals).with("puppetclass").returns %w{one two}
- @searcher.entry2hash(@entry)[:classes].should == %w{one two}
- end
-
- it "should deduplicate class values" do
- @entry.stubs(:to_hash).returns({})
- @searcher.stubs(:class_attributes).returns(%w{one two})
- @entry.stubs(:vals).with("one").returns(%w{a b})
- @entry.stubs(:vals).with("two").returns(%w{b c})
- @searcher.entry2hash(@entry)[:classes].should == %w{a b c}
- end
-
- it "should add the entry's environment to the hash" do
- @entry.stubs(:to_hash).returns("environment" => %w{production})
- @searcher.entry2hash(@entry)[:environment].should == "production"
- end
-
- it "should add all stacked parameters as parameters in the hash" do
- @entry.stubs(:vals).with("puppetvar").returns(%w{one=two three=four})
- result = @searcher.entry2hash(@entry)
- result[:parameters]["one"].should == "two"
- result[:parameters]["three"].should == "four"
- end
-
- it "should not add the stacked parameter as a normal parameter" do
- @entry.stubs(:vals).with("puppetvar").returns(%w{one=two three=four})
- @entry.stubs(:to_hash).returns("puppetvar" => %w{one=two three=four})
- @searcher.entry2hash(@entry)[:parameters]["puppetvar"].should be_nil
- end
-
- it "should add all other attributes as parameters in the hash" do
- @entry.stubs(:to_hash).returns("foo" => %w{one two})
- @searcher.entry2hash(@entry)[:parameters]["foo"].should == %w{one two}
- end
-
- it "should return single-value parameters as strings, not arrays" do
- @entry.stubs(:to_hash).returns("foo" => %w{one})
- @searcher.entry2hash(@entry)[:parameters]["foo"].should == "one"
- end
-
- it "should convert 'true' values to the boolean 'true'" do
- @entry.stubs(:to_hash).returns({"one" => ["true"]})
- @searcher.entry2hash(@entry)[:parameters]["one"].should == true
- end
-
- it "should convert 'false' values to the boolean 'false'" do
- @entry.stubs(:to_hash).returns({"one" => ["false"]})
- @searcher.entry2hash(@entry)[:parameters]["one"].should == false
- end
-
- it "should convert 'true' values to the boolean 'true' inside an array" do
- @entry.stubs(:to_hash).returns({"one" => ["true", "other"]})
- @searcher.entry2hash(@entry)[:parameters]["one"].should == [true, "other"]
- end
-
- it "should convert 'false' values to the boolean 'false' inside an array" do
- @entry.stubs(:to_hash).returns({"one" => ["false", "other"]})
- @searcher.entry2hash(@entry)[:parameters]["one"].should == [false, "other"]
- end
-
- it "should add the parent's name if present" do
- @entry.stubs(:vals).with("parentnode").returns(%w{foo})
- @searcher.entry2hash(@entry)[:parent].should == "foo"
- end
-
- it "should fail if more than one parent is specified" do
- @entry.stubs(:vals).with("parentnode").returns(%w{foo})
- @searcher.entry2hash(@entry)[:parent].should == "foo"
- end
- end
-
- it "should search first for the provided key" do
- @searcher.expects(:name2hash).with("mynode.domain.com", 'production', 'child').returns({})
- @searcher.find(@request)
- end
-
- it "should search for the short version of the provided key if the key looks like a hostname and no results are found for the key itself" do
- @searcher.expects(:name2hash).with("mynode.domain.com", 'production', 'child').returns(nil)
- @searcher.expects(:name2hash).with("mynode", 'production', 'child').returns({})
- @searcher.find(@request)
- end
-
- it "should search for default information if no information can be found for the key" do
- @searcher.expects(:name2hash).with("mynode.domain.com", 'production', 'child').returns(nil)
- @searcher.expects(:name2hash).with("mynode", 'production', 'child').returns(nil)
- @searcher.expects(:name2hash).with("default", 'production', 'child').returns({})
- @searcher.find(@request)
- end
-
- it "should return nil if no results are found in ldap" do
- @searcher.stubs(:name2hash).returns nil
- @searcher.find(@request).should be_nil
- end
-
- it "should return a node object if results are found in ldap" do
- @searcher.stubs(:name2hash).returns({})
- @searcher.find(@request).should equal(@node)
- end
-
- describe "and node information is found in LDAP" do
- before do
- @result = {}
- @searcher.stubs(:name2hash).returns @result
- end
-
- it "should create the node with the correct name, even if it was found by a different name" do
- @searcher.expects(:name2hash).with("mynode.domain.com", 'production', 'child').returns nil
- @searcher.expects(:name2hash).with("mynode", 'production', 'child').returns @result
-
- Puppet::Node.expects(:new).with("mynode.domain.com").returns @node
- @searcher.find(@request)
- end
-
- it "should add any classes from ldap" do
- @result[:classes] = %w{a b c d}
- @node.expects(:classes=).with(%w{a b c d})
- @searcher.find(@request)
- end
+ before do
+ Puppet::Node::Facts.stubs(:terminus_class).returns :yaml
+ end
- it "should add all entry attributes as node parameters" do
- @result[:parameters] = {"one" => "two", "three" => "four"}
- @node.expects(:parameters=).with("one" => "two", "three" => "four")
- @searcher.find(@request)
- end
+ describe "when searching for a single node" do
+ before :each do
+ @searcher = Puppet::Node::Ldap.new
- it "should set the node's environment to the environment of the results" do
- @result[:environment] = "test"
- @node.expects(:environment=).with("test")
- @searcher.find(@request)
- end
+ @name = "mynode.domain.com"
+ @node = stub 'node', :name => @name, :name= => nil
+ @node.stub_everything
- it "should retain false parameter values" do
- @result[:parameters] = {}
- @result[:parameters]["one"] = false
- @node.expects(:parameters=).with("one" => false)
- @searcher.find(@request)
- end
+ Puppet::Node.stubs(:new).returns(@node)
- it "should merge the node's facts after the parameters from ldap are assigned" do
- # Make sure we've got data to start with, so the parameters are actually set.
- @result[:parameters] = {}
- @result[:parameters]["one"] = "yay"
-
- # A hackish way to enforce order.
- set = false
- @node.expects(:parameters=).with { |*args| set = true }
- @node.expects(:fact_merge).with { |*args| raise "Facts were merged before parameters were set" unless set; true }
-
- @searcher.find(@request)
- end
-
- describe "and a parent node is specified" do
- before do
- @entry = {:classes => [], :parameters => {}}
- @parent = {:classes => [], :parameters => {}}
- @parent_parent = {:classes => [], :parameters => {}}
-
- @searcher.stubs(:name2hash).with{|name, env, mode| name == @name}.returns(@entry)
- @searcher.stubs(:name2hash).with{|name, env, mode| name == 'parent'}.returns(@parent)
- @searcher.stubs(:name2hash).with{|name, env, mode| name == 'parent_parent'}.returns(@parent_parent)
-
- @searcher.stubs(:parent_attribute).returns(:parent)
- end
-
- it "should search for the parent node" do
- @entry[:parent] = "parent"
-
- @searcher.find(@request)
- end
+ @request = stub 'request', :key => @name
+ end
- it "should fail if the parent cannot be found" do
- @entry[:parent] = "parent"
+ it "should convert the hostname into a search filter" do
+ entry = stub 'entry', :dn => 'cn=mynode.domain.com,ou=hosts,dc=madstop,dc=com', :vals => %w{}, :to_hash => {"environment" => 'production'}
+ @searcher.expects(:ldapsearch).with("(&(objectclass=puppetClient)(cn=#{@name}))").yields entry
+ @searcher.name2hash(@name, 'production', 'parent')
+ end
- @searcher.expects(:name2hash).with('parent', 'production', 'parent').returns nil
+ it "should convert any found entry into a hash" do
+ entry = stub 'entry', :dn => 'cn=mynode.domain.com,ou=hosts,dc=madstop,dc=com', :vals => %w{}, :to_hash => {"environment" => 'production'}
+ @searcher.expects(:ldapsearch).with("(&(objectclass=puppetClient)(cn=#{@name}))").yields entry
+ myhash = {"myhash" => true, :environment => 'production'}
+ @searcher.expects(:entry2hash).with(entry).returns myhash
+ @searcher.name2hash(@name, 'production', 'parent').should == myhash
+ end
- proc { @searcher.find(@request) }.should raise_error(Puppet::Error)
- end
+ # This heavily tests our entry2hash method, so we don't have to stub out the stupid entry information any more.
+ describe "when an ldap entry is found" do
+ before do
+ @entry = stub 'entry', :dn => 'cn=mynode,ou=hosts,dc=madstop,dc=com', :vals => %w{}, :to_hash => {}
+ @searcher.stubs(:ldapsearch).yields @entry
+ end
+
+ it "should convert the entry to a hash" do
+ @searcher.entry2hash(@entry).should be_instance_of(Hash)
+ end
+
+ it "should add the entry's common name to the hash if fqdn if false" do
+ @searcher.entry2hash(@entry,fqdn = false)[:name].should == "mynode"
+ end
+
+ it "should add the entry's fqdn name to the hash if fqdn if true" do
+ @searcher.entry2hash(@entry,fqdn = true)[:name].should == "mynode.madstop.com"
+ end
+
+ it "should add all of the entry's classes to the hash" do
+ @entry.stubs(:vals).with("puppetclass").returns %w{one two}
+ @searcher.entry2hash(@entry)[:classes].should == %w{one two}
+ end
+
+ it "should deduplicate class values" do
+ @entry.stubs(:to_hash).returns({})
+ @searcher.stubs(:class_attributes).returns(%w{one two})
+ @entry.stubs(:vals).with("one").returns(%w{a b})
+ @entry.stubs(:vals).with("two").returns(%w{b c})
+ @searcher.entry2hash(@entry)[:classes].should == %w{a b c}
+ end
+
+ it "should add the entry's environment to the hash" do
+ @entry.stubs(:to_hash).returns("environment" => %w{production})
+ @searcher.entry2hash(@entry)[:environment].should == "production"
+ end
+
+ it "should add all stacked parameters as parameters in the hash" do
+ @entry.stubs(:vals).with("puppetvar").returns(%w{one=two three=four})
+ result = @searcher.entry2hash(@entry)
+ result[:parameters]["one"].should == "two"
+ result[:parameters]["three"].should == "four"
+ end
+
+ it "should not add the stacked parameter as a normal parameter" do
+ @entry.stubs(:vals).with("puppetvar").returns(%w{one=two three=four})
+ @entry.stubs(:to_hash).returns("puppetvar" => %w{one=two three=four})
+ @searcher.entry2hash(@entry)[:parameters]["puppetvar"].should be_nil
+ end
+
+ it "should add all other attributes as parameters in the hash" do
+ @entry.stubs(:to_hash).returns("foo" => %w{one two})
+ @searcher.entry2hash(@entry)[:parameters]["foo"].should == %w{one two}
+ end
+
+ it "should return single-value parameters as strings, not arrays" do
+ @entry.stubs(:to_hash).returns("foo" => %w{one})
+ @searcher.entry2hash(@entry)[:parameters]["foo"].should == "one"
+ end
+
+ it "should convert 'true' values to the boolean 'true'" do
+ @entry.stubs(:to_hash).returns({"one" => ["true"]})
+ @searcher.entry2hash(@entry)[:parameters]["one"].should == true
+ end
+
+ it "should convert 'false' values to the boolean 'false'" do
+ @entry.stubs(:to_hash).returns({"one" => ["false"]})
+ @searcher.entry2hash(@entry)[:parameters]["one"].should == false
+ end
+
+ it "should convert 'true' values to the boolean 'true' inside an array" do
+ @entry.stubs(:to_hash).returns({"one" => ["true", "other"]})
+ @searcher.entry2hash(@entry)[:parameters]["one"].should == [true, "other"]
+ end
+
+ it "should convert 'false' values to the boolean 'false' inside an array" do
+ @entry.stubs(:to_hash).returns({"one" => ["false", "other"]})
+ @searcher.entry2hash(@entry)[:parameters]["one"].should == [false, "other"]
+ end
+
+ it "should add the parent's name if present" do
+ @entry.stubs(:vals).with("parentnode").returns(%w{foo})
+ @searcher.entry2hash(@entry)[:parent].should == "foo"
+ end
+
+ it "should fail if more than one parent is specified" do
+ @entry.stubs(:vals).with("parentnode").returns(%w{foo})
+ @searcher.entry2hash(@entry)[:parent].should == "foo"
+ end
+ end
- it "should add any parent classes to the node's classes" do
- @entry[:parent] = "parent"
- @entry[:classes] = %w{a b}
+ it "should search first for the provided key" do
+ @searcher.expects(:name2hash).with("mynode.domain.com", 'production', 'child').returns({})
+ @searcher.find(@request)
+ end
- @parent[:classes] = %w{c d}
+ it "should search for the short version of the provided key if the key looks like a hostname and no results are found for the key itself" do
+ @searcher.expects(:name2hash).with("mynode.domain.com", 'production', 'child').returns(nil)
+ @searcher.expects(:name2hash).with("mynode", 'production', 'child').returns({})
+ @searcher.find(@request)
+ end
- @node.expects(:classes=).with(%w{a b c d})
- @searcher.find(@request)
- end
+ it "should search for default information if no information can be found for the key" do
+ @searcher.expects(:name2hash).with("mynode.domain.com", 'production', 'child').returns(nil)
+ @searcher.expects(:name2hash).with("mynode", 'production', 'child').returns(nil)
+ @searcher.expects(:name2hash).with("default", 'production', 'child').returns({})
+ @searcher.find(@request)
+ end
- it "should add any parent parameters to the node's parameters" do
- @entry[:parent] = "parent"
- @entry[:parameters]["one"] = "two"
+ it "should return nil if no results are found in ldap" do
+ @searcher.stubs(:name2hash).returns nil
+ @searcher.find(@request).should be_nil
+ end
- @parent[:parameters]["three"] = "four"
+ it "should return a node object if results are found in ldap" do
+ @searcher.stubs(:name2hash).returns({})
+ @searcher.find(@request).should equal(@node)
+ end
- @node.expects(:parameters=).with("one" => "two", "three" => "four")
- @searcher.find(@request)
- end
+ describe "and node information is found in LDAP" do
+ before do
+ @result = {}
+ @searcher.stubs(:name2hash).returns @result
+ end
+
+ it "should create the node with the correct name, even if it was found by a different name" do
+ @searcher.expects(:name2hash).with("mynode.domain.com", 'production', 'child').returns nil
+ @searcher.expects(:name2hash).with("mynode", 'production', 'child').returns @result
+
+ Puppet::Node.expects(:new).with("mynode.domain.com").returns @node
+ @searcher.find(@request)
+ end
+
+ it "should add any classes from ldap" do
+ @result[:classes] = %w{a b c d}
+ @node.expects(:classes=).with(%w{a b c d})
+ @searcher.find(@request)
+ end
+
+ it "should add all entry attributes as node parameters" do
+ @result[:parameters] = {"one" => "two", "three" => "four"}
+ @node.expects(:parameters=).with("one" => "two", "three" => "four")
+ @searcher.find(@request)
+ end
+
+ it "should set the node's environment to the environment of the results" do
+ @result[:environment] = "test"
+ @node.expects(:environment=).with("test")
+ @searcher.find(@request)
+ end
+
+ it "should retain false parameter values" do
+ @result[:parameters] = {}
+ @result[:parameters]["one"] = false
+ @node.expects(:parameters=).with("one" => false)
+ @searcher.find(@request)
+ end
+
+ it "should merge the node's facts after the parameters from ldap are assigned" do
+ # Make sure we've got data to start with, so the parameters are actually set.
+ @result[:parameters] = {}
+ @result[:parameters]["one"] = "yay"
+
+ # A hackish way to enforce order.
+ set = false
+ @node.expects(:parameters=).with { |*args| set = true }
+ @node.expects(:fact_merge).with { |*args| raise "Facts were merged before parameters were set" unless set; true }
+
+ @searcher.find(@request)
+ end
+
+ describe "and a parent node is specified" do
+ before do
+ @entry = {:classes => [], :parameters => {}}
+ @parent = {:classes => [], :parameters => {}}
+ @parent_parent = {:classes => [], :parameters => {}}
+
+ @searcher.stubs(:name2hash).with{|name, env, mode| name == @name}.returns(@entry)
+ @searcher.stubs(:name2hash).with{|name, env, mode| name == 'parent'}.returns(@parent)
+ @searcher.stubs(:name2hash).with{|name, env, mode| name == 'parent_parent'}.returns(@parent_parent)
+
+ @searcher.stubs(:parent_attribute).returns(:parent)
+ end
- it "should prefer node parameters over parent parameters" do
- @entry[:parent] = "parent"
- @entry[:parameters]["one"] = "two"
+ it "should search for the parent node" do
+ @entry[:parent] = "parent"
- @parent[:parameters]["one"] = "three"
+ @searcher.find(@request)
+ end
- @node.expects(:parameters=).with("one" => "two")
- @searcher.find(@request)
- end
+ it "should fail if the parent cannot be found" do
+ @entry[:parent] = "parent"
- it "should use the parent's environment if the node has none" do
- @entry[:parent] = "parent"
+ @searcher.expects(:name2hash).with('parent', 'production', 'parent').returns nil
- @parent[:environment] = "parent"
+ proc { @searcher.find(@request) }.should raise_error(Puppet::Error)
+ end
- @node.stubs(:parameters=)
- @node.expects(:environment=).with("parent")
- @searcher.find(@request)
- end
+ it "should add any parent classes to the node's classes" do
+ @entry[:parent] = "parent"
+ @entry[:classes] = %w{a b}
- it "should prefer the node's environment to the parent's" do
- @entry[:parent] = "parent"
- @entry[:environment] = "child"
+ @parent[:classes] = %w{c d}
- @parent[:environment] = "parent"
+ @node.expects(:classes=).with(%w{a b c d})
+ @searcher.find(@request)
+ end
- @node.stubs(:parameters=)
- @node.expects(:environment=).with("child")
- @searcher.find(@request)
- end
+ it "should add any parent parameters to the node's parameters" do
+ @entry[:parent] = "parent"
+ @entry[:parameters]["one"] = "two"
- it "should recursively look up parent information" do
- @entry[:parent] = "parent"
- @entry[:parameters]["one"] = "two"
+ @parent[:parameters]["three"] = "four"
- @parent[:parent] = "parent_parent"
- @parent[:parameters]["three"] = "four"
+ @node.expects(:parameters=).with("one" => "two", "three" => "four")
+ @searcher.find(@request)
+ end
- @parent_parent[:parameters]["five"] = "six"
+ it "should prefer node parameters over parent parameters" do
+ @entry[:parent] = "parent"
+ @entry[:parameters]["one"] = "two"
- @node.expects(:parameters=).with("one" => "two", "three" => "four", "five" => "six")
- @searcher.find(@request)
- end
+ @parent[:parameters]["one"] = "three"
- it "should not allow loops in parent declarations" do
- @entry[:parent] = "parent"
- @parent[:parent] = @name
- proc { @searcher.find(@request) }.should raise_error(ArgumentError)
- end
- end
+ @node.expects(:parameters=).with("one" => "two")
+ @searcher.find(@request)
end
- end
- describe "when searching for multiple nodes" do
- before :each do
- @searcher = Puppet::Node::Ldap.new
- @options = {}
- @request = stub 'request', :key => "foo", :options => @options
+ it "should use the parent's environment if the node has none" do
+ @entry[:parent] = "parent"
- Puppet::Node::Facts.stubs(:terminus_class).returns :yaml
- end
+ @parent[:environment] = "parent"
- it "should find all nodes if no arguments are provided" do
- @searcher.expects(:ldapsearch).with("(objectclass=puppetClient)")
- # LAK:NOTE The search method requires an essentially bogus key. It's
- # an API problem that I don't really know how to fix.
- @searcher.search @request
+ @node.stubs(:parameters=)
+ @node.expects(:environment=).with("parent")
+ @searcher.find(@request)
end
- describe "and a class is specified" do
- it "should find all nodes that are members of that class" do
- @searcher.expects(:ldapsearch).with("(&(objectclass=puppetClient)(puppetclass=one))")
+ it "should prefer the node's environment to the parent's" do
+ @entry[:parent] = "parent"
+ @entry[:environment] = "child"
- @options[:class] = "one"
- @searcher.search @request
- end
- end
+ @parent[:environment] = "parent"
- describe "multiple classes are specified" do
- it "should find all nodes that are members of all classes" do
- @searcher.expects(:ldapsearch).with("(&(objectclass=puppetClient)(puppetclass=one)(puppetclass=two))")
- @options[:class] = %w{one two}
- @searcher.search @request
- end
+ @node.stubs(:parameters=)
+ @node.expects(:environment=).with("child")
+ @searcher.find(@request)
end
- it "should process each found entry" do
- # .yields can't be used to yield multiple values :/
- @searcher.expects(:ldapsearch).yields("one")
- @searcher.expects(:entry2hash).with("one",nil).returns(:name => "foo")
- @searcher.search @request
- end
+ it "should recursively look up parent information" do
+ @entry[:parent] = "parent"
+ @entry[:parameters]["one"] = "two"
- it "should return a node for each processed entry with the name from the entry" do
- @searcher.expects(:ldapsearch).yields("whatever")
- @searcher.expects(:entry2hash).with("whatever",nil).returns(:name => "foo")
- result = @searcher.search(@request)
- result[0].should be_instance_of(Puppet::Node)
- result[0].name.should == "foo"
- end
+ @parent[:parent] = "parent_parent"
+ @parent[:parameters]["three"] = "four"
- it "should merge each node's facts" do
- node = mock 'node'
- Puppet::Node.expects(:new).with("foo").returns node
- node.expects(:fact_merge)
- @searcher.stubs(:ldapsearch).yields("one")
- @searcher.stubs(:entry2hash).with("one",nil).returns(:name => "foo")
- @searcher.search(@request)
- end
+ @parent_parent[:parameters]["five"] = "six"
- it "should pass the request's fqdn option to entry2hash" do
- node = mock 'node'
- @options[:fqdn] = :hello
- Puppet::Node.stubs(:new).with("foo").returns node
- node.stubs(:fact_merge)
- @searcher.stubs(:ldapsearch).yields("one")
- @searcher.expects(:entry2hash).with("one",:hello).returns(:name => "foo")
- @searcher.search(@request)
+ @node.expects(:parameters=).with("one" => "two", "three" => "four", "five" => "six")
+ @searcher.find(@request)
end
- end
-end
-describe Puppet::Node::Ldap, " when developing the search query" do
- before do
- @searcher = Puppet::Node::Ldap.new
+ it "should not allow loops in parent declarations" do
+ @entry[:parent] = "parent"
+ @parent[:parent] = @name
+ proc { @searcher.find(@request) }.should raise_error(ArgumentError)
+ end
+ end
end
+ end
- it "should return the value of the :ldapclassattrs split on commas as the class attributes" do
- Puppet.stubs(:[]).with(:ldapclassattrs).returns("one,two")
- @searcher.class_attributes.should == %w{one two}
- end
+ describe "when searching for multiple nodes" do
+ before :each do
+ @searcher = Puppet::Node::Ldap.new
+ @options = {}
+ @request = stub 'request', :key => "foo", :options => @options
- it "should return nil as the parent attribute if the :ldapparentattr is set to an empty string" do
- Puppet.stubs(:[]).with(:ldapparentattr).returns("")
- @searcher.parent_attribute.should be_nil
+ Puppet::Node::Facts.stubs(:terminus_class).returns :yaml
end
- it "should return the value of the :ldapparentattr as the parent attribute" do
- Puppet.stubs(:[]).with(:ldapparentattr).returns("pere")
- @searcher.parent_attribute.should == "pere"
+ it "should find all nodes if no arguments are provided" do
+ @searcher.expects(:ldapsearch).with("(objectclass=puppetClient)")
+ # LAK:NOTE The search method requires an essentially bogus key. It's
+ # an API problem that I don't really know how to fix.
+ @searcher.search @request
end
- it "should use the value of the :ldapstring as the search filter" do
- Puppet.stubs(:[]).with(:ldapstring).returns("mystring")
- @searcher.search_filter("testing").should == "mystring"
- end
+ describe "and a class is specified" do
+ it "should find all nodes that are members of that class" do
+ @searcher.expects(:ldapsearch).with("(&(objectclass=puppetClient)(puppetclass=one))")
- it "should replace '%s' with the node name in the search filter if it is present" do
- Puppet.stubs(:[]).with(:ldapstring).returns("my%sstring")
- @searcher.search_filter("testing").should == "mytestingstring"
+ @options[:class] = "one"
+ @searcher.search @request
+ end
end
- it "should not modify the global :ldapstring when replacing '%s' in the search filter" do
- filter = mock 'filter'
- filter.expects(:include?).with("%s").returns(true)
- filter.expects(:gsub).with("%s", "testing").returns("mynewstring")
- Puppet.stubs(:[]).with(:ldapstring).returns(filter)
- @searcher.search_filter("testing").should == "mynewstring"
+ describe "multiple classes are specified" do
+ it "should find all nodes that are members of all classes" do
+ @searcher.expects(:ldapsearch).with("(&(objectclass=puppetClient)(puppetclass=one)(puppetclass=two))")
+ @options[:class] = %w{one two}
+ @searcher.search @request
+ end
end
-end
-describe Puppet::Node::Ldap, " when deciding attributes to search for" do
- before do
- @searcher = Puppet::Node::Ldap.new
+ it "should process each found entry" do
+ # .yields can't be used to yield multiple values :/
+ @searcher.expects(:ldapsearch).yields("one")
+ @searcher.expects(:entry2hash).with("one",nil).returns(:name => "foo")
+ @searcher.search @request
end
- it "should use 'nil' if the :ldapattrs setting is 'all'" do
- Puppet.stubs(:[]).with(:ldapattrs).returns("all")
- @searcher.search_attributes.should be_nil
+ it "should return a node for each processed entry with the name from the entry" do
+ @searcher.expects(:ldapsearch).yields("whatever")
+ @searcher.expects(:entry2hash).with("whatever",nil).returns(:name => "foo")
+ result = @searcher.search(@request)
+ result[0].should be_instance_of(Puppet::Node)
+ result[0].name.should == "foo"
end
- it "should split the value of :ldapattrs on commas and use the result as the attribute list" do
- Puppet.stubs(:[]).with(:ldapattrs).returns("one,two")
- @searcher.stubs(:class_attributes).returns([])
- @searcher.stubs(:parent_attribute).returns(nil)
- @searcher.search_attributes.should == %w{one two}
+ it "should merge each node's facts" do
+ node = mock 'node'
+ Puppet::Node.expects(:new).with("foo").returns node
+ node.expects(:fact_merge)
+ @searcher.stubs(:ldapsearch).yields("one")
+ @searcher.stubs(:entry2hash).with("one",nil).returns(:name => "foo")
+ @searcher.search(@request)
end
- it "should add the class attributes to the search attributes if not returning all attributes" do
- Puppet.stubs(:[]).with(:ldapattrs).returns("one,two")
- @searcher.stubs(:class_attributes).returns(%w{three four})
- @searcher.stubs(:parent_attribute).returns(nil)
- # Sort them so i don't have to care about return order
- @searcher.search_attributes.sort.should == %w{one two three four}.sort
+ it "should pass the request's fqdn option to entry2hash" do
+ node = mock 'node'
+ @options[:fqdn] = :hello
+ Puppet::Node.stubs(:new).with("foo").returns node
+ node.stubs(:fact_merge)
+ @searcher.stubs(:ldapsearch).yields("one")
+ @searcher.expects(:entry2hash).with("one",:hello).returns(:name => "foo")
+ @searcher.search(@request)
end
+ end
+end
- it "should add the parent attribute to the search attributes if not returning all attributes" do
- Puppet.stubs(:[]).with(:ldapattrs).returns("one,two")
- @searcher.stubs(:class_attributes).returns([])
- @searcher.stubs(:parent_attribute).returns("parent")
- @searcher.search_attributes.sort.should == %w{one two parent}.sort
- end
+describe Puppet::Node::Ldap, " when developing the search query" do
+ before do
+ @searcher = Puppet::Node::Ldap.new
+ end
+
+ it "should return the value of the :ldapclassattrs split on commas as the class attributes" do
+ Puppet.stubs(:[]).with(:ldapclassattrs).returns("one,two")
+ @searcher.class_attributes.should == %w{one two}
+ end
+
+ it "should return nil as the parent attribute if the :ldapparentattr is set to an empty string" do
+ Puppet.stubs(:[]).with(:ldapparentattr).returns("")
+ @searcher.parent_attribute.should be_nil
+ end
+
+ it "should return the value of the :ldapparentattr as the parent attribute" do
+ Puppet.stubs(:[]).with(:ldapparentattr).returns("pere")
+ @searcher.parent_attribute.should == "pere"
+ end
+
+ it "should use the value of the :ldapstring as the search filter" do
+ Puppet.stubs(:[]).with(:ldapstring).returns("mystring")
+ @searcher.search_filter("testing").should == "mystring"
+ end
+
+ it "should replace '%s' with the node name in the search filter if it is present" do
+ Puppet.stubs(:[]).with(:ldapstring).returns("my%sstring")
+ @searcher.search_filter("testing").should == "mytestingstring"
+ end
+
+ it "should not modify the global :ldapstring when replacing '%s' in the search filter" do
+ filter = mock 'filter'
+ filter.expects(:include?).with("%s").returns(true)
+ filter.expects(:gsub).with("%s", "testing").returns("mynewstring")
+ Puppet.stubs(:[]).with(:ldapstring).returns(filter)
+ @searcher.search_filter("testing").should == "mynewstring"
+ end
+end
- it "should not add nil parent attributes to the search attributes" do
- Puppet.stubs(:[]).with(:ldapattrs).returns("one,two")
- @searcher.stubs(:class_attributes).returns([])
- @searcher.stubs(:parent_attribute).returns(nil)
- @searcher.search_attributes.should == %w{one two}
- end
+describe Puppet::Node::Ldap, " when deciding attributes to search for" do
+ before do
+ @searcher = Puppet::Node::Ldap.new
+ end
+
+ it "should use 'nil' if the :ldapattrs setting is 'all'" do
+ Puppet.stubs(:[]).with(:ldapattrs).returns("all")
+ @searcher.search_attributes.should be_nil
+ end
+
+ it "should split the value of :ldapattrs on commas and use the result as the attribute list" do
+ Puppet.stubs(:[]).with(:ldapattrs).returns("one,two")
+ @searcher.stubs(:class_attributes).returns([])
+ @searcher.stubs(:parent_attribute).returns(nil)
+ @searcher.search_attributes.should == %w{one two}
+ end
+
+ it "should add the class attributes to the search attributes if not returning all attributes" do
+ Puppet.stubs(:[]).with(:ldapattrs).returns("one,two")
+ @searcher.stubs(:class_attributes).returns(%w{three four})
+ @searcher.stubs(:parent_attribute).returns(nil)
+ # Sort them so i don't have to care about return order
+ @searcher.search_attributes.sort.should == %w{one two three four}.sort
+ end
+
+ it "should add the parent attribute to the search attributes if not returning all attributes" do
+ Puppet.stubs(:[]).with(:ldapattrs).returns("one,two")
+ @searcher.stubs(:class_attributes).returns([])
+ @searcher.stubs(:parent_attribute).returns("parent")
+ @searcher.search_attributes.sort.should == %w{one two parent}.sort
+ end
+
+ it "should not add nil parent attributes to the search attributes" do
+ Puppet.stubs(:[]).with(:ldapattrs).returns("one,two")
+ @searcher.stubs(:class_attributes).returns([])
+ @searcher.stubs(:parent_attribute).returns(nil)
+ @searcher.search_attributes.should == %w{one two}
+ end
end
diff --git a/spec/unit/indirector/node/memory_spec.rb b/spec/unit/indirector/node/memory_spec.rb
index 71e01d4..3f1fdb9 100755
--- a/spec/unit/indirector/node/memory_spec.rb
+++ b/spec/unit/indirector/node/memory_spec.rb
@@ -7,13 +7,13 @@ require 'puppet/indirector/node/memory'
require 'shared_behaviours/memory_terminus'
describe Puppet::Node::Memory do
- before do
- @name = "me"
- @searcher = Puppet::Node::Memory.new
- @instance = stub 'instance', :name => @name
+ before do
+ @name = "me"
+ @searcher = Puppet::Node::Memory.new
+ @instance = stub 'instance', :name => @name
- @request = stub 'request', :key => @name, :instance => @instance
- end
+ @request = stub 'request', :key => @name, :instance => @instance
+ end
- it_should_behave_like "A Memory Terminus"
+ it_should_behave_like "A Memory Terminus"
end
diff --git a/spec/unit/indirector/node/plain_spec.rb b/spec/unit/indirector/node/plain_spec.rb
index a595998..7300862 100755
--- a/spec/unit/indirector/node/plain_spec.rb
+++ b/spec/unit/indirector/node/plain_spec.rb
@@ -5,15 +5,15 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/node/plain'
describe Puppet::Node::Plain do
- before do
- @searcher = Puppet::Node::Plain.new
- end
+ before do
+ @searcher = Puppet::Node::Plain.new
+ end
- it "should call node_merge() on the returned node" do
- node = mock 'node'
- Puppet::Node.expects(:new).with("mynode").returns(node)
- node.expects(:fact_merge)
- request = stub 'request', :key => "mynode"
- @searcher.find(request)
- end
+ it "should call node_merge() on the returned node" do
+ node = mock 'node'
+ Puppet::Node.expects(:new).with("mynode").returns(node)
+ node.expects(:fact_merge)
+ request = stub 'request', :key => "mynode"
+ @searcher.find(request)
+ end
end
diff --git a/spec/unit/indirector/node/rest_spec.rb b/spec/unit/indirector/node/rest_spec.rb
index c00bb98..0b20752 100755
--- a/spec/unit/indirector/node/rest_spec.rb
+++ b/spec/unit/indirector/node/rest_spec.rb
@@ -5,9 +5,9 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/node/rest'
describe Puppet::Node::Rest do
- before do
- @searcher = Puppet::Node::Rest.new
- end
+ before do
+ @searcher = Puppet::Node::Rest.new
+ end
end
diff --git a/spec/unit/indirector/node/yaml_spec.rb b/spec/unit/indirector/node/yaml_spec.rb
index 2e6c14c..8e19a12 100755
--- a/spec/unit/indirector/node/yaml_spec.rb
+++ b/spec/unit/indirector/node/yaml_spec.rb
@@ -6,20 +6,20 @@ require 'puppet/node'
require 'puppet/indirector/node/yaml'
describe Puppet::Node::Yaml do
- it "should be a subclass of the Yaml terminus" do
- Puppet::Node::Yaml.superclass.should equal(Puppet::Indirector::Yaml)
- end
+ it "should be a subclass of the Yaml terminus" do
+ Puppet::Node::Yaml.superclass.should equal(Puppet::Indirector::Yaml)
+ end
- it "should have documentation" do
- Puppet::Node::Yaml.doc.should_not be_nil
- end
+ it "should have documentation" do
+ Puppet::Node::Yaml.doc.should_not be_nil
+ end
- it "should be registered with the configuration store indirection" do
- indirection = Puppet::Indirector::Indirection.instance(:node)
- Puppet::Node::Yaml.indirection.should equal(indirection)
- end
+ it "should be registered with the configuration store indirection" do
+ indirection = Puppet::Indirector::Indirection.instance(:node)
+ Puppet::Node::Yaml.indirection.should equal(indirection)
+ end
- it "should have its name set to :node" do
- Puppet::Node::Yaml.name.should == :yaml
- end
+ it "should have its name set to :node" do
+ Puppet::Node::Yaml.name.should == :yaml
+ end
end
diff --git a/spec/unit/indirector/plain_spec.rb b/spec/unit/indirector/plain_spec.rb
index aca2816..2fb9e4d 100755
--- a/spec/unit/indirector/plain_spec.rb
+++ b/spec/unit/indirector/plain_spec.rb
@@ -4,26 +4,26 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector/plain'
describe Puppet::Indirector::Plain do
- before do
- Puppet::Indirector::Terminus.stubs(:register_terminus_class)
- @model = mock 'model'
- @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model
- Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
+ before do
+ Puppet::Indirector::Terminus.stubs(:register_terminus_class)
+ @model = mock 'model'
+ @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model
+ Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
- @plain_class = Class.new(Puppet::Indirector::Plain) do
- def self.to_s
- "Mystuff::Testing"
- end
- end
+ @plain_class = Class.new(Puppet::Indirector::Plain) do
+ def self.to_s
+ "Mystuff::Testing"
+ end
+ end
- @searcher = @plain_class.new
+ @searcher = @plain_class.new
- @request = stub 'request', :key => "yay"
- end
+ @request = stub 'request', :key => "yay"
+ end
- it "should return return an instance of the indirected model" do
- object = mock 'object'
- @model.expects(:new).with(@request.key).returns object
- @searcher.find(@request).should equal(object)
- end
+ it "should return return an instance of the indirected model" do
+ object = mock 'object'
+ @model.expects(:new).with(@request.key).returns object
+ @searcher.find(@request).should equal(object)
+ end
end
diff --git a/spec/unit/indirector/queue_spec.rb b/spec/unit/indirector/queue_spec.rb
index 0748b58..83e9c77 100755
--- a/spec/unit/indirector/queue_spec.rb
+++ b/spec/unit/indirector/queue_spec.rb
@@ -7,117 +7,117 @@ class Puppet::Indirector::Queue::TestClient
end
class FooExampleData
- attr_accessor :name
+ attr_accessor :name
- def self.pson_create(pson)
- new(pson['data'].to_sym)
- end
+ def self.pson_create(pson)
+ new(pson['data'].to_sym)
+ end
- def initialize(name = nil)
- @name = name if name
- end
+ def initialize(name = nil)
+ @name = name if name
+ end
- def render(format = :pson)
- to_pson
- end
+ def render(format = :pson)
+ to_pson
+ end
- def to_pson(*args)
- {:type => self.class.to_s, :data => name}.to_pson(*args)
- end
+ def to_pson(*args)
+ {:type => self.class.to_s, :data => name}.to_pson(*args)
+ end
end
describe Puppet::Indirector::Queue do
- confine "PSON library is missing; cannot test queueing" => Puppet.features.pson?
-
- before :each do
- @model = mock 'model'
- @indirection = stub 'indirection', :name => :my_queue, :register_terminus_type => nil, :model => @model
- Puppet::Indirector::Indirection.stubs(:instance).with(:my_queue).returns(@indirection)
- @store_class = Class.new(Puppet::Indirector::Queue) do
- def self.to_s
- 'MyQueue::MyType'
- end
- end
- @store = @store_class.new
-
- @subject_class = FooExampleData
- @subject = @subject_class.new
- @subject.name = :me
-
- Puppet.settings.stubs(:value).returns("bogus setting data")
- Puppet.settings.stubs(:value).with(:queue_type).returns(:test_client)
- Puppet::Util::Queue.stubs(:queue_type_to_class).with(:test_client).returns(Puppet::Indirector::Queue::TestClient)
-
- @request = stub 'request', :key => :me, :instance => @subject
+ confine "PSON library is missing; cannot test queueing" => Puppet.features.pson?
+
+ before :each do
+ @model = mock 'model'
+ @indirection = stub 'indirection', :name => :my_queue, :register_terminus_type => nil, :model => @model
+ Puppet::Indirector::Indirection.stubs(:instance).with(:my_queue).returns(@indirection)
+ @store_class = Class.new(Puppet::Indirector::Queue) do
+ def self.to_s
+ 'MyQueue::MyType'
+ end
end
+ @store = @store_class.new
- it "should require PSON" do
- Puppet.features.expects(:pson?).returns false
+ @subject_class = FooExampleData
+ @subject = @subject_class.new
+ @subject.name = :me
- lambda { @store_class.new }.should raise_error(ArgumentError)
- end
+ Puppet.settings.stubs(:value).returns("bogus setting data")
+ Puppet.settings.stubs(:value).with(:queue_type).returns(:test_client)
+ Puppet::Util::Queue.stubs(:queue_type_to_class).with(:test_client).returns(Puppet::Indirector::Queue::TestClient)
- it 'should use the correct client type and queue' do
- @store.queue.should == :my_queue
- @store.client.should be_an_instance_of(Puppet::Indirector::Queue::TestClient)
- end
+ @request = stub 'request', :key => :me, :instance => @subject
+ end
+
+ it "should require PSON" do
+ Puppet.features.expects(:pson?).returns false
- describe "when saving" do
- it 'should render the instance using pson' do
- @subject.expects(:render).with(:pson)
- @store.client.stubs(:send_message)
- @store.save(@request)
- end
+ lambda { @store_class.new }.should raise_error(ArgumentError)
+ end
- it "should send the rendered message to the appropriate queue on the client" do
- @subject.expects(:render).returns "mypson"
+ it 'should use the correct client type and queue' do
+ @store.queue.should == :my_queue
+ @store.client.should be_an_instance_of(Puppet::Indirector::Queue::TestClient)
+ end
- @store.client.expects(:send_message).with(:my_queue, "mypson")
+ describe "when saving" do
+ it 'should render the instance using pson' do
+ @subject.expects(:render).with(:pson)
+ @store.client.stubs(:send_message)
+ @store.save(@request)
+ end
- @store.save(@request)
- end
+ it "should send the rendered message to the appropriate queue on the client" do
+ @subject.expects(:render).returns "mypson"
- it "should catch any exceptions raised" do
- @store.client.expects(:send_message).raises ArgumentError
+ @store.client.expects(:send_message).with(:my_queue, "mypson")
- lambda { @store.save(@request) }.should raise_error(Puppet::Error)
- end
+ @store.save(@request)
end
- describe "when subscribing to the queue" do
- before do
- @store_class.stubs(:model).returns @model
- end
+ it "should catch any exceptions raised" do
+ @store.client.expects(:send_message).raises ArgumentError
- it "should use the model's Format support to intern the message from pson" do
- @model.expects(:convert_from).with(:pson, "mymessage")
+ lambda { @store.save(@request) }.should raise_error(Puppet::Error)
+ end
+ end
- @store_class.client.expects(:subscribe).yields("mymessage")
- @store_class.subscribe {|o| o }
- end
+ describe "when subscribing to the queue" do
+ before do
+ @store_class.stubs(:model).returns @model
+ end
- it "should yield each interned received message" do
- @model.stubs(:convert_from).returns "something"
+ it "should use the model's Format support to intern the message from pson" do
+ @model.expects(:convert_from).with(:pson, "mymessage")
- @subject_two = @subject_class.new
- @subject_two.name = :too
+ @store_class.client.expects(:subscribe).yields("mymessage")
+ @store_class.subscribe {|o| o }
+ end
- @store_class.client.expects(:subscribe).with(:my_queue).multiple_yields(@subject, @subject_two)
+ it "should yield each interned received message" do
+ @model.stubs(:convert_from).returns "something"
- received = []
- @store_class.subscribe do |obj|
- received.push(obj)
- end
+ @subject_two = @subject_class.new
+ @subject_two.name = :too
- received.should == %w{something something}
- end
+ @store_class.client.expects(:subscribe).with(:my_queue).multiple_yields(@subject, @subject_two)
+
+ received = []
+ @store_class.subscribe do |obj|
+ received.push(obj)
+ end
+
+ received.should == %w{something something}
+ end
- it "should log but not propagate errors" do
- @store_class.client.expects(:subscribe).yields("foo")
- @store_class.expects(:intern).raises ArgumentError
- Puppet.expects(:err)
- @store_class.subscribe {|o| o }
- end
+ it "should log but not propagate errors" do
+ @store_class.client.expects(:subscribe).yields("foo")
+ @store_class.expects(:intern).raises ArgumentError
+ Puppet.expects(:err)
+ @store_class.subscribe {|o| o }
end
+ end
end
diff --git a/spec/unit/indirector/report/processor_spec.rb b/spec/unit/indirector/report/processor_spec.rb
index 3ee9b1b..5602a27 100755
--- a/spec/unit/indirector/report/processor_spec.rb
+++ b/spec/unit/indirector/report/processor_spec.rb
@@ -8,74 +8,74 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/report/processor'
describe Puppet::Transaction::Report::Processor do
- before do
- Puppet.settings.stubs(:use).returns(true)
- end
+ before do
+ Puppet.settings.stubs(:use).returns(true)
+ end
- it "should provide a method for saving reports" do
- Puppet::Transaction::Report::Processor.new.should respond_to(:save)
- end
+ it "should provide a method for saving reports" do
+ Puppet::Transaction::Report::Processor.new.should respond_to(:save)
+ end
end
describe Puppet::Transaction::Report::Processor, " when saving a report" do
- before do
- Puppet.settings.stubs(:use)
- @reporter = Puppet::Transaction::Report::Processor.new
- end
+ before do
+ Puppet.settings.stubs(:use)
+ @reporter = Puppet::Transaction::Report::Processor.new
+ end
- it "should not process the report if reports are set to 'none'" do
- Puppet::Reports.expects(:report).never
- Puppet.settings.expects(:value).with(:reports).returns("none")
+ it "should not process the report if reports are set to 'none'" do
+ Puppet::Reports.expects(:report).never
+ Puppet.settings.expects(:value).with(:reports).returns("none")
- request = stub 'request', :instance => mock("report")
+ request = stub 'request', :instance => mock("report")
- @reporter.save(request)
- end
+ @reporter.save(request)
+ end
- it "should process the report with each configured report type" do
- Puppet.settings.stubs(:value).with(:reports).returns("one,two")
- @reporter.send(:reports).should == %w{one two}
- end
+ it "should process the report with each configured report type" do
+ Puppet.settings.stubs(:value).with(:reports).returns("one,two")
+ @reporter.send(:reports).should == %w{one two}
+ end
end
describe Puppet::Transaction::Report::Processor, " when processing a report" do
- before do
- Puppet.settings.stubs(:value).with(:reports).returns("one")
- Puppet.settings.stubs(:use)
- @reporter = Puppet::Transaction::Report::Processor.new
-
- @report_type = mock 'one'
- @dup_report = mock 'dupe report'
- @dup_report.stubs(:process)
- @report = mock 'report'
- @report.expects(:dup).returns(@dup_report)
-
- @request = stub 'request', :instance => @report
-
- Puppet::Reports.expects(:report).with("one").returns(@report_type)
-
- @dup_report.expects(:extend).with(@report_type)
- end
-
- # LAK:NOTE This is stupid, because the code is so short it doesn't
- # make sense to split it out, which means I just do the same test
- # three times so the spec looks right.
- it "should process a duplicate of the report, not the original" do
- @reporter.save(@request)
- end
-
- it "should extend the report with the report type's module" do
- @reporter.save(@request)
- end
-
- it "should call the report type's :process method" do
- @dup_report.expects(:process)
- @reporter.save(@request)
- end
-
- it "should not raise exceptions" do
- Puppet.settings.stubs(:value).with(:trace).returns(false)
- @dup_report.expects(:process).raises(ArgumentError)
- proc { @reporter.save(@request) }.should_not raise_error
- end
+ before do
+ Puppet.settings.stubs(:value).with(:reports).returns("one")
+ Puppet.settings.stubs(:use)
+ @reporter = Puppet::Transaction::Report::Processor.new
+
+ @report_type = mock 'one'
+ @dup_report = mock 'dupe report'
+ @dup_report.stubs(:process)
+ @report = mock 'report'
+ @report.expects(:dup).returns(@dup_report)
+
+ @request = stub 'request', :instance => @report
+
+ Puppet::Reports.expects(:report).with("one").returns(@report_type)
+
+ @dup_report.expects(:extend).with(@report_type)
+ end
+
+ # LAK:NOTE This is stupid, because the code is so short it doesn't
+ # make sense to split it out, which means I just do the same test
+ # three times so the spec looks right.
+ it "should process a duplicate of the report, not the original" do
+ @reporter.save(@request)
+ end
+
+ it "should extend the report with the report type's module" do
+ @reporter.save(@request)
+ end
+
+ it "should call the report type's :process method" do
+ @dup_report.expects(:process)
+ @reporter.save(@request)
+ end
+
+ it "should not raise exceptions" do
+ Puppet.settings.stubs(:value).with(:trace).returns(false)
+ @dup_report.expects(:process).raises(ArgumentError)
+ proc { @reporter.save(@request) }.should_not raise_error
+ end
end
diff --git a/spec/unit/indirector/report/rest_spec.rb b/spec/unit/indirector/report/rest_spec.rb
index ce61883..d0d29f8 100755
--- a/spec/unit/indirector/report/rest_spec.rb
+++ b/spec/unit/indirector/report/rest_spec.rb
@@ -5,24 +5,24 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/report/rest'
describe Puppet::Transaction::Report::Rest do
- it "should be a subclass of Puppet::Indirector::REST" do
- Puppet::Transaction::Report::Rest.superclass.should equal(Puppet::Indirector::REST)
- end
+ it "should be a subclass of Puppet::Indirector::REST" do
+ Puppet::Transaction::Report::Rest.superclass.should equal(Puppet::Indirector::REST)
+ end
- it "should use the :report_server setting in preference to :reportserver" do
- Puppet.settings[:reportserver] = "reportserver"
- Puppet.settings[:report_server] = "report_server"
- Puppet::Transaction::Report::Rest.server.should == "report_server"
- end
+ it "should use the :report_server setting in preference to :reportserver" do
+ Puppet.settings[:reportserver] = "reportserver"
+ Puppet.settings[:report_server] = "report_server"
+ Puppet::Transaction::Report::Rest.server.should == "report_server"
+ end
- it "should use the :report_server setting in preference to :server" do
- Puppet.settings[:server] = "server"
- Puppet.settings[:report_server] = "report_server"
- Puppet::Transaction::Report::Rest.server.should == "report_server"
- end
+ it "should use the :report_server setting in preference to :server" do
+ Puppet.settings[:server] = "server"
+ Puppet.settings[:report_server] = "report_server"
+ Puppet::Transaction::Report::Rest.server.should == "report_server"
+ end
- it "should have a value for report_server and report_port" do
- Puppet::Transaction::Report::Rest.server.should_not be_nil
- Puppet::Transaction::Report::Rest.port.should_not be_nil
- end
+ it "should have a value for report_server and report_port" do
+ Puppet::Transaction::Report::Rest.server.should_not be_nil
+ Puppet::Transaction::Report::Rest.port.should_not be_nil
+ end
end
diff --git a/spec/unit/indirector/request_spec.rb b/spec/unit/indirector/request_spec.rb
index 5822639..0b3c2c2 100755
--- a/spec/unit/indirector/request_spec.rb
+++ b/spec/unit/indirector/request_spec.rb
@@ -4,301 +4,301 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector/request'
describe Puppet::Indirector::Request do
- describe "when initializing" do
- it "should require an indirection name, a key, and a method" do
- lambda { Puppet::Indirector::Request.new }.should raise_error(ArgumentError)
- end
+ describe "when initializing" do
+ it "should require an indirection name, a key, and a method" do
+ lambda { Puppet::Indirector::Request.new }.should raise_error(ArgumentError)
+ end
- it "should always convert the indirection name to a symbol" do
- Puppet::Indirector::Request.new("ind", :method, "mykey").indirection_name.should == :ind
- end
+ it "should always convert the indirection name to a symbol" do
+ Puppet::Indirector::Request.new("ind", :method, "mykey").indirection_name.should == :ind
+ end
- it "should use provided value as the key if it is a string" do
- Puppet::Indirector::Request.new(:ind, :method, "mykey").key.should == "mykey"
- end
+ it "should use provided value as the key if it is a string" do
+ Puppet::Indirector::Request.new(:ind, :method, "mykey").key.should == "mykey"
+ end
- it "should use provided value as the key if it is a symbol" do
- Puppet::Indirector::Request.new(:ind, :method, :mykey).key.should == :mykey
- end
+ it "should use provided value as the key if it is a symbol" do
+ Puppet::Indirector::Request.new(:ind, :method, :mykey).key.should == :mykey
+ end
- it "should use the name of the provided instance as its key if an instance is provided as the key instead of a string" do
- instance = mock 'instance', :name => "mykey"
- request = Puppet::Indirector::Request.new(:ind, :method, instance)
- request.key.should == "mykey"
- request.instance.should equal(instance)
- end
+ it "should use the name of the provided instance as its key if an instance is provided as the key instead of a string" do
+ instance = mock 'instance', :name => "mykey"
+ request = Puppet::Indirector::Request.new(:ind, :method, instance)
+ request.key.should == "mykey"
+ request.instance.should equal(instance)
+ end
- it "should support options specified as a hash" do
- lambda { Puppet::Indirector::Request.new(:ind, :method, :key, :one => :two) }.should_not raise_error(ArgumentError)
- end
+ it "should support options specified as a hash" do
+ lambda { Puppet::Indirector::Request.new(:ind, :method, :key, :one => :two) }.should_not raise_error(ArgumentError)
+ end
- it "should support nil options" do
- lambda { Puppet::Indirector::Request.new(:ind, :method, :key, nil) }.should_not raise_error(ArgumentError)
- end
+ it "should support nil options" do
+ lambda { Puppet::Indirector::Request.new(:ind, :method, :key, nil) }.should_not raise_error(ArgumentError)
+ end
- it "should support unspecified options" do
- lambda { Puppet::Indirector::Request.new(:ind, :method, :key) }.should_not raise_error(ArgumentError)
- end
+ it "should support unspecified options" do
+ lambda { Puppet::Indirector::Request.new(:ind, :method, :key) }.should_not raise_error(ArgumentError)
+ end
- it "should use an empty options hash if nil was provided" do
- Puppet::Indirector::Request.new(:ind, :method, :key, nil).options.should == {}
- end
+ it "should use an empty options hash if nil was provided" do
+ Puppet::Indirector::Request.new(:ind, :method, :key, nil).options.should == {}
+ end
- it "should default to a nil node" do
- Puppet::Indirector::Request.new(:ind, :method, :key, nil).node.should be_nil
- end
+ it "should default to a nil node" do
+ Puppet::Indirector::Request.new(:ind, :method, :key, nil).node.should be_nil
+ end
- it "should set its node attribute if provided in the options" do
- Puppet::Indirector::Request.new(:ind, :method, :key, :node => "foo.com").node.should == "foo.com"
- end
+ it "should set its node attribute if provided in the options" do
+ Puppet::Indirector::Request.new(:ind, :method, :key, :node => "foo.com").node.should == "foo.com"
+ end
- it "should default to a nil ip" do
- Puppet::Indirector::Request.new(:ind, :method, :key, nil).ip.should be_nil
- end
+ it "should default to a nil ip" do
+ Puppet::Indirector::Request.new(:ind, :method, :key, nil).ip.should be_nil
+ end
- it "should set its ip attribute if provided in the options" do
- Puppet::Indirector::Request.new(:ind, :method, :key, :ip => "192.168.0.1").ip.should == "192.168.0.1"
- end
+ it "should set its ip attribute if provided in the options" do
+ Puppet::Indirector::Request.new(:ind, :method, :key, :ip => "192.168.0.1").ip.should == "192.168.0.1"
+ end
- it "should default to being unauthenticated" do
- Puppet::Indirector::Request.new(:ind, :method, :key, nil).should_not be_authenticated
- end
+ it "should default to being unauthenticated" do
+ Puppet::Indirector::Request.new(:ind, :method, :key, nil).should_not be_authenticated
+ end
- it "should set be marked authenticated if configured in the options" do
- Puppet::Indirector::Request.new(:ind, :method, :key, :authenticated => "eh").should be_authenticated
- end
+ it "should set be marked authenticated if configured in the options" do
+ Puppet::Indirector::Request.new(:ind, :method, :key, :authenticated => "eh").should be_authenticated
+ end
- it "should keep its options as a hash even if a node is specified" do
- Puppet::Indirector::Request.new(:ind, :method, :key, :node => "eh").options.should be_instance_of(Hash)
- end
+ it "should keep its options as a hash even if a node is specified" do
+ Puppet::Indirector::Request.new(:ind, :method, :key, :node => "eh").options.should be_instance_of(Hash)
+ end
- it "should keep its options as a hash even if another option is specified" do
- Puppet::Indirector::Request.new(:ind, :method, :key, :foo => "bar").options.should be_instance_of(Hash)
- end
+ it "should keep its options as a hash even if another option is specified" do
+ Puppet::Indirector::Request.new(:ind, :method, :key, :foo => "bar").options.should be_instance_of(Hash)
+ end
- it "should treat options other than :ip, :node, and :authenticated as options rather than attributes" do
- Puppet::Indirector::Request.new(:ind, :method, :key, :server => "bar").options[:server].should == "bar"
- end
+ it "should treat options other than :ip, :node, and :authenticated as options rather than attributes" do
+ Puppet::Indirector::Request.new(:ind, :method, :key, :server => "bar").options[:server].should == "bar"
+ end
- it "should normalize options to use symbols as keys" do
- Puppet::Indirector::Request.new(:ind, :method, :key, "foo" => "bar").options[:foo].should == "bar"
- end
+ it "should normalize options to use symbols as keys" do
+ Puppet::Indirector::Request.new(:ind, :method, :key, "foo" => "bar").options[:foo].should == "bar"
+ end
- describe "and the request key is a URI" do
- describe "and the URI is a 'file' URI" do
- before do
- @request = Puppet::Indirector::Request.new(:ind, :method, "file:///my/file with spaces")
- end
-
- it "should set the request key to the unescaped full file path" do
- @request.key.should == "/my/file with spaces"
- end
-
- it "should not set the protocol" do
- @request.protocol.should be_nil
- end
-
- it "should not set the port" do
- @request.port.should be_nil
- end
-
- it "should not set the server" do
- @request.server.should be_nil
- end
- end
-
- it "should set the protocol to the URI scheme" do
- Puppet::Indirector::Request.new(:ind, :method, "http://host/stuff").protocol.should == "http"
- end
-
- it "should set the server if a server is provided" do
- Puppet::Indirector::Request.new(:ind, :method, "http://host/stuff").server.should == "host"
- end
-
- it "should set the server and port if both are provided" do
- Puppet::Indirector::Request.new(:ind, :method, "http://host:543/stuff").port.should == 543
- end
-
- it "should default to the masterport if the URI scheme is 'puppet'" do
- Puppet.settings.expects(:value).with(:masterport).returns "321"
- Puppet::Indirector::Request.new(:ind, :method, "puppet://host/stuff").port.should == 321
- end
-
- it "should use the provided port if the URI scheme is not 'puppet'" do
- Puppet::Indirector::Request.new(:ind, :method, "http://host/stuff").port.should == 80
- end
-
- it "should set the request key to the unescaped key part path from the URI" do
- Puppet::Indirector::Request.new(:ind, :method, "http://host/environment/terminus/stuff with spaces").key.should == "stuff with spaces"
- end
-
- it "should set the :uri attribute to the full URI" do
- Puppet::Indirector::Request.new(:ind, :method, "http:///stuff").uri.should == "http:///stuff"
- end
+ describe "and the request key is a URI" do
+ describe "and the URI is a 'file' URI" do
+ before do
+ @request = Puppet::Indirector::Request.new(:ind, :method, "file:///my/file with spaces")
end
- it "should allow indication that it should not read a cached instance" do
- Puppet::Indirector::Request.new(:ind, :method, :key, :ignore_cache => true).should be_ignore_cache
+ it "should set the request key to the unescaped full file path" do
+ @request.key.should == "/my/file with spaces"
end
- it "should default to not ignoring the cache" do
- Puppet::Indirector::Request.new(:ind, :method, :key).should_not be_ignore_cache
+ it "should not set the protocol" do
+ @request.protocol.should be_nil
end
- it "should allow indication that it should not not read an instance from the terminus" do
- Puppet::Indirector::Request.new(:ind, :method, :key, :ignore_terminus => true).should be_ignore_terminus
+ it "should not set the port" do
+ @request.port.should be_nil
end
- it "should default to not ignoring the terminus" do
- Puppet::Indirector::Request.new(:ind, :method, :key).should_not be_ignore_terminus
+ it "should not set the server" do
+ @request.server.should be_nil
end
- end
+ end
- it "should look use the Indirection class to return the appropriate indirection" do
- ind = mock 'indirection'
- Puppet::Indirector::Indirection.expects(:instance).with(:myind).returns ind
- request = Puppet::Indirector::Request.new(:myind, :method, :key)
+ it "should set the protocol to the URI scheme" do
+ Puppet::Indirector::Request.new(:ind, :method, "http://host/stuff").protocol.should == "http"
+ end
- request.indirection.should equal(ind)
- end
+ it "should set the server if a server is provided" do
+ Puppet::Indirector::Request.new(:ind, :method, "http://host/stuff").server.should == "host"
+ end
- it "should use its indirection to look up the appropriate model" do
- ind = mock 'indirection'
- Puppet::Indirector::Indirection.expects(:instance).with(:myind).returns ind
- request = Puppet::Indirector::Request.new(:myind, :method, :key)
+ it "should set the server and port if both are provided" do
+ Puppet::Indirector::Request.new(:ind, :method, "http://host:543/stuff").port.should == 543
+ end
- ind.expects(:model).returns "mymodel"
+ it "should default to the masterport if the URI scheme is 'puppet'" do
+ Puppet.settings.expects(:value).with(:masterport).returns "321"
+ Puppet::Indirector::Request.new(:ind, :method, "puppet://host/stuff").port.should == 321
+ end
- request.model.should == "mymodel"
- end
+ it "should use the provided port if the URI scheme is not 'puppet'" do
+ Puppet::Indirector::Request.new(:ind, :method, "http://host/stuff").port.should == 80
+ end
- it "should fail intelligently when asked to find a model but the indirection cannot be found" do
- Puppet::Indirector::Indirection.expects(:instance).with(:myind).returns nil
- request = Puppet::Indirector::Request.new(:myind, :method, :key)
+ it "should set the request key to the unescaped key part path from the URI" do
+ Puppet::Indirector::Request.new(:ind, :method, "http://host/environment/terminus/stuff with spaces").key.should == "stuff with spaces"
+ end
- lambda { request.model }.should raise_error(ArgumentError)
+ it "should set the :uri attribute to the full URI" do
+ Puppet::Indirector::Request.new(:ind, :method, "http:///stuff").uri.should == "http:///stuff"
+ end
end
- it "should have a method for determining if the request is plural or singular" do
- Puppet::Indirector::Request.new(:myind, :method, :key).should respond_to(:plural?)
+ it "should allow indication that it should not read a cached instance" do
+ Puppet::Indirector::Request.new(:ind, :method, :key, :ignore_cache => true).should be_ignore_cache
end
- it "should be considered plural if the method is 'search'" do
- Puppet::Indirector::Request.new(:myind, :search, :key).should be_plural
+ it "should default to not ignoring the cache" do
+ Puppet::Indirector::Request.new(:ind, :method, :key).should_not be_ignore_cache
end
- it "should not be considered plural if the method is not 'search'" do
- Puppet::Indirector::Request.new(:myind, :find, :key).should_not be_plural
+ it "should allow indication that it should not not read an instance from the terminus" do
+ Puppet::Indirector::Request.new(:ind, :method, :key, :ignore_terminus => true).should be_ignore_terminus
end
- it "should use its uri, if it has one, as its string representation" do
- Puppet::Indirector::Request.new(:myind, :find, "foo://bar/baz").to_s.should == "foo://bar/baz"
+ it "should default to not ignoring the terminus" do
+ Puppet::Indirector::Request.new(:ind, :method, :key).should_not be_ignore_terminus
end
+ end
- it "should use its indirection name and key, if it has no uri, as its string representation" do
- Puppet::Indirector::Request.new(:myind, :find, "key") == "/myind/key"
- end
+ it "should look use the Indirection class to return the appropriate indirection" do
+ ind = mock 'indirection'
+ Puppet::Indirector::Indirection.expects(:instance).with(:myind).returns ind
+ request = Puppet::Indirector::Request.new(:myind, :method, :key)
- it "should be able to return the URI-escaped key" do
- Puppet::Indirector::Request.new(:myind, :find, "my key").escaped_key.should == URI.escape("my key")
- end
+ request.indirection.should equal(ind)
+ end
- it "should have an environment accessor" do
- Puppet::Indirector::Request.new(:myind, :find, "my key", :environment => "foo").should respond_to(:environment)
- end
+ it "should use its indirection to look up the appropriate model" do
+ ind = mock 'indirection'
+ Puppet::Indirector::Indirection.expects(:instance).with(:myind).returns ind
+ request = Puppet::Indirector::Request.new(:myind, :method, :key)
- it "should set its environment to an environment instance when a string is specified as its environment" do
- Puppet::Indirector::Request.new(:myind, :find, "my key", :environment => "foo").environment.should == Puppet::Node::Environment.new("foo")
- end
+ ind.expects(:model).returns "mymodel"
- it "should use any passed in environment instances as its environment" do
- env = Puppet::Node::Environment.new("foo")
- Puppet::Indirector::Request.new(:myind, :find, "my key", :environment => env).environment.should equal(env)
- end
+ request.model.should == "mymodel"
+ end
- it "should use the default environment when none is provided" do
- Puppet::Indirector::Request.new(:myind, :find, "my key" ).environment.should equal(Puppet::Node::Environment.new)
- end
+ it "should fail intelligently when asked to find a model but the indirection cannot be found" do
+ Puppet::Indirector::Indirection.expects(:instance).with(:myind).returns nil
+ request = Puppet::Indirector::Request.new(:myind, :method, :key)
- it "should support converting its options to a hash" do
- Puppet::Indirector::Request.new(:myind, :find, "my key" ).should respond_to(:to_hash)
- end
+ lambda { request.model }.should raise_error(ArgumentError)
+ end
- it "should include all of its attributes when its options are converted to a hash" do
- Puppet::Indirector::Request.new(:myind, :find, "my key", :node => 'foo').to_hash[:node].should == 'foo'
- end
+ it "should have a method for determining if the request is plural or singular" do
+ Puppet::Indirector::Request.new(:myind, :method, :key).should respond_to(:plural?)
+ end
- describe "when building a query string from its options" do
- before do
- @request = Puppet::Indirector::Request.new(:myind, :find, "my key")
- end
+ it "should be considered plural if the method is 'search'" do
+ Puppet::Indirector::Request.new(:myind, :search, :key).should be_plural
+ end
- it "should return an empty query string if there are no options" do
- @request.stubs(:options).returns nil
- @request.query_string.should == ""
- end
+ it "should not be considered plural if the method is not 'search'" do
+ Puppet::Indirector::Request.new(:myind, :find, :key).should_not be_plural
+ end
- it "should return an empty query string if the options are empty" do
- @request.stubs(:options).returns({})
- @request.query_string.should == ""
- end
+ it "should use its uri, if it has one, as its string representation" do
+ Puppet::Indirector::Request.new(:myind, :find, "foo://bar/baz").to_s.should == "foo://bar/baz"
+ end
- it "should prefix the query string with '?'" do
- @request.stubs(:options).returns(:one => "two")
- @request.query_string.should =~ /^\?/
- end
+ it "should use its indirection name and key, if it has no uri, as its string representation" do
+ Puppet::Indirector::Request.new(:myind, :find, "key") == "/myind/key"
+ end
- it "should include all options in the query string, separated by '&'" do
- @request.stubs(:options).returns(:one => "two", :three => "four")
- @request.query_string.sub(/^\?/, '').split("&").sort.should == %w{one=two three=four}.sort
- end
+ it "should be able to return the URI-escaped key" do
+ Puppet::Indirector::Request.new(:myind, :find, "my key").escaped_key.should == URI.escape("my key")
+ end
- it "should ignore nil options" do
- @request.stubs(:options).returns(:one => "two", :three => nil)
- @request.query_string.should_not be_include("three")
- end
+ it "should have an environment accessor" do
+ Puppet::Indirector::Request.new(:myind, :find, "my key", :environment => "foo").should respond_to(:environment)
+ end
- it "should convert 'true' option values into strings" do
- @request.stubs(:options).returns(:one => true)
- @request.query_string.should == "?one=true"
- end
+ it "should set its environment to an environment instance when a string is specified as its environment" do
+ Puppet::Indirector::Request.new(:myind, :find, "my key", :environment => "foo").environment.should == Puppet::Node::Environment.new("foo")
+ end
- it "should convert 'false' option values into strings" do
- @request.stubs(:options).returns(:one => false)
- @request.query_string.should == "?one=false"
- end
+ it "should use any passed in environment instances as its environment" do
+ env = Puppet::Node::Environment.new("foo")
+ Puppet::Indirector::Request.new(:myind, :find, "my key", :environment => env).environment.should equal(env)
+ end
- it "should convert to a string all option values that are integers" do
- @request.stubs(:options).returns(:one => 50)
- @request.query_string.should == "?one=50"
- end
+ it "should use the default environment when none is provided" do
+ Puppet::Indirector::Request.new(:myind, :find, "my key" ).environment.should equal(Puppet::Node::Environment.new)
+ end
- it "should convert to a string all option values that are floating point numbers" do
- @request.stubs(:options).returns(:one => 1.2)
- @request.query_string.should == "?one=1.2"
- end
+ it "should support converting its options to a hash" do
+ Puppet::Indirector::Request.new(:myind, :find, "my key" ).should respond_to(:to_hash)
+ end
- it "should CGI-escape all option values that are strings" do
- escaping = CGI.escape("one two")
- @request.stubs(:options).returns(:one => "one two")
- @request.query_string.should == "?one=#{escaping}"
- end
+ it "should include all of its attributes when its options are converted to a hash" do
+ Puppet::Indirector::Request.new(:myind, :find, "my key", :node => 'foo').to_hash[:node].should == 'foo'
+ end
- it "should YAML-dump and CGI-escape arrays" do
- escaping = CGI.escape(YAML.dump(%w{one two}))
- @request.stubs(:options).returns(:one => %w{one two})
- @request.query_string.should == "?one=#{escaping}"
- end
+ describe "when building a query string from its options" do
+ before do
+ @request = Puppet::Indirector::Request.new(:myind, :find, "my key")
+ end
- it "should convert to a string and CGI-escape all option values that are symbols" do
- escaping = CGI.escape("sym bol")
- @request.stubs(:options).returns(:one => :"sym bol")
- @request.query_string.should == "?one=#{escaping}"
- end
+ it "should return an empty query string if there are no options" do
+ @request.stubs(:options).returns nil
+ @request.query_string.should == ""
+ end
- it "should fail if options other than booleans or strings are provided" do
- @request.stubs(:options).returns(:one => {:one => :two})
- lambda { @request.query_string }.should raise_error(ArgumentError)
- end
+ it "should return an empty query string if the options are empty" do
+ @request.stubs(:options).returns({})
+ @request.query_string.should == ""
+ end
+
+ it "should prefix the query string with '?'" do
+ @request.stubs(:options).returns(:one => "two")
+ @request.query_string.should =~ /^\?/
+ end
+
+ it "should include all options in the query string, separated by '&'" do
+ @request.stubs(:options).returns(:one => "two", :three => "four")
+ @request.query_string.sub(/^\?/, '').split("&").sort.should == %w{one=two three=four}.sort
+ end
+
+ it "should ignore nil options" do
+ @request.stubs(:options).returns(:one => "two", :three => nil)
+ @request.query_string.should_not be_include("three")
+ end
+
+ it "should convert 'true' option values into strings" do
+ @request.stubs(:options).returns(:one => true)
+ @request.query_string.should == "?one=true"
+ end
+
+ it "should convert 'false' option values into strings" do
+ @request.stubs(:options).returns(:one => false)
+ @request.query_string.should == "?one=false"
+ end
+
+ it "should convert to a string all option values that are integers" do
+ @request.stubs(:options).returns(:one => 50)
+ @request.query_string.should == "?one=50"
+ end
+
+ it "should convert to a string all option values that are floating point numbers" do
+ @request.stubs(:options).returns(:one => 1.2)
+ @request.query_string.should == "?one=1.2"
+ end
+
+ it "should CGI-escape all option values that are strings" do
+ escaping = CGI.escape("one two")
+ @request.stubs(:options).returns(:one => "one two")
+ @request.query_string.should == "?one=#{escaping}"
+ end
+
+ it "should YAML-dump and CGI-escape arrays" do
+ escaping = CGI.escape(YAML.dump(%w{one two}))
+ @request.stubs(:options).returns(:one => %w{one two})
+ @request.query_string.should == "?one=#{escaping}"
+ end
+
+ it "should convert to a string and CGI-escape all option values that are symbols" do
+ escaping = CGI.escape("sym bol")
+ @request.stubs(:options).returns(:one => :"sym bol")
+ @request.query_string.should == "?one=#{escaping}"
+ end
+
+ it "should fail if options other than booleans or strings are provided" do
+ @request.stubs(:options).returns(:one => {:one => :two})
+ lambda { @request.query_string }.should raise_error(ArgumentError)
end
+ end
end
diff --git a/spec/unit/indirector/resource/ral_spec.rb b/spec/unit/indirector/resource/ral_spec.rb
index c3dc8d8..a5baef3 100644
--- a/spec/unit/indirector/resource/ral_spec.rb
+++ b/spec/unit/indirector/resource/ral_spec.rb
@@ -3,127 +3,127 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
describe "Puppet::Resource::Ral" do
- describe "find" do
- before do
- @request = stub 'request', :key => "user/root"
- end
-
- it "should find an existing instance" do
- my_resource = stub "my user resource"
-
- wrong_instance = stub "wrong user", :name => "bob"
- my_instance = stub "my user", :name => "root", :to_resource => my_resource
-
- require 'puppet/type/user'
- Puppet::Type::User.expects(:instances).returns([ wrong_instance, my_instance, wrong_instance ])
- Puppet::Resource::Ral.new.find(@request).should == my_resource
- end
-
- it "if there is no instance, it should create one" do
- wrong_instance = stub "wrong user", :name => "bob"
-
- require 'puppet/type/user'
- Puppet::Type::User.expects(:instances).returns([ wrong_instance, wrong_instance ])
- result = Puppet::Resource::Ral.new.find(@request)
- result.should be_is_a(Puppet::Resource)
- result.title.should == "root"
- end
+ describe "find" do
+ before do
+ @request = stub 'request', :key => "user/root"
end
- describe "search" do
- before do
- @request = stub 'request', :key => "user/", :options => {}
- end
+ it "should find an existing instance" do
+ my_resource = stub "my user resource"
- it "should convert ral resources into regular resources" do
- my_resource = stub "my user resource"
- my_instance = stub "my user", :name => "root", :to_resource => my_resource
+ wrong_instance = stub "wrong user", :name => "bob"
+ my_instance = stub "my user", :name => "root", :to_resource => my_resource
- require 'puppet/type/user'
- Puppet::Type::User.expects(:instances).returns([ my_instance ])
- Puppet::Resource::Ral.new.search(@request).should == [my_resource]
- end
+ require 'puppet/type/user'
+ Puppet::Type::User.expects(:instances).returns([ wrong_instance, my_instance, wrong_instance ])
+ Puppet::Resource::Ral.new.find(@request).should == my_resource
+ end
+
+ it "if there is no instance, it should create one" do
+ wrong_instance = stub "wrong user", :name => "bob"
+
+ require 'puppet/type/user'
+ Puppet::Type::User.expects(:instances).returns([ wrong_instance, wrong_instance ])
+ result = Puppet::Resource::Ral.new.find(@request)
+ result.should be_is_a(Puppet::Resource)
+ result.title.should == "root"
+ end
+ end
+
+ describe "search" do
+ before do
+ @request = stub 'request', :key => "user/", :options => {}
+ end
+
+ it "should convert ral resources into regular resources" do
+ my_resource = stub "my user resource"
+ my_instance = stub "my user", :name => "root", :to_resource => my_resource
- it "should filter results by name if there's a name in the key" do
- my_resource = stub "my user resource"
- my_resource.stubs(:to_resource).returns(my_resource)
- my_resource.stubs(:[]).with(:name).returns("root")
+ require 'puppet/type/user'
+ Puppet::Type::User.expects(:instances).returns([ my_instance ])
+ Puppet::Resource::Ral.new.search(@request).should == [my_resource]
+ end
+
+ it "should filter results by name if there's a name in the key" do
+ my_resource = stub "my user resource"
+ my_resource.stubs(:to_resource).returns(my_resource)
+ my_resource.stubs(:[]).with(:name).returns("root")
- wrong_resource = stub "wrong resource"
- wrong_resource.stubs(:to_resource).returns(wrong_resource)
- wrong_resource.stubs(:[]).with(:name).returns("bad")
+ wrong_resource = stub "wrong resource"
+ wrong_resource.stubs(:to_resource).returns(wrong_resource)
+ wrong_resource.stubs(:[]).with(:name).returns("bad")
- my_instance = stub "my user", :to_resource => my_resource
- wrong_instance = stub "wrong user", :to_resource => wrong_resource
+ my_instance = stub "my user", :to_resource => my_resource
+ wrong_instance = stub "wrong user", :to_resource => wrong_resource
- @request = stub 'request', :key => "user/root", :options => {}
+ @request = stub 'request', :key => "user/root", :options => {}
- require 'puppet/type/user'
- Puppet::Type::User.expects(:instances).returns([ my_instance, wrong_instance ])
- Puppet::Resource::Ral.new.search(@request).should == [my_resource]
- end
+ require 'puppet/type/user'
+ Puppet::Type::User.expects(:instances).returns([ my_instance, wrong_instance ])
+ Puppet::Resource::Ral.new.search(@request).should == [my_resource]
+ end
- it "should filter results by query parameters" do
- wrong_resource = stub "my user resource"
- wrong_resource.stubs(:to_resource).returns(wrong_resource)
- wrong_resource.stubs(:[]).with(:name).returns("root")
+ it "should filter results by query parameters" do
+ wrong_resource = stub "my user resource"
+ wrong_resource.stubs(:to_resource).returns(wrong_resource)
+ wrong_resource.stubs(:[]).with(:name).returns("root")
- my_resource = stub "wrong resource"
- my_resource.stubs(:to_resource).returns(my_resource)
- my_resource.stubs(:[]).with(:name).returns("bob")
+ my_resource = stub "wrong resource"
+ my_resource.stubs(:to_resource).returns(my_resource)
+ my_resource.stubs(:[]).with(:name).returns("bob")
- my_instance = stub "my user", :to_resource => my_resource
- wrong_instance = stub "wrong user", :to_resource => wrong_resource
+ my_instance = stub "my user", :to_resource => my_resource
+ wrong_instance = stub "wrong user", :to_resource => wrong_resource
- @request = stub 'request', :key => "user/", :options => {:name => "bob"}
+ @request = stub 'request', :key => "user/", :options => {:name => "bob"}
- require 'puppet/type/user'
- Puppet::Type::User.expects(:instances).returns([ my_instance, wrong_instance ])
- Puppet::Resource::Ral.new.search(@request).should == [my_resource]
- end
+ require 'puppet/type/user'
+ Puppet::Type::User.expects(:instances).returns([ my_instance, wrong_instance ])
+ Puppet::Resource::Ral.new.search(@request).should == [my_resource]
+ end
- it "should return sorted results" do
- a_resource = stub "alice resource"
- a_resource.stubs(:to_resource).returns(a_resource)
- a_resource.stubs(:title).returns("alice")
+ it "should return sorted results" do
+ a_resource = stub "alice resource"
+ a_resource.stubs(:to_resource).returns(a_resource)
+ a_resource.stubs(:title).returns("alice")
- b_resource = stub "bob resource"
- b_resource.stubs(:to_resource).returns(b_resource)
- b_resource.stubs(:title).returns("bob")
+ b_resource = stub "bob resource"
+ b_resource.stubs(:to_resource).returns(b_resource)
+ b_resource.stubs(:title).returns("bob")
- a_instance = stub "alice user", :to_resource => a_resource
- b_instance = stub "bob user", :to_resource => b_resource
+ a_instance = stub "alice user", :to_resource => a_resource
+ b_instance = stub "bob user", :to_resource => b_resource
- @request = stub 'request', :key => "user/", :options => {}
+ @request = stub 'request', :key => "user/", :options => {}
+
+ require 'puppet/type/user'
+ Puppet::Type::User.expects(:instances).returns([ b_instance, a_instance ])
+ Puppet::Resource::Ral.new.search(@request).should == [a_resource, b_resource]
+ end
+ end
+
+ describe "save" do
+ before do
+ @rebuilt_res = stub 'rebuilt instance'
+ @ral_res = stub 'ral resource', :to_resource => @rebuilt_res
+ @instance = stub 'instance', :to_ral => @ral_res
+ @request = stub 'request', :key => "user/", :instance => @instance
+ @catalog = stub 'catalog'
+
+ Puppet::Resource::Catalog.stubs(:new).returns(@catalog)
+ @catalog.stubs(:apply)
+ @catalog.stubs(:add_resource)
+ end
- require 'puppet/type/user'
- Puppet::Type::User.expects(:instances).returns([ b_instance, a_instance ])
- Puppet::Resource::Ral.new.search(@request).should == [a_resource, b_resource]
- end
+ it "should apply a new catalog with a ral object in it" do
+ Puppet::Resource::Catalog.expects(:new).returns(@catalog)
+ @catalog.expects(:add_resource).with(@ral_res)
+ @catalog.expects(:apply)
+ Puppet::Resource::Ral.new.save(@request)
end
- describe "save" do
- before do
- @rebuilt_res = stub 'rebuilt instance'
- @ral_res = stub 'ral resource', :to_resource => @rebuilt_res
- @instance = stub 'instance', :to_ral => @ral_res
- @request = stub 'request', :key => "user/", :instance => @instance
- @catalog = stub 'catalog'
-
- Puppet::Resource::Catalog.stubs(:new).returns(@catalog)
- @catalog.stubs(:apply)
- @catalog.stubs(:add_resource)
- end
-
- it "should apply a new catalog with a ral object in it" do
- Puppet::Resource::Catalog.expects(:new).returns(@catalog)
- @catalog.expects(:add_resource).with(@ral_res)
- @catalog.expects(:apply)
- Puppet::Resource::Ral.new.save(@request)
- end
-
- it "should return a regular resource that used to be the ral resource" do
- Puppet::Resource::Ral.new.save(@request).should == @rebuilt_res
- end
+ it "should return a regular resource that used to be the ral resource" do
+ Puppet::Resource::Ral.new.save(@request).should == @rebuilt_res
end
+ end
end
diff --git a/spec/unit/indirector/resource/rest_spec.rb b/spec/unit/indirector/resource/rest_spec.rb
index d5f2a9d..351aee3 100755
--- a/spec/unit/indirector/resource/rest_spec.rb
+++ b/spec/unit/indirector/resource/rest_spec.rb
@@ -5,7 +5,7 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
require 'puppet/indirector/resource/rest'
describe Puppet::Resource::Rest do
- it "should be a sublcass of Puppet::Indirector::REST" do
- Puppet::Resource::Rest.superclass.should equal(Puppet::Indirector::REST)
- end
+ it "should be a sublcass of Puppet::Indirector::REST" do
+ Puppet::Resource::Rest.superclass.should equal(Puppet::Indirector::REST)
+ end
end
diff --git a/spec/unit/indirector/resource_type/parser_spec.rb b/spec/unit/indirector/resource_type/parser_spec.rb
index 331ca1c..5c0d9e0 100755
--- a/spec/unit/indirector/resource_type/parser_spec.rb
+++ b/spec/unit/indirector/resource_type/parser_spec.rb
@@ -5,71 +5,71 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/resource_type/parser'
describe Puppet::Indirector::ResourceType::Parser do
- before do
- @terminus = Puppet::Indirector::ResourceType::Parser.new
- @request = Puppet::Indirector::Request.new(:resource_type, :find, "foo")
- @krt = Puppet::Resource::TypeCollection.new(@request.environment)
- @request.environment.stubs(:known_resource_types).returns @krt
- end
-
- it "should be registered with the resource_type indirection" do
- Puppet::Indirector::Terminus.terminus_class(:resource_type, :parser).should equal(Puppet::Indirector::ResourceType::Parser)
+ before do
+ @terminus = Puppet::Indirector::ResourceType::Parser.new
+ @request = Puppet::Indirector::Request.new(:resource_type, :find, "foo")
+ @krt = Puppet::Resource::TypeCollection.new(@request.environment)
+ @request.environment.stubs(:known_resource_types).returns @krt
+ end
+
+ it "should be registered with the resource_type indirection" do
+ Puppet::Indirector::Terminus.terminus_class(:resource_type, :parser).should equal(Puppet::Indirector::ResourceType::Parser)
+ end
+
+ describe "when finding" do
+ it "should use the request's environment's list of known resource types" do
+ @request.environment.known_resource_types.expects(:hostclass).returns nil
+
+ @terminus.find(@request)
end
- describe "when finding" do
- it "should use the request's environment's list of known resource types" do
- @request.environment.known_resource_types.expects(:hostclass).returns nil
+ it "should return any found type" do
+ type = @krt.add(Puppet::Resource::Type.new(:hostclass, "foo"))
- @terminus.find(@request)
- end
-
- it "should return any found type" do
- type = @krt.add(Puppet::Resource::Type.new(:hostclass, "foo"))
-
- @terminus.find(@request).should == type
- end
+ @terminus.find(@request).should == type
+ end
- it "should return nil if no type can be found" do
- @terminus.find(@request).should be_nil
- end
+ it "should return nil if no type can be found" do
+ @terminus.find(@request).should be_nil
+ end
- it "should prefer definitions to nodes" do
- type = @krt.add(Puppet::Resource::Type.new(:hostclass, "foo"))
- node = @krt.add(Puppet::Resource::Type.new(:node, "foo"))
+ it "should prefer definitions to nodes" do
+ type = @krt.add(Puppet::Resource::Type.new(:hostclass, "foo"))
+ node = @krt.add(Puppet::Resource::Type.new(:node, "foo"))
- @terminus.find(@request).should == type
- end
+ @terminus.find(@request).should == type
end
+ end
- describe "when searching" do
- before do
- @request.key = "*"
- end
+ describe "when searching" do
+ before do
+ @request.key = "*"
+ end
- it "should use the request's environment's list of known resource types" do
- @request.environment.known_resource_types.expects(:hostclasses).returns({})
+ it "should use the request's environment's list of known resource types" do
+ @request.environment.known_resource_types.expects(:hostclasses).returns({})
- @terminus.search(@request)
- end
+ @terminus.search(@request)
+ end
- it "should fail if anyther other than '*' was provided as the search key" do
- @request.key = "foo*"
- lambda { @terminus.search(@request) }.should raise_error(ArgumentError)
- end
+ it "should fail if anyther other than '*' was provided as the search key" do
+ @request.key = "foo*"
+ lambda { @terminus.search(@request) }.should raise_error(ArgumentError)
+ end
- it "should return all known types" do
- type = @krt.add(Puppet::Resource::Type.new(:hostclass, "foo"))
- node = @krt.add(Puppet::Resource::Type.new(:node, "bar"))
- define = @krt.add(Puppet::Resource::Type.new(:definition, "baz"))
+ it "should return all known types" do
+ type = @krt.add(Puppet::Resource::Type.new(:hostclass, "foo"))
+ node = @krt.add(Puppet::Resource::Type.new(:node, "bar"))
+ define = @krt.add(Puppet::Resource::Type.new(:definition, "baz"))
- result = @terminus.search(@request)
- result.should be_include(type)
- result.should be_include(node)
- result.should be_include(define)
- end
+ result = @terminus.search(@request)
+ result.should be_include(type)
+ result.should be_include(node)
+ result.should be_include(define)
+ end
- it "should return nil if no types can be found" do
- @terminus.search(@request).should be_nil
- end
+ it "should return nil if no types can be found" do
+ @terminus.search(@request).should be_nil
end
+ end
end
diff --git a/spec/unit/indirector/resource_type/rest_spec.rb b/spec/unit/indirector/resource_type/rest_spec.rb
index 28196d5..2486502 100755
--- a/spec/unit/indirector/resource_type/rest_spec.rb
+++ b/spec/unit/indirector/resource_type/rest_spec.rb
@@ -5,11 +5,11 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/resource_type/rest'
describe Puppet::Indirector::ResourceType::Rest do
- it "should be registered with the resource_type indirection" do
- Puppet::Indirector::Terminus.terminus_class(:resource_type, :rest).should equal(Puppet::Indirector::ResourceType::Rest)
- end
+ it "should be registered with the resource_type indirection" do
+ Puppet::Indirector::Terminus.terminus_class(:resource_type, :rest).should equal(Puppet::Indirector::ResourceType::Rest)
+ end
- it "should be a subclass of Puppet::Indirector::Rest" do
- Puppet::Indirector::ResourceType::Rest.superclass.should == Puppet::Indirector::REST
- end
+ it "should be a subclass of Puppet::Indirector::Rest" do
+ Puppet::Indirector::ResourceType::Rest.superclass.should == Puppet::Indirector::REST
+ end
end
diff --git a/spec/unit/indirector/rest_spec.rb b/spec/unit/indirector/rest_spec.rb
index 668158c..3efbfce 100755
--- a/spec/unit/indirector/rest_spec.rb
+++ b/spec/unit/indirector/rest_spec.rb
@@ -4,452 +4,452 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector/rest'
describe "a REST http call", :shared => true do
- it "should accept a path" do
- lambda { @search.send(@method, *@arguments) }.should_not raise_error(ArgumentError)
- end
+ it "should accept a path" do
+ lambda { @search.send(@method, *@arguments) }.should_not raise_error(ArgumentError)
+ end
- it "should require a path" do
- lambda { @searcher.send(@method) }.should raise_error(ArgumentError)
- end
+ it "should require a path" do
+ lambda { @searcher.send(@method) }.should raise_error(ArgumentError)
+ end
- it "should return the results of deserializing the response to the request" do
- conn = mock 'connection'
- conn.stubs(:put).returns @response
- conn.stubs(:delete).returns @response
- conn.stubs(:get).returns @response
- Puppet::Network::HttpPool.stubs(:http_instance).returns conn
+ it "should return the results of deserializing the response to the request" do
+ conn = mock 'connection'
+ conn.stubs(:put).returns @response
+ conn.stubs(:delete).returns @response
+ conn.stubs(:get).returns @response
+ Puppet::Network::HttpPool.stubs(:http_instance).returns conn
- @searcher.expects(:deserialize).with(@response).returns "myobject"
+ @searcher.expects(:deserialize).with(@response).returns "myobject"
- @searcher.send(@method, *@arguments).should == 'myobject'
- end
+ @searcher.send(@method, *@arguments).should == 'myobject'
+ end
end
describe Puppet::Indirector::REST do
- before do
- Puppet::Indirector::Terminus.stubs(:register_terminus_class)
- @model = stub('model', :supported_formats => %w{}, :convert_from => nil)
- @instance = stub('model instance', :name= => nil)
- @indirection = stub('indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model)
- Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
-
- @rest_class = Class.new(Puppet::Indirector::REST) do
- def self.to_s
- "This::Is::A::Test::Class"
- end
- end
-
- @response = stub('mock response', :body => 'result', :code => "200")
- @response.stubs(:[]).with('content-type').returns "text/plain"
- @response.stubs(:[]).with('content-encoding').returns nil
-
- @searcher = @rest_class.new
- @searcher.stubs(:model).returns @model
+ before do
+ Puppet::Indirector::Terminus.stubs(:register_terminus_class)
+ @model = stub('model', :supported_formats => %w{}, :convert_from => nil)
+ @instance = stub('model instance', :name= => nil)
+ @indirection = stub('indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model)
+ Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
+
+ @rest_class = Class.new(Puppet::Indirector::REST) do
+ def self.to_s
+ "This::Is::A::Test::Class"
+ end
end
- it "should include the v1 REST API module" do
- Puppet::Indirector::REST.ancestors.should be_include(Puppet::Network::HTTP::API::V1)
+ @response = stub('mock response', :body => 'result', :code => "200")
+ @response.stubs(:[]).with('content-type').returns "text/plain"
+ @response.stubs(:[]).with('content-encoding').returns nil
+
+ @searcher = @rest_class.new
+ @searcher.stubs(:model).returns @model
+ end
+
+ it "should include the v1 REST API module" do
+ Puppet::Indirector::REST.ancestors.should be_include(Puppet::Network::HTTP::API::V1)
+ end
+
+ it "should have a method for specifying what setting a subclass should use to retrieve its server" do
+ @rest_class.should respond_to(:use_server_setting)
+ end
+
+ it "should use any specified setting to pick the server" do
+ @rest_class.expects(:server_setting).returns :servset
+ Puppet.settings.expects(:value).with(:servset).returns "myserver"
+ @rest_class.server.should == "myserver"
+ end
+
+ it "should default to :server for the server setting" do
+ @rest_class.expects(:server_setting).returns nil
+ Puppet.settings.expects(:value).with(:server).returns "myserver"
+ @rest_class.server.should == "myserver"
+ end
+
+ it "should have a method for specifying what setting a subclass should use to retrieve its port" do
+ @rest_class.should respond_to(:use_port_setting)
+ end
+
+ it "should use any specified setting to pick the port" do
+ @rest_class.expects(:port_setting).returns :servset
+ Puppet.settings.expects(:value).with(:servset).returns "321"
+ @rest_class.port.should == 321
+ end
+
+ it "should default to :port for the port setting" do
+ @rest_class.expects(:port_setting).returns nil
+ Puppet.settings.expects(:value).with(:masterport).returns "543"
+ @rest_class.port.should == 543
+ end
+
+ describe "when deserializing responses" do
+ it "should return nil if the response code is 404" do
+ response = mock 'response'
+ response.expects(:code).returns "404"
+
+ @searcher.deserialize(response).should be_nil
end
- it "should have a method for specifying what setting a subclass should use to retrieve its server" do
- @rest_class.should respond_to(:use_server_setting)
- end
-
- it "should use any specified setting to pick the server" do
- @rest_class.expects(:server_setting).returns :servset
- Puppet.settings.expects(:value).with(:servset).returns "myserver"
- @rest_class.server.should == "myserver"
- end
-
- it "should default to :server for the server setting" do
- @rest_class.expects(:server_setting).returns nil
- Puppet.settings.expects(:value).with(:server).returns "myserver"
- @rest_class.server.should == "myserver"
- end
+ [300,400,403,405,500,501,502,503,504].each { |rc|
+ describe "when the response code is #{rc}" do
+ before :each do
+ @model.expects(:convert_from).never
- it "should have a method for specifying what setting a subclass should use to retrieve its port" do
- @rest_class.should respond_to(:use_port_setting)
- end
+ @response = mock 'response'
+ @response.stubs(:code).returns rc.to_s
+ @response.stubs(:[]).with('content-encoding').returns nil
+ @response.stubs(:message).returns "There was a problem (header)"
+ end
- it "should use any specified setting to pick the port" do
- @rest_class.expects(:port_setting).returns :servset
- Puppet.settings.expects(:value).with(:servset).returns "321"
- @rest_class.port.should == 321
- end
+ it "should fail" do
+ @response.stubs(:body).returns nil
+ lambda { @searcher.deserialize(@response) }.should raise_error(Net::HTTPError)
+ end
- it "should default to :port for the port setting" do
- @rest_class.expects(:port_setting).returns nil
- Puppet.settings.expects(:value).with(:masterport).returns "543"
- @rest_class.port.should == 543
- end
+ it "should take the error message from the body, if present" do
+ @response.stubs(:body).returns "There was a problem (body)"
+ lambda { @searcher.deserialize(@response) }.should raise_error(Net::HTTPError,"Error #{rc} on SERVER: There was a problem (body)")
+ end
- describe "when deserializing responses" do
- it "should return nil if the response code is 404" do
- response = mock 'response'
- response.expects(:code).returns "404"
+ it "should take the error message from the response header if the body is empty" do
+ @response.stubs(:body).returns ""
+ lambda { @searcher.deserialize(@response) }.should raise_error(Net::HTTPError,"Error #{rc} on SERVER: There was a problem (header)")
+ end
- @searcher.deserialize(response).should be_nil
+ it "should take the error message from the response header if the body is absent" do
+ @response.stubs(:body).returns nil
+ lambda { @searcher.deserialize(@response) }.should raise_error(Net::HTTPError,"Error #{rc} on SERVER: There was a problem (header)")
end
- [300,400,403,405,500,501,502,503,504].each { |rc|
- describe "when the response code is #{rc}" do
- before :each do
- @model.expects(:convert_from).never
-
- @response = mock 'response'
- @response.stubs(:code).returns rc.to_s
- @response.stubs(:[]).with('content-encoding').returns nil
- @response.stubs(:message).returns "There was a problem (header)"
- end
-
- it "should fail" do
- @response.stubs(:body).returns nil
- lambda { @searcher.deserialize(@response) }.should raise_error(Net::HTTPError)
- end
-
- it "should take the error message from the body, if present" do
- @response.stubs(:body).returns "There was a problem (body)"
- lambda { @searcher.deserialize(@response) }.should raise_error(Net::HTTPError,"Error #{rc} on SERVER: There was a problem (body)")
- end
-
- it "should take the error message from the response header if the body is empty" do
- @response.stubs(:body).returns ""
- lambda { @searcher.deserialize(@response) }.should raise_error(Net::HTTPError,"Error #{rc} on SERVER: There was a problem (header)")
- end
-
- it "should take the error message from the response header if the body is absent" do
- @response.stubs(:body).returns nil
- lambda { @searcher.deserialize(@response) }.should raise_error(Net::HTTPError,"Error #{rc} on SERVER: There was a problem (header)")
- end
-
- describe "and with http compression" do
- it "should uncompress the body" do
- @response.stubs(:body).returns("compressed body")
- @searcher.expects(:uncompress_body).with(@response).returns("uncompressed")
- lambda { @searcher.deserialize(@response) }.should raise_error { |e| e.message =~ /uncompressed/ }
- end
- end
- end
- }
-
- it "should return the results of converting from the format specified by the content-type header if the response code is in the 200s" do
- @model.expects(:convert_from).with("myformat", "mydata").returns "myobject"
-
- response = mock 'response'
- response.stubs(:[]).with("content-type").returns "myformat"
- response.stubs(:[]).with("content-encoding").returns nil
- response.stubs(:body).returns "mydata"
- response.stubs(:code).returns "200"
-
- @searcher.deserialize(response).should == "myobject"
+ describe "and with http compression" do
+ it "should uncompress the body" do
+ @response.stubs(:body).returns("compressed body")
+ @searcher.expects(:uncompress_body).with(@response).returns("uncompressed")
+ lambda { @searcher.deserialize(@response) }.should raise_error { |e| e.message =~ /uncompressed/ }
+ end
end
+ end
+ }
- it "should convert and return multiple instances if the return code is in the 200s and 'multiple' is specified" do
- @model.expects(:convert_from_multiple).with("myformat", "mydata").returns "myobjects"
+ it "should return the results of converting from the format specified by the content-type header if the response code is in the 200s" do
+ @model.expects(:convert_from).with("myformat", "mydata").returns "myobject"
- response = mock 'response'
- response.stubs(:[]).with("content-type").returns "myformat"
- response.stubs(:[]).with("content-encoding").returns nil
- response.stubs(:body).returns "mydata"
- response.stubs(:code).returns "200"
+ response = mock 'response'
+ response.stubs(:[]).with("content-type").returns "myformat"
+ response.stubs(:[]).with("content-encoding").returns nil
+ response.stubs(:body).returns "mydata"
+ response.stubs(:code).returns "200"
- @searcher.deserialize(response, true).should == "myobjects"
- end
+ @searcher.deserialize(response).should == "myobject"
+ end
- it "should strip the content-type header to keep only the mime-type" do
- @model.expects(:convert_from).with("text/plain", "mydata").returns "myobject"
+ it "should convert and return multiple instances if the return code is in the 200s and 'multiple' is specified" do
+ @model.expects(:convert_from_multiple).with("myformat", "mydata").returns "myobjects"
- response = mock 'response'
- response.stubs(:[]).with("content-type").returns "text/plain; charset=utf-8"
- response.stubs(:[]).with("content-encoding").returns nil
- response.stubs(:body).returns "mydata"
- response.stubs(:code).returns "200"
+ response = mock 'response'
+ response.stubs(:[]).with("content-type").returns "myformat"
+ response.stubs(:[]).with("content-encoding").returns nil
+ response.stubs(:body).returns "mydata"
+ response.stubs(:code).returns "200"
- @searcher.deserialize(response)
- end
+ @searcher.deserialize(response, true).should == "myobjects"
+ end
- it "should uncompress the body" do
- @model.expects(:convert_from).with("myformat", "uncompressed mydata").returns "myobject"
+ it "should strip the content-type header to keep only the mime-type" do
+ @model.expects(:convert_from).with("text/plain", "mydata").returns "myobject"
- response = mock 'response'
- response.stubs(:[]).with("content-type").returns "myformat"
- response.stubs(:body).returns "compressed mydata"
- response.stubs(:code).returns "200"
+ response = mock 'response'
+ response.stubs(:[]).with("content-type").returns "text/plain; charset=utf-8"
+ response.stubs(:[]).with("content-encoding").returns nil
+ response.stubs(:body).returns "mydata"
+ response.stubs(:code).returns "200"
- @searcher.expects(:uncompress_body).with(response).returns("uncompressed mydata")
+ @searcher.deserialize(response)
+ end
- @searcher.deserialize(response).should == "myobject"
- end
+ it "should uncompress the body" do
+ @model.expects(:convert_from).with("myformat", "uncompressed mydata").returns "myobject"
+
+ response = mock 'response'
+ response.stubs(:[]).with("content-type").returns "myformat"
+ response.stubs(:body).returns "compressed mydata"
+ response.stubs(:code).returns "200"
+
+ @searcher.expects(:uncompress_body).with(response).returns("uncompressed mydata")
+
+ @searcher.deserialize(response).should == "myobject"
end
+ end
- describe "when creating an HTTP client" do
- before do
- Puppet.settings.stubs(:value).returns("rest_testing")
- end
+ describe "when creating an HTTP client" do
+ before do
+ Puppet.settings.stubs(:value).returns("rest_testing")
+ end
- it "should use the class's server and port if the indirection request provides neither" do
- @request = stub 'request', :key => "foo", :server => nil, :port => nil
- @searcher.class.expects(:port).returns 321
- @searcher.class.expects(:server).returns "myserver"
- Puppet::Network::HttpPool.expects(:http_instance).with("myserver", 321).returns "myconn"
- @searcher.network(@request).should == "myconn"
- end
+ it "should use the class's server and port if the indirection request provides neither" do
+ @request = stub 'request', :key => "foo", :server => nil, :port => nil
+ @searcher.class.expects(:port).returns 321
+ @searcher.class.expects(:server).returns "myserver"
+ Puppet::Network::HttpPool.expects(:http_instance).with("myserver", 321).returns "myconn"
+ @searcher.network(@request).should == "myconn"
+ end
- it "should use the server from the indirection request if one is present" do
- @request = stub 'request', :key => "foo", :server => "myserver", :port => nil
- @searcher.class.stubs(:port).returns 321
- Puppet::Network::HttpPool.expects(:http_instance).with("myserver", 321).returns "myconn"
- @searcher.network(@request).should == "myconn"
- end
+ it "should use the server from the indirection request if one is present" do
+ @request = stub 'request', :key => "foo", :server => "myserver", :port => nil
+ @searcher.class.stubs(:port).returns 321
+ Puppet::Network::HttpPool.expects(:http_instance).with("myserver", 321).returns "myconn"
+ @searcher.network(@request).should == "myconn"
+ end
- it "should use the port from the indirection request if one is present" do
- @request = stub 'request', :key => "foo", :server => nil, :port => 321
- @searcher.class.stubs(:server).returns "myserver"
- Puppet::Network::HttpPool.expects(:http_instance).with("myserver", 321).returns "myconn"
- @searcher.network(@request).should == "myconn"
- end
+ it "should use the port from the indirection request if one is present" do
+ @request = stub 'request', :key => "foo", :server => nil, :port => 321
+ @searcher.class.stubs(:server).returns "myserver"
+ Puppet::Network::HttpPool.expects(:http_instance).with("myserver", 321).returns "myconn"
+ @searcher.network(@request).should == "myconn"
end
+ end
- describe "when doing a find" do
- before :each do
- @connection = stub('mock http connection', :get => @response)
- @searcher.stubs(:network).returns(@connection) # neuter the network connection
+ describe "when doing a find" do
+ before :each do
+ @connection = stub('mock http connection', :get => @response)
+ @searcher.stubs(:network).returns(@connection) # neuter the network connection
- # Use a key with spaces, so we can test escaping
- @request = Puppet::Indirector::Request.new(:foo, :find, "foo bar")
- end
+ # Use a key with spaces, so we can test escaping
+ @request = Puppet::Indirector::Request.new(:foo, :find, "foo bar")
+ end
- it "should call the GET http method on a network connection" do
- @searcher.expects(:network).returns @connection
- @connection.expects(:get).returns @response
- @searcher.find(@request)
- end
+ it "should call the GET http method on a network connection" do
+ @searcher.expects(:network).returns @connection
+ @connection.expects(:get).returns @response
+ @searcher.find(@request)
+ end
- it "should deserialize and return the http response, setting name" do
- @connection.expects(:get).returns @response
+ it "should deserialize and return the http response, setting name" do
+ @connection.expects(:get).returns @response
- instance = stub 'object'
- instance.expects(:name=)
- @searcher.expects(:deserialize).with(@response).returns instance
+ instance = stub 'object'
+ instance.expects(:name=)
+ @searcher.expects(:deserialize).with(@response).returns instance
- @searcher.find(@request).should == instance
- end
+ @searcher.find(@request).should == instance
+ end
- it "should deserialize and return the http response, and not require name=" do
- @connection.expects(:get).returns @response
+ it "should deserialize and return the http response, and not require name=" do
+ @connection.expects(:get).returns @response
- instance = stub 'object'
- @searcher.expects(:deserialize).with(@response).returns instance
+ instance = stub 'object'
+ @searcher.expects(:deserialize).with(@response).returns instance
- @searcher.find(@request).should == instance
- end
+ @searcher.find(@request).should == instance
+ end
- it "should use the URI generated by the Handler module" do
- @searcher.expects(:indirection2uri).with(@request).returns "/my/uri"
- @connection.expects(:get).with { |path, args| path == "/my/uri" }.returns(@response)
- @searcher.find(@request)
- end
+ it "should use the URI generated by the Handler module" do
+ @searcher.expects(:indirection2uri).with(@request).returns "/my/uri"
+ @connection.expects(:get).with { |path, args| path == "/my/uri" }.returns(@response)
+ @searcher.find(@request)
+ end
- it "should provide an Accept header containing the list of supported formats joined with commas" do
- @connection.expects(:get).with { |path, args| args["Accept"] == "supported, formats" }.returns(@response)
+ it "should provide an Accept header containing the list of supported formats joined with commas" do
+ @connection.expects(:get).with { |path, args| args["Accept"] == "supported, formats" }.returns(@response)
- @searcher.model.expects(:supported_formats).returns %w{supported formats}
- @searcher.find(@request)
- end
+ @searcher.model.expects(:supported_formats).returns %w{supported formats}
+ @searcher.find(@request)
+ end
- it "should add Accept-Encoding header" do
- @searcher.expects(:add_accept_encoding).returns({"accept-encoding" => "gzip"})
+ it "should add Accept-Encoding header" do
+ @searcher.expects(:add_accept_encoding).returns({"accept-encoding" => "gzip"})
- @connection.expects(:get).with { |path, args| args["accept-encoding"] == "gzip" }.returns(@response)
- @searcher.find(@request)
- end
+ @connection.expects(:get).with { |path, args| args["accept-encoding"] == "gzip" }.returns(@response)
+ @searcher.find(@request)
+ end
- it "should deserialize and return the network response" do
- @searcher.expects(:deserialize).with(@response).returns @instance
- @searcher.find(@request).should equal(@instance)
- end
+ it "should deserialize and return the network response" do
+ @searcher.expects(:deserialize).with(@response).returns @instance
+ @searcher.find(@request).should equal(@instance)
+ end
- it "should set the name of the resulting instance to the asked-for name" do
- @searcher.expects(:deserialize).with(@response).returns @instance
- @instance.expects(:name=).with "foo bar"
- @searcher.find(@request)
- end
+ it "should set the name of the resulting instance to the asked-for name" do
+ @searcher.expects(:deserialize).with(@response).returns @instance
+ @instance.expects(:name=).with "foo bar"
+ @searcher.find(@request)
+ end
- it "should generate an error when result data deserializes fails" do
- @searcher.expects(:deserialize).raises(ArgumentError)
- lambda { @searcher.find(@request) }.should raise_error(ArgumentError)
- end
+ it "should generate an error when result data deserializes fails" do
+ @searcher.expects(:deserialize).raises(ArgumentError)
+ lambda { @searcher.find(@request) }.should raise_error(ArgumentError)
end
+ end
- describe "when doing a search" do
- before :each do
- @connection = stub('mock http connection', :get => @response)
- @searcher.stubs(:network).returns(@connection) # neuter the network connection
+ describe "when doing a search" do
+ before :each do
+ @connection = stub('mock http connection', :get => @response)
+ @searcher.stubs(:network).returns(@connection) # neuter the network connection
- @model.stubs(:convert_from_multiple)
+ @model.stubs(:convert_from_multiple)
- @request = Puppet::Indirector::Request.new(:foo, :search, "foo bar")
- end
+ @request = Puppet::Indirector::Request.new(:foo, :search, "foo bar")
+ end
- it "should call the GET http method on a network connection" do
- @searcher.expects(:network).returns @connection
- @connection.expects(:get).returns @response
- @searcher.search(@request)
- end
+ it "should call the GET http method on a network connection" do
+ @searcher.expects(:network).returns @connection
+ @connection.expects(:get).returns @response
+ @searcher.search(@request)
+ end
- it "should deserialize as multiple instances and return the http response" do
- @connection.expects(:get).returns @response
- @searcher.expects(:deserialize).with(@response, true).returns "myobject"
+ it "should deserialize as multiple instances and return the http response" do
+ @connection.expects(:get).returns @response
+ @searcher.expects(:deserialize).with(@response, true).returns "myobject"
- @searcher.search(@request).should == 'myobject'
- end
+ @searcher.search(@request).should == 'myobject'
+ end
- it "should use the URI generated by the Handler module" do
- @searcher.expects(:indirection2uri).with(@request).returns "/mys/uri"
- @connection.expects(:get).with { |path, args| path == "/mys/uri" }.returns(@response)
- @searcher.search(@request)
- end
+ it "should use the URI generated by the Handler module" do
+ @searcher.expects(:indirection2uri).with(@request).returns "/mys/uri"
+ @connection.expects(:get).with { |path, args| path == "/mys/uri" }.returns(@response)
+ @searcher.search(@request)
+ end
- it "should provide an Accept header containing the list of supported formats joined with commas" do
- @connection.expects(:get).with { |path, args| args["Accept"] == "supported, formats" }.returns(@response)
+ it "should provide an Accept header containing the list of supported formats joined with commas" do
+ @connection.expects(:get).with { |path, args| args["Accept"] == "supported, formats" }.returns(@response)
- @searcher.model.expects(:supported_formats).returns %w{supported formats}
- @searcher.search(@request)
- end
+ @searcher.model.expects(:supported_formats).returns %w{supported formats}
+ @searcher.search(@request)
+ end
- it "should return an empty array if serialization returns nil" do
- @model.stubs(:convert_from_multiple).returns nil
+ it "should return an empty array if serialization returns nil" do
+ @model.stubs(:convert_from_multiple).returns nil
- @searcher.search(@request).should == []
- end
+ @searcher.search(@request).should == []
+ end
- it "should generate an error when result data deserializes fails" do
- @searcher.expects(:deserialize).raises(ArgumentError)
- lambda { @searcher.search(@request) }.should raise_error(ArgumentError)
- end
+ it "should generate an error when result data deserializes fails" do
+ @searcher.expects(:deserialize).raises(ArgumentError)
+ lambda { @searcher.search(@request) }.should raise_error(ArgumentError)
end
+ end
- describe "when doing a destroy" do
- before :each do
- @connection = stub('mock http connection', :delete => @response)
- @searcher.stubs(:network).returns(@connection) # neuter the network connection
+ describe "when doing a destroy" do
+ before :each do
+ @connection = stub('mock http connection', :delete => @response)
+ @searcher.stubs(:network).returns(@connection) # neuter the network connection
- @request = Puppet::Indirector::Request.new(:foo, :destroy, "foo bar")
- end
+ @request = Puppet::Indirector::Request.new(:foo, :destroy, "foo bar")
+ end
- it "should call the DELETE http method on a network connection" do
- @searcher.expects(:network).returns @connection
- @connection.expects(:delete).returns @response
- @searcher.destroy(@request)
- end
+ it "should call the DELETE http method on a network connection" do
+ @searcher.expects(:network).returns @connection
+ @connection.expects(:delete).returns @response
+ @searcher.destroy(@request)
+ end
- it "should fail if any options are provided, since DELETE apparently does not support query options" do
- @request.stubs(:options).returns(:one => "two", :three => "four")
+ it "should fail if any options are provided, since DELETE apparently does not support query options" do
+ @request.stubs(:options).returns(:one => "two", :three => "four")
- lambda { @searcher.destroy(@request) }.should raise_error(ArgumentError)
- end
+ lambda { @searcher.destroy(@request) }.should raise_error(ArgumentError)
+ end
- it "should deserialize and return the http response" do
- @connection.expects(:delete).returns @response
- @searcher.expects(:deserialize).with(@response).returns "myobject"
+ it "should deserialize and return the http response" do
+ @connection.expects(:delete).returns @response
+ @searcher.expects(:deserialize).with(@response).returns "myobject"
- @searcher.destroy(@request).should == 'myobject'
- end
+ @searcher.destroy(@request).should == 'myobject'
+ end
- it "should use the URI generated by the Handler module" do
- @searcher.expects(:indirection2uri).with(@request).returns "/my/uri"
- @connection.expects(:delete).with { |path, args| path == "/my/uri" }.returns(@response)
- @searcher.destroy(@request)
- end
+ it "should use the URI generated by the Handler module" do
+ @searcher.expects(:indirection2uri).with(@request).returns "/my/uri"
+ @connection.expects(:delete).with { |path, args| path == "/my/uri" }.returns(@response)
+ @searcher.destroy(@request)
+ end
- it "should not include the query string" do
- @connection.stubs(:delete).returns @response
- @searcher.destroy(@request)
- end
+ it "should not include the query string" do
+ @connection.stubs(:delete).returns @response
+ @searcher.destroy(@request)
+ end
- it "should provide an Accept header containing the list of supported formats joined with commas" do
- @connection.expects(:delete).with { |path, args| args["Accept"] == "supported, formats" }.returns(@response)
+ it "should provide an Accept header containing the list of supported formats joined with commas" do
+ @connection.expects(:delete).with { |path, args| args["Accept"] == "supported, formats" }.returns(@response)
- @searcher.model.expects(:supported_formats).returns %w{supported formats}
- @searcher.destroy(@request)
- end
+ @searcher.model.expects(:supported_formats).returns %w{supported formats}
+ @searcher.destroy(@request)
+ end
- it "should deserialize and return the network response" do
- @searcher.expects(:deserialize).with(@response).returns @instance
- @searcher.destroy(@request).should equal(@instance)
- end
+ it "should deserialize and return the network response" do
+ @searcher.expects(:deserialize).with(@response).returns @instance
+ @searcher.destroy(@request).should equal(@instance)
+ end
- it "should generate an error when result data deserializes fails" do
- @searcher.expects(:deserialize).raises(ArgumentError)
- lambda { @searcher.destroy(@request) }.should raise_error(ArgumentError)
- end
+ it "should generate an error when result data deserializes fails" do
+ @searcher.expects(:deserialize).raises(ArgumentError)
+ lambda { @searcher.destroy(@request) }.should raise_error(ArgumentError)
end
+ end
- describe "when doing a save" do
- before :each do
- @connection = stub('mock http connection', :put => @response)
- @searcher.stubs(:network).returns(@connection) # neuter the network connection
+ describe "when doing a save" do
+ before :each do
+ @connection = stub('mock http connection', :put => @response)
+ @searcher.stubs(:network).returns(@connection) # neuter the network connection
- @instance = stub 'instance', :render => "mydata", :mime => "mime"
- @request = Puppet::Indirector::Request.new(:foo, :save, "foo bar")
- @request.instance = @instance
- end
+ @instance = stub 'instance', :render => "mydata", :mime => "mime"
+ @request = Puppet::Indirector::Request.new(:foo, :save, "foo bar")
+ @request.instance = @instance
+ end
- it "should call the PUT http method on a network connection" do
- @searcher.expects(:network).returns @connection
- @connection.expects(:put).returns @response
- @searcher.save(@request)
- end
+ it "should call the PUT http method on a network connection" do
+ @searcher.expects(:network).returns @connection
+ @connection.expects(:put).returns @response
+ @searcher.save(@request)
+ end
- it "should fail if any options are provided, since DELETE apparently does not support query options" do
- @request.stubs(:options).returns(:one => "two", :three => "four")
+ it "should fail if any options are provided, since DELETE apparently does not support query options" do
+ @request.stubs(:options).returns(:one => "two", :three => "four")
- lambda { @searcher.save(@request) }.should raise_error(ArgumentError)
- end
+ lambda { @searcher.save(@request) }.should raise_error(ArgumentError)
+ end
- it "should use the URI generated by the Handler module" do
- @searcher.expects(:indirection2uri).with(@request).returns "/my/uri"
- @connection.expects(:put).with { |path, args| path == "/my/uri" }.returns(@response)
- @searcher.save(@request)
- end
+ it "should use the URI generated by the Handler module" do
+ @searcher.expects(:indirection2uri).with(@request).returns "/my/uri"
+ @connection.expects(:put).with { |path, args| path == "/my/uri" }.returns(@response)
+ @searcher.save(@request)
+ end
- it "should serialize the instance using the default format and pass the result as the body of the request" do
- @instance.expects(:render).returns "serial_instance"
- @connection.expects(:put).with { |path, data, args| data == "serial_instance" }.returns @response
+ it "should serialize the instance using the default format and pass the result as the body of the request" do
+ @instance.expects(:render).returns "serial_instance"
+ @connection.expects(:put).with { |path, data, args| data == "serial_instance" }.returns @response
- @searcher.save(@request)
- end
+ @searcher.save(@request)
+ end
- it "should deserialize and return the http response" do
- @connection.expects(:put).returns @response
- @searcher.expects(:deserialize).with(@response).returns "myobject"
+ it "should deserialize and return the http response" do
+ @connection.expects(:put).returns @response
+ @searcher.expects(:deserialize).with(@response).returns "myobject"
- @searcher.save(@request).should == 'myobject'
- end
+ @searcher.save(@request).should == 'myobject'
+ end
- it "should provide an Accept header containing the list of supported formats joined with commas" do
- @connection.expects(:put).with { |path, data, args| args["Accept"] == "supported, formats" }.returns(@response)
+ it "should provide an Accept header containing the list of supported formats joined with commas" do
+ @connection.expects(:put).with { |path, data, args| args["Accept"] == "supported, formats" }.returns(@response)
- @searcher.model.expects(:supported_formats).returns %w{supported formats}
- @searcher.save(@request)
- end
+ @searcher.model.expects(:supported_formats).returns %w{supported formats}
+ @searcher.save(@request)
+ end
- it "should provide a Content-Type header containing the mime-type of the sent object" do
- @connection.expects(:put).with { |path, data, args| args['Content-Type'] == "mime" }.returns(@response)
+ it "should provide a Content-Type header containing the mime-type of the sent object" do
+ @connection.expects(:put).with { |path, data, args| args['Content-Type'] == "mime" }.returns(@response)
- @instance.expects(:mime).returns "mime"
- @searcher.save(@request)
- end
+ @instance.expects(:mime).returns "mime"
+ @searcher.save(@request)
+ end
- it "should deserialize and return the network response" do
- @searcher.expects(:deserialize).with(@response).returns @instance
- @searcher.save(@request).should equal(@instance)
- end
+ it "should deserialize and return the network response" do
+ @searcher.expects(:deserialize).with(@response).returns @instance
+ @searcher.save(@request).should equal(@instance)
+ end
- it "should generate an error when result data deserializes fails" do
- @searcher.expects(:deserialize).raises(ArgumentError)
- lambda { @searcher.save(@request) }.should raise_error(ArgumentError)
- end
+ it "should generate an error when result data deserializes fails" do
+ @searcher.expects(:deserialize).raises(ArgumentError)
+ lambda { @searcher.save(@request) }.should raise_error(ArgumentError)
end
+ end
end
diff --git a/spec/unit/indirector/run/local_spec.rb b/spec/unit/indirector/run/local_spec.rb
index face61d..2684096 100644
--- a/spec/unit/indirector/run/local_spec.rb
+++ b/spec/unit/indirector/run/local_spec.rb
@@ -5,16 +5,16 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/run/local'
describe Puppet::Run::Local do
- it "should be a sublcass of Puppet::Indirector::Code" do
- Puppet::Run::Local.superclass.should equal(Puppet::Indirector::Code)
- end
+ it "should be a sublcass of Puppet::Indirector::Code" do
+ Puppet::Run::Local.superclass.should equal(Puppet::Indirector::Code)
+ end
- it "should call runner.run on save and return the runner" do
- runner = Puppet::Run.new
- runner.stubs(:run).returns(runner)
+ it "should call runner.run on save and return the runner" do
+ runner = Puppet::Run.new
+ runner.stubs(:run).returns(runner)
- request = Puppet::Indirector::Request.new(:indirection, :save, "anything")
- request.instance = runner = Puppet::Run.new
- Puppet::Run::Local.new.save(request).should == runner
- end
+ request = Puppet::Indirector::Request.new(:indirection, :save, "anything")
+ request.instance = runner = Puppet::Run.new
+ Puppet::Run::Local.new.save(request).should == runner
+ end
end
diff --git a/spec/unit/indirector/run/rest_spec.rb b/spec/unit/indirector/run/rest_spec.rb
index ee976ed..2b2415a 100755
--- a/spec/unit/indirector/run/rest_spec.rb
+++ b/spec/unit/indirector/run/rest_spec.rb
@@ -5,7 +5,7 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/run/rest'
describe Puppet::Run::Rest do
- it "should be a sublcass of Puppet::Indirector::REST" do
- Puppet::Run::Rest.superclass.should equal(Puppet::Indirector::REST)
- end
+ it "should be a sublcass of Puppet::Indirector::REST" do
+ Puppet::Run::Rest.superclass.should equal(Puppet::Indirector::REST)
+ end
end
diff --git a/spec/unit/indirector/ssl_file_spec.rb b/spec/unit/indirector/ssl_file_spec.rb
index 02c7fcf..83145cf 100755
--- a/spec/unit/indirector/ssl_file_spec.rb
+++ b/spec/unit/indirector/ssl_file_spec.rb
@@ -8,274 +8,274 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector/ssl_file'
describe Puppet::Indirector::SslFile do
+ before do
+ @model = mock 'model'
+ @indirection = stub 'indirection', :name => :testing, :model => @model
+ Puppet::Indirector::Indirection.expects(:instance).with(:testing).returns(@indirection)
+ @file_class = Class.new(Puppet::Indirector::SslFile) do
+ def self.to_s
+ "Testing::Mytype"
+ end
+ end
+
+ @setting = :mydir
+ @file_class.store_in @setting
+ @path = "/my/directory"
+ Puppet.settings.stubs(:value).with(:noop).returns(false)
+ Puppet.settings.stubs(:value).with(@setting).returns(@path)
+ Puppet.settings.stubs(:value).with(:trace).returns(false)
+ end
+
+ it "should use :main and :ssl upon initialization" do
+ Puppet.settings.expects(:use).with(:main, :ssl)
+ @file_class.new
+ end
+
+ it "should return a nil collection directory if no directory setting has been provided" do
+ @file_class.store_in nil
+ @file_class.collection_directory.should be_nil
+ end
+
+ it "should return a nil file location if no location has been provided" do
+ @file_class.store_at nil
+ @file_class.file_location.should be_nil
+ end
+
+ it "should fail if no store directory or file location has been set" do
+ @file_class.store_in nil
+ @file_class.store_at nil
+ lambda { @file_class.new }.should raise_error(Puppet::DevError)
+ end
+
+ describe "when managing ssl files" do
before do
- @model = mock 'model'
- @indirection = stub 'indirection', :name => :testing, :model => @model
- Puppet::Indirector::Indirection.expects(:instance).with(:testing).returns(@indirection)
- @file_class = Class.new(Puppet::Indirector::SslFile) do
- def self.to_s
- "Testing::Mytype"
- end
- end
+ Puppet.settings.stubs(:use)
+ @searcher = @file_class.new
- @setting = :mydir
- @file_class.store_in @setting
- @path = "/my/directory"
- Puppet.settings.stubs(:value).with(:noop).returns(false)
- Puppet.settings.stubs(:value).with(@setting).returns(@path)
- Puppet.settings.stubs(:value).with(:trace).returns(false)
+ @cert = stub 'certificate', :name => "myname"
+ @certpath = File.join(@path, "myname.pem")
+
+ @request = stub 'request', :key => @cert.name, :instance => @cert
end
- it "should use :main and :ssl upon initialization" do
- Puppet.settings.expects(:use).with(:main, :ssl)
- @file_class.new
+ it "should consider the file a ca file if the name is equal to what the SSL::Host class says is the CA name" do
+ Puppet::SSL::Host.expects(:ca_name).returns "amaca"
+ @searcher.should be_ca("amaca")
end
- it "should return a nil collection directory if no directory setting has been provided" do
+ describe "when choosing the location for certificates" do
+ it "should set them at the ca setting's path if a ca setting is available and the name resolves to the CA name" do
@file_class.store_in nil
- @file_class.collection_directory.should be_nil
- end
+ @file_class.store_at :mysetting
+ @file_class.store_ca_at :casetting
- it "should return a nil file location if no location has been provided" do
- @file_class.store_at nil
- @file_class.file_location.should be_nil
- end
+ Puppet.settings.stubs(:value).with(:casetting).returns "/ca/file"
+
+ @searcher.expects(:ca?).with(@cert.name).returns true
+ @searcher.path(@cert.name).should == "/ca/file"
+ end
- it "should fail if no store directory or file location has been set" do
+ it "should set them at the file location if a file setting is available" do
@file_class.store_in nil
- @file_class.store_at nil
- lambda { @file_class.new }.should raise_error(Puppet::DevError)
+ @file_class.store_at :mysetting
+
+ Puppet.settings.stubs(:value).with(:mysetting).returns "/some/file"
+
+ @searcher.path(@cert.name).should == "/some/file"
+ end
+
+ it "should set them in the setting directory, with the certificate name plus '.pem', if a directory setting is available" do
+ @searcher.path(@cert.name).should == @certpath
+ end
end
- describe "when managing ssl files" do
+ describe "when finding certificates on disk" do
+ describe "and no certificate is present" do
+ before do
+ # Stub things so the case management bits work.
+ FileTest.stubs(:exist?).with(File.dirname(@certpath)).returns false
+ FileTest.expects(:exist?).with(@certpath).returns false
+ end
+
+ it "should return nil" do
+ @searcher.find(@request).should be_nil
+ end
+ end
+
+ describe "and a certificate is present" do
before do
- Puppet.settings.stubs(:use)
- @searcher = @file_class.new
+ FileTest.expects(:exist?).with(@certpath).returns true
+ end
- @cert = stub 'certificate', :name => "myname"
- @certpath = File.join(@path, "myname.pem")
+ it "should return an instance of the model, which it should use to read the certificate" do
+ cert = mock 'cert'
+ model = mock 'model'
+ @file_class.stubs(:model).returns model
- @request = stub 'request', :key => @cert.name, :instance => @cert
+ model.expects(:new).with("myname").returns cert
+ cert.expects(:read).with(@certpath)
+ @searcher.find(@request).should equal(cert)
end
+ end
- it "should consider the file a ca file if the name is equal to what the SSL::Host class says is the CA name" do
- Puppet::SSL::Host.expects(:ca_name).returns "amaca"
- @searcher.should be_ca("amaca")
+ describe "and a certificate is present but has uppercase letters" do
+ before do
+ @request = stub 'request', :key => "myhost"
end
- describe "when choosing the location for certificates" do
- it "should set them at the ca setting's path if a ca setting is available and the name resolves to the CA name" do
- @file_class.store_in nil
- @file_class.store_at :mysetting
- @file_class.store_ca_at :casetting
+ # This is kind of more an integration test; it's for #1382, until
+ # the support for upper-case certs can be removed around mid-2009.
+ it "should rename the existing file to the lower-case path" do
+ @path = @searcher.path("myhost")
+ FileTest.expects(:exist?).with(@path).returns(false)
+ dir, file = File.split(@path)
+ FileTest.expects(:exist?).with(dir).returns true
+ Dir.expects(:entries).with(dir).returns [".", "..", "something.pem", file.upcase]
+
+ File.expects(:rename).with(File.join(dir, file.upcase), @path)
+
+ cert = mock 'cert'
+ model = mock 'model'
+ @searcher.stubs(:model).returns model
+ @searcher.model.expects(:new).with("myhost").returns cert
+ cert.expects(:read).with(@path)
- Puppet.settings.stubs(:value).with(:casetting).returns "/ca/file"
+ @searcher.find(@request)
+ end
+ end
+ end
- @searcher.expects(:ca?).with(@cert.name).returns true
- @searcher.path(@cert.name).should == "/ca/file"
- end
+ describe "when saving certificates to disk" do
+ before do
+ FileTest.stubs(:directory?).returns true
+ FileTest.stubs(:writable?).returns true
+ end
+
+ it "should fail if the directory is absent" do
+ FileTest.expects(:directory?).with(File.dirname(@certpath)).returns false
+ lambda { @searcher.save(@request) }.should raise_error(Puppet::Error)
+ end
+
+ it "should fail if the directory is not writeable" do
+ FileTest.stubs(:directory?).returns true
+ FileTest.expects(:writable?).with(File.dirname(@certpath)).returns false
+ lambda { @searcher.save(@request) }.should raise_error(Puppet::Error)
+ end
+
+ it "should save to the path the output of converting the certificate to a string" do
+ fh = mock 'filehandle'
+ fh.expects(:print).with("mycert")
+
+ @searcher.stubs(:write).yields fh
+ @cert.expects(:to_s).returns "mycert"
+
+ @searcher.save(@request)
+ end
+
+ describe "and a directory setting is set" do
+ it "should use the Settings class to write the file" do
+ @searcher.class.store_in @setting
+ fh = mock 'filehandle'
+ fh.stubs :print
+ Puppet.settings.expects(:writesub).with(@setting, @certpath).yields fh
+
+ @searcher.save(@request)
+ end
+ end
- it "should set them at the file location if a file setting is available" do
- @file_class.store_in nil
- @file_class.store_at :mysetting
+ describe "and a file location is set" do
+ it "should use the filehandle provided by the Settings" do
+ @searcher.class.store_at @setting
- Puppet.settings.stubs(:value).with(:mysetting).returns "/some/file"
+ fh = mock 'filehandle'
+ fh.stubs :print
+ Puppet.settings.expects(:write).with(@setting).yields fh
+ @searcher.save(@request)
+ end
+ end
+
+ describe "and the name is the CA name and a ca setting is set" do
+ it "should use the filehandle provided by the Settings" do
+ @searcher.class.store_at @setting
+ @searcher.class.store_ca_at :castuff
+ Puppet.settings.stubs(:value).with(:castuff).returns "castuff stub"
+
+ fh = mock 'filehandle'
+ fh.stubs :print
+ Puppet.settings.expects(:write).with(:castuff).yields fh
+ @searcher.stubs(:ca?).returns true
+ @searcher.save(@request)
+ end
+ end
+ end
- @searcher.path(@cert.name).should == "/some/file"
- end
+ describe "when destroying certificates" do
+ describe "that do not exist" do
+ before do
+ FileTest.expects(:exist?).with(@certpath).returns false
+ end
- it "should set them in the setting directory, with the certificate name plus '.pem', if a directory setting is available" do
- @searcher.path(@cert.name).should == @certpath
- end
+ it "should return false" do
+ @searcher.destroy(@request).should be_false
end
+ end
- describe "when finding certificates on disk" do
- describe "and no certificate is present" do
- before do
- # Stub things so the case management bits work.
- FileTest.stubs(:exist?).with(File.dirname(@certpath)).returns false
- FileTest.expects(:exist?).with(@certpath).returns false
- end
-
- it "should return nil" do
- @searcher.find(@request).should be_nil
- end
- end
-
- describe "and a certificate is present" do
- before do
- FileTest.expects(:exist?).with(@certpath).returns true
- end
-
- it "should return an instance of the model, which it should use to read the certificate" do
- cert = mock 'cert'
- model = mock 'model'
- @file_class.stubs(:model).returns model
-
- model.expects(:new).with("myname").returns cert
- cert.expects(:read).with(@certpath)
- @searcher.find(@request).should equal(cert)
- end
- end
-
- describe "and a certificate is present but has uppercase letters" do
- before do
- @request = stub 'request', :key => "myhost"
- end
-
- # This is kind of more an integration test; it's for #1382, until
- # the support for upper-case certs can be removed around mid-2009.
- it "should rename the existing file to the lower-case path" do
- @path = @searcher.path("myhost")
- FileTest.expects(:exist?).with(@path).returns(false)
- dir, file = File.split(@path)
- FileTest.expects(:exist?).with(dir).returns true
- Dir.expects(:entries).with(dir).returns [".", "..", "something.pem", file.upcase]
-
- File.expects(:rename).with(File.join(dir, file.upcase), @path)
-
- cert = mock 'cert'
- model = mock 'model'
- @searcher.stubs(:model).returns model
- @searcher.model.expects(:new).with("myhost").returns cert
- cert.expects(:read).with(@path)
-
- @searcher.find(@request)
- end
- end
+ describe "that exist" do
+ before do
+ FileTest.expects(:exist?).with(@certpath).returns true
end
- describe "when saving certificates to disk" do
- before do
- FileTest.stubs(:directory?).returns true
- FileTest.stubs(:writable?).returns true
- end
-
- it "should fail if the directory is absent" do
- FileTest.expects(:directory?).with(File.dirname(@certpath)).returns false
- lambda { @searcher.save(@request) }.should raise_error(Puppet::Error)
- end
-
- it "should fail if the directory is not writeable" do
- FileTest.stubs(:directory?).returns true
- FileTest.expects(:writable?).with(File.dirname(@certpath)).returns false
- lambda { @searcher.save(@request) }.should raise_error(Puppet::Error)
- end
-
- it "should save to the path the output of converting the certificate to a string" do
- fh = mock 'filehandle'
- fh.expects(:print).with("mycert")
-
- @searcher.stubs(:write).yields fh
- @cert.expects(:to_s).returns "mycert"
-
- @searcher.save(@request)
- end
-
- describe "and a directory setting is set" do
- it "should use the Settings class to write the file" do
- @searcher.class.store_in @setting
- fh = mock 'filehandle'
- fh.stubs :print
- Puppet.settings.expects(:writesub).with(@setting, @certpath).yields fh
-
- @searcher.save(@request)
- end
- end
-
- describe "and a file location is set" do
- it "should use the filehandle provided by the Settings" do
- @searcher.class.store_at @setting
-
- fh = mock 'filehandle'
- fh.stubs :print
- Puppet.settings.expects(:write).with(@setting).yields fh
- @searcher.save(@request)
- end
- end
-
- describe "and the name is the CA name and a ca setting is set" do
- it "should use the filehandle provided by the Settings" do
- @searcher.class.store_at @setting
- @searcher.class.store_ca_at :castuff
- Puppet.settings.stubs(:value).with(:castuff).returns "castuff stub"
-
- fh = mock 'filehandle'
- fh.stubs :print
- Puppet.settings.expects(:write).with(:castuff).yields fh
- @searcher.stubs(:ca?).returns true
- @searcher.save(@request)
- end
- end
+ it "should unlink the certificate file" do
+ File.expects(:unlink).with(@certpath)
+ @searcher.destroy(@request)
end
- describe "when destroying certificates" do
- describe "that do not exist" do
- before do
- FileTest.expects(:exist?).with(@certpath).returns false
- end
-
- it "should return false" do
- @searcher.destroy(@request).should be_false
- end
- end
-
- describe "that exist" do
- before do
- FileTest.expects(:exist?).with(@certpath).returns true
- end
-
- it "should unlink the certificate file" do
- File.expects(:unlink).with(@certpath)
- @searcher.destroy(@request)
- end
-
- it "should log that is removing the file" do
- File.stubs(:exist?).returns true
- File.stubs(:unlink)
- Puppet.expects(:notice)
- @searcher.destroy(@request)
- end
- end
+ it "should log that is removing the file" do
+ File.stubs(:exist?).returns true
+ File.stubs(:unlink)
+ Puppet.expects(:notice)
+ @searcher.destroy(@request)
end
+ end
+ end
- describe "when searching for certificates" do
- before do
- @model = mock 'model'
- @file_class.stubs(:model).returns @model
- end
- it "should return a certificate instance for all files that exist" do
- Dir.expects(:entries).with(@path).returns %w{one.pem two.pem}
+ describe "when searching for certificates" do
+ before do
+ @model = mock 'model'
+ @file_class.stubs(:model).returns @model
+ end
+ it "should return a certificate instance for all files that exist" do
+ Dir.expects(:entries).with(@path).returns %w{one.pem two.pem}
- one = stub 'one', :read => nil
- two = stub 'two', :read => nil
+ one = stub 'one', :read => nil
+ two = stub 'two', :read => nil
- @model.expects(:new).with("one").returns one
- @model.expects(:new).with("two").returns two
+ @model.expects(:new).with("one").returns one
+ @model.expects(:new).with("two").returns two
- @searcher.search(@request).should == [one, two]
- end
+ @searcher.search(@request).should == [one, two]
+ end
- it "should read each certificate in using the model's :read method" do
- Dir.expects(:entries).with(@path).returns %w{one.pem}
+ it "should read each certificate in using the model's :read method" do
+ Dir.expects(:entries).with(@path).returns %w{one.pem}
- one = stub 'one'
- one.expects(:read).with(File.join(@path, "one.pem"))
+ one = stub 'one'
+ one.expects(:read).with(File.join(@path, "one.pem"))
- @model.expects(:new).with("one").returns one
+ @model.expects(:new).with("one").returns one
- @searcher.search(@request)
- end
+ @searcher.search(@request)
+ end
- it "should skip any files that do not match /\.pem$/" do
- Dir.expects(:entries).with(@path).returns %w{. .. one.pem}
+ it "should skip any files that do not match /\.pem$/" do
+ Dir.expects(:entries).with(@path).returns %w{. .. one.pem}
- one = stub 'one', :read => nil
+ one = stub 'one', :read => nil
- @model.expects(:new).with("one").returns one
+ @model.expects(:new).with("one").returns one
- @searcher.search(@request)
- end
- end
+ @searcher.search(@request)
+ end
end
+ end
end
diff --git a/spec/unit/indirector/status/rest_spec.rb b/spec/unit/indirector/status/rest_spec.rb
index 8f803a2..5eed5fc 100755
--- a/spec/unit/indirector/status/rest_spec.rb
+++ b/spec/unit/indirector/status/rest_spec.rb
@@ -5,7 +5,7 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
require 'puppet/indirector/status/rest'
describe Puppet::Indirector::Status::Rest do
- it "should be a sublcass of Puppet::Indirector::REST" do
- Puppet::Indirector::Status::Rest.superclass.should equal(Puppet::Indirector::REST)
- end
+ it "should be a sublcass of Puppet::Indirector::REST" do
+ Puppet::Indirector::Status::Rest.superclass.should equal(Puppet::Indirector::REST)
+ end
end
diff --git a/spec/unit/indirector/terminus_spec.rb b/spec/unit/indirector/terminus_spec.rb
index 3fcbf9d..826b934 100755
--- a/spec/unit/indirector/terminus_spec.rb
+++ b/spec/unit/indirector/terminus_spec.rb
@@ -6,106 +6,106 @@ require 'puppet/indirector'
require 'puppet/indirector/file'
describe Puppet::Indirector::Terminus do
- before :each do
- Puppet::Indirector::Terminus.stubs(:register_terminus_class)
- @indirection = stub 'indirection', :name => :my_stuff, :register_terminus_type => nil
- Puppet::Indirector::Indirection.stubs(:instance).with(:my_stuff).returns(@indirection)
- @abstract_terminus = Class.new(Puppet::Indirector::Terminus) do
- def self.to_s
- "Testing::Abstract"
- end
- end
- @terminus_class = Class.new(@abstract_terminus) do
- def self.to_s
- "MyStuff::TermType"
- end
- end
- @terminus = @terminus_class.new
+ before :each do
+ Puppet::Indirector::Terminus.stubs(:register_terminus_class)
+ @indirection = stub 'indirection', :name => :my_stuff, :register_terminus_type => nil
+ Puppet::Indirector::Indirection.stubs(:instance).with(:my_stuff).returns(@indirection)
+ @abstract_terminus = Class.new(Puppet::Indirector::Terminus) do
+ def self.to_s
+ "Testing::Abstract"
+ end
end
+ @terminus_class = Class.new(@abstract_terminus) do
+ def self.to_s
+ "MyStuff::TermType"
+ end
+ end
+ @terminus = @terminus_class.new
+ end
- describe Puppet::Indirector::Terminus do
+ describe Puppet::Indirector::Terminus do
- it "should provide a method for setting terminus class documentation" do
- @terminus_class.should respond_to(:desc)
- end
+ it "should provide a method for setting terminus class documentation" do
+ @terminus_class.should respond_to(:desc)
+ end
- it "should support a class-level name attribute" do
- @terminus_class.should respond_to(:name)
- end
+ it "should support a class-level name attribute" do
+ @terminus_class.should respond_to(:name)
+ end
- it "should support a class-level indirection attribute" do
- @terminus_class.should respond_to(:indirection)
- end
+ it "should support a class-level indirection attribute" do
+ @terminus_class.should respond_to(:indirection)
+ end
- it "should support a class-level terminus-type attribute" do
- @terminus_class.should respond_to(:terminus_type)
- end
+ it "should support a class-level terminus-type attribute" do
+ @terminus_class.should respond_to(:terminus_type)
+ end
- it "should support a class-level model attribute" do
- @terminus_class.should respond_to(:model)
- end
+ it "should support a class-level model attribute" do
+ @terminus_class.should respond_to(:model)
+ end
- it "should accept indirection instances as its indirection" do
- indirection = stub 'indirection', :is_a? => true, :register_terminus_type => nil
- proc { @terminus_class.indirection = indirection }.should_not raise_error
- @terminus_class.indirection.should equal(indirection)
- end
+ it "should accept indirection instances as its indirection" do
+ indirection = stub 'indirection', :is_a? => true, :register_terminus_type => nil
+ proc { @terminus_class.indirection = indirection }.should_not raise_error
+ @terminus_class.indirection.should equal(indirection)
+ end
- it "should look up indirection instances when only a name has been provided" do
- indirection = mock 'indirection'
- Puppet::Indirector::Indirection.expects(:instance).with(:myind).returns(indirection)
- @terminus_class.indirection = :myind
- @terminus_class.indirection.should equal(indirection)
- end
+ it "should look up indirection instances when only a name has been provided" do
+ indirection = mock 'indirection'
+ Puppet::Indirector::Indirection.expects(:instance).with(:myind).returns(indirection)
+ @terminus_class.indirection = :myind
+ @terminus_class.indirection.should equal(indirection)
+ end
- it "should fail when provided a name that does not resolve to an indirection" do
- Puppet::Indirector::Indirection.expects(:instance).with(:myind).returns(nil)
- proc { @terminus_class.indirection = :myind }.should raise_error(ArgumentError)
+ it "should fail when provided a name that does not resolve to an indirection" do
+ Puppet::Indirector::Indirection.expects(:instance).with(:myind).returns(nil)
+ proc { @terminus_class.indirection = :myind }.should raise_error(ArgumentError)
- # It shouldn't overwrite our existing one (or, more normally, it shouldn't set
- # anything).
- @terminus_class.indirection.should equal(@indirection)
- end
+ # It shouldn't overwrite our existing one (or, more normally, it shouldn't set
+ # anything).
+ @terminus_class.indirection.should equal(@indirection)
end
+ end
- describe Puppet::Indirector::Terminus, " when creating terminus classes" do
- it "should associate the subclass with an indirection based on the subclass constant" do
- @terminus.indirection.should equal(@indirection)
- end
+ describe Puppet::Indirector::Terminus, " when creating terminus classes" do
+ it "should associate the subclass with an indirection based on the subclass constant" do
+ @terminus.indirection.should equal(@indirection)
+ end
- it "should set the subclass's type to the abstract terminus name" do
- @terminus.terminus_type.should == :abstract
- end
+ it "should set the subclass's type to the abstract terminus name" do
+ @terminus.terminus_type.should == :abstract
+ end
- it "should set the subclass's name to the indirection name" do
- @terminus.name.should == :term_type
- end
+ it "should set the subclass's name to the indirection name" do
+ @terminus.name.should == :term_type
+ end
- it "should set the subclass's model to the indirection model" do
- @indirection.expects(:model).returns :yay
- @terminus.model.should == :yay
- end
+ it "should set the subclass's model to the indirection model" do
+ @indirection.expects(:model).returns :yay
+ @terminus.model.should == :yay
end
+ end
- describe Puppet::Indirector::Terminus, " when a terminus instance" do
+ describe Puppet::Indirector::Terminus, " when a terminus instance" do
- it "should return the class's name as its name" do
- @terminus.name.should == :term_type
- end
+ it "should return the class's name as its name" do
+ @terminus.name.should == :term_type
+ end
- it "should return the class's indirection as its indirection" do
- @terminus.indirection.should equal(@indirection)
- end
+ it "should return the class's indirection as its indirection" do
+ @terminus.indirection.should equal(@indirection)
+ end
- it "should set the instances's type to the abstract terminus type's name" do
- @terminus.terminus_type.should == :abstract
- end
+ it "should set the instances's type to the abstract terminus type's name" do
+ @terminus.terminus_type.should == :abstract
+ end
- it "should set the instances's model to the indirection's model" do
- @indirection.expects(:model).returns :yay
- @terminus.model.should == :yay
- end
+ it "should set the instances's model to the indirection's model" do
+ @indirection.expects(:model).returns :yay
+ @terminus.model.should == :yay
end
+ end
end
# LAK: This could reasonably be in the Indirection instances, too. It doesn't make
@@ -113,133 +113,133 @@ end
# the Terminus base class, we have to have a check to see if we're already
# instance-loading a given terminus class type.
describe Puppet::Indirector::Terminus, " when managing terminus classes" do
- it "should provide a method for registering terminus classes" do
- Puppet::Indirector::Terminus.should respond_to(:register_terminus_class)
- end
-
- it "should provide a method for returning terminus classes by name and type" do
- terminus = stub 'terminus_type', :name => :abstract, :indirection_name => :whatever
- Puppet::Indirector::Terminus.register_terminus_class(terminus)
- Puppet::Indirector::Terminus.terminus_class(:whatever, :abstract).should equal(terminus)
- end
-
- it "should set up autoloading for any terminus class types requested" do
- Puppet::Indirector::Terminus.expects(:instance_load).with(:test2, "puppet/indirector/test2")
- Puppet::Indirector::Terminus.terminus_class(:test2, :whatever)
- end
-
- it "should load terminus classes that are not found" do
- # Set up instance loading; it would normally happen automatically
- Puppet::Indirector::Terminus.instance_load :test1, "puppet/indirector/test1"
-
- Puppet::Indirector::Terminus.instance_loader(:test1).expects(:load).with(:yay)
- Puppet::Indirector::Terminus.terminus_class(:test1, :yay)
- end
+ it "should provide a method for registering terminus classes" do
+ Puppet::Indirector::Terminus.should respond_to(:register_terminus_class)
+ end
- it "should fail when no indirection can be found" do
- Puppet::Indirector::Indirection.expects(:instance).with(:my_indirection).returns(nil)
+ it "should provide a method for returning terminus classes by name and type" do
+ terminus = stub 'terminus_type', :name => :abstract, :indirection_name => :whatever
+ Puppet::Indirector::Terminus.register_terminus_class(terminus)
+ Puppet::Indirector::Terminus.terminus_class(:whatever, :abstract).should equal(terminus)
+ end
- @abstract_terminus = Class.new(Puppet::Indirector::Terminus) do
- def self.to_s
- "Abstract"
- end
- end
- proc {
- @terminus = Class.new(@abstract_terminus) do
- def self.to_s
- "MyIndirection::TestType"
- end
- end
- }.should raise_error(ArgumentError)
- end
-
- it "should register the terminus class with the terminus base class" do
- Puppet::Indirector::Terminus.expects(:register_terminus_class).with do |type|
- type.indirection_name == :my_indirection and type.name == :test_terminus
- end
- @indirection = stub 'indirection', :name => :my_indirection, :register_terminus_type => nil
- Puppet::Indirector::Indirection.expects(:instance).with(:my_indirection).returns(@indirection)
+ it "should set up autoloading for any terminus class types requested" do
+ Puppet::Indirector::Terminus.expects(:instance_load).with(:test2, "puppet/indirector/test2")
+ Puppet::Indirector::Terminus.terminus_class(:test2, :whatever)
+ end
- @abstract_terminus = Class.new(Puppet::Indirector::Terminus) do
- def self.to_s
- "Abstract"
- end
- end
+ it "should load terminus classes that are not found" do
+ # Set up instance loading; it would normally happen automatically
+ Puppet::Indirector::Terminus.instance_load :test1, "puppet/indirector/test1"
- @terminus = Class.new(@abstract_terminus) do
- def self.to_s
- "MyIndirection::TestTerminus"
- end
- end
- end
-end
+ Puppet::Indirector::Terminus.instance_loader(:test1).expects(:load).with(:yay)
+ Puppet::Indirector::Terminus.terminus_class(:test1, :yay)
+ end
-describe Puppet::Indirector::Terminus, " when parsing class constants for indirection and terminus names" do
- before do
- @subclass = mock 'subclass'
- @subclass.stubs(:to_s).returns("TestInd::OneTwo")
- @subclass.stubs(:mark_as_abstract_terminus)
- Puppet::Indirector::Terminus.stubs(:register_terminus_class)
- end
+ it "should fail when no indirection can be found" do
+ Puppet::Indirector::Indirection.expects(:instance).with(:my_indirection).returns(nil)
- it "should fail when anonymous classes are used" do
- proc { Puppet::Indirector::Terminus.inherited(Class.new) }.should raise_error(Puppet::DevError)
- end
-
- it "should use the last term in the constant for the terminus class name" do
- @subclass.expects(:name=).with(:one_two)
- @subclass.stubs(:indirection=)
- Puppet::Indirector::Terminus.inherited(@subclass)
+ @abstract_terminus = Class.new(Puppet::Indirector::Terminus) do
+ def self.to_s
+ "Abstract"
+ end
end
+ proc {
+ @terminus = Class.new(@abstract_terminus) do
+ def self.to_s
+ "MyIndirection::TestType"
+ end
+ end
+ }.should raise_error(ArgumentError)
+ end
- it "should convert the terminus name to a downcased symbol" do
- @subclass.expects(:name=).with(:one_two)
- @subclass.stubs(:indirection=)
- Puppet::Indirector::Terminus.inherited(@subclass)
+ it "should register the terminus class with the terminus base class" do
+ Puppet::Indirector::Terminus.expects(:register_terminus_class).with do |type|
+ type.indirection_name == :my_indirection and type.name == :test_terminus
end
+ @indirection = stub 'indirection', :name => :my_indirection, :register_terminus_type => nil
+ Puppet::Indirector::Indirection.expects(:instance).with(:my_indirection).returns(@indirection)
- it "should use the second to last term in the constant for the indirection name" do
- @subclass.expects(:indirection=).with(:test_ind)
- @subclass.stubs(:name=)
- @subclass.stubs(:terminus_type=)
- Puppet::Indirector::File.inherited(@subclass)
+ @abstract_terminus = Class.new(Puppet::Indirector::Terminus) do
+ def self.to_s
+ "Abstract"
+ end
end
- it "should convert the indirection name to a downcased symbol" do
- @subclass.expects(:indirection=).with(:test_ind)
- @subclass.stubs(:name=)
- @subclass.stubs(:terminus_type=)
- Puppet::Indirector::File.inherited(@subclass)
+ @terminus = Class.new(@abstract_terminus) do
+ def self.to_s
+ "MyIndirection::TestTerminus"
+ end
end
+ end
+end
- it "should convert camel case to lower case with underscores as word separators" do
- @subclass.expects(:name=).with(:one_two)
- @subclass.stubs(:indirection=)
-
- Puppet::Indirector::Terminus.inherited(@subclass)
- end
+describe Puppet::Indirector::Terminus, " when parsing class constants for indirection and terminus names" do
+ before do
+ @subclass = mock 'subclass'
+ @subclass.stubs(:to_s).returns("TestInd::OneTwo")
+ @subclass.stubs(:mark_as_abstract_terminus)
+ Puppet::Indirector::Terminus.stubs(:register_terminus_class)
+ end
+
+ it "should fail when anonymous classes are used" do
+ proc { Puppet::Indirector::Terminus.inherited(Class.new) }.should raise_error(Puppet::DevError)
+ end
+
+ it "should use the last term in the constant for the terminus class name" do
+ @subclass.expects(:name=).with(:one_two)
+ @subclass.stubs(:indirection=)
+ Puppet::Indirector::Terminus.inherited(@subclass)
+ end
+
+ it "should convert the terminus name to a downcased symbol" do
+ @subclass.expects(:name=).with(:one_two)
+ @subclass.stubs(:indirection=)
+ Puppet::Indirector::Terminus.inherited(@subclass)
+ end
+
+ it "should use the second to last term in the constant for the indirection name" do
+ @subclass.expects(:indirection=).with(:test_ind)
+ @subclass.stubs(:name=)
+ @subclass.stubs(:terminus_type=)
+ Puppet::Indirector::File.inherited(@subclass)
+ end
+
+ it "should convert the indirection name to a downcased symbol" do
+ @subclass.expects(:indirection=).with(:test_ind)
+ @subclass.stubs(:name=)
+ @subclass.stubs(:terminus_type=)
+ Puppet::Indirector::File.inherited(@subclass)
+ end
+
+ it "should convert camel case to lower case with underscores as word separators" do
+ @subclass.expects(:name=).with(:one_two)
+ @subclass.stubs(:indirection=)
+
+ Puppet::Indirector::Terminus.inherited(@subclass)
+ end
end
describe Puppet::Indirector::Terminus, " when creating terminus class types" do
- before do
- Puppet::Indirector::Terminus.stubs(:register_terminus_class)
- @subclass = Class.new(Puppet::Indirector::Terminus) do
- def self.to_s
- "Puppet::Indirector::Terminus::MyTermType"
- end
- end
- end
-
- it "should set the name of the abstract subclass to be its class constant" do
- @subclass.name.should equal(:my_term_type)
- end
-
- it "should mark abstract terminus types as such" do
- @subclass.should be_abstract_terminus
- end
-
- it "should not allow instances of abstract subclasses to be created" do
- proc { @subclass.new }.should raise_error(Puppet::DevError)
- end
+ before do
+ Puppet::Indirector::Terminus.stubs(:register_terminus_class)
+ @subclass = Class.new(Puppet::Indirector::Terminus) do
+ def self.to_s
+ "Puppet::Indirector::Terminus::MyTermType"
+ end
+ end
+ end
+
+ it "should set the name of the abstract subclass to be its class constant" do
+ @subclass.name.should equal(:my_term_type)
+ end
+
+ it "should mark abstract terminus types as such" do
+ @subclass.should be_abstract_terminus
+ end
+
+ it "should not allow instances of abstract subclasses to be created" do
+ proc { @subclass.new }.should raise_error(Puppet::DevError)
+ end
end
diff --git a/spec/unit/indirector/yaml_spec.rb b/spec/unit/indirector/yaml_spec.rb
index bd207a8..134d476 100755
--- a/spec/unit/indirector/yaml_spec.rb
+++ b/spec/unit/indirector/yaml_spec.rb
@@ -5,142 +5,142 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector/yaml'
describe Puppet::Indirector::Yaml, " when choosing file location" do
- before :each do
- @indirection = stub 'indirection', :name => :my_yaml, :register_terminus_type => nil
- Puppet::Indirector::Indirection.stubs(:instance).with(:my_yaml).returns(@indirection)
- @store_class = Class.new(Puppet::Indirector::Yaml) do
- def self.to_s
- "MyYaml::MyType"
- end
- end
- @store = @store_class.new
-
- @subject = Object.new
- @subject.singleton_class.send(:attr_accessor, :name)
- @subject.name = :me
-
- @dir = "/what/ever"
- Puppet.settings.stubs(:value).returns("fakesettingdata")
- Puppet.settings.stubs(:value).with(:clientyamldir).returns(@dir)
- Puppet.run_mode.stubs(:master?).returns false
-
- @request = stub 'request', :key => :me, :instance => @subject
+ before :each do
+ @indirection = stub 'indirection', :name => :my_yaml, :register_terminus_type => nil
+ Puppet::Indirector::Indirection.stubs(:instance).with(:my_yaml).returns(@indirection)
+ @store_class = Class.new(Puppet::Indirector::Yaml) do
+ def self.to_s
+ "MyYaml::MyType"
+ end
end
+ @store = @store_class.new
- describe Puppet::Indirector::Yaml, " when choosing file location" do
- it "should use the server_datadir if the run_mode is master" do
- Puppet.run_mode.expects(:master?).returns true
- Puppet.settings.expects(:value).with(:yamldir).returns "/server/yaml/dir"
- @store.path(:me).should =~ %r{^/server/yaml/dir}
- end
-
- it "should use the client yamldir if the run_mode is not master" do
- Puppet.run_mode.expects(:master?).returns false
- Puppet.settings.expects(:value).with(:clientyamldir).returns "/client/yaml/dir"
- @store.path(:me).should =~ %r{^/client/yaml/dir}
- end
-
- it "should store all files in a single file root set in the Puppet defaults" do
- @store.path(:me).should =~ %r{^#{@dir}}
- end
-
- it "should use the terminus name for choosing the subdirectory" do
- @store.path(:me).should =~ %r{^#{@dir}/my_yaml}
- end
-
- it "should use the object's name to determine the file name" do
- @store.path(:me).should =~ %r{me.yaml$}
- end
+ @subject = Object.new
+ @subject.singleton_class.send(:attr_accessor, :name)
+ @subject.name = :me
+
+ @dir = "/what/ever"
+ Puppet.settings.stubs(:value).returns("fakesettingdata")
+ Puppet.settings.stubs(:value).with(:clientyamldir).returns(@dir)
+ Puppet.run_mode.stubs(:master?).returns false
+
+ @request = stub 'request', :key => :me, :instance => @subject
+ end
+
+ describe Puppet::Indirector::Yaml, " when choosing file location" do
+ it "should use the server_datadir if the run_mode is master" do
+ Puppet.run_mode.expects(:master?).returns true
+ Puppet.settings.expects(:value).with(:yamldir).returns "/server/yaml/dir"
+ @store.path(:me).should =~ %r{^/server/yaml/dir}
+ end
+
+ it "should use the client yamldir if the run_mode is not master" do
+ Puppet.run_mode.expects(:master?).returns false
+ Puppet.settings.expects(:value).with(:clientyamldir).returns "/client/yaml/dir"
+ @store.path(:me).should =~ %r{^/client/yaml/dir}
+ end
+
+ it "should store all files in a single file root set in the Puppet defaults" do
+ @store.path(:me).should =~ %r{^#{@dir}}
+ end
+
+ it "should use the terminus name for choosing the subdirectory" do
+ @store.path(:me).should =~ %r{^#{@dir}/my_yaml}
end
- describe Puppet::Indirector::Yaml, " when storing objects as YAML" do
- it "should only store objects that respond to :name" do
- @request.stubs(:instance).returns Object.new
- proc { @store.save(@request) }.should raise_error(ArgumentError)
- end
-
- it "should convert Ruby objects to YAML and write them to disk using a write lock" do
- yaml = @subject.to_yaml
- file = mock 'file'
- path = @store.send(:path, @subject.name)
- FileTest.expects(:exist?).with(File.dirname(path)).returns(true)
- @store.expects(:writelock).with(path, 0660).yields(file)
- file.expects(:print).with(yaml)
-
- @store.save(@request)
- end
-
- it "should create the indirection subdirectory if it does not exist" do
- yaml = @subject.to_yaml
- file = mock 'file'
- path = @store.send(:path, @subject.name)
- dir = File.dirname(path)
-
- FileTest.expects(:exist?).with(dir).returns(false)
- Dir.expects(:mkdir).with(dir)
-
- @store.expects(:writelock).yields(file)
- file.expects(:print).with(yaml)
-
- @store.save(@request)
- end
+ it "should use the object's name to determine the file name" do
+ @store.path(:me).should =~ %r{me.yaml$}
end
+ end
- describe Puppet::Indirector::Yaml, " when retrieving YAML" do
- it "should read YAML in from disk using a read lock and convert it to Ruby objects" do
- path = @store.send(:path, @subject.name)
+ describe Puppet::Indirector::Yaml, " when storing objects as YAML" do
+ it "should only store objects that respond to :name" do
+ @request.stubs(:instance).returns Object.new
+ proc { @store.save(@request) }.should raise_error(ArgumentError)
+ end
- yaml = @subject.to_yaml
- FileTest.expects(:exist?).with(path).returns(true)
+ it "should convert Ruby objects to YAML and write them to disk using a write lock" do
+ yaml = @subject.to_yaml
+ file = mock 'file'
+ path = @store.send(:path, @subject.name)
+ FileTest.expects(:exist?).with(File.dirname(path)).returns(true)
+ @store.expects(:writelock).with(path, 0660).yields(file)
+ file.expects(:print).with(yaml)
- fh = mock 'filehandle'
- @store.expects(:readlock).with(path).yields fh
- fh.expects(:read).returns yaml
+ @store.save(@request)
+ end
- @store.find(@request).instance_variable_get("@name").should == :me
- end
+ it "should create the indirection subdirectory if it does not exist" do
+ yaml = @subject.to_yaml
+ file = mock 'file'
+ path = @store.send(:path, @subject.name)
+ dir = File.dirname(path)
- it "should fail coherently when the stored YAML is invalid" do
- path = @store.send(:path, @subject.name)
- FileTest.expects(:exist?).with(path).returns(true)
+ FileTest.expects(:exist?).with(dir).returns(false)
+ Dir.expects(:mkdir).with(dir)
- # Something that will fail in yaml
- yaml = "--- !ruby/object:Hash"
+ @store.expects(:writelock).yields(file)
+ file.expects(:print).with(yaml)
- fh = mock 'filehandle'
- @store.expects(:readlock).yields fh
- fh.expects(:read).returns yaml
+ @store.save(@request)
+ end
+ end
+
+ describe Puppet::Indirector::Yaml, " when retrieving YAML" do
+ it "should read YAML in from disk using a read lock and convert it to Ruby objects" do
+ path = @store.send(:path, @subject.name)
+
+ yaml = @subject.to_yaml
+ FileTest.expects(:exist?).with(path).returns(true)
+
+ fh = mock 'filehandle'
+ @store.expects(:readlock).with(path).yields fh
+ fh.expects(:read).returns yaml
+
+ @store.find(@request).instance_variable_get("@name").should == :me
+ end
+
+ it "should fail coherently when the stored YAML is invalid" do
+ path = @store.send(:path, @subject.name)
+ FileTest.expects(:exist?).with(path).returns(true)
+
+ # Something that will fail in yaml
+ yaml = "--- !ruby/object:Hash"
+
+ fh = mock 'filehandle'
+ @store.expects(:readlock).yields fh
+ fh.expects(:read).returns yaml
+
+ proc { @store.find(@request) }.should raise_error(Puppet::Error)
+ end
+ end
+
+ describe Puppet::Indirector::Yaml, " when searching" do
+ it "should return an array of fact instances with one instance for each file when globbing *" do
+ @request = stub 'request', :key => "*", :instance => @subject
+ @one = mock 'one'
+ @two = mock 'two'
+ @store.expects(:base).returns "/my/yaml/dir"
+ Dir.expects(:glob).with(File.join("/my/yaml/dir", @store.class.indirection_name.to_s, @request.key)).returns(%w{one.yaml two.yaml})
+ YAML.expects(:load_file).with("one.yaml").returns @one;
+ YAML.expects(:load_file).with("two.yaml").returns @two;
+ @store.search(@request).should == [@one, @two]
+ end
- proc { @store.find(@request) }.should raise_error(Puppet::Error)
- end
+ it "should return an array containing a single instance of fact when globbing 'one*'" do
+ @request = stub 'request', :key => "one*", :instance => @subject
+ @one = mock 'one'
+ @store.expects(:base).returns "/my/yaml/dir"
+ Dir.expects(:glob).with(File.join("/my/yaml/dir", @store.class.indirection_name.to_s, @request.key)).returns(%w{one.yaml})
+ YAML.expects(:load_file).with("one.yaml").returns @one;
+ @store.search(@request).should == [@one]
end
- describe Puppet::Indirector::Yaml, " when searching" do
- it "should return an array of fact instances with one instance for each file when globbing *" do
- @request = stub 'request', :key => "*", :instance => @subject
- @one = mock 'one'
- @two = mock 'two'
- @store.expects(:base).returns "/my/yaml/dir"
- Dir.expects(:glob).with(File.join("/my/yaml/dir", @store.class.indirection_name.to_s, @request.key)).returns(%w{one.yaml two.yaml})
- YAML.expects(:load_file).with("one.yaml").returns @one;
- YAML.expects(:load_file).with("two.yaml").returns @two;
- @store.search(@request).should == [@one, @two]
- end
-
- it "should return an array containing a single instance of fact when globbing 'one*'" do
- @request = stub 'request', :key => "one*", :instance => @subject
- @one = mock 'one'
- @store.expects(:base).returns "/my/yaml/dir"
- Dir.expects(:glob).with(File.join("/my/yaml/dir", @store.class.indirection_name.to_s, @request.key)).returns(%w{one.yaml})
- YAML.expects(:load_file).with("one.yaml").returns @one;
- @store.search(@request).should == [@one]
- end
-
- it "should return an empty array when the glob doesn't match anything" do
- @request = stub 'request', :key => "f*ilglobcanfail*", :instance => @subject
- @store.expects(:base).returns "/my/yaml/dir"
- Dir.expects(:glob).with(File.join("/my/yaml/dir", @store.class.indirection_name.to_s, @request.key)).returns([])
- @store.search(@request).should == []
- end
+ it "should return an empty array when the glob doesn't match anything" do
+ @request = stub 'request', :key => "f*ilglobcanfail*", :instance => @subject
+ @store.expects(:base).returns "/my/yaml/dir"
+ Dir.expects(:glob).with(File.join("/my/yaml/dir", @store.class.indirection_name.to_s, @request.key)).returns([])
+ @store.search(@request).should == []
end
+ end
end
diff --git a/spec/unit/indirector_spec.rb b/spec/unit/indirector_spec.rb
index 806bcec..fb21532 100755
--- a/spec/unit/indirector_spec.rb
+++ b/spec/unit/indirector_spec.rb
@@ -6,152 +6,152 @@ require 'puppet/defaults'
require 'puppet/indirector'
describe Puppet::Indirector, " when available to a model" do
- before do
- @thingie = Class.new do
- extend Puppet::Indirector
- end
+ before do
+ @thingie = Class.new do
+ extend Puppet::Indirector
end
+ end
- it "should provide a way for the model to register an indirection under a name" do
- @thingie.should respond_to(:indirects)
- end
+ it "should provide a way for the model to register an indirection under a name" do
+ @thingie.should respond_to(:indirects)
+ end
end
describe Puppet::Indirector, "when registering an indirection" do
- before do
- @thingie = Class.new do
- extend Puppet::Indirector
- attr_reader :name
- def initialize(name)
- @name = name
- end
- end
- end
-
- it "should require a name when registering a model" do
- Proc.new {@thingie.send(:indirects) }.should raise_error(ArgumentError)
- end
-
- it "should create an indirection instance to manage each indirecting model" do
- @indirection = @thingie.indirects(:test)
- @indirection.should be_instance_of(Puppet::Indirector::Indirection)
- end
-
- it "should not allow a model to register under multiple names" do
- # Keep track of the indirection instance so we can delete it on cleanup
- @indirection = @thingie.indirects :first
- Proc.new { @thingie.indirects :second }.should raise_error(ArgumentError)
- end
-
- it "should make the indirection available via an accessor" do
- @indirection = @thingie.indirects :first
- @thingie.indirection.should equal(@indirection)
- end
-
- it "should pass any provided options to the indirection during initialization" do
- klass = mock 'terminus class'
- Puppet::Indirector::Indirection.expects(:new).with(@thingie, :first, {:some => :options})
- @indirection = @thingie.indirects :first, :some => :options
- end
-
- it "should extend the class with the Format Handler" do
- @indirection = @thingie.indirects :first
- @thingie.singleton_class.ancestors.should be_include(Puppet::Network::FormatHandler)
- end
-
- after do
- @indirection.delete if @indirection
- end
+ before do
+ @thingie = Class.new do
+ extend Puppet::Indirector
+ attr_reader :name
+ def initialize(name)
+ @name = name
+ end
+ end
+ end
+
+ it "should require a name when registering a model" do
+ Proc.new {@thingie.send(:indirects) }.should raise_error(ArgumentError)
+ end
+
+ it "should create an indirection instance to manage each indirecting model" do
+ @indirection = @thingie.indirects(:test)
+ @indirection.should be_instance_of(Puppet::Indirector::Indirection)
+ end
+
+ it "should not allow a model to register under multiple names" do
+ # Keep track of the indirection instance so we can delete it on cleanup
+ @indirection = @thingie.indirects :first
+ Proc.new { @thingie.indirects :second }.should raise_error(ArgumentError)
+ end
+
+ it "should make the indirection available via an accessor" do
+ @indirection = @thingie.indirects :first
+ @thingie.indirection.should equal(@indirection)
+ end
+
+ it "should pass any provided options to the indirection during initialization" do
+ klass = mock 'terminus class'
+ Puppet::Indirector::Indirection.expects(:new).with(@thingie, :first, {:some => :options})
+ @indirection = @thingie.indirects :first, :some => :options
+ end
+
+ it "should extend the class with the Format Handler" do
+ @indirection = @thingie.indirects :first
+ @thingie.singleton_class.ancestors.should be_include(Puppet::Network::FormatHandler)
+ end
+
+ after do
+ @indirection.delete if @indirection
+ end
end
describe "Delegated Indirection Method", :shared => true do
- it "should delegate to the indirection" do
- @indirection.expects(@method)
- @thingie.send(@method, "me")
- end
-
- it "should pass all of the passed arguments directly to the indirection instance" do
- @indirection.expects(@method).with("me", :one => :two)
- @thingie.send(@method, "me", :one => :two)
- end
-
- it "should return the results of the delegation as its result" do
- request = mock 'request'
- @indirection.expects(@method).returns "yay"
- @thingie.send(@method, "me").should == "yay"
- end
+ it "should delegate to the indirection" do
+ @indirection.expects(@method)
+ @thingie.send(@method, "me")
+ end
+
+ it "should pass all of the passed arguments directly to the indirection instance" do
+ @indirection.expects(@method).with("me", :one => :two)
+ @thingie.send(@method, "me", :one => :two)
+ end
+
+ it "should return the results of the delegation as its result" do
+ request = mock 'request'
+ @indirection.expects(@method).returns "yay"
+ @thingie.send(@method, "me").should == "yay"
+ end
end
describe Puppet::Indirector, "when redirecting a model" do
+ before do
+ @thingie = Class.new do
+ extend Puppet::Indirector
+ attr_reader :name
+ def initialize(name)
+ @name = name
+ end
+ end
+ @indirection = @thingie.send(:indirects, :test)
+ end
+
+ it "should include the Envelope module in the model" do
+ @thingie.ancestors.should be_include(Puppet::Indirector::Envelope)
+ end
+
+ describe "when finding instances via the model" do
+ before { @method = :find }
+ it_should_behave_like "Delegated Indirection Method"
+ end
+
+ describe "when destroying instances via the model" do
+ before { @method = :destroy }
+ it_should_behave_like "Delegated Indirection Method"
+ end
+
+ describe "when searching for instances via the model" do
+ before { @method = :search }
+ it_should_behave_like "Delegated Indirection Method"
+ end
+
+ describe "when expiring instances via the model" do
+ before { @method = :expire }
+ it_should_behave_like "Delegated Indirection Method"
+ end
+
+ # This is an instance method, so it behaves a bit differently.
+ describe "when saving instances via the model" do
before do
- @thingie = Class.new do
- extend Puppet::Indirector
- attr_reader :name
- def initialize(name)
- @name = name
- end
- end
- @indirection = @thingie.send(:indirects, :test)
- end
-
- it "should include the Envelope module in the model" do
- @thingie.ancestors.should be_include(Puppet::Indirector::Envelope)
+ @instance = @thingie.new("me")
end
- describe "when finding instances via the model" do
- before { @method = :find }
- it_should_behave_like "Delegated Indirection Method"
- end
-
- describe "when destroying instances via the model" do
- before { @method = :destroy }
- it_should_behave_like "Delegated Indirection Method"
- end
-
- describe "when searching for instances via the model" do
- before { @method = :search }
- it_should_behave_like "Delegated Indirection Method"
+ it "should delegate to the indirection" do
+ @indirection.expects(:save)
+ @instance.save
end
- describe "when expiring instances via the model" do
- before { @method = :expire }
- it_should_behave_like "Delegated Indirection Method"
+ it "should pass the instance and an optional key to the indirection's :save method" do
+ @indirection.expects(:save).with("key", @instance)
+ @instance.save "key"
end
- # This is an instance method, so it behaves a bit differently.
- describe "when saving instances via the model" do
- before do
- @instance = @thingie.new("me")
- end
-
- it "should delegate to the indirection" do
- @indirection.expects(:save)
- @instance.save
- end
-
- it "should pass the instance and an optional key to the indirection's :save method" do
- @indirection.expects(:save).with("key", @instance)
- @instance.save "key"
- end
-
- it "should return the results of the delegation as its result" do
- request = mock 'request'
- @indirection.expects(:save).returns "yay"
- @instance.save.should == "yay"
- end
+ it "should return the results of the delegation as its result" do
+ request = mock 'request'
+ @indirection.expects(:save).returns "yay"
+ @instance.save.should == "yay"
end
+ end
- it "should give the model the ability to set the indirection terminus class" do
- @indirection.expects(:terminus_class=).with(:myterm)
- @thingie.terminus_class = :myterm
- end
+ it "should give the model the ability to set the indirection terminus class" do
+ @indirection.expects(:terminus_class=).with(:myterm)
+ @thingie.terminus_class = :myterm
+ end
- it "should give the model the ability to set the indirection cache class" do
- @indirection.expects(:cache_class=).with(:mycache)
- @thingie.cache_class = :mycache
- end
+ it "should give the model the ability to set the indirection cache class" do
+ @indirection.expects(:cache_class=).with(:mycache)
+ @thingie.cache_class = :mycache
+ end
- after do
- @indirection.delete
- end
+ after do
+ @indirection.delete
+ end
end
diff --git a/spec/unit/module_spec.rb b/spec/unit/module_spec.rb
index 910f74b..c3436df 100755
--- a/spec/unit/module_spec.rb
+++ b/spec/unit/module_spec.rb
@@ -3,545 +3,545 @@
require File.dirname(__FILE__) + '/../spec_helper'
describe Puppet::Module do
- before do
- # This is necessary because of the extra checks we have for the deprecated
- # 'plugins' directory
- FileTest.stubs(:exist?).returns false
- end
+ before do
+ # This is necessary because of the extra checks we have for the deprecated
+ # 'plugins' directory
+ FileTest.stubs(:exist?).returns false
+ end
+
+ it "should have a class method that returns a named module from a given environment" do
+ env = mock 'module'
+ env.expects(:module).with("mymod").returns "yep"
+ Puppet::Node::Environment.expects(:new).with("myenv").returns env
+
+ Puppet::Module.find("mymod", "myenv").should == "yep"
+ end
+
+ it "should return nil if asked for a named module that doesn't exist" do
+ env = mock 'module'
+ env.expects(:module).with("mymod").returns nil
+ Puppet::Node::Environment.expects(:new).with("myenv").returns env
+
+ Puppet::Module.find("mymod", "myenv").should be_nil
+ end
- it "should have a class method that returns a named module from a given environment" do
- env = mock 'module'
- env.expects(:module).with("mymod").returns "yep"
- Puppet::Node::Environment.expects(:new).with("myenv").returns env
+ it "should support a 'version' attribute" do
+ mod = Puppet::Module.new("mymod")
+ mod.version = 1.09
+ mod.version.should == 1.09
+ end
- Puppet::Module.find("mymod", "myenv").should == "yep"
- end
+ it "should support a 'source' attribute" do
+ mod = Puppet::Module.new("mymod")
+ mod.source = "http://foo/bar"
+ mod.source.should == "http://foo/bar"
+ end
- it "should return nil if asked for a named module that doesn't exist" do
- env = mock 'module'
- env.expects(:module).with("mymod").returns nil
- Puppet::Node::Environment.expects(:new).with("myenv").returns env
+ it "should support a 'project_page' attribute" do
+ mod = Puppet::Module.new("mymod")
+ mod.project_page = "http://foo/bar"
+ mod.project_page.should == "http://foo/bar"
+ end
- Puppet::Module.find("mymod", "myenv").should be_nil
- end
+ it "should support an 'author' attribute" do
+ mod = Puppet::Module.new("mymod")
+ mod.author = "Luke Kanies <luke at madstop.com>"
+ mod.author.should == "Luke Kanies <luke at madstop.com>"
+ end
- it "should support a 'version' attribute" do
- mod = Puppet::Module.new("mymod")
- mod.version = 1.09
- mod.version.should == 1.09
- end
+ it "should support a 'license' attribute" do
+ mod = Puppet::Module.new("mymod")
+ mod.license = "GPL2"
+ mod.license.should == "GPL2"
+ end
- it "should support a 'source' attribute" do
- mod = Puppet::Module.new("mymod")
- mod.source = "http://foo/bar"
- mod.source.should == "http://foo/bar"
- end
+ it "should support a 'summary' attribute" do
+ mod = Puppet::Module.new("mymod")
+ mod.summary = "GPL2"
+ mod.summary.should == "GPL2"
+ end
- it "should support a 'project_page' attribute" do
- mod = Puppet::Module.new("mymod")
- mod.project_page = "http://foo/bar"
- mod.project_page.should == "http://foo/bar"
- end
+ it "should support a 'description' attribute" do
+ mod = Puppet::Module.new("mymod")
+ mod.description = "GPL2"
+ mod.description.should == "GPL2"
+ end
- it "should support an 'author' attribute" do
- mod = Puppet::Module.new("mymod")
- mod.author = "Luke Kanies <luke at madstop.com>"
- mod.author.should == "Luke Kanies <luke at madstop.com>"
- end
+ it "should support specifying a compatible puppet version" do
+ mod = Puppet::Module.new("mymod")
+ mod.puppetversion = "0.25"
+ mod.puppetversion.should == "0.25"
+ end
- it "should support a 'license' attribute" do
- mod = Puppet::Module.new("mymod")
- mod.license = "GPL2"
- mod.license.should == "GPL2"
- end
+ it "should validate that the puppet version is compatible" do
+ mod = Puppet::Module.new("mymod")
+ mod.puppetversion = "0.25"
+ Puppet.expects(:version).returns "0.25"
+ mod.validate_puppet_version
+ end
- it "should support a 'summary' attribute" do
- mod = Puppet::Module.new("mymod")
- mod.summary = "GPL2"
- mod.summary.should == "GPL2"
- end
+ it "should fail if the specified puppet version is not compatible" do
+ mod = Puppet::Module.new("mymod")
+ mod.puppetversion = "0.25"
+ Puppet.stubs(:version).returns "0.24"
+ lambda { mod.validate_puppet_version }.should raise_error(Puppet::Module::IncompatibleModule)
+ end
- it "should support a 'description' attribute" do
- mod = Puppet::Module.new("mymod")
- mod.description = "GPL2"
- mod.description.should == "GPL2"
+ describe "when specifying required modules" do
+ it "should support specifying a required module" do
+ mod = Puppet::Module.new("mymod")
+ mod.requires "foobar"
end
- it "should support specifying a compatible puppet version" do
- mod = Puppet::Module.new("mymod")
- mod.puppetversion = "0.25"
- mod.puppetversion.should == "0.25"
+ it "should support specifying multiple required modules" do
+ mod = Puppet::Module.new("mymod")
+ mod.requires "foobar"
+ mod.requires "baz"
end
- it "should validate that the puppet version is compatible" do
- mod = Puppet::Module.new("mymod")
- mod.puppetversion = "0.25"
- Puppet.expects(:version).returns "0.25"
- mod.validate_puppet_version
+ it "should support specifying a required module and version" do
+ mod = Puppet::Module.new("mymod")
+ mod.requires "foobar", 1.0
end
- it "should fail if the specified puppet version is not compatible" do
- mod = Puppet::Module.new("mymod")
- mod.puppetversion = "0.25"
- Puppet.stubs(:version).returns "0.24"
- lambda { mod.validate_puppet_version }.should raise_error(Puppet::Module::IncompatibleModule)
+ it "should fail when required modules are missing" do
+ mod = Puppet::Module.new("mymod")
+ mod.requires "foobar"
+
+ mod.environment.expects(:module).with("foobar").returns nil
+
+ lambda { mod.validate_dependencies }.should raise_error(Puppet::Module::MissingModule)
end
- describe "when specifying required modules" do
- it "should support specifying a required module" do
- mod = Puppet::Module.new("mymod")
- mod.requires "foobar"
- end
+ it "should fail when required modules are present but of the wrong version" do
+ mod = Puppet::Module.new("mymod")
+ mod.requires "foobar", 1.0
- it "should support specifying multiple required modules" do
- mod = Puppet::Module.new("mymod")
- mod.requires "foobar"
- mod.requires "baz"
- end
+ foobar = Puppet::Module.new("foobar")
+ foobar.version = 2.0
- it "should support specifying a required module and version" do
- mod = Puppet::Module.new("mymod")
- mod.requires "foobar", 1.0
- end
+ mod.environment.expects(:module).with("foobar").returns foobar
- it "should fail when required modules are missing" do
- mod = Puppet::Module.new("mymod")
- mod.requires "foobar"
+ lambda { mod.validate_dependencies }.should raise_error(Puppet::Module::IncompatibleModule)
+ end
- mod.environment.expects(:module).with("foobar").returns nil
+ it "should have valid dependencies when no dependencies have been specified" do
+ mod = Puppet::Module.new("mymod")
- lambda { mod.validate_dependencies }.should raise_error(Puppet::Module::MissingModule)
- end
+ lambda { mod.validate_dependencies }.should_not raise_error
+ end
- it "should fail when required modules are present but of the wrong version" do
- mod = Puppet::Module.new("mymod")
- mod.requires "foobar", 1.0
+ it "should fail when some dependencies are present but others aren't" do
+ mod = Puppet::Module.new("mymod")
+ mod.requires "foobar"
+ mod.requires "baz"
- foobar = Puppet::Module.new("foobar")
- foobar.version = 2.0
+ mod.environment.expects(:module).with("foobar").returns Puppet::Module.new("foobar")
+ mod.environment.expects(:module).with("baz").returns nil
- mod.environment.expects(:module).with("foobar").returns foobar
+ lambda { mod.validate_dependencies }.should raise_error(Puppet::Module::MissingModule)
+ end
- lambda { mod.validate_dependencies }.should raise_error(Puppet::Module::IncompatibleModule)
- end
+ it "should have valid dependencies when all dependencies are met" do
+ mod = Puppet::Module.new("mymod")
+ mod.requires "foobar", 1.0
+ mod.requires "baz"
- it "should have valid dependencies when no dependencies have been specified" do
- mod = Puppet::Module.new("mymod")
+ foobar = Puppet::Module.new("foobar")
+ foobar.version = 1.0
- lambda { mod.validate_dependencies }.should_not raise_error
- end
+ baz = Puppet::Module.new("baz")
- it "should fail when some dependencies are present but others aren't" do
- mod = Puppet::Module.new("mymod")
- mod.requires "foobar"
- mod.requires "baz"
+ mod.environment.expects(:module).with("foobar").returns foobar
+ mod.environment.expects(:module).with("baz").returns baz
- mod.environment.expects(:module).with("foobar").returns Puppet::Module.new("foobar")
- mod.environment.expects(:module).with("baz").returns nil
+ lambda { mod.validate_dependencies }.should_not raise_error
+ end
- lambda { mod.validate_dependencies }.should raise_error(Puppet::Module::MissingModule)
- end
+ it "should validate its dependendencies on initialization" do
+ Puppet::Module.any_instance.expects(:validate_dependencies)
+ Puppet::Module.new("mymod")
+ end
+ end
- it "should have valid dependencies when all dependencies are met" do
- mod = Puppet::Module.new("mymod")
- mod.requires "foobar", 1.0
- mod.requires "baz"
+ describe "when managing supported platforms" do
+ it "should support specifying a supported platform" do
+ mod = Puppet::Module.new("mymod")
+ mod.supports "solaris"
+ end
- foobar = Puppet::Module.new("foobar")
- foobar.version = 1.0
+ it "should support specifying a supported platform and version" do
+ mod = Puppet::Module.new("mymod")
+ mod.supports "solaris", 1.0
+ end
+
+ it "should fail when not running on a supported platform" do
+ pending "Not sure how to send client platform to the module"
+ mod = Puppet::Module.new("mymod")
+ Facter.expects(:value).with("operatingsystem").returns "Solaris"
- baz = Puppet::Module.new("baz")
+ mod.supports "hpux"
- mod.environment.expects(:module).with("foobar").returns foobar
- mod.environment.expects(:module).with("baz").returns baz
+ lambda { mod.validate_supported_platform }.should raise_error(Puppet::Module::UnsupportedPlatform)
+ end
- lambda { mod.validate_dependencies }.should_not raise_error
- end
+ it "should fail when supported platforms are present but of the wrong version" do
+ pending "Not sure how to send client platform to the module"
+ mod = Puppet::Module.new("mymod")
+ Facter.expects(:value).with("operatingsystem").returns "Solaris"
+ Facter.expects(:value).with("operatingsystemrelease").returns 2.0
- it "should validate its dependendencies on initialization" do
- Puppet::Module.any_instance.expects(:validate_dependencies)
- Puppet::Module.new("mymod")
- end
+ mod.supports "Solaris", 1.0
+
+ lambda { mod.validate_supported_platform }.should raise_error(Puppet::Module::IncompatiblePlatform)
end
- describe "when managing supported platforms" do
- it "should support specifying a supported platform" do
- mod = Puppet::Module.new("mymod")
- mod.supports "solaris"
- end
+ it "should be considered supported when no supported platforms have been specified" do
+ pending "Not sure how to send client platform to the module"
+ mod = Puppet::Module.new("mymod")
+ lambda { mod.validate_supported_platform }.should_not raise_error
+ end
- it "should support specifying a supported platform and version" do
- mod = Puppet::Module.new("mymod")
- mod.supports "solaris", 1.0
- end
+ it "should be considered supported when running on a supported platform" do
+ pending "Not sure how to send client platform to the module"
+ mod = Puppet::Module.new("mymod")
+ Facter.expects(:value).with("operatingsystem").returns "Solaris"
+ Facter.expects(:value).with("operatingsystemrelease").returns 2.0
- it "should fail when not running on a supported platform" do
- pending "Not sure how to send client platform to the module"
- mod = Puppet::Module.new("mymod")
- Facter.expects(:value).with("operatingsystem").returns "Solaris"
+ mod.supports "Solaris", 1.0
- mod.supports "hpux"
+ lambda { mod.validate_supported_platform }.should raise_error(Puppet::Module::IncompatiblePlatform)
+ end
- lambda { mod.validate_supported_platform }.should raise_error(Puppet::Module::UnsupportedPlatform)
- end
+ it "should be considered supported when running on any of multiple supported platforms" do
+ pending "Not sure how to send client platform to the module"
+ end
- it "should fail when supported platforms are present but of the wrong version" do
- pending "Not sure how to send client platform to the module"
- mod = Puppet::Module.new("mymod")
- Facter.expects(:value).with("operatingsystem").returns "Solaris"
- Facter.expects(:value).with("operatingsystemrelease").returns 2.0
+ it "should validate its platform support on initialization" do
+ pending "Not sure how to send client platform to the module"
+ end
+ end
- mod.supports "Solaris", 1.0
+ it "should return nil if asked for a module whose name is 'nil'" do
+ Puppet::Module.find(nil, "myenv").should be_nil
+ end
- lambda { mod.validate_supported_platform }.should raise_error(Puppet::Module::IncompatiblePlatform)
- end
+ it "should provide support for logging" do
+ Puppet::Module.ancestors.should be_include(Puppet::Util::Logging)
+ end
- it "should be considered supported when no supported platforms have been specified" do
- pending "Not sure how to send client platform to the module"
- mod = Puppet::Module.new("mymod")
- lambda { mod.validate_supported_platform }.should_not raise_error
- end
+ it "should be able to be converted to a string" do
+ Puppet::Module.new("foo").to_s.should == "Module foo"
+ end
- it "should be considered supported when running on a supported platform" do
- pending "Not sure how to send client platform to the module"
- mod = Puppet::Module.new("mymod")
- Facter.expects(:value).with("operatingsystem").returns "Solaris"
- Facter.expects(:value).with("operatingsystemrelease").returns 2.0
+ it "should add the path to its string form if the module is found" do
+ mod = Puppet::Module.new("foo")
+ mod.stubs(:path).returns "/a"
+ mod.to_s.should == "Module foo(/a)"
+ end
- mod.supports "Solaris", 1.0
+ it "should fail if its name is not alphanumeric" do
+ lambda { Puppet::Module.new(".something") }.should raise_error(Puppet::Module::InvalidName)
+ end
- lambda { mod.validate_supported_platform }.should raise_error(Puppet::Module::IncompatiblePlatform)
- end
+ it "should require a name at initialization" do
+ lambda { Puppet::Module.new }.should raise_error(ArgumentError)
+ end
- it "should be considered supported when running on any of multiple supported platforms" do
- pending "Not sure how to send client platform to the module"
- end
+ it "should convert an environment name into an Environment instance" do
+ Puppet::Module.new("foo", "prod").environment.should be_instance_of(Puppet::Node::Environment)
+ end
- it "should validate its platform support on initialization" do
- pending "Not sure how to send client platform to the module"
- end
- end
+ it "should accept an environment at initialization" do
+ Puppet::Module.new("foo", :prod).environment.name.should == :prod
+ end
- it "should return nil if asked for a module whose name is 'nil'" do
- Puppet::Module.find(nil, "myenv").should be_nil
- end
+ it "should use the default environment if none is provided" do
+ env = Puppet::Node::Environment.new
+ Puppet::Module.new("foo").environment.should equal(env)
+ end
- it "should provide support for logging" do
- Puppet::Module.ancestors.should be_include(Puppet::Util::Logging)
- end
+ it "should use any provided Environment instance" do
+ env = Puppet::Node::Environment.new
+ Puppet::Module.new("foo", env).environment.should equal(env)
+ end
- it "should be able to be converted to a string" do
- Puppet::Module.new("foo").to_s.should == "Module foo"
- end
+ it "should return the path to the first found instance in its environment's module paths as its path" do
+ mod = Puppet::Module.new("foo")
+ env = mock 'environment'
+ mod.stubs(:environment).returns env
- it "should add the path to its string form if the module is found" do
- mod = Puppet::Module.new("foo")
- mod.stubs(:path).returns "/a"
- mod.to_s.should == "Module foo(/a)"
- end
+ env.expects(:modulepath).returns %w{/a /b /c}
- it "should fail if its name is not alphanumeric" do
- lambda { Puppet::Module.new(".something") }.should raise_error(Puppet::Module::InvalidName)
- end
+ FileTest.expects(:exist?).with("/a/foo").returns false
+ FileTest.expects(:exist?).with("/b/foo").returns true
+ FileTest.expects(:exist?).with("/c/foo").never
- it "should require a name at initialization" do
- lambda { Puppet::Module.new }.should raise_error(ArgumentError)
- end
+ mod.path.should == "/b/foo"
+ end
- it "should convert an environment name into an Environment instance" do
- Puppet::Module.new("foo", "prod").environment.should be_instance_of(Puppet::Node::Environment)
- end
+ it "should be considered existent if it exists in at least one module path" do
+ mod = Puppet::Module.new("foo")
+ mod.expects(:path).returns "/a/foo"
+ mod.should be_exist
+ end
- it "should accept an environment at initialization" do
- Puppet::Module.new("foo", :prod).environment.name.should == :prod
- end
+ it "should be considered nonexistent if it does not exist in any of the module paths" do
+ mod = Puppet::Module.new("foo")
+ mod.expects(:path).returns nil
+ mod.should_not be_exist
+ end
- it "should use the default environment if none is provided" do
- env = Puppet::Node::Environment.new
- Puppet::Module.new("foo").environment.should equal(env)
+ [:plugins, :templates, :files, :manifests].each do |filetype|
+ dirname = filetype == :plugins ? "lib" : filetype.to_s
+ it "should be able to return individual #{filetype}" do
+ mod = Puppet::Module.new("foo")
+ mod.stubs(:path).returns "/a/foo"
+ path = File.join("/a/foo", dirname, "my/file")
+ FileTest.expects(:exist?).with(path).returns true
+ mod.send(filetype.to_s.sub(/s$/, ''), "my/file").should == path
end
- it "should use any provided Environment instance" do
- env = Puppet::Node::Environment.new
- Puppet::Module.new("foo", env).environment.should equal(env)
+ it "should consider #{filetype} to be present if their base directory exists" do
+ mod = Puppet::Module.new("foo")
+ mod.stubs(:path).returns "/a/foo"
+ path = File.join("/a/foo", dirname)
+ FileTest.expects(:exist?).with(path).returns true
+ mod.send(filetype.to_s + "?").should be_true
end
- it "should return the path to the first found instance in its environment's module paths as its path" do
- mod = Puppet::Module.new("foo")
- env = mock 'environment'
- mod.stubs(:environment).returns env
-
- env.expects(:modulepath).returns %w{/a /b /c}
-
- FileTest.expects(:exist?).with("/a/foo").returns false
- FileTest.expects(:exist?).with("/b/foo").returns true
- FileTest.expects(:exist?).with("/c/foo").never
+ it "should consider #{filetype} to be absent if their base directory does not exist" do
+ mod = Puppet::Module.new("foo")
+ mod.stubs(:path).returns "/a/foo"
+ path = File.join("/a/foo", dirname)
+ FileTest.expects(:exist?).with(path).returns false
+ mod.send(filetype.to_s + "?").should be_false
+ end
- mod.path.should == "/b/foo"
+ it "should consider #{filetype} to be absent if the module base directory does not exist" do
+ mod = Puppet::Module.new("foo")
+ mod.stubs(:path).returns nil
+ mod.send(filetype.to_s + "?").should be_false
end
- it "should be considered existent if it exists in at least one module path" do
- mod = Puppet::Module.new("foo")
- mod.expects(:path).returns "/a/foo"
- mod.should be_exist
+ it "should return nil if asked to return individual #{filetype} that don't exist" do
+ mod = Puppet::Module.new("foo")
+ mod.stubs(:path).returns "/a/foo"
+ path = File.join("/a/foo", dirname, "my/file")
+ FileTest.expects(:exist?).with(path).returns false
+ mod.send(filetype.to_s.sub(/s$/, ''), "my/file").should be_nil
end
- it "should be considered nonexistent if it does not exist in any of the module paths" do
- mod = Puppet::Module.new("foo")
- mod.expects(:path).returns nil
- mod.should_not be_exist
+ it "should return nil when asked for individual #{filetype} if the module does not exist" do
+ mod = Puppet::Module.new("foo")
+ mod.stubs(:path).returns nil
+ mod.send(filetype.to_s.sub(/s$/, ''), "my/file").should be_nil
end
- [:plugins, :templates, :files, :manifests].each do |filetype|
- dirname = filetype == :plugins ? "lib" : filetype.to_s
- it "should be able to return individual #{filetype}" do
- mod = Puppet::Module.new("foo")
- mod.stubs(:path).returns "/a/foo"
- path = File.join("/a/foo", dirname, "my/file")
- FileTest.expects(:exist?).with(path).returns true
- mod.send(filetype.to_s.sub(/s$/, ''), "my/file").should == path
- end
-
- it "should consider #{filetype} to be present if their base directory exists" do
- mod = Puppet::Module.new("foo")
- mod.stubs(:path).returns "/a/foo"
- path = File.join("/a/foo", dirname)
- FileTest.expects(:exist?).with(path).returns true
- mod.send(filetype.to_s + "?").should be_true
- end
-
- it "should consider #{filetype} to be absent if their base directory does not exist" do
- mod = Puppet::Module.new("foo")
- mod.stubs(:path).returns "/a/foo"
- path = File.join("/a/foo", dirname)
- FileTest.expects(:exist?).with(path).returns false
- mod.send(filetype.to_s + "?").should be_false
- end
-
- it "should consider #{filetype} to be absent if the module base directory does not exist" do
- mod = Puppet::Module.new("foo")
- mod.stubs(:path).returns nil
- mod.send(filetype.to_s + "?").should be_false
- end
-
- it "should return nil if asked to return individual #{filetype} that don't exist" do
- mod = Puppet::Module.new("foo")
- mod.stubs(:path).returns "/a/foo"
- path = File.join("/a/foo", dirname, "my/file")
- FileTest.expects(:exist?).with(path).returns false
- mod.send(filetype.to_s.sub(/s$/, ''), "my/file").should be_nil
- end
-
- it "should return nil when asked for individual #{filetype} if the module does not exist" do
- mod = Puppet::Module.new("foo")
- mod.stubs(:path).returns nil
- mod.send(filetype.to_s.sub(/s$/, ''), "my/file").should be_nil
- end
-
- it "should return the base directory if asked for a nil path" do
- mod = Puppet::Module.new("foo")
- mod.stubs(:path).returns "/a/foo"
- base = File.join("/a/foo", dirname)
- FileTest.expects(:exist?).with(base).returns true
- mod.send(filetype.to_s.sub(/s$/, ''), nil).should == base
- end
+ it "should return the base directory if asked for a nil path" do
+ mod = Puppet::Module.new("foo")
+ mod.stubs(:path).returns "/a/foo"
+ base = File.join("/a/foo", dirname)
+ FileTest.expects(:exist?).with(base).returns true
+ mod.send(filetype.to_s.sub(/s$/, ''), nil).should == base
end
+ end
- %w{plugins files}.each do |filetype|
- short = filetype.sub(/s$/, '')
- dirname = filetype == "plugins" ? "lib" : filetype.to_s
- it "should be able to return the #{short} directory" do
- Puppet::Module.new("foo").should respond_to(short + "_directory")
- end
+ %w{plugins files}.each do |filetype|
+ short = filetype.sub(/s$/, '')
+ dirname = filetype == "plugins" ? "lib" : filetype.to_s
+ it "should be able to return the #{short} directory" do
+ Puppet::Module.new("foo").should respond_to(short + "_directory")
+ end
- it "should return the path to the #{short} directory" do
- mod = Puppet::Module.new("foo")
- mod.stubs(:path).returns "/a/foo"
+ it "should return the path to the #{short} directory" do
+ mod = Puppet::Module.new("foo")
+ mod.stubs(:path).returns "/a/foo"
- mod.send(short + "_directory").should == "/a/foo/#{dirname}"
- end
+ mod.send(short + "_directory").should == "/a/foo/#{dirname}"
end
+ end
- it "should throw a warning if plugins are in a 'plugins' directory rather than a 'lib' directory" do
- mod = Puppet::Module.new("foo")
- mod.stubs(:path).returns "/a/foo"
- FileTest.expects(:exist?).with("/a/foo/plugins").returns true
+ it "should throw a warning if plugins are in a 'plugins' directory rather than a 'lib' directory" do
+ mod = Puppet::Module.new("foo")
+ mod.stubs(:path).returns "/a/foo"
+ FileTest.expects(:exist?).with("/a/foo/plugins").returns true
- mod.expects(:warning)
+ mod.expects(:warning)
- mod.plugin_directory.should == "/a/foo/plugins"
- end
+ mod.plugin_directory.should == "/a/foo/plugins"
+ end
- it "should default to 'lib' for the plugins directory" do
- mod = Puppet::Module.new("foo")
- mod.stubs(:path).returns "/a/foo"
- mod.plugin_directory.should == "/a/foo/lib"
- end
+ it "should default to 'lib' for the plugins directory" do
+ mod = Puppet::Module.new("foo")
+ mod.stubs(:path).returns "/a/foo"
+ mod.plugin_directory.should == "/a/foo/lib"
+ end
end
describe Puppet::Module, " when building its search path" do
- it "should use the current environment's search path if no environment is specified" do
- env = mock 'env'
- env.expects(:modulepath).returns "eh"
- Puppet::Node::Environment.expects(:new).with(nil).returns env
+ it "should use the current environment's search path if no environment is specified" do
+ env = mock 'env'
+ env.expects(:modulepath).returns "eh"
+ Puppet::Node::Environment.expects(:new).with(nil).returns env
- Puppet::Module.modulepath.should == "eh"
- end
+ Puppet::Module.modulepath.should == "eh"
+ end
- it "should use the specified environment's search path if an environment is specified" do
- env = mock 'env'
- env.expects(:modulepath).returns "eh"
- Puppet::Node::Environment.expects(:new).with("foo").returns env
+ it "should use the specified environment's search path if an environment is specified" do
+ env = mock 'env'
+ env.expects(:modulepath).returns "eh"
+ Puppet::Node::Environment.expects(:new).with("foo").returns env
- Puppet::Module.modulepath("foo").should == "eh"
- end
+ Puppet::Module.modulepath("foo").should == "eh"
+ end
end
describe Puppet::Module, "when finding matching manifests" do
- before do
- @mod = Puppet::Module.new("mymod")
- @mod.stubs(:path).returns "/a"
- @pq_glob_with_extension = "yay/*.xx"
- @fq_glob_with_extension = "/a/manifests/#{@pq_glob_with_extension}"
- end
+ before do
+ @mod = Puppet::Module.new("mymod")
+ @mod.stubs(:path).returns "/a"
+ @pq_glob_with_extension = "yay/*.xx"
+ @fq_glob_with_extension = "/a/manifests/#{@pq_glob_with_extension}"
+ end
- it "should return all manifests matching the glob pattern" do
- Dir.expects(:glob).with(@fq_glob_with_extension).returns(%w{foo bar})
- FileTest.stubs(:directory?).returns false
+ it "should return all manifests matching the glob pattern" do
+ Dir.expects(:glob).with(@fq_glob_with_extension).returns(%w{foo bar})
+ FileTest.stubs(:directory?).returns false
- @mod.match_manifests(@pq_glob_with_extension).should == %w{foo bar}
- end
+ @mod.match_manifests(@pq_glob_with_extension).should == %w{foo bar}
+ end
- it "should not return directories" do
- Dir.expects(:glob).with(@fq_glob_with_extension).returns(%w{foo bar})
+ it "should not return directories" do
+ Dir.expects(:glob).with(@fq_glob_with_extension).returns(%w{foo bar})
- FileTest.expects(:directory?).with("foo").returns false
- FileTest.expects(:directory?).with("bar").returns true
- @mod.match_manifests(@pq_glob_with_extension).should == %w{foo}
- end
+ FileTest.expects(:directory?).with("foo").returns false
+ FileTest.expects(:directory?).with("bar").returns true
+ @mod.match_manifests(@pq_glob_with_extension).should == %w{foo}
+ end
- it "should default to the 'init' file if no glob pattern is specified" do
- Dir.expects(:glob).with("/a/manifests/init.{pp,rb}").returns(%w{/a/manifests/init.pp})
+ it "should default to the 'init' file if no glob pattern is specified" do
+ Dir.expects(:glob).with("/a/manifests/init.{pp,rb}").returns(%w{/a/manifests/init.pp})
- @mod.match_manifests(nil).should == %w{/a/manifests/init.pp}
- end
+ @mod.match_manifests(nil).should == %w{/a/manifests/init.pp}
+ end
- it "should return all manifests matching the glob pattern in all existing paths" do
- Dir.expects(:glob).with(@fq_glob_with_extension).returns(%w{a b})
+ it "should return all manifests matching the glob pattern in all existing paths" do
+ Dir.expects(:glob).with(@fq_glob_with_extension).returns(%w{a b})
- @mod.match_manifests(@pq_glob_with_extension).should == %w{a b}
- end
+ @mod.match_manifests(@pq_glob_with_extension).should == %w{a b}
+ end
- it "should match the glob pattern plus '.{pp,rb}' if no extention is specified" do
- Dir.expects(:glob).with("/a/manifests/yay/foo.{pp,rb}").returns(%w{yay})
+ it "should match the glob pattern plus '.{pp,rb}' if no extention is specified" do
+ Dir.expects(:glob).with("/a/manifests/yay/foo.{pp,rb}").returns(%w{yay})
- @mod.match_manifests("yay/foo").should == %w{yay}
- end
+ @mod.match_manifests("yay/foo").should == %w{yay}
+ end
- it "should return an empty array if no manifests matched" do
- Dir.expects(:glob).with(@fq_glob_with_extension).returns([])
+ it "should return an empty array if no manifests matched" do
+ Dir.expects(:glob).with(@fq_glob_with_extension).returns([])
- @mod.match_manifests(@pq_glob_with_extension).should == []
- end
+ @mod.match_manifests(@pq_glob_with_extension).should == []
+ end
end
describe Puppet::Module do
- before do
- Puppet::Module.any_instance.stubs(:path).returns "/my/mod/path"
- @module = Puppet::Module.new("foo")
- end
+ before do
+ Puppet::Module.any_instance.stubs(:path).returns "/my/mod/path"
+ @module = Puppet::Module.new("foo")
+ end
- it "should use 'License' in its current path as its metadata file" do
- @module.license_file.should == "/my/mod/path/License"
- end
+ it "should use 'License' in its current path as its metadata file" do
+ @module.license_file.should == "/my/mod/path/License"
+ end
- it "should return nil as its license file when the module has no path" do
- Puppet::Module.any_instance.stubs(:path).returns nil
- Puppet::Module.new("foo").license_file.should be_nil
- end
+ it "should return nil as its license file when the module has no path" do
+ Puppet::Module.any_instance.stubs(:path).returns nil
+ Puppet::Module.new("foo").license_file.should be_nil
+ end
- it "should cache the license file" do
- Puppet::Module.any_instance.expects(:path).once.returns nil
- mod = Puppet::Module.new("foo")
- mod.license_file.should == mod.license_file
- end
+ it "should cache the license file" do
+ Puppet::Module.any_instance.expects(:path).once.returns nil
+ mod = Puppet::Module.new("foo")
+ mod.license_file.should == mod.license_file
+ end
- it "should use 'metadata.json' in its current path as its metadata file" do
- @module.metadata_file.should == "/my/mod/path/metadata.json"
- end
+ it "should use 'metadata.json' in its current path as its metadata file" do
+ @module.metadata_file.should == "/my/mod/path/metadata.json"
+ end
- it "should return nil as its metadata file when the module has no path" do
- Puppet::Module.any_instance.stubs(:path).returns nil
- Puppet::Module.new("foo").metadata_file.should be_nil
- end
+ it "should return nil as its metadata file when the module has no path" do
+ Puppet::Module.any_instance.stubs(:path).returns nil
+ Puppet::Module.new("foo").metadata_file.should be_nil
+ end
- it "should cache the metadata file" do
- Puppet::Module.any_instance.expects(:path).once.returns nil
- mod = Puppet::Module.new("foo")
- mod.metadata_file.should == mod.metadata_file
- end
+ it "should cache the metadata file" do
+ Puppet::Module.any_instance.expects(:path).once.returns nil
+ mod = Puppet::Module.new("foo")
+ mod.metadata_file.should == mod.metadata_file
+ end
- it "should know if it has a metadata file" do
- FileTest.expects(:exist?).with(@module.metadata_file).returns true
+ it "should know if it has a metadata file" do
+ FileTest.expects(:exist?).with(@module.metadata_file).returns true
- @module.should be_has_metadata
- end
+ @module.should be_has_metadata
+ end
- it "should know if it is missing a metadata file" do
- FileTest.expects(:exist?).with(@module.metadata_file).returns false
+ it "should know if it is missing a metadata file" do
+ FileTest.expects(:exist?).with(@module.metadata_file).returns false
- @module.should_not be_has_metadata
- end
+ @module.should_not be_has_metadata
+ end
- it "should be able to parse its metadata file" do
- @module.should respond_to(:load_metadata)
+ it "should be able to parse its metadata file" do
+ @module.should respond_to(:load_metadata)
+ end
+
+ it "should parse its metadata file on initialization if it is present" do
+ Puppet::Module.any_instance.expects(:has_metadata?).returns true
+ Puppet::Module.any_instance.expects(:load_metadata)
+
+ Puppet::Module.new("yay")
+ end
+
+ describe "when loading the medatada file" do
+ confine "Cannot test module metadata without json" => Puppet.features.json?
+
+ before do
+ @data = {
+ :license => "GPL2",
+ :author => "luke",
+ :version => "1.0",
+ :source => "http://foo/",
+ :puppetversion => "0.25"
+ }
+ @text = @data.to_json
+
+ @module = Puppet::Module.new("foo")
+ @module.stubs(:metadata_file).returns "/my/file"
+ File.stubs(:read).with("/my/file").returns @text
end
- it "should parse its metadata file on initialization if it is present" do
- Puppet::Module.any_instance.expects(:has_metadata?).returns true
- Puppet::Module.any_instance.expects(:load_metadata)
+ %w{source author version license}.each do |attr|
+ it "should set #{attr} if present in the metadata file" do
+ @module.load_metadata
+ @module.send(attr).should == @data[attr.to_sym]
+ end
- Puppet::Module.new("yay")
+ it "should fail if #{attr} is not present in the metadata file" do
+ @data.delete(attr.to_sym)
+ @text = @data.to_json
+ File.stubs(:read).with("/my/file").returns @text
+ lambda { @module.load_metadata }.should raise_error(Puppet::Module::MissingMetadata)
+ end
end
- describe "when loading the medatada file" do
- confine "Cannot test module metadata without json" => Puppet.features.json?
-
- before do
- @data = {
- :license => "GPL2",
- :author => "luke",
- :version => "1.0",
- :source => "http://foo/",
- :puppetversion => "0.25"
- }
- @text = @data.to_json
-
- @module = Puppet::Module.new("foo")
- @module.stubs(:metadata_file).returns "/my/file"
- File.stubs(:read).with("/my/file").returns @text
- end
-
- %w{source author version license}.each do |attr|
- it "should set #{attr} if present in the metadata file" do
- @module.load_metadata
- @module.send(attr).should == @data[attr.to_sym]
- end
-
- it "should fail if #{attr} is not present in the metadata file" do
- @data.delete(attr.to_sym)
- @text = @data.to_json
- File.stubs(:read).with("/my/file").returns @text
- lambda { @module.load_metadata }.should raise_error(Puppet::Module::MissingMetadata)
- end
- end
-
- it "should set puppetversion if present in the metadata file" do
- @module.load_metadata
- @module.puppetversion.should == @data[:puppetversion]
- end
-
-
- it "should fail if the discovered name is different than the metadata name"
+ it "should set puppetversion if present in the metadata file" do
+ @module.load_metadata
+ @module.puppetversion.should == @data[:puppetversion]
end
+
+
+ it "should fail if the discovered name is different than the metadata name"
+ end
end
diff --git a/spec/unit/network/authconfig_spec.rb b/spec/unit/network/authconfig_spec.rb
index 2bf9ee1..e10458b 100755
--- a/spec/unit/network/authconfig_spec.rb
+++ b/spec/unit/network/authconfig_spec.rb
@@ -5,288 +5,288 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/network/authconfig'
describe Puppet::Network::AuthConfig do
- before do
- @rights = stubs 'rights'
- Puppet::Network::Rights.stubs(:new).returns(@rights)
- @rights.stubs(:each).returns([])
+ before do
+ @rights = stubs 'rights'
+ Puppet::Network::Rights.stubs(:new).returns(@rights)
+ @rights.stubs(:each).returns([])
- FileTest.stubs(:exists?).returns(true)
- File.stubs(:stat).returns(stub('stat', :ctime => :now))
- Time.stubs(:now).returns :now
+ FileTest.stubs(:exists?).returns(true)
+ File.stubs(:stat).returns(stub('stat', :ctime => :now))
+ Time.stubs(:now).returns :now
- @authconfig = Puppet::Network::AuthConfig.new("dummy", false)
- end
-
- describe "when initializing" do
- before :each do
- Puppet::Network::AuthConfig.any_instance.stubs(:read)
- end
+ @authconfig = Puppet::Network::AuthConfig.new("dummy", false)
+ end
- it "should use the authconfig default pathname if none provided" do
- Puppet.expects(:[]).with(:authconfig).returns("dummy")
+ describe "when initializing" do
+ before :each do
+ Puppet::Network::AuthConfig.any_instance.stubs(:read)
+ end
- Puppet::Network::AuthConfig.new
- end
+ it "should use the authconfig default pathname if none provided" do
+ Puppet.expects(:[]).with(:authconfig).returns("dummy")
- it "should raise an error if no file is defined finally" do
- Puppet.stubs(:[]).with(:authconfig).returns(nil)
+ Puppet::Network::AuthConfig.new
+ end
- lambda { Puppet::Network::AuthConfig.new }.should raise_error(Puppet::DevError)
- end
+ it "should raise an error if no file is defined finally" do
+ Puppet.stubs(:[]).with(:authconfig).returns(nil)
- it "should read and parse the file if parsenow is true" do
- Puppet::Network::AuthConfig.any_instance.expects(:read)
+ lambda { Puppet::Network::AuthConfig.new }.should raise_error(Puppet::DevError)
+ end
- Puppet::Network::AuthConfig.new("dummy", true)
- end
+ it "should read and parse the file if parsenow is true" do
+ Puppet::Network::AuthConfig.any_instance.expects(:read)
+ Puppet::Network::AuthConfig.new("dummy", true)
end
- describe "when checking authorization" do
- before :each do
- @authconfig.stubs(:read)
- @call = stub 'call', :intern => "name"
- @handler = stub 'handler', :intern => "handler"
- @method = stub_everything 'method'
- @request = stub 'request', :call => @call, :handler => @handler, :method => @method, :name => "me", :ip => "1.2.3.4"
- end
+ end
- it "should attempt to read the authconfig file" do
- @rights.stubs(:include?)
+ describe "when checking authorization" do
+ before :each do
+ @authconfig.stubs(:read)
+ @call = stub 'call', :intern => "name"
+ @handler = stub 'handler', :intern => "handler"
+ @method = stub_everything 'method'
+ @request = stub 'request', :call => @call, :handler => @handler, :method => @method, :name => "me", :ip => "1.2.3.4"
+ end
- @authconfig.expects(:read)
+ it "should attempt to read the authconfig file" do
+ @rights.stubs(:include?)
- @authconfig.allowed?(@request)
- end
+ @authconfig.expects(:read)
- it "should use a name right if it exists" do
- right = stub 'right'
+ @authconfig.allowed?(@request)
+ end
- @rights.stubs(:include?).with("name").returns(true)
- @rights.stubs(:[]).with("name").returns(right)
+ it "should use a name right if it exists" do
+ right = stub 'right'
- right.expects(:allowed?).with("me", "1.2.3.4")
+ @rights.stubs(:include?).with("name").returns(true)
+ @rights.stubs(:[]).with("name").returns(right)
- @authconfig.allowed?(@request)
- end
+ right.expects(:allowed?).with("me", "1.2.3.4")
- it "should use a namespace right otherwise" do
- right = stub 'right'
+ @authconfig.allowed?(@request)
+ end
- @rights.stubs(:include?).with("name").returns(false)
- @rights.stubs(:include?).with("handler").returns(true)
- @rights.stubs(:[]).with("handler").returns(right)
+ it "should use a namespace right otherwise" do
+ right = stub 'right'
- right.expects(:allowed?).with("me", "1.2.3.4")
+ @rights.stubs(:include?).with("name").returns(false)
+ @rights.stubs(:include?).with("handler").returns(true)
+ @rights.stubs(:[]).with("handler").returns(right)
- @authconfig.allowed?(@request)
- end
+ right.expects(:allowed?).with("me", "1.2.3.4")
- it "should return whatever the found rights returns" do
- right = stub 'right'
+ @authconfig.allowed?(@request)
+ end
- @rights.stubs(:include?).with("name").returns(true)
- @rights.stubs(:[]).with("name").returns(right)
+ it "should return whatever the found rights returns" do
+ right = stub 'right'
- right.stubs(:allowed?).with("me", "1.2.3.4").returns(:returned)
+ @rights.stubs(:include?).with("name").returns(true)
+ @rights.stubs(:[]).with("name").returns(right)
- @authconfig.allowed?(@request).should == :returned
- end
+ right.stubs(:allowed?).with("me", "1.2.3.4").returns(:returned)
+ @authconfig.allowed?(@request).should == :returned
end
- describe "when parsing authconfig file" do
- before :each do
- @fd = stub 'fd'
- File.stubs(:open).yields(@fd)
- @rights.stubs(:include?).returns(false)
- @rights.stubs(:[])
- end
+ end
- it "should skip comments" do
- @fd.stubs(:each).yields(' # comment')
+ describe "when parsing authconfig file" do
+ before :each do
+ @fd = stub 'fd'
+ File.stubs(:open).yields(@fd)
+ @rights.stubs(:include?).returns(false)
+ @rights.stubs(:[])
+ end
- @rights.expects(:newright).never
+ it "should skip comments" do
+ @fd.stubs(:each).yields(' # comment')
- @authconfig.read
- end
+ @rights.expects(:newright).never
- it "should increment line number even on commented lines" do
- @fd.stubs(:each).multiple_yields(' # comment','[puppetca]')
+ @authconfig.read
+ end
- @rights.expects(:newright).with('[puppetca]', 2, 'dummy')
+ it "should increment line number even on commented lines" do
+ @fd.stubs(:each).multiple_yields(' # comment','[puppetca]')
- @authconfig.read
- end
+ @rights.expects(:newright).with('[puppetca]', 2, 'dummy')
- it "should skip blank lines" do
- @fd.stubs(:each).yields(' ')
+ @authconfig.read
+ end
- @rights.expects(:newright).never
+ it "should skip blank lines" do
+ @fd.stubs(:each).yields(' ')
- @authconfig.read
- end
+ @rights.expects(:newright).never
- it "should increment line number even on blank lines" do
- @fd.stubs(:each).multiple_yields(' ','[puppetca]')
+ @authconfig.read
+ end
- @rights.expects(:newright).with('[puppetca]', 2, 'dummy')
+ it "should increment line number even on blank lines" do
+ @fd.stubs(:each).multiple_yields(' ','[puppetca]')
- @authconfig.read
- end
+ @rights.expects(:newright).with('[puppetca]', 2, 'dummy')
- it "should throw an error if the current namespace right already exist" do
- @fd.stubs(:each).yields('[puppetca]')
+ @authconfig.read
+ end
- @rights.stubs(:include?).with("puppetca").returns(true)
+ it "should throw an error if the current namespace right already exist" do
+ @fd.stubs(:each).yields('[puppetca]')
- lambda { @authconfig.read }.should raise_error
- end
+ @rights.stubs(:include?).with("puppetca").returns(true)
- it "should not throw an error if the current path right already exist" do
- @fd.stubs(:each).yields('path /hello')
+ lambda { @authconfig.read }.should raise_error
+ end
- @rights.stubs(:newright).with("/hello",1, 'dummy')
- @rights.stubs(:include?).with("/hello").returns(true)
+ it "should not throw an error if the current path right already exist" do
+ @fd.stubs(:each).yields('path /hello')
- lambda { @authconfig.read }.should_not raise_error
- end
+ @rights.stubs(:newright).with("/hello",1, 'dummy')
+ @rights.stubs(:include?).with("/hello").returns(true)
- it "should create a new right for found namespaces" do
- @fd.stubs(:each).yields('[puppetca]')
+ lambda { @authconfig.read }.should_not raise_error
+ end
- @rights.expects(:newright).with("[puppetca]", 1, 'dummy')
+ it "should create a new right for found namespaces" do
+ @fd.stubs(:each).yields('[puppetca]')
- @authconfig.read
- end
+ @rights.expects(:newright).with("[puppetca]", 1, 'dummy')
- it "should create a new right for each found namespace line" do
- @fd.stubs(:each).multiple_yields('[puppetca]', '[fileserver]')
+ @authconfig.read
+ end
- @rights.expects(:newright).with("[puppetca]", 1, 'dummy')
- @rights.expects(:newright).with("[fileserver]", 2, 'dummy')
+ it "should create a new right for each found namespace line" do
+ @fd.stubs(:each).multiple_yields('[puppetca]', '[fileserver]')
- @authconfig.read
- end
+ @rights.expects(:newright).with("[puppetca]", 1, 'dummy')
+ @rights.expects(:newright).with("[fileserver]", 2, 'dummy')
- it "should create a new right for each found path line" do
- @fd.stubs(:each).multiple_yields('path /certificates')
+ @authconfig.read
+ end
- @rights.expects(:newright).with("/certificates", 1, 'dummy')
+ it "should create a new right for each found path line" do
+ @fd.stubs(:each).multiple_yields('path /certificates')
- @authconfig.read
- end
+ @rights.expects(:newright).with("/certificates", 1, 'dummy')
- it "should create a new right for each found regex line" do
- @fd.stubs(:each).multiple_yields('path ~ .rb$')
+ @authconfig.read
+ end
- @rights.expects(:newright).with("~ .rb$", 1, 'dummy')
+ it "should create a new right for each found regex line" do
+ @fd.stubs(:each).multiple_yields('path ~ .rb$')
- @authconfig.read
- end
+ @rights.expects(:newright).with("~ .rb$", 1, 'dummy')
- it "should create an allow ACE on each subsequent allow" do
- acl = stub 'acl', :info
+ @authconfig.read
+ end
- @fd.stubs(:each).multiple_yields('[puppetca]', 'allow 127.0.0.1')
- @rights.stubs(:newright).with("[puppetca]", 1, 'dummy').returns(acl)
+ it "should create an allow ACE on each subsequent allow" do
+ acl = stub 'acl', :info
- acl.expects(:allow).with('127.0.0.1')
+ @fd.stubs(:each).multiple_yields('[puppetca]', 'allow 127.0.0.1')
+ @rights.stubs(:newright).with("[puppetca]", 1, 'dummy').returns(acl)
- @authconfig.read
- end
+ acl.expects(:allow).with('127.0.0.1')
- it "should create a deny ACE on each subsequent deny" do
- acl = stub 'acl', :info
+ @authconfig.read
+ end
- @fd.stubs(:each).multiple_yields('[puppetca]', 'deny 127.0.0.1')
- @rights.stubs(:newright).with("[puppetca]", 1, 'dummy').returns(acl)
+ it "should create a deny ACE on each subsequent deny" do
+ acl = stub 'acl', :info
- acl.expects(:deny).with('127.0.0.1')
+ @fd.stubs(:each).multiple_yields('[puppetca]', 'deny 127.0.0.1')
+ @rights.stubs(:newright).with("[puppetca]", 1, 'dummy').returns(acl)
- @authconfig.read
- end
+ acl.expects(:deny).with('127.0.0.1')
- it "should inform the current ACL if we get the 'method' directive" do
- acl = stub 'acl', :info
- acl.stubs(:acl_type).returns(:regex)
+ @authconfig.read
+ end
- @fd.stubs(:each).multiple_yields('path /certificates', 'method search,find')
- @rights.stubs(:newright).with("/certificates", 1, 'dummy').returns(acl)
+ it "should inform the current ACL if we get the 'method' directive" do
+ acl = stub 'acl', :info
+ acl.stubs(:acl_type).returns(:regex)
- acl.expects(:restrict_method).with('search')
- acl.expects(:restrict_method).with('find')
+ @fd.stubs(:each).multiple_yields('path /certificates', 'method search,find')
+ @rights.stubs(:newright).with("/certificates", 1, 'dummy').returns(acl)
- @authconfig.read
- end
+ acl.expects(:restrict_method).with('search')
+ acl.expects(:restrict_method).with('find')
- it "should raise an error if the 'method' directive is used in a right different than a path/regex one" do
- acl = stub 'acl', :info
- acl.stubs(:acl_type).returns(:regex)
+ @authconfig.read
+ end
- @fd.stubs(:each).multiple_yields('[puppetca]', 'method search,find')
- @rights.stubs(:newright).with("puppetca", 1, 'dummy').returns(acl)
+ it "should raise an error if the 'method' directive is used in a right different than a path/regex one" do
+ acl = stub 'acl', :info
+ acl.stubs(:acl_type).returns(:regex)
- lambda { @authconfig.read }.should raise_error
- end
+ @fd.stubs(:each).multiple_yields('[puppetca]', 'method search,find')
+ @rights.stubs(:newright).with("puppetca", 1, 'dummy').returns(acl)
- it "should inform the current ACL if we get the 'environment' directive" do
- acl = stub 'acl', :info
- acl.stubs(:acl_type).returns(:regex)
+ lambda { @authconfig.read }.should raise_error
+ end
- @fd.stubs(:each).multiple_yields('path /certificates', 'environment production,development')
- @rights.stubs(:newright).with("/certificates", 1, 'dummy').returns(acl)
+ it "should inform the current ACL if we get the 'environment' directive" do
+ acl = stub 'acl', :info
+ acl.stubs(:acl_type).returns(:regex)
- acl.expects(:restrict_environment).with('production')
- acl.expects(:restrict_environment).with('development')
+ @fd.stubs(:each).multiple_yields('path /certificates', 'environment production,development')
+ @rights.stubs(:newright).with("/certificates", 1, 'dummy').returns(acl)
- @authconfig.read
- end
+ acl.expects(:restrict_environment).with('production')
+ acl.expects(:restrict_environment).with('development')
- it "should raise an error if the 'environment' directive is used in a right different than a path/regex one" do
- acl = stub 'acl', :info
- acl.stubs(:acl_type).returns(:regex)
+ @authconfig.read
+ end
- @fd.stubs(:each).multiple_yields('[puppetca]', 'environment env')
- @rights.stubs(:newright).with("puppetca", 1, 'dummy').returns(acl)
+ it "should raise an error if the 'environment' directive is used in a right different than a path/regex one" do
+ acl = stub 'acl', :info
+ acl.stubs(:acl_type).returns(:regex)
- lambda { @authconfig.read }.should raise_error
- end
+ @fd.stubs(:each).multiple_yields('[puppetca]', 'environment env')
+ @rights.stubs(:newright).with("puppetca", 1, 'dummy').returns(acl)
- it "should inform the current ACL if we get the 'auth' directive" do
- acl = stub 'acl', :info
- acl.stubs(:acl_type).returns(:regex)
+ lambda { @authconfig.read }.should raise_error
+ end
- @fd.stubs(:each).multiple_yields('path /certificates', 'auth yes')
- @rights.stubs(:newright).with("/certificates", 1, 'dummy').returns(acl)
+ it "should inform the current ACL if we get the 'auth' directive" do
+ acl = stub 'acl', :info
+ acl.stubs(:acl_type).returns(:regex)
- acl.expects(:restrict_authenticated).with('yes')
+ @fd.stubs(:each).multiple_yields('path /certificates', 'auth yes')
+ @rights.stubs(:newright).with("/certificates", 1, 'dummy').returns(acl)
- @authconfig.read
- end
+ acl.expects(:restrict_authenticated).with('yes')
- it "should also allow the longest 'authenticated' directive" do
- acl = stub 'acl', :info
- acl.stubs(:acl_type).returns(:regex)
+ @authconfig.read
+ end
- @fd.stubs(:each).multiple_yields('path /certificates', 'authenticated yes')
- @rights.stubs(:newright).with("/certificates", 1, 'dummy').returns(acl)
+ it "should also allow the longest 'authenticated' directive" do
+ acl = stub 'acl', :info
+ acl.stubs(:acl_type).returns(:regex)
- acl.expects(:restrict_authenticated).with('yes')
+ @fd.stubs(:each).multiple_yields('path /certificates', 'authenticated yes')
+ @rights.stubs(:newright).with("/certificates", 1, 'dummy').returns(acl)
- @authconfig.read
- end
+ acl.expects(:restrict_authenticated).with('yes')
- it "should raise an error if the 'auth' directive is used in a right different than a path/regex one" do
- acl = stub 'acl', :info
- acl.stubs(:acl_type).returns(:regex)
+ @authconfig.read
+ end
- @fd.stubs(:each).multiple_yields('[puppetca]', 'auth yes')
- @rights.stubs(:newright).with("puppetca", 1, 'dummy').returns(acl)
+ it "should raise an error if the 'auth' directive is used in a right different than a path/regex one" do
+ acl = stub 'acl', :info
+ acl.stubs(:acl_type).returns(:regex)
- lambda { @authconfig.read }.should raise_error
- end
+ @fd.stubs(:each).multiple_yields('[puppetca]', 'auth yes')
+ @rights.stubs(:newright).with("puppetca", 1, 'dummy').returns(acl)
+ lambda { @authconfig.read }.should raise_error
end
+ end
+
end
diff --git a/spec/unit/network/authstore_spec.rb b/spec/unit/network/authstore_spec.rb
index e3f8194..094352c 100644
--- a/spec/unit/network/authstore_spec.rb
+++ b/spec/unit/network/authstore_spec.rb
@@ -5,366 +5,366 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/network/authconfig'
describe Puppet::Network::AuthStore do
- describe "when checking if the acl has some entries" do
- before :each do
- @authstore = Puppet::Network::AuthStore.new
- end
+ describe "when checking if the acl has some entries" do
+ before :each do
+ @authstore = Puppet::Network::AuthStore.new
+ end
- it "should be empty if no ACE have been entered" do
- @authstore.should be_empty
- end
+ it "should be empty if no ACE have been entered" do
+ @authstore.should be_empty
+ end
- it "should not be empty if it is a global allow" do
- @authstore.allow('*')
+ it "should not be empty if it is a global allow" do
+ @authstore.allow('*')
- @authstore.should_not be_empty
- end
+ @authstore.should_not be_empty
+ end
- it "should not be empty if at least one allow has been entered" do
- @authstore.allow('1.1.1.*')
+ it "should not be empty if at least one allow has been entered" do
+ @authstore.allow('1.1.1.*')
- @authstore.should_not be_empty
- end
+ @authstore.should_not be_empty
+ end
- it "should not be empty if at least one deny has been entered" do
- @authstore.deny('1.1.1.*')
+ it "should not be empty if at least one deny has been entered" do
+ @authstore.deny('1.1.1.*')
- @authstore.should_not be_empty
- end
+ @authstore.should_not be_empty
end
+ end
end
describe Puppet::Network::AuthStore::Declaration do
- ['100.101.99.98','100.100.100.100','1.2.3.4','11.22.33.44'].each { |ip|
- describe "when the pattern is a simple numeric IP such as #{ip}" do
- before :each do
- @declaration = Puppet::Network::AuthStore::Declaration.new(:allow,ip)
- end
- it "should match the specified IP" do
- @declaration.should be_match('www.testsite.org',ip)
- end
- it "should not match other IPs" do
- @declaration.should_not be_match('www.testsite.org','200.101.99.98')
- end
- end
-
- (1..3).each { |n|
- describe "when the pattern is a IP mask with #{n} numeric segments and a *" do
- before :each do
- @ip_pattern = ip.split('.')[0,n].join('.')+'.*'
- @declaration = Puppet::Network::AuthStore::Declaration.new(:allow, at ip_pattern)
- end
- it "should match an IP in the range" do
- @declaration.should be_match('www.testsite.org',ip)
- end
- it "should not match other IPs" do
- @declaration.should_not be_match('www.testsite.org','200.101.99.98')
- end
- it "should not match IPs that differ in the last non-wildcard segment" do
- other = ip.split('.')
- other[n-1].succ!
- @declaration.should_not be_match('www.testsite.org',other.join('.'))
- end
- end
- }
- }
+ ['100.101.99.98','100.100.100.100','1.2.3.4','11.22.33.44'].each { |ip|
+ describe "when the pattern is a simple numeric IP such as #{ip}" do
+ before :each do
+ @declaration = Puppet::Network::AuthStore::Declaration.new(:allow,ip)
+ end
+ it "should match the specified IP" do
+ @declaration.should be_match('www.testsite.org',ip)
+ end
+ it "should not match other IPs" do
+ @declaration.should_not be_match('www.testsite.org','200.101.99.98')
+ end
+ end
- describe "when the pattern is a numeric IP with a back reference" do
+ (1..3).each { |n|
+ describe "when the pattern is a IP mask with #{n} numeric segments and a *" do
before :each do
- @ip = '100.101.$1'
- @declaration = Puppet::Network::AuthStore::Declaration.new(:allow, at ip).interpolate('12.34'.match(/(.*)/))
+ @ip_pattern = ip.split('.')[0,n].join('.')+'.*'
+ @declaration = Puppet::Network::AuthStore::Declaration.new(:allow, at ip_pattern)
end
- it "should match an IP with the appropriate interpolation" do
- @declaration.should be_match('www.testsite.org', at ip.sub(/\$1/,'12.34'))
+ it "should match an IP in the range" do
+ @declaration.should be_match('www.testsite.org',ip)
end
it "should not match other IPs" do
- @declaration.should_not be_match('www.testsite.org', at ip.sub(/\$1/,'66.34'))
+ @declaration.should_not be_match('www.testsite.org','200.101.99.98')
end
- end
-
- [
- "02001:0000:1234:0000:0000:C1C0:ABCD:0876",
- "2001:0000:1234:0000:00001:C1C0:ABCD:0876",
- " 2001:0000:1234:0000:0000:C1C0:ABCD:0876Â 0",
- "2001:0000:1234: 0000:0000:C1C0:ABCD:0876",
- "3ffe:0b00:0000:0001:0000:0000:000a",
- "FF02:0000:0000:0000:0000:0000:0000:0000:0001",
- "3ffe:b00::1::a",
- "1:2:3::4:5::7:8",
- "12345::6:7:8",
- "1::5:400.2.3.4",
- "1::5:260.2.3.4",
- "1::5:256.2.3.4",
- "1::5:1.256.3.4",
- "1::5:1.2.256.4",
- "1::5:1.2.3.256",
- "1::5:300.2.3.4",
- "1::5:1.300.3.4",
- "1::5:1.2.300.4",
- "1::5:1.2.3.300",
- "1::5:900.2.3.4",
- "1::5:1.900.3.4",
- "1::5:1.2.900.4",
- "1::5:1.2.3.900",
- "1::5:300.300.300.300",
- "1::5:3000.30.30.30",
- "1::400.2.3.4",
- "1::260.2.3.4",
- "1::256.2.3.4",
- "1::1.256.3.4",
- "1::1.2.256.4",
- "1::1.2.3.256",
- "1::300.2.3.4",
- "1::1.300.3.4",
- "1::1.2.300.4",
- "1::1.2.3.300",
- "1::900.2.3.4",
- "1::1.900.3.4",
- "1::1.2.900.4",
- "1::1.2.3.900",
- "1::300.300.300.300",
- "1::3000.30.30.30",
- "::400.2.3.4",
- "::260.2.3.4",
- "::256.2.3.4",
- "::1.256.3.4",
- "::1.2.256.4",
- "::1.2.3.256",
- "::300.2.3.4",
- "::1.300.3.4",
- "::1.2.300.4",
- "::1.2.3.300",
- "::900.2.3.4",
- "::1.900.3.4",
- "::1.2.900.4",
- "::1.2.3.900",
- "::300.300.300.300",
- "::3000.30.30.30",
- "2001:DB8:0:0:8:800:200C:417A:221", # unicast, full
- "FF01::101::2" # multicast, compressed
- ].each { |invalid_ip|
- describe "when the pattern is an invalid IPv6 address such as #{invalid_ip}" do
- it "should raise an exception" do
- lambda { Puppet::Network::AuthStore::Declaration.new(:allow,invalid_ip) }.should raise_error
- end
+ it "should not match IPs that differ in the last non-wildcard segment" do
+ other = ip.split('.')
+ other[n-1].succ!
+ @declaration.should_not be_match('www.testsite.org',other.join('.'))
end
+ end
}
+ }
- [
- "1.2.3.4",
- "2001:0000:1234:0000:0000:C1C0:ABCD:0876",
- "3ffe:0b00:0000:0000:0001:0000:0000:000a",
- "FF02:0000:0000:0000:0000:0000:0000:0001",
- "0000:0000:0000:0000:0000:0000:0000:0001",
- "0000:0000:0000:0000:0000:0000:0000:0000",
- "::ffff:192.168.1.26",
- "2::10",
- "ff02::1",
- "fe80::",
- "2002::",
- "2001:db8::",
- "2001:0db8:1234::",
- "::ffff:0:0",
- "::1",
- "::ffff:192.168.1.1",
- "1:2:3:4:5:6:7:8",
- "1:2:3:4:5:6::8",
- "1:2:3:4:5::8",
- "1:2:3:4::8",
- "1:2:3::8",
- "1:2::8",
- "1::8",
- "1::2:3:4:5:6:7",
- "1::2:3:4:5:6",
- "1::2:3:4:5",
- "1::2:3:4",
- "1::2:3",
- "1::8",
- "::2:3:4:5:6:7:8",
- "::2:3:4:5:6:7",
- "::2:3:4:5:6",
- "::2:3:4:5",
- "::2:3:4",
- "::2:3",
- "::8",
- "1:2:3:4:5:6::",
- "1:2:3:4:5::",
- "1:2:3:4::",
- "1:2:3::",
- "1:2::",
- "1::",
- "1:2:3:4:5::7:8",
- "1:2:3:4::7:8",
- "1:2:3::7:8",
- "1:2::7:8",
- "1::7:8",
- "1:2:3:4:5:6:1.2.3.4",
- "1:2:3:4:5::1.2.3.4",
- "1:2:3:4::1.2.3.4",
- "1:2:3::1.2.3.4",
- "1:2::1.2.3.4",
- "1::1.2.3.4",
- "1:2:3:4::5:1.2.3.4",
- "1:2:3::5:1.2.3.4",
- "1:2::5:1.2.3.4",
- "1::5:1.2.3.4",
- "1::5:11.22.33.44",
- "fe80::217:f2ff:254.7.237.98",
- "fe80::217:f2ff:fe07:ed62",
- "2001:DB8:0:0:8:800:200C:417A", # unicast, full
- "FF01:0:0:0:0:0:0:101", # multicast, full
- "0:0:0:0:0:0:0:1", # loopback, full
- "0:0:0:0:0:0:0:0", # unspecified, full
- "2001:DB8::8:800:200C:417A", # unicast, compressed
- "FF01::101", # multicast, compressed
- "::1", # loopback, compressed, non-routable
- "::", # unspecified, compressed, non-routable
- "0:0:0:0:0:0:13.1.68.3", # IPv4-compatible IPv6 address, full, deprecated
- "0:0:0:0:0:FFFF:129.144.52.38", # IPv4-mapped IPv6 address, full
- "::13.1.68.3", # IPv4-compatible IPv6 address, compressed, deprecated
- "::FFFF:129.144.52.38", # IPv4-mapped IPv6 address, compressed
- "2001:0DB8:0000:CD30:0000:0000:0000:0000/60", # full, with prefix
- "2001:0DB8::CD30:0:0:0:0/60", # compressed, with prefix
- "2001:0DB8:0:CD30::/60", # compressed, with prefix #2
- "::/128", # compressed, unspecified address type, non-routable
- "::1/128", # compressed, loopback address type, non-routable
- "FF00::/8", # compressed, multicast address type
- "FE80::/10", # compressed, link-local unicast, non-routable
- "FEC0::/10", # compressed, site-local unicast, deprecated
- "127.0.0.1", # standard IPv4, loopback, non-routable
- "0.0.0.0", # standard IPv4, unspecified, non-routable
- "255.255.255.255", # standard IPv4
- "fe80:0000:0000:0000:0204:61ff:fe9d:f156",
- "fe80:0:0:0:204:61ff:fe9d:f156",
- "fe80::204:61ff:fe9d:f156",
- "fe80:0000:0000:0000:0204:61ff:254.157.241.086",
- "fe80:0:0:0:204:61ff:254.157.241.86",
- "fe80::204:61ff:254.157.241.86",
- "::1",
- "fe80::",
- "fe80::1"
- ].each { |ip|
- describe "when the pattern is a valid IP such as #{ip}" do
- before :each do
- @declaration = Puppet::Network::AuthStore::Declaration.new(:allow,ip)
- end
- it "should match the specified IP" do
- @declaration.should be_match('www.testsite.org',ip)
- end
- it "should not match other IPs" do
- @declaration.should_not be_match('www.testsite.org','200.101.99.98')
- end
- end unless ip =~ /:.*\./ # Hybrid IPs aren't supported by ruby's ipaddr
- }
+ describe "when the pattern is a numeric IP with a back reference" do
+ before :each do
+ @ip = '100.101.$1'
+ @declaration = Puppet::Network::AuthStore::Declaration.new(:allow, at ip).interpolate('12.34'.match(/(.*)/))
+ end
+ it "should match an IP with the appropriate interpolation" do
+ @declaration.should be_match('www.testsite.org', at ip.sub(/\$1/,'12.34'))
+ end
+ it "should not match other IPs" do
+ @declaration.should_not be_match('www.testsite.org', at ip.sub(/\$1/,'66.34'))
+ end
+ end
- {
- 'spirit.mars.nasa.gov' => 'a PQDN',
- 'ratchet.2ndsiteinc.com' => 'a PQDN with digits',
- 'a.c.ru' => 'a PQDN with short segments',
- }.each {|pqdn,desc|
- describe "when the pattern is #{desc}" do
- before :each do
- @host = pqdn
- @declaration = Puppet::Network::AuthStore::Declaration.new(:allow, at host)
- end
- it "should match the specified PQDN" do
- @declaration.should be_match(@host,'200.101.99.98')
- end
- it "should not match a similar FQDN" do
- pending "FQDN consensus"
- @declaration.should_not be_match(@host+'.','200.101.99.98')
- end
- end
- }
+ [
+ "02001:0000:1234:0000:0000:C1C0:ABCD:0876",
+ "2001:0000:1234:0000:00001:C1C0:ABCD:0876",
+ " 2001:0000:1234:0000:0000:C1C0:ABCD:0876Â 0",
+ "2001:0000:1234: 0000:0000:C1C0:ABCD:0876",
+ "3ffe:0b00:0000:0001:0000:0000:000a",
+ "FF02:0000:0000:0000:0000:0000:0000:0000:0001",
+ "3ffe:b00::1::a",
+ "1:2:3::4:5::7:8",
+ "12345::6:7:8",
+ "1::5:400.2.3.4",
+ "1::5:260.2.3.4",
+ "1::5:256.2.3.4",
+ "1::5:1.256.3.4",
+ "1::5:1.2.256.4",
+ "1::5:1.2.3.256",
+ "1::5:300.2.3.4",
+ "1::5:1.300.3.4",
+ "1::5:1.2.300.4",
+ "1::5:1.2.3.300",
+ "1::5:900.2.3.4",
+ "1::5:1.900.3.4",
+ "1::5:1.2.900.4",
+ "1::5:1.2.3.900",
+ "1::5:300.300.300.300",
+ "1::5:3000.30.30.30",
+ "1::400.2.3.4",
+ "1::260.2.3.4",
+ "1::256.2.3.4",
+ "1::1.256.3.4",
+ "1::1.2.256.4",
+ "1::1.2.3.256",
+ "1::300.2.3.4",
+ "1::1.300.3.4",
+ "1::1.2.300.4",
+ "1::1.2.3.300",
+ "1::900.2.3.4",
+ "1::1.900.3.4",
+ "1::1.2.900.4",
+ "1::1.2.3.900",
+ "1::300.300.300.300",
+ "1::3000.30.30.30",
+ "::400.2.3.4",
+ "::260.2.3.4",
+ "::256.2.3.4",
+ "::1.256.3.4",
+ "::1.2.256.4",
+ "::1.2.3.256",
+ "::300.2.3.4",
+ "::1.300.3.4",
+ "::1.2.300.4",
+ "::1.2.3.300",
+ "::900.2.3.4",
+ "::1.900.3.4",
+ "::1.2.900.4",
+ "::1.2.3.900",
+ "::300.300.300.300",
+ "::3000.30.30.30",
+ "2001:DB8:0:0:8:800:200C:417A:221", # unicast, full
+ "FF01::101::2" # multicast, compressed
+ ].each { |invalid_ip|
+ describe "when the pattern is an invalid IPv6 address such as #{invalid_ip}" do
+ it "should raise an exception" do
+ lambda { Puppet::Network::AuthStore::Declaration.new(:allow,invalid_ip) }.should raise_error
+ end
+ end
+ }
- ['abc.12seps.edu.phisher.biz','www.google.com','slashdot.org'].each { |host|
- (1...(host.split('.').length)).each { |n|
- describe "when the pattern is #{"*."+host.split('.')[-n,n].join('.')}" do
- before :each do
- @pattern = "*."+host.split('.')[-n,n].join('.')
- @declaration = Puppet::Network::AuthStore::Declaration.new(:allow, at pattern)
- end
- it "should match #{host}" do
- @declaration.should be_match(host,'1.2.3.4')
- end
- it "should not match www.testsite.gov" do
- @declaration.should_not be_match('www.testsite.gov','200.101.99.98')
- end
- it "should not match hosts that differ in the first non-wildcard segment" do
- other = host.split('.')
- other[-n].succ!
- @declaration.should_not be_match(other.join('.'),'1.2.3.4')
- end
- end
- }
- }
+ [
+ "1.2.3.4",
+ "2001:0000:1234:0000:0000:C1C0:ABCD:0876",
+ "3ffe:0b00:0000:0000:0001:0000:0000:000a",
+ "FF02:0000:0000:0000:0000:0000:0000:0001",
+ "0000:0000:0000:0000:0000:0000:0000:0001",
+ "0000:0000:0000:0000:0000:0000:0000:0000",
+ "::ffff:192.168.1.26",
+ "2::10",
+ "ff02::1",
+ "fe80::",
+ "2002::",
+ "2001:db8::",
+ "2001:0db8:1234::",
+ "::ffff:0:0",
+ "::1",
+ "::ffff:192.168.1.1",
+ "1:2:3:4:5:6:7:8",
+ "1:2:3:4:5:6::8",
+ "1:2:3:4:5::8",
+ "1:2:3:4::8",
+ "1:2:3::8",
+ "1:2::8",
+ "1::8",
+ "1::2:3:4:5:6:7",
+ "1::2:3:4:5:6",
+ "1::2:3:4:5",
+ "1::2:3:4",
+ "1::2:3",
+ "1::8",
+ "::2:3:4:5:6:7:8",
+ "::2:3:4:5:6:7",
+ "::2:3:4:5:6",
+ "::2:3:4:5",
+ "::2:3:4",
+ "::2:3",
+ "::8",
+ "1:2:3:4:5:6::",
+ "1:2:3:4:5::",
+ "1:2:3:4::",
+ "1:2:3::",
+ "1:2::",
+ "1::",
+ "1:2:3:4:5::7:8",
+ "1:2:3:4::7:8",
+ "1:2:3::7:8",
+ "1:2::7:8",
+ "1::7:8",
+ "1:2:3:4:5:6:1.2.3.4",
+ "1:2:3:4:5::1.2.3.4",
+ "1:2:3:4::1.2.3.4",
+ "1:2:3::1.2.3.4",
+ "1:2::1.2.3.4",
+ "1::1.2.3.4",
+ "1:2:3:4::5:1.2.3.4",
+ "1:2:3::5:1.2.3.4",
+ "1:2::5:1.2.3.4",
+ "1::5:1.2.3.4",
+ "1::5:11.22.33.44",
+ "fe80::217:f2ff:254.7.237.98",
+ "fe80::217:f2ff:fe07:ed62",
+ "2001:DB8:0:0:8:800:200C:417A", # unicast, full
+ "FF01:0:0:0:0:0:0:101", # multicast, full
+ "0:0:0:0:0:0:0:1", # loopback, full
+ "0:0:0:0:0:0:0:0", # unspecified, full
+ "2001:DB8::8:800:200C:417A", # unicast, compressed
+ "FF01::101", # multicast, compressed
+ "::1", # loopback, compressed, non-routable
+ "::", # unspecified, compressed, non-routable
+ "0:0:0:0:0:0:13.1.68.3", # IPv4-compatible IPv6 address, full, deprecated
+ "0:0:0:0:0:FFFF:129.144.52.38", # IPv4-mapped IPv6 address, full
+ "::13.1.68.3", # IPv4-compatible IPv6 address, compressed, deprecated
+ "::FFFF:129.144.52.38", # IPv4-mapped IPv6 address, compressed
+ "2001:0DB8:0000:CD30:0000:0000:0000:0000/60", # full, with prefix
+ "2001:0DB8::CD30:0:0:0:0/60", # compressed, with prefix
+ "2001:0DB8:0:CD30::/60", # compressed, with prefix #2
+ "::/128", # compressed, unspecified address type, non-routable
+ "::1/128", # compressed, loopback address type, non-routable
+ "FF00::/8", # compressed, multicast address type
+ "FE80::/10", # compressed, link-local unicast, non-routable
+ "FEC0::/10", # compressed, site-local unicast, deprecated
+ "127.0.0.1", # standard IPv4, loopback, non-routable
+ "0.0.0.0", # standard IPv4, unspecified, non-routable
+ "255.255.255.255", # standard IPv4
+ "fe80:0000:0000:0000:0204:61ff:fe9d:f156",
+ "fe80:0:0:0:204:61ff:fe9d:f156",
+ "fe80::204:61ff:fe9d:f156",
+ "fe80:0000:0000:0000:0204:61ff:254.157.241.086",
+ "fe80:0:0:0:204:61ff:254.157.241.86",
+ "fe80::204:61ff:254.157.241.86",
+ "::1",
+ "fe80::",
+ "fe80::1"
+ ].each { |ip|
+ describe "when the pattern is a valid IP such as #{ip}" do
+ before :each do
+ @declaration = Puppet::Network::AuthStore::Declaration.new(:allow,ip)
+ end
+ it "should match the specified IP" do
+ @declaration.should be_match('www.testsite.org',ip)
+ end
+ it "should not match other IPs" do
+ @declaration.should_not be_match('www.testsite.org','200.101.99.98')
+ end
+ end unless ip =~ /:.*\./ # Hybrid IPs aren't supported by ruby's ipaddr
+ }
+
+ {
+ 'spirit.mars.nasa.gov' => 'a PQDN',
+ 'ratchet.2ndsiteinc.com' => 'a PQDN with digits',
+ 'a.c.ru' => 'a PQDN with short segments',
+ }.each {|pqdn,desc|
+ describe "when the pattern is #{desc}" do
+ before :each do
+ @host = pqdn
+ @declaration = Puppet::Network::AuthStore::Declaration.new(:allow, at host)
+ end
+ it "should match the specified PQDN" do
+ @declaration.should be_match(@host,'200.101.99.98')
+ end
+ it "should not match a similar FQDN" do
+ pending "FQDN consensus"
+ @declaration.should_not be_match(@host+'.','200.101.99.98')
+ end
+ end
+ }
- describe "when the pattern is a FQDN" do
+ ['abc.12seps.edu.phisher.biz','www.google.com','slashdot.org'].each { |host|
+ (1...(host.split('.').length)).each { |n|
+ describe "when the pattern is #{"*."+host.split('.')[-n,n].join('.')}" do
before :each do
- @host = 'spirit.mars.nasa.gov.'
- @declaration = Puppet::Network::AuthStore::Declaration.new(:allow, at host)
+ @pattern = "*."+host.split('.')[-n,n].join('.')
+ @declaration = Puppet::Network::AuthStore::Declaration.new(:allow, at pattern)
end
- it "should match the specified FQDN" do
- pending "FQDN consensus"
- @declaration.should be_match(@host,'200.101.99.98')
+ it "should match #{host}" do
+ @declaration.should be_match(host,'1.2.3.4')
end
- it "should not match a similar PQDN" do
- @declaration.should_not be_match(@host[0..-2],'200.101.99.98')
+ it "should not match www.testsite.gov" do
+ @declaration.should_not be_match('www.testsite.gov','200.101.99.98')
end
+ it "should not match hosts that differ in the first non-wildcard segment" do
+ other = host.split('.')
+ other[-n].succ!
+ @declaration.should_not be_match(other.join('.'),'1.2.3.4')
+ end
+ end
+ }
+ }
+
+ describe "when the pattern is a FQDN" do
+ before :each do
+ @host = 'spirit.mars.nasa.gov.'
+ @declaration = Puppet::Network::AuthStore::Declaration.new(:allow, at host)
+ end
+ it "should match the specified FQDN" do
+ pending "FQDN consensus"
+ @declaration.should be_match(@host,'200.101.99.98')
end
+ it "should not match a similar PQDN" do
+ @declaration.should_not be_match(@host[0..-2],'200.101.99.98')
+ end
+ end
- describe "when the pattern is an opaque string with a back reference" do
- before :each do
- @host = 'c216f41a-f902-4bfb-a222-850dd957bebb'
- @item = "/catalog/#{@host}"
- @pattern = %{^/catalog/([^/]+)$}
- @declaration = Puppet::Network::AuthStore::Declaration.new(:allow,'$1')
- end
- it "should match an IP with the appropriate interpolation" do
- @declaration.interpolate(@item.match(@pattern)).should be_match(@host,'10.0.0.5')
- end
+ describe "when the pattern is an opaque string with a back reference" do
+ before :each do
+ @host = 'c216f41a-f902-4bfb-a222-850dd957bebb'
+ @item = "/catalog/#{@host}"
+ @pattern = %{^/catalog/([^/]+)$}
+ @declaration = Puppet::Network::AuthStore::Declaration.new(:allow,'$1')
+ end
+ it "should match an IP with the appropriate interpolation" do
+ @declaration.interpolate(@item.match(@pattern)).should be_match(@host,'10.0.0.5')
end
+ end
- describe "when the pattern is an opaque string with a back reference and the matched data contains dots" do
- before :each do
- @host = 'admin.mgmt.nym1'
- @item = "/catalog/#{@host}"
- @pattern = %{^/catalog/([^/]+)$}
- @declaration = Puppet::Network::AuthStore::Declaration.new(:allow,'$1')
- end
- it "should match a name with the appropriate interpolation" do
- @declaration.interpolate(@item.match(@pattern)).should be_match(@host,'10.0.0.5')
- end
+ describe "when the pattern is an opaque string with a back reference and the matched data contains dots" do
+ before :each do
+ @host = 'admin.mgmt.nym1'
+ @item = "/catalog/#{@host}"
+ @pattern = %{^/catalog/([^/]+)$}
+ @declaration = Puppet::Network::AuthStore::Declaration.new(:allow,'$1')
+ end
+ it "should match a name with the appropriate interpolation" do
+ @declaration.interpolate(@item.match(@pattern)).should be_match(@host,'10.0.0.5')
end
+ end
- describe "when the pattern is an opaque string with a back reference and the matched data contains dots with an initial prefix that looks like an IP address" do
- before :each do
- @host = '01.admin.mgmt.nym1'
- @item = "/catalog/#{@host}"
- @pattern = %{^/catalog/([^/]+)$}
- @declaration = Puppet::Network::AuthStore::Declaration.new(:allow,'$1')
- end
- it "should match a name with the appropriate interpolation" do
- @declaration.interpolate(@item.match(@pattern)).should be_match(@host,'10.0.0.5')
- end
+ describe "when the pattern is an opaque string with a back reference and the matched data contains dots with an initial prefix that looks like an IP address" do
+ before :each do
+ @host = '01.admin.mgmt.nym1'
+ @item = "/catalog/#{@host}"
+ @pattern = %{^/catalog/([^/]+)$}
+ @declaration = Puppet::Network::AuthStore::Declaration.new(:allow,'$1')
end
+ it "should match a name with the appropriate interpolation" do
+ @declaration.interpolate(@item.match(@pattern)).should be_match(@host,'10.0.0.5')
+ end
+ end
- describe "when comparing patterns" do
- before :each do
- @ip = Puppet::Network::AuthStore::Declaration.new(:allow,'127.0.0.1')
- @host_name = Puppet::Network::AuthStore::Declaration.new(:allow,'www.hard_knocks.edu')
- @opaque = Puppet::Network::AuthStore::Declaration.new(:allow,'hey_dude')
- end
- it "should consider ip addresses before host names" do
- (@ip < @host_name).should be_true
- end
- it "should consider ip addresses before opaque strings" do
- (@ip < @opaque).should be_true
- end
- it "should consider host_names before opaque strings" do
- (@host_name < @opaque).should be_true
- end
+ describe "when comparing patterns" do
+ before :each do
+ @ip = Puppet::Network::AuthStore::Declaration.new(:allow,'127.0.0.1')
+ @host_name = Puppet::Network::AuthStore::Declaration.new(:allow,'www.hard_knocks.edu')
+ @opaque = Puppet::Network::AuthStore::Declaration.new(:allow,'hey_dude')
+ end
+ it "should consider ip addresses before host names" do
+ (@ip < @host_name).should be_true
+ end
+ it "should consider ip addresses before opaque strings" do
+ (@ip < @opaque).should be_true
+ end
+ it "should consider host_names before opaque strings" do
+ (@host_name < @opaque).should be_true
end
+ end
end
diff --git a/spec/unit/network/client_spec.rb b/spec/unit/network/client_spec.rb
index cea71d1..f42bd78 100755
--- a/spec/unit/network/client_spec.rb
+++ b/spec/unit/network/client_spec.rb
@@ -8,38 +8,38 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/network/client'
describe Puppet::Network::Client do
+ before do
+ Puppet.settings.stubs(:use).returns(true)
+ Puppet::Network::HttpPool.stubs(:cert_setup)
+ end
+
+ describe "when keep-alive is enabled" do
before do
- Puppet.settings.stubs(:use).returns(true)
- Puppet::Network::HttpPool.stubs(:cert_setup)
+ Puppet::Network::HttpPool.stubs(:keep_alive?).returns true
end
+ it "should start the http client up on creation" do
+ http = mock 'http'
+ http.stub_everything
+ http.expects(:start)
+ Net::HTTP.stubs(:new).returns http
- describe "when keep-alive is enabled" do
- before do
- Puppet::Network::HttpPool.stubs(:keep_alive?).returns true
- end
- it "should start the http client up on creation" do
- http = mock 'http'
- http.stub_everything
- http.expects(:start)
- Net::HTTP.stubs(:new).returns http
-
- # Pick a random subclass...
- Puppet::Network::Client.runner.new :Server => Puppet[:server]
- end
+ # Pick a random subclass...
+ Puppet::Network::Client.runner.new :Server => Puppet[:server]
end
+ end
- describe "when keep-alive is disabled" do
- before do
- Puppet::Network::HttpPool.stubs(:keep_alive?).returns false
- end
- it "should not start the http client up on creation" do
- http = mock 'http'
- http.stub_everything
- http.expects(:start).never
- Net::HTTP.stubs(:new).returns http
+ describe "when keep-alive is disabled" do
+ before do
+ Puppet::Network::HttpPool.stubs(:keep_alive?).returns false
+ end
+ it "should not start the http client up on creation" do
+ http = mock 'http'
+ http.stub_everything
+ http.expects(:start).never
+ Net::HTTP.stubs(:new).returns http
- # Pick a random subclass...
- Puppet::Network::Client.runner.new :Server => Puppet[:server]
- end
+ # Pick a random subclass...
+ Puppet::Network::Client.runner.new :Server => Puppet[:server]
end
+ end
end
diff --git a/spec/unit/network/format_handler_spec.rb b/spec/unit/network/format_handler_spec.rb
index 13a9b83..64cca82 100755
--- a/spec/unit/network/format_handler_spec.rb
+++ b/spec/unit/network/format_handler_spec.rb
@@ -5,332 +5,332 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/network/format_handler'
class FormatTester
- extend Puppet::Network::FormatHandler
+ extend Puppet::Network::FormatHandler
end
describe Puppet::Network::FormatHandler do
- after do
- formats = Puppet::Network::FormatHandler.instance_variable_get("@formats")
- formats.each do |name, format|
- formats.delete(name) unless format.is_a?(Puppet::Network::Format)
- end
- end
-
- it "should be able to list supported formats" do
- FormatTester.should respond_to(:supported_formats)
- end
-
- it "should include all supported formats" do
- one = stub 'supported', :supported? => true, :name => :one, :weight => 1
- two = stub 'supported', :supported? => false, :name => :two, :weight => 1
- three = stub 'supported', :supported? => true, :name => :three, :weight => 1
- four = stub 'supported', :supported? => false, :name => :four, :weight => 1
- Puppet::Network::FormatHandler.stubs(:formats).returns [:one, :two, :three, :four]
- Puppet::Network::FormatHandler.stubs(:format).with(:one).returns one
- Puppet::Network::FormatHandler.stubs(:format).with(:two).returns two
- Puppet::Network::FormatHandler.stubs(:format).with(:three).returns three
- Puppet::Network::FormatHandler.stubs(:format).with(:four).returns four
- result = FormatTester.supported_formats
- result.length.should == 2
- result.should be_include(:one)
- result.should be_include(:three)
- end
-
- it "should return the supported formats in decreasing order of weight" do
- one = stub 'supported', :supported? => true, :name => :one, :weight => 1
- two = stub 'supported', :supported? => true, :name => :two, :weight => 6
- three = stub 'supported', :supported? => true, :name => :three, :weight => 2
- four = stub 'supported', :supported? => true, :name => :four, :weight => 8
- Puppet::Network::FormatHandler.stubs(:formats).returns [:one, :two, :three, :four]
- Puppet::Network::FormatHandler.stubs(:format).with(:one).returns one
- Puppet::Network::FormatHandler.stubs(:format).with(:two).returns two
- Puppet::Network::FormatHandler.stubs(:format).with(:three).returns three
- Puppet::Network::FormatHandler.stubs(:format).with(:four).returns four
- FormatTester.supported_formats.should == [:four, :two, :three, :one]
- end
-
-
- describe "with a preferred serialization format setting" do
- before do
- one = stub 'supported', :supported? => true, :name => :one, :weight => 1
- two = stub 'supported', :supported? => true, :name => :two, :weight => 6
- Puppet::Network::FormatHandler.stubs(:formats).returns [:one, :two]
- Puppet::Network::FormatHandler.stubs(:format).with(:one).returns one
- Puppet::Network::FormatHandler.stubs(:format).with(:two).returns two
- end
- describe "that is supported" do
- before do
- Puppet.settings.expects(:value).with(:preferred_serialization_format).returns :one
- end
- it "should return the preferred serialization format first" do
- FormatTester.supported_formats.should == [:one, :two]
- end
- end
- describe "that is not supported" do
- before do
- Puppet.settings.expects(:value).with(:preferred_serialization_format).returns :unsupported
- end
- it "should still return the default format first" do
- FormatTester.supported_formats.should == [:two, :one]
- end
- it "should log a debug message" do
- Puppet.expects(:debug).with("Value of 'preferred_serialization_format' (unsupported) is invalid for FormatTester, using default (two)")
- Puppet.expects(:debug).with("FormatTester supports formats: one two; using two")
- FormatTester.supported_formats
- end
- end
- end
-
- it "should return the first format as the default format" do
- FormatTester.expects(:supported_formats).returns [:one, :two]
- FormatTester.default_format.should == :one
- end
-
- it "should be able to use a protected format for better logging on errors" do
- Puppet::Network::FormatHandler.should respond_to(:protected_format)
- end
-
- it "should delegate all methods from the informative format to the specified format" do
- format = mock 'format'
- format.stubs(:name).returns(:myformat)
- Puppet::Network::FormatHandler.expects(:format).twice.with(:myformat).returns format
-
- format.expects(:render).with("foo").returns "yay"
- Puppet::Network::FormatHandler.protected_format(:myformat).render("foo").should == "yay"
- end
-
- it "should provide better logging if a failure is encountered when delegating from the informative format to the real format" do
- format = mock 'format'
- format.stubs(:name).returns(:myformat)
- Puppet::Network::FormatHandler.expects(:format).twice.with(:myformat).returns format
-
- format.expects(:render).with("foo").raises "foo"
- lambda { Puppet::Network::FormatHandler.protected_format(:myformat).render("foo") }.should raise_error(Puppet::Network::FormatHandler::FormatError)
- end
-
- it "should raise an error if we couldn't find a format by name or mime-type" do
- Puppet::Network::FormatHandler.stubs(:format).with(:myformat).returns nil
- lambda { Puppet::Network::FormatHandler.protected_format(:myformat) }.should raise_error
- end
-
- describe "when using formats" do
- before do
- @format = mock 'format'
- @format.stubs(:supported?).returns true
- @format.stubs(:name).returns :my_format
- Puppet::Network::FormatHandler.stubs(:format).with(:my_format).returns @format
- Puppet::Network::FormatHandler.stubs(:mime).with("text/myformat").returns @format
- Puppet::Network::Format.stubs(:===).returns false
- Puppet::Network::Format.stubs(:===).with(@format).returns true
- end
-
- it "should be able to test whether a format is supported" do
- FormatTester.should respond_to(:support_format?)
- end
-
- it "should use the Format to determine whether a given format is supported" do
- @format.expects(:supported?).with(FormatTester)
- FormatTester.support_format?(:my_format)
- end
-
- it "should be able to convert from a given format" do
- FormatTester.should respond_to(:convert_from)
- end
-
- it "should call the format-specific converter when asked to convert from a given format" do
- @format.expects(:intern).with(FormatTester, "mydata")
- FormatTester.convert_from(:my_format, "mydata")
- end
-
- it "should call the format-specific converter when asked to convert from a given format by mime-type" do
- @format.expects(:intern).with(FormatTester, "mydata")
- FormatTester.convert_from("text/myformat", "mydata")
- end
-
- it "should call the format-specific converter when asked to convert from a given format by format instance" do
- @format.expects(:intern).with(FormatTester, "mydata")
- FormatTester.convert_from(@format, "mydata")
- end
-
- it "should raise a FormatError when an exception is encountered when converting from a format" do
- @format.expects(:intern).with(FormatTester, "mydata").raises "foo"
- lambda { FormatTester.convert_from(:my_format, "mydata") }.should raise_error(Puppet::Network::FormatHandler::FormatError)
- end
-
- it "should be able to use a specific hook for converting into multiple instances" do
- @format.expects(:intern_multiple).with(FormatTester, "mydata")
-
- FormatTester.convert_from_multiple(:my_format, "mydata")
- end
-
- it "should raise a FormatError when an exception is encountered when converting multiple items from a format" do
- @format.expects(:intern_multiple).with(FormatTester, "mydata").raises "foo"
- lambda { FormatTester.convert_from_multiple(:my_format, "mydata") }.should raise_error(Puppet::Network::FormatHandler::FormatError)
- end
-
- it "should be able to use a specific hook for rendering multiple instances" do
- @format.expects(:render_multiple).with("mydata")
-
- FormatTester.render_multiple(:my_format, "mydata")
- end
+ after do
+ formats = Puppet::Network::FormatHandler.instance_variable_get("@formats")
+ formats.each do |name, format|
+ formats.delete(name) unless format.is_a?(Puppet::Network::Format)
+ end
+ end
+
+ it "should be able to list supported formats" do
+ FormatTester.should respond_to(:supported_formats)
+ end
+
+ it "should include all supported formats" do
+ one = stub 'supported', :supported? => true, :name => :one, :weight => 1
+ two = stub 'supported', :supported? => false, :name => :two, :weight => 1
+ three = stub 'supported', :supported? => true, :name => :three, :weight => 1
+ four = stub 'supported', :supported? => false, :name => :four, :weight => 1
+ Puppet::Network::FormatHandler.stubs(:formats).returns [:one, :two, :three, :four]
+ Puppet::Network::FormatHandler.stubs(:format).with(:one).returns one
+ Puppet::Network::FormatHandler.stubs(:format).with(:two).returns two
+ Puppet::Network::FormatHandler.stubs(:format).with(:three).returns three
+ Puppet::Network::FormatHandler.stubs(:format).with(:four).returns four
+ result = FormatTester.supported_formats
+ result.length.should == 2
+ result.should be_include(:one)
+ result.should be_include(:three)
+ end
+
+ it "should return the supported formats in decreasing order of weight" do
+ one = stub 'supported', :supported? => true, :name => :one, :weight => 1
+ two = stub 'supported', :supported? => true, :name => :two, :weight => 6
+ three = stub 'supported', :supported? => true, :name => :three, :weight => 2
+ four = stub 'supported', :supported? => true, :name => :four, :weight => 8
+ Puppet::Network::FormatHandler.stubs(:formats).returns [:one, :two, :three, :four]
+ Puppet::Network::FormatHandler.stubs(:format).with(:one).returns one
+ Puppet::Network::FormatHandler.stubs(:format).with(:two).returns two
+ Puppet::Network::FormatHandler.stubs(:format).with(:three).returns three
+ Puppet::Network::FormatHandler.stubs(:format).with(:four).returns four
+ FormatTester.supported_formats.should == [:four, :two, :three, :one]
+ end
+
+
+ describe "with a preferred serialization format setting" do
+ before do
+ one = stub 'supported', :supported? => true, :name => :one, :weight => 1
+ two = stub 'supported', :supported? => true, :name => :two, :weight => 6
+ Puppet::Network::FormatHandler.stubs(:formats).returns [:one, :two]
+ Puppet::Network::FormatHandler.stubs(:format).with(:one).returns one
+ Puppet::Network::FormatHandler.stubs(:format).with(:two).returns two
+ end
+ describe "that is supported" do
+ before do
+ Puppet.settings.expects(:value).with(:preferred_serialization_format).returns :one
+ end
+ it "should return the preferred serialization format first" do
+ FormatTester.supported_formats.should == [:one, :two]
+ end
+ end
+ describe "that is not supported" do
+ before do
+ Puppet.settings.expects(:value).with(:preferred_serialization_format).returns :unsupported
+ end
+ it "should still return the default format first" do
+ FormatTester.supported_formats.should == [:two, :one]
+ end
+ it "should log a debug message" do
+ Puppet.expects(:debug).with("Value of 'preferred_serialization_format' (unsupported) is invalid for FormatTester, using default (two)")
+ Puppet.expects(:debug).with("FormatTester supports formats: one two; using two")
+ FormatTester.supported_formats
+ end
+ end
+ end
+
+ it "should return the first format as the default format" do
+ FormatTester.expects(:supported_formats).returns [:one, :two]
+ FormatTester.default_format.should == :one
+ end
+
+ it "should be able to use a protected format for better logging on errors" do
+ Puppet::Network::FormatHandler.should respond_to(:protected_format)
+ end
+
+ it "should delegate all methods from the informative format to the specified format" do
+ format = mock 'format'
+ format.stubs(:name).returns(:myformat)
+ Puppet::Network::FormatHandler.expects(:format).twice.with(:myformat).returns format
+
+ format.expects(:render).with("foo").returns "yay"
+ Puppet::Network::FormatHandler.protected_format(:myformat).render("foo").should == "yay"
+ end
+
+ it "should provide better logging if a failure is encountered when delegating from the informative format to the real format" do
+ format = mock 'format'
+ format.stubs(:name).returns(:myformat)
+ Puppet::Network::FormatHandler.expects(:format).twice.with(:myformat).returns format
+
+ format.expects(:render).with("foo").raises "foo"
+ lambda { Puppet::Network::FormatHandler.protected_format(:myformat).render("foo") }.should raise_error(Puppet::Network::FormatHandler::FormatError)
+ end
+
+ it "should raise an error if we couldn't find a format by name or mime-type" do
+ Puppet::Network::FormatHandler.stubs(:format).with(:myformat).returns nil
+ lambda { Puppet::Network::FormatHandler.protected_format(:myformat) }.should raise_error
+ end
+
+ describe "when using formats" do
+ before do
+ @format = mock 'format'
+ @format.stubs(:supported?).returns true
+ @format.stubs(:name).returns :my_format
+ Puppet::Network::FormatHandler.stubs(:format).with(:my_format).returns @format
+ Puppet::Network::FormatHandler.stubs(:mime).with("text/myformat").returns @format
+ Puppet::Network::Format.stubs(:===).returns false
+ Puppet::Network::Format.stubs(:===).with(@format).returns true
+ end
+
+ it "should be able to test whether a format is supported" do
+ FormatTester.should respond_to(:support_format?)
+ end
+
+ it "should use the Format to determine whether a given format is supported" do
+ @format.expects(:supported?).with(FormatTester)
+ FormatTester.support_format?(:my_format)
+ end
+
+ it "should be able to convert from a given format" do
+ FormatTester.should respond_to(:convert_from)
+ end
+
+ it "should call the format-specific converter when asked to convert from a given format" do
+ @format.expects(:intern).with(FormatTester, "mydata")
+ FormatTester.convert_from(:my_format, "mydata")
+ end
+
+ it "should call the format-specific converter when asked to convert from a given format by mime-type" do
+ @format.expects(:intern).with(FormatTester, "mydata")
+ FormatTester.convert_from("text/myformat", "mydata")
+ end
+
+ it "should call the format-specific converter when asked to convert from a given format by format instance" do
+ @format.expects(:intern).with(FormatTester, "mydata")
+ FormatTester.convert_from(@format, "mydata")
+ end
+
+ it "should raise a FormatError when an exception is encountered when converting from a format" do
+ @format.expects(:intern).with(FormatTester, "mydata").raises "foo"
+ lambda { FormatTester.convert_from(:my_format, "mydata") }.should raise_error(Puppet::Network::FormatHandler::FormatError)
+ end
+
+ it "should be able to use a specific hook for converting into multiple instances" do
+ @format.expects(:intern_multiple).with(FormatTester, "mydata")
+
+ FormatTester.convert_from_multiple(:my_format, "mydata")
+ end
+
+ it "should raise a FormatError when an exception is encountered when converting multiple items from a format" do
+ @format.expects(:intern_multiple).with(FormatTester, "mydata").raises "foo"
+ lambda { FormatTester.convert_from_multiple(:my_format, "mydata") }.should raise_error(Puppet::Network::FormatHandler::FormatError)
+ end
+
+ it "should be able to use a specific hook for rendering multiple instances" do
+ @format.expects(:render_multiple).with("mydata")
- it "should raise a FormatError when an exception is encountered when rendering multiple items into a format" do
- @format.expects(:render_multiple).with("mydata").raises "foo"
- lambda { FormatTester.render_multiple(:my_format, "mydata") }.should raise_error(Puppet::Network::FormatHandler::FormatError)
- end
+ FormatTester.render_multiple(:my_format, "mydata")
end
- describe "when managing formats" do
- it "should have a method for defining a new format" do
- Puppet::Network::FormatHandler.should respond_to(:create)
- end
+ it "should raise a FormatError when an exception is encountered when rendering multiple items into a format" do
+ @format.expects(:render_multiple).with("mydata").raises "foo"
+ lambda { FormatTester.render_multiple(:my_format, "mydata") }.should raise_error(Puppet::Network::FormatHandler::FormatError)
+ end
+ end
- it "should create a format instance when asked" do
- format = stub 'format', :name => :foo
- Puppet::Network::Format.expects(:new).with(:foo).returns format
- Puppet::Network::FormatHandler.create(:foo)
- end
-
- it "should instance_eval any block provided when creating a format" do
- format = stub 'format', :name => :instance_eval
- format.expects(:yayness)
- Puppet::Network::Format.expects(:new).returns format
- Puppet::Network::FormatHandler.create(:instance_eval) do
- yayness
- end
- end
-
- it "should be able to retrieve a format by name" do
- format = Puppet::Network::FormatHandler.create(:by_name)
- Puppet::Network::FormatHandler.format(:by_name).should equal(format)
- end
-
- it "should be able to retrieve a format by extension" do
- format = Puppet::Network::FormatHandler.create(:by_extension, :extension => "foo")
- Puppet::Network::FormatHandler.format_by_extension("foo").should equal(format)
- end
-
- it "should return nil if asked to return a format by an unknown extension" do
- Puppet::Network::FormatHandler.format_by_extension("yayness").should be_nil
- end
-
- it "should be able to retrieve formats by name irrespective of case and class" do
- format = Puppet::Network::FormatHandler.create(:by_name)
- Puppet::Network::FormatHandler.format(:By_Name).should equal(format)
- end
+ describe "when managing formats" do
+ it "should have a method for defining a new format" do
+ Puppet::Network::FormatHandler.should respond_to(:create)
+ end
- it "should be able to retrieve a format by mime type" do
- format = Puppet::Network::FormatHandler.create(:by_name, :mime => "foo/bar")
- Puppet::Network::FormatHandler.mime("foo/bar").should equal(format)
- end
+ it "should create a format instance when asked" do
+ format = stub 'format', :name => :foo
+ Puppet::Network::Format.expects(:new).with(:foo).returns format
+ Puppet::Network::FormatHandler.create(:foo)
+ end
- it "should be able to retrieve a format by mime type irrespective of case" do
- format = Puppet::Network::FormatHandler.create(:by_name, :mime => "foo/bar")
- Puppet::Network::FormatHandler.mime("Foo/Bar").should equal(format)
- end
+ it "should instance_eval any block provided when creating a format" do
+ format = stub 'format', :name => :instance_eval
+ format.expects(:yayness)
+ Puppet::Network::Format.expects(:new).returns format
+ Puppet::Network::FormatHandler.create(:instance_eval) do
+ yayness
+ end
+ end
- it "should be able to return all formats" do
- one = stub 'one', :name => :one
- two = stub 'two', :name => :two
- Puppet::Network::Format.expects(:new).with(:one).returns(one)
- Puppet::Network::Format.expects(:new).with(:two).returns(two)
+ it "should be able to retrieve a format by name" do
+ format = Puppet::Network::FormatHandler.create(:by_name)
+ Puppet::Network::FormatHandler.format(:by_name).should equal(format)
+ end
- Puppet::Network::FormatHandler.create(:one)
- Puppet::Network::FormatHandler.create(:two)
+ it "should be able to retrieve a format by extension" do
+ format = Puppet::Network::FormatHandler.create(:by_extension, :extension => "foo")
+ Puppet::Network::FormatHandler.format_by_extension("foo").should equal(format)
+ end
- list = Puppet::Network::FormatHandler.formats
- list.should be_include(:one)
- list.should be_include(:two)
- end
+ it "should return nil if asked to return a format by an unknown extension" do
+ Puppet::Network::FormatHandler.format_by_extension("yayness").should be_nil
end
- describe "when an instance" do
- it "should be able to test whether a format is supported" do
- FormatTester.new.should respond_to(:support_format?)
- end
+ it "should be able to retrieve formats by name irrespective of case and class" do
+ format = Puppet::Network::FormatHandler.create(:by_name)
+ Puppet::Network::FormatHandler.format(:By_Name).should equal(format)
+ end
- it "should be able to convert to a given format" do
- FormatTester.new.should respond_to(:render)
- end
+ it "should be able to retrieve a format by mime type" do
+ format = Puppet::Network::FormatHandler.create(:by_name, :mime => "foo/bar")
+ Puppet::Network::FormatHandler.mime("foo/bar").should equal(format)
+ end
- it "should be able to get a format mime-type" do
- FormatTester.new.should respond_to(:mime)
- end
+ it "should be able to retrieve a format by mime type irrespective of case" do
+ format = Puppet::Network::FormatHandler.create(:by_name, :mime => "foo/bar")
+ Puppet::Network::FormatHandler.mime("Foo/Bar").should equal(format)
+ end
- it "should raise a FormatError when a rendering error is encountered" do
- format = stub 'rendering format', :supported? => true, :name => :foo
- Puppet::Network::FormatHandler.stubs(:format).with(:foo).returns format
+ it "should be able to return all formats" do
+ one = stub 'one', :name => :one
+ two = stub 'two', :name => :two
+ Puppet::Network::Format.expects(:new).with(:one).returns(one)
+ Puppet::Network::Format.expects(:new).with(:two).returns(two)
- tester = FormatTester.new
- format.expects(:render).with(tester).raises "eh"
+ Puppet::Network::FormatHandler.create(:one)
+ Puppet::Network::FormatHandler.create(:two)
- lambda { tester.render(:foo) }.should raise_error(Puppet::Network::FormatHandler::FormatError)
- end
+ list = Puppet::Network::FormatHandler.formats
+ list.should be_include(:one)
+ list.should be_include(:two)
+ end
+ end
- it "should call the format-specific converter when asked to convert to a given format" do
- format = stub 'rendering format', :supported? => true, :name => :foo
+ describe "when an instance" do
+ it "should be able to test whether a format is supported" do
+ FormatTester.new.should respond_to(:support_format?)
+ end
- Puppet::Network::FormatHandler.stubs(:format).with(:foo).returns format
+ it "should be able to convert to a given format" do
+ FormatTester.new.should respond_to(:render)
+ end
- tester = FormatTester.new
- format.expects(:render).with(tester).returns "foo"
+ it "should be able to get a format mime-type" do
+ FormatTester.new.should respond_to(:mime)
+ end
- tester.render(:foo).should == "foo"
- end
+ it "should raise a FormatError when a rendering error is encountered" do
+ format = stub 'rendering format', :supported? => true, :name => :foo
+ Puppet::Network::FormatHandler.stubs(:format).with(:foo).returns format
- it "should call the format-specific converter when asked to convert to a given format by mime-type" do
- format = stub 'rendering format', :supported? => true, :name => :foo
- Puppet::Network::FormatHandler.stubs(:mime).with("text/foo").returns format
- Puppet::Network::FormatHandler.stubs(:format).with(:foo).returns format
+ tester = FormatTester.new
+ format.expects(:render).with(tester).raises "eh"
- tester = FormatTester.new
- format.expects(:render).with(tester).returns "foo"
+ lambda { tester.render(:foo) }.should raise_error(Puppet::Network::FormatHandler::FormatError)
+ end
+
+ it "should call the format-specific converter when asked to convert to a given format" do
+ format = stub 'rendering format', :supported? => true, :name => :foo
+
+ Puppet::Network::FormatHandler.stubs(:format).with(:foo).returns format
+
+ tester = FormatTester.new
+ format.expects(:render).with(tester).returns "foo"
+
+ tester.render(:foo).should == "foo"
+ end
- tester.render("text/foo").should == "foo"
- end
+ it "should call the format-specific converter when asked to convert to a given format by mime-type" do
+ format = stub 'rendering format', :supported? => true, :name => :foo
+ Puppet::Network::FormatHandler.stubs(:mime).with("text/foo").returns format
+ Puppet::Network::FormatHandler.stubs(:format).with(:foo).returns format
- it "should call the format converter when asked to convert to a given format instance" do
- format = stub 'rendering format', :supported? => true, :name => :foo
- Puppet::Network::Format.stubs(:===).with(format).returns(true)
- Puppet::Network::FormatHandler.stubs(:format).with(:foo).returns format
+ tester = FormatTester.new
+ format.expects(:render).with(tester).returns "foo"
- tester = FormatTester.new
- format.expects(:render).with(tester).returns "foo"
+ tester.render("text/foo").should == "foo"
+ end
+
+ it "should call the format converter when asked to convert to a given format instance" do
+ format = stub 'rendering format', :supported? => true, :name => :foo
+ Puppet::Network::Format.stubs(:===).with(format).returns(true)
+ Puppet::Network::FormatHandler.stubs(:format).with(:foo).returns format
+
+ tester = FormatTester.new
+ format.expects(:render).with(tester).returns "foo"
- tester.render(format).should == "foo"
- end
+ tester.render(format).should == "foo"
+ end
- it "should render to the default format if no format is provided when rendering" do
- format = stub 'rendering format', :supported? => true, :name => :foo
- Puppet::Network::FormatHandler.stubs(:format).with(:foo).returns format
+ it "should render to the default format if no format is provided when rendering" do
+ format = stub 'rendering format', :supported? => true, :name => :foo
+ Puppet::Network::FormatHandler.stubs(:format).with(:foo).returns format
- FormatTester.expects(:default_format).returns :foo
- tester = FormatTester.new
+ FormatTester.expects(:default_format).returns :foo
+ tester = FormatTester.new
- format.expects(:render).with(tester)
- tester.render
- end
+ format.expects(:render).with(tester)
+ tester.render
+ end
- it "should call the format-specific converter when asked for the mime-type of a given format" do
- format = stub 'rendering format', :supported? => true, :name => :foo
+ it "should call the format-specific converter when asked for the mime-type of a given format" do
+ format = stub 'rendering format', :supported? => true, :name => :foo
- Puppet::Network::FormatHandler.stubs(:format).with(:foo).returns format
+ Puppet::Network::FormatHandler.stubs(:format).with(:foo).returns format
- tester = FormatTester.new
- format.expects(:mime).returns "text/foo"
+ tester = FormatTester.new
+ format.expects(:mime).returns "text/foo"
- tester.mime(:foo).should == "text/foo"
- end
+ tester.mime(:foo).should == "text/foo"
+ end
- it "should return the default format mime-type if no format is provided" do
- format = stub 'rendering format', :supported? => true, :name => :foo
- Puppet::Network::FormatHandler.stubs(:format).with(:foo).returns format
+ it "should return the default format mime-type if no format is provided" do
+ format = stub 'rendering format', :supported? => true, :name => :foo
+ Puppet::Network::FormatHandler.stubs(:format).with(:foo).returns format
- FormatTester.expects(:default_format).returns :foo
- tester = FormatTester.new
+ FormatTester.expects(:default_format).returns :foo
+ tester = FormatTester.new
- format.expects(:mime).returns "text/foo"
- tester.mime.should == "text/foo"
- end
+ format.expects(:mime).returns "text/foo"
+ tester.mime.should == "text/foo"
end
+ end
end
diff --git a/spec/unit/network/format_spec.rb b/spec/unit/network/format_spec.rb
index 73530b9..bcb0841 100755
--- a/spec/unit/network/format_spec.rb
+++ b/spec/unit/network/format_spec.rb
@@ -7,192 +7,192 @@ require 'puppet/network/format'
# A class with all of the necessary
# hooks.
class FormatRenderer
- def self.to_multiple_my_format(list)
+ def self.to_multiple_my_format(list)
+ end
+
+ def self.from_multiple_my_format(text)
+ end
+
+ def self.from_my_format(text)
+ end
+
+ def to_my_format
+ end
+end
+
+describe Puppet::Network::Format do
+ describe "when initializing" do
+ it "should require a name" do
+ lambda { Puppet::Network::Format.new }.should raise_error(ArgumentError)
end
- def self.from_multiple_my_format(text)
+ it "should be able to provide its name" do
+ Puppet::Network::Format.new(:my_format).name.should == :my_format
end
- def self.from_my_format(text)
+ it "should always convert its name to a downcased symbol" do
+ Puppet::Network::Format.new(:My_Format).name.should == :my_format
end
- def to_my_format
+ it "should be able to set its downcased mime type at initialization" do
+ format = Puppet::Network::Format.new(:my_format, :mime => "Foo/Bar")
+ format.mime.should == "foo/bar"
end
-end
-describe Puppet::Network::Format do
- describe "when initializing" do
- it "should require a name" do
- lambda { Puppet::Network::Format.new }.should raise_error(ArgumentError)
- end
-
- it "should be able to provide its name" do
- Puppet::Network::Format.new(:my_format).name.should == :my_format
- end
-
- it "should always convert its name to a downcased symbol" do
- Puppet::Network::Format.new(:My_Format).name.should == :my_format
- end
-
- it "should be able to set its downcased mime type at initialization" do
- format = Puppet::Network::Format.new(:my_format, :mime => "Foo/Bar")
- format.mime.should == "foo/bar"
- end
-
- it "should default to text plus the name of the format as the mime type" do
- Puppet::Network::Format.new(:my_format).mime.should == "text/my_format"
- end
-
- it "should fail if unsupported options are provided" do
- lambda { Puppet::Network::Format.new(:my_format, :foo => "bar") }.should raise_error(ArgumentError)
- end
- end
-
- describe "instances" do
- before do
- @format = Puppet::Network::Format.new(:my_format)
- end
-
- it "should support being confined" do
- @format.should respond_to(:confine)
- end
-
- it "should not be considered suitable if confinement conditions are not met" do
- @format.confine :true => false
- @format.should_not be_suitable
- end
-
- it "should be able to determine if a class is supported" do
- @format.should respond_to(:supported?)
- end
-
- it "should consider a class to be supported if it has the individual and multiple methods for rendering and interning" do
- @format.should be_supported(FormatRenderer)
- end
-
- it "should default to its required methods being the individual and multiple methods for rendering and interning" do
- Puppet::Network::Format.new(:foo).required_methods.sort { |a,b| a.to_s <=> b.to_s }.should == [:intern_method, :intern_multiple_method, :render_multiple_method, :render_method].sort { |a,b| a.to_s <=> b.to_s }
- end
-
- it "should consider a class supported if the provided class has all required methods present" do
- format = Puppet::Network::Format.new(:foo)
- [:intern_method, :intern_multiple_method, :render_multiple_method, :render_method].each do |method|
- format.expects(:required_method_present?).with { |name, klass, type| name == method and klass == String }.returns true
- end
-
- format.should be_required_methods_present(String)
- end
-
- it "should consider a class not supported if any required methods are missing from the provided class" do
- format = Puppet::Network::Format.new(:foo)
- format.stubs(:required_method_present?).returns true
- format.expects(:required_method_present?).with { |name, *args| name == :intern_method }.returns false
- format.should_not be_required_methods_present(String)
- end
-
- it "should be able to specify the methods required for support" do
- Puppet::Network::Format.new(:foo, :required_methods => [:render_method, :intern_method]).required_methods.should == [:render_method, :intern_method]
- end
-
- it "should only test for required methods if specific methods are specified as required" do
- format = Puppet::Network::Format.new(:foo, :required_methods => [:intern_method])
- format.expects(:required_method_present?).with { |name, klass, type| name == :intern_method }
-
- format.required_methods_present?(String)
- end
-
- it "should not consider a class supported unless the format is suitable" do
- @format.expects(:suitable?).returns false
- @format.should_not be_supported(FormatRenderer)
- end
-
- it "should always downcase mimetypes" do
- @format.mime = "Foo/Bar"
- @format.mime.should == "foo/bar"
- end
-
- it "should support having a weight" do
- @format.should respond_to(:weight)
- end
-
- it "should default to a weight of of 5" do
- @format.weight.should == 5
- end
-
- it "should be able to override its weight at initialization" do
- Puppet::Network::Format.new(:foo, :weight => 1).weight.should == 1
- end
-
- it "should default to its extension being equal to its name" do
- Puppet::Network::Format.new(:foo).extension.should == "foo"
- end
-
- it "should support overriding the extension" do
- Puppet::Network::Format.new(:foo, :extension => "bar").extension.should == "bar"
- end
- [:intern_method, :intern_multiple_method, :render_multiple_method, :render_method].each do |method|
- it "should allow assignment of the #{method}" do
- Puppet::Network::Format.new(:foo, method => :foo).send(method).should == :foo
- end
- end
- end
-
- describe "when converting between instances and formatted text" do
- before do
- @format = Puppet::Network::Format.new(:my_format)
- @instance = FormatRenderer.new
- end
-
- it "should have a method for rendering a single instance" do
- @format.should respond_to(:render)
- end
-
- it "should have a method for rendering multiple instances" do
- @format.should respond_to(:render_multiple)
- end
-
- it "should have a method for interning text" do
- @format.should respond_to(:intern)
- end
-
- it "should have a method for interning text into multiple instances" do
- @format.should respond_to(:intern_multiple)
- end
-
- it "should return the results of calling the instance-specific render method if the method is present" do
- @instance.expects(:to_my_format).returns "foo"
- @format.render(@instance).should == "foo"
- end
-
- it "should return the results of calling the class-specific render_multiple method if the method is present" do
- @instance.class.expects(:to_multiple_my_format).returns ["foo"]
- @format.render_multiple([@instance]).should == ["foo"]
- end
-
- it "should return the results of calling the class-specific intern method if the method is present" do
- FormatRenderer.expects(:from_my_format).with("foo").returns @instance
- @format.intern(FormatRenderer, "foo").should equal(@instance)
- end
-
- it "should return the results of calling the class-specific intern_multiple method if the method is present" do
- FormatRenderer.expects(:from_multiple_my_format).with("foo").returns [@instance]
- @format.intern_multiple(FormatRenderer, "foo").should == [@instance]
- end
-
- it "should fail if asked to render and the instance does not respond to 'to_<format>'" do
- lambda { @format.render("foo") }.should raise_error(NotImplementedError)
- end
-
- it "should fail if asked to intern and the class does not respond to 'from_<format>'" do
- lambda { @format.intern(String, "foo") }.should raise_error(NotImplementedError)
- end
-
- it "should fail if asked to intern multiple and the class does not respond to 'from_multiple_<format>'" do
- lambda { @format.intern_multiple(String, "foo") }.should raise_error(NotImplementedError)
- end
-
- it "should fail if asked to render multiple and the instance does not respond to 'to_multiple_<format>'" do
- lambda { @format.render_multiple(["foo", "bar"]) }.should raise_error(NotImplementedError)
- end
+ it "should default to text plus the name of the format as the mime type" do
+ Puppet::Network::Format.new(:my_format).mime.should == "text/my_format"
+ end
+
+ it "should fail if unsupported options are provided" do
+ lambda { Puppet::Network::Format.new(:my_format, :foo => "bar") }.should raise_error(ArgumentError)
+ end
+ end
+
+ describe "instances" do
+ before do
+ @format = Puppet::Network::Format.new(:my_format)
+ end
+
+ it "should support being confined" do
+ @format.should respond_to(:confine)
+ end
+
+ it "should not be considered suitable if confinement conditions are not met" do
+ @format.confine :true => false
+ @format.should_not be_suitable
+ end
+
+ it "should be able to determine if a class is supported" do
+ @format.should respond_to(:supported?)
+ end
+
+ it "should consider a class to be supported if it has the individual and multiple methods for rendering and interning" do
+ @format.should be_supported(FormatRenderer)
+ end
+
+ it "should default to its required methods being the individual and multiple methods for rendering and interning" do
+ Puppet::Network::Format.new(:foo).required_methods.sort { |a,b| a.to_s <=> b.to_s }.should == [:intern_method, :intern_multiple_method, :render_multiple_method, :render_method].sort { |a,b| a.to_s <=> b.to_s }
+ end
+
+ it "should consider a class supported if the provided class has all required methods present" do
+ format = Puppet::Network::Format.new(:foo)
+ [:intern_method, :intern_multiple_method, :render_multiple_method, :render_method].each do |method|
+ format.expects(:required_method_present?).with { |name, klass, type| name == method and klass == String }.returns true
+ end
+
+ format.should be_required_methods_present(String)
+ end
+
+ it "should consider a class not supported if any required methods are missing from the provided class" do
+ format = Puppet::Network::Format.new(:foo)
+ format.stubs(:required_method_present?).returns true
+ format.expects(:required_method_present?).with { |name, *args| name == :intern_method }.returns false
+ format.should_not be_required_methods_present(String)
+ end
+
+ it "should be able to specify the methods required for support" do
+ Puppet::Network::Format.new(:foo, :required_methods => [:render_method, :intern_method]).required_methods.should == [:render_method, :intern_method]
+ end
+
+ it "should only test for required methods if specific methods are specified as required" do
+ format = Puppet::Network::Format.new(:foo, :required_methods => [:intern_method])
+ format.expects(:required_method_present?).with { |name, klass, type| name == :intern_method }
+
+ format.required_methods_present?(String)
+ end
+
+ it "should not consider a class supported unless the format is suitable" do
+ @format.expects(:suitable?).returns false
+ @format.should_not be_supported(FormatRenderer)
+ end
+
+ it "should always downcase mimetypes" do
+ @format.mime = "Foo/Bar"
+ @format.mime.should == "foo/bar"
+ end
+
+ it "should support having a weight" do
+ @format.should respond_to(:weight)
+ end
+
+ it "should default to a weight of of 5" do
+ @format.weight.should == 5
+ end
+
+ it "should be able to override its weight at initialization" do
+ Puppet::Network::Format.new(:foo, :weight => 1).weight.should == 1
+ end
+
+ it "should default to its extension being equal to its name" do
+ Puppet::Network::Format.new(:foo).extension.should == "foo"
+ end
+
+ it "should support overriding the extension" do
+ Puppet::Network::Format.new(:foo, :extension => "bar").extension.should == "bar"
+ end
+ [:intern_method, :intern_multiple_method, :render_multiple_method, :render_method].each do |method|
+ it "should allow assignment of the #{method}" do
+ Puppet::Network::Format.new(:foo, method => :foo).send(method).should == :foo
+ end
+ end
+ end
+
+ describe "when converting between instances and formatted text" do
+ before do
+ @format = Puppet::Network::Format.new(:my_format)
+ @instance = FormatRenderer.new
+ end
+
+ it "should have a method for rendering a single instance" do
+ @format.should respond_to(:render)
+ end
+
+ it "should have a method for rendering multiple instances" do
+ @format.should respond_to(:render_multiple)
+ end
+
+ it "should have a method for interning text" do
+ @format.should respond_to(:intern)
+ end
+
+ it "should have a method for interning text into multiple instances" do
+ @format.should respond_to(:intern_multiple)
+ end
+
+ it "should return the results of calling the instance-specific render method if the method is present" do
+ @instance.expects(:to_my_format).returns "foo"
+ @format.render(@instance).should == "foo"
+ end
+
+ it "should return the results of calling the class-specific render_multiple method if the method is present" do
+ @instance.class.expects(:to_multiple_my_format).returns ["foo"]
+ @format.render_multiple([@instance]).should == ["foo"]
+ end
+
+ it "should return the results of calling the class-specific intern method if the method is present" do
+ FormatRenderer.expects(:from_my_format).with("foo").returns @instance
+ @format.intern(FormatRenderer, "foo").should equal(@instance)
+ end
+
+ it "should return the results of calling the class-specific intern_multiple method if the method is present" do
+ FormatRenderer.expects(:from_multiple_my_format).with("foo").returns [@instance]
+ @format.intern_multiple(FormatRenderer, "foo").should == [@instance]
+ end
+
+ it "should fail if asked to render and the instance does not respond to 'to_<format>'" do
+ lambda { @format.render("foo") }.should raise_error(NotImplementedError)
+ end
+
+ it "should fail if asked to intern and the class does not respond to 'from_<format>'" do
+ lambda { @format.intern(String, "foo") }.should raise_error(NotImplementedError)
+ end
+
+ it "should fail if asked to intern multiple and the class does not respond to 'from_multiple_<format>'" do
+ lambda { @format.intern_multiple(String, "foo") }.should raise_error(NotImplementedError)
+ end
+
+ it "should fail if asked to render multiple and the instance does not respond to 'to_multiple_<format>'" do
+ lambda { @format.render_multiple(["foo", "bar"]) }.should raise_error(NotImplementedError)
end
+ end
end
diff --git a/spec/unit/network/formats_spec.rb b/spec/unit/network/formats_spec.rb
index 0811d61..7c8e7b1 100755
--- a/spec/unit/network/formats_spec.rb
+++ b/spec/unit/network/formats_spec.rb
@@ -5,333 +5,333 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/network/formats'
class PsonTest
- attr_accessor :string
- def ==(other)
- string == other.string
+ attr_accessor :string
+ def ==(other)
+ string == other.string
+ end
+
+ def self.from_pson(data)
+ new(data)
+ end
+
+ def initialize(string)
+ @string = string
+ end
+
+ def to_pson(*args)
+ {
+ 'type' => self.class.name,
+ 'data' => @string
+ }.to_pson(*args)
+ end
+end
+
+describe "Puppet Network Format" do
+ it "should include a yaml format" do
+ Puppet::Network::FormatHandler.format(:yaml).should_not be_nil
+ end
+
+ describe "yaml" do
+ before do
+ @yaml = Puppet::Network::FormatHandler.format(:yaml)
end
- def self.from_pson(data)
- new(data)
+ it "should have its mime type set to text/yaml" do
+ @yaml.mime.should == "text/yaml"
end
- def initialize(string)
- @string = string
+ it "should be supported on Strings" do
+ @yaml.should be_supported(String)
end
- def to_pson(*args)
- {
- 'type' => self.class.name,
- 'data' => @string
- }.to_pson(*args)
+ it "should render by calling 'to_yaml' on the instance" do
+ instance = mock 'instance'
+ instance.expects(:to_yaml).returns "foo"
+ @yaml.render(instance).should == "foo"
end
-end
-describe "Puppet Network Format" do
- it "should include a yaml format" do
- Puppet::Network::FormatHandler.format(:yaml).should_not be_nil
- end
-
- describe "yaml" do
- before do
- @yaml = Puppet::Network::FormatHandler.format(:yaml)
- end
-
- it "should have its mime type set to text/yaml" do
- @yaml.mime.should == "text/yaml"
- end
-
- it "should be supported on Strings" do
- @yaml.should be_supported(String)
- end
-
- it "should render by calling 'to_yaml' on the instance" do
- instance = mock 'instance'
- instance.expects(:to_yaml).returns "foo"
- @yaml.render(instance).should == "foo"
- end
-
- it "should render multiple instances by calling 'to_yaml' on the array" do
- instances = [mock('instance')]
- instances.expects(:to_yaml).returns "foo"
- @yaml.render_multiple(instances).should == "foo"
- end
-
- it "should intern by calling 'YAML.load'" do
- text = "foo"
- YAML.expects(:load).with("foo").returns "bar"
- @yaml.intern(String, text).should == "bar"
- end
-
- it "should intern multiples by calling 'YAML.load'" do
- text = "foo"
- YAML.expects(:load).with("foo").returns "bar"
- @yaml.intern_multiple(String, text).should == "bar"
- end
+ it "should render multiple instances by calling 'to_yaml' on the array" do
+ instances = [mock('instance')]
+ instances.expects(:to_yaml).returns "foo"
+ @yaml.render_multiple(instances).should == "foo"
end
- describe "base64 compressed yaml" do
- yaml = Puppet::Network::FormatHandler.format(:b64_zlib_yaml)
- confine "We must have zlib" => Puppet.features.zlib?
+ it "should intern by calling 'YAML.load'" do
+ text = "foo"
+ YAML.expects(:load).with("foo").returns "bar"
+ @yaml.intern(String, text).should == "bar"
+ end
+
+ it "should intern multiples by calling 'YAML.load'" do
+ text = "foo"
+ YAML.expects(:load).with("foo").returns "bar"
+ @yaml.intern_multiple(String, text).should == "bar"
+ end
+ end
- before do
- @yaml = Puppet::Network::FormatHandler.format(:b64_zlib_yaml)
- end
+ describe "base64 compressed yaml" do
+ yaml = Puppet::Network::FormatHandler.format(:b64_zlib_yaml)
+ confine "We must have zlib" => Puppet.features.zlib?
+
+ before do
+ @yaml = Puppet::Network::FormatHandler.format(:b64_zlib_yaml)
+ end
- it "should have its mime type set to text/b64_zlib_yaml" do
- @yaml.mime.should == "text/b64_zlib_yaml"
- end
+ it "should have its mime type set to text/b64_zlib_yaml" do
+ @yaml.mime.should == "text/b64_zlib_yaml"
+ end
- it "should render by calling 'to_yaml' on the instance" do
- instance = mock 'instance'
- instance.expects(:to_yaml).returns "foo"
- @yaml.render(instance)
- end
-
- it "should encode generated yaml on render" do
- instance = mock 'instance', :to_yaml => "foo"
+ it "should render by calling 'to_yaml' on the instance" do
+ instance = mock 'instance'
+ instance.expects(:to_yaml).returns "foo"
+ @yaml.render(instance)
+ end
- @yaml.expects(:encode).with("foo").returns "bar"
-
- @yaml.render(instance).should == "bar"
- end
-
- it "should render multiple instances by calling 'to_yaml' on the array" do
- instances = [mock('instance')]
- instances.expects(:to_yaml).returns "foo"
- @yaml.render_multiple(instances)
- end
-
- it "should encode generated yaml on render" do
- instances = [mock('instance')]
- instances.stubs(:to_yaml).returns "foo"
-
- @yaml.expects(:encode).with("foo").returns "bar"
-
- @yaml.render(instances).should == "bar"
- end
-
- it "should intern by calling decode" do
- text = "foo"
- @yaml.expects(:decode).with("foo").returns "bar"
- @yaml.intern(String, text).should == "bar"
- end
-
- it "should intern multiples by calling 'decode'" do
- text = "foo"
- @yaml.expects(:decode).with("foo").returns "bar"
- @yaml.intern_multiple(String, text).should == "bar"
- end
+ it "should encode generated yaml on render" do
+ instance = mock 'instance', :to_yaml => "foo"
- it "should decode by base64 decoding, uncompressing and Yaml loading" do
- Base64.expects(:decode64).with("zorg").returns "foo"
- Zlib::Inflate.expects(:inflate).with("foo").returns "baz"
- YAML.expects(:load).with("baz").returns "bar"
- @yaml.decode("zorg").should == "bar"
- end
-
- it "should encode by compressing and base64 encoding" do
- Zlib::Deflate.expects(:deflate).with("foo", Zlib::BEST_COMPRESSION).returns "bar"
- Base64.expects(:encode64).with("bar").returns "baz"
- @yaml.encode("foo").should == "baz"
- end
-
- describe "when zlib is disabled" do
- before do
- Puppet[:zlib] = false
- end
+ @yaml.expects(:encode).with("foo").returns "bar"
- it "use_zlib? should return false" do
- @yaml.use_zlib?.should == false
- end
+ @yaml.render(instance).should == "bar"
+ end
- it "should refuse to encode" do
- lambda{ @yaml.encode("foo") }.should raise_error
- end
+ it "should render multiple instances by calling 'to_yaml' on the array" do
+ instances = [mock('instance')]
+ instances.expects(:to_yaml).returns "foo"
+ @yaml.render_multiple(instances)
+ end
- it "should refuse to decode" do
- lambda{ @yaml.decode("foo") }.should raise_error
- end
- end
+ it "should encode generated yaml on render" do
+ instances = [mock('instance')]
+ instances.stubs(:to_yaml).returns "foo"
- describe "when zlib is not installed" do
- it "use_zlib? should return false" do
- Puppet[:zlib] = true
- Puppet.features.expects(:zlib?).returns(false)
+ @yaml.expects(:encode).with("foo").returns "bar"
- @yaml.use_zlib?.should == false
- end
- end
+ @yaml.render(instances).should == "bar"
+ end
+ it "should intern by calling decode" do
+ text = "foo"
+ @yaml.expects(:decode).with("foo").returns "bar"
+ @yaml.intern(String, text).should == "bar"
end
- it "should include a marshal format" do
- Puppet::Network::FormatHandler.format(:marshal).should_not be_nil
+ it "should intern multiples by calling 'decode'" do
+ text = "foo"
+ @yaml.expects(:decode).with("foo").returns "bar"
+ @yaml.intern_multiple(String, text).should == "bar"
end
- describe "marshal" do
- before do
- @marshal = Puppet::Network::FormatHandler.format(:marshal)
- end
+ it "should decode by base64 decoding, uncompressing and Yaml loading" do
+ Base64.expects(:decode64).with("zorg").returns "foo"
+ Zlib::Inflate.expects(:inflate).with("foo").returns "baz"
+ YAML.expects(:load).with("baz").returns "bar"
+ @yaml.decode("zorg").should == "bar"
+ end
- it "should have its mime type set to text/marshal" do
- Puppet::Network::FormatHandler.format(:marshal).mime.should == "text/marshal"
- end
+ it "should encode by compressing and base64 encoding" do
+ Zlib::Deflate.expects(:deflate).with("foo", Zlib::BEST_COMPRESSION).returns "bar"
+ Base64.expects(:encode64).with("bar").returns "baz"
+ @yaml.encode("foo").should == "baz"
+ end
- it "should be supported on Strings" do
- @marshal.should be_supported(String)
- end
+ describe "when zlib is disabled" do
+ before do
+ Puppet[:zlib] = false
+ end
- it "should render by calling 'Marshal.dump' on the instance" do
- instance = mock 'instance'
- Marshal.expects(:dump).with(instance).returns "foo"
- @marshal.render(instance).should == "foo"
- end
+ it "use_zlib? should return false" do
+ @yaml.use_zlib?.should == false
+ end
- it "should render multiple instances by calling 'to_marshal' on the array" do
- instances = [mock('instance')]
+ it "should refuse to encode" do
+ lambda{ @yaml.encode("foo") }.should raise_error
+ end
- Marshal.expects(:dump).with(instances).returns "foo"
- @marshal.render_multiple(instances).should == "foo"
- end
+ it "should refuse to decode" do
+ lambda{ @yaml.decode("foo") }.should raise_error
+ end
+ end
- it "should intern by calling 'Marshal.load'" do
- text = "foo"
- Marshal.expects(:load).with("foo").returns "bar"
- @marshal.intern(String, text).should == "bar"
- end
+ describe "when zlib is not installed" do
+ it "use_zlib? should return false" do
+ Puppet[:zlib] = true
+ Puppet.features.expects(:zlib?).returns(false)
- it "should intern multiples by calling 'Marshal.load'" do
- text = "foo"
- Marshal.expects(:load).with("foo").returns "bar"
- @marshal.intern_multiple(String, text).should == "bar"
- end
+ @yaml.use_zlib?.should == false
+ end
end
- describe "plaintext" do
- before do
- @text = Puppet::Network::FormatHandler.format(:s)
- end
+ end
- it "should have its mimetype set to text/plain" do
- @text.mime.should == "text/plain"
- end
+ it "should include a marshal format" do
+ Puppet::Network::FormatHandler.format(:marshal).should_not be_nil
+ end
- it "should use 'txt' as its extension" do
- @text.extension.should == "txt"
- end
+ describe "marshal" do
+ before do
+ @marshal = Puppet::Network::FormatHandler.format(:marshal)
end
- describe "dot" do
- before do
- @dot = Puppet::Network::FormatHandler.format(:dot)
- end
+ it "should have its mime type set to text/marshal" do
+ Puppet::Network::FormatHandler.format(:marshal).mime.should == "text/marshal"
+ end
- it "should have its mimetype set to text/dot" do
- @dot.mime.should == "text/dot"
- end
+ it "should be supported on Strings" do
+ @marshal.should be_supported(String)
end
- describe Puppet::Network::FormatHandler.format(:raw) do
- before do
- @format = Puppet::Network::FormatHandler.format(:raw)
- end
+ it "should render by calling 'Marshal.dump' on the instance" do
+ instance = mock 'instance'
+ Marshal.expects(:dump).with(instance).returns "foo"
+ @marshal.render(instance).should == "foo"
+ end
- it "should exist" do
- @format.should_not be_nil
- end
+ it "should render multiple instances by calling 'to_marshal' on the array" do
+ instances = [mock('instance')]
- it "should have its mimetype set to application/x-raw" do
- @format.mime.should == "application/x-raw"
- end
+ Marshal.expects(:dump).with(instances).returns "foo"
+ @marshal.render_multiple(instances).should == "foo"
+ end
- it "should always be supported" do
- @format.should be_supported(String)
- end
+ it "should intern by calling 'Marshal.load'" do
+ text = "foo"
+ Marshal.expects(:load).with("foo").returns "bar"
+ @marshal.intern(String, text).should == "bar"
+ end
- it "should fail if its multiple_render method is used" do
- lambda { @format.render_multiple("foo") }.should raise_error(NotImplementedError)
- end
+ it "should intern multiples by calling 'Marshal.load'" do
+ text = "foo"
+ Marshal.expects(:load).with("foo").returns "bar"
+ @marshal.intern_multiple(String, text).should == "bar"
+ end
+ end
- it "should fail if its multiple_intern method is used" do
- lambda { @format.intern_multiple(String, "foo") }.should raise_error(NotImplementedError)
- end
+ describe "plaintext" do
+ before do
+ @text = Puppet::Network::FormatHandler.format(:s)
+ end
- it "should have a weight of 1" do
- @format.weight.should == 1
- end
+ it "should have its mimetype set to text/plain" do
+ @text.mime.should == "text/plain"
end
- it "should include a pson format" do
- Puppet::Network::FormatHandler.format(:pson).should_not be_nil
+ it "should use 'txt' as its extension" do
+ @text.extension.should == "txt"
end
+ end
- describe "pson" do
- confine "Missing 'pson' library" => Puppet.features.pson?
+ describe "dot" do
+ before do
+ @dot = Puppet::Network::FormatHandler.format(:dot)
+ end
- before do
- @pson = Puppet::Network::FormatHandler.format(:pson)
- end
+ it "should have its mimetype set to text/dot" do
+ @dot.mime.should == "text/dot"
+ end
+ end
- it "should have its mime type set to text/pson" do
- Puppet::Network::FormatHandler.format(:pson).mime.should == "text/pson"
- end
+ describe Puppet::Network::FormatHandler.format(:raw) do
+ before do
+ @format = Puppet::Network::FormatHandler.format(:raw)
+ end
- it "should require the :render_method" do
- Puppet::Network::FormatHandler.format(:pson).required_methods.should be_include(:render_method)
- end
+ it "should exist" do
+ @format.should_not be_nil
+ end
- it "should require the :intern_method" do
- Puppet::Network::FormatHandler.format(:pson).required_methods.should be_include(:intern_method)
- end
+ it "should have its mimetype set to application/x-raw" do
+ @format.mime.should == "application/x-raw"
+ end
- it "should have a weight of 10" do
- @pson.weight.should == 10
- end
+ it "should always be supported" do
+ @format.should be_supported(String)
+ end
- describe "when supported" do
- it "should render by calling 'to_pson' on the instance" do
- instance = PsonTest.new("foo")
- instance.expects(:to_pson).returns "foo"
- @pson.render(instance).should == "foo"
- end
-
- it "should render multiple instances by calling 'to_pson' on the array" do
- instances = [mock('instance')]
+ it "should fail if its multiple_render method is used" do
+ lambda { @format.render_multiple("foo") }.should raise_error(NotImplementedError)
+ end
- instances.expects(:to_pson).returns "foo"
+ it "should fail if its multiple_intern method is used" do
+ lambda { @format.intern_multiple(String, "foo") }.should raise_error(NotImplementedError)
+ end
- @pson.render_multiple(instances).should == "foo"
- end
+ it "should have a weight of 1" do
+ @format.weight.should == 1
+ end
+ end
+
+ it "should include a pson format" do
+ Puppet::Network::FormatHandler.format(:pson).should_not be_nil
+ end
+
+ describe "pson" do
+ confine "Missing 'pson' library" => Puppet.features.pson?
+
+ before do
+ @pson = Puppet::Network::FormatHandler.format(:pson)
+ end
- it "should intern by calling 'PSON.parse' on the text and then using from_pson to convert the data into an instance" do
- text = "foo"
- PSON.expects(:parse).with("foo").returns("type" => "PsonTest", "data" => "foo")
- PsonTest.expects(:from_pson).with("foo").returns "parsed_pson"
- @pson.intern(PsonTest, text).should == "parsed_pson"
- end
+ it "should have its mime type set to text/pson" do
+ Puppet::Network::FormatHandler.format(:pson).mime.should == "text/pson"
+ end
- it "should not render twice if 'PSON.parse' creates the appropriate instance" do
- text = "foo"
- instance = PsonTest.new("foo")
- PSON.expects(:parse).with("foo").returns(instance)
- PsonTest.expects(:from_pson).never
- @pson.intern(PsonTest, text).should equal(instance)
- end
+ it "should require the :render_method" do
+ Puppet::Network::FormatHandler.format(:pson).required_methods.should be_include(:render_method)
+ end
- it "should intern by calling 'PSON.parse' on the text and then using from_pson to convert the actual into an instance if the pson has no class/data separation" do
- text = "foo"
- PSON.expects(:parse).with("foo").returns("foo")
- PsonTest.expects(:from_pson).with("foo").returns "parsed_pson"
- @pson.intern(PsonTest, text).should == "parsed_pson"
- end
+ it "should require the :intern_method" do
+ Puppet::Network::FormatHandler.format(:pson).required_methods.should be_include(:intern_method)
+ end
+
+ it "should have a weight of 10" do
+ @pson.weight.should == 10
+ end
- it "should intern multiples by parsing the text and using 'class.intern' on each resulting data structure" do
- text = "foo"
- PSON.expects(:parse).with("foo").returns ["bar", "baz"]
- PsonTest.expects(:from_pson).with("bar").returns "BAR"
- PsonTest.expects(:from_pson).with("baz").returns "BAZ"
- @pson.intern_multiple(PsonTest, text).should == %w{BAR BAZ}
- end
- end
+ describe "when supported" do
+ it "should render by calling 'to_pson' on the instance" do
+ instance = PsonTest.new("foo")
+ instance.expects(:to_pson).returns "foo"
+ @pson.render(instance).should == "foo"
+ end
+
+ it "should render multiple instances by calling 'to_pson' on the array" do
+ instances = [mock('instance')]
+
+ instances.expects(:to_pson).returns "foo"
+
+ @pson.render_multiple(instances).should == "foo"
+ end
+
+ it "should intern by calling 'PSON.parse' on the text and then using from_pson to convert the data into an instance" do
+ text = "foo"
+ PSON.expects(:parse).with("foo").returns("type" => "PsonTest", "data" => "foo")
+ PsonTest.expects(:from_pson).with("foo").returns "parsed_pson"
+ @pson.intern(PsonTest, text).should == "parsed_pson"
+ end
+
+ it "should not render twice if 'PSON.parse' creates the appropriate instance" do
+ text = "foo"
+ instance = PsonTest.new("foo")
+ PSON.expects(:parse).with("foo").returns(instance)
+ PsonTest.expects(:from_pson).never
+ @pson.intern(PsonTest, text).should equal(instance)
+ end
+
+ it "should intern by calling 'PSON.parse' on the text and then using from_pson to convert the actual into an instance if the pson has no class/data separation" do
+ text = "foo"
+ PSON.expects(:parse).with("foo").returns("foo")
+ PsonTest.expects(:from_pson).with("foo").returns "parsed_pson"
+ @pson.intern(PsonTest, text).should == "parsed_pson"
+ end
+
+ it "should intern multiples by parsing the text and using 'class.intern' on each resulting data structure" do
+ text = "foo"
+ PSON.expects(:parse).with("foo").returns ["bar", "baz"]
+ PsonTest.expects(:from_pson).with("bar").returns "BAR"
+ PsonTest.expects(:from_pson).with("baz").returns "BAZ"
+ @pson.intern_multiple(PsonTest, text).should == %w{BAR BAZ}
+ end
end
+ end
end
diff --git a/spec/unit/network/handler/fileserver_spec.rb b/spec/unit/network/handler/fileserver_spec.rb
index 371e75d..40d1e57 100644
--- a/spec/unit/network/handler/fileserver_spec.rb
+++ b/spec/unit/network/handler/fileserver_spec.rb
@@ -6,167 +6,167 @@ require 'puppet/network/handler/fileserver'
describe Puppet::Network::Handler::FileServer do
- require 'tmpdir'
-
- def create_file(filename)
- File.open(filename, "w") { |f| f.puts filename}
- end
-
- def create_nested_file
- dirname = File.join(@basedir, "nested_dir")
- Dir.mkdir(dirname)
- file = File.join(dirname, "nested_dir_file")
- create_file(file)
- end
-
- before do
- @basedir = File.join(Dir.tmpdir, "test_network_handler")
- Dir.mkdir(@basedir)
- @file = File.join(@basedir, "aFile")
- @link = File.join(@basedir, "aLink")
- create_file(@file)
- @mount = Puppet::Network::Handler::FileServer::Mount.new("some_path", @basedir)
- end
-
- it "should list a single directory" do
- @mount.list("/", false, false).should == [["/", "directory"]]
- end
-
- it "should list a file within a directory when given the file path" do
- @mount.list("/aFile", false, "false").should == [["/", "file"]]
+ require 'tmpdir'
+
+ def create_file(filename)
+ File.open(filename, "w") { |f| f.puts filename}
+ end
+
+ def create_nested_file
+ dirname = File.join(@basedir, "nested_dir")
+ Dir.mkdir(dirname)
+ file = File.join(dirname, "nested_dir_file")
+ create_file(file)
+ end
+
+ before do
+ @basedir = File.join(Dir.tmpdir, "test_network_handler")
+ Dir.mkdir(@basedir)
+ @file = File.join(@basedir, "aFile")
+ @link = File.join(@basedir, "aLink")
+ create_file(@file)
+ @mount = Puppet::Network::Handler::FileServer::Mount.new("some_path", @basedir)
+ end
+
+ it "should list a single directory" do
+ @mount.list("/", false, false).should == [["/", "directory"]]
+ end
+
+ it "should list a file within a directory when given the file path" do
+ @mount.list("/aFile", false, "false").should == [["/", "file"]]
+ end
+
+ it "should list a file within a directory when given the file path with recursion" do
+ @mount.list("/aFile", true, "false").should == [["/", "file"]]
+ end
+
+ it "should return nil for a non-existent path" do
+ @mount.list("/no_such_file", false, false).should be(nil)
+ end
+
+ it "should list a symbolic link as a file when given the link path" do
+ File.symlink(@file, @link)
+ @mount.list("/aLink", false, false).should == [["/", "file"]]
+ end
+
+ it "should return nil for a dangling symbolic link when given the link path" do
+ File.symlink("/some/where", @link)
+ @mount.list("/aLink", false, false).should be(nil)
+ end
+
+ it "should list directory contents of a flat directory structure when asked to recurse" do
+ list = @mount.list("/", true, false)
+ list.should include(["/aFile", "file"])
+ list.should include(["/", "directory"])
+ list.should have(2).items
+ end
+
+ it "should list the contents of a nested directory" do
+ create_nested_file
+ list = @mount.list("/", true, false)
+ list.sort.should == [ ["/aFile", "file"], ["/", "directory"] , ["/nested_dir", "directory"], ["/nested_dir/nested_dir_file", "file"]].sort
+ end
+
+ it "should list the contents of a directory ignoring files that match" do
+ create_nested_file
+ list = @mount.list("/", true, "*File")
+ list.sort.should == [ ["/", "directory"] , ["/nested_dir", "directory"], ["/nested_dir/nested_dir_file", "file"]].sort
+ end
+
+ it "should list the contents of a directory ignoring directories that match" do
+ create_nested_file
+ list = @mount.list("/", true, "*nested_dir")
+ list.sort.should == [ ["/aFile", "file"], ["/", "directory"] ].sort
+ end
+
+ it "should list the contents of a directory ignoring all ignore patterns that match" do
+ create_nested_file
+ list = @mount.list("/", true, ["*File" , "*nested_dir"])
+ list.should == [ ["/", "directory"] ]
+ end
+
+ it "should list the directory when recursing to a depth of zero" do
+ create_nested_file
+ list = @mount.list("/", 0, false)
+ list.should == [["/", "directory"]]
+ end
+
+ it "should list the base directory and files and nested directory to a depth of one" do
+ create_nested_file
+ list = @mount.list("/", 1, false)
+ list.sort.should == [ ["/aFile", "file"], ["/nested_dir", "directory"], ["/", "directory"] ].sort
+ end
+
+ it "should list the base directory and files and nested directory to a depth of two" do
+ create_nested_file
+ list = @mount.list("/", 2, false)
+ list.sort.should == [ ["/aFile", "file"], ["/", "directory"] , ["/nested_dir", "directory"], ["/nested_dir/nested_dir_file", "file"]].sort
+ end
+
+ it "should list the base directory and files and nested directory to a depth greater than the directory structure" do
+ create_nested_file
+ list = @mount.list("/", 42, false)
+ list.sort.should == [ ["/aFile", "file"], ["/", "directory"] , ["/nested_dir", "directory"], ["/nested_dir/nested_dir_file", "file"]].sort
+ end
+
+ it "should list a valid symbolic link as a file when recursing base dir" do
+ File.symlink(@file, @link)
+ list = @mount.list("/", true, false)
+ list.sort.should == [ ["/", "directory"], ["/aFile", "file"], ["/aLink", "file"] ].sort
+ end
+
+ it "should not error when a dangling symlink is present" do
+ File.symlink("/some/where", @link)
+ lambda { @mount.list("/", true, false) }.should_not raise_error
+ end
+
+ it "should return the directory contents of valid entries when a dangling symlink is present" do
+ File.symlink("/some/where", @link)
+ list = @mount.list("/", true, false)
+ list.sort.should == [ ["/aFile", "file"], ["/", "directory"] ].sort
+ end
+
+ describe Puppet::Network::Handler::FileServer::PluginMount do
+ PLUGINS = Puppet::Network::Handler::FileServer::PLUGINS
+
+ # create a module plugin hierarchy
+ def create_plugin(mod, plugin)
+ dirname = File.join(@basedir, mod)
+ Dir.mkdir(dirname)
+ plugins = File.join(dirname, PLUGINS)
+ Dir.mkdir(plugins)
+ facter = File.join(plugins, plugin)
+ Dir.mkdir(facter)
+ create_file(File.join(facter,"fact.rb"))
+ end
+
+ before :each do
+ @modules = ["one","two"]
+ @modules.each { |m| create_plugin(m, "facter") }
+
+ Puppet::Node::Environment.new.stubs(:modulepath).returns @basedir
+
+ @mount = Puppet::Network::Handler::FileServer::PluginMount.new(PLUGINS)
+ @mount.allow("*")
end
it "should list a file within a directory when given the file path with recursion" do
- @mount.list("/aFile", true, "false").should == [["/", "file"]]
+ @mount.list("facter/fact.rb", true, "false").should == [["/", "file"], ["/", "file"]]
end
- it "should return nil for a non-existent path" do
- @mount.list("/no_such_file", false, false).should be(nil)
+ it "should return a merged view of all plugins for all modules" do
+ list = @mount.list("facter",true,false)
+ list.should == [["/", "directory"], ["/fact.rb", "file"], ["/", "directory"], ["/fact.rb", "file"]]
end
- it "should list a symbolic link as a file when given the link path" do
- File.symlink(@file, @link)
- @mount.list("/aLink", false, false).should == [["/", "file"]]
+ it "should not fail for inexistant plugins type" do
+ lambda { @mount.list("puppet/parser",true,false) }.should_not raise_error
end
- it "should return nil for a dangling symbolic link when given the link path" do
- File.symlink("/some/where", @link)
- @mount.list("/aLink", false, false).should be(nil)
- end
-
- it "should list directory contents of a flat directory structure when asked to recurse" do
- list = @mount.list("/", true, false)
- list.should include(["/aFile", "file"])
- list.should include(["/", "directory"])
- list.should have(2).items
- end
+ end
- it "should list the contents of a nested directory" do
- create_nested_file
- list = @mount.list("/", true, false)
- list.sort.should == [ ["/aFile", "file"], ["/", "directory"] , ["/nested_dir", "directory"], ["/nested_dir/nested_dir_file", "file"]].sort
- end
-
- it "should list the contents of a directory ignoring files that match" do
- create_nested_file
- list = @mount.list("/", true, "*File")
- list.sort.should == [ ["/", "directory"] , ["/nested_dir", "directory"], ["/nested_dir/nested_dir_file", "file"]].sort
- end
-
- it "should list the contents of a directory ignoring directories that match" do
- create_nested_file
- list = @mount.list("/", true, "*nested_dir")
- list.sort.should == [ ["/aFile", "file"], ["/", "directory"] ].sort
- end
-
- it "should list the contents of a directory ignoring all ignore patterns that match" do
- create_nested_file
- list = @mount.list("/", true, ["*File" , "*nested_dir"])
- list.should == [ ["/", "directory"] ]
- end
-
- it "should list the directory when recursing to a depth of zero" do
- create_nested_file
- list = @mount.list("/", 0, false)
- list.should == [["/", "directory"]]
- end
-
- it "should list the base directory and files and nested directory to a depth of one" do
- create_nested_file
- list = @mount.list("/", 1, false)
- list.sort.should == [ ["/aFile", "file"], ["/nested_dir", "directory"], ["/", "directory"] ].sort
- end
-
- it "should list the base directory and files and nested directory to a depth of two" do
- create_nested_file
- list = @mount.list("/", 2, false)
- list.sort.should == [ ["/aFile", "file"], ["/", "directory"] , ["/nested_dir", "directory"], ["/nested_dir/nested_dir_file", "file"]].sort
- end
-
- it "should list the base directory and files and nested directory to a depth greater than the directory structure" do
- create_nested_file
- list = @mount.list("/", 42, false)
- list.sort.should == [ ["/aFile", "file"], ["/", "directory"] , ["/nested_dir", "directory"], ["/nested_dir/nested_dir_file", "file"]].sort
- end
-
- it "should list a valid symbolic link as a file when recursing base dir" do
- File.symlink(@file, @link)
- list = @mount.list("/", true, false)
- list.sort.should == [ ["/", "directory"], ["/aFile", "file"], ["/aLink", "file"] ].sort
- end
-
- it "should not error when a dangling symlink is present" do
- File.symlink("/some/where", @link)
- lambda { @mount.list("/", true, false) }.should_not raise_error
- end
-
- it "should return the directory contents of valid entries when a dangling symlink is present" do
- File.symlink("/some/where", @link)
- list = @mount.list("/", true, false)
- list.sort.should == [ ["/aFile", "file"], ["/", "directory"] ].sort
- end
-
- describe Puppet::Network::Handler::FileServer::PluginMount do
- PLUGINS = Puppet::Network::Handler::FileServer::PLUGINS
-
- # create a module plugin hierarchy
- def create_plugin(mod, plugin)
- dirname = File.join(@basedir, mod)
- Dir.mkdir(dirname)
- plugins = File.join(dirname, PLUGINS)
- Dir.mkdir(plugins)
- facter = File.join(plugins, plugin)
- Dir.mkdir(facter)
- create_file(File.join(facter,"fact.rb"))
- end
-
- before :each do
- @modules = ["one","two"]
- @modules.each { |m| create_plugin(m, "facter") }
-
- Puppet::Node::Environment.new.stubs(:modulepath).returns @basedir
-
- @mount = Puppet::Network::Handler::FileServer::PluginMount.new(PLUGINS)
- @mount.allow("*")
- end
-
- it "should list a file within a directory when given the file path with recursion" do
- @mount.list("facter/fact.rb", true, "false").should == [["/", "file"], ["/", "file"]]
- end
-
- it "should return a merged view of all plugins for all modules" do
- list = @mount.list("facter",true,false)
- list.should == [["/", "directory"], ["/fact.rb", "file"], ["/", "directory"], ["/fact.rb", "file"]]
- end
-
- it "should not fail for inexistant plugins type" do
- lambda { @mount.list("puppet/parser",true,false) }.should_not raise_error
- end
-
- end
-
- after do
- FileUtils.rm_rf(@basedir)
- end
+ after do
+ FileUtils.rm_rf(@basedir)
+ end
end
diff --git a/spec/unit/network/http/api/v1_spec.rb b/spec/unit/network/http/api/v1_spec.rb
index fc284de..c593242 100644
--- a/spec/unit/network/http/api/v1_spec.rb
+++ b/spec/unit/network/http/api/v1_spec.rb
@@ -5,118 +5,118 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
require 'puppet/network/http/api/v1'
class V1RestApiTester
- include Puppet::Network::HTTP::API::V1
+ include Puppet::Network::HTTP::API::V1
end
describe Puppet::Network::HTTP::API::V1 do
+ before do
+ @tester = V1RestApiTester.new
+ end
+
+ it "should be able to convert a URI into a request" do
+ @tester.should respond_to(:uri2indirection)
+ end
+
+ it "should be able to convert a request into a URI" do
+ @tester.should respond_to(:indirection2uri)
+ end
+
+ describe "when converting a URI into a request" do
before do
- @tester = V1RestApiTester.new
+ @tester.stubs(:handler).returns "foo"
end
- it "should be able to convert a URI into a request" do
- @tester.should respond_to(:uri2indirection)
+ it "should require the http method, the URI, and the query parameters" do
+ # Not a terribly useful test, but an important statement for the spec
+ lambda { @tester.uri2indirection("/foo") }.should raise_error(ArgumentError)
end
- it "should be able to convert a request into a URI" do
- @tester.should respond_to(:indirection2uri)
+ it "should use the first field of the URI as the environment" do
+ @tester.uri2indirection("GET", "/env/foo/bar", {}).environment.should == Puppet::Node::Environment.new("env")
end
- describe "when converting a URI into a request" do
- before do
- @tester.stubs(:handler).returns "foo"
- end
-
- it "should require the http method, the URI, and the query parameters" do
- # Not a terribly useful test, but an important statement for the spec
- lambda { @tester.uri2indirection("/foo") }.should raise_error(ArgumentError)
- end
-
- it "should use the first field of the URI as the environment" do
- @tester.uri2indirection("GET", "/env/foo/bar", {}).environment.should == Puppet::Node::Environment.new("env")
- end
-
- it "should fail if the environment is not alphanumeric" do
- lambda { @tester.uri2indirection("GET", "/env ness/foo/bar", {}) }.should raise_error(ArgumentError)
- end
+ it "should fail if the environment is not alphanumeric" do
+ lambda { @tester.uri2indirection("GET", "/env ness/foo/bar", {}) }.should raise_error(ArgumentError)
+ end
- it "should use the environment from the URI even if one is specified in the parameters" do
- @tester.uri2indirection("GET", "/env/foo/bar", {:environment => "otherenv"}).environment.should == Puppet::Node::Environment.new("env")
- end
+ it "should use the environment from the URI even if one is specified in the parameters" do
+ @tester.uri2indirection("GET", "/env/foo/bar", {:environment => "otherenv"}).environment.should == Puppet::Node::Environment.new("env")
+ end
- it "should use the second field of the URI as the indirection name" do
- @tester.uri2indirection("GET", "/env/foo/bar", {}).indirection_name.should == :foo
- end
+ it "should use the second field of the URI as the indirection name" do
+ @tester.uri2indirection("GET", "/env/foo/bar", {}).indirection_name.should == :foo
+ end
- it "should fail if the indirection name is not alphanumeric" do
- lambda { @tester.uri2indirection("GET", "/env/foo ness/bar", {}) }.should raise_error(ArgumentError)
- end
+ it "should fail if the indirection name is not alphanumeric" do
+ lambda { @tester.uri2indirection("GET", "/env/foo ness/bar", {}) }.should raise_error(ArgumentError)
+ end
- it "should use the remainder of the URI as the indirection key" do
- @tester.uri2indirection("GET", "/env/foo/bar", {}).key.should == "bar"
- end
+ it "should use the remainder of the URI as the indirection key" do
+ @tester.uri2indirection("GET", "/env/foo/bar", {}).key.should == "bar"
+ end
- it "should support the indirection key being a /-separated file path" do
- @tester.uri2indirection("GET", "/env/foo/bee/baz/bomb", {}).key.should == "bee/baz/bomb"
- end
+ it "should support the indirection key being a /-separated file path" do
+ @tester.uri2indirection("GET", "/env/foo/bee/baz/bomb", {}).key.should == "bee/baz/bomb"
+ end
- it "should fail if no indirection key is specified" do
- lambda { @tester.uri2indirection("GET", "/env/foo/", {}) }.should raise_error(ArgumentError)
- lambda { @tester.uri2indirection("GET", "/env/foo", {}) }.should raise_error(ArgumentError)
- end
+ it "should fail if no indirection key is specified" do
+ lambda { @tester.uri2indirection("GET", "/env/foo/", {}) }.should raise_error(ArgumentError)
+ lambda { @tester.uri2indirection("GET", "/env/foo", {}) }.should raise_error(ArgumentError)
+ end
- it "should choose 'find' as the indirection method if the http method is a GET and the indirection name is singular" do
- @tester.uri2indirection("GET", "/env/foo/bar", {}).method.should == :find
- end
+ it "should choose 'find' as the indirection method if the http method is a GET and the indirection name is singular" do
+ @tester.uri2indirection("GET", "/env/foo/bar", {}).method.should == :find
+ end
- it "should choose 'search' as the indirection method if the http method is a GET and the indirection name is plural" do
- @tester.uri2indirection("GET", "/env/foos/bar", {}).method.should == :search
- end
+ it "should choose 'search' as the indirection method if the http method is a GET and the indirection name is plural" do
+ @tester.uri2indirection("GET", "/env/foos/bar", {}).method.should == :search
+ end
- it "should choose 'delete' as the indirection method if the http method is a DELETE and the indirection name is singular" do
- @tester.uri2indirection("DELETE", "/env/foo/bar", {}).method.should == :destroy
- end
+ it "should choose 'delete' as the indirection method if the http method is a DELETE and the indirection name is singular" do
+ @tester.uri2indirection("DELETE", "/env/foo/bar", {}).method.should == :destroy
+ end
- it "should choose 'save' as the indirection method if the http method is a PUT and the indirection name is singular" do
- @tester.uri2indirection("PUT", "/env/foo/bar", {}).method.should == :save
- end
+ it "should choose 'save' as the indirection method if the http method is a PUT and the indirection name is singular" do
+ @tester.uri2indirection("PUT", "/env/foo/bar", {}).method.should == :save
+ end
- it "should fail if an indirection method cannot be picked" do
- lambda { @tester.uri2indirection("UPDATE", "/env/foo/bar", {}) }.should raise_error(ArgumentError)
- end
+ it "should fail if an indirection method cannot be picked" do
+ lambda { @tester.uri2indirection("UPDATE", "/env/foo/bar", {}) }.should raise_error(ArgumentError)
+ end
- it "should URI unescape the indirection key" do
- escaped = URI.escape("foo bar")
- @tester.uri2indirection("GET", "/env/foo/#{escaped}", {}).key.should == "foo bar"
- end
+ it "should URI unescape the indirection key" do
+ escaped = URI.escape("foo bar")
+ @tester.uri2indirection("GET", "/env/foo/#{escaped}", {}).key.should == "foo bar"
end
+ end
- describe "when converting a request into a URI" do
- before do
- @request = Puppet::Indirector::Request.new(:foo, :find, "with spaces", :foo => :bar, :environment => "myenv")
- end
+ describe "when converting a request into a URI" do
+ before do
+ @request = Puppet::Indirector::Request.new(:foo, :find, "with spaces", :foo => :bar, :environment => "myenv")
+ end
- it "should use the environment as the first field of the URI" do
- @tester.indirection2uri(@request).split("/")[1].should == "myenv"
- end
+ it "should use the environment as the first field of the URI" do
+ @tester.indirection2uri(@request).split("/")[1].should == "myenv"
+ end
- it "should use the indirection as the second field of the URI" do
- @tester.indirection2uri(@request).split("/")[2].should == "foo"
- end
+ it "should use the indirection as the second field of the URI" do
+ @tester.indirection2uri(@request).split("/")[2].should == "foo"
+ end
- it "should pluralize the indirection name if the method is 'search'" do
- @request.stubs(:method).returns :search
- @tester.indirection2uri(@request).split("/")[2].should == "foos"
- end
+ it "should pluralize the indirection name if the method is 'search'" do
+ @request.stubs(:method).returns :search
+ @tester.indirection2uri(@request).split("/")[2].should == "foos"
+ end
- it "should use the escaped key as the remainder of the URI" do
- escaped = URI.escape("with spaces")
- @tester.indirection2uri(@request).split("/")[3].sub(/\?.+/, '').should == escaped
- end
+ it "should use the escaped key as the remainder of the URI" do
+ escaped = URI.escape("with spaces")
+ @tester.indirection2uri(@request).split("/")[3].sub(/\?.+/, '').should == escaped
+ end
- it "should add the query string to the URI" do
- @request.expects(:query_string).returns "?query"
- @tester.indirection2uri(@request).should =~ /\?query$/
- end
+ it "should add the query string to the URI" do
+ @request.expects(:query_string).returns "?query"
+ @tester.indirection2uri(@request).should =~ /\?query$/
end
+ end
end
diff --git a/spec/unit/network/http/compression_spec.rb b/spec/unit/network/http/compression_spec.rb
index ace1f35..b46941f 100644
--- a/spec/unit/network/http/compression_spec.rb
+++ b/spec/unit/network/http/compression_spec.rb
@@ -4,196 +4,196 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe "http compression" do
- describe "when zlib is not available" do
- before(:each) do
- Puppet.features.stubs(:zlib?).returns false
+ describe "when zlib is not available" do
+ before(:each) do
+ Puppet.features.stubs(:zlib?).returns false
- require 'puppet/network/http/compression'
- class HttpUncompressor
- include Puppet::Network::HTTP::Compression::None
- end
+ require 'puppet/network/http/compression'
+ class HttpUncompressor
+ include Puppet::Network::HTTP::Compression::None
+ end
- @uncompressor = HttpUncompressor.new
- end
+ @uncompressor = HttpUncompressor.new
+ end
- it "should have a module function that returns the None underlying module" do
- Puppet::Network::HTTP::Compression.module.should == Puppet::Network::HTTP::Compression::None
- end
+ it "should have a module function that returns the None underlying module" do
+ Puppet::Network::HTTP::Compression.module.should == Puppet::Network::HTTP::Compression::None
+ end
- it "should not add any Accept-Encoding header" do
- @uncompressor.add_accept_encoding({}).should == {}
- end
+ it "should not add any Accept-Encoding header" do
+ @uncompressor.add_accept_encoding({}).should == {}
+ end
- it "should not tamper the body" do
- response = stub 'response', :body => "data"
- @uncompressor.uncompress_body(response).should == "data"
- end
+ it "should not tamper the body" do
+ response = stub 'response', :body => "data"
+ @uncompressor.uncompress_body(response).should == "data"
+ end
- it "should yield an identity uncompressor" do
- response = stub 'response'
- @uncompressor.uncompress(response) { |u|
- u.should be_instance_of(Puppet::Network::HTTP::Compression::IdentityAdapter)
- }
- end
+ it "should yield an identity uncompressor" do
+ response = stub 'response'
+ @uncompressor.uncompress(response) { |u|
+ u.should be_instance_of(Puppet::Network::HTTP::Compression::IdentityAdapter)
+ }
end
+ end
- describe "when zlib is available" do
- confine "Zlib is missing" => Puppet.features.zlib?
+ describe "when zlib is available" do
+ confine "Zlib is missing" => Puppet.features.zlib?
- before(:each) do
- Puppet.features.stubs(:zlib?).returns true
+ before(:each) do
+ Puppet.features.stubs(:zlib?).returns true
- require 'puppet/network/http/compression'
- class HttpUncompressor
- include Puppet::Network::HTTP::Compression::Active
- end
+ require 'puppet/network/http/compression'
+ class HttpUncompressor
+ include Puppet::Network::HTTP::Compression::Active
+ end
- @uncompressor = HttpUncompressor.new
- end
+ @uncompressor = HttpUncompressor.new
+ end
- it "should have a module function that returns the Active underlying module" do
- Puppet::Network::HTTP::Compression.module.should == Puppet::Network::HTTP::Compression::Active
- end
+ it "should have a module function that returns the Active underlying module" do
+ Puppet::Network::HTTP::Compression.module.should == Puppet::Network::HTTP::Compression::Active
+ end
- it "should add an Accept-Encoding header when http compression is available" do
- Puppet.settings.expects(:[]).with(:http_compression).returns(true)
- headers = @uncompressor.add_accept_encoding({})
- headers.should have_key('accept-encoding')
- headers['accept-encoding'].should =~ /gzip/
- headers['accept-encoding'].should =~ /deflate/
- headers['accept-encoding'].should =~ /identity/
- end
+ it "should add an Accept-Encoding header when http compression is available" do
+ Puppet.settings.expects(:[]).with(:http_compression).returns(true)
+ headers = @uncompressor.add_accept_encoding({})
+ headers.should have_key('accept-encoding')
+ headers['accept-encoding'].should =~ /gzip/
+ headers['accept-encoding'].should =~ /deflate/
+ headers['accept-encoding'].should =~ /identity/
+ end
- it "should not add Accept-Encoding header if http compression is not available" do
- Puppet.settings.stubs(:[]).with(:http_compression).returns(false)
- @uncompressor.add_accept_encoding({}).should == {}
- end
+ it "should not add Accept-Encoding header if http compression is not available" do
+ Puppet.settings.stubs(:[]).with(:http_compression).returns(false)
+ @uncompressor.add_accept_encoding({}).should == {}
+ end
- describe "when uncompressing response body" do
- before do
- @response = stub 'response'
- @response.stubs(:[]).with('content-encoding')
- @response.stubs(:body).returns("mydata")
- end
+ describe "when uncompressing response body" do
+ before do
+ @response = stub 'response'
+ @response.stubs(:[]).with('content-encoding')
+ @response.stubs(:body).returns("mydata")
+ end
- it "should return untransformed response body with no content-encoding" do
- @uncompressor.uncompress_body(@response).should == "mydata"
- end
+ it "should return untransformed response body with no content-encoding" do
+ @uncompressor.uncompress_body(@response).should == "mydata"
+ end
- it "should return untransformed response body with 'identity' content-encoding" do
- @response.stubs(:[]).with('content-encoding').returns('identity')
- @uncompressor.uncompress_body(@response).should == "mydata"
- end
+ it "should return untransformed response body with 'identity' content-encoding" do
+ @response.stubs(:[]).with('content-encoding').returns('identity')
+ @uncompressor.uncompress_body(@response).should == "mydata"
+ end
- it "should use a Zlib inflater with 'deflate' content-encoding" do
- @response.stubs(:[]).with('content-encoding').returns('deflate')
+ it "should use a Zlib inflater with 'deflate' content-encoding" do
+ @response.stubs(:[]).with('content-encoding').returns('deflate')
- inflater = stub 'inflater'
- Zlib::Inflate.expects(:new).returns(inflater)
- inflater.expects(:inflate).with("mydata").returns "uncompresseddata"
+ inflater = stub 'inflater'
+ Zlib::Inflate.expects(:new).returns(inflater)
+ inflater.expects(:inflate).with("mydata").returns "uncompresseddata"
- @uncompressor.uncompress_body(@response).should == "uncompresseddata"
- end
+ @uncompressor.uncompress_body(@response).should == "uncompresseddata"
+ end
- it "should use a GzipReader with 'gzip' content-encoding" do
- @response.stubs(:[]).with('content-encoding').returns('gzip')
+ it "should use a GzipReader with 'gzip' content-encoding" do
+ @response.stubs(:[]).with('content-encoding').returns('gzip')
- io = stub 'io'
- StringIO.expects(:new).with("mydata").returns io
+ io = stub 'io'
+ StringIO.expects(:new).with("mydata").returns io
- reader = stub 'gzip reader'
- Zlib::GzipReader.expects(:new).with(io).returns(reader)
- reader.expects(:read).returns "uncompresseddata"
+ reader = stub 'gzip reader'
+ Zlib::GzipReader.expects(:new).with(io).returns(reader)
+ reader.expects(:read).returns "uncompresseddata"
- @uncompressor.uncompress_body(@response).should == "uncompresseddata"
- end
- end
+ @uncompressor.uncompress_body(@response).should == "uncompresseddata"
+ end
+ end
- describe "when uncompressing by chunk" do
- before do
- @response = stub 'response'
- @response.stubs(:[]).with('content-encoding')
-
- @inflater = stub_everything 'inflater'
- Zlib::Inflate.stubs(:new).returns(@inflater)
- end
-
- it "should yield an identity uncompressor with no content-encoding" do
- @uncompressor.uncompress(@response) { |u|
- u.should be_instance_of(Puppet::Network::HTTP::Compression::IdentityAdapter)
- }
- end
-
- it "should yield an identity uncompressor with 'identity' content-encoding" do
- @response.stubs(:[]).with('content-encoding').returns 'identity'
- @uncompressor.uncompress(@response) { |u|
- u.should be_instance_of(Puppet::Network::HTTP::Compression::IdentityAdapter)
- }
- end
-
- %w{gzip deflate}.each do |c|
- it "should yield a Zlib uncompressor with '#{c}' content-encoding" do
- @response.stubs(:[]).with('content-encoding').returns c
- @uncompressor.uncompress(@response) { |u|
- u.should be_instance_of(Puppet::Network::HTTP::Compression::Active::ZlibAdapter)
- }
- end
- end
-
- it "should close the underlying adapter" do
- adapter = stub_everything 'adapter'
- Puppet::Network::HTTP::Compression::IdentityAdapter.expects(:new).returns(adapter)
-
- adapter.expects(:close)
- @uncompressor.uncompress(@response) { |u| }
- end
+ describe "when uncompressing by chunk" do
+ before do
+ @response = stub 'response'
+ @response.stubs(:[]).with('content-encoding')
+
+ @inflater = stub_everything 'inflater'
+ Zlib::Inflate.stubs(:new).returns(@inflater)
+ end
+
+ it "should yield an identity uncompressor with no content-encoding" do
+ @uncompressor.uncompress(@response) { |u|
+ u.should be_instance_of(Puppet::Network::HTTP::Compression::IdentityAdapter)
+ }
+ end
+
+ it "should yield an identity uncompressor with 'identity' content-encoding" do
+ @response.stubs(:[]).with('content-encoding').returns 'identity'
+ @uncompressor.uncompress(@response) { |u|
+ u.should be_instance_of(Puppet::Network::HTTP::Compression::IdentityAdapter)
+ }
+ end
+
+ %w{gzip deflate}.each do |c|
+ it "should yield a Zlib uncompressor with '#{c}' content-encoding" do
+ @response.stubs(:[]).with('content-encoding').returns c
+ @uncompressor.uncompress(@response) { |u|
+ u.should be_instance_of(Puppet::Network::HTTP::Compression::Active::ZlibAdapter)
+ }
end
+ end
- describe "zlib adapter" do
- before do
- @inflater = stub_everything 'inflater'
- Zlib::Inflate.stubs(:new).returns(@inflater)
- @adapter = Puppet::Network::HTTP::Compression::Active::ZlibAdapter.new
- end
-
- it "should initialize the underlying inflater with gzip/zlib header parsing" do
- Zlib::Inflate.expects(:new).with(15+32)
- Puppet::Network::HTTP::Compression::Active::ZlibAdapter.new
- end
-
- it "should inflate the given chunk" do
- @inflater.expects(:inflate).with("chunk")
- @adapter.uncompress("chunk")
- end
-
- it "should return the inflated chunk" do
- @inflater.stubs(:inflate).with("chunk").returns("uncompressed")
- @adapter.uncompress("chunk").should == "uncompressed"
- end
-
- it "should try a 'regular' inflater on Zlib::DataError" do
- @inflater.expects(:inflate).raises(Zlib::DataError.new("not a zlib stream"))
- inflater = stub_everything 'inflater2'
- inflater.expects(:inflate).with("chunk").returns("uncompressed")
- Zlib::Inflate.expects(:new).with.returns(inflater)
- @adapter.uncompress("chunk")
- end
-
- it "should raise the error the second time" do
- @inflater.expects(:inflate).raises(Zlib::DataError.new("not a zlib stream"))
- Zlib::Inflate.expects(:new).with.returns(@inflater)
- lambda { @adapter.uncompress("chunk") }.should raise_error
- end
-
- it "should finish the stream on close" do
- @inflater.expects(:finish)
- @adapter.close
- end
-
- it "should close the stream on close" do
- @inflater.expects(:close)
- @adapter.close
- end
- end
+ it "should close the underlying adapter" do
+ adapter = stub_everything 'adapter'
+ Puppet::Network::HTTP::Compression::IdentityAdapter.expects(:new).returns(adapter)
+
+ adapter.expects(:close)
+ @uncompressor.uncompress(@response) { |u| }
+ end
+ end
+
+ describe "zlib adapter" do
+ before do
+ @inflater = stub_everything 'inflater'
+ Zlib::Inflate.stubs(:new).returns(@inflater)
+ @adapter = Puppet::Network::HTTP::Compression::Active::ZlibAdapter.new
+ end
+
+ it "should initialize the underlying inflater with gzip/zlib header parsing" do
+ Zlib::Inflate.expects(:new).with(15+32)
+ Puppet::Network::HTTP::Compression::Active::ZlibAdapter.new
+ end
+
+ it "should inflate the given chunk" do
+ @inflater.expects(:inflate).with("chunk")
+ @adapter.uncompress("chunk")
+ end
+
+ it "should return the inflated chunk" do
+ @inflater.stubs(:inflate).with("chunk").returns("uncompressed")
+ @adapter.uncompress("chunk").should == "uncompressed"
+ end
+
+ it "should try a 'regular' inflater on Zlib::DataError" do
+ @inflater.expects(:inflate).raises(Zlib::DataError.new("not a zlib stream"))
+ inflater = stub_everything 'inflater2'
+ inflater.expects(:inflate).with("chunk").returns("uncompressed")
+ Zlib::Inflate.expects(:new).with.returns(inflater)
+ @adapter.uncompress("chunk")
+ end
+
+ it "should raise the error the second time" do
+ @inflater.expects(:inflate).raises(Zlib::DataError.new("not a zlib stream"))
+ Zlib::Inflate.expects(:new).with.returns(@inflater)
+ lambda { @adapter.uncompress("chunk") }.should raise_error
+ end
+
+ it "should finish the stream on close" do
+ @inflater.expects(:finish)
+ @adapter.close
+ end
+
+ it "should close the stream on close" do
+ @inflater.expects(:close)
+ @adapter.close
+ end
end
+ end
end
diff --git a/spec/unit/network/http/handler_spec.rb b/spec/unit/network/http/handler_spec.rb
index e6dd881..76a9c55 100755
--- a/spec/unit/network/http/handler_spec.rb
+++ b/spec/unit/network/http/handler_spec.rb
@@ -5,451 +5,451 @@ require 'puppet/network/http/handler'
require 'puppet/network/rest_authorization'
class HttpHandled
- include Puppet::Network::HTTP::Handler
+ include Puppet::Network::HTTP::Handler
end
describe Puppet::Network::HTTP::Handler do
- before do
- @handler = HttpHandled.new
- end
+ before do
+ @handler = HttpHandled.new
+ end
- it "should include the v1 REST API" do
- Puppet::Network::HTTP::Handler.ancestors.should be_include(Puppet::Network::HTTP::API::V1)
- end
+ it "should include the v1 REST API" do
+ Puppet::Network::HTTP::Handler.ancestors.should be_include(Puppet::Network::HTTP::API::V1)
+ end
- it "should include the Rest Authorization system" do
- Puppet::Network::HTTP::Handler.ancestors.should be_include(Puppet::Network::RestAuthorization)
+ it "should include the Rest Authorization system" do
+ Puppet::Network::HTTP::Handler.ancestors.should be_include(Puppet::Network::RestAuthorization)
+ end
+
+ it "should have a method for initializing" do
+ @handler.should respond_to(:initialize_for_puppet)
+ end
+
+ describe "when initializing" do
+ it "should fail when no server type has been provided" do
+ lambda { @handler.initialize_for_puppet }.should raise_error(ArgumentError)
end
- it "should have a method for initializing" do
- @handler.should respond_to(:initialize_for_puppet)
+ it "should set server type" do
+ @handler.initialize_for_puppet("foo")
+ @handler.server.should == "foo"
end
+ end
- describe "when initializing" do
- it "should fail when no server type has been provided" do
- lambda { @handler.initialize_for_puppet }.should raise_error(ArgumentError)
- end
+ it "should be able to process requests" do
+ @handler.should respond_to(:process)
+ end
- it "should set server type" do
- @handler.initialize_for_puppet("foo")
- @handler.server.should == "foo"
- end
+ describe "when processing a request" do
+ before do
+ @request = stub('http request')
+ @request.stubs(:[]).returns "foo"
+ @response = stub('http response')
+ @model_class = stub('indirected model class')
+
+ @result = stub 'result', :render => "mytext"
+
+ @handler.stubs(:check_authorization)
+
+ stub_server_interface
end
- it "should be able to process requests" do
- @handler.should respond_to(:process)
+ # Stub out the interface we require our including classes to
+ # implement.
+ def stub_server_interface
+ @handler.stubs(:accept_header ).returns "format_one,format_two"
+ @handler.stubs(:content_type_header).returns "text/yaml"
+ @handler.stubs(:set_content_type ).returns "my_result"
+ @handler.stubs(:set_response ).returns "my_result"
+ @handler.stubs(:path ).returns "/my_handler/my_result"
+ @handler.stubs(:http_method ).returns("GET")
+ @handler.stubs(:params ).returns({})
+ @handler.stubs(:content_type ).returns("text/plain")
end
- describe "when processing a request" do
- before do
- @request = stub('http request')
- @request.stubs(:[]).returns "foo"
- @response = stub('http response')
- @model_class = stub('indirected model class')
+ it "should create an indirection request from the path, parameters, and http method" do
+ @handler.expects(:path).with(@request).returns "mypath"
+ @handler.expects(:http_method).with(@request).returns "mymethod"
+ @handler.expects(:params).with(@request).returns "myparams"
- @result = stub 'result', :render => "mytext"
+ @handler.expects(:uri2indirection).with("mymethod", "mypath", "myparams").returns stub("request", :method => :find)
- @handler.stubs(:check_authorization)
+ @handler.stubs(:do_find)
- stub_server_interface
- end
+ @handler.process(@request, @response)
+ end
- # Stub out the interface we require our including classes to
- # implement.
- def stub_server_interface
- @handler.stubs(:accept_header ).returns "format_one,format_two"
- @handler.stubs(:content_type_header).returns "text/yaml"
- @handler.stubs(:set_content_type ).returns "my_result"
- @handler.stubs(:set_response ).returns "my_result"
- @handler.stubs(:path ).returns "/my_handler/my_result"
- @handler.stubs(:http_method ).returns("GET")
- @handler.stubs(:params ).returns({})
- @handler.stubs(:content_type ).returns("text/plain")
- end
+ it "should call the 'do' method associated with the indirection method" do
+ request = stub 'request'
+ @handler.expects(:uri2indirection).returns request
- it "should create an indirection request from the path, parameters, and http method" do
- @handler.expects(:path).with(@request).returns "mypath"
- @handler.expects(:http_method).with(@request).returns "mymethod"
- @handler.expects(:params).with(@request).returns "myparams"
+ request.expects(:method).returns "mymethod"
- @handler.expects(:uri2indirection).with("mymethod", "mypath", "myparams").returns stub("request", :method => :find)
+ @handler.expects(:do_mymethod).with(request, @request, @response)
- @handler.stubs(:do_find)
+ @handler.process(@request, @response)
+ end
- @handler.process(@request, @response)
- end
+ it "should delegate authorization to the RestAuthorization layer" do
+ request = stub 'request'
+ @handler.expects(:uri2indirection).returns request
- it "should call the 'do' method associated with the indirection method" do
- request = stub 'request'
- @handler.expects(:uri2indirection).returns request
+ request.expects(:method).returns "mymethod"
- request.expects(:method).returns "mymethod"
+ @handler.expects(:do_mymethod).with(request, @request, @response)
- @handler.expects(:do_mymethod).with(request, @request, @response)
+ @handler.expects(:check_authorization).with(request)
- @handler.process(@request, @response)
- end
+ @handler.process(@request, @response)
+ end
- it "should delegate authorization to the RestAuthorization layer" do
- request = stub 'request'
- @handler.expects(:uri2indirection).returns request
+ it "should return 403 if the request is not authorized" do
+ request = stub 'request'
+ @handler.expects(:uri2indirection).returns request
- request.expects(:method).returns "mymethod"
+ @handler.expects(:do_mymethod).never
- @handler.expects(:do_mymethod).with(request, @request, @response)
+ @handler.expects(:check_authorization).with(request).raises(Puppet::Network::AuthorizationError.new("forbindden"))
- @handler.expects(:check_authorization).with(request)
+ @handler.expects(:set_response).with { |response, body, status| status == 403 }
- @handler.process(@request, @response)
- end
+ @handler.process(@request, @response)
+ end
- it "should return 403 if the request is not authorized" do
- request = stub 'request'
- @handler.expects(:uri2indirection).returns request
+ it "should serialize a controller exception when an exception is thrown while finding the model instance" do
+ @handler.expects(:uri2indirection).returns stub("request", :method => :find)
- @handler.expects(:do_mymethod).never
+ @handler.expects(:do_find).raises(ArgumentError, "The exception")
+ @handler.expects(:set_response).with { |response, body, status| body == "The exception" and status == 400 }
+ @handler.process(@request, @response)
+ end
- @handler.expects(:check_authorization).with(request).raises(Puppet::Network::AuthorizationError.new("forbindden"))
+ it "should set the format to text/plain when serializing an exception" do
+ @handler.expects(:set_content_type).with(@response, "text/plain")
+ @handler.do_exception(@response, "A test", 404)
+ end
- @handler.expects(:set_response).with { |response, body, status| status == 403 }
+ it "should raise an error if the request is formatted in an unknown format" do
+ @handler.stubs(:content_type_header).returns "unknown format"
+ lambda { @handler.request_format(@request) }.should raise_error
+ end
- @handler.process(@request, @response)
- end
+ it "should still find the correct format if content type contains charset information" do
+ @handler.stubs(:content_type_header).returns "text/plain; charset=UTF-8"
+ @handler.request_format(@request).should == "s"
+ end
- it "should serialize a controller exception when an exception is thrown while finding the model instance" do
- @handler.expects(:uri2indirection).returns stub("request", :method => :find)
+ describe "when finding a model instance" do
+ before do
+ @irequest = stub 'indirection_request', :method => :find, :indirection_name => "my_handler", :to_hash => {}, :key => "my_result", :model => @model_class
- @handler.expects(:do_find).raises(ArgumentError, "The exception")
- @handler.expects(:set_response).with { |response, body, status| body == "The exception" and status == 400 }
- @handler.process(@request, @response)
- end
+ @model_class.stubs(:find).returns @result
- it "should set the format to text/plain when serializing an exception" do
- @handler.expects(:set_content_type).with(@response, "text/plain")
- @handler.do_exception(@response, "A test", 404)
- end
+ @format = stub 'format', :suitable? => true, :mime => "text/format", :name => "format"
+ Puppet::Network::FormatHandler.stubs(:format).returns @format
- it "should raise an error if the request is formatted in an unknown format" do
- @handler.stubs(:content_type_header).returns "unknown format"
- lambda { @handler.request_format(@request) }.should raise_error
- end
+ @oneformat = stub 'one', :suitable? => true, :mime => "text/one", :name => "one"
+ Puppet::Network::FormatHandler.stubs(:format).with("one").returns @oneformat
+ end
- it "should still find the correct format if content type contains charset information" do
- @handler.stubs(:content_type_header).returns "text/plain; charset=UTF-8"
- @handler.request_format(@request).should == "s"
- end
+ it "should use the indirection request to find the model class" do
+ @irequest.expects(:model).returns @model_class
- describe "when finding a model instance" do
- before do
- @irequest = stub 'indirection_request', :method => :find, :indirection_name => "my_handler", :to_hash => {}, :key => "my_result", :model => @model_class
+ @handler.do_find(@irequest, @request, @response)
+ end
- @model_class.stubs(:find).returns @result
+ it "should use the escaped request key" do
+ @model_class.expects(:find).with do |key, args|
+ key == "my_result"
+ end.returns @result
+ @handler.do_find(@irequest, @request, @response)
+ end
- @format = stub 'format', :suitable? => true, :mime => "text/format", :name => "format"
- Puppet::Network::FormatHandler.stubs(:format).returns @format
+ it "should use a common method for determining the request parameters" do
+ @irequest.stubs(:to_hash).returns(:foo => :baz, :bar => :xyzzy)
+ @model_class.expects(:find).with do |key, args|
+ args[:foo] == :baz and args[:bar] == :xyzzy
+ end.returns @result
+ @handler.do_find(@irequest, @request, @response)
+ end
- @oneformat = stub 'one', :suitable? => true, :mime => "text/one", :name => "one"
- Puppet::Network::FormatHandler.stubs(:format).with("one").returns @oneformat
- end
+ it "should set the content type to the first format specified in the accept header" do
+ @handler.expects(:accept_header).with(@request).returns "one,two"
+ @handler.expects(:set_content_type).with(@response, @oneformat)
+ @handler.do_find(@irequest, @request, @response)
+ end
- it "should use the indirection request to find the model class" do
- @irequest.expects(:model).returns @model_class
+ it "should fail if no accept header is provided" do
+ @handler.expects(:accept_header).with(@request).returns nil
+ lambda { @handler.do_find(@irequest, @request, @response) }.should raise_error(ArgumentError)
+ end
- @handler.do_find(@irequest, @request, @response)
- end
+ it "should fail if the accept header does not contain a valid format" do
+ @handler.expects(:accept_header).with(@request).returns ""
+ lambda { @handler.do_find(@irequest, @request, @response) }.should raise_error(RuntimeError)
+ end
- it "should use the escaped request key" do
- @model_class.expects(:find).with do |key, args|
- key == "my_result"
- end.returns @result
- @handler.do_find(@irequest, @request, @response)
- end
+ it "should not use an unsuitable format" do
+ @handler.expects(:accept_header).with(@request).returns "foo,bar"
+ foo = mock 'foo', :suitable? => false
+ bar = mock 'bar', :suitable? => true
+ Puppet::Network::FormatHandler.expects(:format).with("foo").returns foo
+ Puppet::Network::FormatHandler.expects(:format).with("bar").returns bar
- it "should use a common method for determining the request parameters" do
- @irequest.stubs(:to_hash).returns(:foo => :baz, :bar => :xyzzy)
- @model_class.expects(:find).with do |key, args|
- args[:foo] == :baz and args[:bar] == :xyzzy
- end.returns @result
- @handler.do_find(@irequest, @request, @response)
- end
+ @handler.expects(:set_content_type).with(@response, bar) # the suitable one
- it "should set the content type to the first format specified in the accept header" do
- @handler.expects(:accept_header).with(@request).returns "one,two"
- @handler.expects(:set_content_type).with(@response, @oneformat)
- @handler.do_find(@irequest, @request, @response)
- end
+ @handler.do_find(@irequest, @request, @response)
+ end
- it "should fail if no accept header is provided" do
- @handler.expects(:accept_header).with(@request).returns nil
- lambda { @handler.do_find(@irequest, @request, @response) }.should raise_error(ArgumentError)
- end
+ it "should render the result using the first format specified in the accept header" do
- it "should fail if the accept header does not contain a valid format" do
- @handler.expects(:accept_header).with(@request).returns ""
- lambda { @handler.do_find(@irequest, @request, @response) }.should raise_error(RuntimeError)
- end
+ @handler.expects(:accept_header).with(@request).returns "one,two"
+ @result.expects(:render).with(@oneformat)
- it "should not use an unsuitable format" do
- @handler.expects(:accept_header).with(@request).returns "foo,bar"
- foo = mock 'foo', :suitable? => false
- bar = mock 'bar', :suitable? => true
- Puppet::Network::FormatHandler.expects(:format).with("foo").returns foo
- Puppet::Network::FormatHandler.expects(:format).with("bar").returns bar
+ @handler.do_find(@irequest, @request, @response)
+ end
- @handler.expects(:set_content_type).with(@response, bar) # the suitable one
+ it "should use the default status when a model find call succeeds" do
+ @handler.expects(:set_response).with { |response, body, status| status.nil? }
+ @handler.do_find(@irequest, @request, @response)
+ end
- @handler.do_find(@irequest, @request, @response)
- end
+ it "should return a serialized object when a model find call succeeds" do
+ @model_instance = stub('model instance')
+ @model_instance.expects(:render).returns "my_rendered_object"
- it "should render the result using the first format specified in the accept header" do
+ @handler.expects(:set_response).with { |response, body, status| body == "my_rendered_object" }
+ @model_class.stubs(:find).returns(@model_instance)
+ @handler.do_find(@irequest, @request, @response)
+ end
- @handler.expects(:accept_header).with(@request).returns "one,two"
- @result.expects(:render).with(@oneformat)
+ it "should return a 404 when no model instance can be found" do
+ @model_class.stubs(:name).returns "my name"
+ @handler.expects(:set_response).with { |response, body, status| status == 404 }
+ @model_class.stubs(:find).returns(nil)
+ @handler.do_find(@irequest, @request, @response)
+ end
- @handler.do_find(@irequest, @request, @response)
- end
+ it "should write a log message when no model instance can be found" do
+ @model_class.stubs(:name).returns "my name"
+ @model_class.stubs(:find).returns(nil)
- it "should use the default status when a model find call succeeds" do
- @handler.expects(:set_response).with { |response, body, status| status.nil? }
- @handler.do_find(@irequest, @request, @response)
- end
+ Puppet.expects(:info).with("Could not find my_handler for 'my_result'")
- it "should return a serialized object when a model find call succeeds" do
- @model_instance = stub('model instance')
- @model_instance.expects(:render).returns "my_rendered_object"
+ @handler.do_find(@irequest, @request, @response)
+ end
- @handler.expects(:set_response).with { |response, body, status| body == "my_rendered_object" }
- @model_class.stubs(:find).returns(@model_instance)
- @handler.do_find(@irequest, @request, @response)
- end
- it "should return a 404 when no model instance can be found" do
- @model_class.stubs(:name).returns "my name"
- @handler.expects(:set_response).with { |response, body, status| status == 404 }
- @model_class.stubs(:find).returns(nil)
- @handler.do_find(@irequest, @request, @response)
- end
+ it "should serialize the result in with the appropriate format" do
+ @model_instance = stub('model instance')
+
+ @handler.expects(:format_to_use).returns(@oneformat)
+ @model_instance.expects(:render).with(@oneformat).returns "my_rendered_object"
+ @model_class.stubs(:find).returns(@model_instance)
+ @handler.do_find(@irequest, @request, @response)
+ end
+ end
- it "should write a log message when no model instance can be found" do
- @model_class.stubs(:name).returns "my name"
- @model_class.stubs(:find).returns(nil)
+ describe "when searching for model instances" do
+ before do
+ @irequest = stub 'indirection_request', :method => :find, :indirection_name => "my_handler", :to_hash => {}, :key => "key", :model => @model_class
- Puppet.expects(:info).with("Could not find my_handler for 'my_result'")
+ @result1 = mock 'result1'
+ @result2 = mock 'results'
- @handler.do_find(@irequest, @request, @response)
- end
+ @result = [@result1, @result2]
+ @model_class.stubs(:render_multiple).returns "my rendered instances"
+ @model_class.stubs(:search).returns(@result)
+ @format = stub 'format', :suitable? => true, :mime => "text/format", :name => "format"
+ Puppet::Network::FormatHandler.stubs(:format).returns @format
- it "should serialize the result in with the appropriate format" do
- @model_instance = stub('model instance')
-
- @handler.expects(:format_to_use).returns(@oneformat)
- @model_instance.expects(:render).with(@oneformat).returns "my_rendered_object"
- @model_class.stubs(:find).returns(@model_instance)
- @handler.do_find(@irequest, @request, @response)
- end
- end
+ @oneformat = stub 'one', :suitable? => true, :mime => "text/one", :name => "one"
+ Puppet::Network::FormatHandler.stubs(:format).with("one").returns @oneformat
+ end
- describe "when searching for model instances" do
- before do
- @irequest = stub 'indirection_request', :method => :find, :indirection_name => "my_handler", :to_hash => {}, :key => "key", :model => @model_class
+ it "should use the indirection request to find the model" do
+ @irequest.expects(:model).returns @model_class
- @result1 = mock 'result1'
- @result2 = mock 'results'
+ @handler.do_search(@irequest, @request, @response)
+ end
- @result = [@result1, @result2]
- @model_class.stubs(:render_multiple).returns "my rendered instances"
- @model_class.stubs(:search).returns(@result)
+ it "should use a common method for determining the request parameters" do
+ @irequest.stubs(:to_hash).returns(:foo => :baz, :bar => :xyzzy)
+ @model_class.expects(:search).with do |key, args|
+ args[:foo] == :baz and args[:bar] == :xyzzy
+ end.returns @result
+ @handler.do_search(@irequest, @request, @response)
+ end
- @format = stub 'format', :suitable? => true, :mime => "text/format", :name => "format"
- Puppet::Network::FormatHandler.stubs(:format).returns @format
+ it "should use the default status when a model search call succeeds" do
+ @model_class.stubs(:search).returns(@result)
+ @handler.do_search(@irequest, @request, @response)
+ end
- @oneformat = stub 'one', :suitable? => true, :mime => "text/one", :name => "one"
- Puppet::Network::FormatHandler.stubs(:format).with("one").returns @oneformat
- end
+ it "should set the content type to the first format returned by the accept header" do
+ @handler.expects(:accept_header).with(@request).returns "one,two"
+ @handler.expects(:set_content_type).with(@response, @oneformat)
- it "should use the indirection request to find the model" do
- @irequest.expects(:model).returns @model_class
+ @handler.do_search(@irequest, @request, @response)
+ end
- @handler.do_search(@irequest, @request, @response)
- end
+ it "should return a list of serialized objects when a model search call succeeds" do
+ @handler.expects(:accept_header).with(@request).returns "one,two"
- it "should use a common method for determining the request parameters" do
- @irequest.stubs(:to_hash).returns(:foo => :baz, :bar => :xyzzy)
- @model_class.expects(:search).with do |key, args|
- args[:foo] == :baz and args[:bar] == :xyzzy
- end.returns @result
- @handler.do_search(@irequest, @request, @response)
- end
+ @model_class.stubs(:search).returns(@result)
- it "should use the default status when a model search call succeeds" do
- @model_class.stubs(:search).returns(@result)
- @handler.do_search(@irequest, @request, @response)
- end
+ @model_class.expects(:render_multiple).with(@oneformat, @result).returns "my rendered instances"
- it "should set the content type to the first format returned by the accept header" do
- @handler.expects(:accept_header).with(@request).returns "one,two"
- @handler.expects(:set_content_type).with(@response, @oneformat)
+ @handler.expects(:set_response).with { |response, data| data == "my rendered instances" }
+ @handler.do_search(@irequest, @request, @response)
+ end
- @handler.do_search(@irequest, @request, @response)
- end
+ it "should return a 404 when searching returns an empty array" do
+ @model_class.stubs(:name).returns "my name"
+ @handler.expects(:set_response).with { |response, body, status| status == 404 }
+ @model_class.stubs(:search).returns([])
+ @handler.do_search(@irequest, @request, @response)
+ end
- it "should return a list of serialized objects when a model search call succeeds" do
- @handler.expects(:accept_header).with(@request).returns "one,two"
+ it "should return a 404 when searching returns nil" do
+ @model_class.stubs(:name).returns "my name"
+ @handler.expects(:set_response).with { |response, body, status| status == 404 }
+ @model_class.stubs(:search).returns([])
+ @handler.do_search(@irequest, @request, @response)
+ end
+ end
- @model_class.stubs(:search).returns(@result)
+ describe "when destroying a model instance" do
+ before do
+ @irequest = stub 'indirection_request', :method => :destroy, :indirection_name => "my_handler", :to_hash => {}, :key => "key", :model => @model_class
- @model_class.expects(:render_multiple).with(@oneformat, @result).returns "my rendered instances"
+ @result = stub 'result', :render => "the result"
+ @model_class.stubs(:destroy).returns @result
+ end
- @handler.expects(:set_response).with { |response, data| data == "my rendered instances" }
- @handler.do_search(@irequest, @request, @response)
- end
+ it "should use the indirection request to find the model" do
+ @irequest.expects(:model).returns @model_class
- it "should return a 404 when searching returns an empty array" do
- @model_class.stubs(:name).returns "my name"
- @handler.expects(:set_response).with { |response, body, status| status == 404 }
- @model_class.stubs(:search).returns([])
- @handler.do_search(@irequest, @request, @response)
- end
+ @handler.do_destroy(@irequest, @request, @response)
+ end
- it "should return a 404 when searching returns nil" do
- @model_class.stubs(:name).returns "my name"
- @handler.expects(:set_response).with { |response, body, status| status == 404 }
- @model_class.stubs(:search).returns([])
- @handler.do_search(@irequest, @request, @response)
- end
+ it "should use the escaped request key to destroy the instance in the model" do
+ @irequest.expects(:key).returns "foo bar"
+ @model_class.expects(:destroy).with do |key, args|
+ key == "foo bar"
end
+ @handler.do_destroy(@irequest, @request, @response)
+ end
- describe "when destroying a model instance" do
- before do
- @irequest = stub 'indirection_request', :method => :destroy, :indirection_name => "my_handler", :to_hash => {}, :key => "key", :model => @model_class
-
- @result = stub 'result', :render => "the result"
- @model_class.stubs(:destroy).returns @result
- end
-
- it "should use the indirection request to find the model" do
- @irequest.expects(:model).returns @model_class
-
- @handler.do_destroy(@irequest, @request, @response)
- end
-
- it "should use the escaped request key to destroy the instance in the model" do
- @irequest.expects(:key).returns "foo bar"
- @model_class.expects(:destroy).with do |key, args|
- key == "foo bar"
- end
- @handler.do_destroy(@irequest, @request, @response)
- end
-
- it "should use a common method for determining the request parameters" do
- @irequest.stubs(:to_hash).returns(:foo => :baz, :bar => :xyzzy)
- @model_class.expects(:destroy).with do |key, args|
- args[:foo] == :baz and args[:bar] == :xyzzy
- end
- @handler.do_destroy(@irequest, @request, @response)
- end
-
- it "should use the default status code a model destroy call succeeds" do
- @handler.expects(:set_response).with { |response, body, status| status.nil? }
- @handler.do_destroy(@irequest, @request, @response)
- end
-
- it "should return a yaml-encoded result when a model destroy call succeeds" do
- @result = stub 'result', :to_yaml => "the result"
- @model_class.expects(:destroy).returns(@result)
-
- @handler.expects(:set_response).with { |response, body, status| body == "the result" }
-
- @handler.do_destroy(@irequest, @request, @response)
- end
+ it "should use a common method for determining the request parameters" do
+ @irequest.stubs(:to_hash).returns(:foo => :baz, :bar => :xyzzy)
+ @model_class.expects(:destroy).with do |key, args|
+ args[:foo] == :baz and args[:bar] == :xyzzy
end
+ @handler.do_destroy(@irequest, @request, @response)
+ end
- describe "when saving a model instance" do
- before do
- @irequest = stub 'indirection_request', :method => :save, :indirection_name => "my_handler", :to_hash => {}, :key => "key", :model => @model_class
- @handler.stubs(:body).returns('my stuff')
- @handler.stubs(:content_type_header).returns("text/yaml")
+ it "should use the default status code a model destroy call succeeds" do
+ @handler.expects(:set_response).with { |response, body, status| status.nil? }
+ @handler.do_destroy(@irequest, @request, @response)
+ end
- @result = stub 'result', :render => "the result"
+ it "should return a yaml-encoded result when a model destroy call succeeds" do
+ @result = stub 'result', :to_yaml => "the result"
+ @model_class.expects(:destroy).returns(@result)
- @model_instance = stub('indirected model instance', :save => true)
- @model_class.stubs(:convert_from).returns(@model_instance)
+ @handler.expects(:set_response).with { |response, body, status| body == "the result" }
- @format = stub 'format', :suitable? => true, :name => "format", :mime => "text/format"
- Puppet::Network::FormatHandler.stubs(:format).returns @format
- @yamlformat = stub 'yaml', :suitable? => true, :name => "yaml", :mime => "text/yaml"
- Puppet::Network::FormatHandler.stubs(:format).with("yaml").returns @yamlformat
- end
+ @handler.do_destroy(@irequest, @request, @response)
+ end
+ end
- it "should use the indirection request to find the model" do
- @irequest.expects(:model).returns @model_class
+ describe "when saving a model instance" do
+ before do
+ @irequest = stub 'indirection_request', :method => :save, :indirection_name => "my_handler", :to_hash => {}, :key => "key", :model => @model_class
+ @handler.stubs(:body).returns('my stuff')
+ @handler.stubs(:content_type_header).returns("text/yaml")
- @handler.do_save(@irequest, @request, @response)
- end
+ @result = stub 'result', :render => "the result"
- it "should use the 'body' hook to retrieve the body of the request" do
- @handler.expects(:body).returns "my body"
- @model_class.expects(:convert_from).with { |format, body| body == "my body" }.returns @model_instance
+ @model_instance = stub('indirected model instance', :save => true)
+ @model_class.stubs(:convert_from).returns(@model_instance)
- @handler.do_save(@irequest, @request, @response)
- end
+ @format = stub 'format', :suitable? => true, :name => "format", :mime => "text/format"
+ Puppet::Network::FormatHandler.stubs(:format).returns @format
+ @yamlformat = stub 'yaml', :suitable? => true, :name => "yaml", :mime => "text/yaml"
+ Puppet::Network::FormatHandler.stubs(:format).with("yaml").returns @yamlformat
+ end
- it "should fail to save model if data is not specified" do
- @handler.stubs(:body).returns('')
+ it "should use the indirection request to find the model" do
+ @irequest.expects(:model).returns @model_class
- lambda { @handler.do_save(@irequest, @request, @response) }.should raise_error(ArgumentError)
- end
+ @handler.do_save(@irequest, @request, @response)
+ end
- it "should use a common method for determining the request parameters" do
- @model_instance.expects(:save).with('key').once
- @handler.do_save(@irequest, @request, @response)
- end
+ it "should use the 'body' hook to retrieve the body of the request" do
+ @handler.expects(:body).returns "my body"
+ @model_class.expects(:convert_from).with { |format, body| body == "my body" }.returns @model_instance
- it "should use the default status when a model save call succeeds" do
- @handler.expects(:set_response).with { |response, body, status| status.nil? }
- @handler.do_save(@irequest, @request, @response)
- end
+ @handler.do_save(@irequest, @request, @response)
+ end
- it "should return the yaml-serialized result when a model save call succeeds" do
- @model_instance.stubs(:save).returns(@model_instance)
- @model_instance.expects(:to_yaml).returns('foo')
- @handler.do_save(@irequest, @request, @response)
- end
+ it "should fail to save model if data is not specified" do
+ @handler.stubs(:body).returns('')
- it "should set the content to yaml" do
- @handler.expects(:set_content_type).with(@response, @yamlformat)
- @handler.do_save(@irequest, @request, @response)
- end
+ lambda { @handler.do_save(@irequest, @request, @response) }.should raise_error(ArgumentError)
+ end
- it "should use the content-type header to know the body format" do
- @handler.expects(:content_type_header).returns("text/format")
- Puppet::Network::FormatHandler.stubs(:mime).with("text/format").returns @format
+ it "should use a common method for determining the request parameters" do
+ @model_instance.expects(:save).with('key').once
+ @handler.do_save(@irequest, @request, @response)
+ end
- @model_class.expects(:convert_from).with { |format, body| format == "format" }.returns @model_instance
+ it "should use the default status when a model save call succeeds" do
+ @handler.expects(:set_response).with { |response, body, status| status.nil? }
+ @handler.do_save(@irequest, @request, @response)
+ end
- @handler.do_save(@irequest, @request, @response)
- end
- end
+ it "should return the yaml-serialized result when a model save call succeeds" do
+ @model_instance.stubs(:save).returns(@model_instance)
+ @model_instance.expects(:to_yaml).returns('foo')
+ @handler.do_save(@irequest, @request, @response)
+ end
+
+ it "should set the content to yaml" do
+ @handler.expects(:set_content_type).with(@response, @yamlformat)
+ @handler.do_save(@irequest, @request, @response)
+ end
+
+ it "should use the content-type header to know the body format" do
+ @handler.expects(:content_type_header).returns("text/format")
+ Puppet::Network::FormatHandler.stubs(:mime).with("text/format").returns @format
+
+ @model_class.expects(:convert_from).with { |format, body| format == "format" }.returns @model_instance
+
+ @handler.do_save(@irequest, @request, @response)
+ end
end
+ end
- describe "when resolving node" do
- it "should use a look-up from the ip address" do
- Resolv.expects(:getname).with("1.2.3.4").returns("host.domain.com")
+ describe "when resolving node" do
+ it "should use a look-up from the ip address" do
+ Resolv.expects(:getname).with("1.2.3.4").returns("host.domain.com")
- @handler.resolve_node(:ip => "1.2.3.4")
- end
+ @handler.resolve_node(:ip => "1.2.3.4")
+ end
- it "should return the look-up result" do
- Resolv.stubs(:getname).with("1.2.3.4").returns("host.domain.com")
+ it "should return the look-up result" do
+ Resolv.stubs(:getname).with("1.2.3.4").returns("host.domain.com")
- @handler.resolve_node(:ip => "1.2.3.4").should == "host.domain.com"
- end
+ @handler.resolve_node(:ip => "1.2.3.4").should == "host.domain.com"
+ end
- it "should return the ip address if resolving fails" do
- Resolv.stubs(:getname).with("1.2.3.4").raises(RuntimeError, "no such host")
+ it "should return the ip address if resolving fails" do
+ Resolv.stubs(:getname).with("1.2.3.4").raises(RuntimeError, "no such host")
- @handler.resolve_node(:ip => "1.2.3.4").should == "1.2.3.4"
- end
+ @handler.resolve_node(:ip => "1.2.3.4").should == "1.2.3.4"
end
+ end
end
diff --git a/spec/unit/network/http/mongrel/rest_spec.rb b/spec/unit/network/http/mongrel/rest_spec.rb
index 55b6172..92a81a1 100755
--- a/spec/unit/network/http/mongrel/rest_spec.rb
+++ b/spec/unit/network/http/mongrel/rest_spec.rb
@@ -5,245 +5,245 @@ require File.dirname(__FILE__) + '/../../../../spec_helper'
require 'puppet/network/http'
describe "Puppet::Network::HTTP::MongrelREST" do
- confine "Mongrel is not available" => Puppet.features.mongrel?
- before do
- require 'puppet/network/http/mongrel/rest'
- end
+ confine "Mongrel is not available" => Puppet.features.mongrel?
+ before do
+ require 'puppet/network/http/mongrel/rest'
+ end
+
+ it "should include the Puppet::Network::HTTP::Handler module" do
+ Puppet::Network::HTTP::MongrelREST.ancestors.should be_include(Puppet::Network::HTTP::Handler)
+ end
- it "should include the Puppet::Network::HTTP::Handler module" do
- Puppet::Network::HTTP::MongrelREST.ancestors.should be_include(Puppet::Network::HTTP::Handler)
+ describe "when initializing" do
+ it "should call the Handler's initialization hook with its provided arguments as the server and handler" do
+ Puppet::Network::HTTP::MongrelREST.any_instance.expects(:initialize_for_puppet).with(:server => "my", :handler => "arguments")
+ Puppet::Network::HTTP::MongrelREST.new(:server => "my", :handler => "arguments")
end
+ end
- describe "when initializing" do
- it "should call the Handler's initialization hook with its provided arguments as the server and handler" do
- Puppet::Network::HTTP::MongrelREST.any_instance.expects(:initialize_for_puppet).with(:server => "my", :handler => "arguments")
- Puppet::Network::HTTP::MongrelREST.new(:server => "my", :handler => "arguments")
- end
+ describe "when receiving a request" do
+ before do
+ @params = {}
+ @request = stub('mongrel http request', :params => @params)
+
+ @head = stub('response head')
+ @body = stub('response body', :write => true)
+ @response = stub('mongrel http response')
+ @response.stubs(:start).yields(@head, @body)
+ @model_class = stub('indirected model class')
+ @mongrel = stub('mongrel http server', :register => true)
+ Puppet::Indirector::Indirection.stubs(:model).with(:foo).returns(@model_class)
+ @handler = Puppet::Network::HTTP::MongrelREST.new(:server => @mongrel, :handler => :foo)
end
- describe "when receiving a request" do
- before do
- @params = {}
- @request = stub('mongrel http request', :params => @params)
-
- @head = stub('response head')
- @body = stub('response body', :write => true)
- @response = stub('mongrel http response')
- @response.stubs(:start).yields(@head, @body)
- @model_class = stub('indirected model class')
- @mongrel = stub('mongrel http server', :register => true)
- Puppet::Indirector::Indirection.stubs(:model).with(:foo).returns(@model_class)
- @handler = Puppet::Network::HTTP::MongrelREST.new(:server => @mongrel, :handler => :foo)
+ describe "and using the HTTP Handler interface" do
+ it "should return the HTTP_ACCEPT parameter as the accept header" do
+ @params.expects(:[]).with("HTTP_ACCEPT").returns "myaccept"
+ @handler.accept_header(@request).should == "myaccept"
+ end
+
+ it "should return the Content-Type parameter as the Content-Type header" do
+ @params.expects(:[]).with("HTTP_CONTENT_TYPE").returns "mycontent"
+ @handler.content_type_header(@request).should == "mycontent"
+ end
+
+ it "should use the REQUEST_METHOD as the http method" do
+ @params.expects(:[]).with(Mongrel::Const::REQUEST_METHOD).returns "mymethod"
+ @handler.http_method(@request).should == "mymethod"
+ end
+
+ it "should return the request path as the path" do
+ @params.expects(:[]).with(Mongrel::Const::REQUEST_PATH).returns "/foo/bar"
+ @handler.path(@request).should == "/foo/bar"
+ end
+
+ it "should return the request body as the body" do
+ @request.expects(:body).returns StringIO.new("mybody")
+ @handler.body(@request).should == "mybody"
+ end
+
+ it "should set the response's content-type header when setting the content type" do
+ @header = mock 'header'
+ @response.expects(:header).returns @header
+ @header.expects(:[]=).with('Content-Type', "mytype")
+
+ @handler.set_content_type(@response, "mytype")
+ end
+
+ it "should set the status and write the body when setting the response for a successful request" do
+ head = mock 'head'
+ body = mock 'body'
+ @response.expects(:start).with(200).yields(head, body)
+
+ body.expects(:write).with("mybody")
+
+ @handler.set_response(@response, "mybody", 200)
+ end
+
+ describe "when the result is a File" do
+ it "should use response send_file" do
+ head = mock 'head'
+ body = mock 'body'
+ stat = stub 'stat', :size => 100
+ file = stub 'file', :stat => stat, :path => "/tmp/path"
+ file.stubs(:is_a?).with(File).returns(true)
+
+ @response.expects(:start).with(200).yields(head, body)
+ @response.expects(:send_status).with(100)
+ @response.expects(:send_header)
+ @response.expects(:send_file).with("/tmp/path")
+
+ @handler.set_response(@response, file, 200)
end
+ end
- describe "and using the HTTP Handler interface" do
- it "should return the HTTP_ACCEPT parameter as the accept header" do
- @params.expects(:[]).with("HTTP_ACCEPT").returns "myaccept"
- @handler.accept_header(@request).should == "myaccept"
- end
-
- it "should return the Content-Type parameter as the Content-Type header" do
- @params.expects(:[]).with("HTTP_CONTENT_TYPE").returns "mycontent"
- @handler.content_type_header(@request).should == "mycontent"
- end
-
- it "should use the REQUEST_METHOD as the http method" do
- @params.expects(:[]).with(Mongrel::Const::REQUEST_METHOD).returns "mymethod"
- @handler.http_method(@request).should == "mymethod"
- end
-
- it "should return the request path as the path" do
- @params.expects(:[]).with(Mongrel::Const::REQUEST_PATH).returns "/foo/bar"
- @handler.path(@request).should == "/foo/bar"
- end
-
- it "should return the request body as the body" do
- @request.expects(:body).returns StringIO.new("mybody")
- @handler.body(@request).should == "mybody"
- end
-
- it "should set the response's content-type header when setting the content type" do
- @header = mock 'header'
- @response.expects(:header).returns @header
- @header.expects(:[]=).with('Content-Type', "mytype")
-
- @handler.set_content_type(@response, "mytype")
- end
-
- it "should set the status and write the body when setting the response for a successful request" do
- head = mock 'head'
- body = mock 'body'
- @response.expects(:start).with(200).yields(head, body)
-
- body.expects(:write).with("mybody")
-
- @handler.set_response(@response, "mybody", 200)
- end
-
- describe "when the result is a File" do
- it "should use response send_file" do
- head = mock 'head'
- body = mock 'body'
- stat = stub 'stat', :size => 100
- file = stub 'file', :stat => stat, :path => "/tmp/path"
- file.stubs(:is_a?).with(File).returns(true)
-
- @response.expects(:start).with(200).yields(head, body)
- @response.expects(:send_status).with(100)
- @response.expects(:send_header)
- @response.expects(:send_file).with("/tmp/path")
-
- @handler.set_response(@response, file, 200)
- end
- end
-
- it "should set the status and reason and write the body when setting the response for a successful request" do
- head = mock 'head'
- body = mock 'body'
- @response.expects(:start).with(400, false, "mybody").yields(head, body)
-
- body.expects(:write).with("mybody")
-
- @handler.set_response(@response, "mybody", 400)
- end
- end
+ it "should set the status and reason and write the body when setting the response for a successful request" do
+ head = mock 'head'
+ body = mock 'body'
+ @response.expects(:start).with(400, false, "mybody").yields(head, body)
- describe "and determining the request parameters" do
- before do
- @request.stubs(:params).returns({})
- end
-
- it "should skip empty parameter values" do
- @request.expects(:params).returns('QUERY_STRING' => "&=")
- lambda { @handler.params(@request) }.should_not raise_error
- end
-
- it "should include the HTTP request parameters, with the keys as symbols" do
- @request.expects(:params).returns('QUERY_STRING' => 'foo=baz&bar=xyzzy')
- result = @handler.params(@request)
- result[:foo].should == "baz"
- result[:bar].should == "xyzzy"
- end
-
- it "should CGI-decode the HTTP parameters" do
- encoding = CGI.escape("foo bar")
- @request.expects(:params).returns('QUERY_STRING' => "foo=#{encoding}")
- result = @handler.params(@request)
- result[:foo].should == "foo bar"
- end
-
- it "should convert the string 'true' to the boolean" do
- @request.expects(:params).returns('QUERY_STRING' => 'foo=true')
- result = @handler.params(@request)
- result[:foo].should be_true
- end
-
- it "should convert the string 'false' to the boolean" do
- @request.expects(:params).returns('QUERY_STRING' => 'foo=false')
- result = @handler.params(@request)
- result[:foo].should be_false
- end
-
- it "should convert integer arguments to Integers" do
- @request.expects(:params).returns('QUERY_STRING' => 'foo=15')
- result = @handler.params(@request)
- result[:foo].should == 15
- end
-
- it "should convert floating point arguments to Floats" do
- @request.expects(:params).returns('QUERY_STRING' => 'foo=1.5')
- result = @handler.params(@request)
- result[:foo].should == 1.5
- end
-
- it "should YAML-load and URI-decode values that are YAML-encoded" do
- escaping = CGI.escape(YAML.dump(%w{one two}))
- @request.expects(:params).returns('QUERY_STRING' => "foo=#{escaping}")
- result = @handler.params(@request)
- result[:foo].should == %w{one two}
- end
-
- it "should not allow the client to set the node via the query string" do
- @request.stubs(:params).returns('QUERY_STRING' => "node=foo")
- @handler.params(@request)[:node].should be_nil
- end
-
- it "should not allow the client to set the IP address via the query string" do
- @request.stubs(:params).returns('QUERY_STRING' => "ip=foo")
- @handler.params(@request)[:ip].should be_nil
- end
-
- it "should pass the client's ip address to model find" do
- @request.stubs(:params).returns("REMOTE_ADDR" => "ipaddress")
- @handler.params(@request)[:ip].should == "ipaddress"
- end
-
- it "should pass the client's provided X-Forwared-For value as the ip" do
- @request.stubs(:params).returns("HTTP_X_FORWARDED_FOR" => "ipaddress")
- @handler.params(@request)[:ip].should == "ipaddress"
- end
-
- it "should pass the client's provided X-Forwared-For first value as the ip" do
- @request.stubs(:params).returns("HTTP_X_FORWARDED_FOR" => "ipproxy1,ipproxy2,ipaddress")
- @handler.params(@request)[:ip].should == "ipaddress"
- end
-
- it "should pass the client's provided X-Forwared-For value as the ip instead of the REMOTE_ADDR" do
- @request.stubs(:params).returns("REMOTE_ADDR" => "remote_addr")
- @request.stubs(:params).returns("HTTP_X_FORWARDED_FOR" => "ipaddress")
- @handler.params(@request)[:ip].should == "ipaddress"
- end
-
- it "should use the :ssl_client_header to determine the parameter when looking for the certificate" do
- Puppet.settings.stubs(:value).returns "eh"
- Puppet.settings.expects(:value).with(:ssl_client_header).returns "myheader"
- @request.stubs(:params).returns("myheader" => "/CN=host.domain.com")
- @handler.params(@request)
- end
-
- it "should retrieve the hostname by matching the certificate parameter" do
- Puppet.settings.stubs(:value).returns "eh"
- Puppet.settings.expects(:value).with(:ssl_client_header).returns "myheader"
- @request.stubs(:params).returns("myheader" => "/CN=host.domain.com")
- @handler.params(@request)[:node].should == "host.domain.com"
- end
-
- it "should use the :ssl_client_header to determine the parameter for checking whether the host certificate is valid" do
- Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader"
- Puppet.settings.expects(:value).with(:ssl_client_verify_header).returns "myheader"
- @request.stubs(:params).returns("myheader" => "SUCCESS", "certheader" => "/CN=host.domain.com")
- @handler.params(@request)
- end
-
- it "should consider the host authenticated if the validity parameter contains 'SUCCESS'" do
- Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader"
- Puppet.settings.stubs(:value).with(:ssl_client_verify_header).returns "myheader"
- @request.stubs(:params).returns("myheader" => "SUCCESS", "certheader" => "/CN=host.domain.com")
- @handler.params(@request)[:authenticated].should be_true
- end
-
- it "should consider the host unauthenticated if the validity parameter does not contain 'SUCCESS'" do
- Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader"
- Puppet.settings.stubs(:value).with(:ssl_client_verify_header).returns "myheader"
- @request.stubs(:params).returns("myheader" => "whatever", "certheader" => "/CN=host.domain.com")
- @handler.params(@request)[:authenticated].should be_false
- end
-
- it "should consider the host unauthenticated if no certificate information is present" do
- Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader"
- Puppet.settings.stubs(:value).with(:ssl_client_verify_header).returns "myheader"
- @request.stubs(:params).returns("myheader" => nil, "certheader" => "SUCCESS")
- @handler.params(@request)[:authenticated].should be_false
- end
-
- it "should resolve the node name with an ip address look-up if no certificate is present" do
- Puppet.settings.stubs(:value).returns "eh"
- Puppet.settings.expects(:value).with(:ssl_client_header).returns "myheader"
- @request.stubs(:params).returns("myheader" => nil)
- @handler.expects(:resolve_node).returns("host.domain.com")
- @handler.params(@request)[:node].should == "host.domain.com"
- end
- end
+ body.expects(:write).with("mybody")
+
+ @handler.set_response(@response, "mybody", 400)
+ end
+ end
+
+ describe "and determining the request parameters" do
+ before do
+ @request.stubs(:params).returns({})
+ end
+
+ it "should skip empty parameter values" do
+ @request.expects(:params).returns('QUERY_STRING' => "&=")
+ lambda { @handler.params(@request) }.should_not raise_error
+ end
+
+ it "should include the HTTP request parameters, with the keys as symbols" do
+ @request.expects(:params).returns('QUERY_STRING' => 'foo=baz&bar=xyzzy')
+ result = @handler.params(@request)
+ result[:foo].should == "baz"
+ result[:bar].should == "xyzzy"
+ end
+
+ it "should CGI-decode the HTTP parameters" do
+ encoding = CGI.escape("foo bar")
+ @request.expects(:params).returns('QUERY_STRING' => "foo=#{encoding}")
+ result = @handler.params(@request)
+ result[:foo].should == "foo bar"
+ end
+
+ it "should convert the string 'true' to the boolean" do
+ @request.expects(:params).returns('QUERY_STRING' => 'foo=true')
+ result = @handler.params(@request)
+ result[:foo].should be_true
+ end
+
+ it "should convert the string 'false' to the boolean" do
+ @request.expects(:params).returns('QUERY_STRING' => 'foo=false')
+ result = @handler.params(@request)
+ result[:foo].should be_false
+ end
+
+ it "should convert integer arguments to Integers" do
+ @request.expects(:params).returns('QUERY_STRING' => 'foo=15')
+ result = @handler.params(@request)
+ result[:foo].should == 15
+ end
+
+ it "should convert floating point arguments to Floats" do
+ @request.expects(:params).returns('QUERY_STRING' => 'foo=1.5')
+ result = @handler.params(@request)
+ result[:foo].should == 1.5
+ end
+
+ it "should YAML-load and URI-decode values that are YAML-encoded" do
+ escaping = CGI.escape(YAML.dump(%w{one two}))
+ @request.expects(:params).returns('QUERY_STRING' => "foo=#{escaping}")
+ result = @handler.params(@request)
+ result[:foo].should == %w{one two}
+ end
+
+ it "should not allow the client to set the node via the query string" do
+ @request.stubs(:params).returns('QUERY_STRING' => "node=foo")
+ @handler.params(@request)[:node].should be_nil
+ end
+
+ it "should not allow the client to set the IP address via the query string" do
+ @request.stubs(:params).returns('QUERY_STRING' => "ip=foo")
+ @handler.params(@request)[:ip].should be_nil
+ end
+
+ it "should pass the client's ip address to model find" do
+ @request.stubs(:params).returns("REMOTE_ADDR" => "ipaddress")
+ @handler.params(@request)[:ip].should == "ipaddress"
+ end
+
+ it "should pass the client's provided X-Forwared-For value as the ip" do
+ @request.stubs(:params).returns("HTTP_X_FORWARDED_FOR" => "ipaddress")
+ @handler.params(@request)[:ip].should == "ipaddress"
+ end
+
+ it "should pass the client's provided X-Forwared-For first value as the ip" do
+ @request.stubs(:params).returns("HTTP_X_FORWARDED_FOR" => "ipproxy1,ipproxy2,ipaddress")
+ @handler.params(@request)[:ip].should == "ipaddress"
+ end
+
+ it "should pass the client's provided X-Forwared-For value as the ip instead of the REMOTE_ADDR" do
+ @request.stubs(:params).returns("REMOTE_ADDR" => "remote_addr")
+ @request.stubs(:params).returns("HTTP_X_FORWARDED_FOR" => "ipaddress")
+ @handler.params(@request)[:ip].should == "ipaddress"
+ end
+
+ it "should use the :ssl_client_header to determine the parameter when looking for the certificate" do
+ Puppet.settings.stubs(:value).returns "eh"
+ Puppet.settings.expects(:value).with(:ssl_client_header).returns "myheader"
+ @request.stubs(:params).returns("myheader" => "/CN=host.domain.com")
+ @handler.params(@request)
+ end
+
+ it "should retrieve the hostname by matching the certificate parameter" do
+ Puppet.settings.stubs(:value).returns "eh"
+ Puppet.settings.expects(:value).with(:ssl_client_header).returns "myheader"
+ @request.stubs(:params).returns("myheader" => "/CN=host.domain.com")
+ @handler.params(@request)[:node].should == "host.domain.com"
+ end
+
+ it "should use the :ssl_client_header to determine the parameter for checking whether the host certificate is valid" do
+ Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader"
+ Puppet.settings.expects(:value).with(:ssl_client_verify_header).returns "myheader"
+ @request.stubs(:params).returns("myheader" => "SUCCESS", "certheader" => "/CN=host.domain.com")
+ @handler.params(@request)
+ end
+
+ it "should consider the host authenticated if the validity parameter contains 'SUCCESS'" do
+ Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader"
+ Puppet.settings.stubs(:value).with(:ssl_client_verify_header).returns "myheader"
+ @request.stubs(:params).returns("myheader" => "SUCCESS", "certheader" => "/CN=host.domain.com")
+ @handler.params(@request)[:authenticated].should be_true
+ end
+
+ it "should consider the host unauthenticated if the validity parameter does not contain 'SUCCESS'" do
+ Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader"
+ Puppet.settings.stubs(:value).with(:ssl_client_verify_header).returns "myheader"
+ @request.stubs(:params).returns("myheader" => "whatever", "certheader" => "/CN=host.domain.com")
+ @handler.params(@request)[:authenticated].should be_false
+ end
+
+ it "should consider the host unauthenticated if no certificate information is present" do
+ Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader"
+ Puppet.settings.stubs(:value).with(:ssl_client_verify_header).returns "myheader"
+ @request.stubs(:params).returns("myheader" => nil, "certheader" => "SUCCESS")
+ @handler.params(@request)[:authenticated].should be_false
+ end
+
+ it "should resolve the node name with an ip address look-up if no certificate is present" do
+ Puppet.settings.stubs(:value).returns "eh"
+ Puppet.settings.expects(:value).with(:ssl_client_header).returns "myheader"
+ @request.stubs(:params).returns("myheader" => nil)
+ @handler.expects(:resolve_node).returns("host.domain.com")
+ @handler.params(@request)[:node].should == "host.domain.com"
+ end
end
+ end
end
diff --git a/spec/unit/network/http/mongrel_spec.rb b/spec/unit/network/http/mongrel_spec.rb
index c0ca68e..ac3d72b 100755
--- a/spec/unit/network/http/mongrel_spec.rb
+++ b/spec/unit/network/http/mongrel_spec.rb
@@ -7,125 +7,125 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/network/http'
describe "Puppet::Network::HTTP::Mongrel", "after initializing" do
- confine "Mongrel is not available" => Puppet.features.mongrel?
+ confine "Mongrel is not available" => Puppet.features.mongrel?
- it "should not be listening" do
- require 'puppet/network/http/mongrel'
+ it "should not be listening" do
+ require 'puppet/network/http/mongrel'
- Puppet::Network::HTTP::Mongrel.new.should_not be_listening
- end
+ Puppet::Network::HTTP::Mongrel.new.should_not be_listening
+ end
end
describe "Puppet::Network::HTTP::Mongrel", "when turning on listening" do
- confine "Mongrel is not available" => Puppet.features.mongrel?
-
- before do
- require 'puppet/network/http/mongrel'
-
- @server = Puppet::Network::HTTP::Mongrel.new
- @mock_mongrel = mock('mongrel')
- @mock_mongrel.stubs(:run)
- @mock_mongrel.stubs(:register)
- Mongrel::HttpServer.stubs(:new).returns(@mock_mongrel)
-
- @mock_puppet_mongrel = mock('puppet_mongrel')
- Puppet::Network::HTTPServer::Mongrel.stubs(:new).returns(@mock_puppet_mongrel)
-
- @listen_params = { :address => "127.0.0.1", :port => 31337, :protocols => [ :rest, :xmlrpc ], :xmlrpc_handlers => [ :status, :fileserver ] }
- end
-
- it "should fail if already listening" do
- @server.listen(@listen_params)
- Proc.new { @server.listen(@listen_params) }.should raise_error(RuntimeError)
- end
-
- it "should require at least one protocol" do
- Proc.new { @server.listen(@listen_params.delete_if {|k,v| :protocols == k}) }.should raise_error(ArgumentError)
- end
-
- it "should require a listening address to be specified" do
- Proc.new { @server.listen(@listen_params.delete_if {|k,v| :address == k})}.should raise_error(ArgumentError)
- end
-
- it "should require a listening port to be specified" do
- Proc.new { @server.listen(@listen_params.delete_if {|k,v| :port == k})}.should raise_error(ArgumentError)
+ confine "Mongrel is not available" => Puppet.features.mongrel?
+
+ before do
+ require 'puppet/network/http/mongrel'
+
+ @server = Puppet::Network::HTTP::Mongrel.new
+ @mock_mongrel = mock('mongrel')
+ @mock_mongrel.stubs(:run)
+ @mock_mongrel.stubs(:register)
+ Mongrel::HttpServer.stubs(:new).returns(@mock_mongrel)
+
+ @mock_puppet_mongrel = mock('puppet_mongrel')
+ Puppet::Network::HTTPServer::Mongrel.stubs(:new).returns(@mock_puppet_mongrel)
+
+ @listen_params = { :address => "127.0.0.1", :port => 31337, :protocols => [ :rest, :xmlrpc ], :xmlrpc_handlers => [ :status, :fileserver ] }
+ end
+
+ it "should fail if already listening" do
+ @server.listen(@listen_params)
+ Proc.new { @server.listen(@listen_params) }.should raise_error(RuntimeError)
+ end
+
+ it "should require at least one protocol" do
+ Proc.new { @server.listen(@listen_params.delete_if {|k,v| :protocols == k}) }.should raise_error(ArgumentError)
+ end
+
+ it "should require a listening address to be specified" do
+ Proc.new { @server.listen(@listen_params.delete_if {|k,v| :address == k})}.should raise_error(ArgumentError)
+ end
+
+ it "should require a listening port to be specified" do
+ Proc.new { @server.listen(@listen_params.delete_if {|k,v| :port == k})}.should raise_error(ArgumentError)
+ end
+
+ it "should order a mongrel server to start" do
+ @mock_mongrel.expects(:run)
+ @server.listen(@listen_params)
+ end
+
+ it "should tell mongrel to listen on the specified address and port" do
+ Mongrel::HttpServer.expects(:new).with("127.0.0.1", 31337).returns(@mock_mongrel)
+ @server.listen(@listen_params)
+ end
+
+ it "should be listening" do
+ Mongrel::HttpServer.expects(:new).returns(@mock_mongrel)
+ @server.listen(@listen_params)
+ @server.should be_listening
+ end
+
+ describe "when providing REST services" do
+ it "should instantiate a handler at / for handling REST calls" do
+ Puppet::Network::HTTP::MongrelREST.expects(:new).returns "myhandler"
+ @mock_mongrel.expects(:register).with("/", "myhandler")
+
+ @server.listen(@listen_params)
end
- it "should order a mongrel server to start" do
- @mock_mongrel.expects(:run)
- @server.listen(@listen_params)
+ it "should use a Mongrel + REST class to configure Mongrel when REST services are requested" do
+ @server.expects(:class_for_protocol).with(:rest).at_least_once.returns(Puppet::Network::HTTP::MongrelREST)
+ @server.listen(@listen_params)
end
+ end
- it "should tell mongrel to listen on the specified address and port" do
- Mongrel::HttpServer.expects(:new).with("127.0.0.1", 31337).returns(@mock_mongrel)
- @server.listen(@listen_params)
+ describe "when providing XMLRPC services" do
+ it "should do nothing if no xmlrpc handlers have been provided" do
+ Puppet::Network::HTTPServer::Mongrel.expects(:new).never
+ @server.listen(@listen_params.merge(:xmlrpc_handlers => []))
end
- it "should be listening" do
- Mongrel::HttpServer.expects(:new).returns(@mock_mongrel)
- @server.listen(@listen_params)
- @server.should be_listening
+ it "should create an instance of the existing Mongrel http server with the right handlers" do
+ Puppet::Network::HTTPServer::Mongrel.expects(:new).with([:status, :master]).returns(@mock_puppet_mongrel)
+ @server.listen(@listen_params.merge(:xmlrpc_handlers => [:status, :master]))
end
- describe "when providing REST services" do
- it "should instantiate a handler at / for handling REST calls" do
- Puppet::Network::HTTP::MongrelREST.expects(:new).returns "myhandler"
- @mock_mongrel.expects(:register).with("/", "myhandler")
+ it "should register the Mongrel server instance at /RPC2" do
+ @mock_mongrel.expects(:register).with("/RPC2", @mock_puppet_mongrel)
- @server.listen(@listen_params)
- end
-
- it "should use a Mongrel + REST class to configure Mongrel when REST services are requested" do
- @server.expects(:class_for_protocol).with(:rest).at_least_once.returns(Puppet::Network::HTTP::MongrelREST)
- @server.listen(@listen_params)
- end
- end
-
- describe "when providing XMLRPC services" do
- it "should do nothing if no xmlrpc handlers have been provided" do
- Puppet::Network::HTTPServer::Mongrel.expects(:new).never
- @server.listen(@listen_params.merge(:xmlrpc_handlers => []))
- end
-
- it "should create an instance of the existing Mongrel http server with the right handlers" do
- Puppet::Network::HTTPServer::Mongrel.expects(:new).with([:status, :master]).returns(@mock_puppet_mongrel)
- @server.listen(@listen_params.merge(:xmlrpc_handlers => [:status, :master]))
- end
-
- it "should register the Mongrel server instance at /RPC2" do
- @mock_mongrel.expects(:register).with("/RPC2", @mock_puppet_mongrel)
-
- @server.listen(@listen_params.merge(:xmlrpc_handlers => [:status, :master]))
- end
+ @server.listen(@listen_params.merge(:xmlrpc_handlers => [:status, :master]))
end
+ end
end
describe "Puppet::Network::HTTP::Mongrel", "when turning off listening" do
- confine "Mongrel is not available" => Puppet.features.mongrel?
-
- before do
- @mock_mongrel = mock('mongrel httpserver')
- @mock_mongrel.stubs(:run)
- @mock_mongrel.stubs(:register)
- Mongrel::HttpServer.stubs(:new).returns(@mock_mongrel)
- @server = Puppet::Network::HTTP::Mongrel.new
- @listen_params = { :address => "127.0.0.1", :port => 31337, :handlers => [ :node, :catalog ], :protocols => [ :rest ] }
- end
-
- it "should fail unless listening" do
- Proc.new { @server.unlisten }.should raise_error(RuntimeError)
- end
-
- it "should order mongrel server to stop" do
- @server.listen(@listen_params)
- @mock_mongrel.expects(:stop)
- @server.unlisten
- end
-
- it "should not be listening" do
- @server.listen(@listen_params)
- @mock_mongrel.stubs(:stop)
- @server.unlisten
- @server.should_not be_listening
- end
+ confine "Mongrel is not available" => Puppet.features.mongrel?
+
+ before do
+ @mock_mongrel = mock('mongrel httpserver')
+ @mock_mongrel.stubs(:run)
+ @mock_mongrel.stubs(:register)
+ Mongrel::HttpServer.stubs(:new).returns(@mock_mongrel)
+ @server = Puppet::Network::HTTP::Mongrel.new
+ @listen_params = { :address => "127.0.0.1", :port => 31337, :handlers => [ :node, :catalog ], :protocols => [ :rest ] }
+ end
+
+ it "should fail unless listening" do
+ Proc.new { @server.unlisten }.should raise_error(RuntimeError)
+ end
+
+ it "should order mongrel server to stop" do
+ @server.listen(@listen_params)
+ @mock_mongrel.expects(:stop)
+ @server.unlisten
+ end
+
+ it "should not be listening" do
+ @server.listen(@listen_params)
+ @mock_mongrel.stubs(:stop)
+ @server.unlisten
+ @server.should_not be_listening
+ end
end
diff --git a/spec/unit/network/http/rack/rest_spec.rb b/spec/unit/network/http/rack/rest_spec.rb
index fb4917d..9b3e1e5 100755
--- a/spec/unit/network/http/rack/rest_spec.rb
+++ b/spec/unit/network/http/rack/rest_spec.rb
@@ -5,245 +5,245 @@ require 'puppet/network/http/rack' if Puppet.features.rack?
require 'puppet/network/http/rack/rest'
describe "Puppet::Network::HTTP::RackREST" do
- confine "Rack is not available" => Puppet.features.rack?
+ confine "Rack is not available" => Puppet.features.rack?
- it "should include the Puppet::Network::HTTP::Handler module" do
- Puppet::Network::HTTP::RackREST.ancestors.should be_include(Puppet::Network::HTTP::Handler)
+ it "should include the Puppet::Network::HTTP::Handler module" do
+ Puppet::Network::HTTP::RackREST.ancestors.should be_include(Puppet::Network::HTTP::Handler)
+ end
+
+ describe "when initializing" do
+ it "should call the Handler's initialization hook with its provided arguments" do
+ Puppet::Network::HTTP::RackREST.any_instance.expects(:initialize_for_puppet).with(:server => "my", :handler => "arguments")
+ Puppet::Network::HTTP::RackREST.new(:server => "my", :handler => "arguments")
end
+ end
- describe "when initializing" do
- it "should call the Handler's initialization hook with its provided arguments" do
- Puppet::Network::HTTP::RackREST.any_instance.expects(:initialize_for_puppet).with(:server => "my", :handler => "arguments")
- Puppet::Network::HTTP::RackREST.new(:server => "my", :handler => "arguments")
- end
+ describe "when serving a request" do
+ before :all do
+ @model_class = stub('indirected model class')
+ Puppet::Indirector::Indirection.stubs(:model).with(:foo).returns(@model_class)
+ @handler = Puppet::Network::HTTP::RackREST.new(:handler => :foo)
end
- describe "when serving a request" do
- before :all do
- @model_class = stub('indirected model class')
- Puppet::Indirector::Indirection.stubs(:model).with(:foo).returns(@model_class)
- @handler = Puppet::Network::HTTP::RackREST.new(:handler => :foo)
- end
+ before :each do
+ @response = Rack::Response.new
+ end
+
+ def mk_req(uri, opts = {})
+ env = Rack::MockRequest.env_for(uri, opts)
+ Rack::Request.new(env)
+ end
+
+ describe "and using the HTTP Handler interface" do
+ it "should return the HTTP_ACCEPT parameter as the accept header" do
+ req = mk_req('/', 'HTTP_ACCEPT' => 'myaccept')
+ @handler.accept_header(req).should == "myaccept"
+ end
+
+ it "should return the CONTENT_TYPE parameter as the content type header" do
+ req = mk_req('/', 'CONTENT_TYPE' => 'mycontent')
+ @handler.content_type_header(req).should == "mycontent"
+ end
+
+ it "should use the REQUEST_METHOD as the http method" do
+ req = mk_req('/', :method => 'MYMETHOD')
+ @handler.http_method(req).should == "MYMETHOD"
+ end
+
+ it "should return the request path as the path" do
+ req = mk_req('/foo/bar')
+ @handler.path(req).should == "/foo/bar"
+ end
+
+ it "should return the request body as the body" do
+ req = mk_req('/foo/bar', :input => 'mybody')
+ @handler.body(req).should == "mybody"
+ end
+
+ it "should set the response's content-type header when setting the content type" do
+ @header = mock 'header'
+ @response.expects(:header).returns @header
+ @header.expects(:[]=).with('Content-Type', "mytype")
+ @handler.set_content_type(@response, "mytype")
+ end
+
+ it "should set the status and write the body when setting the response for a request" do
+ @response.expects(:status=).with(400)
+ @response.expects(:write).with("mybody")
+
+ @handler.set_response(@response, "mybody", 400)
+ end
+
+ describe "when result is a File" do
before :each do
- @response = Rack::Response.new
+ stat = stub 'stat', :size => 100
+ @file = stub 'file', :stat => stat, :path => "/tmp/path"
+ @file.stubs(:is_a?).with(File).returns(true)
end
- def mk_req(uri, opts = {})
- env = Rack::MockRequest.env_for(uri, opts)
- Rack::Request.new(env)
- end
+ it "should set the Content-Length header" do
+ @response.expects(:[]=).with("Content-Length", 100)
- describe "and using the HTTP Handler interface" do
- it "should return the HTTP_ACCEPT parameter as the accept header" do
- req = mk_req('/', 'HTTP_ACCEPT' => 'myaccept')
- @handler.accept_header(req).should == "myaccept"
- end
-
- it "should return the CONTENT_TYPE parameter as the content type header" do
- req = mk_req('/', 'CONTENT_TYPE' => 'mycontent')
- @handler.content_type_header(req).should == "mycontent"
- end
-
- it "should use the REQUEST_METHOD as the http method" do
- req = mk_req('/', :method => 'MYMETHOD')
- @handler.http_method(req).should == "MYMETHOD"
- end
-
- it "should return the request path as the path" do
- req = mk_req('/foo/bar')
- @handler.path(req).should == "/foo/bar"
- end
-
- it "should return the request body as the body" do
- req = mk_req('/foo/bar', :input => 'mybody')
- @handler.body(req).should == "mybody"
- end
-
- it "should set the response's content-type header when setting the content type" do
- @header = mock 'header'
- @response.expects(:header).returns @header
- @header.expects(:[]=).with('Content-Type', "mytype")
-
- @handler.set_content_type(@response, "mytype")
- end
-
- it "should set the status and write the body when setting the response for a request" do
- @response.expects(:status=).with(400)
- @response.expects(:write).with("mybody")
-
- @handler.set_response(@response, "mybody", 400)
- end
-
- describe "when result is a File" do
- before :each do
- stat = stub 'stat', :size => 100
- @file = stub 'file', :stat => stat, :path => "/tmp/path"
- @file.stubs(:is_a?).with(File).returns(true)
- end
-
- it "should set the Content-Length header" do
- @response.expects(:[]=).with("Content-Length", 100)
-
- @handler.set_response(@response, @file, 200)
- end
-
- it "should return a RackFile adapter as body" do
- @response.expects(:body=).with { |val| val.is_a?(Puppet::Network::HTTP::RackREST::RackFile) }
-
- @handler.set_response(@response, @file, 200)
- end
- end
+ @handler.set_response(@response, @file, 200)
end
- describe "and determining the request parameters" do
- it "should include the HTTP request parameters, with the keys as symbols" do
- req = mk_req('/?foo=baz&bar=xyzzy')
- result = @handler.params(req)
- result[:foo].should == "baz"
- result[:bar].should == "xyzzy"
- end
-
- it "should CGI-decode the HTTP parameters" do
- encoding = CGI.escape("foo bar")
- req = mk_req("/?foo=#{encoding}")
- result = @handler.params(req)
- result[:foo].should == "foo bar"
- end
-
- it "should convert the string 'true' to the boolean" do
- req = mk_req("/?foo=true")
- result = @handler.params(req)
- result[:foo].should be_true
- end
-
- it "should convert the string 'false' to the boolean" do
- req = mk_req("/?foo=false")
- result = @handler.params(req)
- result[:foo].should be_false
- end
-
- it "should convert integer arguments to Integers" do
- req = mk_req("/?foo=15")
- result = @handler.params(req)
- result[:foo].should == 15
- end
-
- it "should convert floating point arguments to Floats" do
- req = mk_req("/?foo=1.5")
- result = @handler.params(req)
- result[:foo].should == 1.5
- end
-
- it "should YAML-load and CGI-decode values that are YAML-encoded" do
- escaping = CGI.escape(YAML.dump(%w{one two}))
- req = mk_req("/?foo=#{escaping}")
- result = @handler.params(req)
- result[:foo].should == %w{one two}
- end
-
- it "should not allow the client to set the node via the query string" do
- req = mk_req("/?node=foo")
- @handler.params(req)[:node].should be_nil
- end
-
- it "should not allow the client to set the IP address via the query string" do
- req = mk_req("/?ip=foo")
- @handler.params(req)[:ip].should be_nil
- end
-
- it "should pass the client's ip address to model find" do
- req = mk_req("/", 'REMOTE_ADDR' => 'ipaddress')
- @handler.params(req)[:ip].should == "ipaddress"
- end
-
- it "should set 'authenticated' to false if no certificate is present" do
- req = mk_req('/')
- @handler.params(req)[:authenticated].should be_false
- end
- end
+ it "should return a RackFile adapter as body" do
+ @response.expects(:body=).with { |val| val.is_a?(Puppet::Network::HTTP::RackREST::RackFile) }
- describe "with pre-validated certificates" do
-
- it "should use the :ssl_client_header to determine the parameter when looking for the certificate" do
- Puppet.settings.stubs(:value).returns "eh"
- Puppet.settings.expects(:value).with(:ssl_client_header).returns "myheader"
- req = mk_req('/', "myheader" => "/CN=host.domain.com")
- @handler.params(req)
- end
-
- it "should retrieve the hostname by matching the certificate parameter" do
- Puppet.settings.stubs(:value).returns "eh"
- Puppet.settings.expects(:value).with(:ssl_client_header).returns "myheader"
- req = mk_req('/', "myheader" => "/CN=host.domain.com")
- @handler.params(req)[:node].should == "host.domain.com"
- end
-
- it "should use the :ssl_client_header to determine the parameter for checking whether the host certificate is valid" do
- Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader"
- Puppet.settings.expects(:value).with(:ssl_client_verify_header).returns "myheader"
- req = mk_req('/', "myheader" => "SUCCESS", "certheader" => "/CN=host.domain.com")
- @handler.params(req)
- end
-
- it "should consider the host authenticated if the validity parameter contains 'SUCCESS'" do
- Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader"
- Puppet.settings.stubs(:value).with(:ssl_client_verify_header).returns "myheader"
- req = mk_req('/', "myheader" => "SUCCESS", "certheader" => "/CN=host.domain.com")
- @handler.params(req)[:authenticated].should be_true
- end
-
- it "should consider the host unauthenticated if the validity parameter does not contain 'SUCCESS'" do
- Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader"
- Puppet.settings.stubs(:value).with(:ssl_client_verify_header).returns "myheader"
- req = mk_req('/', "myheader" => "whatever", "certheader" => "/CN=host.domain.com")
- @handler.params(req)[:authenticated].should be_false
- end
-
- it "should consider the host unauthenticated if no certificate information is present" do
- Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader"
- Puppet.settings.stubs(:value).with(:ssl_client_verify_header).returns "myheader"
- req = mk_req('/', "myheader" => nil, "certheader" => "/CN=host.domain.com")
- @handler.params(req)[:authenticated].should be_false
- end
-
- it "should resolve the node name with an ip address look-up if no certificate is present" do
- Puppet.settings.stubs(:value).returns "eh"
- Puppet.settings.expects(:value).with(:ssl_client_header).returns "myheader"
- req = mk_req('/', "myheader" => nil)
- @handler.expects(:resolve_node).returns("host.domain.com")
- @handler.params(req)[:node].should == "host.domain.com"
- end
+ @handler.set_response(@response, @file, 200)
end
+ end
end
-end
-describe Puppet::Network::HTTP::RackREST::RackFile do
- before(:each) do
- stat = stub 'stat', :size => 100
- @file = stub 'file', :stat => stat, :path => "/tmp/path"
- @rackfile = Puppet::Network::HTTP::RackREST::RackFile.new(@file)
+ describe "and determining the request parameters" do
+ it "should include the HTTP request parameters, with the keys as symbols" do
+ req = mk_req('/?foo=baz&bar=xyzzy')
+ result = @handler.params(req)
+ result[:foo].should == "baz"
+ result[:bar].should == "xyzzy"
+ end
+
+ it "should CGI-decode the HTTP parameters" do
+ encoding = CGI.escape("foo bar")
+ req = mk_req("/?foo=#{encoding}")
+ result = @handler.params(req)
+ result[:foo].should == "foo bar"
+ end
+
+ it "should convert the string 'true' to the boolean" do
+ req = mk_req("/?foo=true")
+ result = @handler.params(req)
+ result[:foo].should be_true
+ end
+
+ it "should convert the string 'false' to the boolean" do
+ req = mk_req("/?foo=false")
+ result = @handler.params(req)
+ result[:foo].should be_false
+ end
+
+ it "should convert integer arguments to Integers" do
+ req = mk_req("/?foo=15")
+ result = @handler.params(req)
+ result[:foo].should == 15
+ end
+
+ it "should convert floating point arguments to Floats" do
+ req = mk_req("/?foo=1.5")
+ result = @handler.params(req)
+ result[:foo].should == 1.5
+ end
+
+ it "should YAML-load and CGI-decode values that are YAML-encoded" do
+ escaping = CGI.escape(YAML.dump(%w{one two}))
+ req = mk_req("/?foo=#{escaping}")
+ result = @handler.params(req)
+ result[:foo].should == %w{one two}
+ end
+
+ it "should not allow the client to set the node via the query string" do
+ req = mk_req("/?node=foo")
+ @handler.params(req)[:node].should be_nil
+ end
+
+ it "should not allow the client to set the IP address via the query string" do
+ req = mk_req("/?ip=foo")
+ @handler.params(req)[:ip].should be_nil
+ end
+
+ it "should pass the client's ip address to model find" do
+ req = mk_req("/", 'REMOTE_ADDR' => 'ipaddress')
+ @handler.params(req)[:ip].should == "ipaddress"
+ end
+
+ it "should set 'authenticated' to false if no certificate is present" do
+ req = mk_req('/')
+ @handler.params(req)[:authenticated].should be_false
+ end
end
- it "should have an each method" do
- @rackfile.should be_respond_to(:each)
+ describe "with pre-validated certificates" do
+
+ it "should use the :ssl_client_header to determine the parameter when looking for the certificate" do
+ Puppet.settings.stubs(:value).returns "eh"
+ Puppet.settings.expects(:value).with(:ssl_client_header).returns "myheader"
+ req = mk_req('/', "myheader" => "/CN=host.domain.com")
+ @handler.params(req)
+ end
+
+ it "should retrieve the hostname by matching the certificate parameter" do
+ Puppet.settings.stubs(:value).returns "eh"
+ Puppet.settings.expects(:value).with(:ssl_client_header).returns "myheader"
+ req = mk_req('/', "myheader" => "/CN=host.domain.com")
+ @handler.params(req)[:node].should == "host.domain.com"
+ end
+
+ it "should use the :ssl_client_header to determine the parameter for checking whether the host certificate is valid" do
+ Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader"
+ Puppet.settings.expects(:value).with(:ssl_client_verify_header).returns "myheader"
+ req = mk_req('/', "myheader" => "SUCCESS", "certheader" => "/CN=host.domain.com")
+ @handler.params(req)
+ end
+
+ it "should consider the host authenticated if the validity parameter contains 'SUCCESS'" do
+ Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader"
+ Puppet.settings.stubs(:value).with(:ssl_client_verify_header).returns "myheader"
+ req = mk_req('/', "myheader" => "SUCCESS", "certheader" => "/CN=host.domain.com")
+ @handler.params(req)[:authenticated].should be_true
+ end
+
+ it "should consider the host unauthenticated if the validity parameter does not contain 'SUCCESS'" do
+ Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader"
+ Puppet.settings.stubs(:value).with(:ssl_client_verify_header).returns "myheader"
+ req = mk_req('/', "myheader" => "whatever", "certheader" => "/CN=host.domain.com")
+ @handler.params(req)[:authenticated].should be_false
+ end
+
+ it "should consider the host unauthenticated if no certificate information is present" do
+ Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader"
+ Puppet.settings.stubs(:value).with(:ssl_client_verify_header).returns "myheader"
+ req = mk_req('/', "myheader" => nil, "certheader" => "/CN=host.domain.com")
+ @handler.params(req)[:authenticated].should be_false
+ end
+
+ it "should resolve the node name with an ip address look-up if no certificate is present" do
+ Puppet.settings.stubs(:value).returns "eh"
+ Puppet.settings.expects(:value).with(:ssl_client_header).returns "myheader"
+ req = mk_req('/', "myheader" => nil)
+ @handler.expects(:resolve_node).returns("host.domain.com")
+ @handler.params(req)[:node].should == "host.domain.com"
+ end
end
+ end
+end
- it "should yield file chunks by chunks" do
- @file.expects(:read).times(3).with(8192).returns("1", "2", nil)
- i = 1
- @rackfile.each do |chunk|
- chunk.to_i.should == i
- i += 1
- end
+describe Puppet::Network::HTTP::RackREST::RackFile do
+ before(:each) do
+ stat = stub 'stat', :size => 100
+ @file = stub 'file', :stat => stat, :path => "/tmp/path"
+ @rackfile = Puppet::Network::HTTP::RackREST::RackFile.new(@file)
+ end
+
+ it "should have an each method" do
+ @rackfile.should be_respond_to(:each)
+ end
+
+ it "should yield file chunks by chunks" do
+ @file.expects(:read).times(3).with(8192).returns("1", "2", nil)
+ i = 1
+ @rackfile.each do |chunk|
+ chunk.to_i.should == i
+ i += 1
end
+ end
- it "should have a close method" do
- @rackfile.should be_respond_to(:close)
- end
+ it "should have a close method" do
+ @rackfile.should be_respond_to(:close)
+ end
- it "should delegate close to File close" do
- @file.expects(:close)
- @rackfile.close
- end
+ it "should delegate close to File close" do
+ @file.expects(:close)
+ @rackfile.close
+ end
end
\ No newline at end of file
diff --git a/spec/unit/network/http/rack/xmlrpc_spec.rb b/spec/unit/network/http/rack/xmlrpc_spec.rb
index f91f483..63ba28b 100755
--- a/spec/unit/network/http/rack/xmlrpc_spec.rb
+++ b/spec/unit/network/http/rack/xmlrpc_spec.rb
@@ -5,153 +5,153 @@ require 'puppet/network/http/rack' if Puppet.features.rack?
require 'puppet/network/http/rack/xmlrpc' if Puppet.features.rack?
describe "Puppet::Network::HTTP::RackXMLRPC" do
- confine "Rack is not available" => Puppet.features.rack?
-
- describe "when initializing" do
- it "should create an Puppet::Network::XMLRPCServer" do
- Puppet::Network::XMLRPCServer.expects(:new).returns stub_everything
- Puppet::Network::HTTP::RackXMLRPC.new([])
- end
-
- it "should create each handler" do
- handler = stub_everything 'handler'
- Puppet::Network::XMLRPCServer.any_instance.stubs(:add_handler)
- Puppet::Network::Handler.expects(:handler).returns(handler).times(2)
- Puppet::Network::HTTP::RackXMLRPC.new([:foo, :bar])
- end
-
- it "should add each handler to the XMLRPCserver" do
- handler = stub_everything 'handler'
- Puppet::Network::Handler.stubs(:handler).returns(handler)
- Puppet::Network::XMLRPCServer.any_instance.expects(:add_handler).times(2)
- Puppet::Network::HTTP::RackXMLRPC.new([:foo, :bar])
- end
+ confine "Rack is not available" => Puppet.features.rack?
+
+ describe "when initializing" do
+ it "should create an Puppet::Network::XMLRPCServer" do
+ Puppet::Network::XMLRPCServer.expects(:new).returns stub_everything
+ Puppet::Network::HTTP::RackXMLRPC.new([])
+ end
+
+ it "should create each handler" do
+ handler = stub_everything 'handler'
+ Puppet::Network::XMLRPCServer.any_instance.stubs(:add_handler)
+ Puppet::Network::Handler.expects(:handler).returns(handler).times(2)
+ Puppet::Network::HTTP::RackXMLRPC.new([:foo, :bar])
+ end
+
+ it "should add each handler to the XMLRPCserver" do
+ handler = stub_everything 'handler'
+ Puppet::Network::Handler.stubs(:handler).returns(handler)
+ Puppet::Network::XMLRPCServer.any_instance.expects(:add_handler).times(2)
+ Puppet::Network::HTTP::RackXMLRPC.new([:foo, :bar])
+ end
+ end
+
+ describe "when serving a request" do
+
+ before :each do
+ foo_handler = stub_everything 'foo_handler'
+ Puppet::Network::Handler.stubs(:handler).with(:foo).returns foo_handler
+ Puppet::Network::XMLRPCServer.any_instance.stubs(:add_handler)
+ Puppet::Network::XMLRPCServer.any_instance.stubs(:process).returns('<xml/>')
+ @handler = Puppet::Network::HTTP::RackXMLRPC.new([:foo])
+ end
+
+ before :each do
+ @response = Rack::Response.new
+ end
+
+ def mk_req(opts = {})
+ opts[:method] = 'POST' if !opts[:method]
+ opts['CONTENT_TYPE'] = 'text/xml; foo=bar' if !opts['CONTENT_TYPE']
+ env = Rack::MockRequest.env_for('/RPC2', opts)
+ Rack::Request.new(env)
+ end
+
+ it "should reject non-POST requests" do
+ req = mk_req :method => 'PUT'
+ @handler.process(req, @response)
+ @response.status.should == 405
+ end
+
+ it "should reject non text/xml requests" do
+ req = mk_req 'CONTENT_TYPE' => 'yadda/plain'
+ end
+
+ it "should create a ClientRequest" do
+ cr = Puppet::Network::ClientRequest.new(nil, '127.0.0.1', false)
+ Puppet::Network::ClientRequest.expects(:new).returns cr
+ req = mk_req
+ @handler.process(req, @response)
+ end
+
+ it "should let xmlrpcserver process the request" do
+ Puppet::Network::XMLRPCServer.any_instance.expects(:process).returns('yay')
+ req = mk_req
+ @handler.process(req, @response)
+ end
+
+ it "should report the response as OK" do
+ req = mk_req
+ @handler.process(req, @response)
+ @response.status.should == 200
+ end
+
+ it "should report the response with the correct content type" do
+ req = mk_req
+ @handler.process(req, @response)
+ @response['Content-Type'].should == 'text/xml; charset=utf-8'
+ end
+
+ it "should set 'authenticated' to false if no certificate is present" do
+ req = mk_req
+ Puppet::Network::ClientRequest.expects(:new).with { |node,ip,authenticated| authenticated == false }
+ @handler.process(req, @response)
+ end
+
+ it "should use the client's ip address" do
+ req = mk_req 'REMOTE_ADDR' => 'ipaddress'
+ Puppet::Network::ClientRequest.expects(:new).with { |node,ip,authenticated| ip == 'ipaddress' }
+ @handler.process(req, @response)
end
- describe "when serving a request" do
-
- before :each do
- foo_handler = stub_everything 'foo_handler'
- Puppet::Network::Handler.stubs(:handler).with(:foo).returns foo_handler
- Puppet::Network::XMLRPCServer.any_instance.stubs(:add_handler)
- Puppet::Network::XMLRPCServer.any_instance.stubs(:process).returns('<xml/>')
- @handler = Puppet::Network::HTTP::RackXMLRPC.new([:foo])
- end
-
- before :each do
- @response = Rack::Response.new
- end
-
- def mk_req(opts = {})
- opts[:method] = 'POST' if !opts[:method]
- opts['CONTENT_TYPE'] = 'text/xml; foo=bar' if !opts['CONTENT_TYPE']
- env = Rack::MockRequest.env_for('/RPC2', opts)
- Rack::Request.new(env)
- end
-
- it "should reject non-POST requests" do
- req = mk_req :method => 'PUT'
- @handler.process(req, @response)
- @response.status.should == 405
- end
-
- it "should reject non text/xml requests" do
- req = mk_req 'CONTENT_TYPE' => 'yadda/plain'
- end
-
- it "should create a ClientRequest" do
- cr = Puppet::Network::ClientRequest.new(nil, '127.0.0.1', false)
- Puppet::Network::ClientRequest.expects(:new).returns cr
- req = mk_req
- @handler.process(req, @response)
- end
-
- it "should let xmlrpcserver process the request" do
- Puppet::Network::XMLRPCServer.any_instance.expects(:process).returns('yay')
- req = mk_req
- @handler.process(req, @response)
- end
-
- it "should report the response as OK" do
- req = mk_req
- @handler.process(req, @response)
- @response.status.should == 200
- end
-
- it "should report the response with the correct content type" do
- req = mk_req
- @handler.process(req, @response)
- @response['Content-Type'].should == 'text/xml; charset=utf-8'
- end
-
- it "should set 'authenticated' to false if no certificate is present" do
- req = mk_req
- Puppet::Network::ClientRequest.expects(:new).with { |node,ip,authenticated| authenticated == false }
- @handler.process(req, @response)
- end
-
- it "should use the client's ip address" do
- req = mk_req 'REMOTE_ADDR' => 'ipaddress'
- Puppet::Network::ClientRequest.expects(:new).with { |node,ip,authenticated| ip == 'ipaddress' }
- @handler.process(req, @response)
- end
-
- describe "with pre-validated certificates" do
-
- it "should use the :ssl_client_header to determine the parameter when looking for the certificate" do
- Puppet.settings.stubs(:value).returns "eh"
- Puppet.settings.expects(:value).with(:ssl_client_header).returns "myheader"
- req = mk_req "myheader" => "/CN=host.domain.com"
- @handler.process(req, @response)
- end
-
- it "should retrieve the hostname by matching the certificate parameter" do
- Puppet.settings.stubs(:value).returns "eh"
- Puppet.settings.expects(:value).with(:ssl_client_header).returns "myheader"
- Puppet::Network::ClientRequest.expects(:new).with { |node,ip,authenticated| node == "host.domain.com" }
- req = mk_req "myheader" => "/CN=host.domain.com"
- @handler.process(req, @response)
- end
-
- it "should use the :ssl_client_header to determine the parameter for checking whether the host certificate is valid" do
- Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader"
- Puppet.settings.expects(:value).with(:ssl_client_verify_header).returns "myheader"
- req = mk_req "myheader" => "SUCCESS", "certheader" => "/CN=host.domain.com"
- @handler.process(req, @response)
- end
-
- it "should consider the host authenticated if the validity parameter contains 'SUCCESS'" do
- Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader"
- Puppet.settings.stubs(:value).with(:ssl_client_verify_header).returns "myheader"
- Puppet::Network::ClientRequest.expects(:new).with { |node,ip,authenticated| authenticated == true }
- req = mk_req "myheader" => "SUCCESS", "certheader" => "/CN=host.domain.com"
- @handler.process(req, @response)
- end
-
- it "should consider the host unauthenticated if the validity parameter does not contain 'SUCCESS'" do
- Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader"
- Puppet.settings.stubs(:value).with(:ssl_client_verify_header).returns "myheader"
- Puppet::Network::ClientRequest.expects(:new).with { |node,ip,authenticated| authenticated == false }
- req = mk_req "myheader" => "whatever", "certheader" => "/CN=host.domain.com"
- @handler.process(req, @response)
- end
-
- it "should consider the host unauthenticated if no certificate information is present" do
- Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader"
- Puppet.settings.stubs(:value).with(:ssl_client_verify_header).returns "myheader"
- Puppet::Network::ClientRequest.expects(:new).with { |node,ip,authenticated| authenticated == false }
- req = mk_req "myheader" => nil, "certheader" => "/CN=host.domain.com"
- @handler.process(req, @response)
- end
-
- it "should resolve the node name with an ip address look-up if no certificate is present" do
- Puppet.settings.stubs(:value).returns "eh"
- Puppet.settings.expects(:value).with(:ssl_client_header).returns "myheader"
- Resolv.any_instance.expects(:getname).returns("host.domain.com")
- Puppet::Network::ClientRequest.expects(:new).with { |node,ip,authenticated| node == "host.domain.com" }
- req = mk_req "myheader" => nil
- @handler.process(req, @response)
- end
- end
+ describe "with pre-validated certificates" do
+
+ it "should use the :ssl_client_header to determine the parameter when looking for the certificate" do
+ Puppet.settings.stubs(:value).returns "eh"
+ Puppet.settings.expects(:value).with(:ssl_client_header).returns "myheader"
+ req = mk_req "myheader" => "/CN=host.domain.com"
+ @handler.process(req, @response)
+ end
+
+ it "should retrieve the hostname by matching the certificate parameter" do
+ Puppet.settings.stubs(:value).returns "eh"
+ Puppet.settings.expects(:value).with(:ssl_client_header).returns "myheader"
+ Puppet::Network::ClientRequest.expects(:new).with { |node,ip,authenticated| node == "host.domain.com" }
+ req = mk_req "myheader" => "/CN=host.domain.com"
+ @handler.process(req, @response)
+ end
+
+ it "should use the :ssl_client_header to determine the parameter for checking whether the host certificate is valid" do
+ Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader"
+ Puppet.settings.expects(:value).with(:ssl_client_verify_header).returns "myheader"
+ req = mk_req "myheader" => "SUCCESS", "certheader" => "/CN=host.domain.com"
+ @handler.process(req, @response)
+ end
+
+ it "should consider the host authenticated if the validity parameter contains 'SUCCESS'" do
+ Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader"
+ Puppet.settings.stubs(:value).with(:ssl_client_verify_header).returns "myheader"
+ Puppet::Network::ClientRequest.expects(:new).with { |node,ip,authenticated| authenticated == true }
+ req = mk_req "myheader" => "SUCCESS", "certheader" => "/CN=host.domain.com"
+ @handler.process(req, @response)
+ end
+
+ it "should consider the host unauthenticated if the validity parameter does not contain 'SUCCESS'" do
+ Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader"
+ Puppet.settings.stubs(:value).with(:ssl_client_verify_header).returns "myheader"
+ Puppet::Network::ClientRequest.expects(:new).with { |node,ip,authenticated| authenticated == false }
+ req = mk_req "myheader" => "whatever", "certheader" => "/CN=host.domain.com"
+ @handler.process(req, @response)
+ end
+
+ it "should consider the host unauthenticated if no certificate information is present" do
+ Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader"
+ Puppet.settings.stubs(:value).with(:ssl_client_verify_header).returns "myheader"
+ Puppet::Network::ClientRequest.expects(:new).with { |node,ip,authenticated| authenticated == false }
+ req = mk_req "myheader" => nil, "certheader" => "/CN=host.domain.com"
+ @handler.process(req, @response)
+ end
+
+ it "should resolve the node name with an ip address look-up if no certificate is present" do
+ Puppet.settings.stubs(:value).returns "eh"
+ Puppet.settings.expects(:value).with(:ssl_client_header).returns "myheader"
+ Resolv.any_instance.expects(:getname).returns("host.domain.com")
+ Puppet::Network::ClientRequest.expects(:new).with { |node,ip,authenticated| node == "host.domain.com" }
+ req = mk_req "myheader" => nil
+ @handler.process(req, @response)
+ end
end
+ end
end
diff --git a/spec/unit/network/http/rack_spec.rb b/spec/unit/network/http/rack_spec.rb
index cd2961a..df42a1f 100755
--- a/spec/unit/network/http/rack_spec.rb
+++ b/spec/unit/network/http/rack_spec.rb
@@ -4,99 +4,99 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/network/http/rack' if Puppet.features.rack?
describe "Puppet::Network::HTTP::Rack" do
- confine "Rack is not available" => Puppet.features.rack?
+ confine "Rack is not available" => Puppet.features.rack?
- describe "while initializing" do
+ describe "while initializing" do
- it "should require a protocol specification" do
- Proc.new { Puppet::Network::HTTP::Rack.new({}) }.should raise_error(ArgumentError)
- end
-
- it "should not accept imaginary protocols" do
- Proc.new { Puppet::Network::HTTP::Rack.new({:protocols => [:foo]}) }.should raise_error(ArgumentError)
- end
+ it "should require a protocol specification" do
+ Proc.new { Puppet::Network::HTTP::Rack.new({}) }.should raise_error(ArgumentError)
+ end
- it "should accept the REST protocol" do
- Proc.new { Puppet::Network::HTTP::Rack.new({:protocols => [:rest]}) }.should_not raise_error(ArgumentError)
- end
+ it "should not accept imaginary protocols" do
+ Proc.new { Puppet::Network::HTTP::Rack.new({:protocols => [:foo]}) }.should raise_error(ArgumentError)
+ end
- it "should create a RackREST instance" do
- Puppet::Network::HTTP::RackREST.expects(:new)
- Puppet::Network::HTTP::Rack.new({:protocols => [:rest]})
- end
+ it "should accept the REST protocol" do
+ Proc.new { Puppet::Network::HTTP::Rack.new({:protocols => [:rest]}) }.should_not raise_error(ArgumentError)
+ end
- describe "with XMLRPC enabled" do
+ it "should create a RackREST instance" do
+ Puppet::Network::HTTP::RackREST.expects(:new)
+ Puppet::Network::HTTP::Rack.new({:protocols => [:rest]})
+ end
- it "should require XMLRPC handlers" do
- Proc.new { Puppet::Network::HTTP::Rack.new({:protocols => [:xmlrpc]}) }.should raise_error(ArgumentError)
- end
+ describe "with XMLRPC enabled" do
- it "should create a RackXMLRPC instance" do
- Puppet::Network::HTTP::RackXMLRPC.expects(:new)
- Puppet::Network::HTTP::Rack.new({:protocols => [:xmlrpc], :xmlrpc_handlers => [:Status]})
- end
+ it "should require XMLRPC handlers" do
+ Proc.new { Puppet::Network::HTTP::Rack.new({:protocols => [:xmlrpc]}) }.should raise_error(ArgumentError)
+ end
- end
+ it "should create a RackXMLRPC instance" do
+ Puppet::Network::HTTP::RackXMLRPC.expects(:new)
+ Puppet::Network::HTTP::Rack.new({:protocols => [:xmlrpc], :xmlrpc_handlers => [:Status]})
+ end
end
- describe "when called" do
+ end
- before :all do
- @app = Puppet::Network::HTTP::Rack.new({:protocols => [:rest]})
- # let's use Rack::Lint to verify that we're OK with the rack specification
- @linted = Rack::Lint.new(@app)
- end
+ describe "when called" do
- before :each do
- @env = Rack::MockRequest.env_for('/')
- end
+ before :all do
+ @app = Puppet::Network::HTTP::Rack.new({:protocols => [:rest]})
+ # let's use Rack::Lint to verify that we're OK with the rack specification
+ @linted = Rack::Lint.new(@app)
+ end
- it "should create a Request object" do
- request = Rack::Request.new(@env)
- Rack::Request.expects(:new).returns request
- @linted.call(@env)
- end
+ before :each do
+ @env = Rack::MockRequest.env_for('/')
+ end
- it "should create a Response object" do
- Rack::Response.expects(:new).returns stub_everything
- @app.call(@env) # can't lint when Rack::Response is a stub
- end
+ it "should create a Request object" do
+ request = Rack::Request.new(@env)
+ Rack::Request.expects(:new).returns request
+ @linted.call(@env)
+ end
- it "should let RackREST process the request" do
- Puppet::Network::HTTP::RackREST.any_instance.expects(:process).once
- @linted.call(@env)
- end
+ it "should create a Response object" do
+ Rack::Response.expects(:new).returns stub_everything
+ @app.call(@env) # can't lint when Rack::Response is a stub
+ end
- it "should catch unhandled exceptions from RackREST" do
- Puppet::Network::HTTP::RackREST.any_instance.expects(:process).raises(ArgumentError, 'test error')
- Proc.new { @linted.call(@env) }.should_not raise_error
- end
+ it "should let RackREST process the request" do
+ Puppet::Network::HTTP::RackREST.any_instance.expects(:process).once
+ @linted.call(@env)
+ end
- it "should finish() the Response" do
- Rack::Response.any_instance.expects(:finish).once
- @app.call(@env) # can't lint when finish is a stub
- end
+ it "should catch unhandled exceptions from RackREST" do
+ Puppet::Network::HTTP::RackREST.any_instance.expects(:process).raises(ArgumentError, 'test error')
+ Proc.new { @linted.call(@env) }.should_not raise_error
+ end
+ it "should finish() the Response" do
+ Rack::Response.any_instance.expects(:finish).once
+ @app.call(@env) # can't lint when finish is a stub
end
- describe "when serving XMLRPC" do
+ end
- before :all do
- @app = Puppet::Network::HTTP::Rack.new({:protocols => [:rest, :xmlrpc], :xmlrpc_handlers => [:Status]})
- @linted = Rack::Lint.new(@app)
- end
+ describe "when serving XMLRPC" do
- before :each do
- @env = Rack::MockRequest.env_for('/RPC2', :method => 'POST')
- end
+ before :all do
+ @app = Puppet::Network::HTTP::Rack.new({:protocols => [:rest, :xmlrpc], :xmlrpc_handlers => [:Status]})
+ @linted = Rack::Lint.new(@app)
+ end
- it "should use RackXMLRPC to serve /RPC2 requests" do
- Puppet::Network::HTTP::RackXMLRPC.any_instance.expects(:process).once
- @linted.call(@env)
- end
+ before :each do
+ @env = Rack::MockRequest.env_for('/RPC2', :method => 'POST')
+ end
+ it "should use RackXMLRPC to serve /RPC2 requests" do
+ Puppet::Network::HTTP::RackXMLRPC.any_instance.expects(:process).once
+ @linted.call(@env)
end
+ end
+
end
diff --git a/spec/unit/network/http/webrick/rest_spec.rb b/spec/unit/network/http/webrick/rest_spec.rb
index f726fd9..aa2b931 100755
--- a/spec/unit/network/http/webrick/rest_spec.rb
+++ b/spec/unit/network/http/webrick/rest_spec.rb
@@ -5,176 +5,176 @@ require 'puppet/network/http'
require 'puppet/network/http/webrick/rest'
describe Puppet::Network::HTTP::WEBrickREST do
- it "should include the Puppet::Network::HTTP::Handler module" do
- Puppet::Network::HTTP::WEBrickREST.ancestors.should be_include(Puppet::Network::HTTP::Handler)
+ it "should include the Puppet::Network::HTTP::Handler module" do
+ Puppet::Network::HTTP::WEBrickREST.ancestors.should be_include(Puppet::Network::HTTP::Handler)
+ end
+
+ describe "when initializing" do
+ it "should call the Handler's initialization hook with its provided arguments as the server and handler" do
+ Puppet::Network::HTTP::WEBrickREST.any_instance.expects(:initialize_for_puppet).with(:server => "my", :handler => "arguments")
+ Puppet::Network::HTTP::WEBrickREST.new("my", "arguments")
+ end
+ end
+
+ describe "when receiving a request" do
+ before do
+ @request = stub('webrick http request', :query => {}, :peeraddr => %w{eh boo host ip}, :client_cert => nil)
+ @response = stub('webrick http response', :status= => true, :body= => true)
+ @model_class = stub('indirected model class')
+ @webrick = stub('webrick http server', :mount => true, :[] => {})
+ Puppet::Indirector::Indirection.stubs(:model).with(:foo).returns(@model_class)
+ @handler = Puppet::Network::HTTP::WEBrickREST.new(@webrick, :foo)
end
- describe "when initializing" do
- it "should call the Handler's initialization hook with its provided arguments as the server and handler" do
- Puppet::Network::HTTP::WEBrickREST.any_instance.expects(:initialize_for_puppet).with(:server => "my", :handler => "arguments")
- Puppet::Network::HTTP::WEBrickREST.new("my", "arguments")
- end
+ it "should delegate its :service method to its :process method" do
+ @handler.expects(:process).with(@request, @response).returns "stuff"
+ @handler.service(@request, @response).should == "stuff"
end
- describe "when receiving a request" do
- before do
- @request = stub('webrick http request', :query => {}, :peeraddr => %w{eh boo host ip}, :client_cert => nil)
- @response = stub('webrick http response', :status= => true, :body= => true)
- @model_class = stub('indirected model class')
- @webrick = stub('webrick http server', :mount => true, :[] => {})
- Puppet::Indirector::Indirection.stubs(:model).with(:foo).returns(@model_class)
- @handler = Puppet::Network::HTTP::WEBrickREST.new(@webrick, :foo)
+ describe "when using the Handler interface" do
+ it "should use the 'accept' request parameter as the Accept header" do
+ @request.expects(:[]).with("accept").returns "foobar"
+ @handler.accept_header(@request).should == "foobar"
+ end
+
+ it "should use the 'content-type' request header as the Content-Type header" do
+ @request.expects(:[]).with("content-type").returns "foobar"
+ @handler.content_type_header(@request).should == "foobar"
+ end
+
+ it "should use the request method as the http method" do
+ @request.expects(:request_method).returns "FOO"
+ @handler.http_method(@request).should == "FOO"
+ end
+
+ it "should return the request path as the path" do
+ @request.expects(:path).returns "/foo/bar"
+ @handler.path(@request).should == "/foo/bar"
+ end
+
+ it "should return the request body as the body" do
+ @request.expects(:body).returns "my body"
+ @handler.body(@request).should == "my body"
+ end
+
+ it "should set the response's 'content-type' header when setting the content type" do
+ @response.expects(:[]=).with("content-type", "text/html")
+ @handler.set_content_type(@response, "text/html")
+ end
+
+ it "should set the status and body on the response when setting the response for a successful query" do
+ @response.expects(:status=).with 200
+ @response.expects(:body=).with "mybody"
+
+ @handler.set_response(@response, "mybody", 200)
+ end
+
+ describe "when the result is a File" do
+ before(:each) do
+ stat = stub 'stat', :size => 100
+ @file = stub 'file', :stat => stat, :path => "/tmp/path"
+ @file.stubs(:is_a?).with(File).returns(true)
end
- it "should delegate its :service method to its :process method" do
- @handler.expects(:process).with(@request, @response).returns "stuff"
- @handler.service(@request, @response).should == "stuff"
- end
+ it "should serve it" do
+ @response.stubs(:[]=)
- describe "when using the Handler interface" do
- it "should use the 'accept' request parameter as the Accept header" do
- @request.expects(:[]).with("accept").returns "foobar"
- @handler.accept_header(@request).should == "foobar"
- end
-
- it "should use the 'content-type' request header as the Content-Type header" do
- @request.expects(:[]).with("content-type").returns "foobar"
- @handler.content_type_header(@request).should == "foobar"
- end
-
- it "should use the request method as the http method" do
- @request.expects(:request_method).returns "FOO"
- @handler.http_method(@request).should == "FOO"
- end
-
- it "should return the request path as the path" do
- @request.expects(:path).returns "/foo/bar"
- @handler.path(@request).should == "/foo/bar"
- end
-
- it "should return the request body as the body" do
- @request.expects(:body).returns "my body"
- @handler.body(@request).should == "my body"
- end
-
- it "should set the response's 'content-type' header when setting the content type" do
- @response.expects(:[]=).with("content-type", "text/html")
- @handler.set_content_type(@response, "text/html")
- end
-
- it "should set the status and body on the response when setting the response for a successful query" do
- @response.expects(:status=).with 200
- @response.expects(:body=).with "mybody"
-
- @handler.set_response(@response, "mybody", 200)
- end
-
- describe "when the result is a File" do
- before(:each) do
- stat = stub 'stat', :size => 100
- @file = stub 'file', :stat => stat, :path => "/tmp/path"
- @file.stubs(:is_a?).with(File).returns(true)
- end
-
- it "should serve it" do
- @response.stubs(:[]=)
-
- @response.expects(:status=).with 200
- @response.expects(:body=).with @file
-
- @handler.set_response(@response, @file, 200)
- end
-
- it "should set the Content-Length header" do
- @response.expects(:[]=).with('content-length', 100)
-
- @handler.set_response(@response, @file, 200)
- end
- end
-
- it "should set the status and message on the response when setting the response for a failed query" do
- @response.expects(:status=).with 400
- @response.expects(:reason_phrase=).with "mybody"
-
- @handler.set_response(@response, "mybody", 400)
- end
+ @response.expects(:status=).with 200
+ @response.expects(:body=).with @file
+
+ @handler.set_response(@response, @file, 200)
end
- describe "and determining the request parameters" do
- it "should include the HTTP request parameters, with the keys as symbols" do
- @request.stubs(:query).returns("foo" => "baz", "bar" => "xyzzy")
- result = @handler.params(@request)
- result[:foo].should == "baz"
- result[:bar].should == "xyzzy"
- end
-
- it "should CGI-decode the HTTP parameters" do
- encoding = CGI.escape("foo bar")
- @request.expects(:query).returns('foo' => encoding)
- result = @handler.params(@request)
- result[:foo].should == "foo bar"
- end
-
- it "should convert the string 'true' to the boolean" do
- @request.expects(:query).returns('foo' => "true")
- result = @handler.params(@request)
- result[:foo].should be_true
- end
-
- it "should convert the string 'false' to the boolean" do
- @request.expects(:query).returns('foo' => "false")
- result = @handler.params(@request)
- result[:foo].should be_false
- end
-
- it "should YAML-load and CGI-decode values that are YAML-encoded" do
- escaping = CGI.escape(YAML.dump(%w{one two}))
- @request.expects(:query).returns('foo' => escaping)
- result = @handler.params(@request)
- result[:foo].should == %w{one two}
- end
-
- it "should not allow clients to set the node via the request parameters" do
- @request.stubs(:query).returns("node" => "foo")
- @handler.stubs(:resolve_node)
-
- @handler.params(@request)[:node].should be_nil
- end
-
- it "should not allow clients to set the IP via the request parameters" do
- @request.stubs(:query).returns("ip" => "foo")
- @handler.params(@request)[:ip].should_not == "foo"
- end
-
- it "should pass the client's ip address to model find" do
- @request.stubs(:peeraddr).returns(%w{noidea dunno hostname ipaddress})
- @handler.params(@request)[:ip].should == "ipaddress"
- end
-
- it "should set 'authenticated' to true if a certificate is present" do
- cert = stub 'cert', :subject => [%w{CN host.domain.com}]
- @request.stubs(:client_cert).returns cert
- @handler.params(@request)[:authenticated].should be_true
- end
-
- it "should set 'authenticated' to false if no certificate is present" do
- @request.stubs(:client_cert).returns nil
- @handler.params(@request)[:authenticated].should be_false
- end
-
- it "should pass the client's certificate name to model method if a certificate is present" do
- cert = stub 'cert', :subject => [%w{CN host.domain.com}]
- @request.stubs(:client_cert).returns cert
- @handler.params(@request)[:node].should == "host.domain.com"
- end
-
- it "should resolve the node name with an ip address look-up if no certificate is present" do
- @request.stubs(:client_cert).returns nil
-
- @handler.expects(:resolve_node).returns(:resolved_node)
-
- @handler.params(@request)[:node].should == :resolved_node
- end
+ it "should set the Content-Length header" do
+ @response.expects(:[]=).with('content-length', 100)
+
+ @handler.set_response(@response, @file, 200)
end
+ end
+
+ it "should set the status and message on the response when setting the response for a failed query" do
+ @response.expects(:status=).with 400
+ @response.expects(:reason_phrase=).with "mybody"
+
+ @handler.set_response(@response, "mybody", 400)
+ end
+ end
+
+ describe "and determining the request parameters" do
+ it "should include the HTTP request parameters, with the keys as symbols" do
+ @request.stubs(:query).returns("foo" => "baz", "bar" => "xyzzy")
+ result = @handler.params(@request)
+ result[:foo].should == "baz"
+ result[:bar].should == "xyzzy"
+ end
+
+ it "should CGI-decode the HTTP parameters" do
+ encoding = CGI.escape("foo bar")
+ @request.expects(:query).returns('foo' => encoding)
+ result = @handler.params(@request)
+ result[:foo].should == "foo bar"
+ end
+
+ it "should convert the string 'true' to the boolean" do
+ @request.expects(:query).returns('foo' => "true")
+ result = @handler.params(@request)
+ result[:foo].should be_true
+ end
+
+ it "should convert the string 'false' to the boolean" do
+ @request.expects(:query).returns('foo' => "false")
+ result = @handler.params(@request)
+ result[:foo].should be_false
+ end
+
+ it "should YAML-load and CGI-decode values that are YAML-encoded" do
+ escaping = CGI.escape(YAML.dump(%w{one two}))
+ @request.expects(:query).returns('foo' => escaping)
+ result = @handler.params(@request)
+ result[:foo].should == %w{one two}
+ end
+
+ it "should not allow clients to set the node via the request parameters" do
+ @request.stubs(:query).returns("node" => "foo")
+ @handler.stubs(:resolve_node)
+
+ @handler.params(@request)[:node].should be_nil
+ end
+
+ it "should not allow clients to set the IP via the request parameters" do
+ @request.stubs(:query).returns("ip" => "foo")
+ @handler.params(@request)[:ip].should_not == "foo"
+ end
+
+ it "should pass the client's ip address to model find" do
+ @request.stubs(:peeraddr).returns(%w{noidea dunno hostname ipaddress})
+ @handler.params(@request)[:ip].should == "ipaddress"
+ end
+
+ it "should set 'authenticated' to true if a certificate is present" do
+ cert = stub 'cert', :subject => [%w{CN host.domain.com}]
+ @request.stubs(:client_cert).returns cert
+ @handler.params(@request)[:authenticated].should be_true
+ end
+
+ it "should set 'authenticated' to false if no certificate is present" do
+ @request.stubs(:client_cert).returns nil
+ @handler.params(@request)[:authenticated].should be_false
+ end
+
+ it "should pass the client's certificate name to model method if a certificate is present" do
+ cert = stub 'cert', :subject => [%w{CN host.domain.com}]
+ @request.stubs(:client_cert).returns cert
+ @handler.params(@request)[:node].should == "host.domain.com"
+ end
+
+ it "should resolve the node name with an ip address look-up if no certificate is present" do
+ @request.stubs(:client_cert).returns nil
+
+ @handler.expects(:resolve_node).returns(:resolved_node)
+
+ @handler.params(@request)[:node].should == :resolved_node
+ end
end
+ end
end
diff --git a/spec/unit/network/http/webrick_spec.rb b/spec/unit/network/http/webrick_spec.rb
index 34abc69..2a6ef22 100755
--- a/spec/unit/network/http/webrick_spec.rb
+++ b/spec/unit/network/http/webrick_spec.rb
@@ -8,332 +8,332 @@ require 'puppet/network/http'
require 'puppet/network/http/webrick'
describe Puppet::Network::HTTP::WEBrick, "after initializing" do
- it "should not be listening" do
- Puppet::Network::HTTP::WEBrick.new.should_not be_listening
- end
+ it "should not be listening" do
+ Puppet::Network::HTTP::WEBrick.new.should_not be_listening
+ end
end
describe Puppet::Network::HTTP::WEBrick, "when turning on listening" do
- before do
- @mock_webrick = stub('webrick', :[] => {}, :listeners => [], :status => :Running)
- [:mount, :start, :shutdown].each {|meth| @mock_webrick.stubs(meth)}
- WEBrick::HTTPServer.stubs(:new).returns(@mock_webrick)
- @server = Puppet::Network::HTTP::WEBrick.new
- [:setup_logger, :setup_ssl].each {|meth| @server.stubs(meth).returns({})} # the empty hash is required because of how we're merging
- @listen_params = { :address => "127.0.0.1", :port => 31337, :xmlrpc_handlers => [], :protocols => [ :rest ] }
+ before do
+ @mock_webrick = stub('webrick', :[] => {}, :listeners => [], :status => :Running)
+ [:mount, :start, :shutdown].each {|meth| @mock_webrick.stubs(meth)}
+ WEBrick::HTTPServer.stubs(:new).returns(@mock_webrick)
+ @server = Puppet::Network::HTTP::WEBrick.new
+ [:setup_logger, :setup_ssl].each {|meth| @server.stubs(meth).returns({})} # the empty hash is required because of how we're merging
+ @listen_params = { :address => "127.0.0.1", :port => 31337, :xmlrpc_handlers => [], :protocols => [ :rest ] }
+ end
+
+ it "should fail if already listening" do
+ @server.listen(@listen_params)
+ Proc.new { @server.listen(@listen_params) }.should raise_error(RuntimeError)
+ end
+
+ it "should require at least one protocol" do
+ Proc.new { @server.listen(@listen_params.delete_if {|k,v| :protocols == k}) }.should raise_error(ArgumentError)
+ end
+
+ it "should require a listening address to be specified" do
+ Proc.new { @server.listen(@listen_params.delete_if {|k,v| :address == k})}.should raise_error(ArgumentError)
+ end
+
+ it "should require a listening port to be specified" do
+ Proc.new { @server.listen(@listen_params.delete_if {|k,v| :port == k})}.should raise_error(ArgumentError)
+ end
+
+ it "should order a webrick server to start in a separate thread" do
+ @mock_webrick.expects(:start)
+ # If you remove this you'll sometimes get race condition problems
+ Thread.expects(:new).yields
+ @server.listen(@listen_params)
+ end
+
+ it "should tell webrick to listen on the specified address and port" do
+ WEBrick::HTTPServer.expects(:new).with {|args|
+ args[:Port] == 31337 and args[:BindAddress] == "127.0.0.1"
+ }.returns(@mock_webrick)
+ @server.listen(@listen_params)
+ end
+
+ it "should configure a logger for webrick" do
+ @server.expects(:setup_logger).returns(:Logger => :mylogger)
+
+ WEBrick::HTTPServer.expects(:new).with {|args|
+ args[:Logger] == :mylogger
+ }.returns(@mock_webrick)
+
+ @server.listen(@listen_params)
+ end
+
+ it "should configure SSL for webrick" do
+ @server.expects(:setup_ssl).returns(:Ssl => :testing, :Other => :yay)
+
+ WEBrick::HTTPServer.expects(:new).with {|args|
+ args[:Ssl] == :testing and args[:Other] == :yay
+ }.returns(@mock_webrick)
+
+ @server.listen(@listen_params)
+ end
+
+ it "should be listening" do
+ @server.listen(@listen_params)
+ @server.should be_listening
+ end
+
+ describe "when the REST protocol is requested" do
+ it "should register the REST handler at /" do
+ # We don't care about the options here.
+ @mock_webrick.expects(:mount).with { |path, klass, options| path == "/" and klass == Puppet::Network::HTTP::WEBrickREST }
+
+ @server.listen(@listen_params.merge(:protocols => [:rest]))
end
+ end
- it "should fail if already listening" do
- @server.listen(@listen_params)
- Proc.new { @server.listen(@listen_params) }.should raise_error(RuntimeError)
- end
+ describe "when the XMLRPC protocol is requested" do
+ before do
+ @servlet = mock 'servlet'
- it "should require at least one protocol" do
- Proc.new { @server.listen(@listen_params.delete_if {|k,v| :protocols == k}) }.should raise_error(ArgumentError)
- end
+ Puppet::Network::XMLRPC::WEBrickServlet.stubs(:new).returns @servlet
- it "should require a listening address to be specified" do
- Proc.new { @server.listen(@listen_params.delete_if {|k,v| :address == k})}.should raise_error(ArgumentError)
- end
+ @master_handler = mock('master_handler')
+ @file_handler = mock('file_handler')
- it "should require a listening port to be specified" do
- Proc.new { @server.listen(@listen_params.delete_if {|k,v| :port == k})}.should raise_error(ArgumentError)
- end
+ @master = mock 'master'
+ @file = mock 'file'
+ @master_handler.stubs(:new).returns @master
+ @file_handler.stubs(:new).returns @file
- it "should order a webrick server to start in a separate thread" do
- @mock_webrick.expects(:start)
- # If you remove this you'll sometimes get race condition problems
- Thread.expects(:new).yields
- @server.listen(@listen_params)
+ Puppet::Network::Handler.stubs(:handler).with(:master).returns @master_handler
+ Puppet::Network::Handler.stubs(:handler).with(:fileserver).returns @file_handler
end
- it "should tell webrick to listen on the specified address and port" do
- WEBrick::HTTPServer.expects(:new).with {|args|
- args[:Port] == 31337 and args[:BindAddress] == "127.0.0.1"
- }.returns(@mock_webrick)
- @server.listen(@listen_params)
- end
+ it "should do nothing if no xmlrpc handlers have been specified" do
+ Puppet::Network::Handler.expects(:handler).never
- it "should configure a logger for webrick" do
- @server.expects(:setup_logger).returns(:Logger => :mylogger)
-
- WEBrick::HTTPServer.expects(:new).with {|args|
- args[:Logger] == :mylogger
- }.returns(@mock_webrick)
-
- @server.listen(@listen_params)
+ @server.listen(@listen_params.merge(:protocols => [:xmlrpc], :xmlrpc_handlers => []))
end
- it "should configure SSL for webrick" do
- @server.expects(:setup_ssl).returns(:Ssl => :testing, :Other => :yay)
+ it "should look the handler classes up via their base class" do
+ Puppet::Network::Handler.expects(:handler).with(:master).returns @master_handler
+ Puppet::Network::Handler.expects(:handler).with(:fileserver).returns @file_handler
- WEBrick::HTTPServer.expects(:new).with {|args|
- args[:Ssl] == :testing and args[:Other] == :yay
- }.returns(@mock_webrick)
-
- @server.listen(@listen_params)
+ @server.listen(@listen_params.merge(:protocols => [:xmlrpc], :xmlrpc_handlers => [:master, :fileserver]))
end
- it "should be listening" do
- @server.listen(@listen_params)
- @server.should be_listening
- end
+ it "should create an instance for each requested xmlrpc handler" do
+ @master_handler.expects(:new).returns @master
+ @file_handler.expects(:new).returns @file
- describe "when the REST protocol is requested" do
- it "should register the REST handler at /" do
- # We don't care about the options here.
- @mock_webrick.expects(:mount).with { |path, klass, options| path == "/" and klass == Puppet::Network::HTTP::WEBrickREST }
-
- @server.listen(@listen_params.merge(:protocols => [:rest]))
- end
+ @server.listen(@listen_params.merge(:protocols => [:xmlrpc], :xmlrpc_handlers => [:master, :fileserver]))
end
- describe "when the XMLRPC protocol is requested" do
- before do
- @servlet = mock 'servlet'
-
- Puppet::Network::XMLRPC::WEBrickServlet.stubs(:new).returns @servlet
-
- @master_handler = mock('master_handler')
- @file_handler = mock('file_handler')
+ it "should create a webrick servlet with the xmlrpc handler instances" do
+ Puppet::Network::XMLRPC::WEBrickServlet.expects(:new).with([@master, @file]).returns @servlet
- @master = mock 'master'
- @file = mock 'file'
- @master_handler.stubs(:new).returns @master
- @file_handler.stubs(:new).returns @file
-
- Puppet::Network::Handler.stubs(:handler).with(:master).returns @master_handler
- Puppet::Network::Handler.stubs(:handler).with(:fileserver).returns @file_handler
- end
-
- it "should do nothing if no xmlrpc handlers have been specified" do
- Puppet::Network::Handler.expects(:handler).never
-
- @server.listen(@listen_params.merge(:protocols => [:xmlrpc], :xmlrpc_handlers => []))
- end
-
- it "should look the handler classes up via their base class" do
- Puppet::Network::Handler.expects(:handler).with(:master).returns @master_handler
- Puppet::Network::Handler.expects(:handler).with(:fileserver).returns @file_handler
-
- @server.listen(@listen_params.merge(:protocols => [:xmlrpc], :xmlrpc_handlers => [:master, :fileserver]))
- end
-
- it "should create an instance for each requested xmlrpc handler" do
- @master_handler.expects(:new).returns @master
- @file_handler.expects(:new).returns @file
-
- @server.listen(@listen_params.merge(:protocols => [:xmlrpc], :xmlrpc_handlers => [:master, :fileserver]))
- end
-
- it "should create a webrick servlet with the xmlrpc handler instances" do
- Puppet::Network::XMLRPC::WEBrickServlet.expects(:new).with([@master, @file]).returns @servlet
-
- @server.listen(@listen_params.merge(:protocols => [:xmlrpc], :xmlrpc_handlers => [:master, :fileserver]))
- end
+ @server.listen(@listen_params.merge(:protocols => [:xmlrpc], :xmlrpc_handlers => [:master, :fileserver]))
+ end
- it "should mount the webrick servlet at /RPC2" do
- @mock_webrick.stubs(:mount)
- @mock_webrick.expects(:mount).with("/RPC2", @servlet)
+ it "should mount the webrick servlet at /RPC2" do
+ @mock_webrick.stubs(:mount)
+ @mock_webrick.expects(:mount).with("/RPC2", @servlet)
- @server.listen(@listen_params.merge(:protocols => [:xmlrpc], :xmlrpc_handlers => [:master, :fileserver]))
- end
+ @server.listen(@listen_params.merge(:protocols => [:xmlrpc], :xmlrpc_handlers => [:master, :fileserver]))
end
+ end
end
describe Puppet::Network::HTTP::WEBrick, "when looking up the class to handle a protocol" do
- it "should require a protocol" do
- lambda { Puppet::Network::HTTP::WEBrick.class_for_protocol }.should raise_error(ArgumentError)
- end
+ it "should require a protocol" do
+ lambda { Puppet::Network::HTTP::WEBrick.class_for_protocol }.should raise_error(ArgumentError)
+ end
- it "should accept a protocol" do
- lambda { Puppet::Network::HTTP::WEBrick.class_for_protocol("bob") }.should_not raise_error(ArgumentError)
- end
+ it "should accept a protocol" do
+ lambda { Puppet::Network::HTTP::WEBrick.class_for_protocol("bob") }.should_not raise_error(ArgumentError)
+ end
- it "should use a WEBrick + REST class when a REST protocol is specified" do
- Puppet::Network::HTTP::WEBrick.class_for_protocol("rest").should == Puppet::Network::HTTP::WEBrickREST
- end
+ it "should use a WEBrick + REST class when a REST protocol is specified" do
+ Puppet::Network::HTTP::WEBrick.class_for_protocol("rest").should == Puppet::Network::HTTP::WEBrickREST
+ end
- it "should fail when an unknown protocol is specified" do
- lambda { Puppet::Network::HTTP::WEBrick.class_for_protocol("abcdefg") }.should raise_error
- end
+ it "should fail when an unknown protocol is specified" do
+ lambda { Puppet::Network::HTTP::WEBrick.class_for_protocol("abcdefg") }.should raise_error
+ end
end
describe Puppet::Network::HTTP::WEBrick, "when turning off listening" do
- before do
- @mock_webrick = stub('webrick', :[] => {}, :listeners => [], :status => :Running)
- [:mount, :start, :shutdown].each {|meth| @mock_webrick.stubs(meth)}
- WEBrick::HTTPServer.stubs(:new).returns(@mock_webrick)
- @server = Puppet::Network::HTTP::WEBrick.new
- [:setup_logger, :setup_ssl].each {|meth| @server.stubs(meth).returns({})} # the empty hash is required because of how we're merging
- @listen_params = { :address => "127.0.0.1", :port => 31337, :handlers => [ :node, :catalog ], :protocols => [ :rest ] }
- end
-
- it "should fail unless listening" do
- Proc.new { @server.unlisten }.should raise_error(RuntimeError)
- end
-
- it "should order webrick server to stop" do
- @mock_webrick.expects(:shutdown)
- @server.listen(@listen_params)
- @server.unlisten
- end
-
- it "should no longer be listening" do
- @server.listen(@listen_params)
- @server.unlisten
- @server.should_not be_listening
- end
+ before do
+ @mock_webrick = stub('webrick', :[] => {}, :listeners => [], :status => :Running)
+ [:mount, :start, :shutdown].each {|meth| @mock_webrick.stubs(meth)}
+ WEBrick::HTTPServer.stubs(:new).returns(@mock_webrick)
+ @server = Puppet::Network::HTTP::WEBrick.new
+ [:setup_logger, :setup_ssl].each {|meth| @server.stubs(meth).returns({})} # the empty hash is required because of how we're merging
+ @listen_params = { :address => "127.0.0.1", :port => 31337, :handlers => [ :node, :catalog ], :protocols => [ :rest ] }
+ end
+
+ it "should fail unless listening" do
+ Proc.new { @server.unlisten }.should raise_error(RuntimeError)
+ end
+
+ it "should order webrick server to stop" do
+ @mock_webrick.expects(:shutdown)
+ @server.listen(@listen_params)
+ @server.unlisten
+ end
+
+ it "should no longer be listening" do
+ @server.listen(@listen_params)
+ @server.unlisten
+ @server.should_not be_listening
+ end
end
describe Puppet::Network::HTTP::WEBrick do
+ before do
+ @mock_webrick = stub('webrick', :[] => {})
+ [:mount, :start, :shutdown].each {|meth| @mock_webrick.stubs(meth)}
+ WEBrick::HTTPServer.stubs(:new).returns(@mock_webrick)
+ @server = Puppet::Network::HTTP::WEBrick.new
+ end
+
+ describe "when configuring an http logger" do
before do
- @mock_webrick = stub('webrick', :[] => {})
- [:mount, :start, :shutdown].each {|meth| @mock_webrick.stubs(meth)}
- WEBrick::HTTPServer.stubs(:new).returns(@mock_webrick)
- @server = Puppet::Network::HTTP::WEBrick.new
- end
+ Puppet.settings.stubs(:value).returns "something"
+ Puppet.settings.stubs(:use)
+ @filehandle = stub 'handle', :fcntl => nil, :sync => nil
- describe "when configuring an http logger" do
- before do
- Puppet.settings.stubs(:value).returns "something"
- Puppet.settings.stubs(:use)
- @filehandle = stub 'handle', :fcntl => nil, :sync => nil
-
- File.stubs(:open).returns @filehandle
- end
+ File.stubs(:open).returns @filehandle
+ end
- it "should use the settings for :main, :ssl, and the process name" do
- Puppet.settings.stubs(:value).with(:name).returns "myname"
- Puppet.settings.expects(:use).with(:main, :ssl, "myname")
+ it "should use the settings for :main, :ssl, and the process name" do
+ Puppet.settings.stubs(:value).with(:name).returns "myname"
+ Puppet.settings.expects(:use).with(:main, :ssl, "myname")
- @server.setup_logger
- end
+ @server.setup_logger
+ end
- it "should use the masterlog if the run_mode is master" do
- Puppet.run_mode.stubs(:master?).returns(true)
- Puppet.settings.expects(:value).with(:masterhttplog).returns "/master/log"
+ it "should use the masterlog if the run_mode is master" do
+ Puppet.run_mode.stubs(:master?).returns(true)
+ Puppet.settings.expects(:value).with(:masterhttplog).returns "/master/log"
- File.expects(:open).with("/master/log", "a+").returns @filehandle
+ File.expects(:open).with("/master/log", "a+").returns @filehandle
- @server.setup_logger
- end
+ @server.setup_logger
+ end
- it "should use the httplog if the run_mode is not master" do
- Puppet.run_mode.stubs(:master?).returns(false)
- Puppet.settings.expects(:value).with(:httplog).returns "/other/log"
+ it "should use the httplog if the run_mode is not master" do
+ Puppet.run_mode.stubs(:master?).returns(false)
+ Puppet.settings.expects(:value).with(:httplog).returns "/other/log"
- File.expects(:open).with("/other/log", "a+").returns @filehandle
+ File.expects(:open).with("/other/log", "a+").returns @filehandle
- @server.setup_logger
- end
+ @server.setup_logger
+ end
- describe "and creating the logging filehandle" do
- it "should set fcntl to 'Fcntl::F_SETFD, Fcntl::FD_CLOEXEC'" do
- @filehandle.expects(:fcntl).with(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
+ describe "and creating the logging filehandle" do
+ it "should set fcntl to 'Fcntl::F_SETFD, Fcntl::FD_CLOEXEC'" do
+ @filehandle.expects(:fcntl).with(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
- @server.setup_logger
- end
+ @server.setup_logger
+ end
- it "should sync the filehandle" do
- @filehandle.expects(:sync)
+ it "should sync the filehandle" do
+ @filehandle.expects(:sync)
- @server.setup_logger
- end
- end
+ @server.setup_logger
+ end
+ end
- it "should create a new WEBrick::Log instance with the open filehandle" do
- WEBrick::Log.expects(:new).with(@filehandle)
+ it "should create a new WEBrick::Log instance with the open filehandle" do
+ WEBrick::Log.expects(:new).with(@filehandle)
- @server.setup_logger
- end
+ @server.setup_logger
+ end
- it "should set debugging if the current loglevel is :debug" do
- Puppet::Util::Log.expects(:level).returns :debug
+ it "should set debugging if the current loglevel is :debug" do
+ Puppet::Util::Log.expects(:level).returns :debug
- WEBrick::Log.expects(:new).with { |handle, debug| debug == WEBrick::Log::DEBUG }
+ WEBrick::Log.expects(:new).with { |handle, debug| debug == WEBrick::Log::DEBUG }
- @server.setup_logger
- end
+ @server.setup_logger
+ end
- it "should return the logger as the main log" do
- logger = mock 'logger'
- WEBrick::Log.expects(:new).returns logger
+ it "should return the logger as the main log" do
+ logger = mock 'logger'
+ WEBrick::Log.expects(:new).returns logger
- @server.setup_logger[:Logger].should == logger
- end
+ @server.setup_logger[:Logger].should == logger
+ end
- it "should return the logger as the access log using both the Common and Referer log format" do
- logger = mock 'logger'
- WEBrick::Log.expects(:new).returns logger
+ it "should return the logger as the access log using both the Common and Referer log format" do
+ logger = mock 'logger'
+ WEBrick::Log.expects(:new).returns logger
- @server.setup_logger[:AccessLog].should == [
- [logger, WEBrick::AccessLog::COMMON_LOG_FORMAT],
- [logger, WEBrick::AccessLog::REFERER_LOG_FORMAT]
- ]
- end
+ @server.setup_logger[:AccessLog].should == [
+ [logger, WEBrick::AccessLog::COMMON_LOG_FORMAT],
+ [logger, WEBrick::AccessLog::REFERER_LOG_FORMAT]
+ ]
end
+ end
- describe "when configuring ssl" do
- before do
- @key = stub 'key', :content => "mykey"
- @cert = stub 'cert', :content => "mycert"
- @host = stub 'host', :key => @key, :certificate => @cert, :name => "yay", :ssl_store => "mystore"
+ describe "when configuring ssl" do
+ before do
+ @key = stub 'key', :content => "mykey"
+ @cert = stub 'cert', :content => "mycert"
+ @host = stub 'host', :key => @key, :certificate => @cert, :name => "yay", :ssl_store => "mystore"
- Puppet::SSL::Certificate.stubs(:find).with('ca').returns @cert
+ Puppet::SSL::Certificate.stubs(:find).with('ca').returns @cert
- Puppet::SSL::Host.stubs(:localhost).returns @host
- end
+ Puppet::SSL::Host.stubs(:localhost).returns @host
+ end
- it "should use the key from the localhost SSL::Host instance" do
- Puppet::SSL::Host.expects(:localhost).returns @host
- @host.expects(:key).returns @key
+ it "should use the key from the localhost SSL::Host instance" do
+ Puppet::SSL::Host.expects(:localhost).returns @host
+ @host.expects(:key).returns @key
- @server.setup_ssl[:SSLPrivateKey].should == "mykey"
- end
+ @server.setup_ssl[:SSLPrivateKey].should == "mykey"
+ end
- it "should configure the certificate" do
- @server.setup_ssl[:SSLCertificate].should == "mycert"
- end
+ it "should configure the certificate" do
+ @server.setup_ssl[:SSLCertificate].should == "mycert"
+ end
- it "should fail if no CA certificate can be found" do
- Puppet::SSL::Certificate.stubs(:find).with('ca').returns nil
+ it "should fail if no CA certificate can be found" do
+ Puppet::SSL::Certificate.stubs(:find).with('ca').returns nil
- lambda { @server.setup_ssl }.should raise_error(Puppet::Error)
- end
+ lambda { @server.setup_ssl }.should raise_error(Puppet::Error)
+ end
- it "should specify the path to the CA certificate" do
- Puppet.settings.stubs(:value).returns "whatever"
- Puppet.settings.stubs(:value).with(:hostcrl).returns 'false'
- Puppet.settings.stubs(:value).with(:localcacert).returns '/ca/crt'
+ it "should specify the path to the CA certificate" do
+ Puppet.settings.stubs(:value).returns "whatever"
+ Puppet.settings.stubs(:value).with(:hostcrl).returns 'false'
+ Puppet.settings.stubs(:value).with(:localcacert).returns '/ca/crt'
- @server.setup_ssl[:SSLCACertificateFile].should == "/ca/crt"
- end
+ @server.setup_ssl[:SSLCACertificateFile].should == "/ca/crt"
+ end
- it "should start ssl immediately" do
- @server.setup_ssl[:SSLStartImmediately].should be_true
- end
+ it "should start ssl immediately" do
+ @server.setup_ssl[:SSLStartImmediately].should be_true
+ end
- it "should enable ssl" do
- @server.setup_ssl[:SSLEnable].should be_true
- end
+ it "should enable ssl" do
+ @server.setup_ssl[:SSLEnable].should be_true
+ end
- it "should configure the verification method as 'OpenSSL::SSL::VERIFY_PEER'" do
- @server.setup_ssl[:SSLVerifyClient].should == OpenSSL::SSL::VERIFY_PEER
- end
+ it "should configure the verification method as 'OpenSSL::SSL::VERIFY_PEER'" do
+ @server.setup_ssl[:SSLVerifyClient].should == OpenSSL::SSL::VERIFY_PEER
+ end
- it "should add an x509 store" do
- Puppet.settings.stubs(:value).returns "whatever"
- Puppet.settings.stubs(:value).with(:hostcrl).returns '/my/crl'
+ it "should add an x509 store" do
+ Puppet.settings.stubs(:value).returns "whatever"
+ Puppet.settings.stubs(:value).with(:hostcrl).returns '/my/crl'
- @host.expects(:ssl_store).returns "mystore"
+ @host.expects(:ssl_store).returns "mystore"
- @server.setup_ssl[:SSLCertificateStore].should == "mystore"
- end
+ @server.setup_ssl[:SSLCertificateStore].should == "mystore"
+ end
- it "should set the certificate name to 'nil'" do
- @server.setup_ssl[:SSLCertName].should be_nil
- end
+ it "should set the certificate name to 'nil'" do
+ @server.setup_ssl[:SSLCertName].should be_nil
end
+ end
end
diff --git a/spec/unit/network/http_pool_spec.rb b/spec/unit/network/http_pool_spec.rb
index 1d64f9c..8fa7de8 100755
--- a/spec/unit/network/http_pool_spec.rb
+++ b/spec/unit/network/http_pool_spec.rb
@@ -7,200 +7,200 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/network/http_pool'
describe Puppet::Network::HttpPool do
- after do
- Puppet::Util::Cacher.expire
+ after do
+ Puppet::Util::Cacher.expire
+ Puppet::Network::HttpPool.clear_http_instances
+ Puppet::Network::HttpPool.instance_variable_set("@ssl_host", nil)
+ end
+
+ it "should have keep-alive disabled" do
+ Puppet::Network::HttpPool::HTTP_KEEP_ALIVE.should be_false
+ end
+
+ it "should use the global SSL::Host instance to get its certificate information" do
+ host = mock 'host'
+ Puppet::SSL::Host.expects(:localhost).with.returns host
+ Puppet::Network::HttpPool.ssl_host.should equal(host)
+ end
+
+ describe "when managing http instances" do
+ def stub_settings(settings)
+ settings.each do |param, value|
+ Puppet.settings.stubs(:value).with(param).returns(value)
+ end
+ end
+
+ before do
+ # All of the cert stuff is tested elsewhere
+ Puppet::Network::HttpPool.stubs(:cert_setup)
+ end
+
+ it "should return an http instance created with the passed host and port" do
+ http = stub 'http', :use_ssl= => nil, :read_timeout= => nil, :open_timeout= => nil, :started? => false
+ Net::HTTP.expects(:new).with("me", 54321, nil, nil).returns(http)
+ Puppet::Network::HttpPool.http_instance("me", 54321).should equal(http)
+ end
+
+ it "should enable ssl on the http instance" do
+ Puppet::Network::HttpPool.http_instance("me", 54321).instance_variable_get("@use_ssl").should be_true
+ end
+
+ it "should set the read timeout" do
+ Puppet::Network::HttpPool.http_instance("me", 54321).read_timeout.should == 120
+ end
+
+ it "should set the open timeout" do
+ Puppet::Network::HttpPool.http_instance("me", 54321).open_timeout.should == 120
+ end
+
+ it "should create the http instance with the proxy host and port set if the http_proxy is not set to 'none'" do
+ stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :configtimeout => 120
+ Puppet::Network::HttpPool.http_instance("me", 54321).open_timeout.should == 120
+ end
+
+ describe "and http keep-alive is enabled" do
+ before do
+ Puppet::Network::HttpPool.stubs(:keep_alive?).returns true
+ end
+
+ it "should cache http instances" do
+ stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :configtimeout => 120
+ old = Puppet::Network::HttpPool.http_instance("me", 54321)
+ Puppet::Network::HttpPool.http_instance("me", 54321).should equal(old)
+ end
+
+ it "should have a mechanism for getting a new http instance instead of the cached instance" do
+ stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :configtimeout => 120
+ old = Puppet::Network::HttpPool.http_instance("me", 54321)
+ Puppet::Network::HttpPool.http_instance("me", 54321, true).should_not equal(old)
+ end
+
+ it "should close existing, open connections when requesting a new connection" do
+ stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :configtimeout => 120
+ old = Puppet::Network::HttpPool.http_instance("me", 54321)
+ old.expects(:started?).returns(true)
+ old.expects(:finish)
+ Puppet::Network::HttpPool.http_instance("me", 54321, true)
+ end
+
+ it "should have a mechanism for clearing the http cache" do
+ stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :configtimeout => 120
+ old = Puppet::Network::HttpPool.http_instance("me", 54321)
+ Puppet::Network::HttpPool.http_instance("me", 54321).should equal(old)
+ old = Puppet::Network::HttpPool.http_instance("me", 54321)
+ Puppet::Network::HttpPool.clear_http_instances
+ Puppet::Network::HttpPool.http_instance("me", 54321).should_not equal(old)
+ end
+
+ it "should close open http connections when clearing the cache" do
+ stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :configtimeout => 120
+ one = Puppet::Network::HttpPool.http_instance("me", 54321)
+ one.expects(:started?).returns(true)
+ one.expects(:finish).returns(true)
+ Puppet::Network::HttpPool.clear_http_instances
+ end
+
+ it "should not close unopened http connections when clearing the cache" do
+ stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :configtimeout => 120
+ one = Puppet::Network::HttpPool.http_instance("me", 54321)
+ one.expects(:started?).returns(false)
+ one.expects(:finish).never
Puppet::Network::HttpPool.clear_http_instances
- Puppet::Network::HttpPool.instance_variable_set("@ssl_host", nil)
- end
-
- it "should have keep-alive disabled" do
- Puppet::Network::HttpPool::HTTP_KEEP_ALIVE.should be_false
- end
-
- it "should use the global SSL::Host instance to get its certificate information" do
- host = mock 'host'
- Puppet::SSL::Host.expects(:localhost).with.returns host
- Puppet::Network::HttpPool.ssl_host.should equal(host)
- end
-
- describe "when managing http instances" do
- def stub_settings(settings)
- settings.each do |param, value|
- Puppet.settings.stubs(:value).with(param).returns(value)
- end
- end
-
- before do
- # All of the cert stuff is tested elsewhere
- Puppet::Network::HttpPool.stubs(:cert_setup)
- end
-
- it "should return an http instance created with the passed host and port" do
- http = stub 'http', :use_ssl= => nil, :read_timeout= => nil, :open_timeout= => nil, :started? => false
- Net::HTTP.expects(:new).with("me", 54321, nil, nil).returns(http)
- Puppet::Network::HttpPool.http_instance("me", 54321).should equal(http)
- end
-
- it "should enable ssl on the http instance" do
- Puppet::Network::HttpPool.http_instance("me", 54321).instance_variable_get("@use_ssl").should be_true
- end
-
- it "should set the read timeout" do
- Puppet::Network::HttpPool.http_instance("me", 54321).read_timeout.should == 120
- end
-
- it "should set the open timeout" do
- Puppet::Network::HttpPool.http_instance("me", 54321).open_timeout.should == 120
- end
-
- it "should create the http instance with the proxy host and port set if the http_proxy is not set to 'none'" do
- stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :configtimeout => 120
- Puppet::Network::HttpPool.http_instance("me", 54321).open_timeout.should == 120
- end
-
- describe "and http keep-alive is enabled" do
- before do
- Puppet::Network::HttpPool.stubs(:keep_alive?).returns true
- end
-
- it "should cache http instances" do
- stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :configtimeout => 120
- old = Puppet::Network::HttpPool.http_instance("me", 54321)
- Puppet::Network::HttpPool.http_instance("me", 54321).should equal(old)
- end
-
- it "should have a mechanism for getting a new http instance instead of the cached instance" do
- stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :configtimeout => 120
- old = Puppet::Network::HttpPool.http_instance("me", 54321)
- Puppet::Network::HttpPool.http_instance("me", 54321, true).should_not equal(old)
- end
-
- it "should close existing, open connections when requesting a new connection" do
- stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :configtimeout => 120
- old = Puppet::Network::HttpPool.http_instance("me", 54321)
- old.expects(:started?).returns(true)
- old.expects(:finish)
- Puppet::Network::HttpPool.http_instance("me", 54321, true)
- end
-
- it "should have a mechanism for clearing the http cache" do
- stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :configtimeout => 120
- old = Puppet::Network::HttpPool.http_instance("me", 54321)
- Puppet::Network::HttpPool.http_instance("me", 54321).should equal(old)
- old = Puppet::Network::HttpPool.http_instance("me", 54321)
- Puppet::Network::HttpPool.clear_http_instances
- Puppet::Network::HttpPool.http_instance("me", 54321).should_not equal(old)
- end
-
- it "should close open http connections when clearing the cache" do
- stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :configtimeout => 120
- one = Puppet::Network::HttpPool.http_instance("me", 54321)
- one.expects(:started?).returns(true)
- one.expects(:finish).returns(true)
- Puppet::Network::HttpPool.clear_http_instances
- end
-
- it "should not close unopened http connections when clearing the cache" do
- stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :configtimeout => 120
- one = Puppet::Network::HttpPool.http_instance("me", 54321)
- one.expects(:started?).returns(false)
- one.expects(:finish).never
- Puppet::Network::HttpPool.clear_http_instances
- end
- end
-
- describe "and http keep-alive is disabled" do
- before do
- Puppet::Network::HttpPool.stubs(:keep_alive?).returns false
- end
-
- it "should not cache http instances" do
- stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :configtimeout => 120
- old = Puppet::Network::HttpPool.http_instance("me", 54321)
- Puppet::Network::HttpPool.http_instance("me", 54321).should_not equal(old)
- end
- end
-
- after do
- Puppet::Network::HttpPool.clear_http_instances
- end
- end
-
- describe "when adding certificate information to http instances" do
- before do
- @http = mock 'http'
- [:cert_store=, :verify_mode=, :ca_file=, :cert=, :key=].each { |m| @http.stubs(m) }
- @store = stub 'store'
-
- @cert = stub 'cert', :content => "real_cert"
- @key = stub 'key', :content => "real_key"
- @host = stub 'host', :certificate => @cert, :key => @key, :ssl_store => @store
-
- Puppet[:confdir] = "/sometthing/else"
- Puppet.settings.stubs(:value).returns "/some/file"
- Puppet.settings.stubs(:value).with(:hostcert).returns "/host/cert"
- Puppet.settings.stubs(:value).with(:localcacert).returns "/local/ca/cert"
-
- FileTest.stubs(:exist?).with("/host/cert").returns true
- FileTest.stubs(:exist?).with("/local/ca/cert").returns true
-
- Puppet::Network::HttpPool.stubs(:ssl_host).returns @host
- end
-
- after do
- Puppet.settings.clear
- end
-
- it "should do nothing if no host certificate is on disk" do
- FileTest.expects(:exist?).with("/host/cert").returns false
- @http.expects(:cert=).never
- Puppet::Network::HttpPool.cert_setup(@http)
- end
-
- it "should do nothing if no local certificate is on disk" do
- FileTest.expects(:exist?).with("/local/ca/cert").returns false
- @http.expects(:cert=).never
- Puppet::Network::HttpPool.cert_setup(@http)
- end
-
- it "should add a certificate store from the ssl host" do
- @http.expects(:cert_store=).with(@store)
-
- Puppet::Network::HttpPool.cert_setup(@http)
- end
-
- it "should add the client certificate" do
- @http.expects(:cert=).with("real_cert")
-
- Puppet::Network::HttpPool.cert_setup(@http)
- end
-
- it "should add the client key" do
- @http.expects(:key=).with("real_key")
-
- Puppet::Network::HttpPool.cert_setup(@http)
- end
-
- it "should set the verify mode to OpenSSL::SSL::VERIFY_PEER" do
- @http.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
-
- Puppet::Network::HttpPool.cert_setup(@http)
- end
-
- it "should set the ca file" do
- Puppet.settings.stubs(:value).returns "/some/file"
- FileTest.stubs(:exist?).with(Puppet[:hostcert]).returns true
-
- Puppet.settings.stubs(:value).with(:localcacert).returns "/ca/cert/file"
- FileTest.stubs(:exist?).with("/ca/cert/file").returns true
- @http.expects(:ca_file=).with("/ca/cert/file")
-
- Puppet::Network::HttpPool.cert_setup(@http)
- end
+ end
+ end
+
+ describe "and http keep-alive is disabled" do
+ before do
+ Puppet::Network::HttpPool.stubs(:keep_alive?).returns false
+ end
+
+ it "should not cache http instances" do
+ stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :configtimeout => 120
+ old = Puppet::Network::HttpPool.http_instance("me", 54321)
+ Puppet::Network::HttpPool.http_instance("me", 54321).should_not equal(old)
+ end
+ end
+
+ after do
+ Puppet::Network::HttpPool.clear_http_instances
+ end
+ end
+
+ describe "when adding certificate information to http instances" do
+ before do
+ @http = mock 'http'
+ [:cert_store=, :verify_mode=, :ca_file=, :cert=, :key=].each { |m| @http.stubs(m) }
+ @store = stub 'store'
+
+ @cert = stub 'cert', :content => "real_cert"
+ @key = stub 'key', :content => "real_key"
+ @host = stub 'host', :certificate => @cert, :key => @key, :ssl_store => @store
+
+ Puppet[:confdir] = "/sometthing/else"
+ Puppet.settings.stubs(:value).returns "/some/file"
+ Puppet.settings.stubs(:value).with(:hostcert).returns "/host/cert"
+ Puppet.settings.stubs(:value).with(:localcacert).returns "/local/ca/cert"
+
+ FileTest.stubs(:exist?).with("/host/cert").returns true
+ FileTest.stubs(:exist?).with("/local/ca/cert").returns true
+
+ Puppet::Network::HttpPool.stubs(:ssl_host).returns @host
+ end
+
+ after do
+ Puppet.settings.clear
+ end
+
+ it "should do nothing if no host certificate is on disk" do
+ FileTest.expects(:exist?).with("/host/cert").returns false
+ @http.expects(:cert=).never
+ Puppet::Network::HttpPool.cert_setup(@http)
+ end
+
+ it "should do nothing if no local certificate is on disk" do
+ FileTest.expects(:exist?).with("/local/ca/cert").returns false
+ @http.expects(:cert=).never
+ Puppet::Network::HttpPool.cert_setup(@http)
+ end
+
+ it "should add a certificate store from the ssl host" do
+ @http.expects(:cert_store=).with(@store)
+
+ Puppet::Network::HttpPool.cert_setup(@http)
+ end
+
+ it "should add the client certificate" do
+ @http.expects(:cert=).with("real_cert")
+
+ Puppet::Network::HttpPool.cert_setup(@http)
+ end
+
+ it "should add the client key" do
+ @http.expects(:key=).with("real_key")
+
+ Puppet::Network::HttpPool.cert_setup(@http)
+ end
+
+ it "should set the verify mode to OpenSSL::SSL::VERIFY_PEER" do
+ @http.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
+
+ Puppet::Network::HttpPool.cert_setup(@http)
+ end
+
+ it "should set the ca file" do
+ Puppet.settings.stubs(:value).returns "/some/file"
+ FileTest.stubs(:exist?).with(Puppet[:hostcert]).returns true
+
+ Puppet.settings.stubs(:value).with(:localcacert).returns "/ca/cert/file"
+ FileTest.stubs(:exist?).with("/ca/cert/file").returns true
+ @http.expects(:ca_file=).with("/ca/cert/file")
+
+ Puppet::Network::HttpPool.cert_setup(@http)
+ end
- it "should set up certificate information when creating http instances" do
- Puppet::Network::HttpPool.expects(:cert_setup).with { |i| i.is_a?(Net::HTTP) }
- Puppet::Network::HttpPool.http_instance("one", "two")
- end
+ it "should set up certificate information when creating http instances" do
+ Puppet::Network::HttpPool.expects(:cert_setup).with { |i| i.is_a?(Net::HTTP) }
+ Puppet::Network::HttpPool.http_instance("one", "two")
end
+ end
end
diff --git a/spec/unit/network/http_spec.rb b/spec/unit/network/http_spec.rb
index 2207267..e1d0d22 100755
--- a/spec/unit/network/http_spec.rb
+++ b/spec/unit/network/http_spec.rb
@@ -8,28 +8,28 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/network/http'
describe Puppet::Network::HTTP do
- it "should return the webrick HTTP server class when asked for a webrick server" do
- Puppet::Network::HTTP.server_class_by_type(:webrick).should be(Puppet::Network::HTTP::WEBrick)
- end
+ it "should return the webrick HTTP server class when asked for a webrick server" do
+ Puppet::Network::HTTP.server_class_by_type(:webrick).should be(Puppet::Network::HTTP::WEBrick)
+ end
- describe "when asked for a mongrel server" do
- if Puppet.features.mongrel?
- it "should return the mongrel server class" do
- Puppet::Network::HTTP.server_class_by_type(:mongrel).should be(Puppet::Network::HTTP::Mongrel)
- end
- else
- it "should fail" do
- lambda { Puppet::Network::HTTP.server_class_by_type(:mongrel) }.should raise_error(ArgumentError)
- end
- end
+ describe "when asked for a mongrel server" do
+ if Puppet.features.mongrel?
+ it "should return the mongrel server class" do
+ Puppet::Network::HTTP.server_class_by_type(:mongrel).should be(Puppet::Network::HTTP::Mongrel)
+ end
+ else
+ it "should fail" do
+ lambda { Puppet::Network::HTTP.server_class_by_type(:mongrel) }.should raise_error(ArgumentError)
+ end
end
+ end
- it "should fail to return the mongrel HTTP server class if mongrel is not available " do
- Puppet.features.expects(:mongrel?).returns(false)
- Proc.new { Puppet::Network::HTTP.server_class_by_type(:mongrel) }.should raise_error(ArgumentError)
- end
+ it "should fail to return the mongrel HTTP server class if mongrel is not available " do
+ Puppet.features.expects(:mongrel?).returns(false)
+ Proc.new { Puppet::Network::HTTP.server_class_by_type(:mongrel) }.should raise_error(ArgumentError)
+ end
- it "should return an error when asked for an unknown server" do
- Proc.new { Puppet::Network::HTTP.server_class_by_type :foo }.should raise_error(ArgumentError)
- end
+ it "should return an error when asked for an unknown server" do
+ Proc.new { Puppet::Network::HTTP.server_class_by_type :foo }.should raise_error(ArgumentError)
+ end
end
diff --git a/spec/unit/network/rest_authconfig_spec.rb b/spec/unit/network/rest_authconfig_spec.rb
index 79fa968..351f3f0 100755
--- a/spec/unit/network/rest_authconfig_spec.rb
+++ b/spec/unit/network/rest_authconfig_spec.rb
@@ -6,143 +6,143 @@ require 'puppet/network/rest_authconfig'
describe Puppet::Network::RestAuthConfig do
- DEFAULT_ACL = [
- { :acl => "~ ^\/catalog\/([^\/]+)$", :method => :find, :allow => '$1', :authenticated => true },
- # this one will allow all file access, and thus delegate
- # to fileserver.conf
- { :acl => "/file" },
- { :acl => "/certificate_revocation_list/ca", :method => :find, :authenticated => true },
- { :acl => "/report", :method => :save, :authenticated => true },
- { :acl => "/certificate/ca", :method => :find, :authenticated => false },
- { :acl => "/certificate/", :method => :find, :authenticated => false },
- { :acl => "/certificate_request", :method => [:find, :save], :authenticated => false },
- { :acl => "/status", :method => [:find], :authenticated => true },
- { :acl => "/resource", :method => [:find, :save, :search], :authenticated => true },
- ]
-
- before :each do
- FileTest.stubs(:exists?).returns(true)
- File.stubs(:stat).returns(stub('stat', :ctime => :now))
- Time.stubs(:now).returns :now
-
- @authconfig = Puppet::Network::RestAuthConfig.new("dummy", false)
- @authconfig.stubs(:read)
-
- @acl = stub_everything 'rights'
- @authconfig.rights = @acl
-
- @request = stub 'request', :indirection_name => "path", :key => "to/resource", :ip => "127.0.0.1",
- :node => "me", :method => :save, :environment => :env, :authenticated => true
+ DEFAULT_ACL = [
+ { :acl => "~ ^\/catalog\/([^\/]+)$", :method => :find, :allow => '$1', :authenticated => true },
+ # this one will allow all file access, and thus delegate
+ # to fileserver.conf
+ { :acl => "/file" },
+ { :acl => "/certificate_revocation_list/ca", :method => :find, :authenticated => true },
+ { :acl => "/report", :method => :save, :authenticated => true },
+ { :acl => "/certificate/ca", :method => :find, :authenticated => false },
+ { :acl => "/certificate/", :method => :find, :authenticated => false },
+ { :acl => "/certificate_request", :method => [:find, :save], :authenticated => false },
+ { :acl => "/status", :method => [:find], :authenticated => true },
+ { :acl => "/resource", :method => [:find, :save, :search], :authenticated => true },
+ ]
+
+ before :each do
+ FileTest.stubs(:exists?).returns(true)
+ File.stubs(:stat).returns(stub('stat', :ctime => :now))
+ Time.stubs(:now).returns :now
+
+ @authconfig = Puppet::Network::RestAuthConfig.new("dummy", false)
+ @authconfig.stubs(:read)
+
+ @acl = stub_everything 'rights'
+ @authconfig.rights = @acl
+
+ @request = stub 'request', :indirection_name => "path", :key => "to/resource", :ip => "127.0.0.1",
+ :node => "me", :method => :save, :environment => :env, :authenticated => true
+ end
+
+ it "should use the puppet default rest authorization file" do
+ Puppet.expects(:[]).with(:rest_authconfig).returns("dummy")
+
+ Puppet::Network::RestAuthConfig.new(nil, false)
+ end
+
+ it "should read the config file when needed" do
+ @authconfig.expects(:read)
+
+ @authconfig.allowed?(@request)
+ end
+
+ it "should ask for authorization to the ACL subsystem" do
+ @acl.expects(:fail_on_deny).with("/path/to/resource", :node => "me", :ip => "127.0.0.1", :method => :save, :environment => :env, :authenticated => true)
+
+ @authconfig.allowed?(@request)
+ end
+
+ describe "when defining an acl with mk_acl" do
+ it "should create a new right for each default acl" do
+ @acl.expects(:newright).with(:path)
+ @authconfig.mk_acl(:acl => :path)
end
- it "should use the puppet default rest authorization file" do
- Puppet.expects(:[]).with(:rest_authconfig).returns("dummy")
-
- Puppet::Network::RestAuthConfig.new(nil, false)
+ it "should allow everyone for each default right" do
+ @acl.expects(:allow).with(:path, "*")
+ @authconfig.mk_acl(:acl => :path)
end
- it "should read the config file when needed" do
- @authconfig.expects(:read)
-
- @authconfig.allowed?(@request)
+ it "should restrict the ACL to a method" do
+ @acl.expects(:restrict_method).with(:path, :method)
+ @authconfig.mk_acl(:acl => :path, :method => :method)
end
- it "should ask for authorization to the ACL subsystem" do
- @acl.expects(:fail_on_deny).with("/path/to/resource", :node => "me", :ip => "127.0.0.1", :method => :save, :environment => :env, :authenticated => true)
-
- @authconfig.allowed?(@request)
+ it "should restrict the ACL to a specific authentication state" do
+ @acl.expects(:restrict_authenticated).with(:path, :authentication)
+ @authconfig.mk_acl(:acl => :path, :authenticated => :authentication)
end
+ end
- describe "when defining an acl with mk_acl" do
- it "should create a new right for each default acl" do
- @acl.expects(:newright).with(:path)
- @authconfig.mk_acl(:acl => :path)
- end
-
- it "should allow everyone for each default right" do
- @acl.expects(:allow).with(:path, "*")
- @authconfig.mk_acl(:acl => :path)
- end
-
- it "should restrict the ACL to a method" do
- @acl.expects(:restrict_method).with(:path, :method)
- @authconfig.mk_acl(:acl => :path, :method => :method)
- end
-
- it "should restrict the ACL to a specific authentication state" do
- @acl.expects(:restrict_authenticated).with(:path, :authentication)
- @authconfig.mk_acl(:acl => :path, :authenticated => :authentication)
- end
- end
+ describe "when parsing the configuration file" do
+ it "should check for missing ACL after reading the authconfig file" do
+ File.stubs(:open)
- describe "when parsing the configuration file" do
- it "should check for missing ACL after reading the authconfig file" do
- File.stubs(:open)
+ @authconfig.expects(:insert_default_acl)
- @authconfig.expects(:insert_default_acl)
-
- @authconfig.parse
- end
+ @authconfig.parse
end
+ end
- DEFAULT_ACL.each do |acl|
- it "should insert #{acl[:acl]} if not present" do
- @authconfig.rights.stubs(:[]).returns(true)
- @authconfig.rights.stubs(:[]).with(acl[:acl]).returns(nil)
+ DEFAULT_ACL.each do |acl|
+ it "should insert #{acl[:acl]} if not present" do
+ @authconfig.rights.stubs(:[]).returns(true)
+ @authconfig.rights.stubs(:[]).with(acl[:acl]).returns(nil)
- @authconfig.expects(:mk_acl).with { |h| h[:acl] == acl[:acl] }
+ @authconfig.expects(:mk_acl).with { |h| h[:acl] == acl[:acl] }
- @authconfig.insert_default_acl
- end
+ @authconfig.insert_default_acl
+ end
- it "should not insert #{acl[:acl]} if present" do
- @authconfig.rights.stubs(:[]).returns(true)
- @authconfig.rights.stubs(:[]).with(acl).returns(true)
+ it "should not insert #{acl[:acl]} if present" do
+ @authconfig.rights.stubs(:[]).returns(true)
+ @authconfig.rights.stubs(:[]).with(acl).returns(true)
- @authconfig.expects(:mk_acl).never
+ @authconfig.expects(:mk_acl).never
- @authconfig.insert_default_acl
- end
+ @authconfig.insert_default_acl
end
+ end
- it "should create default ACL entries if no file have been read" do
- Puppet::Network::RestAuthConfig.any_instance.stubs(:exists?).returns(false)
+ it "should create default ACL entries if no file have been read" do
+ Puppet::Network::RestAuthConfig.any_instance.stubs(:exists?).returns(false)
- Puppet::Network::RestAuthConfig.any_instance.expects(:insert_default_acl)
+ Puppet::Network::RestAuthConfig.any_instance.expects(:insert_default_acl)
- Puppet::Network::RestAuthConfig.main
- end
-
- describe "when adding default ACLs" do
+ Puppet::Network::RestAuthConfig.main
+ end
- DEFAULT_ACL.each do |acl|
- it "should create a default right for #{acl[:acl]}" do
- @authconfig.stubs(:mk_acl)
- @authconfig.expects(:mk_acl).with(acl)
- @authconfig.insert_default_acl
- end
- end
+ describe "when adding default ACLs" do
- it "should log at info loglevel" do
- Puppet.expects(:info).at_least_once
- @authconfig.insert_default_acl
- end
+ DEFAULT_ACL.each do |acl|
+ it "should create a default right for #{acl[:acl]}" do
+ @authconfig.stubs(:mk_acl)
+ @authconfig.expects(:mk_acl).with(acl)
+ @authconfig.insert_default_acl
+ end
+ end
- it "should create a last catch-all deny all rule" do
- @authconfig.stubs(:mk_acl)
- @acl.expects(:newright).with("/")
- @authconfig.insert_default_acl
- end
+ it "should log at info loglevel" do
+ Puppet.expects(:info).at_least_once
+ @authconfig.insert_default_acl
+ end
- it "should create a last catch-all deny all rule for any authenticated request state" do
- @authconfig.stubs(:mk_acl)
- @acl.stubs(:newright).with("/")
+ it "should create a last catch-all deny all rule" do
+ @authconfig.stubs(:mk_acl)
+ @acl.expects(:newright).with("/")
+ @authconfig.insert_default_acl
+ end
- @acl.expects(:restrict_authenticated).with("/", :any)
+ it "should create a last catch-all deny all rule for any authenticated request state" do
+ @authconfig.stubs(:mk_acl)
+ @acl.stubs(:newright).with("/")
- @authconfig.insert_default_acl
- end
+ @acl.expects(:restrict_authenticated).with("/", :any)
+ @authconfig.insert_default_acl
end
+ end
+
end
diff --git a/spec/unit/network/rest_authorization_spec.rb b/spec/unit/network/rest_authorization_spec.rb
index 4703c18..0cb0bce 100755
--- a/spec/unit/network/rest_authorization_spec.rb
+++ b/spec/unit/network/rest_authorization_spec.rb
@@ -5,39 +5,39 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/network/rest_authorization'
class RestAuthorized
- include Puppet::Network::RestAuthorization
+ include Puppet::Network::RestAuthorization
end
describe Puppet::Network::RestAuthorization do
- before :each do
- @auth = RestAuthorized.new
- @authconig = stub 'authconfig'
- @auth.stubs(:authconfig).returns(@authconfig)
-
- @request = stub_everything 'request'
- @request.stubs(:method).returns(:find)
- @request.stubs(:node).returns("node")
- @request.stubs(:ip).returns("ip")
+ before :each do
+ @auth = RestAuthorized.new
+ @authconig = stub 'authconfig'
+ @auth.stubs(:authconfig).returns(@authconfig)
+
+ @request = stub_everything 'request'
+ @request.stubs(:method).returns(:find)
+ @request.stubs(:node).returns("node")
+ @request.stubs(:ip).returns("ip")
+ end
+
+ describe "when testing request authorization" do
+ it "should delegate to the current rest authconfig" do
+ @authconfig.expects(:allowed?).with(@request).returns(true)
+
+ @auth.check_authorization(@request)
end
- describe "when testing request authorization" do
- it "should delegate to the current rest authconfig" do
- @authconfig.expects(:allowed?).with(@request).returns(true)
+ it "should raise an AuthorizationError if authconfig raises an AuthorizationError" do
+ @authconfig.expects(:allowed?).with(@request).raises(Puppet::Network::AuthorizationError.new("forbidden"))
- @auth.check_authorization(@request)
- end
-
- it "should raise an AuthorizationError if authconfig raises an AuthorizationError" do
- @authconfig.expects(:allowed?).with(@request).raises(Puppet::Network::AuthorizationError.new("forbidden"))
-
- lambda { @auth.check_authorization(@request) }.should raise_error(Puppet::Network::AuthorizationError)
- end
+ lambda { @auth.check_authorization(@request) }.should raise_error(Puppet::Network::AuthorizationError)
+ end
- it "should not raise an AuthorizationError if request is allowed" do
- @authconfig.expects(:allowed?).with(@request).returns(true)
+ it "should not raise an AuthorizationError if request is allowed" do
+ @authconfig.expects(:allowed?).with(@request).returns(true)
- lambda { @auth.check_authorization(@request) }.should_not raise_error(Puppet::Network::AuthorizationError)
- end
+ lambda { @auth.check_authorization(@request) }.should_not raise_error(Puppet::Network::AuthorizationError)
end
+ end
end
diff --git a/spec/unit/network/rights_spec.rb b/spec/unit/network/rights_spec.rb
index 7f00891..969fc18 100755
--- a/spec/unit/network/rights_spec.rb
+++ b/spec/unit/network/rights_spec.rb
@@ -5,515 +5,515 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/network/rights'
describe Puppet::Network::Rights do
- before do
- @right = Puppet::Network::Rights.new
- end
+ before do
+ @right = Puppet::Network::Rights.new
+ end
- [:allow, :deny, :restrict_method, :restrict_environment, :restrict_authenticated].each do |m|
- it "should have a #{m} method" do
- @right.should respond_to(m)
- end
+ [:allow, :deny, :restrict_method, :restrict_environment, :restrict_authenticated].each do |m|
+ it "should have a #{m} method" do
+ @right.should respond_to(m)
+ end
- describe "when using #{m}" do
- it "should delegate to the correct acl" do
- acl = stub 'acl'
- @right.stubs(:[]).returns(acl)
+ describe "when using #{m}" do
+ it "should delegate to the correct acl" do
+ acl = stub 'acl'
+ @right.stubs(:[]).returns(acl)
- acl.expects(m).with("me")
+ acl.expects(m).with("me")
- @right.send(m, 'thisacl', "me")
- end
- end
+ @right.send(m, 'thisacl', "me")
+ end
end
+ end
- it "should throw an error if type can't be determined" do
- lambda { @right.newright("name") }.should raise_error
- end
+ it "should throw an error if type can't be determined" do
+ lambda { @right.newright("name") }.should raise_error
+ end
- describe "when creating new namespace ACLs" do
+ describe "when creating new namespace ACLs" do
- it "should throw an error if the ACL already exists" do
- @right.newright("[name]")
+ it "should throw an error if the ACL already exists" do
+ @right.newright("[name]")
- lambda { @right.newright("[name]") }.should raise_error
- end
+ lambda { @right.newright("[name]") }.should raise_error
+ end
- it "should create a new ACL with the correct name" do
- @right.newright("[name]")
+ it "should create a new ACL with the correct name" do
+ @right.newright("[name]")
- @right["name"].key.should == :name
- end
+ @right["name"].key.should == :name
+ end
- it "should create an ACL of type Puppet::Network::AuthStore" do
- @right.newright("[name]")
+ it "should create an ACL of type Puppet::Network::AuthStore" do
+ @right.newright("[name]")
- @right["name"].should be_a_kind_of(Puppet::Network::AuthStore)
- end
+ @right["name"].should be_a_kind_of(Puppet::Network::AuthStore)
end
+ end
- describe "when creating new path ACLs" do
- it "should not throw an error if the ACL already exists" do
- @right.newright("/name")
+ describe "when creating new path ACLs" do
+ it "should not throw an error if the ACL already exists" do
+ @right.newright("/name")
- lambda { @right.newright("/name")}.should_not raise_error
- end
+ lambda { @right.newright("/name")}.should_not raise_error
+ end
- it "should throw an error if the acl uri path is not absolute" do
- lambda { @right.newright("name")}.should raise_error
- end
+ it "should throw an error if the acl uri path is not absolute" do
+ lambda { @right.newright("name")}.should raise_error
+ end
- it "should create a new ACL with the correct path" do
- @right.newright("/name")
+ it "should create a new ACL with the correct path" do
+ @right.newright("/name")
- @right["/name"].should_not be_nil
- end
+ @right["/name"].should_not be_nil
+ end
- it "should create an ACL of type Puppet::Network::AuthStore" do
- @right.newright("/name")
+ it "should create an ACL of type Puppet::Network::AuthStore" do
+ @right.newright("/name")
- @right["/name"].should be_a_kind_of(Puppet::Network::AuthStore)
- end
+ @right["/name"].should be_a_kind_of(Puppet::Network::AuthStore)
end
+ end
- describe "when creating new regex ACLs" do
- it "should not throw an error if the ACL already exists" do
- @right.newright("~ .rb$")
+ describe "when creating new regex ACLs" do
+ it "should not throw an error if the ACL already exists" do
+ @right.newright("~ .rb$")
- lambda { @right.newright("~ .rb$")}.should_not raise_error
- end
+ lambda { @right.newright("~ .rb$")}.should_not raise_error
+ end
- it "should create a new ACL with the correct regex" do
- @right.newright("~ .rb$")
+ it "should create a new ACL with the correct regex" do
+ @right.newright("~ .rb$")
- @right.include?(".rb$").should_not be_nil
- end
+ @right.include?(".rb$").should_not be_nil
+ end
- it "should be able to lookup the regex" do
- @right.newright("~ .rb$")
+ it "should be able to lookup the regex" do
+ @right.newright("~ .rb$")
- @right[".rb$"].should_not be_nil
- end
+ @right[".rb$"].should_not be_nil
+ end
- it "should be able to lookup the regex by its full name" do
- @right.newright("~ .rb$")
+ it "should be able to lookup the regex by its full name" do
+ @right.newright("~ .rb$")
- @right["~ .rb$"].should_not be_nil
- end
+ @right["~ .rb$"].should_not be_nil
+ end
- it "should create an ACL of type Puppet::Network::AuthStore" do
- @right.newright("~ .rb$").should be_a_kind_of(Puppet::Network::AuthStore)
- end
+ it "should create an ACL of type Puppet::Network::AuthStore" do
+ @right.newright("~ .rb$").should be_a_kind_of(Puppet::Network::AuthStore)
end
+ end
- describe "when checking ACLs existence" do
- it "should return false if there are no matching rights" do
- @right.include?("name").should be_false
- end
+ describe "when checking ACLs existence" do
+ it "should return false if there are no matching rights" do
+ @right.include?("name").should be_false
+ end
- it "should return true if a namespace rights exist" do
- @right.newright("[name]")
+ it "should return true if a namespace rights exist" do
+ @right.newright("[name]")
- @right.include?("name").should be_true
- end
+ @right.include?("name").should be_true
+ end
- it "should return false if no matching namespace rights exist" do
- @right.newright("[name]")
+ it "should return false if no matching namespace rights exist" do
+ @right.newright("[name]")
- @right.include?("notname").should be_false
- end
+ @right.include?("notname").should be_false
+ end
- it "should return true if a path right exists" do
- @right.newright("/name")
+ it "should return true if a path right exists" do
+ @right.newright("/name")
- @right.include?("/name").should be_true
- end
+ @right.include?("/name").should be_true
+ end
- it "should return false if no matching path rights exist" do
- @right.newright("/name")
+ it "should return false if no matching path rights exist" do
+ @right.newright("/name")
- @right.include?("/differentname").should be_false
- end
+ @right.include?("/differentname").should be_false
+ end
- it "should return true if a regex right exists" do
- @right.newright("~ .rb$")
+ it "should return true if a regex right exists" do
+ @right.newright("~ .rb$")
- @right.include?(".rb$").should be_true
- end
+ @right.include?(".rb$").should be_true
+ end
- it "should return false if no matching path rights exist" do
- @right.newright("~ .rb$")
+ it "should return false if no matching path rights exist" do
+ @right.newright("~ .rb$")
- @right.include?(".pp$").should be_false
- end
+ @right.include?(".pp$").should be_false
end
+ end
- describe "when checking if right is allowed" do
- before :each do
- @right.stubs(:right).returns(nil)
+ describe "when checking if right is allowed" do
+ before :each do
+ @right.stubs(:right).returns(nil)
- @pathacl = stub 'pathacl', :acl_type => :regex, :"<=>" => 1, :line => 0, :file => 'dummy'
- Puppet::Network::Rights::Right.stubs(:new).returns(@pathacl)
- end
+ @pathacl = stub 'pathacl', :acl_type => :regex, :"<=>" => 1, :line => 0, :file => 'dummy'
+ Puppet::Network::Rights::Right.stubs(:new).returns(@pathacl)
+ end
- it "should delegate to fail_on_deny" do
- @right.expects(:fail_on_deny).with("namespace", :node => "host.domain.com", :ip => "127.0.0.1")
+ it "should delegate to fail_on_deny" do
+ @right.expects(:fail_on_deny).with("namespace", :node => "host.domain.com", :ip => "127.0.0.1")
- @right.allowed?("namespace", "host.domain.com", "127.0.0.1")
- end
+ @right.allowed?("namespace", "host.domain.com", "127.0.0.1")
+ end
- it "should return true if fail_on_deny doesn't fail" do
- @right.stubs(:fail_on_deny)
- @right.allowed?("namespace", :args).should be_true
- end
+ it "should return true if fail_on_deny doesn't fail" do
+ @right.stubs(:fail_on_deny)
+ @right.allowed?("namespace", :args).should be_true
+ end
- it "should return false if fail_on_deny raises an AuthorizationError" do
- @right.stubs(:fail_on_deny).raises(Puppet::Network::AuthorizationError.new("forbidden"))
- @right.allowed?("namespace", :args1, :args2).should be_false
- end
+ it "should return false if fail_on_deny raises an AuthorizationError" do
+ @right.stubs(:fail_on_deny).raises(Puppet::Network::AuthorizationError.new("forbidden"))
+ @right.allowed?("namespace", :args1, :args2).should be_false
+ end
- it "should first check namespace rights" do
- acl = stub 'acl', :acl_type => :name, :key => :namespace
- Puppet::Network::Rights::Right.stubs(:new).returns(acl)
+ it "should first check namespace rights" do
+ acl = stub 'acl', :acl_type => :name, :key => :namespace
+ Puppet::Network::Rights::Right.stubs(:new).returns(acl)
- @right.newright("[namespace]")
- acl.expects(:match?).returns(true)
- acl.expects(:allowed?).with { |node,ip,h| node == "node" and ip == "ip" }.returns(true)
+ @right.newright("[namespace]")
+ acl.expects(:match?).returns(true)
+ acl.expects(:allowed?).with { |node,ip,h| node == "node" and ip == "ip" }.returns(true)
- @right.fail_on_deny("namespace", { :node => "node", :ip => "ip" } )
- end
+ @right.fail_on_deny("namespace", { :node => "node", :ip => "ip" } )
+ end
- it "should then check for path rights if no namespace match" do
- acl = stub 'nmacl', :acl_type => :name, :key => :namespace, :"<=>" => -1, :line => 0, :file => 'dummy'
- acl.stubs(:match?).returns(false)
- Puppet::Network::Rights::Right.stubs(:new).with("[namespace]").returns(acl)
+ it "should then check for path rights if no namespace match" do
+ acl = stub 'nmacl', :acl_type => :name, :key => :namespace, :"<=>" => -1, :line => 0, :file => 'dummy'
+ acl.stubs(:match?).returns(false)
+ Puppet::Network::Rights::Right.stubs(:new).with("[namespace]").returns(acl)
- @right.newright("[namespace]")
- @right.newright("/path/to/there", 0, nil)
+ @right.newright("[namespace]")
+ @right.newright("/path/to/there", 0, nil)
- @pathacl.stubs(:match?).returns(true)
+ @pathacl.stubs(:match?).returns(true)
- acl.expects(:allowed?).never
- @pathacl.expects(:allowed?).returns(true)
+ acl.expects(:allowed?).never
+ @pathacl.expects(:allowed?).returns(true)
- @right.fail_on_deny("/path/to/there", {})
- end
+ @right.fail_on_deny("/path/to/there", {})
+ end
- it "should pass the match? return to allowed?" do
- @right.newright("/path/to/there")
+ it "should pass the match? return to allowed?" do
+ @right.newright("/path/to/there")
- @pathacl.expects(:match?).returns(:match)
- @pathacl.expects(:allowed?).with { |node,ip,h| h[:match] == :match }.returns(true)
+ @pathacl.expects(:match?).returns(:match)
+ @pathacl.expects(:allowed?).with { |node,ip,h| h[:match] == :match }.returns(true)
- @right.fail_on_deny("/path/to/there", {})
- end
+ @right.fail_on_deny("/path/to/there", {})
+ end
- describe "with namespace acls" do
- it "should raise an error if this namespace right doesn't exist" do
- lambda{ @right.fail_on_deny("namespace") }.should raise_error
- end
- end
+ describe "with namespace acls" do
+ it "should raise an error if this namespace right doesn't exist" do
+ lambda{ @right.fail_on_deny("namespace") }.should raise_error
+ end
+ end
- describe "with path acls" do
- before :each do
- @long_acl = stub 'longpathacl', :name => "/path/to/there", :acl_type => :regex, :line => 0, :file => 'dummy'
- Puppet::Network::Rights::Right.stubs(:new).with("/path/to/there", 0, nil).returns(@long_acl)
+ describe "with path acls" do
+ before :each do
+ @long_acl = stub 'longpathacl', :name => "/path/to/there", :acl_type => :regex, :line => 0, :file => 'dummy'
+ Puppet::Network::Rights::Right.stubs(:new).with("/path/to/there", 0, nil).returns(@long_acl)
- @short_acl = stub 'shortpathacl', :name => "/path/to", :acl_type => :regex, :line => 0, :file => 'dummy'
- Puppet::Network::Rights::Right.stubs(:new).with("/path/to", 0, nil).returns(@short_acl)
+ @short_acl = stub 'shortpathacl', :name => "/path/to", :acl_type => :regex, :line => 0, :file => 'dummy'
+ Puppet::Network::Rights::Right.stubs(:new).with("/path/to", 0, nil).returns(@short_acl)
- @long_acl.stubs(:"<=>").with(@short_acl).returns(0)
- @short_acl.stubs(:"<=>").with(@long_acl).returns(0)
- end
+ @long_acl.stubs(:"<=>").with(@short_acl).returns(0)
+ @short_acl.stubs(:"<=>").with(@long_acl).returns(0)
+ end
- it "should select the first match" do
- @right.newright("/path/to/there", 0)
- @right.newright("/path/to", 0)
+ it "should select the first match" do
+ @right.newright("/path/to/there", 0)
+ @right.newright("/path/to", 0)
- @long_acl.stubs(:match?).returns(true)
- @short_acl.stubs(:match?).returns(true)
+ @long_acl.stubs(:match?).returns(true)
+ @short_acl.stubs(:match?).returns(true)
- @long_acl.expects(:allowed?).returns(true)
- @short_acl.expects(:allowed?).never
+ @long_acl.expects(:allowed?).returns(true)
+ @short_acl.expects(:allowed?).never
- @right.fail_on_deny("/path/to/there/and/there", {})
- end
+ @right.fail_on_deny("/path/to/there/and/there", {})
+ end
- it "should select the first match that doesn't return :dunno" do
- @right.newright("/path/to/there", 0, nil)
- @right.newright("/path/to", 0, nil)
+ it "should select the first match that doesn't return :dunno" do
+ @right.newright("/path/to/there", 0, nil)
+ @right.newright("/path/to", 0, nil)
- @long_acl.stubs(:match?).returns(true)
- @short_acl.stubs(:match?).returns(true)
+ @long_acl.stubs(:match?).returns(true)
+ @short_acl.stubs(:match?).returns(true)
- @long_acl.expects(:allowed?).returns(:dunno)
- @short_acl.expects(:allowed?).returns(true)
+ @long_acl.expects(:allowed?).returns(:dunno)
+ @short_acl.expects(:allowed?).returns(true)
- @right.fail_on_deny("/path/to/there/and/there", {})
- end
+ @right.fail_on_deny("/path/to/there/and/there", {})
+ end
- it "should not select an ACL that doesn't match" do
- @right.newright("/path/to/there", 0)
- @right.newright("/path/to", 0)
+ it "should not select an ACL that doesn't match" do
+ @right.newright("/path/to/there", 0)
+ @right.newright("/path/to", 0)
- @long_acl.stubs(:match?).returns(false)
- @short_acl.stubs(:match?).returns(true)
+ @long_acl.stubs(:match?).returns(false)
+ @short_acl.stubs(:match?).returns(true)
- @long_acl.expects(:allowed?).never
- @short_acl.expects(:allowed?).returns(true)
+ @long_acl.expects(:allowed?).never
+ @short_acl.expects(:allowed?).returns(true)
- @right.fail_on_deny("/path/to/there/and/there", {})
- end
+ @right.fail_on_deny("/path/to/there/and/there", {})
+ end
- it "should not raise an AuthorizationError if allowed" do
- @right.newright("/path/to/there", 0)
+ it "should not raise an AuthorizationError if allowed" do
+ @right.newright("/path/to/there", 0)
- @long_acl.stubs(:match?).returns(true)
- @long_acl.stubs(:allowed?).returns(true)
+ @long_acl.stubs(:match?).returns(true)
+ @long_acl.stubs(:allowed?).returns(true)
- lambda { @right.fail_on_deny("/path/to/there/and/there", {}) }.should_not raise_error(Puppet::Network::AuthorizationError)
- end
+ lambda { @right.fail_on_deny("/path/to/there/and/there", {}) }.should_not raise_error(Puppet::Network::AuthorizationError)
+ end
- it "should raise an AuthorizationError if the match is denied" do
- @right.newright("/path/to/there", 0, nil)
+ it "should raise an AuthorizationError if the match is denied" do
+ @right.newright("/path/to/there", 0, nil)
- @long_acl.stubs(:match?).returns(true)
- @long_acl.stubs(:allowed?).returns(false)
+ @long_acl.stubs(:match?).returns(true)
+ @long_acl.stubs(:allowed?).returns(false)
- lambda{ @right.fail_on_deny("/path/to/there", {}) }.should raise_error(Puppet::Network::AuthorizationError)
- end
+ lambda{ @right.fail_on_deny("/path/to/there", {}) }.should raise_error(Puppet::Network::AuthorizationError)
+ end
- it "should raise an AuthorizationError if no path match" do
- lambda { @right.fail_on_deny("/nomatch", {}) }.should raise_error(Puppet::Network::AuthorizationError)
- end
- end
+ it "should raise an AuthorizationError if no path match" do
+ lambda { @right.fail_on_deny("/nomatch", {}) }.should raise_error(Puppet::Network::AuthorizationError)
+ end
+ end
- describe "with regex acls" do
- before :each do
- @regex_acl1 = stub 'regex_acl1', :name => "/files/(.*)/myfile", :acl_type => :regex, :line => 0, :file => 'dummy'
- Puppet::Network::Rights::Right.stubs(:new).with("~ /files/(.*)/myfile", 0, nil).returns(@regex_acl1)
+ describe "with regex acls" do
+ before :each do
+ @regex_acl1 = stub 'regex_acl1', :name => "/files/(.*)/myfile", :acl_type => :regex, :line => 0, :file => 'dummy'
+ Puppet::Network::Rights::Right.stubs(:new).with("~ /files/(.*)/myfile", 0, nil).returns(@regex_acl1)
- @regex_acl2 = stub 'regex_acl2', :name => "/files/(.*)/myfile/", :acl_type => :regex, :line => 0, :file => 'dummy'
- Puppet::Network::Rights::Right.stubs(:new).with("~ /files/(.*)/myfile/", 0, nil).returns(@regex_acl2)
+ @regex_acl2 = stub 'regex_acl2', :name => "/files/(.*)/myfile/", :acl_type => :regex, :line => 0, :file => 'dummy'
+ Puppet::Network::Rights::Right.stubs(:new).with("~ /files/(.*)/myfile/", 0, nil).returns(@regex_acl2)
- @regex_acl1.stubs(:"<=>").with(@regex_acl2).returns(0)
- @regex_acl2.stubs(:"<=>").with(@regex_acl1).returns(0)
- end
+ @regex_acl1.stubs(:"<=>").with(@regex_acl2).returns(0)
+ @regex_acl2.stubs(:"<=>").with(@regex_acl1).returns(0)
+ end
- it "should select the first match" do
- @right.newright("~ /files/(.*)/myfile", 0)
- @right.newright("~ /files/(.*)/myfile/", 0)
+ it "should select the first match" do
+ @right.newright("~ /files/(.*)/myfile", 0)
+ @right.newright("~ /files/(.*)/myfile/", 0)
- @regex_acl1.stubs(:match?).returns(true)
- @regex_acl2.stubs(:match?).returns(true)
+ @regex_acl1.stubs(:match?).returns(true)
+ @regex_acl2.stubs(:match?).returns(true)
- @regex_acl1.expects(:allowed?).returns(true)
- @regex_acl2.expects(:allowed?).never
+ @regex_acl1.expects(:allowed?).returns(true)
+ @regex_acl2.expects(:allowed?).never
- @right.fail_on_deny("/files/repository/myfile/other", {})
- end
+ @right.fail_on_deny("/files/repository/myfile/other", {})
+ end
- it "should select the first match that doesn't return :dunno" do
- @right.newright("~ /files/(.*)/myfile", 0)
- @right.newright("~ /files/(.*)/myfile/", 0)
+ it "should select the first match that doesn't return :dunno" do
+ @right.newright("~ /files/(.*)/myfile", 0)
+ @right.newright("~ /files/(.*)/myfile/", 0)
- @regex_acl1.stubs(:match?).returns(true)
- @regex_acl2.stubs(:match?).returns(true)
+ @regex_acl1.stubs(:match?).returns(true)
+ @regex_acl2.stubs(:match?).returns(true)
- @regex_acl1.expects(:allowed?).returns(:dunno)
- @regex_acl2.expects(:allowed?).returns(true)
+ @regex_acl1.expects(:allowed?).returns(:dunno)
+ @regex_acl2.expects(:allowed?).returns(true)
- @right.fail_on_deny("/files/repository/myfile/other", {})
- end
+ @right.fail_on_deny("/files/repository/myfile/other", {})
+ end
- it "should not select an ACL that doesn't match" do
- @right.newright("~ /files/(.*)/myfile", 0)
- @right.newright("~ /files/(.*)/myfile/", 0)
+ it "should not select an ACL that doesn't match" do
+ @right.newright("~ /files/(.*)/myfile", 0)
+ @right.newright("~ /files/(.*)/myfile/", 0)
- @regex_acl1.stubs(:match?).returns(false)
- @regex_acl2.stubs(:match?).returns(true)
+ @regex_acl1.stubs(:match?).returns(false)
+ @regex_acl2.stubs(:match?).returns(true)
- @regex_acl1.expects(:allowed?).never
- @regex_acl2.expects(:allowed?).returns(true)
+ @regex_acl1.expects(:allowed?).never
+ @regex_acl2.expects(:allowed?).returns(true)
- @right.fail_on_deny("/files/repository/myfile/other", {})
- end
+ @right.fail_on_deny("/files/repository/myfile/other", {})
+ end
- it "should not raise an AuthorizationError if allowed" do
- @right.newright("~ /files/(.*)/myfile", 0)
+ it "should not raise an AuthorizationError if allowed" do
+ @right.newright("~ /files/(.*)/myfile", 0)
- @regex_acl1.stubs(:match?).returns(true)
- @regex_acl1.stubs(:allowed?).returns(true)
+ @regex_acl1.stubs(:match?).returns(true)
+ @regex_acl1.stubs(:allowed?).returns(true)
- lambda { @right.fail_on_deny("/files/repository/myfile/other", {}) }.should_not raise_error(Puppet::Network::AuthorizationError)
- end
+ lambda { @right.fail_on_deny("/files/repository/myfile/other", {}) }.should_not raise_error(Puppet::Network::AuthorizationError)
+ end
- it "should raise an error if no regex acl match" do
- lambda{ @right.fail_on_deny("/path", {}) }.should raise_error(Puppet::Network::AuthorizationError)
- end
+ it "should raise an error if no regex acl match" do
+ lambda{ @right.fail_on_deny("/path", {}) }.should raise_error(Puppet::Network::AuthorizationError)
+ end
- it "should raise an AuthorizedError on deny" do
- lambda { @right.fail_on_deny("/path", {}) }.should raise_error(Puppet::Network::AuthorizationError)
- end
+ it "should raise an AuthorizedError on deny" do
+ lambda { @right.fail_on_deny("/path", {}) }.should raise_error(Puppet::Network::AuthorizationError)
+ end
- end
end
+ end
- describe Puppet::Network::Rights::Right do
- before :each do
- @acl = Puppet::Network::Rights::Right.new("/path",0, nil)
- end
+ describe Puppet::Network::Rights::Right do
+ before :each do
+ @acl = Puppet::Network::Rights::Right.new("/path",0, nil)
+ end
- describe "with path" do
- it "should say it's a regex ACL" do
- @acl.acl_type.should == :regex
- end
+ describe "with path" do
+ it "should say it's a regex ACL" do
+ @acl.acl_type.should == :regex
+ end
- it "should match up to its path length" do
- @acl.match?("/path/that/works").should_not be_nil
- end
+ it "should match up to its path length" do
+ @acl.match?("/path/that/works").should_not be_nil
+ end
- it "should match up to its path length" do
- @acl.match?("/paththatalsoworks").should_not be_nil
- end
+ it "should match up to its path length" do
+ @acl.match?("/paththatalsoworks").should_not be_nil
+ end
- it "should return nil if no match" do
- @acl.match?("/notpath").should be_nil
- end
- end
+ it "should return nil if no match" do
+ @acl.match?("/notpath").should be_nil
+ end
+ end
- describe "with regex" do
- before :each do
- @acl = Puppet::Network::Rights::Right.new("~ .rb$",0, nil)
- end
+ describe "with regex" do
+ before :each do
+ @acl = Puppet::Network::Rights::Right.new("~ .rb$",0, nil)
+ end
- it "should say it's a regex ACL" do
- @acl.acl_type.should == :regex
- end
+ it "should say it's a regex ACL" do
+ @acl.acl_type.should == :regex
+ end
- it "should match as a regex" do
- @acl.match?("this should work.rb").should_not be_nil
- end
+ it "should match as a regex" do
+ @acl.match?("this should work.rb").should_not be_nil
+ end
- it "should return nil if no match" do
- @acl.match?("do not match").should be_nil
- end
- end
+ it "should return nil if no match" do
+ @acl.match?("do not match").should be_nil
+ end
+ end
- it "should allow all rest methods by default" do
- @acl.methods.should == Puppet::Network::Rights::Right::ALL
- end
+ it "should allow all rest methods by default" do
+ @acl.methods.should == Puppet::Network::Rights::Right::ALL
+ end
- it "should allow only authenticated request by default" do
- @acl.authentication.should be_true
- end
+ it "should allow only authenticated request by default" do
+ @acl.authentication.should be_true
+ end
- it "should allow modification of the methods filters" do
- @acl.restrict_method(:save)
+ it "should allow modification of the methods filters" do
+ @acl.restrict_method(:save)
- @acl.methods.should == [:save]
- end
+ @acl.methods.should == [:save]
+ end
- it "should stack methods filters" do
- @acl.restrict_method(:save)
- @acl.restrict_method(:destroy)
+ it "should stack methods filters" do
+ @acl.restrict_method(:save)
+ @acl.restrict_method(:destroy)
- @acl.methods.should == [:save, :destroy]
- end
+ @acl.methods.should == [:save, :destroy]
+ end
- it "should raise an error if the method is already filtered" do
- @acl.restrict_method(:save)
+ it "should raise an error if the method is already filtered" do
+ @acl.restrict_method(:save)
- lambda { @acl.restrict_method(:save) }.should raise_error
- end
+ lambda { @acl.restrict_method(:save) }.should raise_error
+ end
- it "should allow setting an environment filters" do
- Puppet::Node::Environment.stubs(:new).with(:environment).returns(:env)
+ it "should allow setting an environment filters" do
+ Puppet::Node::Environment.stubs(:new).with(:environment).returns(:env)
- @acl.restrict_environment(:environment)
+ @acl.restrict_environment(:environment)
- @acl.environment.should == [:env]
- end
+ @acl.environment.should == [:env]
+ end
- ["on", "yes", "true", true].each do |auth|
- it "should allow filtering on authenticated requests with '#{auth}'" do
- @acl.restrict_authenticated(auth)
+ ["on", "yes", "true", true].each do |auth|
+ it "should allow filtering on authenticated requests with '#{auth}'" do
+ @acl.restrict_authenticated(auth)
- @acl.authentication.should be_true
- end
- end
+ @acl.authentication.should be_true
+ end
+ end
- ["off", "no", "false", false].each do |auth|
- it "should allow filtering on unauthenticated requests with '#{auth}'" do
- @acl.restrict_authenticated(auth)
+ ["off", "no", "false", false].each do |auth|
+ it "should allow filtering on unauthenticated requests with '#{auth}'" do
+ @acl.restrict_authenticated(auth)
- @acl.authentication.should be_false
- end
- end
+ @acl.authentication.should be_false
+ end
+ end
- ["all", "any", :all, :any].each do |auth|
- it "should not use request authenticated state filtering with '#{auth}'" do
- @acl.restrict_authenticated(auth)
+ ["all", "any", :all, :any].each do |auth|
+ it "should not use request authenticated state filtering with '#{auth}'" do
+ @acl.restrict_authenticated(auth)
- @acl.authentication.should be_nil
- end
- end
+ @acl.authentication.should be_nil
+ end
+ end
- describe "when checking right authorization" do
- it "should return :dunno if this right is not restricted to the given method" do
- @acl.restrict_method(:destroy)
+ describe "when checking right authorization" do
+ it "should return :dunno if this right is not restricted to the given method" do
+ @acl.restrict_method(:destroy)
- @acl.allowed?("me","127.0.0.1", { :method => :save } ).should == :dunno
- end
+ @acl.allowed?("me","127.0.0.1", { :method => :save } ).should == :dunno
+ end
- it "should return allow/deny if this right is restricted to the given method" do
- @acl.restrict_method(:save)
- @acl.allow("127.0.0.1")
+ it "should return allow/deny if this right is restricted to the given method" do
+ @acl.restrict_method(:save)
+ @acl.allow("127.0.0.1")
- @acl.allowed?("me","127.0.0.1", { :method => :save }).should be_true
- end
+ @acl.allowed?("me","127.0.0.1", { :method => :save }).should be_true
+ end
- it "should return :dunno if this right is not restricted to the given environment" do
- Puppet::Node::Environment.stubs(:new).returns(:production)
+ it "should return :dunno if this right is not restricted to the given environment" do
+ Puppet::Node::Environment.stubs(:new).returns(:production)
- @acl.restrict_environment(:production)
+ @acl.restrict_environment(:production)
- @acl.allowed?("me","127.0.0.1", { :method => :save, :environment => :development }).should == :dunno
- end
+ @acl.allowed?("me","127.0.0.1", { :method => :save, :environment => :development }).should == :dunno
+ end
- it "should return :dunno if this right is not restricted to the given request authentication state" do
- @acl.restrict_authenticated(true)
+ it "should return :dunno if this right is not restricted to the given request authentication state" do
+ @acl.restrict_authenticated(true)
- @acl.allowed?("me","127.0.0.1", { :method => :save, :authenticated => false }).should == :dunno
- end
+ @acl.allowed?("me","127.0.0.1", { :method => :save, :authenticated => false }).should == :dunno
+ end
- it "should return allow/deny if this right is restricted to the given request authentication state" do
- @acl.restrict_authenticated(false)
- @acl.allow("127.0.0.1")
+ it "should return allow/deny if this right is restricted to the given request authentication state" do
+ @acl.restrict_authenticated(false)
+ @acl.allow("127.0.0.1")
- @acl.allowed?("me","127.0.0.1", { :authenticated => false }).should be_true
- end
+ @acl.allowed?("me","127.0.0.1", { :authenticated => false }).should be_true
+ end
- it "should interpolate allow/deny patterns with the given match" do
- @acl.expects(:interpolate).with(:match)
+ it "should interpolate allow/deny patterns with the given match" do
+ @acl.expects(:interpolate).with(:match)
- @acl.allowed?("me","127.0.0.1", { :method => :save, :match => :match, :authenticated => true })
- end
+ @acl.allowed?("me","127.0.0.1", { :method => :save, :match => :match, :authenticated => true })
+ end
- it "should reset interpolation after the match" do
- @acl.expects(:reset_interpolation)
+ it "should reset interpolation after the match" do
+ @acl.expects(:reset_interpolation)
- @acl.allowed?("me","127.0.0.1", { :method => :save, :match => :match, :authenticated => true })
- end
+ @acl.allowed?("me","127.0.0.1", { :method => :save, :match => :match, :authenticated => true })
+ end
- # mocha doesn't allow testing super...
- # it "should delegate to the AuthStore for the result" do
- # @acl.method(:save)
- #
- # @acl.expects(:allowed?).with("me","127.0.0.1")
- #
- # @acl.allowed?("me","127.0.0.1", :save)
- # end
- end
+ # mocha doesn't allow testing super...
+ # it "should delegate to the AuthStore for the result" do
+ # @acl.method(:save)
+ #
+ # @acl.expects(:allowed?).with("me","127.0.0.1")
+ #
+ # @acl.allowed?("me","127.0.0.1", :save)
+ # end
end
+ end
end
diff --git a/spec/unit/network/server_spec.rb b/spec/unit/network/server_spec.rb
index 4ebbe08..ccd9c08 100755
--- a/spec/unit/network/server_spec.rb
+++ b/spec/unit/network/server_spec.rb
@@ -7,528 +7,528 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/network/server'
describe Puppet::Network::Server do
+ before do
+ @mock_http_server_class = mock('http server class')
+ Puppet.settings.stubs(:use)
+ Puppet.settings.stubs(:value).with(:name).returns("me")
+ Puppet.settings.stubs(:value).with(:servertype).returns(:suparserver)
+ Puppet.settings.stubs(:value).with(:bindaddress).returns("")
+ Puppet.settings.stubs(:value).with(:masterport).returns(8140)
+ Puppet::Network::HTTP.stubs(:server_class_by_type).returns(@mock_http_server_class)
+ Puppet.settings.stubs(:value).with(:servertype).returns(:suparserver)
+ @server = Puppet::Network::Server.new(:port => 31337)
+ end
+
+ describe "when initializing" do
before do
- @mock_http_server_class = mock('http server class')
- Puppet.settings.stubs(:use)
- Puppet.settings.stubs(:value).with(:name).returns("me")
- Puppet.settings.stubs(:value).with(:servertype).returns(:suparserver)
- Puppet.settings.stubs(:value).with(:bindaddress).returns("")
- Puppet.settings.stubs(:value).with(:masterport).returns(8140)
- Puppet::Network::HTTP.stubs(:server_class_by_type).returns(@mock_http_server_class)
- Puppet.settings.stubs(:value).with(:servertype).returns(:suparserver)
- @server = Puppet::Network::Server.new(:port => 31337)
- end
-
- describe "when initializing" do
- before do
- Puppet::Indirector::Indirection.stubs(:model).returns mock('indirection')
- Puppet::Network::Handler.stubs(:handler).returns mock('xmlrpc_handler')
- Puppet.settings.stubs(:value).with(:bindaddress).returns("")
- Puppet.settings.stubs(:value).with(:masterport).returns('')
- end
-
- it 'should fail if an unknown option is provided' do
- lambda { Puppet::Network::Server.new(:foo => 31337) }.should raise_error(ArgumentError)
- end
-
- it "should allow specifying a listening port" do
- Puppet.settings.stubs(:value).with(:bindaddress).returns('')
- @server = Puppet::Network::Server.new(:port => 31337)
- @server.port.should == 31337
- end
-
- it "should use the :bindaddress setting to determine the default listening address" do
- Puppet.settings.stubs(:value).with(:masterport).returns('')
- Puppet.settings.expects(:value).with(:bindaddress).returns("10.0.0.1")
- @server = Puppet::Network::Server.new
- @server.address.should == "10.0.0.1"
- end
-
- it "should set the bind address to '127.0.0.1' if the default address is an empty string and the server type is mongrel" do
- Puppet.settings.stubs(:value).with(:servertype).returns("mongrel")
- Puppet.settings.expects(:value).with(:bindaddress).returns("")
- @server = Puppet::Network::Server.new
- @server.address.should == '127.0.0.1'
- end
-
- it "should set the bind address to '0.0.0.0' if the default address is an empty string and the server type is webrick" do
- Puppet.settings.stubs(:value).with(:servertype).returns("webrick")
- Puppet.settings.expects(:value).with(:bindaddress).returns("")
- @server = Puppet::Network::Server.new
- @server.address.should == '0.0.0.0'
- end
-
- it "should use the Puppet configurator to find a default listening port" do
- Puppet.settings.stubs(:value).with(:bindaddress).returns('')
- Puppet.settings.expects(:value).with(:masterport).returns(6667)
- @server = Puppet::Network::Server.new
- @server.port.should == 6667
- end
-
- it "should fail to initialize if no listening port can be found" do
- Puppet.settings.stubs(:value).with(:bindaddress).returns("127.0.0.1")
- Puppet.settings.stubs(:value).with(:masterport).returns(nil)
- lambda { Puppet::Network::Server.new }.should raise_error(ArgumentError)
- end
-
- it "should use the Puppet configurator to determine which HTTP server will be used to provide access to clients" do
- Puppet.settings.expects(:value).with(:servertype).returns(:suparserver)
- @server = Puppet::Network::Server.new(:port => 31337)
- @server.server_type.should == :suparserver
- end
-
- it "should fail to initialize if there is no HTTP server known to the Puppet configurator" do
- Puppet.settings.expects(:value).with(:servertype).returns(nil)
- lambda { Puppet::Network::Server.new(:port => 31337) }.should raise_error
- end
-
- it "should ask the Puppet::Network::HTTP class to fetch the proper HTTP server class" do
- Puppet::Network::HTTP.expects(:server_class_by_type).with(:suparserver).returns(@mock_http_server_class)
- @server = Puppet::Network::Server.new(:port => 31337)
- end
-
- it "should fail if the HTTP server class is unknown" do
- Puppet::Network::HTTP.stubs(:server_class_by_type).returns(nil)
- lambda { Puppet::Network::Server.new(:port => 31337) }.should raise_error(ArgumentError)
- end
-
- it "should allow registering REST handlers" do
- @server = Puppet::Network::Server.new(:port => 31337, :handlers => [ :foo, :bar, :baz])
- lambda { @server.unregister(:foo, :bar, :baz) }.should_not raise_error
- end
-
- it "should allow registering XMLRPC handlers" do
- @server = Puppet::Network::Server.new(:port => 31337, :xmlrpc_handlers => [ :foo, :bar, :baz])
- lambda { @server.unregister_xmlrpc(:foo, :bar, :baz) }.should_not raise_error
- end
-
- it "should not be listening after initialization" do
- Puppet::Network::Server.new(:port => 31337).should_not be_listening
- end
-
- it "should use the :main setting section" do
- Puppet.settings.expects(:use).with { |*args| args.include?(:main) }
- @server = Puppet::Network::Server.new(:port => 31337, :xmlrpc_handlers => [ :foo, :bar, :baz])
- end
-
- it "should use the Puppet[:name] setting section" do
- Puppet.settings.expects(:value).with(:name).returns "me"
- Puppet.settings.expects(:use).with { |*args| args.include?("me") }
-
- @server = Puppet::Network::Server.new(:port => 31337, :xmlrpc_handlers => [ :foo, :bar, :baz])
- end
+ Puppet::Indirector::Indirection.stubs(:model).returns mock('indirection')
+ Puppet::Network::Handler.stubs(:handler).returns mock('xmlrpc_handler')
+ Puppet.settings.stubs(:value).with(:bindaddress).returns("")
+ Puppet.settings.stubs(:value).with(:masterport).returns('')
end
- # We don't test the method, because it's too much of a Unix-y pain.
- it "should be able to daemonize" do
- @server.should respond_to(:daemonize)
- end
-
- describe "when being started" do
- before do
- @server.stubs(:listen)
- @server.stubs(:create_pidfile)
- end
-
- it "should listen" do
- @server.expects(:listen)
- @server.start
- end
+ it 'should fail if an unknown option is provided' do
+ lambda { Puppet::Network::Server.new(:foo => 31337) }.should raise_error(ArgumentError)
+ end
+
+ it "should allow specifying a listening port" do
+ Puppet.settings.stubs(:value).with(:bindaddress).returns('')
+ @server = Puppet::Network::Server.new(:port => 31337)
+ @server.port.should == 31337
+ end
+
+ it "should use the :bindaddress setting to determine the default listening address" do
+ Puppet.settings.stubs(:value).with(:masterport).returns('')
+ Puppet.settings.expects(:value).with(:bindaddress).returns("10.0.0.1")
+ @server = Puppet::Network::Server.new
+ @server.address.should == "10.0.0.1"
+ end
+
+ it "should set the bind address to '127.0.0.1' if the default address is an empty string and the server type is mongrel" do
+ Puppet.settings.stubs(:value).with(:servertype).returns("mongrel")
+ Puppet.settings.expects(:value).with(:bindaddress).returns("")
+ @server = Puppet::Network::Server.new
+ @server.address.should == '127.0.0.1'
+ end
- it "should create its PID file" do
- @server.expects(:create_pidfile)
- @server.start
- end
+ it "should set the bind address to '0.0.0.0' if the default address is an empty string and the server type is webrick" do
+ Puppet.settings.stubs(:value).with(:servertype).returns("webrick")
+ Puppet.settings.expects(:value).with(:bindaddress).returns("")
+ @server = Puppet::Network::Server.new
+ @server.address.should == '0.0.0.0'
end
- describe "when being stopped" do
- before do
- @server.stubs(:unlisten)
- @server.stubs(:remove_pidfile)
- end
+ it "should use the Puppet configurator to find a default listening port" do
+ Puppet.settings.stubs(:value).with(:bindaddress).returns('')
+ Puppet.settings.expects(:value).with(:masterport).returns(6667)
+ @server = Puppet::Network::Server.new
+ @server.port.should == 6667
+ end
- it "should unlisten" do
- @server.expects(:unlisten)
- @server.stop
- end
+ it "should fail to initialize if no listening port can be found" do
+ Puppet.settings.stubs(:value).with(:bindaddress).returns("127.0.0.1")
+ Puppet.settings.stubs(:value).with(:masterport).returns(nil)
+ lambda { Puppet::Network::Server.new }.should raise_error(ArgumentError)
+ end
- it "should remove its PID file" do
- @server.expects(:remove_pidfile)
- @server.stop
- end
+ it "should use the Puppet configurator to determine which HTTP server will be used to provide access to clients" do
+ Puppet.settings.expects(:value).with(:servertype).returns(:suparserver)
+ @server = Puppet::Network::Server.new(:port => 31337)
+ @server.server_type.should == :suparserver
end
- describe "when creating its pidfile" do
- it "should use an exclusive mutex" do
- Puppet.settings.expects(:value).with(:name).returns "me"
+ it "should fail to initialize if there is no HTTP server known to the Puppet configurator" do
+ Puppet.settings.expects(:value).with(:servertype).returns(nil)
+ lambda { Puppet::Network::Server.new(:port => 31337) }.should raise_error
+ end
- sync = mock 'sync'
- Puppet::Util.expects(:sync).with("me").returns sync
+ it "should ask the Puppet::Network::HTTP class to fetch the proper HTTP server class" do
+ Puppet::Network::HTTP.expects(:server_class_by_type).with(:suparserver).returns(@mock_http_server_class)
+ @server = Puppet::Network::Server.new(:port => 31337)
+ end
- sync.expects(:synchronize).with(Sync::EX)
- @server.create_pidfile
- end
+ it "should fail if the HTTP server class is unknown" do
+ Puppet::Network::HTTP.stubs(:server_class_by_type).returns(nil)
+ lambda { Puppet::Network::Server.new(:port => 31337) }.should raise_error(ArgumentError)
+ end
- it "should lock the pidfile using the Pidlock class" do
- pidfile = mock 'pidfile'
+ it "should allow registering REST handlers" do
+ @server = Puppet::Network::Server.new(:port => 31337, :handlers => [ :foo, :bar, :baz])
+ lambda { @server.unregister(:foo, :bar, :baz) }.should_not raise_error
+ end
- Puppet.settings.stubs(:value).with(:name).returns "eh"
- Puppet.settings.expects(:value).with(:pidfile).returns "/my/file"
+ it "should allow registering XMLRPC handlers" do
+ @server = Puppet::Network::Server.new(:port => 31337, :xmlrpc_handlers => [ :foo, :bar, :baz])
+ lambda { @server.unregister_xmlrpc(:foo, :bar, :baz) }.should_not raise_error
+ end
+
+ it "should not be listening after initialization" do
+ Puppet::Network::Server.new(:port => 31337).should_not be_listening
+ end
+
+ it "should use the :main setting section" do
+ Puppet.settings.expects(:use).with { |*args| args.include?(:main) }
+ @server = Puppet::Network::Server.new(:port => 31337, :xmlrpc_handlers => [ :foo, :bar, :baz])
+ end
+
+ it "should use the Puppet[:name] setting section" do
+ Puppet.settings.expects(:value).with(:name).returns "me"
+ Puppet.settings.expects(:use).with { |*args| args.include?("me") }
+
+ @server = Puppet::Network::Server.new(:port => 31337, :xmlrpc_handlers => [ :foo, :bar, :baz])
+ end
+ end
+
+ # We don't test the method, because it's too much of a Unix-y pain.
+ it "should be able to daemonize" do
+ @server.should respond_to(:daemonize)
+ end
+
+ describe "when being started" do
+ before do
+ @server.stubs(:listen)
+ @server.stubs(:create_pidfile)
+ end
+
+ it "should listen" do
+ @server.expects(:listen)
+ @server.start
+ end
- Puppet::Util::Pidlock.expects(:new).with("/my/file").returns pidfile
+ it "should create its PID file" do
+ @server.expects(:create_pidfile)
+ @server.start
+ end
+ end
- pidfile.expects(:lock).returns true
- @server.create_pidfile
- end
+ describe "when being stopped" do
+ before do
+ @server.stubs(:unlisten)
+ @server.stubs(:remove_pidfile)
+ end
- it "should fail if it cannot lock" do
- pidfile = mock 'pidfile'
+ it "should unlisten" do
+ @server.expects(:unlisten)
+ @server.stop
+ end
- Puppet.settings.stubs(:value).with(:name).returns "eh"
- Puppet.settings.stubs(:value).with(:pidfile).returns "/my/file"
+ it "should remove its PID file" do
+ @server.expects(:remove_pidfile)
+ @server.stop
+ end
+ end
- Puppet::Util::Pidlock.expects(:new).with("/my/file").returns pidfile
+ describe "when creating its pidfile" do
+ it "should use an exclusive mutex" do
+ Puppet.settings.expects(:value).with(:name).returns "me"
- pidfile.expects(:lock).returns false
+ sync = mock 'sync'
+ Puppet::Util.expects(:sync).with("me").returns sync
- lambda { @server.create_pidfile }.should raise_error
- end
+ sync.expects(:synchronize).with(Sync::EX)
+ @server.create_pidfile
end
- describe "when removing its pidfile" do
- it "should use an exclusive mutex" do
- Puppet.settings.expects(:value).with(:name).returns "me"
+ it "should lock the pidfile using the Pidlock class" do
+ pidfile = mock 'pidfile'
- sync = mock 'sync'
- Puppet::Util.expects(:sync).with("me").returns sync
+ Puppet.settings.stubs(:value).with(:name).returns "eh"
+ Puppet.settings.expects(:value).with(:pidfile).returns "/my/file"
- sync.expects(:synchronize).with(Sync::EX)
- @server.remove_pidfile
- end
+ Puppet::Util::Pidlock.expects(:new).with("/my/file").returns pidfile
- it "should do nothing if the pidfile is not present" do
- pidfile = mock 'pidfile', :locked? => false
- Puppet::Util::Pidlock.expects(:new).with("/my/file").returns pidfile
+ pidfile.expects(:lock).returns true
+ @server.create_pidfile
+ end
- Puppet.settings.stubs(:value).with(:name).returns "eh"
- Puppet.settings.stubs(:value).with(:pidfile).returns "/my/file"
+ it "should fail if it cannot lock" do
+ pidfile = mock 'pidfile'
- pidfile.expects(:unlock).never
- @server.remove_pidfile
- end
+ Puppet.settings.stubs(:value).with(:name).returns "eh"
+ Puppet.settings.stubs(:value).with(:pidfile).returns "/my/file"
- it "should unlock the pidfile using the Pidlock class" do
- pidfile = mock 'pidfile', :locked? => true
- Puppet::Util::Pidlock.expects(:new).with("/my/file").returns pidfile
- pidfile.expects(:unlock).returns true
+ Puppet::Util::Pidlock.expects(:new).with("/my/file").returns pidfile
- Puppet.settings.stubs(:value).with(:name).returns "eh"
- Puppet.settings.stubs(:value).with(:pidfile).returns "/my/file"
+ pidfile.expects(:lock).returns false
- @server.remove_pidfile
- end
+ lambda { @server.create_pidfile }.should raise_error
+ end
+ end
- it "should warn if it cannot remove the pidfile" do
- pidfile = mock 'pidfile', :locked? => true
- Puppet::Util::Pidlock.expects(:new).with("/my/file").returns pidfile
- pidfile.expects(:unlock).returns false
+ describe "when removing its pidfile" do
+ it "should use an exclusive mutex" do
+ Puppet.settings.expects(:value).with(:name).returns "me"
- Puppet.settings.stubs(:value).with(:name).returns "eh"
- Puppet.settings.stubs(:value).with(:pidfile).returns "/my/file"
+ sync = mock 'sync'
+ Puppet::Util.expects(:sync).with("me").returns sync
- Puppet.expects :err
- @server.remove_pidfile
- end
+ sync.expects(:synchronize).with(Sync::EX)
+ @server.remove_pidfile
end
- describe "when managing indirection registrations" do
- before do
- Puppet::Indirector::Indirection.stubs(:model).returns mock('indirection')
- end
+ it "should do nothing if the pidfile is not present" do
+ pidfile = mock 'pidfile', :locked? => false
+ Puppet::Util::Pidlock.expects(:new).with("/my/file").returns pidfile
- it "should allow registering an indirection for client access by specifying its indirection name" do
- lambda { @server.register(:foo) }.should_not raise_error
- end
+ Puppet.settings.stubs(:value).with(:name).returns "eh"
+ Puppet.settings.stubs(:value).with(:pidfile).returns "/my/file"
- it "should require that the indirection be valid" do
- Puppet::Indirector::Indirection.expects(:model).with(:foo).returns nil
- lambda { @server.register(:foo) }.should raise_error(ArgumentError)
- end
+ pidfile.expects(:unlock).never
+ @server.remove_pidfile
+ end
- it "should require at least one indirection name when registering indirections for client access" do
- lambda { @server.register }.should raise_error(ArgumentError)
- end
+ it "should unlock the pidfile using the Pidlock class" do
+ pidfile = mock 'pidfile', :locked? => true
+ Puppet::Util::Pidlock.expects(:new).with("/my/file").returns pidfile
+ pidfile.expects(:unlock).returns true
- it "should allow for numerous indirections to be registered at once for client access" do
- lambda { @server.register(:foo, :bar, :baz) }.should_not raise_error
- end
+ Puppet.settings.stubs(:value).with(:name).returns "eh"
+ Puppet.settings.stubs(:value).with(:pidfile).returns "/my/file"
- it "should allow the use of indirection names to specify which indirections are to be no longer accessible to clients" do
- @server.register(:foo)
- lambda { @server.unregister(:foo) }.should_not raise_error
- end
+ @server.remove_pidfile
+ end
- it "should leave other indirections accessible to clients when turning off indirections" do
- @server.register(:foo, :bar)
- @server.unregister(:foo)
- lambda { @server.unregister(:bar)}.should_not raise_error
- end
+ it "should warn if it cannot remove the pidfile" do
+ pidfile = mock 'pidfile', :locked? => true
+ Puppet::Util::Pidlock.expects(:new).with("/my/file").returns pidfile
+ pidfile.expects(:unlock).returns false
- it "should allow specifying numerous indirections which are to be no longer accessible to clients" do
- @server.register(:foo, :bar)
- lambda { @server.unregister(:foo, :bar) }.should_not raise_error
- end
+ Puppet.settings.stubs(:value).with(:name).returns "eh"
+ Puppet.settings.stubs(:value).with(:pidfile).returns "/my/file"
- it "should not turn off any indirections if given unknown indirection names to turn off" do
- @server.register(:foo, :bar)
- lambda { @server.unregister(:foo, :bar, :baz) }.should raise_error(ArgumentError)
- lambda { @server.unregister(:foo, :bar) }.should_not raise_error
- end
+ Puppet.expects :err
+ @server.remove_pidfile
+ end
+ end
- it "should not allow turning off unknown indirection names" do
- @server.register(:foo, :bar)
- lambda { @server.unregister(:baz) }.should raise_error(ArgumentError)
- end
+ describe "when managing indirection registrations" do
+ before do
+ Puppet::Indirector::Indirection.stubs(:model).returns mock('indirection')
+ end
- it "should disable client access immediately when turning off indirections" do
- @server.register(:foo, :bar)
- @server.unregister(:foo)
- lambda { @server.unregister(:foo) }.should raise_error(ArgumentError)
- end
+ it "should allow registering an indirection for client access by specifying its indirection name" do
+ lambda { @server.register(:foo) }.should_not raise_error
+ end
- it "should allow turning off all indirections at once" do
- @server.register(:foo, :bar)
- @server.unregister
- [ :foo, :bar, :baz].each do |indirection|
- lambda { @server.unregister(indirection) }.should raise_error(ArgumentError)
- end
- end
+ it "should require that the indirection be valid" do
+ Puppet::Indirector::Indirection.expects(:model).with(:foo).returns nil
+ lambda { @server.register(:foo) }.should raise_error(ArgumentError)
end
- it "should provide a means of determining whether it is listening" do
- @server.should respond_to(:listening?)
+ it "should require at least one indirection name when registering indirections for client access" do
+ lambda { @server.register }.should raise_error(ArgumentError)
end
- it "should provide a means of determining which HTTP server will be used to provide access to clients" do
- @server.server_type.should == :suparserver
+ it "should allow for numerous indirections to be registered at once for client access" do
+ lambda { @server.register(:foo, :bar, :baz) }.should_not raise_error
end
- it "should provide a means of determining which protocols are in use" do
- @server.should respond_to(:protocols)
+ it "should allow the use of indirection names to specify which indirections are to be no longer accessible to clients" do
+ @server.register(:foo)
+ lambda { @server.unregister(:foo) }.should_not raise_error
end
- it "should set the protocols to :rest and :xmlrpc" do
- @server.protocols.should == [ :rest, :xmlrpc ]
+ it "should leave other indirections accessible to clients when turning off indirections" do
+ @server.register(:foo, :bar)
+ @server.unregister(:foo)
+ lambda { @server.unregister(:bar)}.should_not raise_error
end
- it "should provide a means of determining the listening address" do
- @server.address.should == "127.0.0.1"
+ it "should allow specifying numerous indirections which are to be no longer accessible to clients" do
+ @server.register(:foo, :bar)
+ lambda { @server.unregister(:foo, :bar) }.should_not raise_error
end
- it "should provide a means of determining the listening port" do
- @server.port.should == 31337
+ it "should not turn off any indirections if given unknown indirection names to turn off" do
+ @server.register(:foo, :bar)
+ lambda { @server.unregister(:foo, :bar, :baz) }.should raise_error(ArgumentError)
+ lambda { @server.unregister(:foo, :bar) }.should_not raise_error
end
- it "should allow for multiple configurations, each handling different indirections" do
- Puppet::Indirector::Indirection.stubs(:model).returns mock('indirection')
+ it "should not allow turning off unknown indirection names" do
+ @server.register(:foo, :bar)
+ lambda { @server.unregister(:baz) }.should raise_error(ArgumentError)
+ end
- @server2 = Puppet::Network::Server.new(:port => 31337)
- @server.register(:foo, :bar)
- @server2.register(:foo, :xyzzy)
- @server.unregister(:foo, :bar)
- @server2.unregister(:foo, :xyzzy)
- lambda { @server.unregister(:xyzzy) }.should raise_error(ArgumentError)
- lambda { @server2.unregister(:bar) }.should raise_error(ArgumentError)
+ it "should disable client access immediately when turning off indirections" do
+ @server.register(:foo, :bar)
+ @server.unregister(:foo)
+ lambda { @server.unregister(:foo) }.should raise_error(ArgumentError)
end
- describe "when managing xmlrpc registrations" do
- before do
- Puppet::Network::Handler.stubs(:handler).returns mock('xmlrpc_handler')
- end
+ it "should allow turning off all indirections at once" do
+ @server.register(:foo, :bar)
+ @server.unregister
+ [ :foo, :bar, :baz].each do |indirection|
+ lambda { @server.unregister(indirection) }.should raise_error(ArgumentError)
+ end
+ end
+ end
- it "should allow registering an xmlrpc handler by specifying its namespace" do
- lambda { @server.register_xmlrpc(:foo) }.should_not raise_error
- end
+ it "should provide a means of determining whether it is listening" do
+ @server.should respond_to(:listening?)
+ end
- it "should require that the xmlrpc namespace be valid" do
- Puppet::Network::Handler.stubs(:handler).returns nil
+ it "should provide a means of determining which HTTP server will be used to provide access to clients" do
+ @server.server_type.should == :suparserver
+ end
- lambda { @server.register_xmlrpc(:foo) }.should raise_error(ArgumentError)
- end
+ it "should provide a means of determining which protocols are in use" do
+ @server.should respond_to(:protocols)
+ end
- it "should require at least one namespace" do
- lambda { @server.register_xmlrpc }.should raise_error(ArgumentError)
- end
+ it "should set the protocols to :rest and :xmlrpc" do
+ @server.protocols.should == [ :rest, :xmlrpc ]
+ end
- it "should allow multiple namespaces to be registered at once" do
- lambda { @server.register_xmlrpc(:foo, :bar) }.should_not raise_error
- end
+ it "should provide a means of determining the listening address" do
+ @server.address.should == "127.0.0.1"
+ end
- it "should allow the use of namespaces to specify which are no longer accessible to clients" do
- @server.register_xmlrpc(:foo, :bar)
- end
+ it "should provide a means of determining the listening port" do
+ @server.port.should == 31337
+ end
- it "should leave other namespaces accessible to clients when turning off xmlrpc namespaces" do
- @server.register_xmlrpc(:foo, :bar)
- @server.unregister_xmlrpc(:foo)
- lambda { @server.unregister_xmlrpc(:bar)}.should_not raise_error
- end
+ it "should allow for multiple configurations, each handling different indirections" do
+ Puppet::Indirector::Indirection.stubs(:model).returns mock('indirection')
- it "should allow specifying numerous namespaces which are to be no longer accessible to clients" do
- @server.register_xmlrpc(:foo, :bar)
- lambda { @server.unregister_xmlrpc(:foo, :bar) }.should_not raise_error
- end
+ @server2 = Puppet::Network::Server.new(:port => 31337)
+ @server.register(:foo, :bar)
+ @server2.register(:foo, :xyzzy)
+ @server.unregister(:foo, :bar)
+ @server2.unregister(:foo, :xyzzy)
+ lambda { @server.unregister(:xyzzy) }.should raise_error(ArgumentError)
+ lambda { @server2.unregister(:bar) }.should raise_error(ArgumentError)
+ end
- it "should not turn off any indirections if given unknown namespaces to turn off" do
- @server.register_xmlrpc(:foo, :bar)
- lambda { @server.unregister_xmlrpc(:foo, :bar, :baz) }.should raise_error(ArgumentError)
- lambda { @server.unregister_xmlrpc(:foo, :bar) }.should_not raise_error
- end
+ describe "when managing xmlrpc registrations" do
+ before do
+ Puppet::Network::Handler.stubs(:handler).returns mock('xmlrpc_handler')
+ end
- it "should not allow turning off unknown namespaces" do
- @server.register_xmlrpc(:foo, :bar)
- lambda { @server.unregister_xmlrpc(:baz) }.should raise_error(ArgumentError)
- end
+ it "should allow registering an xmlrpc handler by specifying its namespace" do
+ lambda { @server.register_xmlrpc(:foo) }.should_not raise_error
+ end
- it "should disable client access immediately when turning off namespaces" do
- @server.register_xmlrpc(:foo, :bar)
- @server.unregister_xmlrpc(:foo)
- lambda { @server.unregister_xmlrpc(:foo) }.should raise_error(ArgumentError)
- end
+ it "should require that the xmlrpc namespace be valid" do
+ Puppet::Network::Handler.stubs(:handler).returns nil
- it "should allow turning off all namespaces at once" do
- @server.register_xmlrpc(:foo, :bar)
- @server.unregister_xmlrpc
- [ :foo, :bar, :baz].each do |indirection|
- lambda { @server.unregister_xmlrpc(indirection) }.should raise_error(ArgumentError)
- end
- end
+ lambda { @server.register_xmlrpc(:foo) }.should raise_error(ArgumentError)
end
-
- describe "when listening is off" do
- before do
- @mock_http_server = mock('http server')
- @mock_http_server.stubs(:listen)
- @server.stubs(:http_server).returns(@mock_http_server)
- end
-
- it "should indicate that it is not listening" do
- @server.should_not be_listening
- end
-
- it "should not allow listening to be turned off" do
- lambda { @server.unlisten }.should raise_error(RuntimeError)
- end
-
- it "should allow listening to be turned on" do
- lambda { @server.listen }.should_not raise_error
- end
-
- end
-
- describe "when listening is on" do
- before do
- @mock_http_server = mock('http server')
- @mock_http_server.stubs(:listen)
- @mock_http_server.stubs(:unlisten)
- @server.stubs(:http_server).returns(@mock_http_server)
- @server.listen
- end
-
- it "should indicate that it is listening" do
- @server.should be_listening
- end
-
- it "should not allow listening to be turned on" do
- lambda { @server.listen }.should raise_error(RuntimeError)
- end
-
- it "should allow listening to be turned off" do
- lambda { @server.unlisten }.should_not raise_error
- end
- end
-
- describe "when listening is being turned on" do
- before do
- Puppet::Indirector::Indirection.stubs(:model).returns mock('indirection')
- Puppet::Network::Handler.stubs(:handler).returns mock('xmlrpc_handler')
-
- @server = Puppet::Network::Server.new(:port => 31337, :handlers => [:node], :xmlrpc_handlers => [:master])
- @mock_http_server = mock('http server')
- @mock_http_server.stubs(:listen)
- end
-
- it "should fetch an instance of an HTTP server" do
- @server.stubs(:http_server_class).returns(@mock_http_server_class)
- @mock_http_server_class.expects(:new).returns(@mock_http_server)
- @server.listen
- end
-
- it "should cause the HTTP server to listen" do
- @server.stubs(:http_server).returns(@mock_http_server)
- @mock_http_server.expects(:listen)
- @server.listen
- end
-
- it "should pass the listening address to the HTTP server" do
- @server.stubs(:http_server).returns(@mock_http_server)
- @mock_http_server.expects(:listen).with do |args|
- args[:address] == '127.0.0.1'
- end
- @server.listen
- end
-
- it "should pass the listening port to the HTTP server" do
- @server.stubs(:http_server).returns(@mock_http_server)
- @mock_http_server.expects(:listen).with do |args|
- args[:port] == 31337
- end
- @server.listen
- end
-
- it "should pass a list of REST handlers to the HTTP server" do
- @server.stubs(:http_server).returns(@mock_http_server)
- @mock_http_server.expects(:listen).with do |args|
- args[:handlers] == [ :node ]
- end
- @server.listen
- end
-
- it "should pass a list of XMLRPC handlers to the HTTP server" do
- @server.stubs(:http_server).returns(@mock_http_server)
- @mock_http_server.expects(:listen).with do |args|
- args[:xmlrpc_handlers] == [ :master ]
- end
- @server.listen
- end
-
- it "should pass a list of protocols to the HTTP server" do
- @server.stubs(:http_server).returns(@mock_http_server)
- @mock_http_server.expects(:listen).with do |args|
- args[:protocols] == [ :rest, :xmlrpc ]
- end
- @server.listen
- end
- end
-
- describe "when listening is being turned off" do
- before do
- @mock_http_server = mock('http server')
- @mock_http_server.stubs(:listen)
- @server.stubs(:http_server).returns(@mock_http_server)
- @server.listen
- end
-
- it "should cause the HTTP server to stop listening" do
- @mock_http_server.expects(:unlisten)
- @server.unlisten
- end
-
- it "should not allow for indirections to be turned off" do
- Puppet::Indirector::Indirection.stubs(:model).returns mock('indirection')
-
- @server.register(:foo)
- lambda { @server.unregister(:foo) }.should raise_error(RuntimeError)
- end
+
+ it "should require at least one namespace" do
+ lambda { @server.register_xmlrpc }.should raise_error(ArgumentError)
+ end
+
+ it "should allow multiple namespaces to be registered at once" do
+ lambda { @server.register_xmlrpc(:foo, :bar) }.should_not raise_error
+ end
+
+ it "should allow the use of namespaces to specify which are no longer accessible to clients" do
+ @server.register_xmlrpc(:foo, :bar)
+ end
+
+ it "should leave other namespaces accessible to clients when turning off xmlrpc namespaces" do
+ @server.register_xmlrpc(:foo, :bar)
+ @server.unregister_xmlrpc(:foo)
+ lambda { @server.unregister_xmlrpc(:bar)}.should_not raise_error
+ end
+
+ it "should allow specifying numerous namespaces which are to be no longer accessible to clients" do
+ @server.register_xmlrpc(:foo, :bar)
+ lambda { @server.unregister_xmlrpc(:foo, :bar) }.should_not raise_error
+ end
+
+ it "should not turn off any indirections if given unknown namespaces to turn off" do
+ @server.register_xmlrpc(:foo, :bar)
+ lambda { @server.unregister_xmlrpc(:foo, :bar, :baz) }.should raise_error(ArgumentError)
+ lambda { @server.unregister_xmlrpc(:foo, :bar) }.should_not raise_error
+ end
+
+ it "should not allow turning off unknown namespaces" do
+ @server.register_xmlrpc(:foo, :bar)
+ lambda { @server.unregister_xmlrpc(:baz) }.should raise_error(ArgumentError)
+ end
+
+ it "should disable client access immediately when turning off namespaces" do
+ @server.register_xmlrpc(:foo, :bar)
+ @server.unregister_xmlrpc(:foo)
+ lambda { @server.unregister_xmlrpc(:foo) }.should raise_error(ArgumentError)
+ end
+
+ it "should allow turning off all namespaces at once" do
+ @server.register_xmlrpc(:foo, :bar)
+ @server.unregister_xmlrpc
+ [ :foo, :bar, :baz].each do |indirection|
+ lambda { @server.unregister_xmlrpc(indirection) }.should raise_error(ArgumentError)
+ end
+ end
+ end
+
+ describe "when listening is off" do
+ before do
+ @mock_http_server = mock('http server')
+ @mock_http_server.stubs(:listen)
+ @server.stubs(:http_server).returns(@mock_http_server)
+ end
+
+ it "should indicate that it is not listening" do
+ @server.should_not be_listening
+ end
+
+ it "should not allow listening to be turned off" do
+ lambda { @server.unlisten }.should raise_error(RuntimeError)
+ end
+
+ it "should allow listening to be turned on" do
+ lambda { @server.listen }.should_not raise_error
+ end
+
+ end
+
+ describe "when listening is on" do
+ before do
+ @mock_http_server = mock('http server')
+ @mock_http_server.stubs(:listen)
+ @mock_http_server.stubs(:unlisten)
+ @server.stubs(:http_server).returns(@mock_http_server)
+ @server.listen
+ end
+
+ it "should indicate that it is listening" do
+ @server.should be_listening
+ end
+
+ it "should not allow listening to be turned on" do
+ lambda { @server.listen }.should raise_error(RuntimeError)
+ end
+
+ it "should allow listening to be turned off" do
+ lambda { @server.unlisten }.should_not raise_error
+ end
+ end
+
+ describe "when listening is being turned on" do
+ before do
+ Puppet::Indirector::Indirection.stubs(:model).returns mock('indirection')
+ Puppet::Network::Handler.stubs(:handler).returns mock('xmlrpc_handler')
+
+ @server = Puppet::Network::Server.new(:port => 31337, :handlers => [:node], :xmlrpc_handlers => [:master])
+ @mock_http_server = mock('http server')
+ @mock_http_server.stubs(:listen)
+ end
+
+ it "should fetch an instance of an HTTP server" do
+ @server.stubs(:http_server_class).returns(@mock_http_server_class)
+ @mock_http_server_class.expects(:new).returns(@mock_http_server)
+ @server.listen
+ end
+
+ it "should cause the HTTP server to listen" do
+ @server.stubs(:http_server).returns(@mock_http_server)
+ @mock_http_server.expects(:listen)
+ @server.listen
+ end
+
+ it "should pass the listening address to the HTTP server" do
+ @server.stubs(:http_server).returns(@mock_http_server)
+ @mock_http_server.expects(:listen).with do |args|
+ args[:address] == '127.0.0.1'
+ end
+ @server.listen
+ end
+
+ it "should pass the listening port to the HTTP server" do
+ @server.stubs(:http_server).returns(@mock_http_server)
+ @mock_http_server.expects(:listen).with do |args|
+ args[:port] == 31337
+ end
+ @server.listen
+ end
+
+ it "should pass a list of REST handlers to the HTTP server" do
+ @server.stubs(:http_server).returns(@mock_http_server)
+ @mock_http_server.expects(:listen).with do |args|
+ args[:handlers] == [ :node ]
+ end
+ @server.listen
+ end
+
+ it "should pass a list of XMLRPC handlers to the HTTP server" do
+ @server.stubs(:http_server).returns(@mock_http_server)
+ @mock_http_server.expects(:listen).with do |args|
+ args[:xmlrpc_handlers] == [ :master ]
+ end
+ @server.listen
+ end
+
+ it "should pass a list of protocols to the HTTP server" do
+ @server.stubs(:http_server).returns(@mock_http_server)
+ @mock_http_server.expects(:listen).with do |args|
+ args[:protocols] == [ :rest, :xmlrpc ]
+ end
+ @server.listen
+ end
+ end
+
+ describe "when listening is being turned off" do
+ before do
+ @mock_http_server = mock('http server')
+ @mock_http_server.stubs(:listen)
+ @server.stubs(:http_server).returns(@mock_http_server)
+ @server.listen
+ end
+
+ it "should cause the HTTP server to stop listening" do
+ @mock_http_server.expects(:unlisten)
+ @server.unlisten
+ end
+
+ it "should not allow for indirections to be turned off" do
+ Puppet::Indirector::Indirection.stubs(:model).returns mock('indirection')
+
+ @server.register(:foo)
+ lambda { @server.unregister(:foo) }.should raise_error(RuntimeError)
end
+ end
end
diff --git a/spec/unit/network/xmlrpc/client_spec.rb b/spec/unit/network/xmlrpc/client_spec.rb
index 1b97583..0b9b2b0 100755
--- a/spec/unit/network/xmlrpc/client_spec.rb
+++ b/spec/unit/network/xmlrpc/client_spec.rb
@@ -3,169 +3,169 @@
Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") }
describe Puppet::Network::XMLRPCClient do
- describe "when performing the rpc call" do
- before do
- Puppet::SSL::Host.any_instance.stubs(:certificate_matches_key?).returns true
- @client = Puppet::Network::Client.report.xmlrpc_client.new
- @client.stubs(:call).returns "foo"
- end
+ describe "when performing the rpc call" do
+ before do
+ Puppet::SSL::Host.any_instance.stubs(:certificate_matches_key?).returns true
+ @client = Puppet::Network::Client.report.xmlrpc_client.new
+ @client.stubs(:call).returns "foo"
+ end
- it "should call the specified namespace and method, with the specified arguments" do
- @client.expects(:call).with("puppetreports.report", "eh").returns "foo"
- @client.report("eh")
- end
+ it "should call the specified namespace and method, with the specified arguments" do
+ @client.expects(:call).with("puppetreports.report", "eh").returns "foo"
+ @client.report("eh")
+ end
- it "should return the results from the call" do
- @client.expects(:call).returns "foo"
- @client.report("eh").should == "foo"
- end
+ it "should return the results from the call" do
+ @client.expects(:call).returns "foo"
+ @client.report("eh").should == "foo"
+ end
- it "should always close the http connection if it is still open after the call" do
- http = mock 'http'
- @client.stubs(:http).returns http
+ it "should always close the http connection if it is still open after the call" do
+ http = mock 'http'
+ @client.stubs(:http).returns http
- http.expects(:started?).returns true
- http.expects(:finish)
+ http.expects(:started?).returns true
+ http.expects(:finish)
- @client.report("eh").should == "foo"
- end
+ @client.report("eh").should == "foo"
+ end
- it "should always close the http connection if it is still open after a call that raises an exception" do
- http = mock 'http'
- @client.stubs(:http).returns http
+ it "should always close the http connection if it is still open after a call that raises an exception" do
+ http = mock 'http'
+ @client.stubs(:http).returns http
- @client.expects(:call).raises RuntimeError
+ @client.expects(:call).raises RuntimeError
- http.expects(:started?).returns true
- http.expects(:finish)
+ http.expects(:started?).returns true
+ http.expects(:finish)
- lambda { @client.report("eh") }.should raise_error
- end
+ lambda { @client.report("eh") }.should raise_error
+ end
- describe "when returning the http instance" do
- it "should use the http pool to create the instance" do
- @client.instance_variable_set("@http", nil)
- @client.expects(:host).returns "myhost"
- @client.expects(:port).returns "myport"
- Puppet::Network::HttpPool.expects(:http_instance).with("myhost", "myport", true).returns "http"
+ describe "when returning the http instance" do
+ it "should use the http pool to create the instance" do
+ @client.instance_variable_set("@http", nil)
+ @client.expects(:host).returns "myhost"
+ @client.expects(:port).returns "myport"
+ Puppet::Network::HttpPool.expects(:http_instance).with("myhost", "myport", true).returns "http"
- @client.http.should == "http"
- end
+ @client.http.should == "http"
+ end
- it "should reuse existing instances" do
- @client.http.should equal(@client.http)
- end
- end
+ it "should reuse existing instances" do
+ @client.http.should equal(@client.http)
+ end
+ end
- describe "when recycling the connection" do
- it "should close the existing instance if it's open" do
- http = mock 'http'
- @client.stubs(:http).returns http
+ describe "when recycling the connection" do
+ it "should close the existing instance if it's open" do
+ http = mock 'http'
+ @client.stubs(:http).returns http
- http.expects(:started?).returns true
- http.expects(:finish)
+ http.expects(:started?).returns true
+ http.expects(:finish)
- @client.recycle_connection
- end
+ @client.recycle_connection
+ end
- it "should force creation of a new instance" do
- Puppet::Network::HttpPool.expects(:http_instance).returns "second_http"
+ it "should force creation of a new instance" do
+ Puppet::Network::HttpPool.expects(:http_instance).returns "second_http"
- @client.recycle_connection
+ @client.recycle_connection
- @client.http.should == "second_http"
- end
- end
+ @client.http.should == "second_http"
+ end
+ end
- describe "and an exception is raised" do
- it "should raise XMLRPCClientError if XMLRPC::FaultException is raised" do
- error = XMLRPC::FaultException.new("foo", "bar")
+ describe "and an exception is raised" do
+ it "should raise XMLRPCClientError if XMLRPC::FaultException is raised" do
+ error = XMLRPC::FaultException.new("foo", "bar")
- @client.expects(:call).raises(error)
+ @client.expects(:call).raises(error)
- lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError)
- end
+ lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError)
+ end
- it "should raise XMLRPCClientError if Errno::ECONNREFUSED is raised" do
- @client.expects(:call).raises(Errno::ECONNREFUSED)
+ it "should raise XMLRPCClientError if Errno::ECONNREFUSED is raised" do
+ @client.expects(:call).raises(Errno::ECONNREFUSED)
- lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError)
- end
+ lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError)
+ end
- it "should log and raise XMLRPCClientError if Timeout::Error is raised" do
- Puppet.expects(:err)
- @client.expects(:call).raises(Timeout::Error)
+ it "should log and raise XMLRPCClientError if Timeout::Error is raised" do
+ Puppet.expects(:err)
+ @client.expects(:call).raises(Timeout::Error)
- lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError)
- end
+ lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError)
+ end
- it "should log and raise XMLRPCClientError if SocketError is raised" do
- Puppet.expects(:err)
- @client.expects(:call).raises(SocketError)
+ it "should log and raise XMLRPCClientError if SocketError is raised" do
+ Puppet.expects(:err)
+ @client.expects(:call).raises(SocketError)
- lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError)
- end
+ lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError)
+ end
- it "should log, recycle the connection, and retry if Errno::EPIPE is raised" do
- @client.expects(:call).times(2).raises(Errno::EPIPE).then.returns "eh"
+ it "should log, recycle the connection, and retry if Errno::EPIPE is raised" do
+ @client.expects(:call).times(2).raises(Errno::EPIPE).then.returns "eh"
- Puppet.expects(:info)
- @client.expects(:recycle_connection)
+ Puppet.expects(:info)
+ @client.expects(:recycle_connection)
- @client.report("eh")
- end
+ @client.report("eh")
+ end
- it "should log, recycle the connection, and retry if EOFError is raised" do
- @client.expects(:call).times(2).raises(EOFError).then.returns "eh"
+ it "should log, recycle the connection, and retry if EOFError is raised" do
+ @client.expects(:call).times(2).raises(EOFError).then.returns "eh"
- Puppet.expects(:info)
- @client.expects(:recycle_connection)
+ Puppet.expects(:info)
+ @client.expects(:recycle_connection)
- @client.report("eh")
- end
+ @client.report("eh")
+ end
- it "should log and retry if an exception containing 'Wrong size' is raised" do
- error = RuntimeError.new("Wrong size. Was 15, should be 30")
- @client.expects(:call).times(2).raises(error).then.returns "eh"
+ it "should log and retry if an exception containing 'Wrong size' is raised" do
+ error = RuntimeError.new("Wrong size. Was 15, should be 30")
+ @client.expects(:call).times(2).raises(error).then.returns "eh"
- Puppet.expects(:warning)
+ Puppet.expects(:warning)
- @client.report("eh")
- end
+ @client.report("eh")
+ end
- it "should raise XMLRPCClientError if OpenSSL::SSL::SSLError is raised" do
- @client.expects(:call).raises(OpenSSL::SSL::SSLError)
+ it "should raise XMLRPCClientError if OpenSSL::SSL::SSLError is raised" do
+ @client.expects(:call).raises(OpenSSL::SSL::SSLError)
- lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError)
- end
+ lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError)
+ end
- it "should log and raise XMLRPCClientError if OpenSSL::SSL::SSLError is raised with certificate issues" do
- error = OpenSSL::SSL::SSLError.new("hostname was not match")
- @client.expects(:call).raises(error)
+ it "should log and raise XMLRPCClientError if OpenSSL::SSL::SSLError is raised with certificate issues" do
+ error = OpenSSL::SSL::SSLError.new("hostname was not match")
+ @client.expects(:call).raises(error)
- Puppet.expects(:warning)
+ Puppet.expects(:warning)
- lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError)
- end
+ lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError)
+ end
- it "should log, recycle the connection, and retry if OpenSSL::SSL::SSLError is raised containing 'bad write retry'" do
- error = OpenSSL::SSL::SSLError.new("bad write retry")
- @client.expects(:call).times(2).raises(error).then.returns "eh"
+ it "should log, recycle the connection, and retry if OpenSSL::SSL::SSLError is raised containing 'bad write retry'" do
+ error = OpenSSL::SSL::SSLError.new("bad write retry")
+ @client.expects(:call).times(2).raises(error).then.returns "eh"
- @client.expects(:recycle_connection)
+ @client.expects(:recycle_connection)
- Puppet.expects(:warning)
+ Puppet.expects(:warning)
- @client.report("eh")
- end
+ @client.report("eh")
+ end
- it "should log and raise XMLRPCClientError if any other exception is raised" do
- @client.expects(:call).raises(RuntimeError)
+ it "should log and raise XMLRPCClientError if any other exception is raised" do
+ @client.expects(:call).raises(RuntimeError)
- Puppet.expects(:err)
+ Puppet.expects(:err)
- lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError)
- end
- end
+ lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError)
+ end
end
+ end
end
diff --git a/spec/unit/node/environment_spec.rb b/spec/unit/node/environment_spec.rb
index 29a4f0c..b400865 100755
--- a/spec/unit/node/environment_spec.rb
+++ b/spec/unit/node/environment_spec.rb
@@ -6,243 +6,243 @@ require 'puppet/node/environment'
require 'puppet/util/execution'
describe Puppet::Node::Environment do
- after do
- Puppet::Node::Environment.clear
- end
+ after do
+ Puppet::Node::Environment.clear
+ end
- it "should include the Cacher module" do
- Puppet::Node::Environment.ancestors.should be_include(Puppet::Util::Cacher)
- end
+ it "should include the Cacher module" do
+ Puppet::Node::Environment.ancestors.should be_include(Puppet::Util::Cacher)
+ end
- it "should use the filetimeout for the ttl for the modulepath" do
- Puppet::Node::Environment.attr_ttl(:modulepath).should == Integer(Puppet[:filetimeout])
- end
+ it "should use the filetimeout for the ttl for the modulepath" do
+ Puppet::Node::Environment.attr_ttl(:modulepath).should == Integer(Puppet[:filetimeout])
+ end
- it "should use the filetimeout for the ttl for the module list" do
- Puppet::Node::Environment.attr_ttl(:modules).should == Integer(Puppet[:filetimeout])
- end
+ it "should use the filetimeout for the ttl for the module list" do
+ Puppet::Node::Environment.attr_ttl(:modules).should == Integer(Puppet[:filetimeout])
+ end
- it "should use the filetimeout for the ttl for the manifestdir" do
- Puppet::Node::Environment.attr_ttl(:manifestdir).should == Integer(Puppet[:filetimeout])
- end
+ it "should use the filetimeout for the ttl for the manifestdir" do
+ Puppet::Node::Environment.attr_ttl(:manifestdir).should == Integer(Puppet[:filetimeout])
+ end
- it "should use the default environment if no name is provided while initializing an environment" do
- Puppet.settings.expects(:value).with(:environment).returns("one")
- Puppet::Node::Environment.new.name.should == :one
- end
+ it "should use the default environment if no name is provided while initializing an environment" do
+ Puppet.settings.expects(:value).with(:environment).returns("one")
+ Puppet::Node::Environment.new.name.should == :one
+ end
- it "should treat environment instances as singletons" do
- Puppet::Node::Environment.new("one").should equal(Puppet::Node::Environment.new("one"))
- end
+ it "should treat environment instances as singletons" do
+ Puppet::Node::Environment.new("one").should equal(Puppet::Node::Environment.new("one"))
+ end
- it "should treat an environment specified as names or strings as equivalent" do
- Puppet::Node::Environment.new(:one).should equal(Puppet::Node::Environment.new("one"))
- end
+ it "should treat an environment specified as names or strings as equivalent" do
+ Puppet::Node::Environment.new(:one).should equal(Puppet::Node::Environment.new("one"))
+ end
+
+ it "should return its name when converted to a string" do
+ Puppet::Node::Environment.new(:one).to_s.should == "one"
+ end
+
+ it "should just return any provided environment if an environment is provided as the name" do
+ one = Puppet::Node::Environment.new(:one)
+ Puppet::Node::Environment.new(one).should equal(one)
+ end
- it "should return its name when converted to a string" do
- Puppet::Node::Environment.new(:one).to_s.should == "one"
+ describe "when managing known resource types" do
+ before do
+ @env = Puppet::Node::Environment.new("dev")
+ @collection = Puppet::Resource::TypeCollection.new(@env)
+ @collection.stubs(:perform_initial_import)
end
- it "should just return any provided environment if an environment is provided as the name" do
- one = Puppet::Node::Environment.new(:one)
- Puppet::Node::Environment.new(one).should equal(one)
+ it "should create a resource type collection if none exists" do
+ Puppet::Resource::TypeCollection.expects(:new).with(@env).returns @collection
+ @env.known_resource_types.should equal(@collection)
end
- describe "when managing known resource types" do
- before do
- @env = Puppet::Node::Environment.new("dev")
- @collection = Puppet::Resource::TypeCollection.new(@env)
- @collection.stubs(:perform_initial_import)
- end
+ it "should reuse any existing resource type collection" do
+ @env.known_resource_types.should equal(@env.known_resource_types)
+ end
- it "should create a resource type collection if none exists" do
- Puppet::Resource::TypeCollection.expects(:new).with(@env).returns @collection
- @env.known_resource_types.should equal(@collection)
- end
+ it "should perform the initial import when creating a new collection" do
+ @collection.expects(:perform_initial_import)
+ Puppet::Resource::TypeCollection.expects(:new).returns @collection
- it "should reuse any existing resource type collection" do
- @env.known_resource_types.should equal(@env.known_resource_types)
- end
+ @env.known_resource_types
+ end
- it "should perform the initial import when creating a new collection" do
- @collection.expects(:perform_initial_import)
- Puppet::Resource::TypeCollection.expects(:new).returns @collection
+ it "should create and return a new collection rather than returning a stale collection" do
+ @env.known_resource_types.expects(:stale?).returns true
- @env.known_resource_types
- end
+ Puppet::Resource::TypeCollection.expects(:new).returns @collection
- it "should create and return a new collection rather than returning a stale collection" do
- @env.known_resource_types.expects(:stale?).returns true
+ @env.known_resource_types.should equal(@collection)
+ end
+ end
- Puppet::Resource::TypeCollection.expects(:new).returns @collection
+ [:modulepath, :manifestdir].each do |setting|
+ it "should validate the #{setting} directories" do
+ path = %w{/one /two}.join(File::PATH_SEPARATOR)
- @env.known_resource_types.should equal(@collection)
- end
- end
+ env = Puppet::Node::Environment.new("testing")
+ env.stubs(:[]).with(setting).returns path
- [:modulepath, :manifestdir].each do |setting|
- it "should validate the #{setting} directories" do
- path = %w{/one /two}.join(File::PATH_SEPARATOR)
+ env.expects(:validate_dirs).with(%w{/one /two})
- env = Puppet::Node::Environment.new("testing")
- env.stubs(:[]).with(setting).returns path
+ env.send(setting)
+ end
- env.expects(:validate_dirs).with(%w{/one /two})
+ it "should return the validated dirs for #{setting}" do
+ path = %w{/one /two}.join(File::PATH_SEPARATOR)
- env.send(setting)
- end
+ env = Puppet::Node::Environment.new("testing")
+ env.stubs(:[]).with(setting).returns path
+ env.stubs(:validate_dirs).returns %w{/one /two}
- it "should return the validated dirs for #{setting}" do
- path = %w{/one /two}.join(File::PATH_SEPARATOR)
+ env.send(setting).should == %w{/one /two}
+ end
+ end
- env = Puppet::Node::Environment.new("testing")
- env.stubs(:[]).with(setting).returns path
- env.stubs(:validate_dirs).returns %w{/one /two}
+ it "should prefix the value of the 'PUPPETLIB' environment variable to the module path if present" do
+ Puppet::Util::Execution.withenv("PUPPETLIB" => %w{/l1 /l2}.join(File::PATH_SEPARATOR)) do
+ env = Puppet::Node::Environment.new("testing")
+ module_path = %w{/one /two}.join(File::PATH_SEPARATOR)
+ env.expects(:validate_dirs).with(%w{/l1 /l2 /one /two}).returns %w{/l1 /l2 /one /two}
+ env.expects(:[]).with(:modulepath).returns module_path
- env.send(setting).should == %w{/one /two}
- end
+ env.modulepath.should == %w{/l1 /l2 /one /two}
end
+ end
+
+ describe "when validating modulepath or manifestdir directories" do
+ it "should not return non-directories" do
+ env = Puppet::Node::Environment.new("testing")
- it "should prefix the value of the 'PUPPETLIB' environment variable to the module path if present" do
- Puppet::Util::Execution.withenv("PUPPETLIB" => %w{/l1 /l2}.join(File::PATH_SEPARATOR)) do
- env = Puppet::Node::Environment.new("testing")
- module_path = %w{/one /two}.join(File::PATH_SEPARATOR)
- env.expects(:validate_dirs).with(%w{/l1 /l2 /one /two}).returns %w{/l1 /l2 /one /two}
- env.expects(:[]).with(:modulepath).returns module_path
+ FileTest.expects(:directory?).with("/one").returns true
+ FileTest.expects(:directory?).with("/two").returns false
- env.modulepath.should == %w{/l1 /l2 /one /two}
- end
+ env.validate_dirs(%w{/one /two}).should == %w{/one}
end
- describe "when validating modulepath or manifestdir directories" do
- it "should not return non-directories" do
- env = Puppet::Node::Environment.new("testing")
+ it "should use the current working directory to fully-qualify unqualified paths" do
+ FileTest.stubs(:directory?).returns true
+ env = Puppet::Node::Environment.new("testing")
- FileTest.expects(:directory?).with("/one").returns true
- FileTest.expects(:directory?).with("/two").returns false
+ two = File.join(Dir.getwd, "two")
+ env.validate_dirs(%w{/one two}).should == ["/one", two]
+ end
+ end
- env.validate_dirs(%w{/one /two}).should == %w{/one}
- end
+ describe "when modeling a specific environment" do
+ it "should have a method for returning the environment name" do
+ Puppet::Node::Environment.new("testing").name.should == :testing
+ end
- it "should use the current working directory to fully-qualify unqualified paths" do
- FileTest.stubs(:directory?).returns true
- env = Puppet::Node::Environment.new("testing")
+ it "should provide an array-like accessor method for returning any environment-specific setting" do
+ env = Puppet::Node::Environment.new("testing")
+ env.should respond_to(:[])
+ end
- two = File.join(Dir.getwd, "two")
- env.validate_dirs(%w{/one two}).should == ["/one", two]
- end
+ it "should ask the Puppet settings instance for the setting qualified with the environment name" do
+ Puppet.settings.expects(:value).with("myvar", :testing).returns("myval")
+ env = Puppet::Node::Environment.new("testing")
+ env["myvar"].should == "myval"
end
- describe "when modeling a specific environment" do
- it "should have a method for returning the environment name" do
- Puppet::Node::Environment.new("testing").name.should == :testing
- end
+ it "should be able to return an individual module that exists in its module path" do
+ env = Puppet::Node::Environment.new("testing")
- it "should provide an array-like accessor method for returning any environment-specific setting" do
- env = Puppet::Node::Environment.new("testing")
- env.should respond_to(:[])
- end
+ mod = mock 'module'
+ Puppet::Module.expects(:new).with("one", env).returns mod
+ mod.expects(:exist?).returns true
- it "should ask the Puppet settings instance for the setting qualified with the environment name" do
- Puppet.settings.expects(:value).with("myvar", :testing).returns("myval")
- env = Puppet::Node::Environment.new("testing")
- env["myvar"].should == "myval"
- end
+ env.module("one").should equal(mod)
+ end
- it "should be able to return an individual module that exists in its module path" do
- env = Puppet::Node::Environment.new("testing")
+ it "should return nil if asked for a module that does not exist in its path" do
+ env = Puppet::Node::Environment.new("testing")
- mod = mock 'module'
- Puppet::Module.expects(:new).with("one", env).returns mod
- mod.expects(:exist?).returns true
+ mod = mock 'module'
+ Puppet::Module.expects(:new).with("one", env).returns mod
+ mod.expects(:exist?).returns false
- env.module("one").should equal(mod)
- end
+ env.module("one").should be_nil
+ end
- it "should return nil if asked for a module that does not exist in its path" do
- env = Puppet::Node::Environment.new("testing")
+ it "should be able to return its modules" do
+ Puppet::Node::Environment.new("testing").should respond_to(:modules)
+ end
- mod = mock 'module'
- Puppet::Module.expects(:new).with("one", env).returns mod
- mod.expects(:exist?).returns false
+ describe ".modules" do
+ it "should return a module named for every directory in each module path" do
+ env = Puppet::Node::Environment.new("testing")
+ env.expects(:modulepath).at_least_once.returns %w{/a /b}
+ Dir.expects(:entries).with("/a").returns %w{foo bar}
+ Dir.expects(:entries).with("/b").returns %w{bee baz}
- env.module("one").should be_nil
- end
+ env.modules.collect{|mod| mod.name}.sort.should == %w{foo bar bee baz}.sort
+ end
- it "should be able to return its modules" do
- Puppet::Node::Environment.new("testing").should respond_to(:modules)
- end
+ it "should remove duplicates" do
+ env = Puppet::Node::Environment.new("testing")
+ env.expects(:modulepath).returns( %w{/a /b} ).at_least_once
+ Dir.expects(:entries).with("/a").returns %w{foo}
+ Dir.expects(:entries).with("/b").returns %w{foo}
- describe ".modules" do
- it "should return a module named for every directory in each module path" do
- env = Puppet::Node::Environment.new("testing")
- env.expects(:modulepath).at_least_once.returns %w{/a /b}
- Dir.expects(:entries).with("/a").returns %w{foo bar}
- Dir.expects(:entries).with("/b").returns %w{bee baz}
+ env.modules.collect{|mod| mod.name}.sort.should == %w{foo}
+ end
- env.modules.collect{|mod| mod.name}.sort.should == %w{foo bar bee baz}.sort
- end
+ it "should ignore invalid modules" do
+ env = Puppet::Node::Environment.new("testing")
+ env.stubs(:modulepath).returns %w{/a}
+ Dir.expects(:entries).with("/a").returns %w{foo bar}
- it "should remove duplicates" do
- env = Puppet::Node::Environment.new("testing")
- env.expects(:modulepath).returns( %w{/a /b} ).at_least_once
- Dir.expects(:entries).with("/a").returns %w{foo}
- Dir.expects(:entries).with("/b").returns %w{foo}
+ Puppet::Module.expects(:new).with { |name, env| name == "foo" }.returns mock("foomod", :name => "foo")
+ Puppet::Module.expects(:new).with { |name, env| name == "bar" }.raises( Puppet::Module::InvalidName, "name is invalid" )
- env.modules.collect{|mod| mod.name}.sort.should == %w{foo}
- end
+ env.modules.collect{|mod| mod.name}.sort.should == %w{foo}
+ end
- it "should ignore invalid modules" do
- env = Puppet::Node::Environment.new("testing")
- env.stubs(:modulepath).returns %w{/a}
- Dir.expects(:entries).with("/a").returns %w{foo bar}
+ it "should create modules with the correct environment" do
+ env = Puppet::Node::Environment.new("testing")
+ env.expects(:modulepath).at_least_once.returns %w{/a}
+ Dir.expects(:entries).with("/a").returns %w{foo}
- Puppet::Module.expects(:new).with { |name, env| name == "foo" }.returns mock("foomod", :name => "foo")
- Puppet::Module.expects(:new).with { |name, env| name == "bar" }.raises( Puppet::Module::InvalidName, "name is invalid" )
+ env.modules.each {|mod| mod.environment.should == env }
+ end
- env.modules.collect{|mod| mod.name}.sort.should == %w{foo}
- end
+ it "should cache the module list" do
+ env = Puppet::Node::Environment.new("testing")
+ env.expects(:modulepath).at_least_once.returns %w{/a}
+ Dir.expects(:entries).once.with("/a").returns %w{foo}
- it "should create modules with the correct environment" do
- env = Puppet::Node::Environment.new("testing")
- env.expects(:modulepath).at_least_once.returns %w{/a}
- Dir.expects(:entries).with("/a").returns %w{foo}
+ env.modules
+ env.modules
+ end
+ end
+ end
- env.modules.each {|mod| mod.environment.should == env }
- end
+ describe Puppet::Node::Environment::Helper do
+ before do
+ @helper = Object.new
+ @helper.extend(Puppet::Node::Environment::Helper)
+ end
- it "should cache the module list" do
- env = Puppet::Node::Environment.new("testing")
- env.expects(:modulepath).at_least_once.returns %w{/a}
- Dir.expects(:entries).once.with("/a").returns %w{foo}
+ it "should be able to set and retrieve the environment" do
+ @helper.environment = :foo
+ @helper.environment.name.should == :foo
+ end
- env.modules
- env.modules
- end
- end
+ it "should accept an environment directly" do
+ env = Puppet::Node::Environment.new :foo
+ @helper.environment = env
+ @helper.environment.name.should == :foo
end
- describe Puppet::Node::Environment::Helper do
- before do
- @helper = Object.new
- @helper.extend(Puppet::Node::Environment::Helper)
- end
-
- it "should be able to set and retrieve the environment" do
- @helper.environment = :foo
- @helper.environment.name.should == :foo
- end
-
- it "should accept an environment directly" do
- env = Puppet::Node::Environment.new :foo
- @helper.environment = env
- @helper.environment.name.should == :foo
- end
-
- it "should accept an environment as a string" do
- env = Puppet::Node::Environment.new "foo"
- @helper.environment = env
- @helper.environment.name.should == :foo
- end
+ it "should accept an environment as a string" do
+ env = Puppet::Node::Environment.new "foo"
+ @helper.environment = env
+ @helper.environment.name.should == :foo
end
+ end
end
diff --git a/spec/unit/node/facts_spec.rb b/spec/unit/node/facts_spec.rb
index d276de2..a2f4ab9 100755
--- a/spec/unit/node/facts_spec.rb
+++ b/spec/unit/node/facts_spec.rb
@@ -5,98 +5,98 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/node/facts'
describe Puppet::Node::Facts, "when indirecting" do
+ before do
+ @facts = Puppet::Node::Facts.new("me")
+ end
+
+ it "should be able to convert all fact values to strings" do
+ @facts.values["one"] = 1
+ @facts.stringify
+ @facts.values["one"].should == "1"
+ end
+
+ it "should add the node's certificate name as the 'clientcert' fact when adding local facts" do
+ @facts.add_local_facts
+ @facts.values["clientcert"].should == Puppet.settings[:certname]
+ end
+
+ it "should add the Puppet version as a 'clientversion' fact when adding local facts" do
+ @facts.add_local_facts
+ @facts.values["clientversion"].should == Puppet.version.to_s
+ end
+
+ it "should add the current environment as a fact if one is not set when adding local facts" do
+ @facts.add_local_facts
+ @facts.values["environment"].should == Puppet[:environment]
+ end
+
+ it "should not replace any existing environment fact when adding local facts" do
+ @facts.values["environment"] = "foo"
+ @facts.add_local_facts
+ @facts.values["environment"].should == "foo"
+ end
+
+ it "should be able to downcase fact values" do
+ Puppet.settings.stubs(:value).returns "eh"
+ Puppet.settings.expects(:value).with(:downcasefacts).returns true
+
+ @facts.values["one"] = "Two"
+
+ @facts.downcase_if_necessary
+ @facts.values["one"].should == "two"
+ end
+
+ it "should only try to downcase strings" do
+ Puppet.settings.stubs(:value).returns "eh"
+ Puppet.settings.expects(:value).with(:downcasefacts).returns true
+
+ @facts.values["now"] = Time.now
+
+ @facts.downcase_if_necessary
+ @facts.values["now"].should be_instance_of(Time)
+ end
+
+ it "should not downcase facts if not configured to do so" do
+ Puppet.settings.stubs(:value).returns "eh"
+ Puppet.settings.expects(:value).with(:downcasefacts).returns false
+
+ @facts.values["one"] = "Two"
+ @facts.downcase_if_necessary
+ @facts.values["one"].should == "Two"
+ end
+
+ describe "when indirecting" do
before do
- @facts = Puppet::Node::Facts.new("me")
- end
-
- it "should be able to convert all fact values to strings" do
- @facts.values["one"] = 1
- @facts.stringify
- @facts.values["one"].should == "1"
- end
-
- it "should add the node's certificate name as the 'clientcert' fact when adding local facts" do
- @facts.add_local_facts
- @facts.values["clientcert"].should == Puppet.settings[:certname]
- end
-
- it "should add the Puppet version as a 'clientversion' fact when adding local facts" do
- @facts.add_local_facts
- @facts.values["clientversion"].should == Puppet.version.to_s
- end
-
- it "should add the current environment as a fact if one is not set when adding local facts" do
- @facts.add_local_facts
- @facts.values["environment"].should == Puppet[:environment]
- end
-
- it "should not replace any existing environment fact when adding local facts" do
- @facts.values["environment"] = "foo"
- @facts.add_local_facts
- @facts.values["environment"].should == "foo"
- end
-
- it "should be able to downcase fact values" do
- Puppet.settings.stubs(:value).returns "eh"
- Puppet.settings.expects(:value).with(:downcasefacts).returns true
+ @indirection = stub 'indirection', :request => mock('request'), :name => :facts
- @facts.values["one"] = "Two"
+ # We have to clear the cache so that the facts ask for our indirection stub,
+ # instead of anything that might be cached.
+ Puppet::Util::Cacher.expire
- @facts.downcase_if_necessary
- @facts.values["one"].should == "two"
+ @facts = Puppet::Node::Facts.new("me", "one" => "two")
end
- it "should only try to downcase strings" do
- Puppet.settings.stubs(:value).returns "eh"
- Puppet.settings.expects(:value).with(:downcasefacts).returns true
-
- @facts.values["now"] = Time.now
-
- @facts.downcase_if_necessary
- @facts.values["now"].should be_instance_of(Time)
+ it "should redirect to the specified fact store for retrieval" do
+ Puppet::Node::Facts.stubs(:indirection).returns(@indirection)
+ @indirection.expects(:find)
+ Puppet::Node::Facts.find(:my_facts)
end
- it "should not downcase facts if not configured to do so" do
- Puppet.settings.stubs(:value).returns "eh"
- Puppet.settings.expects(:value).with(:downcasefacts).returns false
-
- @facts.values["one"] = "Two"
- @facts.downcase_if_necessary
- @facts.values["one"].should == "Two"
+ it "should redirect to the specified fact store for storage" do
+ Puppet::Node::Facts.stubs(:indirection).returns(@indirection)
+ @indirection.expects(:save)
+ @facts.save
end
- describe "when indirecting" do
- before do
- @indirection = stub 'indirection', :request => mock('request'), :name => :facts
-
- # We have to clear the cache so that the facts ask for our indirection stub,
- # instead of anything that might be cached.
- Puppet::Util::Cacher.expire
-
- @facts = Puppet::Node::Facts.new("me", "one" => "two")
- end
-
- it "should redirect to the specified fact store for retrieval" do
- Puppet::Node::Facts.stubs(:indirection).returns(@indirection)
- @indirection.expects(:find)
- Puppet::Node::Facts.find(:my_facts)
- end
-
- it "should redirect to the specified fact store for storage" do
- Puppet::Node::Facts.stubs(:indirection).returns(@indirection)
- @indirection.expects(:save)
- @facts.save
- end
-
- it "should default to the 'facter' terminus" do
- Puppet::Node::Facts.indirection.terminus_class.should == :facter
- end
+ it "should default to the 'facter' terminus" do
+ Puppet::Node::Facts.indirection.terminus_class.should == :facter
end
+ end
- describe "when storing and retrieving" do
- it "should add metadata to the facts" do
- facts = Puppet::Node::Facts.new("me", "one" => "two", "three" => "four")
- facts.values[:_timestamp].should be_instance_of(Time)
- end
+ describe "when storing and retrieving" do
+ it "should add metadata to the facts" do
+ facts = Puppet::Node::Facts.new("me", "one" => "two", "three" => "four")
+ facts.values[:_timestamp].should be_instance_of(Time)
end
+ end
end
diff --git a/spec/unit/node_spec.rb b/spec/unit/node_spec.rb
index e0b4530..36334ea 100755
--- a/spec/unit/node_spec.rb
+++ b/spec/unit/node_spec.rb
@@ -3,208 +3,208 @@
require File.dirname(__FILE__) + '/../spec_helper'
describe Puppet::Node do
- describe "when managing its environment" do
- it "should use any set environment" do
- Puppet::Node.new("foo", :environment => "bar").environment.name.should == :bar
- end
-
- it "should support providing an actual environment instance" do
- Puppet::Node.new("foo", :environment => Puppet::Node::Environment.new(:bar)).environment.name.should == :bar
- end
-
- it "should determine its environment from its parameters if no environment is set" do
- Puppet::Node.new("foo", :parameters => {"environment" => :bar}).environment.name.should == :bar
- end
-
- it "should use the default environment if no environment is provided" do
- Puppet::Node.new("foo").environment.name.should == Puppet::Node::Environment.new.name
- end
-
- it "should always return an environment instance rather than a string" do
- Puppet::Node.new("foo").environment.should be_instance_of(Puppet::Node::Environment)
- end
-
- it "should allow the environment to be set after initialization" do
- node = Puppet::Node.new("foo")
- node.environment = :bar
- node.environment.name.should == :bar
- end
-
- it "should allow its environment to be set by parameters after initialization" do
- node = Puppet::Node.new("foo")
- node.parameters["environment"] = :bar
- node.environment.name.should == :bar
- end
- end
-end
-
-describe Puppet::Node, "when initializing" do
- before do
- @node = Puppet::Node.new("testnode")
+ describe "when managing its environment" do
+ it "should use any set environment" do
+ Puppet::Node.new("foo", :environment => "bar").environment.name.should == :bar
end
- it "should set the node name" do
- @node.name.should == "testnode"
+ it "should support providing an actual environment instance" do
+ Puppet::Node.new("foo", :environment => Puppet::Node::Environment.new(:bar)).environment.name.should == :bar
end
- it "should not allow nil node names" do
- proc { Puppet::Node.new(nil) }.should raise_error(ArgumentError)
+ it "should determine its environment from its parameters if no environment is set" do
+ Puppet::Node.new("foo", :parameters => {"environment" => :bar}).environment.name.should == :bar
end
- it "should default to an empty parameter hash" do
- @node.parameters.should == {}
+ it "should use the default environment if no environment is provided" do
+ Puppet::Node.new("foo").environment.name.should == Puppet::Node::Environment.new.name
end
- it "should default to an empty class array" do
- @node.classes.should == []
+ it "should always return an environment instance rather than a string" do
+ Puppet::Node.new("foo").environment.should be_instance_of(Puppet::Node::Environment)
end
- it "should note its creation time" do
- @node.time.should be_instance_of(Time)
+ it "should allow the environment to be set after initialization" do
+ node = Puppet::Node.new("foo")
+ node.environment = :bar
+ node.environment.name.should == :bar
end
- it "should accept parameters passed in during initialization" do
- params = {"a" => "b"}
- @node = Puppet::Node.new("testing", :parameters => params)
- @node.parameters.should == params
- end
-
- it "should accept classes passed in during initialization" do
- classes = %w{one two}
- @node = Puppet::Node.new("testing", :classes => classes)
- @node.classes.should == classes
+ it "should allow its environment to be set by parameters after initialization" do
+ node = Puppet::Node.new("foo")
+ node.parameters["environment"] = :bar
+ node.environment.name.should == :bar
end
+ end
+end
- it "should always return classes as an array" do
- @node = Puppet::Node.new("testing", :classes => "myclass")
- @node.classes.should == ["myclass"]
- end
+describe Puppet::Node, "when initializing" do
+ before do
+ @node = Puppet::Node.new("testnode")
+ end
+
+ it "should set the node name" do
+ @node.name.should == "testnode"
+ end
+
+ it "should not allow nil node names" do
+ proc { Puppet::Node.new(nil) }.should raise_error(ArgumentError)
+ end
+
+ it "should default to an empty parameter hash" do
+ @node.parameters.should == {}
+ end
+
+ it "should default to an empty class array" do
+ @node.classes.should == []
+ end
+
+ it "should note its creation time" do
+ @node.time.should be_instance_of(Time)
+ end
+
+ it "should accept parameters passed in during initialization" do
+ params = {"a" => "b"}
+ @node = Puppet::Node.new("testing", :parameters => params)
+ @node.parameters.should == params
+ end
+
+ it "should accept classes passed in during initialization" do
+ classes = %w{one two}
+ @node = Puppet::Node.new("testing", :classes => classes)
+ @node.classes.should == classes
+ end
+
+ it "should always return classes as an array" do
+ @node = Puppet::Node.new("testing", :classes => "myclass")
+ @node.classes.should == ["myclass"]
+ end
end
describe Puppet::Node, "when merging facts" do
- before do
- @node = Puppet::Node.new("testnode")
- Puppet::Node::Facts.stubs(:find).with(@node.name).returns(Puppet::Node::Facts.new(@node.name, "one" => "c", "two" => "b"))
- end
-
- it "should fail intelligently if it cannot find facts" do
- Puppet::Node::Facts.expects(:find).with(@node.name).raises "foo"
- lambda { @node.fact_merge }.should raise_error(Puppet::Error)
- end
-
- it "should prefer parameters already set on the node over facts from the node" do
- @node = Puppet::Node.new("testnode", :parameters => {"one" => "a"})
- @node.fact_merge
- @node.parameters["one"].should == "a"
- end
-
- it "should add passed parameters to the parameter list" do
- @node = Puppet::Node.new("testnode", :parameters => {"one" => "a"})
- @node.fact_merge
- @node.parameters["two"].should == "b"
- end
-
- it "should accept arbitrary parameters to merge into its parameters" do
- @node = Puppet::Node.new("testnode", :parameters => {"one" => "a"})
- @node.merge "two" => "three"
- @node.parameters["two"].should == "three"
- end
-
- it "should add the environment to the list of parameters" do
- Puppet.settings.stubs(:value).with(:environments).returns("one,two")
- Puppet.settings.stubs(:value).with(:environment).returns("one")
- @node = Puppet::Node.new("testnode", :environment => "one")
- @node.merge "two" => "three"
- @node.parameters["environment"].should == "one"
- end
-
- it "should not set the environment if it is already set in the parameters" do
- Puppet.settings.stubs(:value).with(:environments).returns("one,two")
- Puppet.settings.stubs(:value).with(:environment).returns("one")
- @node = Puppet::Node.new("testnode", :environment => "one")
- @node.merge "environment" => "two"
- @node.parameters["environment"].should == "two"
- end
+ before do
+ @node = Puppet::Node.new("testnode")
+ Puppet::Node::Facts.stubs(:find).with(@node.name).returns(Puppet::Node::Facts.new(@node.name, "one" => "c", "two" => "b"))
+ end
+
+ it "should fail intelligently if it cannot find facts" do
+ Puppet::Node::Facts.expects(:find).with(@node.name).raises "foo"
+ lambda { @node.fact_merge }.should raise_error(Puppet::Error)
+ end
+
+ it "should prefer parameters already set on the node over facts from the node" do
+ @node = Puppet::Node.new("testnode", :parameters => {"one" => "a"})
+ @node.fact_merge
+ @node.parameters["one"].should == "a"
+ end
+
+ it "should add passed parameters to the parameter list" do
+ @node = Puppet::Node.new("testnode", :parameters => {"one" => "a"})
+ @node.fact_merge
+ @node.parameters["two"].should == "b"
+ end
+
+ it "should accept arbitrary parameters to merge into its parameters" do
+ @node = Puppet::Node.new("testnode", :parameters => {"one" => "a"})
+ @node.merge "two" => "three"
+ @node.parameters["two"].should == "three"
+ end
+
+ it "should add the environment to the list of parameters" do
+ Puppet.settings.stubs(:value).with(:environments).returns("one,two")
+ Puppet.settings.stubs(:value).with(:environment).returns("one")
+ @node = Puppet::Node.new("testnode", :environment => "one")
+ @node.merge "two" => "three"
+ @node.parameters["environment"].should == "one"
+ end
+
+ it "should not set the environment if it is already set in the parameters" do
+ Puppet.settings.stubs(:value).with(:environments).returns("one,two")
+ Puppet.settings.stubs(:value).with(:environment).returns("one")
+ @node = Puppet::Node.new("testnode", :environment => "one")
+ @node.merge "environment" => "two"
+ @node.parameters["environment"].should == "two"
+ end
end
describe Puppet::Node, "when indirecting" do
- it "should redirect to the indirection" do
- @indirection = stub 'indirection', :name => :node
- Puppet::Node.stubs(:indirection).returns(@indirection)
- @indirection.expects(:find)
- Puppet::Node.find(:my_node.to_s)
- end
+ it "should redirect to the indirection" do
+ @indirection = stub 'indirection', :name => :node
+ Puppet::Node.stubs(:indirection).returns(@indirection)
+ @indirection.expects(:find)
+ Puppet::Node.find(:my_node.to_s)
+ end
+
+ it "should default to the 'plain' node terminus" do
+ Puppet::Node.indirection.terminus_class.should == :plain
+ end
+
+ it "should not have a cache class defined" do
+ Puppet::Node.indirection.cache_class.should be_nil
+ end
+
+ after do
+ Puppet::Util::Cacher.expire
+ end
+end
- it "should default to the 'plain' node terminus" do
- Puppet::Node.indirection.terminus_class.should == :plain
- end
+describe Puppet::Node, "when generating the list of names to search through" do
+ before do
+ @node = Puppet::Node.new("foo.domain.com", :parameters => {"hostname" => "yay", "domain" => "domain.com"})
+ end
- it "should not have a cache class defined" do
- Puppet::Node.indirection.cache_class.should be_nil
- end
+ it "should return an array of names" do
+ @node.names.should be_instance_of(Array)
+ end
- after do
- Puppet::Util::Cacher.expire
+ describe "and the node name is fully qualified" do
+ it "should contain an entry for each part of the node name" do
+ @node.names.should be_include("foo.domain.com")
+ @node.names.should be_include("foo.domain")
+ @node.names.should be_include("foo")
end
-end
+ end
-describe Puppet::Node, "when generating the list of names to search through" do
- before do
- @node = Puppet::Node.new("foo.domain.com", :parameters => {"hostname" => "yay", "domain" => "domain.com"})
- end
+ it "should include the node's fqdn" do
+ @node.names.should be_include("yay.domain.com")
+ end
- it "should return an array of names" do
- @node.names.should be_instance_of(Array)
- end
+ it "should combine and include the node's hostname and domain if no fqdn is available" do
+ @node.names.should be_include("yay.domain.com")
+ end
- describe "and the node name is fully qualified" do
- it "should contain an entry for each part of the node name" do
- @node.names.should be_include("foo.domain.com")
- @node.names.should be_include("foo.domain")
- @node.names.should be_include("foo")
- end
- end
+ it "should contain an entry for each name available by stripping a segment of the fqdn" do
+ @node.parameters["fqdn"] = "foo.deep.sub.domain.com"
+ @node.names.should be_include("foo.deep.sub.domain")
+ @node.names.should be_include("foo.deep.sub")
+ end
- it "should include the node's fqdn" do
- @node.names.should be_include("yay.domain.com")
+ describe "and :node_name is set to 'cert'" do
+ before do
+ Puppet.settings.stubs(:value).with(:strict_hostname_checking).returns false
+ Puppet.settings.stubs(:value).with(:node_name).returns "cert"
end
- it "should combine and include the node's hostname and domain if no fqdn is available" do
- @node.names.should be_include("yay.domain.com")
+ it "should use the passed-in key as the first value" do
+ @node.names[0].should == "foo.domain.com"
end
- it "should contain an entry for each name available by stripping a segment of the fqdn" do
- @node.parameters["fqdn"] = "foo.deep.sub.domain.com"
- @node.names.should be_include("foo.deep.sub.domain")
- @node.names.should be_include("foo.deep.sub")
+ describe "and strict hostname checking is enabled" do
+ it "should only use the passed-in key" do
+ Puppet.settings.expects(:value).with(:strict_hostname_checking).returns true
+ @node.names.should == ["foo.domain.com"]
+ end
end
+ end
- describe "and :node_name is set to 'cert'" do
- before do
- Puppet.settings.stubs(:value).with(:strict_hostname_checking).returns false
- Puppet.settings.stubs(:value).with(:node_name).returns "cert"
- end
-
- it "should use the passed-in key as the first value" do
- @node.names[0].should == "foo.domain.com"
- end
-
- describe "and strict hostname checking is enabled" do
- it "should only use the passed-in key" do
- Puppet.settings.expects(:value).with(:strict_hostname_checking).returns true
- @node.names.should == ["foo.domain.com"]
- end
- end
+ describe "and :node_name is set to 'facter'" do
+ before do
+ Puppet.settings.stubs(:value).with(:strict_hostname_checking).returns false
+ Puppet.settings.stubs(:value).with(:node_name).returns "facter"
end
- describe "and :node_name is set to 'facter'" do
- before do
- Puppet.settings.stubs(:value).with(:strict_hostname_checking).returns false
- Puppet.settings.stubs(:value).with(:node_name).returns "facter"
- end
-
- it "should use the node's 'hostname' fact as the first value" do
- @node.names[0].should == "yay"
- end
+ it "should use the node's 'hostname' fact as the first value" do
+ @node.names[0].should == "yay"
end
+ end
end
diff --git a/spec/unit/other/selinux_spec.rb b/spec/unit/other/selinux_spec.rb
index 46e07b8..4ec0bba 100644
--- a/spec/unit/other/selinux_spec.rb
+++ b/spec/unit/other/selinux_spec.rb
@@ -6,89 +6,89 @@ require 'puppet/type/selboolean'
require 'puppet/type/selmodule'
describe Puppet::Type.type(:file), " when manipulating file contexts" do
- before :each do
+ before :each do
- @file = Puppet::Type::File.new(
+ @file = Puppet::Type::File.new(
- :name => "/tmp/foo",
- :ensure => "file",
- :seluser => "user_u",
- :selrole => "role_r",
+ :name => "/tmp/foo",
+ :ensure => "file",
+ :seluser => "user_u",
+ :selrole => "role_r",
- :seltype => "type_t" )
- end
- it "should use :seluser to get/set an SELinux user file context attribute" do
- @file.property(:seluser).should == "user_u"
- end
- it "should use :selrole to get/set an SELinux role file context attribute" do
- @file.property(:selrole).should == "role_r"
- end
- it "should use :seltype to get/set an SELinux user file context attribute" do
- @file.property(:seltype).should == "type_t"
- end
+ :seltype => "type_t" )
+ end
+ it "should use :seluser to get/set an SELinux user file context attribute" do
+ @file.property(:seluser).should == "user_u"
+ end
+ it "should use :selrole to get/set an SELinux role file context attribute" do
+ @file.property(:selrole).should == "role_r"
+ end
+ it "should use :seltype to get/set an SELinux user file context attribute" do
+ @file.property(:seltype).should == "type_t"
+ end
end
describe Puppet::Type.type(:selboolean), " when manipulating booleans" do
- before :each do
- provider_class = Puppet::Type::Selboolean.provider(Puppet::Type::Selboolean.providers[0])
- Puppet::Type::Selboolean.stubs(:defaultprovider).returns provider_class
+ before :each do
+ provider_class = Puppet::Type::Selboolean.provider(Puppet::Type::Selboolean.providers[0])
+ Puppet::Type::Selboolean.stubs(:defaultprovider).returns provider_class
- @bool = Puppet::Type::Selboolean.new(
+ @bool = Puppet::Type::Selboolean.new(
- :name => "foo",
- :value => "on",
+ :name => "foo",
+ :value => "on",
- :persistent => true )
- end
- it "should be able to access :name" do
- @bool[:name].should == "foo"
- end
- it "should be able to access :value" do
- @bool.property(:value).should == :on
- end
- it "should set :value to off" do
- @bool[:value] = :off
- @bool.property(:value).should == :off
- end
- it "should be able to access :persistent" do
- @bool[:persistent].should == :true
- end
- it "should set :persistent to false" do
- @bool[:persistent] = false
- @bool[:persistent].should == :false
- end
+ :persistent => true )
+ end
+ it "should be able to access :name" do
+ @bool[:name].should == "foo"
+ end
+ it "should be able to access :value" do
+ @bool.property(:value).should == :on
+ end
+ it "should set :value to off" do
+ @bool[:value] = :off
+ @bool.property(:value).should == :off
+ end
+ it "should be able to access :persistent" do
+ @bool[:persistent].should == :true
+ end
+ it "should set :persistent to false" do
+ @bool[:persistent] = false
+ @bool[:persistent].should == :false
+ end
end
describe Puppet::Type.type(:selmodule), " when checking policy modules" do
- before :each do
- provider_class = Puppet::Type::Selmodule.provider(Puppet::Type::Selmodule.providers[0])
- Puppet::Type::Selmodule.stubs(:defaultprovider).returns provider_class
+ before :each do
+ provider_class = Puppet::Type::Selmodule.provider(Puppet::Type::Selmodule.providers[0])
+ Puppet::Type::Selmodule.stubs(:defaultprovider).returns provider_class
- @module = Puppet::Type::Selmodule.new(
+ @module = Puppet::Type::Selmodule.new(
- :name => "foo",
- :selmoduledir => "/some/path",
- :selmodulepath => "/some/path/foo.pp",
+ :name => "foo",
+ :selmoduledir => "/some/path",
+ :selmodulepath => "/some/path/foo.pp",
- :syncversion => true)
- end
- it "should be able to access :name" do
- @module[:name].should == "foo"
- end
- it "should be able to access :selmoduledir" do
- @module[:selmoduledir].should == "/some/path"
- end
- it "should be able to access :selmodulepath" do
- @module[:selmodulepath].should == "/some/path/foo.pp"
- end
- it "should be able to access :syncversion" do
- @module.property(:syncversion).should == :true
- end
- it "should set the syncversion value to false" do
- @module[:syncversion] = :false
- @module.property(:syncversion).should == :false
- end
+ :syncversion => true)
+ end
+ it "should be able to access :name" do
+ @module[:name].should == "foo"
+ end
+ it "should be able to access :selmoduledir" do
+ @module[:selmoduledir].should == "/some/path"
+ end
+ it "should be able to access :selmodulepath" do
+ @module[:selmodulepath].should == "/some/path/foo.pp"
+ end
+ it "should be able to access :syncversion" do
+ @module.property(:syncversion).should == :true
+ end
+ it "should set the syncversion value to false" do
+ @module[:syncversion] = :false
+ @module.property(:syncversion).should == :false
+ end
end
diff --git a/spec/unit/other/transbucket_spec.rb b/spec/unit/other/transbucket_spec.rb
index 1224dfa..a5c4b47 100755
--- a/spec/unit/other/transbucket_spec.rb
+++ b/spec/unit/other/transbucket_spec.rb
@@ -3,186 +3,186 @@
require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::TransBucket do
- before do
- @bucket = Puppet::TransBucket.new
- end
-
- it "should be able to produce a RAL component" do
- @bucket.name = "luke"
- @bucket.type = "foo"
-
- resource = nil
- proc { resource = @bucket.to_ral }.should_not raise_error
- resource.should be_instance_of(Puppet::Type::Component)
- resource.title.should == "Foo[luke]"
- end
-
- it "should accept TransObjects into its children list" do
- object = Puppet::TransObject.new("luke", "user")
- proc { @bucket.push(object) }.should_not raise_error
- @bucket.each do |o|
- o.should equal(object)
- end
- end
-
- it "should accept TransBuckets into its children list" do
- object = Puppet::TransBucket.new
- proc { @bucket.push(object) }.should_not raise_error
- @bucket.each do |o|
- o.should equal(object)
- end
- end
-
- it "should refuse to accept any children that are not TransObjects or TransBuckets" do
- proc { @bucket.push "a test" }.should raise_error
- end
-
- it "should return use 'node' as the type and the provided name as the title if only a type is provided" do
- @bucket.type = "mystuff"
- @bucket.to_ref.should == "Node[mystuff]"
- end
-
- it "should return use 'component' as the type and the provided type as the title if only a name is provided" do
- @bucket.name = "mystuff"
- @bucket.to_ref.should == "Class[Mystuff]"
- end
-
- it "should return nil as its reference when type and name are missing" do
- @bucket.to_ref.should be_nil
- end
-
- it "should return the title as its reference" do
- @bucket.name = "luke"
- @bucket.type = "user"
- @bucket.to_ref.should == "User[luke]"
- end
-
- it "should canonize resource references when the type is 'component'" do
- @bucket.name = 'something'
- @bucket.type = 'foo::bar'
-
- @bucket.to_ref.should == "Foo::Bar[something]"
- end
+ before do
+ @bucket = Puppet::TransBucket.new
+ end
+
+ it "should be able to produce a RAL component" do
+ @bucket.name = "luke"
+ @bucket.type = "foo"
+
+ resource = nil
+ proc { resource = @bucket.to_ral }.should_not raise_error
+ resource.should be_instance_of(Puppet::Type::Component)
+ resource.title.should == "Foo[luke]"
+ end
+
+ it "should accept TransObjects into its children list" do
+ object = Puppet::TransObject.new("luke", "user")
+ proc { @bucket.push(object) }.should_not raise_error
+ @bucket.each do |o|
+ o.should equal(object)
+ end
+ end
+
+ it "should accept TransBuckets into its children list" do
+ object = Puppet::TransBucket.new
+ proc { @bucket.push(object) }.should_not raise_error
+ @bucket.each do |o|
+ o.should equal(object)
+ end
+ end
+
+ it "should refuse to accept any children that are not TransObjects or TransBuckets" do
+ proc { @bucket.push "a test" }.should raise_error
+ end
+
+ it "should return use 'node' as the type and the provided name as the title if only a type is provided" do
+ @bucket.type = "mystuff"
+ @bucket.to_ref.should == "Node[mystuff]"
+ end
+
+ it "should return use 'component' as the type and the provided type as the title if only a name is provided" do
+ @bucket.name = "mystuff"
+ @bucket.to_ref.should == "Class[Mystuff]"
+ end
+
+ it "should return nil as its reference when type and name are missing" do
+ @bucket.to_ref.should be_nil
+ end
+
+ it "should return the title as its reference" do
+ @bucket.name = "luke"
+ @bucket.type = "user"
+ @bucket.to_ref.should == "User[luke]"
+ end
+
+ it "should canonize resource references when the type is 'component'" do
+ @bucket.name = 'something'
+ @bucket.type = 'foo::bar'
+
+ @bucket.to_ref.should == "Foo::Bar[something]"
+ end
end
describe Puppet::TransBucket, " when generating a catalog" do
- before do
- @bottom = Puppet::TransBucket.new
- @bottom.type = "fake"
- @bottom.name = "bottom"
- @bottomobj = Puppet::TransObject.new("bottom", "notify")
- @bottom.push @bottomobj
-
- @middle = Puppet::TransBucket.new
- @middle.type = "fake"
- @middle.name = "middle"
- @middleobj = Puppet::TransObject.new("middle", "notify")
- @middle.push(@middleobj)
- @middle.push(@bottom)
-
- @top = Puppet::TransBucket.new
- @top.type = "fake"
- @top.name = "top"
- @topobj = Puppet::TransObject.new("top", "notify")
- @top.push(@topobj)
- @top.push(@middle)
-
- @users = %w{top middle bottom}
- @fakes = %w{Fake[bottom] Fake[middle] Fake[top]}
- end
-
- it "should convert all transportable objects to RAL resources" do
- @catalog = @top.to_catalog
- @users.each do |name|
- @catalog.vertices.find { |r| r.class.name == :notify and r.title == name }.should be_instance_of(Puppet::Type.type(:notify))
- end
- end
-
- it "should fail if any transportable resources fail to convert to RAL resources" do
- @bottomobj.expects(:to_ral).raises ArgumentError
- lambda { @bottom.to_catalog }.should raise_error(ArgumentError)
- end
-
- it "should convert all transportable buckets to RAL components" do
- @catalog = @top.to_catalog
- @fakes.each do |name|
- @catalog.vertices.find { |r| r.class.name == :component and r.title == name }.should be_instance_of(Puppet::Type.type(:component))
- end
- end
-
- it "should add all resources to the graph's resource table" do
- @catalog = @top.to_catalog
- @catalog.resource("fake[top]").should equal(@top)
- end
-
- it "should finalize all resources" do
- @catalog = @top.to_catalog
- @catalog.vertices.each do |vertex| vertex.should be_finalized end
- end
-
- it "should only call to_ral on each resource once" do
- # We just raise exceptions here because we're not interested in
- # what happens with the result, only that the method only
- # gets called once.
- resource = @topobj.to_ral
- @topobj.expects(:to_ral).once.returns resource
- @top.to_catalog
- end
-
- it "should set each TransObject's catalog before converting to a RAL resource" do
- @middleobj.expects(:catalog=).with { |c| c.is_a?(Puppet::Resource::Catalog) }
- @top.to_catalog
- end
-
- it "should set each TransBucket's catalog before converting to a RAL resource" do
- # each bucket is seen twice in the loop, so we have to handle the case where the config
- # is set twice
- @bottom.expects(:catalog=).with { |c| c.is_a?(Puppet::Resource::Catalog) }.at_least_once
- @top.to_catalog
- end
+ before do
+ @bottom = Puppet::TransBucket.new
+ @bottom.type = "fake"
+ @bottom.name = "bottom"
+ @bottomobj = Puppet::TransObject.new("bottom", "notify")
+ @bottom.push @bottomobj
+
+ @middle = Puppet::TransBucket.new
+ @middle.type = "fake"
+ @middle.name = "middle"
+ @middleobj = Puppet::TransObject.new("middle", "notify")
+ @middle.push(@middleobj)
+ @middle.push(@bottom)
+
+ @top = Puppet::TransBucket.new
+ @top.type = "fake"
+ @top.name = "top"
+ @topobj = Puppet::TransObject.new("top", "notify")
+ @top.push(@topobj)
+ @top.push(@middle)
+
+ @users = %w{top middle bottom}
+ @fakes = %w{Fake[bottom] Fake[middle] Fake[top]}
+ end
+
+ it "should convert all transportable objects to RAL resources" do
+ @catalog = @top.to_catalog
+ @users.each do |name|
+ @catalog.vertices.find { |r| r.class.name == :notify and r.title == name }.should be_instance_of(Puppet::Type.type(:notify))
+ end
+ end
+
+ it "should fail if any transportable resources fail to convert to RAL resources" do
+ @bottomobj.expects(:to_ral).raises ArgumentError
+ lambda { @bottom.to_catalog }.should raise_error(ArgumentError)
+ end
+
+ it "should convert all transportable buckets to RAL components" do
+ @catalog = @top.to_catalog
+ @fakes.each do |name|
+ @catalog.vertices.find { |r| r.class.name == :component and r.title == name }.should be_instance_of(Puppet::Type.type(:component))
+ end
+ end
+
+ it "should add all resources to the graph's resource table" do
+ @catalog = @top.to_catalog
+ @catalog.resource("fake[top]").should equal(@top)
+ end
+
+ it "should finalize all resources" do
+ @catalog = @top.to_catalog
+ @catalog.vertices.each do |vertex| vertex.should be_finalized end
+ end
+
+ it "should only call to_ral on each resource once" do
+ # We just raise exceptions here because we're not interested in
+ # what happens with the result, only that the method only
+ # gets called once.
+ resource = @topobj.to_ral
+ @topobj.expects(:to_ral).once.returns resource
+ @top.to_catalog
+ end
+
+ it "should set each TransObject's catalog before converting to a RAL resource" do
+ @middleobj.expects(:catalog=).with { |c| c.is_a?(Puppet::Resource::Catalog) }
+ @top.to_catalog
+ end
+
+ it "should set each TransBucket's catalog before converting to a RAL resource" do
+ # each bucket is seen twice in the loop, so we have to handle the case where the config
+ # is set twice
+ @bottom.expects(:catalog=).with { |c| c.is_a?(Puppet::Resource::Catalog) }.at_least_once
+ @top.to_catalog
+ end
end
describe Puppet::TransBucket, " when serializing" do
- before do
- @bucket = Puppet::TransBucket.new(%w{one two})
- @bucket.name = "one"
- @bucket.type = "two"
- end
-
- it "should be able to be dumped to yaml" do
- proc { YAML.dump(@bucket) }.should_not raise_error
- end
-
- it "should dump YAML that produces an equivalent object" do
- result = YAML.dump(@bucket)
-
- newobj = YAML.load(result)
- newobj.name.should == "one"
- newobj.type.should == "two"
- children = []
- newobj.each do |o|
- children << o
- end
- children.should == %w{one two}
- end
+ before do
+ @bucket = Puppet::TransBucket.new(%w{one two})
+ @bucket.name = "one"
+ @bucket.type = "two"
+ end
+
+ it "should be able to be dumped to yaml" do
+ proc { YAML.dump(@bucket) }.should_not raise_error
+ end
+
+ it "should dump YAML that produces an equivalent object" do
+ result = YAML.dump(@bucket)
+
+ newobj = YAML.load(result)
+ newobj.name.should == "one"
+ newobj.type.should == "two"
+ children = []
+ newobj.each do |o|
+ children << o
+ end
+ children.should == %w{one two}
+ end
end
describe Puppet::TransBucket, " when converting to a Puppet::Resource" do
- before do
- @trans = Puppet::TransBucket.new
- @trans.name = "foo"
- @trans.type = "bar"
- @trans.param(:noop, true)
- end
-
- it "should create a resource with the correct type and title" do
- result = @trans.to_resource
- result.type.should == "Bar"
- result.title.should == "foo"
- end
-
- it "should add all of its parameters to the created resource" do
- @trans.param(:noop, true)
- @trans.to_resource[:noop].should be_true
- end
+ before do
+ @trans = Puppet::TransBucket.new
+ @trans.name = "foo"
+ @trans.type = "bar"
+ @trans.param(:noop, true)
+ end
+
+ it "should create a resource with the correct type and title" do
+ result = @trans.to_resource
+ result.type.should == "Bar"
+ result.title.should == "foo"
+ end
+
+ it "should add all of its parameters to the created resource" do
+ @trans.param(:noop, true)
+ @trans.to_resource[:noop].should be_true
+ end
end
diff --git a/spec/unit/other/transobject_spec.rb b/spec/unit/other/transobject_spec.rb
index 92ed266..352af48 100755
--- a/spec/unit/other/transobject_spec.rb
+++ b/spec/unit/other/transobject_spec.rb
@@ -5,108 +5,108 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/transportable'
describe Puppet::TransObject do
- it "should canonize resource references" do
- resource = Puppet::TransObject.new("me", "foo::bar")
- resource.ref.should == 'Foo::Bar[me]'
- end
-
- it "should lower-case resource types for backward compatibility with 0.23.2" do
- resource = Puppet::TransObject.new("me", "Foo")
- resource.type.should == 'foo'
- end
+ it "should canonize resource references" do
+ resource = Puppet::TransObject.new("me", "foo::bar")
+ resource.ref.should == 'Foo::Bar[me]'
+ end
+
+ it "should lower-case resource types for backward compatibility with 0.23.2" do
+ resource = Puppet::TransObject.new("me", "Foo")
+ resource.type.should == 'foo'
+ end
end
describe Puppet::TransObject, " when serializing" do
- before do
- @resource = Puppet::TransObject.new("/my/file", "file")
- @resource["one"] = "test"
- @resource["two"] = "other"
- end
-
- it "should be able to be dumped to yaml" do
- proc { YAML.dump(@resource) }.should_not raise_error
- end
-
- it "should produce an equivalent yaml object" do
- text = YAML.dump(@resource)
-
- newresource = YAML.load(text)
- newresource.name.should == "/my/file"
- newresource.type.should == "file"
- %w{one two}.each do |param|
- newresource[param].should == @resource[param]
- end
- end
+ before do
+ @resource = Puppet::TransObject.new("/my/file", "file")
+ @resource["one"] = "test"
+ @resource["two"] = "other"
+ end
+
+ it "should be able to be dumped to yaml" do
+ proc { YAML.dump(@resource) }.should_not raise_error
+ end
+
+ it "should produce an equivalent yaml object" do
+ text = YAML.dump(@resource)
+
+ newresource = YAML.load(text)
+ newresource.name.should == "/my/file"
+ newresource.type.should == "file"
+ %w{one two}.each do |param|
+ newresource[param].should == @resource[param]
+ end
+ end
end
describe Puppet::TransObject, " when converting to a Puppet::Resource" do
- before do
- @trans = Puppet::TransObject.new("/my/file", "file")
- @trans["one"] = "test"
- @trans["two"] = "other"
- end
-
- it "should create a resource with the correct type and title" do
- result = @trans.to_resource
- result.type.should == "File"
- result.title.should == "/my/file"
- end
-
- it "should add all of its parameters to the created resource" do
- @trans[:noop] = true
- @trans.to_resource[:noop].should be_true
- end
-
- it "should copy over the tags" do
- @trans.tags = %w{foo bar}
- result = @trans.to_resource
- result.should be_tagged("foo")
- result.should be_tagged("bar")
- end
+ before do
+ @trans = Puppet::TransObject.new("/my/file", "file")
+ @trans["one"] = "test"
+ @trans["two"] = "other"
+ end
+
+ it "should create a resource with the correct type and title" do
+ result = @trans.to_resource
+ result.type.should == "File"
+ result.title.should == "/my/file"
+ end
+
+ it "should add all of its parameters to the created resource" do
+ @trans[:noop] = true
+ @trans.to_resource[:noop].should be_true
+ end
+
+ it "should copy over the tags" do
+ @trans.tags = %w{foo bar}
+ result = @trans.to_resource
+ result.should be_tagged("foo")
+ result.should be_tagged("bar")
+ end
end
describe Puppet::TransObject, " when converting to a RAL resource" do
- before do
- @resource = Puppet::TransObject.new("/my/file", "file")
- @resource["one"] = "test"
- @resource["two"] = "other"
- end
-
- it "should use a Puppet::Resource to create the resource" do
- resource = mock 'resource'
- @resource.expects(:to_resource).returns resource
- resource.expects(:to_ral).returns "myral"
- @resource.to_ral.should == "myral"
- end
+ before do
+ @resource = Puppet::TransObject.new("/my/file", "file")
+ @resource["one"] = "test"
+ @resource["two"] = "other"
+ end
+
+ it "should use a Puppet::Resource to create the resource" do
+ resource = mock 'resource'
+ @resource.expects(:to_resource).returns resource
+ resource.expects(:to_ral).returns "myral"
+ @resource.to_ral.should == "myral"
+ end
end
describe Puppet::TransObject, " when converting to a RAL component instance" do
- before do
- @resource = Puppet::TransObject.new("/my/file", "one::two")
- @resource["one"] = "test"
- @resource["noop"] = "other"
- end
-
- it "should use a new TransObject whose name is a resource reference of the type and title of the original TransObject" do
- Puppet::Type::Component.expects(:new).with { |resource| resource.type == "component" and resource.name == "One::Two[/my/file]" }.returns(:yay)
- @resource.to_component.should == :yay
- end
-
- it "should pass the resource parameters on to the newly created TransObject" do
- Puppet::Type::Component.expects(:new).with { |resource| resource["noop"] == "other" }.returns(:yay)
- @resource.to_component.should == :yay
- end
-
- it "should copy over the catalog" do
- @resource.catalog = "mycat"
- Puppet::Type::Component.expects(:new).with { |resource| resource.catalog == "mycat" }.returns(:yay)
- @resource.to_component
- end
-
- # LAK:FIXME This really isn't the design we want going forward, but it's
- # good enough for now.
- it "should not pass resource parameters that are not metaparams" do
- Puppet::Type::Component.expects(:new).with { |resource| resource["one"].nil? }.returns(:yay)
- @resource.to_component.should == :yay
- end
+ before do
+ @resource = Puppet::TransObject.new("/my/file", "one::two")
+ @resource["one"] = "test"
+ @resource["noop"] = "other"
+ end
+
+ it "should use a new TransObject whose name is a resource reference of the type and title of the original TransObject" do
+ Puppet::Type::Component.expects(:new).with { |resource| resource.type == "component" and resource.name == "One::Two[/my/file]" }.returns(:yay)
+ @resource.to_component.should == :yay
+ end
+
+ it "should pass the resource parameters on to the newly created TransObject" do
+ Puppet::Type::Component.expects(:new).with { |resource| resource["noop"] == "other" }.returns(:yay)
+ @resource.to_component.should == :yay
+ end
+
+ it "should copy over the catalog" do
+ @resource.catalog = "mycat"
+ Puppet::Type::Component.expects(:new).with { |resource| resource.catalog == "mycat" }.returns(:yay)
+ @resource.to_component
+ end
+
+ # LAK:FIXME This really isn't the design we want going forward, but it's
+ # good enough for now.
+ it "should not pass resource parameters that are not metaparams" do
+ Puppet::Type::Component.expects(:new).with { |resource| resource["one"].nil? }.returns(:yay)
+ @resource.to_component.should == :yay
+ end
end
diff --git a/spec/unit/parameter/value_collection_spec.rb b/spec/unit/parameter/value_collection_spec.rb
index 421e5a2..78c2c52 100755
--- a/spec/unit/parameter/value_collection_spec.rb
+++ b/spec/unit/parameter/value_collection_spec.rb
@@ -5,163 +5,163 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/parameter'
describe Puppet::Parameter::ValueCollection do
- before do
- @collection = Puppet::Parameter::ValueCollection.new
- end
+ before do
+ @collection = Puppet::Parameter::ValueCollection.new
+ end
+
+ it "should have a method for defining new values" do
+ @collection.should respond_to(:newvalues)
+ end
+
+ it "should have a method for adding individual values" do
+ @collection.should respond_to(:newvalue)
+ end
+
+ it "should be able to retrieve individual values" do
+ value = @collection.newvalue(:foo)
+ @collection.value(:foo).should equal(value)
+ end
- it "should have a method for defining new values" do
- @collection.should respond_to(:newvalues)
- end
+ it "should be able to add an individual value with a block" do
+ @collection.newvalue(:foo) { raise "testing" }
+ @collection.value(:foo).block.should be_instance_of(Proc)
+ end
- it "should have a method for adding individual values" do
- @collection.should respond_to(:newvalue)
- end
+ it "should be able to add values that are empty strings" do
+ lambda { @collection.newvalue('') }.should_not raise_error
+ end
- it "should be able to retrieve individual values" do
- value = @collection.newvalue(:foo)
- @collection.value(:foo).should equal(value)
- end
+ it "should be able to add values that are empty strings" do
+ value = @collection.newvalue('')
+ @collection.match?('').should equal(value)
+ end
- it "should be able to add an individual value with a block" do
- @collection.newvalue(:foo) { raise "testing" }
- @collection.value(:foo).block.should be_instance_of(Proc)
- end
+ it "should set :call to :none when adding a value with no block" do
+ value = @collection.newvalue(:foo)
+ value.call.should == :none
+ end
- it "should be able to add values that are empty strings" do
- lambda { @collection.newvalue('') }.should_not raise_error
+ describe "when adding a value with a block" do
+ it "should set the method name to 'set_' plus the value name" do
+ value = @collection.newvalue(:myval) { raise "testing" }
+ value.method.should == "set_myval"
end
+ end
- it "should be able to add values that are empty strings" do
- value = @collection.newvalue('')
- @collection.match?('').should equal(value)
- end
+ it "should be able to add an individual value with options" do
+ value = @collection.newvalue(:foo, :call => :bar)
+ value.call.should == :bar
+ end
- it "should set :call to :none when adding a value with no block" do
- value = @collection.newvalue(:foo)
- value.call.should == :none
- end
+ it "should have a method for validating a value" do
+ @collection.should respond_to(:validate)
+ end
- describe "when adding a value with a block" do
- it "should set the method name to 'set_' plus the value name" do
- value = @collection.newvalue(:myval) { raise "testing" }
- value.method.should == "set_myval"
- end
- end
+ it "should have a method for munging a value" do
+ @collection.should respond_to(:munge)
+ end
- it "should be able to add an individual value with options" do
- value = @collection.newvalue(:foo, :call => :bar)
- value.call.should == :bar
- end
+ it "should be able to generate documentation when it has both values and regexes" do
+ @collection.newvalues :foo, "bar", %r{test}
+ @collection.doc.should be_instance_of(String)
+ end
+
+ it "should correctly generate documentation for values" do
+ @collection.newvalues :foo
+ @collection.doc.should be_include("Valid values are ``foo``")
+ end
+
+ it "should correctly generate documentation for regexes" do
+ @collection.newvalues %r{\w+}
+ @collection.doc.should be_include("Values can match ``/\\w+/``")
+ end
+
+ it "should be able to find the first matching value" do
+ @collection.newvalues :foo, :bar
+ @collection.match?("foo").should be_instance_of(Puppet::Parameter::Value)
+ end
+
+ it "should be able to match symbols" do
+ @collection.newvalues :foo, :bar
+ @collection.match?(:foo).should be_instance_of(Puppet::Parameter::Value)
+ end
+
+ it "should be able to match symbols when a regex is provided" do
+ @collection.newvalues %r{.}
+ @collection.match?(:foo).should be_instance_of(Puppet::Parameter::Value)
+ end
+
+ it "should be able to match values using regexes" do
+ @collection.newvalues %r{.}
+ @collection.match?("foo").should_not be_nil
+ end
+
+ it "should prefer value matches to regex matches" do
+ @collection.newvalues %r{.}, :foo
+ @collection.match?("foo").name.should == :foo
+ end
- it "should have a method for validating a value" do
- @collection.should respond_to(:validate)
+ describe "when validating values" do
+ it "should do nothing if no values or regexes have been defined" do
+ @collection.validate("foo")
end
- it "should have a method for munging a value" do
- @collection.should respond_to(:munge)
+ it "should fail if the value is not a defined value or alias and does not match a regex" do
+ @collection.newvalues :foo
+ lambda { @collection.validate("bar") }.should raise_error(ArgumentError)
end
- it "should be able to generate documentation when it has both values and regexes" do
- @collection.newvalues :foo, "bar", %r{test}
- @collection.doc.should be_instance_of(String)
+ it "should succeed if the value is one of the defined values" do
+ @collection.newvalues :foo
+ lambda { @collection.validate(:foo) }.should_not raise_error(ArgumentError)
end
- it "should correctly generate documentation for values" do
- @collection.newvalues :foo
- @collection.doc.should be_include("Valid values are ``foo``")
+ it "should succeed if the value is one of the defined values even if the definition uses a symbol and the validation uses a string" do
+ @collection.newvalues :foo
+ lambda { @collection.validate("foo") }.should_not raise_error(ArgumentError)
end
- it "should correctly generate documentation for regexes" do
- @collection.newvalues %r{\w+}
- @collection.doc.should be_include("Values can match ``/\\w+/``")
+ it "should succeed if the value is one of the defined values even if the definition uses a string and the validation uses a symbol" do
+ @collection.newvalues "foo"
+ lambda { @collection.validate(:foo) }.should_not raise_error(ArgumentError)
end
- it "should be able to find the first matching value" do
- @collection.newvalues :foo, :bar
- @collection.match?("foo").should be_instance_of(Puppet::Parameter::Value)
+ it "should succeed if the value is one of the defined aliases" do
+ @collection.newvalues :foo
+ @collection.aliasvalue :bar, :foo
+ lambda { @collection.validate("bar") }.should_not raise_error(ArgumentError)
end
- it "should be able to match symbols" do
- @collection.newvalues :foo, :bar
- @collection.match?(:foo).should be_instance_of(Puppet::Parameter::Value)
+ it "should succeed if the value matches one of the regexes" do
+ @collection.newvalues %r{\d}
+ lambda { @collection.validate("10") }.should_not raise_error(ArgumentError)
end
+ end
- it "should be able to match symbols when a regex is provided" do
- @collection.newvalues %r{.}
- @collection.match?(:foo).should be_instance_of(Puppet::Parameter::Value)
+ describe "when munging values" do
+ it "should do nothing if no values or regexes have been defined" do
+ @collection.munge("foo").should == "foo"
end
- it "should be able to match values using regexes" do
- @collection.newvalues %r{.}
- @collection.match?("foo").should_not be_nil
+ it "should return return any matching defined values" do
+ @collection.newvalues :foo, :bar
+ @collection.munge("foo").should == :foo
end
- it "should prefer value matches to regex matches" do
- @collection.newvalues %r{.}, :foo
- @collection.match?("foo").name.should == :foo
+ it "should return any matching aliases" do
+ @collection.newvalues :foo
+ @collection.aliasvalue :bar, :foo
+ @collection.munge("bar").should == :foo
end
- describe "when validating values" do
- it "should do nothing if no values or regexes have been defined" do
- @collection.validate("foo")
- end
-
- it "should fail if the value is not a defined value or alias and does not match a regex" do
- @collection.newvalues :foo
- lambda { @collection.validate("bar") }.should raise_error(ArgumentError)
- end
-
- it "should succeed if the value is one of the defined values" do
- @collection.newvalues :foo
- lambda { @collection.validate(:foo) }.should_not raise_error(ArgumentError)
- end
-
- it "should succeed if the value is one of the defined values even if the definition uses a symbol and the validation uses a string" do
- @collection.newvalues :foo
- lambda { @collection.validate("foo") }.should_not raise_error(ArgumentError)
- end
-
- it "should succeed if the value is one of the defined values even if the definition uses a string and the validation uses a symbol" do
- @collection.newvalues "foo"
- lambda { @collection.validate(:foo) }.should_not raise_error(ArgumentError)
- end
-
- it "should succeed if the value is one of the defined aliases" do
- @collection.newvalues :foo
- @collection.aliasvalue :bar, :foo
- lambda { @collection.validate("bar") }.should_not raise_error(ArgumentError)
- end
-
- it "should succeed if the value matches one of the regexes" do
- @collection.newvalues %r{\d}
- lambda { @collection.validate("10") }.should_not raise_error(ArgumentError)
- end
+ it "should return the value if it matches a regex" do
+ @collection.newvalues %r{\w}
+ @collection.munge("bar").should == "bar"
end
- describe "when munging values" do
- it "should do nothing if no values or regexes have been defined" do
- @collection.munge("foo").should == "foo"
- end
-
- it "should return return any matching defined values" do
- @collection.newvalues :foo, :bar
- @collection.munge("foo").should == :foo
- end
-
- it "should return any matching aliases" do
- @collection.newvalues :foo
- @collection.aliasvalue :bar, :foo
- @collection.munge("bar").should == :foo
- end
-
- it "should return the value if it matches a regex" do
- @collection.newvalues %r{\w}
- @collection.munge("bar").should == "bar"
- end
-
- it "should return the value if no other option is matched" do
- @collection.newvalues :foo
- @collection.munge("bar").should == "bar"
- end
+ it "should return the value if no other option is matched" do
+ @collection.newvalues :foo
+ @collection.munge("bar").should == "bar"
end
+ end
end
diff --git a/spec/unit/parameter/value_spec.rb b/spec/unit/parameter/value_spec.rb
index f6def01..10b24fb 100755
--- a/spec/unit/parameter/value_spec.rb
+++ b/spec/unit/parameter/value_spec.rb
@@ -5,84 +5,84 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/parameter'
describe Puppet::Parameter::Value do
- it "should require a name" do
- lambda { Puppet::Parameter::Value.new }.should raise_error(ArgumentError)
+ it "should require a name" do
+ lambda { Puppet::Parameter::Value.new }.should raise_error(ArgumentError)
+ end
+
+ it "should set its name" do
+ Puppet::Parameter::Value.new(:foo).name.should == :foo
+ end
+
+ it "should support regexes as names" do
+ lambda { Puppet::Parameter::Value.new(%r{foo}) }.should_not raise_error
+ end
+
+ it "should mark itself as a regex if its name is a regex" do
+ Puppet::Parameter::Value.new(%r{foo}).should be_regex
+ end
+
+ it "should always convert its name to a symbol if it is not a regex" do
+ Puppet::Parameter::Value.new("foo").name.should == :foo
+ Puppet::Parameter::Value.new(true).name.should == :true
+ end
+
+ it "should support adding aliases" do
+ Puppet::Parameter::Value.new("foo").should respond_to(:alias)
+ end
+
+ it "should be able to return its aliases" do
+ value = Puppet::Parameter::Value.new("foo")
+ value.alias("bar")
+ value.alias("baz")
+ value.aliases.should == [:bar, :baz]
+ end
+
+ [:block, :call, :method, :event, :required_features].each do |attr|
+ it "should support a #{attr} attribute" do
+ value = Puppet::Parameter::Value.new("foo")
+ value.should respond_to(attr.to_s + "=")
+ value.should respond_to(attr)
end
-
- it "should set its name" do
- Puppet::Parameter::Value.new(:foo).name.should == :foo
- end
-
- it "should support regexes as names" do
- lambda { Puppet::Parameter::Value.new(%r{foo}) }.should_not raise_error
- end
-
- it "should mark itself as a regex if its name is a regex" do
- Puppet::Parameter::Value.new(%r{foo}).should be_regex
+ end
+
+ it "should default to :instead for :call if a block is provided" do
+ Puppet::Parameter::Value.new("foo").call.should == :instead
+ end
+
+ it "should always return events as symbols" do
+ value = Puppet::Parameter::Value.new("foo")
+ value.event = "foo_test"
+ value.event.should == :foo_test
+ end
+
+ describe "when matching" do
+ describe "a regex" do
+ it "should return true if the regex matches the value" do
+ Puppet::Parameter::Value.new(/\w/).should be_match("foo")
+ end
+
+ it "should return false if the regex does not match the value" do
+ Puppet::Parameter::Value.new(/\d/).should_not be_match("foo")
+ end
end
- it "should always convert its name to a symbol if it is not a regex" do
- Puppet::Parameter::Value.new("foo").name.should == :foo
- Puppet::Parameter::Value.new(true).name.should == :true
- end
+ describe "a non-regex" do
+ it "should return true if the value, converted to a symbol, matches the name" do
+ Puppet::Parameter::Value.new("foo").should be_match("foo")
+ Puppet::Parameter::Value.new(:foo).should be_match(:foo)
+ Puppet::Parameter::Value.new(:foo).should be_match("foo")
+ Puppet::Parameter::Value.new("foo").should be_match(:foo)
+ end
- it "should support adding aliases" do
- Puppet::Parameter::Value.new("foo").should respond_to(:alias)
- end
+ it "should return false if the value, converted to a symbol, does not match the name" do
+ Puppet::Parameter::Value.new(:foo).should_not be_match(:bar)
+ end
- it "should be able to return its aliases" do
+ it "should return true if any of its aliases match" do
value = Puppet::Parameter::Value.new("foo")
value.alias("bar")
- value.alias("baz")
- value.aliases.should == [:bar, :baz]
- end
-
- [:block, :call, :method, :event, :required_features].each do |attr|
- it "should support a #{attr} attribute" do
- value = Puppet::Parameter::Value.new("foo")
- value.should respond_to(attr.to_s + "=")
- value.should respond_to(attr)
- end
- end
-
- it "should default to :instead for :call if a block is provided" do
- Puppet::Parameter::Value.new("foo").call.should == :instead
- end
-
- it "should always return events as symbols" do
- value = Puppet::Parameter::Value.new("foo")
- value.event = "foo_test"
- value.event.should == :foo_test
- end
-
- describe "when matching" do
- describe "a regex" do
- it "should return true if the regex matches the value" do
- Puppet::Parameter::Value.new(/\w/).should be_match("foo")
- end
-
- it "should return false if the regex does not match the value" do
- Puppet::Parameter::Value.new(/\d/).should_not be_match("foo")
- end
- end
-
- describe "a non-regex" do
- it "should return true if the value, converted to a symbol, matches the name" do
- Puppet::Parameter::Value.new("foo").should be_match("foo")
- Puppet::Parameter::Value.new(:foo).should be_match(:foo)
- Puppet::Parameter::Value.new(:foo).should be_match("foo")
- Puppet::Parameter::Value.new("foo").should be_match(:foo)
- end
-
- it "should return false if the value, converted to a symbol, does not match the name" do
- Puppet::Parameter::Value.new(:foo).should_not be_match(:bar)
- end
-
- it "should return true if any of its aliases match" do
- value = Puppet::Parameter::Value.new("foo")
- value.alias("bar")
- value.should be_match("bar")
- end
- end
+ value.should be_match("bar")
+ end
end
+ end
end
diff --git a/spec/unit/parameter_spec.rb b/spec/unit/parameter_spec.rb
index 03674cb..966bbfb 100755
--- a/spec/unit/parameter_spec.rb
+++ b/spec/unit/parameter_spec.rb
@@ -5,168 +5,168 @@ require File.dirname(__FILE__) + '/../spec_helper'
require 'puppet/parameter'
describe Puppet::Parameter do
- before do
- @class = Class.new(Puppet::Parameter) do
- @name = :foo
- end
- @class.initvars
- @resource = mock 'resource'
- @resource.stub_everything
- @parameter = @class.new :resource => @resource
+ before do
+ @class = Class.new(Puppet::Parameter) do
+ @name = :foo
+ end
+ @class.initvars
+ @resource = mock 'resource'
+ @resource.stub_everything
+ @parameter = @class.new :resource => @resource
+ end
+
+ it "should create a value collection" do
+ @class = Class.new(Puppet::Parameter)
+ @class.value_collection.should be_nil
+ @class.initvars
+ @class.value_collection.should be_instance_of(Puppet::Parameter::ValueCollection)
+ end
+
+ it "should return its name as a string when converted to a string" do
+ @parameter.to_s.should == @parameter.name.to_s
+ end
+
+ it "should be able to use cached attributes" do
+ Puppet::Parameter.ancestors.should be_include(Puppet::Util::Cacher)
+ end
+
+ it "should use the resource catalog for expiration" do
+ catalog = mock 'catalog'
+ @resource.stubs(:catalog).returns catalog
+ @parameter.expirer.should equal(catalog)
+ end
+
+ [:line, :file, :version].each do |data|
+ it "should return its resource's #{data} as its #{data}" do
+ @resource.expects(data).returns "foo"
+ @parameter.send(data).should == "foo"
+ end
+ end
+
+ it "should return the resource's tags plus its name as its tags" do
+ @resource.expects(:tags).returns %w{one two}
+ @parameter.tags.should == %w{one two foo}
+ end
+
+ it "should provide source_descriptors" do
+ @resource.expects(:line).returns 10
+ @resource.expects(:file).returns "file"
+ @resource.expects(:tags).returns %w{one two}
+ @resource.expects(:version).returns 50
+ @parameter.source_descriptors.should == {:tags=>["one", "two", "foo"], :path=>"//foo", :version=>50, :file => "file", :line => 10}
+ end
+
+ describe "when returning the value" do
+ it "should return nil if no value is set" do
+ @parameter.value.should be_nil
+ end
+
+ it "should validate the value" do
+ @parameter.expects(:validate).with("foo")
+ @parameter.value = "foo"
+ end
+
+ it "should munge the value and use any result as the actual value" do
+ @parameter.expects(:munge).with("foo").returns "bar"
+ @parameter.value = "foo"
+ @parameter.value.should == "bar"
end
- it "should create a value collection" do
- @class = Class.new(Puppet::Parameter)
- @class.value_collection.should be_nil
- @class.initvars
- @class.value_collection.should be_instance_of(Puppet::Parameter::ValueCollection)
+ it "should unmunge the value when accessing the actual value" do
+ @parameter.class.unmunge do |value| value.to_sym end
+ @parameter.value = "foo"
+ @parameter.value.should == :foo
end
- it "should return its name as a string when converted to a string" do
- @parameter.to_s.should == @parameter.name.to_s
+ it "should return the actual value by default when unmunging" do
+ @parameter.unmunge("bar").should == "bar"
end
- it "should be able to use cached attributes" do
- Puppet::Parameter.ancestors.should be_include(Puppet::Util::Cacher)
+ it "should return any set value" do
+ @parameter.value = "foo"
+ @parameter.value.should == "foo"
end
+ end
- it "should use the resource catalog for expiration" do
- catalog = mock 'catalog'
- @resource.stubs(:catalog).returns catalog
- @parameter.expirer.should equal(catalog)
+ describe "when validating values" do
+ it "should do nothing if no values or regexes have been defined" do
+ @parameter.validate("foo")
end
- [:line, :file, :version].each do |data|
- it "should return its resource's #{data} as its #{data}" do
- @resource.expects(data).returns "foo"
- @parameter.send(data).should == "foo"
- end
+ it "should catch abnormal failures thrown during validation" do
+ @class.validate { |v| raise "This is broken" }
+ lambda { @parameter.validate("eh") }.should raise_error(Puppet::DevError)
end
- it "should return the resource's tags plus its name as its tags" do
- @resource.expects(:tags).returns %w{one two}
- @parameter.tags.should == %w{one two foo}
+ it "should fail if the value is not a defined value or alias and does not match a regex" do
+ @class.newvalues :foo
+ lambda { @parameter.validate("bar") }.should raise_error(Puppet::Error)
end
- it "should provide source_descriptors" do
- @resource.expects(:line).returns 10
- @resource.expects(:file).returns "file"
- @resource.expects(:tags).returns %w{one two}
- @resource.expects(:version).returns 50
- @parameter.source_descriptors.should == {:tags=>["one", "two", "foo"], :path=>"//foo", :version=>50, :file => "file", :line => 10}
- end
+ it "should succeed if the value is one of the defined values" do
+ @class.newvalues :foo
+ lambda { @parameter.validate(:foo) }.should_not raise_error(ArgumentError)
+ end
+
+ it "should succeed if the value is one of the defined values even if the definition uses a symbol and the validation uses a string" do
+ @class.newvalues :foo
+ lambda { @parameter.validate("foo") }.should_not raise_error(ArgumentError)
+ end
- describe "when returning the value" do
- it "should return nil if no value is set" do
- @parameter.value.should be_nil
- end
-
- it "should validate the value" do
- @parameter.expects(:validate).with("foo")
- @parameter.value = "foo"
- end
-
- it "should munge the value and use any result as the actual value" do
- @parameter.expects(:munge).with("foo").returns "bar"
- @parameter.value = "foo"
- @parameter.value.should == "bar"
- end
-
- it "should unmunge the value when accessing the actual value" do
- @parameter.class.unmunge do |value| value.to_sym end
- @parameter.value = "foo"
- @parameter.value.should == :foo
- end
-
- it "should return the actual value by default when unmunging" do
- @parameter.unmunge("bar").should == "bar"
- end
-
- it "should return any set value" do
- @parameter.value = "foo"
- @parameter.value.should == "foo"
- end
- end
-
- describe "when validating values" do
- it "should do nothing if no values or regexes have been defined" do
- @parameter.validate("foo")
- end
-
- it "should catch abnormal failures thrown during validation" do
- @class.validate { |v| raise "This is broken" }
- lambda { @parameter.validate("eh") }.should raise_error(Puppet::DevError)
- end
-
- it "should fail if the value is not a defined value or alias and does not match a regex" do
- @class.newvalues :foo
- lambda { @parameter.validate("bar") }.should raise_error(Puppet::Error)
- end
-
- it "should succeed if the value is one of the defined values" do
- @class.newvalues :foo
- lambda { @parameter.validate(:foo) }.should_not raise_error(ArgumentError)
- end
+ it "should succeed if the value is one of the defined values even if the definition uses a string and the validation uses a symbol" do
+ @class.newvalues "foo"
+ lambda { @parameter.validate(:foo) }.should_not raise_error(ArgumentError)
+ end
- it "should succeed if the value is one of the defined values even if the definition uses a symbol and the validation uses a string" do
- @class.newvalues :foo
- lambda { @parameter.validate("foo") }.should_not raise_error(ArgumentError)
- end
+ it "should succeed if the value is one of the defined aliases" do
+ @class.newvalues :foo
+ @class.aliasvalue :bar, :foo
+ lambda { @parameter.validate("bar") }.should_not raise_error(ArgumentError)
+ end
- it "should succeed if the value is one of the defined values even if the definition uses a string and the validation uses a symbol" do
- @class.newvalues "foo"
- lambda { @parameter.validate(:foo) }.should_not raise_error(ArgumentError)
- end
+ it "should succeed if the value matches one of the regexes" do
+ @class.newvalues %r{\d}
+ lambda { @parameter.validate("10") }.should_not raise_error(ArgumentError)
+ end
+ end
- it "should succeed if the value is one of the defined aliases" do
- @class.newvalues :foo
- @class.aliasvalue :bar, :foo
- lambda { @parameter.validate("bar") }.should_not raise_error(ArgumentError)
- end
+ describe "when munging values" do
+ it "should do nothing if no values or regexes have been defined" do
+ @parameter.munge("foo").should == "foo"
+ end
+
+ it "should catch abnormal failures thrown during munging" do
+ @class.munge { |v| raise "This is broken" }
+ lambda { @parameter.munge("eh") }.should raise_error(Puppet::DevError)
+ end
+
+ it "should return return any matching defined values" do
+ @class.newvalues :foo, :bar
+ @parameter.munge("foo").should == :foo
+ end
+
+ it "should return any matching aliases" do
+ @class.newvalues :foo
+ @class.aliasvalue :bar, :foo
+ @parameter.munge("bar").should == :foo
+ end
+
+ it "should return the value if it matches a regex" do
+ @class.newvalues %r{\w}
+ @parameter.munge("bar").should == "bar"
+ end
+
+ it "should return the value if no other option is matched" do
+ @class.newvalues :foo
+ @parameter.munge("bar").should == "bar"
+ end
+ end
- it "should succeed if the value matches one of the regexes" do
- @class.newvalues %r{\d}
- lambda { @parameter.validate("10") }.should_not raise_error(ArgumentError)
- end
- end
-
- describe "when munging values" do
- it "should do nothing if no values or regexes have been defined" do
- @parameter.munge("foo").should == "foo"
- end
-
- it "should catch abnormal failures thrown during munging" do
- @class.munge { |v| raise "This is broken" }
- lambda { @parameter.munge("eh") }.should raise_error(Puppet::DevError)
- end
-
- it "should return return any matching defined values" do
- @class.newvalues :foo, :bar
- @parameter.munge("foo").should == :foo
- end
-
- it "should return any matching aliases" do
- @class.newvalues :foo
- @class.aliasvalue :bar, :foo
- @parameter.munge("bar").should == :foo
- end
-
- it "should return the value if it matches a regex" do
- @class.newvalues %r{\w}
- @parameter.munge("bar").should == "bar"
- end
-
- it "should return the value if no other option is matched" do
- @class.newvalues :foo
- @parameter.munge("bar").should == "bar"
- end
- end
-
- describe "when logging" do
- it "should use its resource's log level and the provided message" do
- @resource.expects(:[]).with(:loglevel).returns :notice
- @parameter.expects(:send_log).with(:notice, "mymessage")
- @parameter.log "mymessage"
- end
+ describe "when logging" do
+ it "should use its resource's log level and the provided message" do
+ @resource.expects(:[]).with(:loglevel).returns :notice
+ @parameter.expects(:send_log).with(:notice, "mymessage")
+ @parameter.log "mymessage"
end
+ end
end
diff --git a/spec/unit/parser/ast/arithmetic_operator_spec.rb b/spec/unit/parser/ast/arithmetic_operator_spec.rb
index 3ebd269..093cf94 100755
--- a/spec/unit/parser/ast/arithmetic_operator_spec.rb
+++ b/spec/unit/parser/ast/arithmetic_operator_spec.rb
@@ -4,70 +4,70 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::ArithmeticOperator do
- ast = Puppet::Parser::AST
-
- before :each do
- @scope = Puppet::Parser::Scope.new
- @one = stub 'lval', :safeevaluate => 1
- @two = stub 'rval', :safeevaluate => 2
- end
-
- it "should evaluate both branches" do
- lval = stub "lval"
- lval.expects(:safeevaluate).with(@scope).returns(1)
- rval = stub "rval"
- rval.expects(:safeevaluate).with(@scope).returns(2)
-
- operator = ast::ArithmeticOperator.new :rval => rval, :operator => "+", :lval => lval
- operator.evaluate(@scope)
- end
-
- it "should fail for an unknown operator" do
- lambda { operator = ast::ArithmeticOperator.new :lval => @one, :operator => "%", :rval => @two }.should raise_error
- end
-
- it "should call Puppet::Parser::Scope.number?" do
- Puppet::Parser::Scope.expects(:number?).with(1).returns(1)
- Puppet::Parser::Scope.expects(:number?).with(2).returns(2)
-
- ast::ArithmeticOperator.new(:lval => @one, :operator => "+", :rval => @two).evaluate(@scope)
- end
-
-
- %w{ + - * / << >>}.each do |op|
- it "should call ruby Numeric '#{op}'" do
- one = stub 'one'
- two = stub 'two'
- operator = ast::ArithmeticOperator.new :lval => @one, :operator => op, :rval => @two
- Puppet::Parser::Scope.stubs(:number?).with(1).returns(one)
- Puppet::Parser::Scope.stubs(:number?).with(2).returns(two)
- one.expects(:send).with(op,two)
- operator.evaluate(@scope)
- end
- end
-
- it "should work even with numbers embedded in strings" do
- two = stub 'two', :safeevaluate => "2"
- one = stub 'one', :safeevaluate => "1"
- operator = ast::ArithmeticOperator.new :lval => two, :operator => "+", :rval => one
- operator.evaluate(@scope).should == 3
- end
-
- it "should work even with floats" do
- two = stub 'two', :safeevaluate => 2.53
- one = stub 'one', :safeevaluate => 1.80
- operator = ast::ArithmeticOperator.new :lval => two, :operator => "+", :rval => one
- operator.evaluate(@scope).should == 4.33
- end
-
- it "should work for variables too" do
- @scope.expects(:lookupvar).with("one", false).returns(1)
- @scope.expects(:lookupvar).with("two", false).returns(2)
- one = ast::Variable.new( :value => "one" )
- two = ast::Variable.new( :value => "two" )
-
- operator = ast::ArithmeticOperator.new :lval => one, :operator => "+", :rval => two
- operator.evaluate(@scope).should == 3
+ ast = Puppet::Parser::AST
+
+ before :each do
+ @scope = Puppet::Parser::Scope.new
+ @one = stub 'lval', :safeevaluate => 1
+ @two = stub 'rval', :safeevaluate => 2
+ end
+
+ it "should evaluate both branches" do
+ lval = stub "lval"
+ lval.expects(:safeevaluate).with(@scope).returns(1)
+ rval = stub "rval"
+ rval.expects(:safeevaluate).with(@scope).returns(2)
+
+ operator = ast::ArithmeticOperator.new :rval => rval, :operator => "+", :lval => lval
+ operator.evaluate(@scope)
+ end
+
+ it "should fail for an unknown operator" do
+ lambda { operator = ast::ArithmeticOperator.new :lval => @one, :operator => "%", :rval => @two }.should raise_error
+ end
+
+ it "should call Puppet::Parser::Scope.number?" do
+ Puppet::Parser::Scope.expects(:number?).with(1).returns(1)
+ Puppet::Parser::Scope.expects(:number?).with(2).returns(2)
+
+ ast::ArithmeticOperator.new(:lval => @one, :operator => "+", :rval => @two).evaluate(@scope)
+ end
+
+
+ %w{ + - * / << >>}.each do |op|
+ it "should call ruby Numeric '#{op}'" do
+ one = stub 'one'
+ two = stub 'two'
+ operator = ast::ArithmeticOperator.new :lval => @one, :operator => op, :rval => @two
+ Puppet::Parser::Scope.stubs(:number?).with(1).returns(one)
+ Puppet::Parser::Scope.stubs(:number?).with(2).returns(two)
+ one.expects(:send).with(op,two)
+ operator.evaluate(@scope)
end
+ end
+
+ it "should work even with numbers embedded in strings" do
+ two = stub 'two', :safeevaluate => "2"
+ one = stub 'one', :safeevaluate => "1"
+ operator = ast::ArithmeticOperator.new :lval => two, :operator => "+", :rval => one
+ operator.evaluate(@scope).should == 3
+ end
+
+ it "should work even with floats" do
+ two = stub 'two', :safeevaluate => 2.53
+ one = stub 'one', :safeevaluate => 1.80
+ operator = ast::ArithmeticOperator.new :lval => two, :operator => "+", :rval => one
+ operator.evaluate(@scope).should == 4.33
+ end
+
+ it "should work for variables too" do
+ @scope.expects(:lookupvar).with("one", false).returns(1)
+ @scope.expects(:lookupvar).with("two", false).returns(2)
+ one = ast::Variable.new( :value => "one" )
+ two = ast::Variable.new( :value => "two" )
+
+ operator = ast::ArithmeticOperator.new :lval => one, :operator => "+", :rval => two
+ operator.evaluate(@scope).should == 3
+ end
end
diff --git a/spec/unit/parser/ast/astarray_spec.rb b/spec/unit/parser/ast/astarray_spec.rb
index b9453c9..f79d6c5 100755
--- a/spec/unit/parser/ast/astarray_spec.rb
+++ b/spec/unit/parser/ast/astarray_spec.rb
@@ -3,70 +3,70 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::ASTArray do
- before :each do
- @scope = Puppet::Parser::Scope.new
- end
-
- it "should have a [] accessor" do
- array = Puppet::Parser::AST::ASTArray.new :children => []
- array.should respond_to(:[])
- end
-
- it "should evaluate all its children" do
- item1 = stub "item1", :is_a? => true
- item2 = stub "item2", :is_a? => true
-
- item1.expects(:safeevaluate).with(@scope).returns(123)
- item2.expects(:safeevaluate).with(@scope).returns(246)
-
- operator = Puppet::Parser::AST::ASTArray.new :children => [item1,item2]
- operator.evaluate(@scope)
- end
-
- it "should evaluate childrens of type ASTArray" do
- item1 = stub "item1", :is_a? => true
- item2 = stub "item2"
- item2.stubs(:is_a?).with(Puppet::Parser::AST).returns(true)
- item2.stubs(:instance_of?).with(Puppet::Parser::AST::ASTArray).returns(true)
- item2.stubs(:each).yields(item1)
-
- item1.expects(:safeevaluate).with(@scope).returns(123)
-
- operator = Puppet::Parser::AST::ASTArray.new :children => [item2]
- operator.evaluate(@scope).should == [123]
- end
-
- it "should flatten children coming from children ASTArray" do
- item1 = stub "item1", :is_a? => true
- item2 = stub "item2"
- item2.stubs(:is_a?).with(Puppet::Parser::AST).returns(true)
- item2.stubs(:instance_of?).with(Puppet::Parser::AST::ASTArray).returns(true)
- item2.stubs(:each).yields([item1])
-
- item1.expects(:safeevaluate).with(@scope).returns(123)
-
- operator = Puppet::Parser::AST::ASTArray.new :children => [item2]
- operator.evaluate(@scope).should == [123]
- end
-
- it "should not flatten the results of children evaluation" do
- item1 = stub "item1", :is_a? => true
- item2 = stub "item2"
- item2.stubs(:is_a?).with(Puppet::Parser::AST).returns(true)
- item2.stubs(:instance_of?).with(Puppet::Parser::AST::ASTArray).returns(true)
- item2.stubs(:each).yields([item1])
-
- item1.expects(:safeevaluate).with(@scope).returns([123])
-
- operator = Puppet::Parser::AST::ASTArray.new :children => [item2]
- operator.evaluate(@scope).should == [[123]]
- end
-
- it "should return a valid string with to_s" do
- a = stub 'a', :is_a? => true, :to_s => "a"
- b = stub 'b', :is_a? => true, :to_s => "b"
- array = Puppet::Parser::AST::ASTArray.new :children => [a,b]
-
- array.to_s.should == "[a, b]"
- end
+ before :each do
+ @scope = Puppet::Parser::Scope.new
+ end
+
+ it "should have a [] accessor" do
+ array = Puppet::Parser::AST::ASTArray.new :children => []
+ array.should respond_to(:[])
+ end
+
+ it "should evaluate all its children" do
+ item1 = stub "item1", :is_a? => true
+ item2 = stub "item2", :is_a? => true
+
+ item1.expects(:safeevaluate).with(@scope).returns(123)
+ item2.expects(:safeevaluate).with(@scope).returns(246)
+
+ operator = Puppet::Parser::AST::ASTArray.new :children => [item1,item2]
+ operator.evaluate(@scope)
+ end
+
+ it "should evaluate childrens of type ASTArray" do
+ item1 = stub "item1", :is_a? => true
+ item2 = stub "item2"
+ item2.stubs(:is_a?).with(Puppet::Parser::AST).returns(true)
+ item2.stubs(:instance_of?).with(Puppet::Parser::AST::ASTArray).returns(true)
+ item2.stubs(:each).yields(item1)
+
+ item1.expects(:safeevaluate).with(@scope).returns(123)
+
+ operator = Puppet::Parser::AST::ASTArray.new :children => [item2]
+ operator.evaluate(@scope).should == [123]
+ end
+
+ it "should flatten children coming from children ASTArray" do
+ item1 = stub "item1", :is_a? => true
+ item2 = stub "item2"
+ item2.stubs(:is_a?).with(Puppet::Parser::AST).returns(true)
+ item2.stubs(:instance_of?).with(Puppet::Parser::AST::ASTArray).returns(true)
+ item2.stubs(:each).yields([item1])
+
+ item1.expects(:safeevaluate).with(@scope).returns(123)
+
+ operator = Puppet::Parser::AST::ASTArray.new :children => [item2]
+ operator.evaluate(@scope).should == [123]
+ end
+
+ it "should not flatten the results of children evaluation" do
+ item1 = stub "item1", :is_a? => true
+ item2 = stub "item2"
+ item2.stubs(:is_a?).with(Puppet::Parser::AST).returns(true)
+ item2.stubs(:instance_of?).with(Puppet::Parser::AST::ASTArray).returns(true)
+ item2.stubs(:each).yields([item1])
+
+ item1.expects(:safeevaluate).with(@scope).returns([123])
+
+ operator = Puppet::Parser::AST::ASTArray.new :children => [item2]
+ operator.evaluate(@scope).should == [[123]]
+ end
+
+ it "should return a valid string with to_s" do
+ a = stub 'a', :is_a? => true, :to_s => "a"
+ b = stub 'b', :is_a? => true, :to_s => "b"
+ array = Puppet::Parser::AST::ASTArray.new :children => [a,b]
+
+ array.to_s.should == "[a, b]"
+ end
end
diff --git a/spec/unit/parser/ast/asthash_spec.rb b/spec/unit/parser/ast/asthash_spec.rb
index be3199b..c70553c 100644
--- a/spec/unit/parser/ast/asthash_spec.rb
+++ b/spec/unit/parser/ast/asthash_spec.rb
@@ -3,96 +3,96 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::ASTHash do
- before :each do
- @scope = Puppet::Parser::Scope.new
+ before :each do
+ @scope = Puppet::Parser::Scope.new
+ end
+
+ it "should have a merge functionality" do
+ hash = Puppet::Parser::AST::ASTHash.new(:value => {})
+ hash.should respond_to(:merge)
+ end
+
+ it "should be able to merge 2 AST hashes" do
+ hash = Puppet::Parser::AST::ASTHash.new(:value => { "a" => "b" })
+
+ hash.merge(Puppet::Parser::AST::ASTHash.new(:value => {"c" => "d"}))
+
+ hash.value.should == { "a" => "b", "c" => "d" }
+ end
+
+ it "should be able to merge with a ruby Hash" do
+ hash = Puppet::Parser::AST::ASTHash.new(:value => { "a" => "b" })
+
+ hash.merge({"c" => "d"})
+
+ hash.value.should == { "a" => "b", "c" => "d" }
+ end
+
+ it "should evaluate each hash value" do
+ key1 = stub "key1"
+ value1 = stub "value1"
+ key2 = stub "key2"
+ value2 = stub "value2"
+
+ value1.expects(:safeevaluate).with(@scope).returns("b")
+ value2.expects(:safeevaluate).with(@scope).returns("d")
+
+ operator = Puppet::Parser::AST::ASTHash.new(:value => { key1 => value1, key2 => value2})
+ operator.evaluate(@scope)
+ end
+
+ it "should evaluate the hash keys if they are AST instances" do
+ key1 = stub "key1"
+ value1 = stub "value1", :safeevaluate => "one"
+ key2 = stub "key2"
+ value2 = stub "value2", :safeevaluate => "two"
+
+ key1.expects(:safeevaluate).with(@scope).returns("1")
+ key2.expects(:safeevaluate).with(@scope).returns("2")
+
+ operator = Puppet::Parser::AST::ASTHash.new(:value => { key1 => value1, key2 => value2})
+ hash = operator.evaluate(@scope)
+ hash["1"].should == "one"
+ hash["2"].should == "two"
+ end
+
+ it "should evaluate the hash keys if they are not AST instances" do
+ key1 = "1"
+ value1 = stub "value1", :safeevaluate => "one"
+ key2 = "2"
+ value2 = stub "value2", :safeevaluate => "two"
+
+ operator = Puppet::Parser::AST::ASTHash.new(:value => { key1 => value1, key2 => value2})
+ hash = operator.evaluate(@scope)
+ hash["1"].should == "one"
+ hash["2"].should == "two"
+ end
+
+ it "should return an evaluated hash" do
+ key1 = stub "key1"
+ value1 = stub "value1", :safeevaluate => "b"
+ key2 = stub "key2"
+ value2 = stub "value2", :safeevaluate => "d"
+
+ operator = Puppet::Parser::AST::ASTHash.new(:value => { key1 => value1, key2 => value2})
+ operator.evaluate(@scope).should == { key1 => "b", key2 => "d" }
+ end
+
+ describe "when being initialized without arguments" do
+ it "should evaluate to an empty hash" do
+ hash = Puppet::Parser::AST::ASTHash.new({})
+ hash.evaluate(@scope).should == {}
end
- it "should have a merge functionality" do
- hash = Puppet::Parser::AST::ASTHash.new(:value => {})
- hash.should respond_to(:merge)
+ it "should support merging" do
+ hash = Puppet::Parser::AST::ASTHash.new({})
+ hash.merge({"a" => "b"}).should == {"a" => "b"}
end
+ end
- it "should be able to merge 2 AST hashes" do
- hash = Puppet::Parser::AST::ASTHash.new(:value => { "a" => "b" })
+ it "should return a valid string with to_s" do
+ hash = Puppet::Parser::AST::ASTHash.new(:value => { "a" => "b", "c" => "d" })
- hash.merge(Puppet::Parser::AST::ASTHash.new(:value => {"c" => "d"}))
-
- hash.value.should == { "a" => "b", "c" => "d" }
- end
-
- it "should be able to merge with a ruby Hash" do
- hash = Puppet::Parser::AST::ASTHash.new(:value => { "a" => "b" })
-
- hash.merge({"c" => "d"})
-
- hash.value.should == { "a" => "b", "c" => "d" }
- end
-
- it "should evaluate each hash value" do
- key1 = stub "key1"
- value1 = stub "value1"
- key2 = stub "key2"
- value2 = stub "value2"
-
- value1.expects(:safeevaluate).with(@scope).returns("b")
- value2.expects(:safeevaluate).with(@scope).returns("d")
-
- operator = Puppet::Parser::AST::ASTHash.new(:value => { key1 => value1, key2 => value2})
- operator.evaluate(@scope)
- end
-
- it "should evaluate the hash keys if they are AST instances" do
- key1 = stub "key1"
- value1 = stub "value1", :safeevaluate => "one"
- key2 = stub "key2"
- value2 = stub "value2", :safeevaluate => "two"
-
- key1.expects(:safeevaluate).with(@scope).returns("1")
- key2.expects(:safeevaluate).with(@scope).returns("2")
-
- operator = Puppet::Parser::AST::ASTHash.new(:value => { key1 => value1, key2 => value2})
- hash = operator.evaluate(@scope)
- hash["1"].should == "one"
- hash["2"].should == "two"
- end
-
- it "should evaluate the hash keys if they are not AST instances" do
- key1 = "1"
- value1 = stub "value1", :safeevaluate => "one"
- key2 = "2"
- value2 = stub "value2", :safeevaluate => "two"
-
- operator = Puppet::Parser::AST::ASTHash.new(:value => { key1 => value1, key2 => value2})
- hash = operator.evaluate(@scope)
- hash["1"].should == "one"
- hash["2"].should == "two"
- end
-
- it "should return an evaluated hash" do
- key1 = stub "key1"
- value1 = stub "value1", :safeevaluate => "b"
- key2 = stub "key2"
- value2 = stub "value2", :safeevaluate => "d"
-
- operator = Puppet::Parser::AST::ASTHash.new(:value => { key1 => value1, key2 => value2})
- operator.evaluate(@scope).should == { key1 => "b", key2 => "d" }
- end
-
- describe "when being initialized without arguments" do
- it "should evaluate to an empty hash" do
- hash = Puppet::Parser::AST::ASTHash.new({})
- hash.evaluate(@scope).should == {}
- end
-
- it "should support merging" do
- hash = Puppet::Parser::AST::ASTHash.new({})
- hash.merge({"a" => "b"}).should == {"a" => "b"}
- end
- end
-
- it "should return a valid string with to_s" do
- hash = Puppet::Parser::AST::ASTHash.new(:value => { "a" => "b", "c" => "d" })
-
- hash.to_s.should == '{a => b, c => d}'
- end
+ hash.to_s.should == '{a => b, c => d}'
+ end
end
diff --git a/spec/unit/parser/ast/boolean_operator_spec.rb b/spec/unit/parser/ast/boolean_operator_spec.rb
index 2307315..10e987e 100755
--- a/spec/unit/parser/ast/boolean_operator_spec.rb
+++ b/spec/unit/parser/ast/boolean_operator_spec.rb
@@ -4,50 +4,50 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::BooleanOperator do
- ast = Puppet::Parser::AST
-
- before :each do
- @scope = Puppet::Parser::Scope.new
- @true_ast = ast::Boolean.new( :value => true)
- @false_ast = ast::Boolean.new( :value => false)
- end
-
- it "should evaluate left operand inconditionally" do
- lval = stub "lval"
- lval.expects(:safeevaluate).with(@scope).returns("true")
- rval = stub "rval", :safeevaluate => false
- rval.expects(:safeevaluate).never
-
- operator = ast::BooleanOperator.new :rval => rval, :operator => "or", :lval => lval
- operator.evaluate(@scope)
- end
-
- it "should evaluate right 'and' operand only if left operand is true" do
- lval = stub "lval", :safeevaluate => true
- rval = stub "rval", :safeevaluate => false
- rval.expects(:safeevaluate).with(@scope).returns(false)
- operator = ast::BooleanOperator.new :rval => rval, :operator => "and", :lval => lval
- operator.evaluate(@scope)
- end
-
- it "should evaluate right 'or' operand only if left operand is false" do
- lval = stub "lval", :safeevaluate => false
- rval = stub "rval", :safeevaluate => false
- rval.expects(:safeevaluate).with(@scope).returns(false)
- operator = ast::BooleanOperator.new :rval => rval, :operator => "or", :lval => lval
- operator.evaluate(@scope)
- end
-
- it "should return true for false OR true" do
- ast::BooleanOperator.new(:rval => @true_ast, :operator => "or", :lval => @false_ast).evaluate(@scope).should be_true
- end
-
- it "should return false for true AND false" do
- ast::BooleanOperator.new(:rval => @true_ast, :operator => "and", :lval => @false_ast ).evaluate(@scope).should be_false
- end
-
- it "should return true for true AND true" do
- ast::BooleanOperator.new(:rval => @true_ast, :operator => "and", :lval => @true_ast ).evaluate(@scope).should be_true
- end
+ ast = Puppet::Parser::AST
+
+ before :each do
+ @scope = Puppet::Parser::Scope.new
+ @true_ast = ast::Boolean.new( :value => true)
+ @false_ast = ast::Boolean.new( :value => false)
+ end
+
+ it "should evaluate left operand inconditionally" do
+ lval = stub "lval"
+ lval.expects(:safeevaluate).with(@scope).returns("true")
+ rval = stub "rval", :safeevaluate => false
+ rval.expects(:safeevaluate).never
+
+ operator = ast::BooleanOperator.new :rval => rval, :operator => "or", :lval => lval
+ operator.evaluate(@scope)
+ end
+
+ it "should evaluate right 'and' operand only if left operand is true" do
+ lval = stub "lval", :safeevaluate => true
+ rval = stub "rval", :safeevaluate => false
+ rval.expects(:safeevaluate).with(@scope).returns(false)
+ operator = ast::BooleanOperator.new :rval => rval, :operator => "and", :lval => lval
+ operator.evaluate(@scope)
+ end
+
+ it "should evaluate right 'or' operand only if left operand is false" do
+ lval = stub "lval", :safeevaluate => false
+ rval = stub "rval", :safeevaluate => false
+ rval.expects(:safeevaluate).with(@scope).returns(false)
+ operator = ast::BooleanOperator.new :rval => rval, :operator => "or", :lval => lval
+ operator.evaluate(@scope)
+ end
+
+ it "should return true for false OR true" do
+ ast::BooleanOperator.new(:rval => @true_ast, :operator => "or", :lval => @false_ast).evaluate(@scope).should be_true
+ end
+
+ it "should return false for true AND false" do
+ ast::BooleanOperator.new(:rval => @true_ast, :operator => "and", :lval => @false_ast ).evaluate(@scope).should be_false
+ end
+
+ it "should return true for true AND true" do
+ ast::BooleanOperator.new(:rval => @true_ast, :operator => "and", :lval => @true_ast ).evaluate(@scope).should be_true
+ end
end
diff --git a/spec/unit/parser/ast/casestatement_spec.rb b/spec/unit/parser/ast/casestatement_spec.rb
index dca8e5a..4d79e54 100755
--- a/spec/unit/parser/ast/casestatement_spec.rb
+++ b/spec/unit/parser/ast/casestatement_spec.rb
@@ -3,159 +3,159 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::CaseStatement do
+ before :each do
+ @scope = Puppet::Parser::Scope.new
+ end
+
+ describe "when evaluating" do
+
before :each do
- @scope = Puppet::Parser::Scope.new
- end
+ @test = stub 'test'
+ @test.stubs(:safeevaluate).with(@scope).returns("value")
+
+ @option1 = stub 'option1', :eachopt => nil, :default? => false
+ @option2 = stub 'option2', :eachopt => nil, :default? => false
- describe "when evaluating" do
+ @options = stub 'options'
+ @options.stubs(:each).multiple_yields(@option1, @option2)
- before :each do
- @test = stub 'test'
- @test.stubs(:safeevaluate).with(@scope).returns("value")
+ @casestmt = Puppet::Parser::AST::CaseStatement.new :test => @test, :options => @options
+ end
- @option1 = stub 'option1', :eachopt => nil, :default? => false
- @option2 = stub 'option2', :eachopt => nil, :default? => false
+ it "should evaluate test" do
+ @test.expects(:safeevaluate).with(@scope)
- @options = stub 'options'
- @options.stubs(:each).multiple_yields(@option1, @option2)
+ @casestmt.evaluate(@scope)
+ end
- @casestmt = Puppet::Parser::AST::CaseStatement.new :test => @test, :options => @options
- end
+ it "should scan each option" do
+ @options.expects(:each).multiple_yields(@option1, @option2)
- it "should evaluate test" do
- @test.expects(:safeevaluate).with(@scope)
+ @casestmt.evaluate(@scope)
+ end
- @casestmt.evaluate(@scope)
- end
+ describe "when scanning options" do
+ before :each do
+ @opval1 = stub_everything 'opval1'
+ @option1.stubs(:eachopt).yields(@opval1)
- it "should scan each option" do
- @options.expects(:each).multiple_yields(@option1, @option2)
+ @opval2 = stub_everything 'opval2'
+ @option2.stubs(:eachopt).yields(@opval2)
+ end
- @casestmt.evaluate(@scope)
- end
+ it "should evaluate each sub-option" do
+ @option1.expects(:eachopt)
+ @option2.expects(:eachopt)
- describe "when scanning options" do
- before :each do
- @opval1 = stub_everything 'opval1'
- @option1.stubs(:eachopt).yields(@opval1)
+ @casestmt.evaluate(@scope)
+ end
- @opval2 = stub_everything 'opval2'
- @option2.stubs(:eachopt).yields(@opval2)
- end
+ it "should evaluate first matching option" do
+ @opval2.stubs(:evaluate_match).with { |*arg| arg[0] == "value" }.returns(true)
+ @option2.expects(:safeevaluate).with(@scope)
- it "should evaluate each sub-option" do
- @option1.expects(:eachopt)
- @option2.expects(:eachopt)
+ @casestmt.evaluate(@scope)
+ end
- @casestmt.evaluate(@scope)
- end
+ it "should return the first matching evaluated option" do
+ @opval2.stubs(:evaluate_match).with { |*arg| arg[0] == "value" }.returns(true)
+ @option2.stubs(:safeevaluate).with(@scope).returns(:result)
- it "should evaluate first matching option" do
- @opval2.stubs(:evaluate_match).with { |*arg| arg[0] == "value" }.returns(true)
- @option2.expects(:safeevaluate).with(@scope)
+ @casestmt.evaluate(@scope).should == :result
+ end
- @casestmt.evaluate(@scope)
- end
+ it "should evaluate the default option if none matched" do
+ @option1.stubs(:default?).returns(true)
+ @option1.expects(:safeevaluate).with(@scope)
- it "should return the first matching evaluated option" do
- @opval2.stubs(:evaluate_match).with { |*arg| arg[0] == "value" }.returns(true)
- @option2.stubs(:safeevaluate).with(@scope).returns(:result)
+ @casestmt.evaluate(@scope)
+ end
- @casestmt.evaluate(@scope).should == :result
- end
+ it "should return the default evaluated option if none matched" do
+ @option1.stubs(:default?).returns(true)
+ @option1.stubs(:safeevaluate).with(@scope).returns(:result)
- it "should evaluate the default option if none matched" do
- @option1.stubs(:default?).returns(true)
- @option1.expects(:safeevaluate).with(@scope)
+ @casestmt.evaluate(@scope).should == :result
+ end
- @casestmt.evaluate(@scope)
- end
+ it "should return nil if nothing matched" do
+ @casestmt.evaluate(@scope).should be_nil
+ end
- it "should return the default evaluated option if none matched" do
- @option1.stubs(:default?).returns(true)
- @option1.stubs(:safeevaluate).with(@scope).returns(:result)
+ it "should match and set scope ephemeral variables" do
+ @opval1.expects(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }
- @casestmt.evaluate(@scope).should == :result
- end
+ @casestmt.evaluate(@scope)
+ end
- it "should return nil if nothing matched" do
- @casestmt.evaluate(@scope).should be_nil
- end
+ it "should evaluate this regex option if it matches" do
+ @opval1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true)
- it "should match and set scope ephemeral variables" do
- @opval1.expects(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }
+ @option1.expects(:safeevaluate).with(@scope)
- @casestmt.evaluate(@scope)
- end
+ @casestmt.evaluate(@scope)
+ end
- it "should evaluate this regex option if it matches" do
- @opval1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true)
+ it "should return this evaluated regex option if it matches" do
+ @opval1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true)
+ @option1.stubs(:safeevaluate).with(@scope).returns(:result)
- @option1.expects(:safeevaluate).with(@scope)
+ @casestmt.evaluate(@scope).should == :result
+ end
- @casestmt.evaluate(@scope)
- end
+ it "should unset scope ephemeral variables after option evaluation" do
+ @scope.stubs(:ephemeral_level).returns(:level)
+ @opval1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true)
+ @option1.stubs(:safeevaluate).with(@scope).returns(:result)
- it "should return this evaluated regex option if it matches" do
- @opval1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true)
- @option1.stubs(:safeevaluate).with(@scope).returns(:result)
+ @scope.expects(:unset_ephemeral_var).with(:level)
- @casestmt.evaluate(@scope).should == :result
- end
+ @casestmt.evaluate(@scope)
+ end
- it "should unset scope ephemeral variables after option evaluation" do
- @scope.stubs(:ephemeral_level).returns(:level)
- @opval1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true)
- @option1.stubs(:safeevaluate).with(@scope).returns(:result)
+ it "should not leak ephemeral variables even if evaluation fails" do
+ @scope.stubs(:ephemeral_level).returns(:level)
+ @opval1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true)
+ @option1.stubs(:safeevaluate).with(@scope).raises
- @scope.expects(:unset_ephemeral_var).with(:level)
+ @scope.expects(:unset_ephemeral_var).with(:level)
- @casestmt.evaluate(@scope)
- end
+ lambda { @casestmt.evaluate(@scope) }.should raise_error
+ end
+ end
- it "should not leak ephemeral variables even if evaluation fails" do
- @scope.stubs(:ephemeral_level).returns(:level)
- @opval1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true)
- @option1.stubs(:safeevaluate).with(@scope).raises
+ end
- @scope.expects(:unset_ephemeral_var).with(:level)
+ it "should match if any of the provided options evaluate as true" do
+ ast = nil
+ AST = Puppet::Parser::AST
- lambda { @casestmt.evaluate(@scope) }.should raise_error
- end
- end
+ tests = {
+ "one" => %w{a b c},
+ "two" => %w{e f g}
+ }
+ options = tests.collect do |result, values|
+ values = values.collect { |v| AST::Leaf.new :value => v }
+ AST::CaseOpt.new(
+ :value => AST::ASTArray.new(:children => values),
+
+ :statements => AST::Leaf.new(:value => result))
end
+ options << AST::CaseOpt.new(:value => AST::Default.new(:value => "default"), :statements => AST::Leaf.new(:value => "default"))
- it "should match if any of the provided options evaluate as true" do
- ast = nil
- AST = Puppet::Parser::AST
+ ast = nil
+ param = AST::Variable.new(:value => "testparam")
+ ast = AST::CaseStatement.new(:test => param, :options => options)
- tests = {
- "one" => %w{a b c},
- "two" => %w{e f g}
- }
- options = tests.collect do |result, values|
- values = values.collect { |v| AST::Leaf.new :value => v }
+ tests.each do |should, values|
+ values.each do |value|
+ @scope = Puppet::Parser::Scope.new
+ @scope.setvar("testparam", value)
+ result = ast.evaluate(@scope)
- AST::CaseOpt.new(
- :value => AST::ASTArray.new(:children => values),
-
- :statements => AST::Leaf.new(:value => result))
- end
- options << AST::CaseOpt.new(:value => AST::Default.new(:value => "default"), :statements => AST::Leaf.new(:value => "default"))
-
- ast = nil
- param = AST::Variable.new(:value => "testparam")
- ast = AST::CaseStatement.new(:test => param, :options => options)
-
- tests.each do |should, values|
- values.each do |value|
- @scope = Puppet::Parser::Scope.new
- @scope.setvar("testparam", value)
- result = ast.evaluate(@scope)
-
- result.should == should
- end
- end
+ result.should == should
+ end
end
+ end
end
diff --git a/spec/unit/parser/ast/collection_spec.rb b/spec/unit/parser/ast/collection_spec.rb
index c141bd7..3f7878a 100755
--- a/spec/unit/parser/ast/collection_spec.rb
+++ b/spec/unit/parser/ast/collection_spec.rb
@@ -3,61 +3,61 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::Collection do
- before :each do
- @scope = stub_everything 'scope'
- @compiler = stub_everything 'compile'
- @scope.stubs(:compiler).returns(@compiler)
+ before :each do
+ @scope = stub_everything 'scope'
+ @compiler = stub_everything 'compile'
+ @scope.stubs(:compiler).returns(@compiler)
- @overrides = stub_everything 'overrides'
- @overrides.stubs(:is_a?).with(Puppet::Parser::AST).returns(true)
+ @overrides = stub_everything 'overrides'
+ @overrides.stubs(:is_a?).with(Puppet::Parser::AST).returns(true)
- end
+ end
- it "should evaluate its query" do
- query = mock 'query'
- collection = Puppet::Parser::AST::Collection.new :query => query, :form => :virtual
+ it "should evaluate its query" do
+ query = mock 'query'
+ collection = Puppet::Parser::AST::Collection.new :query => query, :form => :virtual
- query.expects(:safeevaluate).with(@scope)
+ query.expects(:safeevaluate).with(@scope)
- collection.evaluate(@scope)
- end
+ collection.evaluate(@scope)
+ end
- it "should instantiate a Collector for this type" do
- collection = Puppet::Parser::AST::Collection.new :form => :virtual, :type => "test"
+ it "should instantiate a Collector for this type" do
+ collection = Puppet::Parser::AST::Collection.new :form => :virtual, :type => "test"
- Puppet::Parser::Collector.expects(:new).with(@scope, "test", nil, nil, :virtual)
+ Puppet::Parser::Collector.expects(:new).with(@scope, "test", nil, nil, :virtual)
- collection.evaluate(@scope)
- end
+ collection.evaluate(@scope)
+ end
- it "should tell the compiler about this collector" do
- collection = Puppet::Parser::AST::Collection.new :form => :virtual, :type => "test"
- Puppet::Parser::Collector.stubs(:new).returns("whatever")
+ it "should tell the compiler about this collector" do
+ collection = Puppet::Parser::AST::Collection.new :form => :virtual, :type => "test"
+ Puppet::Parser::Collector.stubs(:new).returns("whatever")
- @compiler.expects(:add_collection).with("whatever")
+ @compiler.expects(:add_collection).with("whatever")
- collection.evaluate(@scope)
- end
+ collection.evaluate(@scope)
+ end
- it "should evaluate overriden paramaters" do
- collector = stub_everything 'collector'
- collection = Puppet::Parser::AST::Collection.new :form => :virtual, :type => "test", :override => @overrides
- Puppet::Parser::Collector.stubs(:new).returns(collector)
+ it "should evaluate overriden paramaters" do
+ collector = stub_everything 'collector'
+ collection = Puppet::Parser::AST::Collection.new :form => :virtual, :type => "test", :override => @overrides
+ Puppet::Parser::Collector.stubs(:new).returns(collector)
- @overrides.expects(:safeevaluate).with(@scope)
+ @overrides.expects(:safeevaluate).with(@scope)
- collection.evaluate(@scope)
- end
+ collection.evaluate(@scope)
+ end
- it "should tell the collector about overrides" do
- collector = mock 'collector'
- collection = Puppet::Parser::AST::Collection.new :form => :virtual, :type => "test", :override => @overrides
- Puppet::Parser::Collector.stubs(:new).returns(collector)
+ it "should tell the collector about overrides" do
+ collector = mock 'collector'
+ collection = Puppet::Parser::AST::Collection.new :form => :virtual, :type => "test", :override => @overrides
+ Puppet::Parser::Collector.stubs(:new).returns(collector)
- collector.expects(:add_override)
+ collector.expects(:add_override)
- collection.evaluate(@scope)
- end
+ collection.evaluate(@scope)
+ end
end
diff --git a/spec/unit/parser/ast/collexpr_spec.rb b/spec/unit/parser/ast/collexpr_spec.rb
index 2aefe2f..01276df 100755
--- a/spec/unit/parser/ast/collexpr_spec.rb
+++ b/spec/unit/parser/ast/collexpr_spec.rb
@@ -4,112 +4,112 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::CollExpr do
- ast = Puppet::Parser::AST
+ ast = Puppet::Parser::AST
+ before :each do
+ @scope = Puppet::Parser::Scope.new
+ end
+
+ describe "when evaluating with two operands" do
before :each do
- @scope = Puppet::Parser::Scope.new
+ @test1 = mock 'test1'
+ @test1.expects(:safeevaluate).with(@scope).returns("test1")
+ @test2 = mock 'test2'
+ @test2.expects(:safeevaluate).with(@scope).returns("test2")
+ end
+
+ it "should evaluate both" do
+ collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=>"==")
+ collexpr.evaluate(@scope)
end
- describe "when evaluating with two operands" do
- before :each do
- @test1 = mock 'test1'
- @test1.expects(:safeevaluate).with(@scope).returns("test1")
- @test2 = mock 'test2'
- @test2.expects(:safeevaluate).with(@scope).returns("test2")
- end
-
- it "should evaluate both" do
- collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=>"==")
- collexpr.evaluate(@scope)
- end
-
- it "should produce a textual representation and code of the expression" do
- collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=>"==")
- result = collexpr.evaluate(@scope)
- result[0].should == "param_values.value = 'test2' and param_names.name = 'test1'"
- result[1].should be_an_instance_of(Proc)
- end
-
- it "should propagate expression type and form to child if expression themselves" do
- [@test1, @test2].each do |t|
- t.expects(:is_a?).returns(true)
- t.expects(:form).returns(false)
- t.expects(:type).returns(false)
- t.expects(:type=)
- t.expects(:form=)
- end
-
- collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=>"==", :form => true, :type => true)
- result = collexpr.evaluate(@scope)
- end
-
- describe "and when evaluating the produced code" do
- before :each do
- @resource = mock 'resource'
- @resource.expects(:[]).with("test1").at_least(1).returns("test2")
- end
-
- it "should evaluate like the original expression for ==" do
- collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper => "==")
- collexpr.evaluate(@scope)[1].call(@resource).should === (@resource["test1"] == "test2")
- end
-
- it "should evaluate like the original expression for !=" do
- collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper => "!=")
- collexpr.evaluate(@scope)[1].call(@resource).should === (@resource["test1"] != "test2")
- end
- end
-
- it "should warn if this is an exported collection containing parenthesis (unsupported)" do
- collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=>"==", :parens => true, :form => :exported)
- Puppet.expects(:warning)
- collexpr.evaluate(@scope)
- end
-
- %w{and or}.each do |op|
- it "should raise an error if this is an exported collection with #{op} operator (unsupported)" do
- collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=> op, :form => :exported)
- lambda { collexpr.evaluate(@scope) }.should raise_error(Puppet::ParseError)
- end
- end
+ it "should produce a textual representation and code of the expression" do
+ collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=>"==")
+ result = collexpr.evaluate(@scope)
+ result[0].should == "param_values.value = 'test2' and param_names.name = 'test1'"
+ result[1].should be_an_instance_of(Proc)
end
- describe "when evaluating with tags" do
- before :each do
- @tag = stub 'tag', :safeevaluate => 'tag'
- @value = stub 'value', :safeevaluate => 'value'
-
- @resource = stub 'resource'
- @resource.stubs(:tagged?).with("value").returns(true)
- end
-
- it "should produce a textual representation of the expression" do
- collexpr = ast::CollExpr.new(:test1 => @tag, :test2 => @value, :oper=>"==")
- result = collexpr.evaluate(@scope)
- result[0].should == "puppet_tags.name = 'value'"
- end
-
- it "should inspect resource tags if the query term is on tags" do
- collexpr = ast::CollExpr.new(:test1 => @tag, :test2 => @value, :oper => "==")
- collexpr.evaluate(@scope)[1].call(@resource).should be_true
- end
+ it "should propagate expression type and form to child if expression themselves" do
+ [@test1, @test2].each do |t|
+ t.expects(:is_a?).returns(true)
+ t.expects(:form).returns(false)
+ t.expects(:type).returns(false)
+ t.expects(:type=)
+ t.expects(:form=)
+ end
+
+ collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=>"==", :form => true, :type => true)
+ result = collexpr.evaluate(@scope)
end
- [:exported,:virtual].each do |mode|
- it "should check for array member equality if resource parameter is an array for == in mode #{mode}" do
- array = mock 'array', :safeevaluate => "array"
- test1 = mock 'test1'
- test1.expects(:safeevaluate).with(@scope).returns("test1")
+ describe "and when evaluating the produced code" do
+ before :each do
+ @resource = mock 'resource'
+ @resource.expects(:[]).with("test1").at_least(1).returns("test2")
+ end
+
+ it "should evaluate like the original expression for ==" do
+ collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper => "==")
+ collexpr.evaluate(@scope)[1].call(@resource).should === (@resource["test1"] == "test2")
+ end
+
+ it "should evaluate like the original expression for !=" do
+ collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper => "!=")
+ collexpr.evaluate(@scope)[1].call(@resource).should === (@resource["test1"] != "test2")
+ end
+ end
+
+ it "should warn if this is an exported collection containing parenthesis (unsupported)" do
+ collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=>"==", :parens => true, :form => :exported)
+ Puppet.expects(:warning)
+ collexpr.evaluate(@scope)
+ end
- resource = mock 'resource'
- resource.expects(:[]).with("array").at_least(1).returns(["test1","test2","test3"])
- collexpr = ast::CollExpr.new(:test1 => array, :test2 => test1, :oper => "==", :form => mode)
- collexpr.evaluate(@scope)[1].call(resource).should be_true
+ %w{and or}.each do |op|
+ it "should raise an error if this is an exported collection with #{op} operator (unsupported)" do
+ collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=> op, :form => :exported)
+ lambda { collexpr.evaluate(@scope) }.should raise_error(Puppet::ParseError)
+ end
end
+ end
+
+ describe "when evaluating with tags" do
+ before :each do
+ @tag = stub 'tag', :safeevaluate => 'tag'
+ @value = stub 'value', :safeevaluate => 'value'
+
+ @resource = stub 'resource'
+ @resource.stubs(:tagged?).with("value").returns(true)
+ end
+
+ it "should produce a textual representation of the expression" do
+ collexpr = ast::CollExpr.new(:test1 => @tag, :test2 => @value, :oper=>"==")
+ result = collexpr.evaluate(@scope)
+ result[0].should == "puppet_tags.name = 'value'"
end
- it "should raise an error for invalid operator" do
- lambda { collexpr = ast::CollExpr.new(:oper=>">") }.should raise_error
+ it "should inspect resource tags if the query term is on tags" do
+ collexpr = ast::CollExpr.new(:test1 => @tag, :test2 => @value, :oper => "==")
+ collexpr.evaluate(@scope)[1].call(@resource).should be_true
end
+ end
+
+ [:exported,:virtual].each do |mode|
+ it "should check for array member equality if resource parameter is an array for == in mode #{mode}" do
+ array = mock 'array', :safeevaluate => "array"
+ test1 = mock 'test1'
+ test1.expects(:safeevaluate).with(@scope).returns("test1")
+
+ resource = mock 'resource'
+ resource.expects(:[]).with("array").at_least(1).returns(["test1","test2","test3"])
+ collexpr = ast::CollExpr.new(:test1 => array, :test2 => test1, :oper => "==", :form => mode)
+ collexpr.evaluate(@scope)[1].call(resource).should be_true
+ end
+ end
+
+ it "should raise an error for invalid operator" do
+ lambda { collexpr = ast::CollExpr.new(:oper=>">") }.should raise_error
+ end
end
diff --git a/spec/unit/parser/ast/comparison_operator_spec.rb b/spec/unit/parser/ast/comparison_operator_spec.rb
index 0ef9117..724b6c6 100755
--- a/spec/unit/parser/ast/comparison_operator_spec.rb
+++ b/spec/unit/parser/ast/comparison_operator_spec.rb
@@ -3,90 +3,90 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::ComparisonOperator do
- before :each do
- @scope = Puppet::Parser::Scope.new
- @one = stub 'one', :safeevaluate => "1"
- @two = stub 'two', :safeevaluate => "2"
+ before :each do
+ @scope = Puppet::Parser::Scope.new
+ @one = stub 'one', :safeevaluate => "1"
+ @two = stub 'two', :safeevaluate => "2"
+ end
+
+ it "should evaluate both branches" do
+ lval = stub "lval"
+ lval.expects(:safeevaluate).with(@scope)
+ rval = stub "rval"
+ rval.expects(:safeevaluate).with(@scope)
+
+ operator = Puppet::Parser::AST::ComparisonOperator.new :lval => lval, :operator => "==", :rval => rval
+ operator.evaluate(@scope)
+ end
+
+ it "should convert arguments strings to numbers if they are" do
+ Puppet::Parser::Scope.expects(:number?).with("1").returns(1)
+ Puppet::Parser::Scope.expects(:number?).with("2").returns(2)
+
+ operator = Puppet::Parser::AST::ComparisonOperator.new :lval => @one, :operator => "==", :rval => @two
+ operator.evaluate(@scope)
+ end
+
+ %w{< > <= >= ==}.each do |oper|
+ it "should use string comparison #{oper} if operands are strings" do
+ lval = stub 'one', :safeevaluate => "one"
+ rval = stub 'two', :safeevaluate => "two"
+ Puppet::Parser::Scope.stubs(:number?).with("one").returns(nil)
+ Puppet::Parser::Scope.stubs(:number?).with("two").returns(nil)
+
+ operator = Puppet::Parser::AST::ComparisonOperator.new :lval => lval, :operator => oper, :rval => rval
+ operator.evaluate(@scope).should == "one".send(oper,"two")
end
+ end
- it "should evaluate both branches" do
- lval = stub "lval"
- lval.expects(:safeevaluate).with(@scope)
- rval = stub "rval"
- rval.expects(:safeevaluate).with(@scope)
+ it "should fail with arguments of different types" do
+ lval = stub 'one', :safeevaluate => "one"
+ rval = stub 'two', :safeevaluate => "2"
+ Puppet::Parser::Scope.stubs(:number?).with("one").returns(nil)
+ Puppet::Parser::Scope.stubs(:number?).with("2").returns(2)
- operator = Puppet::Parser::AST::ComparisonOperator.new :lval => lval, :operator => "==", :rval => rval
- operator.evaluate(@scope)
- end
-
- it "should convert arguments strings to numbers if they are" do
- Puppet::Parser::Scope.expects(:number?).with("1").returns(1)
- Puppet::Parser::Scope.expects(:number?).with("2").returns(2)
+ operator = Puppet::Parser::AST::ComparisonOperator.new :lval => lval, :operator => ">", :rval => rval
+ lambda { operator.evaluate(@scope) }.should raise_error(ArgumentError)
+ end
- operator = Puppet::Parser::AST::ComparisonOperator.new :lval => @one, :operator => "==", :rval => @two
- operator.evaluate(@scope)
- end
+ it "should fail for an unknown operator" do
+ lambda { operator = Puppet::Parser::AST::ComparisonOperator.new :lval => @one, :operator => "or", :rval => @two }.should raise_error
+ end
- %w{< > <= >= ==}.each do |oper|
- it "should use string comparison #{oper} if operands are strings" do
- lval = stub 'one', :safeevaluate => "one"
- rval = stub 'two', :safeevaluate => "two"
- Puppet::Parser::Scope.stubs(:number?).with("one").returns(nil)
- Puppet::Parser::Scope.stubs(:number?).with("two").returns(nil)
+ %w{< > <= >= ==}.each do |oper|
+ it "should return the result of using '#{oper}' to compare the left and right sides" do
+ operator = Puppet::Parser::AST::ComparisonOperator.new :lval => @one, :operator => oper, :rval => @two
- operator = Puppet::Parser::AST::ComparisonOperator.new :lval => lval, :operator => oper, :rval => rval
- operator.evaluate(@scope).should == "one".send(oper,"two")
- end
+ operator.evaluate(@scope).should == 1.send(oper,2)
end
+ end
- it "should fail with arguments of different types" do
- lval = stub 'one', :safeevaluate => "one"
- rval = stub 'two', :safeevaluate => "2"
- Puppet::Parser::Scope.stubs(:number?).with("one").returns(nil)
- Puppet::Parser::Scope.stubs(:number?).with("2").returns(2)
+ it "should return the result of using '!=' to compare the left and right sides" do
+ operator = Puppet::Parser::AST::ComparisonOperator.new :lval => @one, :operator => '!=', :rval => @two
- operator = Puppet::Parser::AST::ComparisonOperator.new :lval => lval, :operator => ">", :rval => rval
- lambda { operator.evaluate(@scope) }.should raise_error(ArgumentError)
- end
+ operator.evaluate(@scope).should == true
+ end
- it "should fail for an unknown operator" do
- lambda { operator = Puppet::Parser::AST::ComparisonOperator.new :lval => @one, :operator => "or", :rval => @two }.should raise_error
- end
-
- %w{< > <= >= ==}.each do |oper|
- it "should return the result of using '#{oper}' to compare the left and right sides" do
- operator = Puppet::Parser::AST::ComparisonOperator.new :lval => @one, :operator => oper, :rval => @two
+ it "should work for variables too" do
+ one = Puppet::Parser::AST::Variable.new( :value => "one" )
+ two = Puppet::Parser::AST::Variable.new( :value => "two" )
- operator.evaluate(@scope).should == 1.send(oper,2)
- end
- end
+ @scope.expects(:lookupvar).with("one", false).returns(1)
+ @scope.expects(:lookupvar).with("two", false).returns(2)
- it "should return the result of using '!=' to compare the left and right sides" do
- operator = Puppet::Parser::AST::ComparisonOperator.new :lval => @one, :operator => '!=', :rval => @two
-
- operator.evaluate(@scope).should == true
- end
-
- it "should work for variables too" do
- one = Puppet::Parser::AST::Variable.new( :value => "one" )
- two = Puppet::Parser::AST::Variable.new( :value => "two" )
-
- @scope.expects(:lookupvar).with("one", false).returns(1)
- @scope.expects(:lookupvar).with("two", false).returns(2)
-
- operator = Puppet::Parser::AST::ComparisonOperator.new :lval => one, :operator => "<", :rval => two
- operator.evaluate(@scope).should == true
- end
+ operator = Puppet::Parser::AST::ComparisonOperator.new :lval => one, :operator => "<", :rval => two
+ operator.evaluate(@scope).should == true
+ end
- # see ticket #1759
- %w{< > <= >=}.each do |oper|
- it "should return the correct result of using '#{oper}' to compare 10 and 9" do
- ten = stub 'one', :safeevaluate => "10"
- nine = stub 'two', :safeevaluate => "9"
- operator = Puppet::Parser::AST::ComparisonOperator.new :lval => ten, :operator => oper, :rval => nine
+ # see ticket #1759
+ %w{< > <= >=}.each do |oper|
+ it "should return the correct result of using '#{oper}' to compare 10 and 9" do
+ ten = stub 'one', :safeevaluate => "10"
+ nine = stub 'two', :safeevaluate => "9"
+ operator = Puppet::Parser::AST::ComparisonOperator.new :lval => ten, :operator => oper, :rval => nine
- operator.evaluate(@scope).should == 10.send(oper,9)
- end
+ operator.evaluate(@scope).should == 10.send(oper,9)
end
+ end
end
diff --git a/spec/unit/parser/ast/function_spec.rb b/spec/unit/parser/ast/function_spec.rb
index bb687ea..c57c7f0 100644
--- a/spec/unit/parser/ast/function_spec.rb
+++ b/spec/unit/parser/ast/function_spec.rb
@@ -3,81 +3,81 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::Function do
- before :each do
- @scope = mock 'scope'
- end
+ before :each do
+ @scope = mock 'scope'
+ end
- describe "when initializing" do
- it "should not fail if the function doesn't exist" do
- Puppet::Parser::Functions.stubs(:function).returns(false)
+ describe "when initializing" do
+ it "should not fail if the function doesn't exist" do
+ Puppet::Parser::Functions.stubs(:function).returns(false)
- lambda{ Puppet::Parser::AST::Function.new :name => "dontexist" }.should_not raise_error(Puppet::ParseError)
+ lambda{ Puppet::Parser::AST::Function.new :name => "dontexist" }.should_not raise_error(Puppet::ParseError)
- end
end
+ end
- it "should return its representation with to_s" do
- args = stub 'args', :is_a? => true, :to_s => "[a, b]"
-
- Puppet::Parser::AST::Function.new(:name => "func", :arguments => args).to_s.should == "func(a, b)"
- end
+ it "should return its representation with to_s" do
+ args = stub 'args', :is_a? => true, :to_s => "[a, b]"
- describe "when evaluating" do
+ Puppet::Parser::AST::Function.new(:name => "func", :arguments => args).to_s.should == "func(a, b)"
+ end
- it "should fail if the function doesn't exist" do
- Puppet::Parser::Functions.stubs(:function).returns(false)
- func = Puppet::Parser::AST::Function.new :name => "dontexist"
+ describe "when evaluating" do
- lambda{ func.evaluate(@scope) }.should raise_error(Puppet::ParseError)
- end
+ it "should fail if the function doesn't exist" do
+ Puppet::Parser::Functions.stubs(:function).returns(false)
+ func = Puppet::Parser::AST::Function.new :name => "dontexist"
- it "should fail if the function is a statement used as rvalue" do
- Puppet::Parser::Functions.stubs(:function).with("exist").returns(true)
- Puppet::Parser::Functions.stubs(:rvalue?).with("exist").returns(false)
+ lambda{ func.evaluate(@scope) }.should raise_error(Puppet::ParseError)
+ end
- func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :rvalue
+ it "should fail if the function is a statement used as rvalue" do
+ Puppet::Parser::Functions.stubs(:function).with("exist").returns(true)
+ Puppet::Parser::Functions.stubs(:rvalue?).with("exist").returns(false)
- lambda{ func.evaluate(@scope) }.should raise_error(Puppet::ParseError, "Function 'exist' does not return a value")
- end
+ func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :rvalue
- it "should fail if the function is an rvalue used as statement" do
- Puppet::Parser::Functions.stubs(:function).with("exist").returns(true)
- Puppet::Parser::Functions.stubs(:rvalue?).with("exist").returns(true)
+ lambda{ func.evaluate(@scope) }.should raise_error(Puppet::ParseError, "Function 'exist' does not return a value")
+ end
- func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :statement
+ it "should fail if the function is an rvalue used as statement" do
+ Puppet::Parser::Functions.stubs(:function).with("exist").returns(true)
+ Puppet::Parser::Functions.stubs(:rvalue?).with("exist").returns(true)
- lambda{ func.evaluate(@scope) }.should raise_error(Puppet::ParseError,"Function 'exist' must be the value of a statement")
- end
+ func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :statement
- it "should evaluate its arguments" do
- argument = stub 'arg'
- Puppet::Parser::Functions.stubs(:function).with("exist").returns(true)
- func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :statement, :arguments => argument
- @scope.stubs(:function_exist)
+ lambda{ func.evaluate(@scope) }.should raise_error(Puppet::ParseError,"Function 'exist' must be the value of a statement")
+ end
- argument.expects(:safeevaluate).with(@scope).returns("argument")
+ it "should evaluate its arguments" do
+ argument = stub 'arg'
+ Puppet::Parser::Functions.stubs(:function).with("exist").returns(true)
+ func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :statement, :arguments => argument
+ @scope.stubs(:function_exist)
- func.evaluate(@scope)
- end
+ argument.expects(:safeevaluate).with(@scope).returns("argument")
- it "should call the underlying ruby function" do
- argument = stub 'arg', :safeevaluate => "nothing"
- Puppet::Parser::Functions.stubs(:function).with("exist").returns(true)
- func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :statement, :arguments => argument
+ func.evaluate(@scope)
+ end
- @scope.expects(:function_exist).with("nothing")
+ it "should call the underlying ruby function" do
+ argument = stub 'arg', :safeevaluate => "nothing"
+ Puppet::Parser::Functions.stubs(:function).with("exist").returns(true)
+ func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :statement, :arguments => argument
- func.evaluate(@scope)
- end
+ @scope.expects(:function_exist).with("nothing")
- it "should return the ruby function return for rvalue functions" do
- argument = stub 'arg', :safeevaluate => "nothing"
- Puppet::Parser::Functions.stubs(:function).with("exist").returns(true)
- func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :statement, :arguments => argument
- @scope.stubs(:function_exist).with("nothing").returns("returning")
+ func.evaluate(@scope)
+ end
- func.evaluate(@scope).should == "returning"
- end
+ it "should return the ruby function return for rvalue functions" do
+ argument = stub 'arg', :safeevaluate => "nothing"
+ Puppet::Parser::Functions.stubs(:function).with("exist").returns(true)
+ func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :statement, :arguments => argument
+ @scope.stubs(:function_exist).with("nothing").returns("returning")
+ func.evaluate(@scope).should == "returning"
end
+
+ end
end
diff --git a/spec/unit/parser/ast/ifstatement_spec.rb b/spec/unit/parser/ast/ifstatement_spec.rb
index c1f3305..2a9e1e3 100755
--- a/spec/unit/parser/ast/ifstatement_spec.rb
+++ b/spec/unit/parser/ast/ifstatement_spec.rb
@@ -3,74 +3,74 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::IfStatement do
- before :each do
- @scope = Puppet::Parser::Scope.new
- end
+ before :each do
+ @scope = Puppet::Parser::Scope.new
+ end
- describe "when evaluating" do
+ describe "when evaluating" do
- before :each do
- @test = stub 'test'
- @test.stubs(:safeevaluate).with(@scope)
+ before :each do
+ @test = stub 'test'
+ @test.stubs(:safeevaluate).with(@scope)
- @stmt = stub 'stmt'
- @stmt.stubs(:safeevaluate).with(@scope)
+ @stmt = stub 'stmt'
+ @stmt.stubs(:safeevaluate).with(@scope)
- @else = stub 'else'
- @else.stubs(:safeevaluate).with(@scope)
+ @else = stub 'else'
+ @else.stubs(:safeevaluate).with(@scope)
- @ifstmt = Puppet::Parser::AST::IfStatement.new :test => @test, :statements => @stmt
- @ifelsestmt = Puppet::Parser::AST::IfStatement.new :test => @test, :statements => @stmt, :else => @else
- end
+ @ifstmt = Puppet::Parser::AST::IfStatement.new :test => @test, :statements => @stmt
+ @ifelsestmt = Puppet::Parser::AST::IfStatement.new :test => @test, :statements => @stmt, :else => @else
+ end
- it "should evaluate test" do
- Puppet::Parser::Scope.stubs(:true?).returns(false)
+ it "should evaluate test" do
+ Puppet::Parser::Scope.stubs(:true?).returns(false)
- @test.expects(:safeevaluate).with(@scope)
+ @test.expects(:safeevaluate).with(@scope)
- @ifstmt.evaluate(@scope)
- end
+ @ifstmt.evaluate(@scope)
+ end
- it "should evaluate if statements if test is true" do
- Puppet::Parser::Scope.stubs(:true?).returns(true)
+ it "should evaluate if statements if test is true" do
+ Puppet::Parser::Scope.stubs(:true?).returns(true)
- @stmt.expects(:safeevaluate).with(@scope)
+ @stmt.expects(:safeevaluate).with(@scope)
- @ifstmt.evaluate(@scope)
- end
+ @ifstmt.evaluate(@scope)
+ end
- it "should not evaluate if statements if test is false" do
- Puppet::Parser::Scope.stubs(:true?).returns(false)
+ it "should not evaluate if statements if test is false" do
+ Puppet::Parser::Scope.stubs(:true?).returns(false)
- @stmt.expects(:safeevaluate).with(@scope).never
+ @stmt.expects(:safeevaluate).with(@scope).never
- @ifstmt.evaluate(@scope)
- end
+ @ifstmt.evaluate(@scope)
+ end
- it "should evaluate the else branch if test is false" do
- Puppet::Parser::Scope.stubs(:true?).returns(false)
+ it "should evaluate the else branch if test is false" do
+ Puppet::Parser::Scope.stubs(:true?).returns(false)
- @else.expects(:safeevaluate).with(@scope)
+ @else.expects(:safeevaluate).with(@scope)
- @ifelsestmt.evaluate(@scope)
- end
+ @ifelsestmt.evaluate(@scope)
+ end
- it "should not evaluate the else branch if test is true" do
- Puppet::Parser::Scope.stubs(:true?).returns(true)
+ it "should not evaluate the else branch if test is true" do
+ Puppet::Parser::Scope.stubs(:true?).returns(true)
- @else.expects(:safeevaluate).with(@scope).never
+ @else.expects(:safeevaluate).with(@scope).never
- @ifelsestmt.evaluate(@scope)
- end
+ @ifelsestmt.evaluate(@scope)
+ end
- it "should reset ephemeral statements after evaluation" do
- @scope.expects(:ephemeral_level).returns(:level)
- Puppet::Parser::Scope.stubs(:true?).returns(true)
+ it "should reset ephemeral statements after evaluation" do
+ @scope.expects(:ephemeral_level).returns(:level)
+ Puppet::Parser::Scope.stubs(:true?).returns(true)
- @stmt.expects(:safeevaluate).with(@scope)
- @scope.expects(:unset_ephemeral_var).with(:level)
+ @stmt.expects(:safeevaluate).with(@scope)
+ @scope.expects(:unset_ephemeral_var).with(:level)
- @ifstmt.evaluate(@scope)
- end
+ @ifstmt.evaluate(@scope)
end
+ end
end
diff --git a/spec/unit/parser/ast/in_operator_spec.rb b/spec/unit/parser/ast/in_operator_spec.rb
index 15128d8..aebe442 100644
--- a/spec/unit/parser/ast/in_operator_spec.rb
+++ b/spec/unit/parser/ast/in_operator_spec.rb
@@ -5,56 +5,56 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/parser/ast/in_operator'
describe Puppet::Parser::AST::InOperator do
- before :each do
- @scope = Puppet::Parser::Scope.new
+ before :each do
+ @scope = Puppet::Parser::Scope.new
- @lval = stub 'lval'
- @lval.stubs(:safeevaluate).with(@scope).returns("left")
+ @lval = stub 'lval'
+ @lval.stubs(:safeevaluate).with(@scope).returns("left")
- @rval = stub 'rval'
- @rval.stubs(:safeevaluate).with(@scope).returns("right")
+ @rval = stub 'rval'
+ @rval.stubs(:safeevaluate).with(@scope).returns("right")
- @operator = Puppet::Parser::AST::InOperator.new :lval => @lval, :rval => @rval
- end
+ @operator = Puppet::Parser::AST::InOperator.new :lval => @lval, :rval => @rval
+ end
- it "should evaluate the left operand" do
- @lval.expects(:safeevaluate).with(@scope).returns("string")
+ it "should evaluate the left operand" do
+ @lval.expects(:safeevaluate).with(@scope).returns("string")
- @operator.evaluate(@scope)
- end
+ @operator.evaluate(@scope)
+ end
- it "should evaluate the right operand" do
- @rval.expects(:safeevaluate).with(@scope).returns("string")
+ it "should evaluate the right operand" do
+ @rval.expects(:safeevaluate).with(@scope).returns("string")
- @operator.evaluate(@scope)
- end
+ @operator.evaluate(@scope)
+ end
- it "should raise an argument error if lval is not a string" do
- @lval.expects(:safeevaluate).with(@scope).returns([12,13])
+ it "should raise an argument error if lval is not a string" do
+ @lval.expects(:safeevaluate).with(@scope).returns([12,13])
- lambda { @operator.evaluate(@scope) }.should raise_error
- end
+ lambda { @operator.evaluate(@scope) }.should raise_error
+ end
- it "should raise an argument error if rval doesn't support the include? method" do
- @rval.expects(:safeevaluate).with(@scope).returns(stub('value'))
+ it "should raise an argument error if rval doesn't support the include? method" do
+ @rval.expects(:safeevaluate).with(@scope).returns(stub('value'))
- lambda { @operator.evaluate(@scope) }.should raise_error
- end
+ lambda { @operator.evaluate(@scope) }.should raise_error
+ end
- it "should not raise an argument error if rval supports the include? method" do
- @rval.expects(:safeevaluate).with(@scope).returns(stub('value', :include? => true))
+ it "should not raise an argument error if rval supports the include? method" do
+ @rval.expects(:safeevaluate).with(@scope).returns(stub('value', :include? => true))
- lambda { @operator.evaluate(@scope) }.should_not raise_error
- end
+ lambda { @operator.evaluate(@scope) }.should_not raise_error
+ end
- it "should return rval.include?(lval)" do
- lval = stub 'lvalue', :is_a? => true
- @lval.stubs(:safeevaluate).with(@scope).returns(lval)
+ it "should return rval.include?(lval)" do
+ lval = stub 'lvalue', :is_a? => true
+ @lval.stubs(:safeevaluate).with(@scope).returns(lval)
- rval = stub 'rvalue'
- @rval.stubs(:safeevaluate).with(@scope).returns(rval)
- rval.expects(:include?).with(lval).returns(:result)
+ rval = stub 'rvalue'
+ @rval.stubs(:safeevaluate).with(@scope).returns(rval)
+ rval.expects(:include?).with(lval).returns(:result)
- @operator.evaluate(@scope).should == :result
- end
+ @operator.evaluate(@scope).should == :result
+ end
end
diff --git a/spec/unit/parser/ast/leaf_spec.rb b/spec/unit/parser/ast/leaf_spec.rb
index d5534de..379cbfd 100755
--- a/spec/unit/parser/ast/leaf_spec.rb
+++ b/spec/unit/parser/ast/leaf_spec.rb
@@ -3,365 +3,365 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::Leaf do
- before :each do
- @scope = stub 'scope'
- @value = stub 'value'
- @leaf = Puppet::Parser::AST::Leaf.new(:value => @value)
- end
+ before :each do
+ @scope = stub 'scope'
+ @value = stub 'value'
+ @leaf = Puppet::Parser::AST::Leaf.new(:value => @value)
+ end
- it "should have a evaluate_match method" do
- Puppet::Parser::AST::Leaf.new(:value => "value").should respond_to(:evaluate_match)
- end
+ it "should have a evaluate_match method" do
+ Puppet::Parser::AST::Leaf.new(:value => "value").should respond_to(:evaluate_match)
+ end
- describe "when evaluate_match is called" do
- it "should evaluate itself" do
- @leaf.expects(:safeevaluate).with(@scope)
+ describe "when evaluate_match is called" do
+ it "should evaluate itself" do
+ @leaf.expects(:safeevaluate).with(@scope)
- @leaf.evaluate_match("value", @scope)
- end
+ @leaf.evaluate_match("value", @scope)
+ end
- it "should match values by equality" do
- @value.stubs(:==).returns(false)
- @leaf.stubs(:safeevaluate).with(@scope).returns(@value)
- @value.expects(:==).with("value")
+ it "should match values by equality" do
+ @value.stubs(:==).returns(false)
+ @leaf.stubs(:safeevaluate).with(@scope).returns(@value)
+ @value.expects(:==).with("value")
- @leaf.evaluate_match("value", @scope)
- end
+ @leaf.evaluate_match("value", @scope)
+ end
- it "should downcase the evaluated value if wanted" do
- @leaf.stubs(:safeevaluate).with(@scope).returns(@value)
- @value.expects(:downcase).returns("value")
+ it "should downcase the evaluated value if wanted" do
+ @leaf.stubs(:safeevaluate).with(@scope).returns(@value)
+ @value.expects(:downcase).returns("value")
- @leaf.evaluate_match("value", @scope)
- end
+ @leaf.evaluate_match("value", @scope)
+ end
- it "should match undef if value is an empty string" do
- @leaf.stubs(:safeevaluate).with(@scope).returns("")
+ it "should match undef if value is an empty string" do
+ @leaf.stubs(:safeevaluate).with(@scope).returns("")
- @leaf.evaluate_match(:undef, @scope).should be_true
- end
+ @leaf.evaluate_match(:undef, @scope).should be_true
+ end
- it "should downcase the parameter value if wanted" do
- parameter = stub 'parameter'
- parameter.expects(:downcase).returns("value")
+ it "should downcase the parameter value if wanted" do
+ parameter = stub 'parameter'
+ parameter.expects(:downcase).returns("value")
- @leaf.evaluate_match(parameter, @scope)
- end
+ @leaf.evaluate_match(parameter, @scope)
end
+ end
- describe "when converting to string" do
- it "should transform its value to string" do
- value = stub 'value', :is_a? => true
- value.expects(:to_s)
- Puppet::Parser::AST::Leaf.new( :value => value ).to_s
- end
+ describe "when converting to string" do
+ it "should transform its value to string" do
+ value = stub 'value', :is_a? => true
+ value.expects(:to_s)
+ Puppet::Parser::AST::Leaf.new( :value => value ).to_s
end
+ end
- it "should have a match method" do
- @leaf.should respond_to(:match)
- end
+ it "should have a match method" do
+ @leaf.should respond_to(:match)
+ end
- it "should delegate match to ==" do
- @value.expects(:==).with("value")
+ it "should delegate match to ==" do
+ @value.expects(:==).with("value")
- @leaf.match("value")
- end
+ @leaf.match("value")
+ end
end
describe Puppet::Parser::AST::FlatString do
- describe "when converting to string" do
- it "should transform its value to a quoted string" do
- value = stub 'value', :is_a? => true, :to_s => "ab"
- Puppet::Parser::AST::FlatString.new( :value => value ).to_s.should == "\"ab\""
- end
+ describe "when converting to string" do
+ it "should transform its value to a quoted string" do
+ value = stub 'value', :is_a? => true, :to_s => "ab"
+ Puppet::Parser::AST::FlatString.new( :value => value ).to_s.should == "\"ab\""
end
+ end
end
describe Puppet::Parser::AST::String do
- describe "when converting to string" do
- it "should transform its value to a quoted string" do
- value = stub 'value', :is_a? => true, :to_s => "ab"
- Puppet::Parser::AST::String.new( :value => value ).to_s.should == "\"ab\""
- end
+ describe "when converting to string" do
+ it "should transform its value to a quoted string" do
+ value = stub 'value', :is_a? => true, :to_s => "ab"
+ Puppet::Parser::AST::String.new( :value => value ).to_s.should == "\"ab\""
end
+ end
end
describe Puppet::Parser::AST::Undef do
- before :each do
- @scope = stub 'scope'
- @undef = Puppet::Parser::AST::Undef.new(:value => :undef)
- end
-
- it "should match undef with undef" do
- @undef.evaluate_match(:undef, @scope).should be_true
- end
-
- it "should not match undef with an empty string" do
- @undef.evaluate_match("", @scope).should be_false
- end
+ before :each do
+ @scope = stub 'scope'
+ @undef = Puppet::Parser::AST::Undef.new(:value => :undef)
+ end
+
+ it "should match undef with undef" do
+ @undef.evaluate_match(:undef, @scope).should be_true
+ end
+
+ it "should not match undef with an empty string" do
+ @undef.evaluate_match("", @scope).should be_false
+ end
end
describe Puppet::Parser::AST::HashOrArrayAccess do
- before :each do
- @scope = stub 'scope'
- end
+ before :each do
+ @scope = stub 'scope'
+ end
- describe "when evaluating" do
- it "should evaluate the variable part if necessary" do
- @scope.stubs(:lookupvar).with("a").returns(["b"])
+ describe "when evaluating" do
+ it "should evaluate the variable part if necessary" do
+ @scope.stubs(:lookupvar).with("a").returns(["b"])
- variable = stub 'variable', :evaluate => "a"
- access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => variable, :key => 0 )
+ variable = stub 'variable', :evaluate => "a"
+ access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => variable, :key => 0 )
- variable.expects(:safeevaluate).with(@scope).returns("a")
+ variable.expects(:safeevaluate).with(@scope).returns("a")
- access.evaluate(@scope).should == "b"
- end
+ access.evaluate(@scope).should == "b"
+ end
- it "should evaluate the access key part if necessary" do
- @scope.stubs(:lookupvar).with("a").returns(["b"])
+ it "should evaluate the access key part if necessary" do
+ @scope.stubs(:lookupvar).with("a").returns(["b"])
- index = stub 'index', :evaluate => 0
- access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => index )
+ index = stub 'index', :evaluate => 0
+ access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => index )
- index.expects(:safeevaluate).with(@scope).returns(0)
+ index.expects(:safeevaluate).with(@scope).returns(0)
- access.evaluate(@scope).should == "b"
- end
+ access.evaluate(@scope).should == "b"
+ end
- it "should be able to return an array member" do
- @scope.stubs(:lookupvar).with("a").returns(["val1", "val2", "val3"])
+ it "should be able to return an array member" do
+ @scope.stubs(:lookupvar).with("a").returns(["val1", "val2", "val3"])
- access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => 1 )
+ access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => 1 )
- access.evaluate(@scope).should == "val2"
- end
+ access.evaluate(@scope).should == "val2"
+ end
- it "should be able to return an hash value" do
- @scope.stubs(:lookupvar).with("a").returns({ "key1" => "val1", "key2" => "val2", "key3" => "val3" })
+ it "should be able to return an hash value" do
+ @scope.stubs(:lookupvar).with("a").returns({ "key1" => "val1", "key2" => "val2", "key3" => "val3" })
- access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key2" )
+ access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key2" )
- access.evaluate(@scope).should == "val2"
- end
+ access.evaluate(@scope).should == "val2"
+ end
- it "should raise an error if the variable lookup didn't return an hash or an array" do
- @scope.stubs(:lookupvar).with("a").returns("I'm a string")
+ it "should raise an error if the variable lookup didn't return an hash or an array" do
+ @scope.stubs(:lookupvar).with("a").returns("I'm a string")
- access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key2" )
+ access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key2" )
- lambda { access.evaluate(@scope) }.should raise_error
- end
+ lambda { access.evaluate(@scope) }.should raise_error
+ end
- it "should raise an error if the variable wasn't in the scope" do
- @scope.stubs(:lookupvar).with("a").returns(nil)
+ it "should raise an error if the variable wasn't in the scope" do
+ @scope.stubs(:lookupvar).with("a").returns(nil)
- access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key2" )
+ access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key2" )
- lambda { access.evaluate(@scope) }.should raise_error
- end
+ lambda { access.evaluate(@scope) }.should raise_error
+ end
- it "should return a correct string representation" do
- access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key2" )
- access.to_s.should == '$a[key2]'
- end
+ it "should return a correct string representation" do
+ access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key2" )
+ access.to_s.should == '$a[key2]'
+ end
- it "should work with recursive hash access" do
- @scope.stubs(:lookupvar).with("a").returns({ "key" => { "subkey" => "b" }})
+ it "should work with recursive hash access" do
+ @scope.stubs(:lookupvar).with("a").returns({ "key" => { "subkey" => "b" }})
- access1 = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key")
- access2 = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => access1, :key => "subkey")
+ access1 = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key")
+ access2 = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => access1, :key => "subkey")
- access2.evaluate(@scope).should == 'b'
- end
+ access2.evaluate(@scope).should == 'b'
+ end
- it "should work with interleaved array and hash access" do
- @scope.stubs(:lookupvar).with("a").returns({ "key" => [ "a" , "b" ]})
+ it "should work with interleaved array and hash access" do
+ @scope.stubs(:lookupvar).with("a").returns({ "key" => [ "a" , "b" ]})
- access1 = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key")
- access2 = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => access1, :key => 1)
+ access1 = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key")
+ access2 = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => access1, :key => 1)
- access2.evaluate(@scope).should == 'b'
- end
+ access2.evaluate(@scope).should == 'b'
end
+ end
- describe "when assigning" do
- it "should add a new key and value" do
- scope = Puppet::Parser::Scope.new
- scope.setvar("a", { 'a' => 'b' })
+ describe "when assigning" do
+ it "should add a new key and value" do
+ scope = Puppet::Parser::Scope.new
+ scope.setvar("a", { 'a' => 'b' })
- access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "b")
- access.assign(scope, "c" )
+ access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "b")
+ access.assign(scope, "c" )
- scope.lookupvar("a").should be_include("b")
- end
+ scope.lookupvar("a").should be_include("b")
+ end
- it "should raise an error when trying to overwrite an hash value" do
- @scope.stubs(:lookupvar).with("a").returns({ "key" => [ "a" , "b" ]})
- access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key")
+ it "should raise an error when trying to overwrite an hash value" do
+ @scope.stubs(:lookupvar).with("a").returns({ "key" => [ "a" , "b" ]})
+ access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key")
- lambda { access.assign(@scope, "test") }.should raise_error
- end
+ lambda { access.assign(@scope, "test") }.should raise_error
end
+ end
end
describe Puppet::Parser::AST::Regex do
- before :each do
- @scope = stub 'scope'
- end
+ before :each do
+ @scope = stub 'scope'
+ end
- describe "when initializing" do
- it "should create a Regexp with its content when value is not a Regexp" do
- Regexp.expects(:new).with("/ab/")
+ describe "when initializing" do
+ it "should create a Regexp with its content when value is not a Regexp" do
+ Regexp.expects(:new).with("/ab/")
- Puppet::Parser::AST::Regex.new :value => "/ab/"
- end
-
- it "should not create a Regexp with its content when value is a Regexp" do
- value = Regexp.new("/ab/")
- Regexp.expects(:new).with("/ab/").never
-
- Puppet::Parser::AST::Regex.new :value => value
- end
+ Puppet::Parser::AST::Regex.new :value => "/ab/"
end
- describe "when evaluating" do
- it "should return self" do
- val = Puppet::Parser::AST::Regex.new :value => "/ab/"
+ it "should not create a Regexp with its content when value is a Regexp" do
+ value = Regexp.new("/ab/")
+ Regexp.expects(:new).with("/ab/").never
- val.evaluate(@scope).should === val
- end
+ Puppet::Parser::AST::Regex.new :value => value
end
+ end
- describe "when evaluate_match" do
- before :each do
- @value = stub 'regex'
- @value.stubs(:match).with("value").returns(true)
- Regexp.stubs(:new).returns(@value)
- @regex = Puppet::Parser::AST::Regex.new :value => "/ab/"
- end
-
- it "should issue the regexp match" do
- @value.expects(:match).with("value")
-
- @regex.evaluate_match("value", @scope)
- end
+ describe "when evaluating" do
+ it "should return self" do
+ val = Puppet::Parser::AST::Regex.new :value => "/ab/"
- it "should not downcase the paramater value" do
- @value.expects(:match).with("VaLuE")
-
- @regex.evaluate_match("VaLuE", @scope)
- end
-
- it "should set ephemeral scope vars if there is a match" do
- @scope.expects(:ephemeral_from).with(true, nil, nil)
-
- @regex.evaluate_match("value", @scope)
- end
-
- it "should return the match to the caller" do
- @value.stubs(:match).with("value").returns(:match)
- @scope.stubs(:ephemeral_from)
-
- @regex.evaluate_match("value", @scope)
- end
+ val.evaluate(@scope).should === val
end
+ end
- it "should return the regex source with to_s" do
- regex = stub 'regex'
- Regexp.stubs(:new).returns(regex)
-
- val = Puppet::Parser::AST::Regex.new :value => "/ab/"
-
- regex.expects(:source)
-
- val.to_s
+ describe "when evaluate_match" do
+ before :each do
+ @value = stub 'regex'
+ @value.stubs(:match).with("value").returns(true)
+ Regexp.stubs(:new).returns(@value)
+ @regex = Puppet::Parser::AST::Regex.new :value => "/ab/"
end
- it "should delegate match to the underlying regexp match method" do
- regex = Regexp.new("/ab/")
- val = Puppet::Parser::AST::Regex.new :value => regex
-
- regex.expects(:match).with("value")
+ it "should issue the regexp match" do
+ @value.expects(:match).with("value")
- val.match("value")
+ @regex.evaluate_match("value", @scope)
end
-end
-describe Puppet::Parser::AST::Variable do
- before :each do
- @scope = stub 'scope'
- @var = Puppet::Parser::AST::Variable.new(:value => "myvar")
- end
+ it "should not downcase the paramater value" do
+ @value.expects(:match).with("VaLuE")
- it "should lookup the variable in scope" do
- @scope.expects(:lookupvar).with("myvar", false).returns(:myvalue)
- @var.safeevaluate(@scope).should == :myvalue
+ @regex.evaluate_match("VaLuE", @scope)
end
- it "should return undef if the variable wasn't set" do
- @scope.expects(:lookupvar).with("myvar", false).returns(:undefined)
- @var.safeevaluate(@scope).should == :undef
- end
+ it "should set ephemeral scope vars if there is a match" do
+ @scope.expects(:ephemeral_from).with(true, nil, nil)
- describe "when converting to string" do
- it "should transform its value to a variable" do
- value = stub 'value', :is_a? => true, :to_s => "myvar"
- Puppet::Parser::AST::Variable.new( :value => value ).to_s.should == "\$myvar"
- end
+ @regex.evaluate_match("value", @scope)
end
-end
-describe Puppet::Parser::AST::HostName do
- before :each do
- @scope = stub 'scope'
- @value = stub 'value', :=~ => false
- @value.stubs(:to_s).returns(@value)
- @value.stubs(:downcase).returns(@value)
- @host = Puppet::Parser::AST::HostName.new( :value => @value)
- end
-
- it "should raise an error if hostname is not valid" do
- lambda { Puppet::Parser::AST::HostName.new( :value => "not an hostname!" ) }.should raise_error
- end
+ it "should return the match to the caller" do
+ @value.stubs(:match).with("value").returns(:match)
+ @scope.stubs(:ephemeral_from)
- it "should not raise an error if hostname is a regex" do
- lambda { Puppet::Parser::AST::HostName.new( :value => Puppet::Parser::AST::Regex.new(:value => "/test/") ) }.should_not raise_error
+ @regex.evaluate_match("value", @scope)
end
+ end
- it "should stringify the value" do
- value = stub 'value', :=~ => false
+ it "should return the regex source with to_s" do
+ regex = stub 'regex'
+ Regexp.stubs(:new).returns(regex)
- value.expects(:to_s).returns("test")
+ val = Puppet::Parser::AST::Regex.new :value => "/ab/"
- Puppet::Parser::AST::HostName.new(:value => value)
- end
+ regex.expects(:source)
- it "should downcase the value" do
- value = stub 'value', :=~ => false
- value.stubs(:to_s).returns("UPCASED")
- host = Puppet::Parser::AST::HostName.new(:value => value)
+ val.to_s
+ end
- host.value == "upcased"
- end
+ it "should delegate match to the underlying regexp match method" do
+ regex = Regexp.new("/ab/")
+ val = Puppet::Parser::AST::Regex.new :value => regex
- it "should evaluate to its value" do
- @host.evaluate(@scope).should == @value
- end
+ regex.expects(:match).with("value")
- it "should delegate eql? to the underlying value if it is an HostName" do
- @value.expects(:eql?).with("value")
- @host.eql?("value")
- end
+ val.match("value")
+ end
+end
- it "should delegate eql? to the underlying value if it is not an HostName" do
- value = stub 'compared', :is_a? => true, :value => "value"
- @value.expects(:eql?).with("value")
- @host.eql?(value)
- end
+describe Puppet::Parser::AST::Variable do
+ before :each do
+ @scope = stub 'scope'
+ @var = Puppet::Parser::AST::Variable.new(:value => "myvar")
+ end
+
+ it "should lookup the variable in scope" do
+ @scope.expects(:lookupvar).with("myvar", false).returns(:myvalue)
+ @var.safeevaluate(@scope).should == :myvalue
+ end
+
+ it "should return undef if the variable wasn't set" do
+ @scope.expects(:lookupvar).with("myvar", false).returns(:undefined)
+ @var.safeevaluate(@scope).should == :undef
+ end
+
+ describe "when converting to string" do
+ it "should transform its value to a variable" do
+ value = stub 'value', :is_a? => true, :to_s => "myvar"
+ Puppet::Parser::AST::Variable.new( :value => value ).to_s.should == "\$myvar"
+ end
+ end
+end
- it "should delegate hash to the underlying value" do
- @value.expects(:hash)
- @host.hash
- end
+describe Puppet::Parser::AST::HostName do
+ before :each do
+ @scope = stub 'scope'
+ @value = stub 'value', :=~ => false
+ @value.stubs(:to_s).returns(@value)
+ @value.stubs(:downcase).returns(@value)
+ @host = Puppet::Parser::AST::HostName.new( :value => @value)
+ end
+
+ it "should raise an error if hostname is not valid" do
+ lambda { Puppet::Parser::AST::HostName.new( :value => "not an hostname!" ) }.should raise_error
+ end
+
+ it "should not raise an error if hostname is a regex" do
+ lambda { Puppet::Parser::AST::HostName.new( :value => Puppet::Parser::AST::Regex.new(:value => "/test/") ) }.should_not raise_error
+ end
+
+ it "should stringify the value" do
+ value = stub 'value', :=~ => false
+
+ value.expects(:to_s).returns("test")
+
+ Puppet::Parser::AST::HostName.new(:value => value)
+ end
+
+ it "should downcase the value" do
+ value = stub 'value', :=~ => false
+ value.stubs(:to_s).returns("UPCASED")
+ host = Puppet::Parser::AST::HostName.new(:value => value)
+
+ host.value == "upcased"
+ end
+
+ it "should evaluate to its value" do
+ @host.evaluate(@scope).should == @value
+ end
+
+ it "should delegate eql? to the underlying value if it is an HostName" do
+ @value.expects(:eql?).with("value")
+ @host.eql?("value")
+ end
+
+ it "should delegate eql? to the underlying value if it is not an HostName" do
+ value = stub 'compared', :is_a? => true, :value => "value"
+ @value.expects(:eql?).with("value")
+ @host.eql?(value)
+ end
+
+ it "should delegate hash to the underlying value" do
+ @value.expects(:hash)
+ @host.hash
+ end
end
diff --git a/spec/unit/parser/ast/match_operator_spec.rb b/spec/unit/parser/ast/match_operator_spec.rb
index e76d076..d6e9987 100755
--- a/spec/unit/parser/ast/match_operator_spec.rb
+++ b/spec/unit/parser/ast/match_operator_spec.rb
@@ -3,48 +3,48 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::MatchOperator do
- before :each do
- @scope = Puppet::Parser::Scope.new
+ before :each do
+ @scope = Puppet::Parser::Scope.new
- @lval = stub 'lval'
- @lval.stubs(:safeevaluate).with(@scope).returns("this is a string")
+ @lval = stub 'lval'
+ @lval.stubs(:safeevaluate).with(@scope).returns("this is a string")
- @rval = stub 'rval'
- @rval.stubs(:evaluate_match)
+ @rval = stub 'rval'
+ @rval.stubs(:evaluate_match)
- @operator = Puppet::Parser::AST::MatchOperator.new :lval => @lval, :rval => @rval, :operator => "=~"
- end
+ @operator = Puppet::Parser::AST::MatchOperator.new :lval => @lval, :rval => @rval, :operator => "=~"
+ end
- it "should evaluate the left operand" do
- @lval.expects(:safeevaluate).with(@scope)
+ it "should evaluate the left operand" do
+ @lval.expects(:safeevaluate).with(@scope)
- @operator.evaluate(@scope)
- end
+ @operator.evaluate(@scope)
+ end
- it "should fail for an unknown operator" do
- lambda { operator = Puppet::Parser::AST::MatchOperator.new :lval => @lval, :operator => "unknown", :rval => @rval }.should raise_error
- end
+ it "should fail for an unknown operator" do
+ lambda { operator = Puppet::Parser::AST::MatchOperator.new :lval => @lval, :operator => "unknown", :rval => @rval }.should raise_error
+ end
- it "should evaluate_match the left operand" do
- @rval.expects(:evaluate_match).with("this is a string", @scope).returns(:match)
+ it "should evaluate_match the left operand" do
+ @rval.expects(:evaluate_match).with("this is a string", @scope).returns(:match)
- @operator.evaluate(@scope)
- end
+ @operator.evaluate(@scope)
+ end
- { "=~" => true, "!~" => false }.each do |op, res|
- it "should return #{res} if the regexp matches with #{op}" do
- match = stub 'match'
- @rval.stubs(:evaluate_match).with("this is a string", @scope).returns(match)
+ { "=~" => true, "!~" => false }.each do |op, res|
+ it "should return #{res} if the regexp matches with #{op}" do
+ match = stub 'match'
+ @rval.stubs(:evaluate_match).with("this is a string", @scope).returns(match)
- operator = Puppet::Parser::AST::MatchOperator.new :lval => @lval, :rval => @rval, :operator => op
- operator.evaluate(@scope).should == res
- end
+ operator = Puppet::Parser::AST::MatchOperator.new :lval => @lval, :rval => @rval, :operator => op
+ operator.evaluate(@scope).should == res
+ end
- it "should return #{!res} if the regexp doesn't match" do
- @rval.stubs(:evaluate_match).with("this is a string", @scope).returns(nil)
+ it "should return #{!res} if the regexp doesn't match" do
+ @rval.stubs(:evaluate_match).with("this is a string", @scope).returns(nil)
- operator = Puppet::Parser::AST::MatchOperator.new :lval => @lval, :rval => @rval, :operator => op
- operator.evaluate(@scope).should == !res
- end
+ operator = Puppet::Parser::AST::MatchOperator.new :lval => @lval, :rval => @rval, :operator => op
+ operator.evaluate(@scope).should == !res
end
+ end
end
diff --git a/spec/unit/parser/ast/minus_spec.rb b/spec/unit/parser/ast/minus_spec.rb
index a2c5a78..108c881 100755
--- a/spec/unit/parser/ast/minus_spec.rb
+++ b/spec/unit/parser/ast/minus_spec.rb
@@ -3,34 +3,34 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::Minus do
- before :each do
- @scope = Puppet::Parser::Scope.new
- end
-
- it "should evaluate its argument" do
- value = stub "value"
- value.expects(:safeevaluate).with(@scope).returns(123)
-
- operator = Puppet::Parser::AST::Minus.new :value => value
- operator.evaluate(@scope)
- end
-
- it "should fail if argument is not a string or integer" do
- array_ast = stub 'array_ast', :safeevaluate => [2]
- operator = Puppet::Parser::AST::Minus.new :value => array_ast
- lambda { operator.evaluate(@scope) }.should raise_error
- end
-
- it "should work with integer as string" do
- string = stub 'string', :safeevaluate => "123"
- operator = Puppet::Parser::AST::Minus.new :value => string
- operator.evaluate(@scope).should == -123
- end
-
- it "should work with integers" do
- int = stub 'int', :safeevaluate => 123
- operator = Puppet::Parser::AST::Minus.new :value => int
- operator.evaluate(@scope).should == -123
- end
+ before :each do
+ @scope = Puppet::Parser::Scope.new
+ end
+
+ it "should evaluate its argument" do
+ value = stub "value"
+ value.expects(:safeevaluate).with(@scope).returns(123)
+
+ operator = Puppet::Parser::AST::Minus.new :value => value
+ operator.evaluate(@scope)
+ end
+
+ it "should fail if argument is not a string or integer" do
+ array_ast = stub 'array_ast', :safeevaluate => [2]
+ operator = Puppet::Parser::AST::Minus.new :value => array_ast
+ lambda { operator.evaluate(@scope) }.should raise_error
+ end
+
+ it "should work with integer as string" do
+ string = stub 'string', :safeevaluate => "123"
+ operator = Puppet::Parser::AST::Minus.new :value => string
+ operator.evaluate(@scope).should == -123
+ end
+
+ it "should work with integers" do
+ int = stub 'int', :safeevaluate => 123
+ operator = Puppet::Parser::AST::Minus.new :value => int
+ operator.evaluate(@scope).should == -123
+ end
end
diff --git a/spec/unit/parser/ast/nop_spec.rb b/spec/unit/parser/ast/nop_spec.rb
index 5a71325..3e49319 100755
--- a/spec/unit/parser/ast/nop_spec.rb
+++ b/spec/unit/parser/ast/nop_spec.rb
@@ -4,17 +4,17 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::Nop do
- before do
- @scope = mock 'scope'
- end
+ before do
+ @scope = mock 'scope'
+ end
- it "should do nothing on evaluation" do
- Puppet::Parser::AST.expects(:safeevaluate).never
- Puppet::Parser::AST::Nop.new({}).evaluate(@scope)
- end
+ it "should do nothing on evaluation" do
+ Puppet::Parser::AST.expects(:safeevaluate).never
+ Puppet::Parser::AST::Nop.new({}).evaluate(@scope)
+ end
- it "should not return anything" do
- Puppet::Parser::AST::Nop.new({}).evaluate(@scope).should be_nil
- end
+ it "should not return anything" do
+ Puppet::Parser::AST::Nop.new({}).evaluate(@scope).should be_nil
+ end
end
diff --git a/spec/unit/parser/ast/not_spec.rb b/spec/unit/parser/ast/not_spec.rb
index 3e8b361..2ef6e06 100755
--- a/spec/unit/parser/ast/not_spec.rb
+++ b/spec/unit/parser/ast/not_spec.rb
@@ -3,28 +3,28 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::Not do
- before :each do
- @scope = Puppet::Parser::Scope.new
- @true_ast = Puppet::Parser::AST::Boolean.new( :value => true)
- @false_ast = Puppet::Parser::AST::Boolean.new( :value => false)
- end
+ before :each do
+ @scope = Puppet::Parser::Scope.new
+ @true_ast = Puppet::Parser::AST::Boolean.new( :value => true)
+ @false_ast = Puppet::Parser::AST::Boolean.new( :value => false)
+ end
- it "should evaluate its child expression" do
- val = stub "val"
- val.expects(:safeevaluate).with(@scope)
+ it "should evaluate its child expression" do
+ val = stub "val"
+ val.expects(:safeevaluate).with(@scope)
- operator = Puppet::Parser::AST::Not.new :value => val
- operator.evaluate(@scope)
- end
+ operator = Puppet::Parser::AST::Not.new :value => val
+ operator.evaluate(@scope)
+ end
- it "should return true for ! false" do
- operator = Puppet::Parser::AST::Not.new :value => @false_ast
- operator.evaluate(@scope).should == true
- end
+ it "should return true for ! false" do
+ operator = Puppet::Parser::AST::Not.new :value => @false_ast
+ operator.evaluate(@scope).should == true
+ end
- it "should return false for ! true" do
- operator = Puppet::Parser::AST::Not.new :value => @true_ast
- operator.evaluate(@scope).should == false
- end
+ it "should return false for ! true" do
+ operator = Puppet::Parser::AST::Not.new :value => @true_ast
+ operator.evaluate(@scope).should == false
+ end
end
diff --git a/spec/unit/parser/ast/relationship_spec.rb b/spec/unit/parser/ast/relationship_spec.rb
index acb46e4..2a0f658 100644
--- a/spec/unit/parser/ast/relationship_spec.rb
+++ b/spec/unit/parser/ast/relationship_spec.rb
@@ -3,86 +3,86 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::Relationship do
+ before do
+ @class = Puppet::Parser::AST::Relationship
+ end
+
+ it "should set its 'left' and 'right' arguments accordingly" do
+ dep = @class.new(:left, :right, '->')
+ dep.left.should == :left
+ dep.right.should == :right
+ end
+
+ it "should set its arrow to whatever arrow is passed" do
+ @class.new(:left, :right, '->').arrow.should == '->'
+ end
+
+ it "should set its type to :relationship if the relationship type is '<-'" do
+ @class.new(:left, :right, '<-').type.should == :relationship
+ end
+
+ it "should set its type to :relationship if the relationship type is '->'" do
+ @class.new(:left, :right, '->').type.should == :relationship
+ end
+
+ it "should set its type to :subscription if the relationship type is '~>'" do
+ @class.new(:left, :right, '~>').type.should == :subscription
+ end
+
+ it "should set its type to :subscription if the relationship type is '<~'" do
+ @class.new(:left, :right, '<~').type.should == :subscription
+ end
+
+ it "should set its line and file if provided" do
+ dep = @class.new(:left, :right, '->', :line => 50, :file => "/foo")
+ dep.line.should == 50
+ dep.file.should == "/foo"
+ end
+
+ describe "when evaluating" do
before do
- @class = Puppet::Parser::AST::Relationship
+ @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("foo"))
+ @scope = Puppet::Parser::Scope.new(:compiler => @compiler)
end
- it "should set its 'left' and 'right' arguments accordingly" do
- dep = @class.new(:left, :right, '->')
- dep.left.should == :left
- dep.right.should == :right
+ it "should create a relationship with the evaluated source and target and add it to the scope" do
+ source = stub 'source', :safeevaluate => :left
+ target = stub 'target', :safeevaluate => :right
+ @class.new(source, target, '->').evaluate(@scope)
+ @compiler.relationships[0].source.should == :left
+ @compiler.relationships[0].target.should == :right
end
- it "should set its arrow to whatever arrow is passed" do
- @class.new(:left, :right, '->').arrow.should == '->'
- end
-
- it "should set its type to :relationship if the relationship type is '<-'" do
- @class.new(:left, :right, '<-').type.should == :relationship
- end
-
- it "should set its type to :relationship if the relationship type is '->'" do
- @class.new(:left, :right, '->').type.should == :relationship
- end
-
- it "should set its type to :subscription if the relationship type is '~>'" do
- @class.new(:left, :right, '~>').type.should == :subscription
- end
-
- it "should set its type to :subscription if the relationship type is '<~'" do
- @class.new(:left, :right, '<~').type.should == :subscription
- end
-
- it "should set its line and file if provided" do
- dep = @class.new(:left, :right, '->', :line => 50, :file => "/foo")
- dep.line.should == 50
- dep.file.should == "/foo"
- end
-
- describe "when evaluating" do
- before do
- @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("foo"))
- @scope = Puppet::Parser::Scope.new(:compiler => @compiler)
- end
-
- it "should create a relationship with the evaluated source and target and add it to the scope" do
- source = stub 'source', :safeevaluate => :left
- target = stub 'target', :safeevaluate => :right
- @class.new(source, target, '->').evaluate(@scope)
- @compiler.relationships[0].source.should == :left
- @compiler.relationships[0].target.should == :right
- end
-
- describe "a chained relationship" do
- before do
- @left = stub 'left', :safeevaluate => :left
- @middle = stub 'middle', :safeevaluate => :middle
- @right = stub 'right', :safeevaluate => :right
- @first = @class.new(@left, @middle, '->')
- @second = @class.new(@first, @right, '->')
- end
-
- it "should evaluate the relationship to the left" do
- @first.expects(:evaluate).with(@scope).returns Puppet::Parser::Relationship.new(:left, :right, :relationship)
-
- @second.evaluate(@scope)
- end
-
- it "should use the right side of the left relationship as its source" do
- @second.evaluate(@scope)
-
- @compiler.relationships[0].source.should == :left
- @compiler.relationships[0].target.should == :middle
- @compiler.relationships[1].source.should == :middle
- @compiler.relationships[1].target.should == :right
- end
-
- it "should only evaluate a given AST node once" do
- @left.expects(:safeevaluate).once.returns :left
- @middle.expects(:safeevaluate).once.returns :middle
- @right.expects(:safeevaluate).once.returns :right
- @second.evaluate(@scope)
- end
- end
+ describe "a chained relationship" do
+ before do
+ @left = stub 'left', :safeevaluate => :left
+ @middle = stub 'middle', :safeevaluate => :middle
+ @right = stub 'right', :safeevaluate => :right
+ @first = @class.new(@left, @middle, '->')
+ @second = @class.new(@first, @right, '->')
+ end
+
+ it "should evaluate the relationship to the left" do
+ @first.expects(:evaluate).with(@scope).returns Puppet::Parser::Relationship.new(:left, :right, :relationship)
+
+ @second.evaluate(@scope)
+ end
+
+ it "should use the right side of the left relationship as its source" do
+ @second.evaluate(@scope)
+
+ @compiler.relationships[0].source.should == :left
+ @compiler.relationships[0].target.should == :middle
+ @compiler.relationships[1].source.should == :middle
+ @compiler.relationships[1].target.should == :right
+ end
+
+ it "should only evaluate a given AST node once" do
+ @left.expects(:safeevaluate).once.returns :left
+ @middle.expects(:safeevaluate).once.returns :middle
+ @right.expects(:safeevaluate).once.returns :right
+ @second.evaluate(@scope)
+ end
end
+ end
end
diff --git a/spec/unit/parser/ast/resource_defaults_spec.rb b/spec/unit/parser/ast/resource_defaults_spec.rb
index b2cec31..7843fd9 100755
--- a/spec/unit/parser/ast/resource_defaults_spec.rb
+++ b/spec/unit/parser/ast/resource_defaults_spec.rb
@@ -4,19 +4,19 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::ResourceDefaults do
- ast = Puppet::Parser::AST
+ ast = Puppet::Parser::AST
- before :each do
- @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode"))
- @scope = Puppet::Parser::Scope.new(:compiler => @compiler)
- @params = Puppet::Parser::AST::ASTArray.new({})
- @compiler.stubs(:add_override)
- end
+ before :each do
+ @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode"))
+ @scope = Puppet::Parser::Scope.new(:compiler => @compiler)
+ @params = Puppet::Parser::AST::ASTArray.new({})
+ @compiler.stubs(:add_override)
+ end
- it "should add defaults when evaluated" do
- default = Puppet::Parser::AST::ResourceDefaults.new :type => "file", :parameters => Puppet::Parser::AST::ASTArray.new(:children => [])
- default.evaluate @scope
+ it "should add defaults when evaluated" do
+ default = Puppet::Parser::AST::ResourceDefaults.new :type => "file", :parameters => Puppet::Parser::AST::ASTArray.new(:children => [])
+ default.evaluate @scope
- @scope.lookupdefaults("file").should_not be_nil
- end
+ @scope.lookupdefaults("file").should_not be_nil
+ end
end
diff --git a/spec/unit/parser/ast/resource_override_spec.rb b/spec/unit/parser/ast/resource_override_spec.rb
index d327b57..637ab41 100755
--- a/spec/unit/parser/ast/resource_override_spec.rb
+++ b/spec/unit/parser/ast/resource_override_spec.rb
@@ -4,48 +4,48 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::ResourceOverride do
- ast = Puppet::Parser::AST
-
- before :each do
- @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode"))
- @scope = Puppet::Parser::Scope.new(:compiler => @compiler)
- @params = ast::ASTArray.new({})
- @compiler.stubs(:add_override)
- end
-
- it "should evaluate the overriden object" do
- klass = stub 'klass', :title => "title", :type => "type"
- object = mock 'object'
- object.expects(:safeevaluate).with(@scope).returns(klass)
- ast::ResourceOverride.new(:object => object, :parameters => @params ).evaluate(@scope)
- end
-
- it "should tell the compiler to override the resource with our own" do
- @compiler.expects(:add_override)
-
- klass = stub 'klass', :title => "title", :type => "one"
- object = mock 'object', :safeevaluate => klass
- ast::ResourceOverride.new(:object => object , :parameters => @params).evaluate(@scope)
- end
-
- it "should return the overriden resource directly when called with one item" do
- klass = stub 'klass', :title => "title", :type => "one"
- object = mock 'object', :safeevaluate => klass
- override = ast::ResourceOverride.new(:object => object , :parameters => @params).evaluate(@scope)
- override.should be_an_instance_of(Puppet::Parser::Resource)
- override.title.should == "title"
- override.type.should == "One"
- end
-
- it "should return an array of overriden resources when called with an array of titles" do
- klass1 = stub 'klass1', :title => "title1", :type => "one"
- klass2 = stub 'klass2', :title => "title2", :type => "one"
-
- object = mock 'object', :safeevaluate => [klass1,klass2]
-
- override = ast::ResourceOverride.new(:object => object , :parameters => @params).evaluate(@scope)
- override.should have(2).elements
- override.each {|o| o.should be_an_instance_of(Puppet::Parser::Resource) }
- end
+ ast = Puppet::Parser::AST
+
+ before :each do
+ @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode"))
+ @scope = Puppet::Parser::Scope.new(:compiler => @compiler)
+ @params = ast::ASTArray.new({})
+ @compiler.stubs(:add_override)
+ end
+
+ it "should evaluate the overriden object" do
+ klass = stub 'klass', :title => "title", :type => "type"
+ object = mock 'object'
+ object.expects(:safeevaluate).with(@scope).returns(klass)
+ ast::ResourceOverride.new(:object => object, :parameters => @params ).evaluate(@scope)
+ end
+
+ it "should tell the compiler to override the resource with our own" do
+ @compiler.expects(:add_override)
+
+ klass = stub 'klass', :title => "title", :type => "one"
+ object = mock 'object', :safeevaluate => klass
+ ast::ResourceOverride.new(:object => object , :parameters => @params).evaluate(@scope)
+ end
+
+ it "should return the overriden resource directly when called with one item" do
+ klass = stub 'klass', :title => "title", :type => "one"
+ object = mock 'object', :safeevaluate => klass
+ override = ast::ResourceOverride.new(:object => object , :parameters => @params).evaluate(@scope)
+ override.should be_an_instance_of(Puppet::Parser::Resource)
+ override.title.should == "title"
+ override.type.should == "One"
+ end
+
+ it "should return an array of overriden resources when called with an array of titles" do
+ klass1 = stub 'klass1', :title => "title1", :type => "one"
+ klass2 = stub 'klass2', :title => "title2", :type => "one"
+
+ object = mock 'object', :safeevaluate => [klass1,klass2]
+
+ override = ast::ResourceOverride.new(:object => object , :parameters => @params).evaluate(@scope)
+ override.should have(2).elements
+ override.each {|o| o.should be_an_instance_of(Puppet::Parser::Resource) }
+ end
end
diff --git a/spec/unit/parser/ast/resource_reference_spec.rb b/spec/unit/parser/ast/resource_reference_spec.rb
index a2a11e2..7b48119 100755
--- a/spec/unit/parser/ast/resource_reference_spec.rb
+++ b/spec/unit/parser/ast/resource_reference_spec.rb
@@ -4,43 +4,43 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::ResourceReference do
- ast = Puppet::Parser::AST
-
- before :each do
- @scope = Puppet::Parser::Scope.new
- end
-
- def newref(type, title)
- title = stub 'title', :safeevaluate => title
- ref = Puppet::Parser::AST::ResourceReference.new(:type => type, :title => title)
- end
-
- it "should correctly produce reference strings" do
- newref("File", "/tmp/yay").evaluate(@scope).to_s.should == "File[/tmp/yay]"
- end
-
- it "should produce a single resource when the title evaluates to a string" do
- newref("File", "/tmp/yay").evaluate(@scope).should == Puppet::Resource.new("file", "/tmp/yay")
- end
-
- it "should return an array of resources if given an array of titles" do
- titles = mock 'titles', :safeevaluate => ["title1","title2"]
- ref = ast::ResourceReference.new( :title => titles, :type => "File" )
- ref.evaluate(@scope).should == [
- Puppet::Resource.new("file", "title1"),
- Puppet::Resource.new("file", "title2")
- ]
- end
-
- it "should pass its scope's namespaces to all created resource references" do
- @scope.add_namespace "foo"
- newref("File", "/tmp/yay").evaluate(@scope).namespaces.should == ["foo"]
- end
-
- it "should return a correct representation when converting to string" do
- type = stub 'type', :is_a? => true, :to_s => "file"
- title = stub 'title', :is_a? => true, :to_s => "[/tmp/a, /tmp/b]"
-
- ast::ResourceReference.new( :type => type, :title => title ).to_s.should == "File[/tmp/a, /tmp/b]"
- end
+ ast = Puppet::Parser::AST
+
+ before :each do
+ @scope = Puppet::Parser::Scope.new
+ end
+
+ def newref(type, title)
+ title = stub 'title', :safeevaluate => title
+ ref = Puppet::Parser::AST::ResourceReference.new(:type => type, :title => title)
+ end
+
+ it "should correctly produce reference strings" do
+ newref("File", "/tmp/yay").evaluate(@scope).to_s.should == "File[/tmp/yay]"
+ end
+
+ it "should produce a single resource when the title evaluates to a string" do
+ newref("File", "/tmp/yay").evaluate(@scope).should == Puppet::Resource.new("file", "/tmp/yay")
+ end
+
+ it "should return an array of resources if given an array of titles" do
+ titles = mock 'titles', :safeevaluate => ["title1","title2"]
+ ref = ast::ResourceReference.new( :title => titles, :type => "File" )
+ ref.evaluate(@scope).should == [
+ Puppet::Resource.new("file", "title1"),
+ Puppet::Resource.new("file", "title2")
+ ]
+ end
+
+ it "should pass its scope's namespaces to all created resource references" do
+ @scope.add_namespace "foo"
+ newref("File", "/tmp/yay").evaluate(@scope).namespaces.should == ["foo"]
+ end
+
+ it "should return a correct representation when converting to string" do
+ type = stub 'type', :is_a? => true, :to_s => "file"
+ title = stub 'title', :is_a? => true, :to_s => "[/tmp/a, /tmp/b]"
+
+ ast::ResourceReference.new( :type => type, :title => title ).to_s.should == "File[/tmp/a, /tmp/b]"
+ end
end
diff --git a/spec/unit/parser/ast/resource_spec.rb b/spec/unit/parser/ast/resource_spec.rb
index 2473fda..58ffae9 100755
--- a/spec/unit/parser/ast/resource_spec.rb
+++ b/spec/unit/parser/ast/resource_spec.rb
@@ -3,118 +3,118 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::Resource do
- ast = Puppet::Parser::AST
-
- before :each do
- @title = Puppet::Parser::AST::String.new(:value => "mytitle")
- @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode"))
- @scope = Puppet::Parser::Scope.new(:compiler => @compiler)
- @scope.stubs(:resource).returns(stub_everything)
- @resource = ast::Resource.new(:title => @title, :type => "file", :parameters => ast::ASTArray.new(:children => []) )
- @resource.stubs(:qualified_type).returns("Resource")
+ ast = Puppet::Parser::AST
+
+ before :each do
+ @title = Puppet::Parser::AST::String.new(:value => "mytitle")
+ @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode"))
+ @scope = Puppet::Parser::Scope.new(:compiler => @compiler)
+ @scope.stubs(:resource).returns(stub_everything)
+ @resource = ast::Resource.new(:title => @title, :type => "file", :parameters => ast::ASTArray.new(:children => []) )
+ @resource.stubs(:qualified_type).returns("Resource")
+ end
+
+ it "should evaluate all its parameters" do
+ param = stub 'param'
+ param.expects(:safeevaluate).with(@scope).returns Puppet::Parser::Resource::Param.new(:name => "myparam", :value => "myvalue", :source => stub("source"))
+ @resource.stubs(:parameters).returns [param]
+
+ @resource.evaluate(@scope)
+ end
+
+ it "should evaluate its title" do
+ @resource.evaluate(@scope)[0].title.should == "mytitle"
+ end
+
+ it "should flatten the titles array" do
+ titles = []
+ %w{one two}.each do |title|
+ titles << Puppet::Parser::AST::String.new(:value => title)
end
- it "should evaluate all its parameters" do
- param = stub 'param'
- param.expects(:safeevaluate).with(@scope).returns Puppet::Parser::Resource::Param.new(:name => "myparam", :value => "myvalue", :source => stub("source"))
- @resource.stubs(:parameters).returns [param]
+ array = Puppet::Parser::AST::ASTArray.new(:children => titles)
- @resource.evaluate(@scope)
- end
+ @resource.title = array
+ result = @resource.evaluate(@scope).collect { |r| r.title }
+ result.should be_include("one")
+ result.should be_include("two")
+ end
- it "should evaluate its title" do
- @resource.evaluate(@scope)[0].title.should == "mytitle"
+ it "should create and return one resource objects per title" do
+ titles = []
+ %w{one two}.each do |title|
+ titles << Puppet::Parser::AST::String.new(:value => title)
end
- it "should flatten the titles array" do
- titles = []
- %w{one two}.each do |title|
- titles << Puppet::Parser::AST::String.new(:value => title)
- end
+ array = Puppet::Parser::AST::ASTArray.new(:children => titles)
- array = Puppet::Parser::AST::ASTArray.new(:children => titles)
+ @resource.title = array
+ result = @resource.evaluate(@scope).collect { |r| r.title }
+ result.should be_include("one")
+ result.should be_include("two")
+ end
- @resource.title = array
- result = @resource.evaluate(@scope).collect { |r| r.title }
- result.should be_include("one")
- result.should be_include("two")
+ it "should handover resources to the compiler" do
+ titles = []
+ %w{one two}.each do |title|
+ titles << Puppet::Parser::AST::String.new(:value => title)
end
- it "should create and return one resource objects per title" do
- titles = []
- %w{one two}.each do |title|
- titles << Puppet::Parser::AST::String.new(:value => title)
- end
+ array = Puppet::Parser::AST::ASTArray.new(:children => titles)
- array = Puppet::Parser::AST::ASTArray.new(:children => titles)
+ @resource.title = array
+ result = @resource.evaluate(@scope)
- @resource.title = array
- result = @resource.evaluate(@scope).collect { |r| r.title }
- result.should be_include("one")
- result.should be_include("two")
+ result.each do |res|
+ @compiler.catalog.resource(res.ref).should be_instance_of(Puppet::Parser::Resource)
+ end
+ end
+ it "should generate virtual resources if it is virtual" do
+ @resource.virtual = true
+
+ result = @resource.evaluate(@scope)
+ result[0].should be_virtual
+ end
+
+ it "should generate virtual and exported resources if it is exported" do
+ @resource.exported = true
+
+ result = @resource.evaluate(@scope)
+ result[0].should be_virtual
+ result[0].should be_exported
+ end
+
+ # Related to #806, make sure resources always look up the full path to the resource.
+ describe "when generating qualified resources" do
+ before do
+ @scope = Puppet::Parser::Scope.new :compiler => Puppet::Parser::Compiler.new(Puppet::Node.new("mynode"))
+ @parser = Puppet::Parser::Parser.new(Puppet::Node::Environment.new)
+ @parser.newdefine "one"
+ @parser.newdefine "one::two"
+ @parser.newdefine "three"
+ @twoscope = @scope.newscope(:namespace => "one")
+ @twoscope.resource = @scope.resource
end
- it "should handover resources to the compiler" do
- titles = []
- %w{one two}.each do |title|
- titles << Puppet::Parser::AST::String.new(:value => title)
- end
-
- array = Puppet::Parser::AST::ASTArray.new(:children => titles)
-
- @resource.title = array
- result = @resource.evaluate(@scope)
-
- result.each do |res|
- @compiler.catalog.resource(res.ref).should be_instance_of(Puppet::Parser::Resource)
- end
+ def resource(type, params = nil)
+ params ||= Puppet::Parser::AST::ASTArray.new(:children => [])
+ Puppet::Parser::AST::Resource.new(:type => type, :title => Puppet::Parser::AST::String.new(:value => "myresource"), :parameters => params)
end
- it "should generate virtual resources if it is virtual" do
- @resource.virtual = true
- result = @resource.evaluate(@scope)
- result[0].should be_virtual
+ it "should be able to generate resources with fully qualified type information" do
+ resource("two").evaluate(@twoscope)[0].type.should == "One::Two"
end
- it "should generate virtual and exported resources if it is exported" do
- @resource.exported = true
+ it "should be able to generate resources with unqualified type information" do
+ resource("one").evaluate(@twoscope)[0].type.should == "One"
+ end
- result = @resource.evaluate(@scope)
- result[0].should be_virtual
- result[0].should be_exported
+ it "should correctly generate resources that can look up builtin types" do
+ resource("file").evaluate(@twoscope)[0].type.should == "File"
end
- # Related to #806, make sure resources always look up the full path to the resource.
- describe "when generating qualified resources" do
- before do
- @scope = Puppet::Parser::Scope.new :compiler => Puppet::Parser::Compiler.new(Puppet::Node.new("mynode"))
- @parser = Puppet::Parser::Parser.new(Puppet::Node::Environment.new)
- @parser.newdefine "one"
- @parser.newdefine "one::two"
- @parser.newdefine "three"
- @twoscope = @scope.newscope(:namespace => "one")
- @twoscope.resource = @scope.resource
- end
-
- def resource(type, params = nil)
- params ||= Puppet::Parser::AST::ASTArray.new(:children => [])
- Puppet::Parser::AST::Resource.new(:type => type, :title => Puppet::Parser::AST::String.new(:value => "myresource"), :parameters => params)
- end
-
- it "should be able to generate resources with fully qualified type information" do
- resource("two").evaluate(@twoscope)[0].type.should == "One::Two"
- end
-
- it "should be able to generate resources with unqualified type information" do
- resource("one").evaluate(@twoscope)[0].type.should == "One"
- end
-
- it "should correctly generate resources that can look up builtin types" do
- resource("file").evaluate(@twoscope)[0].type.should == "File"
- end
-
- it "should fail for resource types that do not exist" do
- lambda { resource("nosuchtype").evaluate(@twoscope) }.should raise_error(Puppet::ParseError)
- end
+ it "should fail for resource types that do not exist" do
+ lambda { resource("nosuchtype").evaluate(@twoscope) }.should raise_error(Puppet::ParseError)
end
+ end
end
diff --git a/spec/unit/parser/ast/selector_spec.rb b/spec/unit/parser/ast/selector_spec.rb
index e10849c..4289847 100755
--- a/spec/unit/parser/ast/selector_spec.rb
+++ b/spec/unit/parser/ast/selector_spec.rb
@@ -3,137 +3,137 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::Selector do
- before :each do
- @scope = Puppet::Parser::Scope.new
- end
-
- describe "when evaluating" do
-
- before :each do
- @param = stub 'param'
- @param.stubs(:safeevaluate).with(@scope).returns("value")
-
- @value1 = stub 'value1'
- @param1 = stub_everything 'param1'
- @param1.stubs(:safeevaluate).with(@scope).returns(@param1)
- @param1.stubs(:respond_to?).with(:downcase).returns(false)
- @value1.stubs(:param).returns(@param1)
- @value1.stubs(:value).returns(@value1)
+ before :each do
+ @scope = Puppet::Parser::Scope.new
+ end
- @value2 = stub 'value2'
- @param2 = stub_everything 'param2'
- @param2.stubs(:safeevaluate).with(@scope).returns(@param2)
- @param2.stubs(:respond_to?).with(:downcase).returns(false)
- @value2.stubs(:param).returns(@param2)
- @value2.stubs(:value).returns(@value2)
+ describe "when evaluating" do
- @values = stub 'values', :instance_of? => true
- @values.stubs(:each).multiple_yields(@value1, @value2)
-
- @selector = Puppet::Parser::AST::Selector.new :param => @param, :values => @values
- @selector.stubs(:fail)
- end
+ before :each do
+ @param = stub 'param'
+ @param.stubs(:safeevaluate).with(@scope).returns("value")
+
+ @value1 = stub 'value1'
+ @param1 = stub_everything 'param1'
+ @param1.stubs(:safeevaluate).with(@scope).returns(@param1)
+ @param1.stubs(:respond_to?).with(:downcase).returns(false)
+ @value1.stubs(:param).returns(@param1)
+ @value1.stubs(:value).returns(@value1)
+
+ @value2 = stub 'value2'
+ @param2 = stub_everything 'param2'
+ @param2.stubs(:safeevaluate).with(@scope).returns(@param2)
+ @param2.stubs(:respond_to?).with(:downcase).returns(false)
+ @value2.stubs(:param).returns(@param2)
+ @value2.stubs(:value).returns(@value2)
+
+ @values = stub 'values', :instance_of? => true
+ @values.stubs(:each).multiple_yields(@value1, @value2)
+
+ @selector = Puppet::Parser::AST::Selector.new :param => @param, :values => @values
+ @selector.stubs(:fail)
+ end
- it "should evaluate param" do
- @param.expects(:safeevaluate).with(@scope)
+ it "should evaluate param" do
+ @param.expects(:safeevaluate).with(@scope)
- @selector.evaluate(@scope)
- end
+ @selector.evaluate(@scope)
+ end
- it "should scan each option" do
- @values.expects(:each).multiple_yields(@value1, @value2)
+ it "should scan each option" do
+ @values.expects(:each).multiple_yields(@value1, @value2)
- @selector.evaluate(@scope)
- end
+ @selector.evaluate(@scope)
+ end
- describe "when scanning values" do
- it "should evaluate first matching option" do
- @param2.stubs(:evaluate_match).with { |*arg| arg[0] == "value" }.returns(true)
- @value2.expects(:safeevaluate).with(@scope)
+ describe "when scanning values" do
+ it "should evaluate first matching option" do
+ @param2.stubs(:evaluate_match).with { |*arg| arg[0] == "value" }.returns(true)
+ @value2.expects(:safeevaluate).with(@scope)
- @selector.evaluate(@scope)
- end
+ @selector.evaluate(@scope)
+ end
- it "should return the first matching evaluated option" do
- @param2.stubs(:evaluate_match).with { |*arg| arg[0] == "value" }.returns(true)
- @value2.stubs(:safeevaluate).with(@scope).returns(:result)
+ it "should return the first matching evaluated option" do
+ @param2.stubs(:evaluate_match).with { |*arg| arg[0] == "value" }.returns(true)
+ @value2.stubs(:safeevaluate).with(@scope).returns(:result)
- @selector.evaluate(@scope).should == :result
- end
+ @selector.evaluate(@scope).should == :result
+ end
- it "should evaluate the default option if none matched" do
- @param1.stubs(:is_a?).with(Puppet::Parser::AST::Default).returns(true)
- @value1.expects(:safeevaluate).with(@scope).returns(@param1)
+ it "should evaluate the default option if none matched" do
+ @param1.stubs(:is_a?).with(Puppet::Parser::AST::Default).returns(true)
+ @value1.expects(:safeevaluate).with(@scope).returns(@param1)
- @selector.evaluate(@scope)
- end
+ @selector.evaluate(@scope)
+ end
- it "should return the default evaluated option if none matched" do
- result = stub 'result'
- @param1.stubs(:is_a?).with(Puppet::Parser::AST::Default).returns(true)
- @value1.stubs(:safeevaluate).returns(result)
+ it "should return the default evaluated option if none matched" do
+ result = stub 'result'
+ @param1.stubs(:is_a?).with(Puppet::Parser::AST::Default).returns(true)
+ @value1.stubs(:safeevaluate).returns(result)
- @selector.evaluate(@scope).should == result
- end
+ @selector.evaluate(@scope).should == result
+ end
- it "should return nil if nothing matched" do
- @selector.evaluate(@scope).should be_nil
- end
+ it "should return nil if nothing matched" do
+ @selector.evaluate(@scope).should be_nil
+ end
- it "should delegate matching to evaluate_match" do
- @param1.expects(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }
+ it "should delegate matching to evaluate_match" do
+ @param1.expects(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }
- @selector.evaluate(@scope)
- end
+ @selector.evaluate(@scope)
+ end
- it "should evaluate the matching param" do
- @param1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true)
+ it "should evaluate the matching param" do
+ @param1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true)
- @value1.expects(:safeevaluate).with(@scope)
+ @value1.expects(:safeevaluate).with(@scope)
- @selector.evaluate(@scope)
- end
+ @selector.evaluate(@scope)
+ end
- it "should return this evaluated option if it matches" do
- @param1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true)
- @value1.stubs(:safeevaluate).with(@scope).returns(:result)
+ it "should return this evaluated option if it matches" do
+ @param1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true)
+ @value1.stubs(:safeevaluate).with(@scope).returns(:result)
- @selector.evaluate(@scope).should == :result
- end
+ @selector.evaluate(@scope).should == :result
+ end
- it "should unset scope ephemeral variables after option evaluation" do
- @scope.stubs(:ephemeral_level).returns(:level)
- @param1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true)
- @value1.stubs(:safeevaluate).with(@scope).returns(:result)
+ it "should unset scope ephemeral variables after option evaluation" do
+ @scope.stubs(:ephemeral_level).returns(:level)
+ @param1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true)
+ @value1.stubs(:safeevaluate).with(@scope).returns(:result)
- @scope.expects(:unset_ephemeral_var).with(:level)
+ @scope.expects(:unset_ephemeral_var).with(:level)
- @selector.evaluate(@scope)
- end
+ @selector.evaluate(@scope)
+ end
- it "should not leak ephemeral variables even if evaluation fails" do
- @scope.stubs(:ephemeral_level).returns(:level)
- @param1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true)
- @value1.stubs(:safeevaluate).with(@scope).raises
+ it "should not leak ephemeral variables even if evaluation fails" do
+ @scope.stubs(:ephemeral_level).returns(:level)
+ @param1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true)
+ @value1.stubs(:safeevaluate).with(@scope).raises
- @scope.expects(:unset_ephemeral_var).with(:level)
+ @scope.expects(:unset_ephemeral_var).with(:level)
- lambda { @selector.evaluate(@scope) }.should raise_error
- end
+ lambda { @selector.evaluate(@scope) }.should raise_error
+ end
- it "should fail if there is no default" do
- @selector.expects(:fail)
+ it "should fail if there is no default" do
+ @selector.expects(:fail)
- @selector.evaluate(@scope)
- end
- end
+ @selector.evaluate(@scope)
+ end
end
- describe "when converting to string" do
- it "should produce a string version of this selector" do
- values = Puppet::Parser::AST::ASTArray.new :children => [ Puppet::Parser::AST::ResourceParam.new(:param => "type", :value => "value", :add => false) ]
- param = Puppet::Parser::AST::Variable.new :value => "myvar"
- selector = Puppet::Parser::AST::Selector.new :param => param, :values => values
- selector.to_s.should == "$myvar ? { type => value }"
- end
+ end
+ describe "when converting to string" do
+ it "should produce a string version of this selector" do
+ values = Puppet::Parser::AST::ASTArray.new :children => [ Puppet::Parser::AST::ResourceParam.new(:param => "type", :value => "value", :add => false) ]
+ param = Puppet::Parser::AST::Variable.new :value => "myvar"
+ selector = Puppet::Parser::AST::Selector.new :param => param, :values => values
+ selector.to_s.should == "$myvar ? { type => value }"
end
+ end
end
diff --git a/spec/unit/parser/ast/vardef_spec.rb b/spec/unit/parser/ast/vardef_spec.rb
index e133b67..a90010f 100755
--- a/spec/unit/parser/ast/vardef_spec.rb
+++ b/spec/unit/parser/ast/vardef_spec.rb
@@ -3,58 +3,58 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::VarDef do
- before :each do
- @scope = Puppet::Parser::Scope.new
- end
-
- describe "when evaluating" do
+ before :each do
+ @scope = Puppet::Parser::Scope.new
+ end
- it "should evaluate arguments" do
- name = mock 'name'
- value = mock 'value'
+ describe "when evaluating" do
- name.expects(:safeevaluate).with(@scope)
- value.expects(:safeevaluate).with(@scope)
+ it "should evaluate arguments" do
+ name = mock 'name'
+ value = mock 'value'
- vardef = Puppet::Parser::AST::VarDef.new :name => name, :value => value, :file => nil,
- :line => nil
- vardef.evaluate(@scope)
- end
+ name.expects(:safeevaluate).with(@scope)
+ value.expects(:safeevaluate).with(@scope)
- it "should be in append=false mode if called without append" do
- name = stub 'name', :safeevaluate => "var"
- value = stub 'value', :safeevaluate => "1"
+ vardef = Puppet::Parser::AST::VarDef.new :name => name, :value => value, :file => nil,
+ :line => nil
+ vardef.evaluate(@scope)
+ end
- @scope.expects(:setvar).with { |name,value,options| options[:append] == nil }
+ it "should be in append=false mode if called without append" do
+ name = stub 'name', :safeevaluate => "var"
+ value = stub 'value', :safeevaluate => "1"
- vardef = Puppet::Parser::AST::VarDef.new :name => name, :value => value, :file => nil,
- :line => nil
- vardef.evaluate(@scope)
- end
+ @scope.expects(:setvar).with { |name,value,options| options[:append] == nil }
- it "should call scope in append mode if append is true" do
- name = stub 'name', :safeevaluate => "var"
- value = stub 'value', :safeevaluate => "1"
+ vardef = Puppet::Parser::AST::VarDef.new :name => name, :value => value, :file => nil,
+ :line => nil
+ vardef.evaluate(@scope)
+ end
- @scope.expects(:setvar).with { |name,value,options| options[:append] == true }
+ it "should call scope in append mode if append is true" do
+ name = stub 'name', :safeevaluate => "var"
+ value = stub 'value', :safeevaluate => "1"
- vardef = Puppet::Parser::AST::VarDef.new :name => name, :value => value, :file => nil,
- :line => nil, :append => true
- vardef.evaluate(@scope)
- end
+ @scope.expects(:setvar).with { |name,value,options| options[:append] == true }
- describe "when dealing with hash" do
- it "should delegate to the HashOrArrayAccess assign" do
- access = stub 'name'
- access.stubs(:is_a?).with(Puppet::Parser::AST::HashOrArrayAccess).returns(true)
- value = stub 'value', :safeevaluate => "1"
- vardef = Puppet::Parser::AST::VarDef.new :name => access, :value => value, :file => nil, :line => nil
+ vardef = Puppet::Parser::AST::VarDef.new :name => name, :value => value, :file => nil,
+ :line => nil, :append => true
+ vardef.evaluate(@scope)
+ end
- access.expects(:assign).with(@scope, '1')
+ describe "when dealing with hash" do
+ it "should delegate to the HashOrArrayAccess assign" do
+ access = stub 'name'
+ access.stubs(:is_a?).with(Puppet::Parser::AST::HashOrArrayAccess).returns(true)
+ value = stub 'value', :safeevaluate => "1"
+ vardef = Puppet::Parser::AST::VarDef.new :name => access, :value => value, :file => nil, :line => nil
- vardef.evaluate(@scope)
- end
- end
+ access.expects(:assign).with(@scope, '1')
+ vardef.evaluate(@scope)
+ end
end
+
+ end
end
diff --git a/spec/unit/parser/ast_spec.rb b/spec/unit/parser/ast_spec.rb
index cd271af..b743cea 100644
--- a/spec/unit/parser/ast_spec.rb
+++ b/spec/unit/parser/ast_spec.rb
@@ -6,36 +6,36 @@ require 'puppet/parser/ast'
describe Puppet::Parser::AST do
- it "should use the file lookup module" do
- Puppet::Parser::AST.ancestors.should be_include(Puppet::FileCollection::Lookup)
+ it "should use the file lookup module" do
+ Puppet::Parser::AST.ancestors.should be_include(Puppet::FileCollection::Lookup)
+ end
+
+ it "should have a doc accessor" do
+ ast = Puppet::Parser::AST.new({})
+ ast.should respond_to(:doc)
+ end
+
+ it "should have a use_docs accessor to indicate it wants documentation" do
+ ast = Puppet::Parser::AST.new({})
+ ast.should respond_to(:use_docs)
+ end
+
+ [ Puppet::Parser::AST::Collection, Puppet::Parser::AST::Else,
+ Puppet::Parser::AST::Function, Puppet::Parser::AST::IfStatement,
+ Puppet::Parser::AST::Resource, Puppet::Parser::AST::ResourceDefaults,
+ Puppet::Parser::AST::ResourceOverride, Puppet::Parser::AST::VarDef
+ ].each do |k|
+ it "#{k}.use_docs should return true" do
+ ast = k.new({})
+ ast.use_docs.should be_true
end
+ end
- it "should have a doc accessor" do
- ast = Puppet::Parser::AST.new({})
- ast.should respond_to(:doc)
- end
-
- it "should have a use_docs accessor to indicate it wants documentation" do
- ast = Puppet::Parser::AST.new({})
- ast.should respond_to(:use_docs)
- end
-
- [ Puppet::Parser::AST::Collection, Puppet::Parser::AST::Else,
- Puppet::Parser::AST::Function, Puppet::Parser::AST::IfStatement,
- Puppet::Parser::AST::Resource, Puppet::Parser::AST::ResourceDefaults,
- Puppet::Parser::AST::ResourceOverride, Puppet::Parser::AST::VarDef
- ].each do |k|
- it "#{k}.use_docs should return true" do
- ast = k.new({})
- ast.use_docs.should be_true
- end
- end
-
- describe "when initializing" do
- it "should store the doc argument if passed" do
- ast = Puppet::Parser::AST.new(:doc => "documentation")
- ast.doc.should == "documentation"
- end
+ describe "when initializing" do
+ it "should store the doc argument if passed" do
+ ast = Puppet::Parser::AST.new(:doc => "documentation")
+ ast.doc.should == "documentation"
end
+ end
end
diff --git a/spec/unit/parser/collector_spec.rb b/spec/unit/parser/collector_spec.rb
index c414207..15808d6 100755
--- a/spec/unit/parser/collector_spec.rb
+++ b/spec/unit/parser/collector_spec.rb
@@ -5,555 +5,555 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/parser/collector'
describe Puppet::Parser::Collector, "when initializing" do
- before do
- @scope = mock 'scope'
- @resource_type = 'resource_type'
- @form = :exported
- @vquery = mock 'vquery'
- @equery = mock 'equery'
-
- @collector = Puppet::Parser::Collector.new(@scope, @resource_type, @equery, @vquery, @form)
- end
-
- it "should require a scope" do
- @collector.scope.should equal(@scope)
- end
-
- it "should require a resource type" do
- @collector.type.should == 'Resource_type'
- end
-
- it "should only accept :virtual or :exported as the collector form" do
- proc { @collector = Puppet::Parser::Collector.new(@scope, @resource_type, @vquery, @equery, :other) }.should raise_error(ArgumentError)
- end
-
- it "should accept an optional virtual query" do
- @collector.vquery.should equal(@vquery)
- end
-
- it "should accept an optional exported query" do
- @collector.equery.should equal(@equery)
- end
-
- it "should canonize the type name" do
- @collector = Puppet::Parser::Collector.new(@scope, "resource::type", @equery, @vquery, @form)
- @collector.type.should == "Resource::Type"
- end
-
- it "should accept an optional resource override" do
- @collector = Puppet::Parser::Collector.new(@scope, "resource::type", @equery, @vquery, @form)
- override = { :parameters => "whatever" }
- @collector.add_override(override)
- @collector.overrides.should equal(override)
- end
+ before do
+ @scope = mock 'scope'
+ @resource_type = 'resource_type'
+ @form = :exported
+ @vquery = mock 'vquery'
+ @equery = mock 'equery'
+
+ @collector = Puppet::Parser::Collector.new(@scope, @resource_type, @equery, @vquery, @form)
+ end
+
+ it "should require a scope" do
+ @collector.scope.should equal(@scope)
+ end
+
+ it "should require a resource type" do
+ @collector.type.should == 'Resource_type'
+ end
+
+ it "should only accept :virtual or :exported as the collector form" do
+ proc { @collector = Puppet::Parser::Collector.new(@scope, @resource_type, @vquery, @equery, :other) }.should raise_error(ArgumentError)
+ end
+
+ it "should accept an optional virtual query" do
+ @collector.vquery.should equal(@vquery)
+ end
+
+ it "should accept an optional exported query" do
+ @collector.equery.should equal(@equery)
+ end
+
+ it "should canonize the type name" do
+ @collector = Puppet::Parser::Collector.new(@scope, "resource::type", @equery, @vquery, @form)
+ @collector.type.should == "Resource::Type"
+ end
+
+ it "should accept an optional resource override" do
+ @collector = Puppet::Parser::Collector.new(@scope, "resource::type", @equery, @vquery, @form)
+ override = { :parameters => "whatever" }
+ @collector.add_override(override)
+ @collector.overrides.should equal(override)
+ end
end
describe Puppet::Parser::Collector, "when collecting specific virtual resources" do
- before do
- @scope = mock 'scope'
- @vquery = mock 'vquery'
- @equery = mock 'equery'
-
- @collector = Puppet::Parser::Collector.new(@scope, "resource_type", @equery, @vquery, :virtual)
- end
-
- it "should not fail when it does not find any resources to collect" do
- @collector.resources = ["File[virtual1]", "File[virtual2]"]
- @scope.stubs(:findresource).returns(false)
- proc { @collector.evaluate }.should_not raise_error
- end
-
- it "should mark matched resources as non-virtual" do
- @collector.resources = ["File[virtual1]", "File[virtual2]"]
- one = stub_everything 'one'
- one.expects(:virtual=).with(false)
-
- @scope.stubs(:findresource).with("File[virtual1]").returns(one)
- @scope.stubs(:findresource).with("File[virtual2]").returns(nil)
- @collector.evaluate
- end
-
- it "should return matched resources" do
- @collector.resources = ["File[virtual1]", "File[virtual2]"]
- one = stub_everything 'one'
- @scope.stubs(:findresource).with("File[virtual1]").returns(one)
- @scope.stubs(:findresource).with("File[virtual2]").returns(nil)
- @collector.evaluate.should == [one]
- end
-
- it "should delete itself from the compile's collection list if it has found all of its resources" do
- @collector.resources = ["File[virtual1]"]
- one = stub_everything 'one'
- @compiler.expects(:delete_collection).with(@collector)
- @scope.expects(:compiler).returns(@compiler)
- @scope.stubs(:findresource).with("File[virtual1]").returns(one)
- @collector.evaluate
- end
-
- it "should not delete itself from the compile's collection list if it has unfound resources" do
- @collector.resources = ["File[virtual1]"]
- one = stub_everything 'one'
- @compiler.expects(:delete_collection).never
- @scope.stubs(:findresource).with("File[virtual1]").returns(nil)
- @collector.evaluate
- end
+ before do
+ @scope = mock 'scope'
+ @vquery = mock 'vquery'
+ @equery = mock 'equery'
+
+ @collector = Puppet::Parser::Collector.new(@scope, "resource_type", @equery, @vquery, :virtual)
+ end
+
+ it "should not fail when it does not find any resources to collect" do
+ @collector.resources = ["File[virtual1]", "File[virtual2]"]
+ @scope.stubs(:findresource).returns(false)
+ proc { @collector.evaluate }.should_not raise_error
+ end
+
+ it "should mark matched resources as non-virtual" do
+ @collector.resources = ["File[virtual1]", "File[virtual2]"]
+ one = stub_everything 'one'
+ one.expects(:virtual=).with(false)
+
+ @scope.stubs(:findresource).with("File[virtual1]").returns(one)
+ @scope.stubs(:findresource).with("File[virtual2]").returns(nil)
+ @collector.evaluate
+ end
+
+ it "should return matched resources" do
+ @collector.resources = ["File[virtual1]", "File[virtual2]"]
+ one = stub_everything 'one'
+ @scope.stubs(:findresource).with("File[virtual1]").returns(one)
+ @scope.stubs(:findresource).with("File[virtual2]").returns(nil)
+ @collector.evaluate.should == [one]
+ end
+
+ it "should delete itself from the compile's collection list if it has found all of its resources" do
+ @collector.resources = ["File[virtual1]"]
+ one = stub_everything 'one'
+ @compiler.expects(:delete_collection).with(@collector)
+ @scope.expects(:compiler).returns(@compiler)
+ @scope.stubs(:findresource).with("File[virtual1]").returns(one)
+ @collector.evaluate
+ end
+
+ it "should not delete itself from the compile's collection list if it has unfound resources" do
+ @collector.resources = ["File[virtual1]"]
+ one = stub_everything 'one'
+ @compiler.expects(:delete_collection).never
+ @scope.stubs(:findresource).with("File[virtual1]").returns(nil)
+ @collector.evaluate
+ end
end
describe Puppet::Parser::Collector, "when collecting virtual and catalog resources" do
- before do
- @scope = mock 'scope'
- @compiler = mock 'compile'
- @scope.stubs(:compiler).returns(@compiler)
- @resource_type = "Mytype"
- @vquery = proc { |res| true }
-
- @collector = Puppet::Parser::Collector.new(@scope, @resource_type, nil, @vquery, :virtual)
- end
+ before do
+ @scope = mock 'scope'
+ @compiler = mock 'compile'
+ @scope.stubs(:compiler).returns(@compiler)
+ @resource_type = "Mytype"
+ @vquery = proc { |res| true }
- it "should find all virtual resources matching the vquery" do
- one = stub_everything 'one', :type => "Mytype", :virtual? => true
- two = stub_everything 'two', :type => "Mytype", :virtual? => true
+ @collector = Puppet::Parser::Collector.new(@scope, @resource_type, nil, @vquery, :virtual)
+ end
- @compiler.expects(:resources).returns([one, two])
+ it "should find all virtual resources matching the vquery" do
+ one = stub_everything 'one', :type => "Mytype", :virtual? => true
+ two = stub_everything 'two', :type => "Mytype", :virtual? => true
- @collector.evaluate.should == [one, two]
- end
+ @compiler.expects(:resources).returns([one, two])
- it "should find all non-virtual resources matching the vquery" do
- one = stub_everything 'one', :type => "Mytype", :virtual? => false
- two = stub_everything 'two', :type => "Mytype", :virtual? => false
+ @collector.evaluate.should == [one, two]
+ end
- @compiler.expects(:resources).returns([one, two])
+ it "should find all non-virtual resources matching the vquery" do
+ one = stub_everything 'one', :type => "Mytype", :virtual? => false
+ two = stub_everything 'two', :type => "Mytype", :virtual? => false
- @collector.evaluate.should == [one, two]
- end
+ @compiler.expects(:resources).returns([one, two])
- it "should mark all matched resources as non-virtual" do
- one = stub_everything 'one', :type => "Mytype", :virtual? => true
+ @collector.evaluate.should == [one, two]
+ end
- one.expects(:virtual=).with(false)
+ it "should mark all matched resources as non-virtual" do
+ one = stub_everything 'one', :type => "Mytype", :virtual? => true
- @compiler.expects(:resources).returns([one])
+ one.expects(:virtual=).with(false)
- @collector.evaluate
- end
+ @compiler.expects(:resources).returns([one])
- it "should return matched resources" do
- one = stub_everything 'one', :type => "Mytype", :virtual? => true
- two = stub_everything 'two', :type => "Mytype", :virtual? => true
+ @collector.evaluate
+ end
- @compiler.expects(:resources).returns([one, two])
+ it "should return matched resources" do
+ one = stub_everything 'one', :type => "Mytype", :virtual? => true
+ two = stub_everything 'two', :type => "Mytype", :virtual? => true
- @collector.evaluate.should == [one, two]
- end
+ @compiler.expects(:resources).returns([one, two])
- it "should return all resources of the correct type if there is no virtual query" do
- one = stub_everything 'one', :type => "Mytype", :virtual? => true
- two = stub_everything 'two', :type => "Mytype", :virtual? => true
+ @collector.evaluate.should == [one, two]
+ end
- one.expects(:virtual=).with(false)
- two.expects(:virtual=).with(false)
+ it "should return all resources of the correct type if there is no virtual query" do
+ one = stub_everything 'one', :type => "Mytype", :virtual? => true
+ two = stub_everything 'two', :type => "Mytype", :virtual? => true
- @compiler.expects(:resources).returns([one, two])
+ one.expects(:virtual=).with(false)
+ two.expects(:virtual=).with(false)
- @collector = Puppet::Parser::Collector.new(@scope, @resource_type, nil, nil, :virtual)
+ @compiler.expects(:resources).returns([one, two])
- @collector.evaluate.should == [one, two]
- end
+ @collector = Puppet::Parser::Collector.new(@scope, @resource_type, nil, nil, :virtual)
- it "should not return or mark resources of a different type" do
- one = stub_everything 'one', :type => "Mytype", :virtual? => true
- two = stub_everything 'two', :type => :other, :virtual? => true
+ @collector.evaluate.should == [one, two]
+ end
- one.expects(:virtual=).with(false)
- two.expects(:virtual=).never
+ it "should not return or mark resources of a different type" do
+ one = stub_everything 'one', :type => "Mytype", :virtual? => true
+ two = stub_everything 'two', :type => :other, :virtual? => true
- @compiler.expects(:resources).returns([one, two])
+ one.expects(:virtual=).with(false)
+ two.expects(:virtual=).never
- @collector.evaluate.should == [one]
- end
+ @compiler.expects(:resources).returns([one, two])
- it "should create a resource with overridden parameters" do
- one = stub_everything 'one', :type => "Mytype", :virtual? => true, :title => "test"
- param = stub 'param'
- @compiler.stubs(:add_override)
+ @collector.evaluate.should == [one]
+ end
- @compiler.expects(:resources).returns([one])
+ it "should create a resource with overridden parameters" do
+ one = stub_everything 'one', :type => "Mytype", :virtual? => true, :title => "test"
+ param = stub 'param'
+ @compiler.stubs(:add_override)
- @collector.add_override(:parameters => param )
- Puppet::Parser::Resource.expects(:new).with { |type, title, h|
- h[:parameters] == param
- }
+ @compiler.expects(:resources).returns([one])
- @collector.evaluate
- end
+ @collector.add_override(:parameters => param )
+ Puppet::Parser::Resource.expects(:new).with { |type, title, h|
+ h[:parameters] == param
+ }
- it "should define a new allow all child_of? on overriden resource" do
- one = stub_everything 'one', :type => "Mytype", :virtual? => true, :title => "test"
- param = stub 'param'
- source = stub 'source'
- @compiler.stubs(:add_override)
+ @collector.evaluate
+ end
- @compiler.expects(:resources).returns([one])
+ it "should define a new allow all child_of? on overriden resource" do
+ one = stub_everything 'one', :type => "Mytype", :virtual? => true, :title => "test"
+ param = stub 'param'
+ source = stub 'source'
+ @compiler.stubs(:add_override)
- @collector.add_override(:parameters => param, :source => source )
- Puppet::Parser::Resource.stubs(:new)
+ @compiler.expects(:resources).returns([one])
- source.expects(:meta_def).with { |name,block| name == :child_of? }
+ @collector.add_override(:parameters => param, :source => source )
+ Puppet::Parser::Resource.stubs(:new)
- @collector.evaluate
- end
+ source.expects(:meta_def).with { |name,block| name == :child_of? }
+ @collector.evaluate
+ end
- it "should not override already overriden resources for this same collection in a previous run" do
- one = stub_everything 'one', :type => "Mytype", :virtual? => true, :title => "test"
- param = stub 'param'
- @compiler.stubs(:add_override)
- @compiler.expects(:resources).at_least(2).returns([one])
+ it "should not override already overriden resources for this same collection in a previous run" do
+ one = stub_everything 'one', :type => "Mytype", :virtual? => true, :title => "test"
+ param = stub 'param'
+ @compiler.stubs(:add_override)
- @collector.add_override(:parameters => param )
- Puppet::Parser::Resource.expects(:new).once.with { |type, title, h|
- h[:parameters] == param
- }
+ @compiler.expects(:resources).at_least(2).returns([one])
- @collector.evaluate
+ @collector.add_override(:parameters => param )
+ Puppet::Parser::Resource.expects(:new).once.with { |type, title, h|
+ h[:parameters] == param
+ }
- @collector.evaluate
- end
+ @collector.evaluate
- it "should not return resources that were collected in a previous run of this collector" do
- one = stub_everything 'one', :type => "Mytype", :virtual? => true, :title => "test"
- @compiler.stubs(:resources).returns([one])
+ @collector.evaluate
+ end
- @collector.evaluate
+ it "should not return resources that were collected in a previous run of this collector" do
+ one = stub_everything 'one', :type => "Mytype", :virtual? => true, :title => "test"
+ @compiler.stubs(:resources).returns([one])
- @collector.evaluate.should be_false
- end
+ @collector.evaluate
+ @collector.evaluate.should be_false
+ end
- it "should tell the compiler about the overriden resources" do
- one = stub_everything 'one', :type => "Mytype", :virtual? => true, :title => "test"
- param = stub 'param'
- one.expects(:virtual=).with(false)
- @compiler.expects(:resources).returns([one])
- @collector.add_override(:parameters => param )
- Puppet::Parser::Resource.stubs(:new).returns("whatever")
+ it "should tell the compiler about the overriden resources" do
+ one = stub_everything 'one', :type => "Mytype", :virtual? => true, :title => "test"
+ param = stub 'param'
- @compiler.expects(:add_override).with("whatever")
+ one.expects(:virtual=).with(false)
+ @compiler.expects(:resources).returns([one])
+ @collector.add_override(:parameters => param )
+ Puppet::Parser::Resource.stubs(:new).returns("whatever")
- @collector.evaluate
- end
+ @compiler.expects(:add_override).with("whatever")
- it "should not return or mark non-matching resources" do
- @collector.vquery = proc { |res| res.name == :one }
+ @collector.evaluate
+ end
- one = stub_everything 'one', :name => :one, :type => "Mytype", :virtual? => true
- two = stub_everything 'two', :name => :two, :type => "Mytype", :virtual? => true
+ it "should not return or mark non-matching resources" do
+ @collector.vquery = proc { |res| res.name == :one }
- one.expects(:virtual=).with(false)
- two.expects(:virtual=).never
+ one = stub_everything 'one', :name => :one, :type => "Mytype", :virtual? => true
+ two = stub_everything 'two', :name => :two, :type => "Mytype", :virtual? => true
- @compiler.expects(:resources).returns([one, two])
+ one.expects(:virtual=).with(false)
+ two.expects(:virtual=).never
- @collector.evaluate.should == [one]
- end
+ @compiler.expects(:resources).returns([one, two])
+
+ @collector.evaluate.should == [one]
+ end
end
describe Puppet::Parser::Collector, "when collecting exported resources" do
- confine "Cannot test Rails integration without ActiveRecord" => Puppet.features.rails?
+ confine "Cannot test Rails integration without ActiveRecord" => Puppet.features.rails?
- before do
- @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode"))
- @scope = Puppet::Parser::Scope.new :compiler => @compiler
- @resource_type = "Mytype"
- @equery = "test = true"
- @vquery = proc { |r| true }
+ before do
+ @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode"))
+ @scope = Puppet::Parser::Scope.new :compiler => @compiler
+ @resource_type = "Mytype"
+ @equery = "test = true"
+ @vquery = proc { |r| true }
- res = stub("resource 1")
- res.stubs(:type).returns @resource_type
- Puppet::Resource.stubs(:new).returns res
+ res = stub("resource 1")
+ res.stubs(:type).returns @resource_type
+ Puppet::Resource.stubs(:new).returns res
- Puppet.settings.stubs(:value).with(:storeconfigs).returns true
- Puppet.settings.stubs(:value).with(:environment).returns "production"
+ Puppet.settings.stubs(:value).with(:storeconfigs).returns true
+ Puppet.settings.stubs(:value).with(:environment).returns "production"
- @collector = Puppet::Parser::Collector.new(@scope, @resource_type, @equery, @vquery, :exported)
- end
+ @collector = Puppet::Parser::Collector.new(@scope, @resource_type, @equery, @vquery, :exported)
+ end
- # Stub most of our interface to Rails.
- def stub_rails(everything = false)
- ActiveRecord::Base.stubs(:connected?).returns(false)
- Puppet::Rails.stubs(:init)
- if everything
- Puppet::Rails::Host.stubs(:find_by_name).returns(nil)
- Puppet::Rails::Resource.stubs(:find).returns([])
- end
+ # Stub most of our interface to Rails.
+ def stub_rails(everything = false)
+ ActiveRecord::Base.stubs(:connected?).returns(false)
+ Puppet::Rails.stubs(:init)
+ if everything
+ Puppet::Rails::Host.stubs(:find_by_name).returns(nil)
+ Puppet::Rails::Resource.stubs(:find).returns([])
end
+ end
- it "should just return false if :storeconfigs is not enabled" do
- Puppet.settings.expects(:value).with(:storeconfigs).returns false
- @collector.evaluate.should be_false
- end
+ it "should just return false if :storeconfigs is not enabled" do
+ Puppet.settings.expects(:value).with(:storeconfigs).returns false
+ @collector.evaluate.should be_false
+ end
- it "should use initialize the Rails support if ActiveRecord is not connected" do
- @compiler.stubs(:resources).returns([])
- ActiveRecord::Base.expects(:connected?).returns(false)
- Puppet::Rails.expects(:init)
- Puppet::Rails::Host.stubs(:find_by_name).returns(nil)
- Puppet::Rails::Resource.stubs(:find).returns([])
+ it "should use initialize the Rails support if ActiveRecord is not connected" do
+ @compiler.stubs(:resources).returns([])
+ ActiveRecord::Base.expects(:connected?).returns(false)
+ Puppet::Rails.expects(:init)
+ Puppet::Rails::Host.stubs(:find_by_name).returns(nil)
+ Puppet::Rails::Resource.stubs(:find).returns([])
- @collector.evaluate
- end
+ @collector.evaluate
+ end
- it "should return all matching resources from the current compile and mark them non-virtual and non-exported" do
- stub_rails(true)
+ it "should return all matching resources from the current compile and mark them non-virtual and non-exported" do
+ stub_rails(true)
- one = stub 'one', :type => "Mytype", :virtual? => true, :exported? => true, :ref => "one"
- two = stub 'two', :type => "Mytype", :virtual? => true, :exported? => true, :ref => "two"
+ one = stub 'one', :type => "Mytype", :virtual? => true, :exported? => true, :ref => "one"
+ two = stub 'two', :type => "Mytype", :virtual? => true, :exported? => true, :ref => "two"
- one.stubs(:exported=)
- one.stubs(:virtual=)
- two.stubs(:exported=)
- two.stubs(:virtual=)
+ one.stubs(:exported=)
+ one.stubs(:virtual=)
+ two.stubs(:exported=)
+ two.stubs(:virtual=)
- @compiler.expects(:resources).returns([one, two])
+ @compiler.expects(:resources).returns([one, two])
- @collector.evaluate.should == [one, two]
- end
+ @collector.evaluate.should == [one, two]
+ end
- it "should mark all returned resources as not virtual" do
- stub_rails(true)
+ it "should mark all returned resources as not virtual" do
+ stub_rails(true)
- one = stub 'one', :type => "Mytype", :virtual? => true, :exported? => true, :ref => "one"
+ one = stub 'one', :type => "Mytype", :virtual? => true, :exported? => true, :ref => "one"
- one.stubs(:exported=)
- one.expects(:virtual=).with(false)
+ one.stubs(:exported=)
+ one.expects(:virtual=).with(false)
- @compiler.expects(:resources).returns([one])
+ @compiler.expects(:resources).returns([one])
- @collector.evaluate.should == [one]
- end
+ @collector.evaluate.should == [one]
+ end
- it "should convert all found resources into parser resources" do
- stub_rails
- Puppet::Rails::Host.stubs(:find_by_name).returns(nil)
+ it "should convert all found resources into parser resources" do
+ stub_rails
+ Puppet::Rails::Host.stubs(:find_by_name).returns(nil)
- one = stub 'one', :restype => "Mytype", :title => "one", :virtual? => true, :exported? => true, :ref => "one"
- Puppet::Rails::Resource.stubs(:find).returns([one])
+ one = stub 'one', :restype => "Mytype", :title => "one", :virtual? => true, :exported? => true, :ref => "one"
+ Puppet::Rails::Resource.stubs(:find).returns([one])
- resource = mock 'resource'
- one.expects(:to_resource).with(@scope).returns(resource)
- resource.stubs(:exported=)
- resource.stubs(:virtual=)
- resource.stubs(:ref)
+ resource = mock 'resource'
+ one.expects(:to_resource).with(@scope).returns(resource)
+ resource.stubs(:exported=)
+ resource.stubs(:virtual=)
+ resource.stubs(:ref)
- @compiler.stubs(:resources).returns([])
- @scope.stubs(:findresource).returns(nil)
+ @compiler.stubs(:resources).returns([])
+ @scope.stubs(:findresource).returns(nil)
- @compiler.stubs(:add_resource)
+ @compiler.stubs(:add_resource)
- @collector.evaluate.should == [resource]
- end
+ @collector.evaluate.should == [resource]
+ end
- it "should override all exported collected resources if collector has an override" do
- stub_rails
- Puppet::Rails::Host.stubs(:find_by_name).returns(nil)
+ it "should override all exported collected resources if collector has an override" do
+ stub_rails
+ Puppet::Rails::Host.stubs(:find_by_name).returns(nil)
- one = stub 'one', :restype => "Mytype", :title => "one", :virtual? => true, :exported? => true, :ref => "one"
- Puppet::Rails::Resource.stubs(:find).returns([one])
+ one = stub 'one', :restype => "Mytype", :title => "one", :virtual? => true, :exported? => true, :ref => "one"
+ Puppet::Rails::Resource.stubs(:find).returns([one])
- resource = mock 'resource', :type => "Mytype"
- one.expects(:to_resource).with(@scope).returns(resource)
- resource.stubs(:exported=)
- resource.stubs(:virtual=)
- resource.stubs(:ref)
- resource.stubs(:title)
+ resource = mock 'resource', :type => "Mytype"
+ one.expects(:to_resource).with(@scope).returns(resource)
+ resource.stubs(:exported=)
+ resource.stubs(:virtual=)
+ resource.stubs(:ref)
+ resource.stubs(:title)
- @compiler.stubs(:resources).returns([])
- @scope.stubs(:findresource).returns(nil)
+ @compiler.stubs(:resources).returns([])
+ @scope.stubs(:findresource).returns(nil)
- param = stub 'param'
- @compiler.stubs(:add_override)
- @compiler.stubs(:add_resource)
+ param = stub 'param'
+ @compiler.stubs(:add_override)
+ @compiler.stubs(:add_resource)
- @collector.add_override(:parameters => param )
- Puppet::Parser::Resource.expects(:new).once.with { |type, title, h|
- h[:parameters] == param
- }
+ @collector.add_override(:parameters => param )
+ Puppet::Parser::Resource.expects(:new).once.with { |type, title, h|
+ h[:parameters] == param
+ }
- @collector.evaluate
- end
+ @collector.evaluate
+ end
- it "should store converted resources in the compile's resource list" do
- stub_rails
- Puppet::Rails::Host.stubs(:find_by_name).returns(nil)
+ it "should store converted resources in the compile's resource list" do
+ stub_rails
+ Puppet::Rails::Host.stubs(:find_by_name).returns(nil)
- one = stub 'one', :restype => "Mytype", :title => "one", :virtual? => true, :exported? => true, :ref => "one"
- Puppet::Rails::Resource.stubs(:find).returns([one])
+ one = stub 'one', :restype => "Mytype", :title => "one", :virtual? => true, :exported? => true, :ref => "one"
+ Puppet::Rails::Resource.stubs(:find).returns([one])
- resource = mock 'resource'
- one.expects(:to_resource).with(@scope).returns(resource)
- resource.stubs(:exported=)
- resource.stubs(:virtual=)
- resource.stubs(:ref)
+ resource = mock 'resource'
+ one.expects(:to_resource).with(@scope).returns(resource)
+ resource.stubs(:exported=)
+ resource.stubs(:virtual=)
+ resource.stubs(:ref)
- @compiler.stubs(:resources).returns([])
- @scope.stubs(:findresource).returns(nil)
+ @compiler.stubs(:resources).returns([])
+ @scope.stubs(:findresource).returns(nil)
- @compiler.expects(:add_resource).with(@scope, resource)
+ @compiler.expects(:add_resource).with(@scope, resource)
- @collector.evaluate.should == [resource]
- end
+ @collector.evaluate.should == [resource]
+ end
- # This way one host doesn't store another host's resources as exported.
- it "should mark resources collected from the database as not exported" do
- stub_rails
- Puppet::Rails::Host.stubs(:find_by_name).returns(nil)
+ # This way one host doesn't store another host's resources as exported.
+ it "should mark resources collected from the database as not exported" do
+ stub_rails
+ Puppet::Rails::Host.stubs(:find_by_name).returns(nil)
- one = stub 'one', :restype => "Mytype", :title => "one", :virtual? => true, :exported? => true, :ref => "one"
- Puppet::Rails::Resource.stubs(:find).returns([one])
+ one = stub 'one', :restype => "Mytype", :title => "one", :virtual? => true, :exported? => true, :ref => "one"
+ Puppet::Rails::Resource.stubs(:find).returns([one])
- resource = mock 'resource'
- one.expects(:to_resource).with(@scope).returns(resource)
- resource.expects(:exported=).with(false)
- resource.stubs(:virtual=)
- resource.stubs(:ref)
+ resource = mock 'resource'
+ one.expects(:to_resource).with(@scope).returns(resource)
+ resource.expects(:exported=).with(false)
+ resource.stubs(:virtual=)
+ resource.stubs(:ref)
- @compiler.stubs(:resources).returns([])
- @scope.stubs(:findresource).returns(nil)
+ @compiler.stubs(:resources).returns([])
+ @scope.stubs(:findresource).returns(nil)
- @compiler.stubs(:add_resource)
+ @compiler.stubs(:add_resource)
- @collector.evaluate
- end
+ @collector.evaluate
+ end
- it "should fail if an equivalent resource already exists in the compile" do
- stub_rails
- Puppet::Rails::Host.stubs(:find_by_name).returns(nil)
+ it "should fail if an equivalent resource already exists in the compile" do
+ stub_rails
+ Puppet::Rails::Host.stubs(:find_by_name).returns(nil)
- rails = stub 'one', :restype => "Mytype", :title => "one", :virtual? => true, :exported? => true, :id => 1, :ref => "yay"
- inmemory = stub 'one', :type => "Mytype", :virtual? => true, :exported? => true, :rails_id => 2
+ rails = stub 'one', :restype => "Mytype", :title => "one", :virtual? => true, :exported? => true, :id => 1, :ref => "yay"
+ inmemory = stub 'one', :type => "Mytype", :virtual? => true, :exported? => true, :rails_id => 2
- Puppet::Rails::Resource.stubs(:find).returns([rails])
+ Puppet::Rails::Resource.stubs(:find).returns([rails])
- resource = mock 'resource'
+ resource = mock 'resource'
- @compiler.stubs(:resources).returns([])
- @scope.stubs(:findresource).returns(inmemory)
+ @compiler.stubs(:resources).returns([])
+ @scope.stubs(:findresource).returns(inmemory)
- @compiler.stubs(:add_resource)
+ @compiler.stubs(:add_resource)
- proc { @collector.evaluate }.should raise_error(Puppet::ParseError)
- end
+ proc { @collector.evaluate }.should raise_error(Puppet::ParseError)
+ end
- it "should ignore exported resources that match already-collected resources" do
- stub_rails
- Puppet::Rails::Host.stubs(:find_by_name).returns(nil)
+ it "should ignore exported resources that match already-collected resources" do
+ stub_rails
+ Puppet::Rails::Host.stubs(:find_by_name).returns(nil)
- rails = stub 'one', :restype => "Mytype", :title => "one", :virtual? => true, :exported? => true, :id => 1, :ref => "yay"
- inmemory = stub 'one', :type => "Mytype", :virtual? => true, :exported? => true, :rails_id => 1
+ rails = stub 'one', :restype => "Mytype", :title => "one", :virtual? => true, :exported? => true, :id => 1, :ref => "yay"
+ inmemory = stub 'one', :type => "Mytype", :virtual? => true, :exported? => true, :rails_id => 1
- Puppet::Rails::Resource.stubs(:find).returns([rails])
+ Puppet::Rails::Resource.stubs(:find).returns([rails])
- resource = mock 'resource'
+ resource = mock 'resource'
- @compiler.stubs(:resources).returns([])
- @scope.stubs(:findresource).returns(inmemory)
+ @compiler.stubs(:resources).returns([])
+ @scope.stubs(:findresource).returns(inmemory)
- @compiler.stubs(:add_resource)
+ @compiler.stubs(:add_resource)
- proc { @collector.evaluate }.should_not raise_error(Puppet::ParseError)
- end
+ proc { @collector.evaluate }.should_not raise_error(Puppet::ParseError)
+ end
end
describe Puppet::Parser::Collector, "when building its ActiveRecord query for collecting exported resources" do
- confine "Cannot test Rails integration without ActiveRecord" => Puppet.features.rails?
-
- before do
- @scope = stub 'scope', :host => "myhost", :debug => nil
- @compiler = mock 'compile'
- @scope.stubs(:compiler).returns(@compiler)
- @resource_type = "Mytype"
- @equery = nil
- @vquery = proc { |r| true }
-
- @resource = stub_everything 'collected'
-
- @collector = Puppet::Parser::Collector.new(@scope, @resource_type, @equery, @vquery, :exported)
- @collector.stubs(:exported_resource).with(@resource).returns(@resource)
- @compiler.stubs(:resources).returns([])
-
- ActiveRecord::Base.stubs(:connected?).returns(false)
-
- Puppet::Rails.stubs(:init)
- Puppet::Rails::Host.stubs(:find_by_name).returns(nil)
- Puppet::Rails::Resource.stubs(:find).returns([])
-
- Puppet.settings.stubs(:value).with(:storeconfigs).returns true
- end
-
- it "should exclude all resources from the host if ActiveRecord contains information for this host" do
- @host = mock 'host'
- @host.stubs(:id).returns 5
-
- Puppet::Rails::Host.expects(:find_by_name).with(@scope.host).returns(@host)
-
- Puppet::Rails::Resource.stubs(:find).with { |*arguments|
- options = arguments[1]
- options[:conditions][0] =~ /^host_id != \?/ and options[:conditions][1] == 5
- }.returns([@resource])
-
- @collector.evaluate.should == [@resource]
- end
-
- it "should join with parameter names, parameter values when querying ActiveRecord" do
- @collector.equery = "param_names.name = title"
- Puppet::Rails::Resource.stubs(:find).with { |*arguments|
- options = arguments[1]
- options[:joins] == {:param_values => :param_name}
- }.returns([@resource])
-
- @collector.evaluate.should == [@resource]
- end
-
- it "should join with tag tables when querying ActiveRecord with a tag exported query" do
- @collector.equery = "puppet_tags.name = test"
- Puppet::Rails::Resource.stubs(:find).with { |*arguments|
- options = arguments[1]
- options[:joins] == {:resource_tags => :puppet_tag}
- }.returns([@resource])
-
- @collector.evaluate.should == [@resource]
- end
-
- it "should not join parameters when querying ActiveRecord with a tag exported query" do
- @collector.equery = "puppet_tags.name = test"
- Puppet::Rails::Resource.stubs(:find).with { |*arguments|
- options = arguments[1]
- options[:joins] == {:param_values => :param_name}
- }.returns([@resource])
-
- @collector.evaluate.should be_false
- end
-
- it "should only search for exported resources with the matching type" do
- Puppet::Rails::Resource.stubs(:find).with { |*arguments|
- options = arguments[1]
- options[:conditions][0].include?("(exported=? AND restype=?)") and options[:conditions][1] == true and options[:conditions][2] == "Mytype"
- }.returns([@resource])
-
- @collector.evaluate.should == [@resource]
- end
-
- it "should include the export query if one is provided" do
- @collector.equery = "test = true"
- Puppet::Rails::Resource.stubs(:find).with { |*arguments|
- options = arguments[1]
- options[:conditions][0].include?("test = true")
- }.returns([@resource])
-
- @collector.evaluate.should == [@resource]
- end
+ confine "Cannot test Rails integration without ActiveRecord" => Puppet.features.rails?
+
+ before do
+ @scope = stub 'scope', :host => "myhost", :debug => nil
+ @compiler = mock 'compile'
+ @scope.stubs(:compiler).returns(@compiler)
+ @resource_type = "Mytype"
+ @equery = nil
+ @vquery = proc { |r| true }
+
+ @resource = stub_everything 'collected'
+
+ @collector = Puppet::Parser::Collector.new(@scope, @resource_type, @equery, @vquery, :exported)
+ @collector.stubs(:exported_resource).with(@resource).returns(@resource)
+ @compiler.stubs(:resources).returns([])
+
+ ActiveRecord::Base.stubs(:connected?).returns(false)
+
+ Puppet::Rails.stubs(:init)
+ Puppet::Rails::Host.stubs(:find_by_name).returns(nil)
+ Puppet::Rails::Resource.stubs(:find).returns([])
+
+ Puppet.settings.stubs(:value).with(:storeconfigs).returns true
+ end
+
+ it "should exclude all resources from the host if ActiveRecord contains information for this host" do
+ @host = mock 'host'
+ @host.stubs(:id).returns 5
+
+ Puppet::Rails::Host.expects(:find_by_name).with(@scope.host).returns(@host)
+
+ Puppet::Rails::Resource.stubs(:find).with { |*arguments|
+ options = arguments[1]
+ options[:conditions][0] =~ /^host_id != \?/ and options[:conditions][1] == 5
+ }.returns([@resource])
+
+ @collector.evaluate.should == [@resource]
+ end
+
+ it "should join with parameter names, parameter values when querying ActiveRecord" do
+ @collector.equery = "param_names.name = title"
+ Puppet::Rails::Resource.stubs(:find).with { |*arguments|
+ options = arguments[1]
+ options[:joins] == {:param_values => :param_name}
+ }.returns([@resource])
+
+ @collector.evaluate.should == [@resource]
+ end
+
+ it "should join with tag tables when querying ActiveRecord with a tag exported query" do
+ @collector.equery = "puppet_tags.name = test"
+ Puppet::Rails::Resource.stubs(:find).with { |*arguments|
+ options = arguments[1]
+ options[:joins] == {:resource_tags => :puppet_tag}
+ }.returns([@resource])
+
+ @collector.evaluate.should == [@resource]
+ end
+
+ it "should not join parameters when querying ActiveRecord with a tag exported query" do
+ @collector.equery = "puppet_tags.name = test"
+ Puppet::Rails::Resource.stubs(:find).with { |*arguments|
+ options = arguments[1]
+ options[:joins] == {:param_values => :param_name}
+ }.returns([@resource])
+
+ @collector.evaluate.should be_false
+ end
+
+ it "should only search for exported resources with the matching type" do
+ Puppet::Rails::Resource.stubs(:find).with { |*arguments|
+ options = arguments[1]
+ options[:conditions][0].include?("(exported=? AND restype=?)") and options[:conditions][1] == true and options[:conditions][2] == "Mytype"
+ }.returns([@resource])
+
+ @collector.evaluate.should == [@resource]
+ end
+
+ it "should include the export query if one is provided" do
+ @collector.equery = "test = true"
+ Puppet::Rails::Resource.stubs(:find).with { |*arguments|
+ options = arguments[1]
+ options[:conditions][0].include?("test = true")
+ }.returns([@resource])
+
+ @collector.evaluate.should == [@resource]
+ end
end
diff --git a/spec/unit/parser/compiler_spec.rb b/spec/unit/parser/compiler_spec.rb
index 872cd79..a3fe56c 100755
--- a/spec/unit/parser/compiler_spec.rb
+++ b/spec/unit/parser/compiler_spec.rb
@@ -3,752 +3,752 @@
require File.dirname(__FILE__) + '/../../spec_helper'
class CompilerTestResource
- attr_accessor :builtin, :virtual, :evaluated, :type, :title
+ attr_accessor :builtin, :virtual, :evaluated, :type, :title
- def initialize(type, title)
- @type = type
- @title = title
- end
+ def initialize(type, title)
+ @type = type
+ @title = title
+ end
- def [](attr)
- return nil if attr == :stage
- :main
- end
+ def [](attr)
+ return nil if attr == :stage
+ :main
+ end
- def ref
- "#{type.to_s.capitalize}[#{title}]"
- end
+ def ref
+ "#{type.to_s.capitalize}[#{title}]"
+ end
- def evaluated?
- @evaluated
- end
+ def evaluated?
+ @evaluated
+ end
- def builtin?
- @builtin
- end
+ def builtin?
+ @builtin
+ end
- def virtual?
- @virtual
- end
+ def virtual?
+ @virtual
+ end
- def evaluate
- end
+ def evaluate
+ end
end
describe Puppet::Parser::Compiler do
- def resource(type, title)
- Puppet::Parser::Resource.new(type, title, :scope => @scope)
+ def resource(type, title)
+ Puppet::Parser::Resource.new(type, title, :scope => @scope)
+ end
+
+ before :each do
+ @node = Puppet::Node.new "testnode"
+ @known_resource_types = Puppet::Resource::TypeCollection.new "development"
+ @compiler = Puppet::Parser::Compiler.new(@node)
+ @scope = Puppet::Parser::Scope.new(:compiler => @compiler, :source => stub('source'))
+ @scope_resource = Puppet::Parser::Resource.new(:file, "/my/file", :scope => @scope)
+ @scope.resource = @scope_resource
+ @compiler.environment.stubs(:known_resource_types).returns @known_resource_types
+ end
+
+ it "should have a class method that compiles, converts, and returns a catalog" do
+ compiler = stub 'compiler'
+ Puppet::Parser::Compiler.expects(:new).with(@node).returns compiler
+ catalog = stub 'catalog'
+ compiler.expects(:compile).returns catalog
+ converted_catalog = stub 'converted_catalog'
+ catalog.expects(:to_resource).returns converted_catalog
+
+ Puppet::Parser::Compiler.compile(@node).should equal(converted_catalog)
+ end
+
+ it "should fail intelligently when a class-level compile fails" do
+ Puppet::Parser::Compiler.expects(:new).raises ArgumentError
+ lambda { Puppet::Parser::Compiler.compile(@node) }.should raise_error(Puppet::Error)
+ end
+
+ it "should use the node's environment as its environment" do
+ @compiler.environment.should equal(@node.environment)
+ end
+
+ it "should include the resource type collection helper" do
+ Puppet::Parser::Compiler.ancestors.should be_include(Puppet::Resource::TypeCollectionHelper)
+ end
+
+ it "should be able to return a class list containing all added classes" do
+ @compiler.add_class ""
+ @compiler.add_class "one"
+ @compiler.add_class "two"
+
+ @compiler.classlist.sort.should == %w{one two}.sort
+ end
+
+ describe "when initializing" do
+
+ it "should set its node attribute" do
+ @compiler.node.should equal(@node)
end
-
- before :each do
- @node = Puppet::Node.new "testnode"
- @known_resource_types = Puppet::Resource::TypeCollection.new "development"
- @compiler = Puppet::Parser::Compiler.new(@node)
- @scope = Puppet::Parser::Scope.new(:compiler => @compiler, :source => stub('source'))
- @scope_resource = Puppet::Parser::Resource.new(:file, "/my/file", :scope => @scope)
- @scope.resource = @scope_resource
- @compiler.environment.stubs(:known_resource_types).returns @known_resource_types
+ it "should detect when ast nodes are absent" do
+ @compiler.ast_nodes?.should be_false
end
- it "should have a class method that compiles, converts, and returns a catalog" do
- compiler = stub 'compiler'
- Puppet::Parser::Compiler.expects(:new).with(@node).returns compiler
- catalog = stub 'catalog'
- compiler.expects(:compile).returns catalog
- converted_catalog = stub 'converted_catalog'
- catalog.expects(:to_resource).returns converted_catalog
-
- Puppet::Parser::Compiler.compile(@node).should equal(converted_catalog)
+ it "should detect when ast nodes are present" do
+ @known_resource_types.expects(:nodes?).returns true
+ @compiler.ast_nodes?.should be_true
end
- it "should fail intelligently when a class-level compile fails" do
- Puppet::Parser::Compiler.expects(:new).raises ArgumentError
- lambda { Puppet::Parser::Compiler.compile(@node) }.should raise_error(Puppet::Error)
+ it "should copy the known_resource_types version to the catalog" do
+ @compiler.catalog.version.should == @known_resource_types.version
end
- it "should use the node's environment as its environment" do
- @compiler.environment.should equal(@node.environment)
+ it "should copy any node classes into the class list" do
+ node = Puppet::Node.new("mynode")
+ node.classes = %w{foo bar}
+ compiler = Puppet::Parser::Compiler.new(node)
+
+ compiler.classlist.should include("foo")
+ compiler.classlist.should include("bar")
end
- it "should include the resource type collection helper" do
- Puppet::Parser::Compiler.ancestors.should be_include(Puppet::Resource::TypeCollectionHelper)
+ it "should add a 'main' stage to the catalog" do
+ @compiler.catalog.resource(:stage, :main).should be_instance_of(Puppet::Parser::Resource)
end
+ end
- it "should be able to return a class list containing all added classes" do
- @compiler.add_class ""
- @compiler.add_class "one"
- @compiler.add_class "two"
+ describe "when managing scopes" do
- @compiler.classlist.sort.should == %w{one two}.sort
+ it "should create a top scope" do
+ @compiler.topscope.should be_instance_of(Puppet::Parser::Scope)
end
- describe "when initializing" do
-
- it "should set its node attribute" do
- @compiler.node.should equal(@node)
- end
- it "should detect when ast nodes are absent" do
- @compiler.ast_nodes?.should be_false
- end
+ it "should be able to create new scopes" do
+ @compiler.newscope(@compiler.topscope).should be_instance_of(Puppet::Parser::Scope)
+ end
- it "should detect when ast nodes are present" do
- @known_resource_types.expects(:nodes?).returns true
- @compiler.ast_nodes?.should be_true
- end
+ it "should correctly set the level of newly created scopes" do
+ @compiler.newscope(@compiler.topscope, :level => 5).level.should == 5
+ end
- it "should copy the known_resource_types version to the catalog" do
- @compiler.catalog.version.should == @known_resource_types.version
- end
+ it "should set the parent scope of the new scope to be the passed-in parent" do
+ scope = mock 'scope'
+ newscope = @compiler.newscope(scope)
- it "should copy any node classes into the class list" do
- node = Puppet::Node.new("mynode")
- node.classes = %w{foo bar}
- compiler = Puppet::Parser::Compiler.new(node)
+ newscope.parent.should equal(scope)
+ end
- compiler.classlist.should include("foo")
- compiler.classlist.should include("bar")
- end
+ it "should set the parent scope of the new scope to its topscope if the parent passed in is nil" do
+ scope = mock 'scope'
+ newscope = @compiler.newscope(nil)
- it "should add a 'main' stage to the catalog" do
- @compiler.catalog.resource(:stage, :main).should be_instance_of(Puppet::Parser::Resource)
- end
+ newscope.parent.should equal(@compiler.topscope)
end
+ end
- describe "when managing scopes" do
-
- it "should create a top scope" do
- @compiler.topscope.should be_instance_of(Puppet::Parser::Scope)
- end
+ describe "when compiling" do
- it "should be able to create new scopes" do
- @compiler.newscope(@compiler.topscope).should be_instance_of(Puppet::Parser::Scope)
- end
+ def compile_methods
+ [:set_node_parameters, :evaluate_main, :evaluate_ast_node, :evaluate_node_classes, :evaluate_generators, :fail_on_unevaluated,
+ :finish, :store, :extract, :evaluate_relationships]
+ end
- it "should correctly set the level of newly created scopes" do
- @compiler.newscope(@compiler.topscope, :level => 5).level.should == 5
- end
+ # Stub all of the main compile methods except the ones we're specifically interested in.
+ def compile_stub(*except)
+ (compile_methods - except).each { |m| @compiler.stubs(m) }
+ end
- it "should set the parent scope of the new scope to be the passed-in parent" do
- scope = mock 'scope'
- newscope = @compiler.newscope(scope)
+ it "should set node parameters as variables in the top scope" do
+ params = {"a" => "b", "c" => "d"}
+ @node.stubs(:parameters).returns(params)
+ compile_stub(:set_node_parameters)
+ @compiler.compile
+ @compiler.topscope.lookupvar("a").should == "b"
+ @compiler.topscope.lookupvar("c").should == "d"
+ end
- newscope.parent.should equal(scope)
- end
+ it "should set the client and server versions on the catalog" do
+ params = {"clientversion" => "2", "serverversion" => "3"}
+ @node.stubs(:parameters).returns(params)
+ compile_stub(:set_node_parameters)
+ @compiler.compile
+ @compiler.catalog.client_version.should == "2"
+ @compiler.catalog.server_version.should == "3"
+ end
- it "should set the parent scope of the new scope to its topscope if the parent passed in is nil" do
- scope = mock 'scope'
- newscope = @compiler.newscope(nil)
+ it "should evaluate any existing classes named in the node" do
+ classes = %w{one two three four}
+ main = stub 'main'
+ one = stub 'one', :name => "one"
+ three = stub 'three', :name => "three"
+ @node.stubs(:name).returns("whatever")
+ @node.stubs(:classes).returns(classes)
- newscope.parent.should equal(@compiler.topscope)
- end
+ @compiler.expects(:evaluate_classes).with(classes, @compiler.topscope)
+ @compiler.class.publicize_methods(:evaluate_node_classes) { @compiler.evaluate_node_classes }
end
- describe "when compiling" do
+ it "should evaluate the main class if it exists" do
+ compile_stub(:evaluate_main)
+ main_class = @known_resource_types.add Puppet::Resource::Type.new(:hostclass, "")
+ main_class.expects(:evaluate_code).with { |r| r.is_a?(Puppet::Parser::Resource) }
+ @compiler.topscope.expects(:source=).with(main_class)
- def compile_methods
- [:set_node_parameters, :evaluate_main, :evaluate_ast_node, :evaluate_node_classes, :evaluate_generators, :fail_on_unevaluated,
- :finish, :store, :extract, :evaluate_relationships]
- end
-
- # Stub all of the main compile methods except the ones we're specifically interested in.
- def compile_stub(*except)
- (compile_methods - except).each { |m| @compiler.stubs(m) }
- end
+ @compiler.compile
+ end
- it "should set node parameters as variables in the top scope" do
- params = {"a" => "b", "c" => "d"}
- @node.stubs(:parameters).returns(params)
- compile_stub(:set_node_parameters)
- @compiler.compile
- @compiler.topscope.lookupvar("a").should == "b"
- @compiler.topscope.lookupvar("c").should == "d"
- end
+ it "should create a new, empty 'main' if no main class exists" do
+ compile_stub(:evaluate_main)
+ @compiler.compile
+ @known_resource_types.find_hostclass([""], "").should be_instance_of(Puppet::Resource::Type)
+ end
- it "should set the client and server versions on the catalog" do
- params = {"clientversion" => "2", "serverversion" => "3"}
- @node.stubs(:parameters).returns(params)
- compile_stub(:set_node_parameters)
- @compiler.compile
- @compiler.catalog.client_version.should == "2"
- @compiler.catalog.server_version.should == "3"
- end
+ it "should add an edge between the main stage and main class" do
+ @compiler.compile
+ (stage = @compiler.catalog.resource(:stage, "main")).should be_instance_of(Puppet::Parser::Resource)
+ (klass = @compiler.catalog.resource(:class, "")).should be_instance_of(Puppet::Parser::Resource)
- it "should evaluate any existing classes named in the node" do
- classes = %w{one two three four}
- main = stub 'main'
- one = stub 'one', :name => "one"
- three = stub 'three', :name => "three"
- @node.stubs(:name).returns("whatever")
- @node.stubs(:classes).returns(classes)
+ @compiler.catalog.edge?(stage, klass).should be_true
+ end
- @compiler.expects(:evaluate_classes).with(classes, @compiler.topscope)
- @compiler.class.publicize_methods(:evaluate_node_classes) { @compiler.evaluate_node_classes }
- end
+ it "should evaluate any node classes" do
+ @node.stubs(:classes).returns(%w{one two three four})
+ @compiler.expects(:evaluate_classes).with(%w{one two three four}, @compiler.topscope)
+ @compiler.send(:evaluate_node_classes)
+ end
- it "should evaluate the main class if it exists" do
- compile_stub(:evaluate_main)
- main_class = @known_resource_types.add Puppet::Resource::Type.new(:hostclass, "")
- main_class.expects(:evaluate_code).with { |r| r.is_a?(Puppet::Parser::Resource) }
- @compiler.topscope.expects(:source=).with(main_class)
+ it "should evaluate all added collections" do
+ colls = []
+ # And when the collections fail to evaluate.
+ colls << mock("coll1-false")
+ colls << mock("coll2-false")
+ colls.each { |c| c.expects(:evaluate).returns(false) }
- @compiler.compile
- end
+ @compiler.add_collection(colls[0])
+ @compiler.add_collection(colls[1])
- it "should create a new, empty 'main' if no main class exists" do
- compile_stub(:evaluate_main)
- @compiler.compile
- @known_resource_types.find_hostclass([""], "").should be_instance_of(Puppet::Resource::Type)
- end
+ compile_stub(:evaluate_generators)
+ @compiler.compile
+ end
- it "should add an edge between the main stage and main class" do
- @compiler.compile
- (stage = @compiler.catalog.resource(:stage, "main")).should be_instance_of(Puppet::Parser::Resource)
- (klass = @compiler.catalog.resource(:class, "")).should be_instance_of(Puppet::Parser::Resource)
+ it "should ignore builtin resources" do
+ resource = resource(:file, "testing")
- @compiler.catalog.edge?(stage, klass).should be_true
- end
+ @compiler.add_resource(@scope, resource)
+ resource.expects(:evaluate).never
- it "should evaluate any node classes" do
- @node.stubs(:classes).returns(%w{one two three four})
- @compiler.expects(:evaluate_classes).with(%w{one two three four}, @compiler.topscope)
- @compiler.send(:evaluate_node_classes)
- end
+ @compiler.compile
+ end
- it "should evaluate all added collections" do
- colls = []
- # And when the collections fail to evaluate.
- colls << mock("coll1-false")
- colls << mock("coll2-false")
- colls.each { |c| c.expects(:evaluate).returns(false) }
+ it "should evaluate unevaluated resources" do
+ resource = CompilerTestResource.new(:file, "testing")
- @compiler.add_collection(colls[0])
- @compiler.add_collection(colls[1])
+ @compiler.add_resource(@scope, resource)
- compile_stub(:evaluate_generators)
- @compiler.compile
- end
+ # We have to now mark the resource as evaluated
+ resource.expects(:evaluate).with { |*whatever| resource.evaluated = true }
- it "should ignore builtin resources" do
- resource = resource(:file, "testing")
+ @compiler.compile
+ end
- @compiler.add_resource(@scope, resource)
- resource.expects(:evaluate).never
+ it "should not evaluate already-evaluated resources" do
+ resource = resource(:file, "testing")
+ resource.stubs(:evaluated?).returns true
- @compiler.compile
- end
+ @compiler.add_resource(@scope, resource)
+ resource.expects(:evaluate).never
- it "should evaluate unevaluated resources" do
- resource = CompilerTestResource.new(:file, "testing")
+ @compiler.compile
+ end
- @compiler.add_resource(@scope, resource)
+ it "should evaluate unevaluated resources created by evaluating other resources" do
+ resource = CompilerTestResource.new(:file, "testing")
+ @compiler.add_resource(@scope, resource)
- # We have to now mark the resource as evaluated
- resource.expects(:evaluate).with { |*whatever| resource.evaluated = true }
+ resource2 = CompilerTestResource.new(:file, "other")
- @compiler.compile
- end
+ # We have to now mark the resource as evaluated
+ resource.expects(:evaluate).with { |*whatever| resource.evaluated = true; @compiler.add_resource(@scope, resource2) }
+ resource2.expects(:evaluate).with { |*whatever| resource2.evaluated = true }
- it "should not evaluate already-evaluated resources" do
- resource = resource(:file, "testing")
- resource.stubs(:evaluated?).returns true
- @compiler.add_resource(@scope, resource)
- resource.expects(:evaluate).never
+ @compiler.compile
+ end
- @compiler.compile
- end
+ describe "when finishing" do
+ before do
+ @compiler.send(:evaluate_main)
+ @catalog = @compiler.catalog
+ end
- it "should evaluate unevaluated resources created by evaluating other resources" do
- resource = CompilerTestResource.new(:file, "testing")
- @compiler.add_resource(@scope, resource)
+ def add_resource(name, parent = nil)
+ resource = Puppet::Parser::Resource.new "file", name, :scope => @scope
+ @compiler.add_resource(@scope, resource)
+ @catalog.add_edge(parent, resource) if parent
+ resource
+ end
- resource2 = CompilerTestResource.new(:file, "other")
+ it "should call finish() on all resources" do
+ # Add a resource that does respond to :finish
+ resource = Puppet::Parser::Resource.new "file", "finish", :scope => @scope
+ resource.expects(:finish)
- # We have to now mark the resource as evaluated
- resource.expects(:evaluate).with { |*whatever| resource.evaluated = true; @compiler.add_resource(@scope, resource2) }
- resource2.expects(:evaluate).with { |*whatever| resource2.evaluated = true }
+ @compiler.add_resource(@scope, resource)
+ # And one that does not
+ dnf_resource = stub_everything "dnf", :ref => "File[dnf]", :type => "file"
- @compiler.compile
- end
+ @compiler.add_resource(@scope, dnf_resource)
- describe "when finishing" do
- before do
- @compiler.send(:evaluate_main)
- @catalog = @compiler.catalog
- end
+ @compiler.send(:finish)
+ end
- def add_resource(name, parent = nil)
- resource = Puppet::Parser::Resource.new "file", name, :scope => @scope
- @compiler.add_resource(@scope, resource)
- @catalog.add_edge(parent, resource) if parent
- resource
- end
+ it "should call finish() in add_resource order" do
+ resources = sequence('resources')
- it "should call finish() on all resources" do
- # Add a resource that does respond to :finish
- resource = Puppet::Parser::Resource.new "file", "finish", :scope => @scope
- resource.expects(:finish)
+ resource1 = add_resource("finish1")
+ resource1.expects(:finish).in_sequence(resources)
- @compiler.add_resource(@scope, resource)
+ resource2 = add_resource("finish2")
+ resource2.expects(:finish).in_sequence(resources)
- # And one that does not
- dnf_resource = stub_everything "dnf", :ref => "File[dnf]", :type => "file"
+ @compiler.send(:finish)
+ end
- @compiler.add_resource(@scope, dnf_resource)
+ it "should add each container's metaparams to its contained resources" do
+ main = @catalog.resource(:class, :main)
+ main[:noop] = true
- @compiler.send(:finish)
- end
+ resource1 = add_resource("meh", main)
- it "should call finish() in add_resource order" do
- resources = sequence('resources')
+ @compiler.send(:finish)
+ resource1[:noop].should be_true
+ end
- resource1 = add_resource("finish1")
- resource1.expects(:finish).in_sequence(resources)
+ it "should add metaparams recursively" do
+ main = @catalog.resource(:class, :main)
+ main[:noop] = true
- resource2 = add_resource("finish2")
- resource2.expects(:finish).in_sequence(resources)
+ resource1 = add_resource("meh", main)
+ resource2 = add_resource("foo", resource1)
- @compiler.send(:finish)
- end
+ @compiler.send(:finish)
+ resource2[:noop].should be_true
+ end
- it "should add each container's metaparams to its contained resources" do
- main = @catalog.resource(:class, :main)
- main[:noop] = true
+ it "should prefer metaparams from immediate parents" do
+ main = @catalog.resource(:class, :main)
+ main[:noop] = true
- resource1 = add_resource("meh", main)
+ resource1 = add_resource("meh", main)
+ resource2 = add_resource("foo", resource1)
- @compiler.send(:finish)
- resource1[:noop].should be_true
- end
+ resource1[:noop] = false
- it "should add metaparams recursively" do
- main = @catalog.resource(:class, :main)
- main[:noop] = true
+ @compiler.send(:finish)
+ resource2[:noop].should be_false
+ end
- resource1 = add_resource("meh", main)
- resource2 = add_resource("foo", resource1)
+ it "should merge tags downward" do
+ main = @catalog.resource(:class, :main)
+ main.tag("one")
- @compiler.send(:finish)
- resource2[:noop].should be_true
- end
+ resource1 = add_resource("meh", main)
+ resource1.tag "two"
+ resource2 = add_resource("foo", resource1)
- it "should prefer metaparams from immediate parents" do
- main = @catalog.resource(:class, :main)
- main[:noop] = true
+ @compiler.send(:finish)
+ resource2.tags.should be_include("one")
+ resource2.tags.should be_include("two")
+ end
- resource1 = add_resource("meh", main)
- resource2 = add_resource("foo", resource1)
+ it "should work if only middle resources have metaparams set" do
+ main = @catalog.resource(:class, :main)
- resource1[:noop] = false
+ resource1 = add_resource("meh", main)
+ resource1[:noop] = true
+ resource2 = add_resource("foo", resource1)
- @compiler.send(:finish)
- resource2[:noop].should be_false
- end
+ @compiler.send(:finish)
+ resource2[:noop].should be_true
+ end
+ end
- it "should merge tags downward" do
- main = @catalog.resource(:class, :main)
- main.tag("one")
+ it "should return added resources in add order" do
+ resource1 = resource(:file, "yay")
+ @compiler.add_resource(@scope, resource1)
+ resource2 = resource(:file, "youpi")
+ @compiler.add_resource(@scope, resource2)
- resource1 = add_resource("meh", main)
- resource1.tag "two"
- resource2 = add_resource("foo", resource1)
+ @compiler.resources.should == [resource1, resource2]
+ end
- @compiler.send(:finish)
- resource2.tags.should be_include("one")
- resource2.tags.should be_include("two")
- end
+ it "should add resources that do not conflict with existing resources" do
+ resource = resource(:file, "yay")
+ @compiler.add_resource(@scope, resource)
- it "should work if only middle resources have metaparams set" do
- main = @catalog.resource(:class, :main)
+ @compiler.catalog.should be_vertex(resource)
+ end
- resource1 = add_resource("meh", main)
- resource1[:noop] = true
- resource2 = add_resource("foo", resource1)
+ it "should fail to add resources that conflict with existing resources" do
+ path = Puppet.features.posix? ? "/foo" : "C:/foo"
+ file1 = Puppet::Type.type(:file).new :path => path
+ file2 = Puppet::Type.type(:file).new :path => path
- @compiler.send(:finish)
- resource2[:noop].should be_true
- end
- end
+ @compiler.add_resource(@scope, file1)
+ lambda { @compiler.add_resource(@scope, file2) }.should raise_error(Puppet::Resource::Catalog::DuplicateResourceError)
+ end
- it "should return added resources in add order" do
- resource1 = resource(:file, "yay")
- @compiler.add_resource(@scope, resource1)
- resource2 = resource(:file, "youpi")
- @compiler.add_resource(@scope, resource2)
+ it "should add an edge from the scope resource to the added resource" do
+ resource = resource(:file, "yay")
+ @compiler.add_resource(@scope, resource)
- @compiler.resources.should == [resource1, resource2]
- end
+ @compiler.catalog.should be_edge(@scope.resource, resource)
+ end
- it "should add resources that do not conflict with existing resources" do
- resource = resource(:file, "yay")
- @compiler.add_resource(@scope, resource)
+ it "should add an edge to any specified stage for class resources" do
+ other_stage = resource(:stage, "other")
+ @compiler.add_resource(@scope, other_stage)
+ resource = resource(:class, "foo")
+ resource[:stage] = 'other'
- @compiler.catalog.should be_vertex(resource)
- end
+ @compiler.add_resource(@scope, resource)
- it "should fail to add resources that conflict with existing resources" do
- path = Puppet.features.posix? ? "/foo" : "C:/foo"
- file1 = Puppet::Type.type(:file).new :path => path
- file2 = Puppet::Type.type(:file).new :path => path
+ @compiler.catalog.edge?(other_stage, resource).should be_true
+ end
- @compiler.add_resource(@scope, file1)
- lambda { @compiler.add_resource(@scope, file2) }.should raise_error(Puppet::Resource::Catalog::DuplicateResourceError)
- end
+ it "should fail if a non-class resource attempts to set a stage" do
+ other_stage = resource(:stage, "other")
+ @compiler.add_resource(@scope, other_stage)
+ resource = resource(:file, "foo")
+ resource[:stage] = 'other'
- it "should add an edge from the scope resource to the added resource" do
- resource = resource(:file, "yay")
- @compiler.add_resource(@scope, resource)
+ lambda { @compiler.add_resource(@scope, resource) }.should raise_error(ArgumentError)
+ end
- @compiler.catalog.should be_edge(@scope.resource, resource)
- end
+ it "should fail if an unknown stage is specified" do
+ resource = resource(:class, "foo")
+ resource[:stage] = 'other'
- it "should add an edge to any specified stage for class resources" do
- other_stage = resource(:stage, "other")
- @compiler.add_resource(@scope, other_stage)
- resource = resource(:class, "foo")
- resource[:stage] = 'other'
+ lambda { @compiler.add_resource(@scope, resource) }.should raise_error(ArgumentError)
+ end
- @compiler.add_resource(@scope, resource)
+ it "should add edges from the class resources to the main stage if no stage is specified" do
+ main = @compiler.catalog.resource(:stage, :main)
+ resource = resource(:class, "foo")
+ @compiler.add_resource(@scope, resource)
- @compiler.catalog.edge?(other_stage, resource).should be_true
- end
+ @compiler.catalog.should be_edge(main, resource)
+ end
- it "should fail if a non-class resource attempts to set a stage" do
- other_stage = resource(:stage, "other")
- @compiler.add_resource(@scope, other_stage)
- resource = resource(:file, "foo")
- resource[:stage] = 'other'
+ it "should not add non-class resources that don't specify a stage to the 'main' stage" do
+ main = @compiler.catalog.resource(:stage, :main)
+ resource = resource(:file, "foo")
+ @compiler.add_resource(@scope, resource)
- lambda { @compiler.add_resource(@scope, resource) }.should raise_error(ArgumentError)
- end
+ @compiler.catalog.should_not be_edge(main, resource)
+ end
- it "should fail if an unknown stage is specified" do
- resource = resource(:class, "foo")
- resource[:stage] = 'other'
+ it "should not add any parent-edges to stages" do
+ stage = resource(:stage, "other")
+ @compiler.add_resource(@scope, stage)
- lambda { @compiler.add_resource(@scope, resource) }.should raise_error(ArgumentError)
- end
+ @scope.resource = resource(:class, "foo")
- it "should add edges from the class resources to the main stage if no stage is specified" do
- main = @compiler.catalog.resource(:stage, :main)
- resource = resource(:class, "foo")
- @compiler.add_resource(@scope, resource)
+ @compiler.catalog.edge?(@scope.resource, stage).should be_false
+ end
- @compiler.catalog.should be_edge(main, resource)
- end
+ it "should not attempt to add stages to other stages" do
+ other_stage = resource(:stage, "other")
+ second_stage = resource(:stage, "second")
+ @compiler.add_resource(@scope, other_stage)
+ @compiler.add_resource(@scope, second_stage)
- it "should not add non-class resources that don't specify a stage to the 'main' stage" do
- main = @compiler.catalog.resource(:stage, :main)
- resource = resource(:file, "foo")
- @compiler.add_resource(@scope, resource)
+ second_stage[:stage] = "other"
- @compiler.catalog.should_not be_edge(main, resource)
- end
+ @compiler.catalog.edge?(other_stage, second_stage).should be_false
+ end
- it "should not add any parent-edges to stages" do
- stage = resource(:stage, "other")
- @compiler.add_resource(@scope, stage)
+ it "should have a method for looking up resources" do
+ resource = resource(:yay, "foo")
+ @compiler.add_resource(@scope, resource)
+ @compiler.findresource("Yay[foo]").should equal(resource)
+ end
- @scope.resource = resource(:class, "foo")
+ it "should be able to look resources up by type and title" do
+ resource = resource(:yay, "foo")
+ @compiler.add_resource(@scope, resource)
+ @compiler.findresource("Yay", "foo").should equal(resource)
+ end
- @compiler.catalog.edge?(@scope.resource, stage).should be_false
- end
+ it "should not evaluate virtual defined resources" do
+ resource = resource(:file, "testing")
+ resource.virtual = true
+ @compiler.add_resource(@scope, resource)
- it "should not attempt to add stages to other stages" do
- other_stage = resource(:stage, "other")
- second_stage = resource(:stage, "second")
- @compiler.add_resource(@scope, other_stage)
- @compiler.add_resource(@scope, second_stage)
+ resource.expects(:evaluate).never
- second_stage[:stage] = "other"
+ @compiler.compile
+ end
+ end
- @compiler.catalog.edge?(other_stage, second_stage).should be_false
- end
+ describe "when evaluating collections" do
- it "should have a method for looking up resources" do
- resource = resource(:yay, "foo")
- @compiler.add_resource(@scope, resource)
- @compiler.findresource("Yay[foo]").should equal(resource)
- end
+ it "should evaluate each collection" do
+ 2.times { |i|
+ coll = mock 'coll%s' % i
+ @compiler.add_collection(coll)
- it "should be able to look resources up by type and title" do
- resource = resource(:yay, "foo")
- @compiler.add_resource(@scope, resource)
- @compiler.findresource("Yay", "foo").should equal(resource)
+ # This is the hard part -- we have to emulate the fact that
+ # collections delete themselves if they are done evaluating.
+ coll.expects(:evaluate).with do
+ @compiler.delete_collection(coll)
end
+ }
- it "should not evaluate virtual defined resources" do
- resource = resource(:file, "testing")
- resource.virtual = true
- @compiler.add_resource(@scope, resource)
-
- resource.expects(:evaluate).never
-
- @compiler.compile
- end
+ @compiler.class.publicize_methods(:evaluate_collections) { @compiler.evaluate_collections }
end
- describe "when evaluating collections" do
-
- it "should evaluate each collection" do
- 2.times { |i|
- coll = mock 'coll%s' % i
- @compiler.add_collection(coll)
-
- # This is the hard part -- we have to emulate the fact that
- # collections delete themselves if they are done evaluating.
- coll.expects(:evaluate).with do
- @compiler.delete_collection(coll)
- end
- }
-
- @compiler.class.publicize_methods(:evaluate_collections) { @compiler.evaluate_collections }
- end
+ it "should not fail when there are unevaluated resource collections that do not refer to specific resources" do
+ coll = stub 'coll', :evaluate => false
+ coll.expects(:resources).returns(nil)
- it "should not fail when there are unevaluated resource collections that do not refer to specific resources" do
- coll = stub 'coll', :evaluate => false
- coll.expects(:resources).returns(nil)
+ @compiler.add_collection(coll)
- @compiler.add_collection(coll)
-
- lambda { @compiler.compile }.should_not raise_error
- end
+ lambda { @compiler.compile }.should_not raise_error
+ end
- it "should fail when there are unevaluated resource collections that refer to a specific resource" do
- coll = stub 'coll', :evaluate => false
- coll.expects(:resources).returns(:something)
+ it "should fail when there are unevaluated resource collections that refer to a specific resource" do
+ coll = stub 'coll', :evaluate => false
+ coll.expects(:resources).returns(:something)
- @compiler.add_collection(coll)
+ @compiler.add_collection(coll)
- lambda { @compiler.compile }.should raise_error(Puppet::ParseError)
- end
+ lambda { @compiler.compile }.should raise_error(Puppet::ParseError)
+ end
- it "should fail when there are unevaluated resource collections that refer to multiple specific resources" do
- coll = stub 'coll', :evaluate => false
- coll.expects(:resources).returns([:one, :two])
+ it "should fail when there are unevaluated resource collections that refer to multiple specific resources" do
+ coll = stub 'coll', :evaluate => false
+ coll.expects(:resources).returns([:one, :two])
- @compiler.add_collection(coll)
+ @compiler.add_collection(coll)
- lambda { @compiler.compile }.should raise_error(Puppet::ParseError)
- end
+ lambda { @compiler.compile }.should raise_error(Puppet::ParseError)
end
-
- describe "when evaluating relationships" do
- it "should evaluate each relationship with its catalog" do
- dep = stub 'dep'
- dep.expects(:evaluate).with(@compiler.catalog)
- @compiler.add_relationship dep
- @compiler.evaluate_relationships
- end
+ end
+
+ describe "when evaluating relationships" do
+ it "should evaluate each relationship with its catalog" do
+ dep = stub 'dep'
+ dep.expects(:evaluate).with(@compiler.catalog)
+ @compiler.add_relationship dep
+ @compiler.evaluate_relationships
end
+ end
- describe "when told to evaluate missing classes" do
+ describe "when told to evaluate missing classes" do
- it "should fail if there's no source listed for the scope" do
- scope = stub 'scope', :source => nil
- proc { @compiler.evaluate_classes(%w{one two}, scope) }.should raise_error(Puppet::DevError)
- end
+ it "should fail if there's no source listed for the scope" do
+ scope = stub 'scope', :source => nil
+ proc { @compiler.evaluate_classes(%w{one two}, scope) }.should raise_error(Puppet::DevError)
+ end
- it "should tag the catalog with the name of each not-found class" do
- @compiler.catalog.expects(:tag).with("notfound")
- @scope.expects(:find_hostclass).with("notfound").returns(nil)
- @compiler.evaluate_classes(%w{notfound}, @scope)
- end
+ it "should tag the catalog with the name of each not-found class" do
+ @compiler.catalog.expects(:tag).with("notfound")
+ @scope.expects(:find_hostclass).with("notfound").returns(nil)
+ @compiler.evaluate_classes(%w{notfound}, @scope)
end
+ end
- describe "when evaluating found classes" do
+ describe "when evaluating found classes" do
- before do
- @class = stub 'class', :name => "my::class"
- @scope.stubs(:find_hostclass).with("myclass").returns(@class)
+ before do
+ @class = stub 'class', :name => "my::class"
+ @scope.stubs(:find_hostclass).with("myclass").returns(@class)
- @resource = stub 'resource', :ref => "Class[myclass]", :type => "file"
- end
+ @resource = stub 'resource', :ref => "Class[myclass]", :type => "file"
+ end
- it "should evaluate each class" do
- @compiler.catalog.stubs(:tag)
+ it "should evaluate each class" do
+ @compiler.catalog.stubs(:tag)
- @class.expects(:mk_plain_resource).with(@scope)
- @scope.stubs(:class_scope).with(@class)
+ @class.expects(:mk_plain_resource).with(@scope)
+ @scope.stubs(:class_scope).with(@class)
- @compiler.evaluate_classes(%w{myclass}, @scope)
- end
+ @compiler.evaluate_classes(%w{myclass}, @scope)
+ end
- it "should not evaluate the resources created for found classes unless asked" do
- @compiler.catalog.stubs(:tag)
+ it "should not evaluate the resources created for found classes unless asked" do
+ @compiler.catalog.stubs(:tag)
- @resource.expects(:evaluate).never
+ @resource.expects(:evaluate).never
- @class.expects(:mk_plain_resource).returns(@resource)
- @scope.stubs(:class_scope).with(@class)
+ @class.expects(:mk_plain_resource).returns(@resource)
+ @scope.stubs(:class_scope).with(@class)
- @compiler.evaluate_classes(%w{myclass}, @scope)
- end
+ @compiler.evaluate_classes(%w{myclass}, @scope)
+ end
- it "should immediately evaluate the resources created for found classes when asked" do
- @compiler.catalog.stubs(:tag)
+ it "should immediately evaluate the resources created for found classes when asked" do
+ @compiler.catalog.stubs(:tag)
- @resource.expects(:evaluate)
- @class.expects(:mk_plain_resource).returns(@resource)
- @scope.stubs(:class_scope).with(@class)
+ @resource.expects(:evaluate)
+ @class.expects(:mk_plain_resource).returns(@resource)
+ @scope.stubs(:class_scope).with(@class)
- @compiler.evaluate_classes(%w{myclass}, @scope, false)
- end
+ @compiler.evaluate_classes(%w{myclass}, @scope, false)
+ end
- it "should skip classes that have already been evaluated" do
- @compiler.catalog.stubs(:tag)
+ it "should skip classes that have already been evaluated" do
+ @compiler.catalog.stubs(:tag)
- @scope.stubs(:class_scope).with(@class).returns("something")
+ @scope.stubs(:class_scope).with(@class).returns("something")
- @compiler.expects(:add_resource).never
+ @compiler.expects(:add_resource).never
- @resource.expects(:evaluate).never
+ @resource.expects(:evaluate).never
- Puppet::Parser::Resource.expects(:new).never
- @compiler.evaluate_classes(%w{myclass}, @scope, false)
- end
+ Puppet::Parser::Resource.expects(:new).never
+ @compiler.evaluate_classes(%w{myclass}, @scope, false)
+ end
- it "should skip classes previously evaluated with different capitalization" do
- @compiler.catalog.stubs(:tag)
- @scope.stubs(:find_hostclass).with("MyClass").returns(@class)
- @scope.stubs(:class_scope).with(@class).returns("something")
- @compiler.expects(:add_resource).never
- @resource.expects(:evaluate).never
- Puppet::Parser::Resource.expects(:new).never
- @compiler.evaluate_classes(%w{MyClass}, @scope, false)
- end
+ it "should skip classes previously evaluated with different capitalization" do
+ @compiler.catalog.stubs(:tag)
+ @scope.stubs(:find_hostclass).with("MyClass").returns(@class)
+ @scope.stubs(:class_scope).with(@class).returns("something")
+ @compiler.expects(:add_resource).never
+ @resource.expects(:evaluate).never
+ Puppet::Parser::Resource.expects(:new).never
+ @compiler.evaluate_classes(%w{MyClass}, @scope, false)
+ end
- it "should return the list of found classes" do
- @compiler.catalog.stubs(:tag)
+ it "should return the list of found classes" do
+ @compiler.catalog.stubs(:tag)
- @compiler.stubs(:add_resource)
- @scope.stubs(:find_hostclass).with("notfound").returns(nil)
- @scope.stubs(:class_scope).with(@class)
+ @compiler.stubs(:add_resource)
+ @scope.stubs(:find_hostclass).with("notfound").returns(nil)
+ @scope.stubs(:class_scope).with(@class)
- Puppet::Parser::Resource.stubs(:new).returns(@resource)
- @class.stubs :mk_plain_resource
- @compiler.evaluate_classes(%w{myclass notfound}, @scope).should == %w{myclass}
- end
+ Puppet::Parser::Resource.stubs(:new).returns(@resource)
+ @class.stubs :mk_plain_resource
+ @compiler.evaluate_classes(%w{myclass notfound}, @scope).should == %w{myclass}
end
+ end
- describe "when evaluating AST nodes with no AST nodes present" do
+ describe "when evaluating AST nodes with no AST nodes present" do
- it "should do nothing" do
- @compiler.expects(:ast_nodes?).returns(false)
- @compiler.known_resource_types.expects(:nodes).never
- Puppet::Parser::Resource.expects(:new).never
+ it "should do nothing" do
+ @compiler.expects(:ast_nodes?).returns(false)
+ @compiler.known_resource_types.expects(:nodes).never
+ Puppet::Parser::Resource.expects(:new).never
- @compiler.send(:evaluate_ast_node)
- end
+ @compiler.send(:evaluate_ast_node)
end
+ end
- describe "when evaluating AST nodes with AST nodes present" do
+ describe "when evaluating AST nodes with AST nodes present" do
- before do
- @compiler.known_resource_types.stubs(:nodes?).returns true
+ before do
+ @compiler.known_resource_types.stubs(:nodes?).returns true
- # Set some names for our test
- @node.stubs(:names).returns(%w{a b c})
- @compiler.known_resource_types.stubs(:node).with("a").returns(nil)
- @compiler.known_resource_types.stubs(:node).with("b").returns(nil)
- @compiler.known_resource_types.stubs(:node).with("c").returns(nil)
+ # Set some names for our test
+ @node.stubs(:names).returns(%w{a b c})
+ @compiler.known_resource_types.stubs(:node).with("a").returns(nil)
+ @compiler.known_resource_types.stubs(:node).with("b").returns(nil)
+ @compiler.known_resource_types.stubs(:node).with("c").returns(nil)
- # It should check this last, of course.
- @compiler.known_resource_types.stubs(:node).with("default").returns(nil)
- end
+ # It should check this last, of course.
+ @compiler.known_resource_types.stubs(:node).with("default").returns(nil)
+ end
- it "should fail if the named node cannot be found" do
- proc { @compiler.send(:evaluate_ast_node) }.should raise_error(Puppet::ParseError)
- end
+ it "should fail if the named node cannot be found" do
+ proc { @compiler.send(:evaluate_ast_node) }.should raise_error(Puppet::ParseError)
+ end
- it "should evaluate the first node class matching the node name" do
- node_class = stub 'node', :name => "c", :evaluate_code => nil
- @compiler.known_resource_types.stubs(:node).with("c").returns(node_class)
+ it "should evaluate the first node class matching the node name" do
+ node_class = stub 'node', :name => "c", :evaluate_code => nil
+ @compiler.known_resource_types.stubs(:node).with("c").returns(node_class)
- node_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil, :type => "node"
- node_class.expects(:mk_plain_resource).returns(node_resource)
+ node_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil, :type => "node"
+ node_class.expects(:mk_plain_resource).returns(node_resource)
- @compiler.compile
- end
+ @compiler.compile
+ end
- it "should match the default node if no matching node can be found" do
- node_class = stub 'node', :name => "default", :evaluate_code => nil
- @compiler.known_resource_types.stubs(:node).with("default").returns(node_class)
+ it "should match the default node if no matching node can be found" do
+ node_class = stub 'node', :name => "default", :evaluate_code => nil
+ @compiler.known_resource_types.stubs(:node).with("default").returns(node_class)
- node_resource = stub 'node resource', :ref => "Node[default]", :evaluate => nil, :type => "node"
- node_class.expects(:mk_plain_resource).returns(node_resource)
+ node_resource = stub 'node resource', :ref => "Node[default]", :evaluate => nil, :type => "node"
+ node_class.expects(:mk_plain_resource).returns(node_resource)
- @compiler.compile
- end
+ @compiler.compile
+ end
- it "should evaluate the node resource immediately rather than using lazy evaluation" do
- node_class = stub 'node', :name => "c"
- @compiler.known_resource_types.stubs(:node).with("c").returns(node_class)
+ it "should evaluate the node resource immediately rather than using lazy evaluation" do
+ node_class = stub 'node', :name => "c"
+ @compiler.known_resource_types.stubs(:node).with("c").returns(node_class)
- node_resource = stub 'node resource', :ref => "Node[c]", :type => "node"
- node_class.expects(:mk_plain_resource).returns(node_resource)
+ node_resource = stub 'node resource', :ref => "Node[c]", :type => "node"
+ node_class.expects(:mk_plain_resource).returns(node_resource)
- node_resource.expects(:evaluate)
+ node_resource.expects(:evaluate)
- @compiler.send(:evaluate_ast_node)
- end
+ @compiler.send(:evaluate_ast_node)
+ end
- it "should set the node's scope as the top scope" do
- node_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil, :type => "node"
- node_class = stub 'node', :name => "c", :mk_plain_resource => node_resource
+ it "should set the node's scope as the top scope" do
+ node_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil, :type => "node"
+ node_class = stub 'node', :name => "c", :mk_plain_resource => node_resource
- @compiler.known_resource_types.stubs(:node).with("c").returns(node_class)
+ @compiler.known_resource_types.stubs(:node).with("c").returns(node_class)
- # The #evaluate method normally does this.
- scope = stub 'scope', :source => "mysource"
- @compiler.topscope.expects(:class_scope).with(node_class).returns(scope)
- node_resource.stubs(:evaluate)
- @compiler.stubs :create_settings_scope
+ # The #evaluate method normally does this.
+ scope = stub 'scope', :source => "mysource"
+ @compiler.topscope.expects(:class_scope).with(node_class).returns(scope)
+ node_resource.stubs(:evaluate)
+ @compiler.stubs :create_settings_scope
- @compiler.compile
+ @compiler.compile
- @compiler.topscope.should equal(scope)
- end
+ @compiler.topscope.should equal(scope)
end
+ end
- describe "when managing resource overrides" do
+ describe "when managing resource overrides" do
- before do
- @override = stub 'override', :ref => "File[/foo]", :type => "my"
- @resource = resource(:file, "/foo")
- end
+ before do
+ @override = stub 'override', :ref => "File[/foo]", :type => "my"
+ @resource = resource(:file, "/foo")
+ end
- it "should be able to store overrides" do
- lambda { @compiler.add_override(@override) }.should_not raise_error
- end
+ it "should be able to store overrides" do
+ lambda { @compiler.add_override(@override) }.should_not raise_error
+ end
- it "should apply overrides to the appropriate resources" do
- @compiler.add_resource(@scope, @resource)
- @resource.expects(:merge).with(@override)
+ it "should apply overrides to the appropriate resources" do
+ @compiler.add_resource(@scope, @resource)
+ @resource.expects(:merge).with(@override)
- @compiler.add_override(@override)
+ @compiler.add_override(@override)
- @compiler.compile
- end
+ @compiler.compile
+ end
- it "should accept overrides before the related resource has been created" do
- @resource.expects(:merge).with(@override)
+ it "should accept overrides before the related resource has been created" do
+ @resource.expects(:merge).with(@override)
- # First store the override
- @compiler.add_override(@override)
+ # First store the override
+ @compiler.add_override(@override)
- # Then the resource
- @compiler.add_resource(@scope, @resource)
+ # Then the resource
+ @compiler.add_resource(@scope, @resource)
- # And compile, so they get resolved
- @compiler.compile
- end
+ # And compile, so they get resolved
+ @compiler.compile
+ end
- it "should fail if the compile is finished and resource overrides have not been applied" do
- @compiler.add_override(@override)
+ it "should fail if the compile is finished and resource overrides have not been applied" do
+ @compiler.add_override(@override)
- lambda { @compiler.compile }.should raise_error(Puppet::ParseError)
- end
+ lambda { @compiler.compile }.should raise_error(Puppet::ParseError)
end
+ end
end
diff --git a/spec/unit/parser/files_spec.rb b/spec/unit/parser/files_spec.rb
index df96c0e..d1b5491 100644
--- a/spec/unit/parser/files_spec.rb
+++ b/spec/unit/parser/files_spec.rb
@@ -6,190 +6,190 @@ require 'puppet/parser/files'
describe Puppet::Parser::Files do
+ before do
+ @basepath = Puppet.features.posix? ? "/somepath" : "C:/somepath"
+ end
+
+ it "should have a method for finding a template" do
+ Puppet::Parser::Files.should respond_to(:find_template)
+ end
+
+ it "should have a method for finding manifests" do
+ Puppet::Parser::Files.should respond_to(:find_manifests)
+ end
+
+ describe "when searching for templates" do
+ it "should return fully-qualified templates directly" do
+ Puppet::Parser::Files.expects(:modulepath).never
+ Puppet::Parser::Files.find_template(@basepath + "/my/template").should == @basepath + "/my/template"
+ end
+
+ it "should return the template from the first found module" do
+ mod = mock 'module'
+ Puppet::Node::Environment.new.expects(:module).with("mymod").returns mod
+
+ mod.expects(:template).returns("/one/mymod/templates/mytemplate")
+ Puppet::Parser::Files.find_template("mymod/mytemplate").should == "/one/mymod/templates/mytemplate"
+ end
+
+ it "should return the file in the templatedir if it exists" do
+ Puppet.settings.expects(:value).with(:templatedir, nil).returns("/my/templates")
+ Puppet[:modulepath] = "/one:/two"
+ File.stubs(:directory?).returns(true)
+ FileTest.stubs(:exist?).returns(true)
+ Puppet::Parser::Files.find_template("mymod/mytemplate").should == "/my/templates/mymod/mytemplate"
+ end
+
+ it "should not raise an error if no valid templatedir exists and the template exists in a module" do
+ mod = mock 'module'
+ Puppet::Node::Environment.new.expects(:module).with("mymod").returns mod
+
+ mod.expects(:template).returns("/one/mymod/templates/mytemplate")
+ Puppet::Parser::Files.stubs(:templatepath).with(nil).returns(nil)
+
+ Puppet::Parser::Files.find_template("mymod/mytemplate").should == "/one/mymod/templates/mytemplate"
+ end
+
+ it "should return unqualified templates if they exist in the template dir" do
+ FileTest.stubs(:exist?).returns true
+ Puppet::Parser::Files.stubs(:templatepath).with(nil).returns(["/my/templates"])
+ Puppet::Parser::Files.find_template("mytemplate").should == "/my/templates/mytemplate"
+ end
+
+ it "should only return templates if they actually exist" do
+ FileTest.expects(:exist?).with("/my/templates/mytemplate").returns true
+ Puppet::Parser::Files.stubs(:templatepath).with(nil).returns(["/my/templates"])
+ Puppet::Parser::Files.find_template("mytemplate").should == "/my/templates/mytemplate"
+ end
+
+ it "should return nil when asked for a template that doesn't exist" do
+ FileTest.expects(:exist?).with("/my/templates/mytemplate").returns false
+ Puppet::Parser::Files.stubs(:templatepath).with(nil).returns(["/my/templates"])
+ Puppet::Parser::Files.find_template("mytemplate").should be_nil
+ end
+
+ it "should search in the template directories before modules" do
+ FileTest.stubs(:exist?).returns true
+ Puppet::Parser::Files.stubs(:templatepath).with(nil).returns(["/my/templates"])
+ Puppet::Module.expects(:find).never
+ Puppet::Parser::Files.find_template("mytemplate")
+ end
+
+ it "should accept relative templatedirs" do
+ FileTest.stubs(:exist?).returns true
+ Puppet[:templatedir] = "my/templates"
+ File.expects(:directory?).with(File.join(Dir.getwd,"my/templates")).returns(true)
+ Puppet::Parser::Files.find_template("mytemplate").should == File.join(Dir.getwd,"my/templates/mytemplate")
+ end
+
+ it "should use the environment templatedir if no module is found and an environment is specified" do
+ FileTest.stubs(:exist?).returns true
+ Puppet::Parser::Files.stubs(:templatepath).with("myenv").returns(["/myenv/templates"])
+ Puppet::Parser::Files.find_template("mymod/mytemplate", "myenv").should == "/myenv/templates/mymod/mytemplate"
+ end
+
+ it "should use first dir from environment templatedir if no module is found and an environment is specified" do
+ FileTest.stubs(:exist?).returns true
+ Puppet::Parser::Files.stubs(:templatepath).with("myenv").returns(["/myenv/templates", "/two/templates"])
+ Puppet::Parser::Files.find_template("mymod/mytemplate", "myenv").should == "/myenv/templates/mymod/mytemplate"
+ end
+
+ it "should use a valid dir when templatedir is a path for unqualified templates and the first dir contains template" do
+ Puppet::Parser::Files.stubs(:templatepath).returns(["/one/templates", "/two/templates"])
+ FileTest.expects(:exist?).with("/one/templates/mytemplate").returns(true)
+ Puppet::Parser::Files.find_template("mytemplate").should == "/one/templates/mytemplate"
+ end
+
+ it "should use a valid dir when templatedir is a path for unqualified templates and only second dir contains template" do
+ Puppet::Parser::Files.stubs(:templatepath).returns(["/one/templates", "/two/templates"])
+ FileTest.expects(:exist?).with("/one/templates/mytemplate").returns(false)
+ FileTest.expects(:exist?).with("/two/templates/mytemplate").returns(true)
+ Puppet::Parser::Files.find_template("mytemplate").should == "/two/templates/mytemplate"
+ end
+
+ it "should use the node environment if specified" do
+ mod = mock 'module'
+ Puppet::Node::Environment.new("myenv").expects(:module).with("mymod").returns mod
+
+ mod.expects(:template).returns("/my/modules/mymod/templates/envtemplate")
+
+ Puppet::Parser::Files.find_template("mymod/envtemplate", "myenv").should == "/my/modules/mymod/templates/envtemplate"
+ end
+
+ it "should return nil if no template can be found" do
+ Puppet::Parser::Files.find_template("foomod/envtemplate", "myenv").should be_nil
+ end
+
+ after { Puppet.settings.clear }
+ end
+
+ describe "when searching for manifests" do
+ it "should ignore invalid modules" do
+ mod = mock 'module'
+ Puppet::Node::Environment.new.expects(:module).with("mymod").raises(Puppet::Module::InvalidName, "name is invalid")
+ Puppet.expects(:value).with(:modulepath).never
+ Dir.stubs(:glob).returns %w{foo}
+
+ Puppet::Parser::Files.find_manifests("mymod/init.pp")
+ end
+ end
+
+ describe "when searching for manifests when no module is found" do
before do
- @basepath = Puppet.features.posix? ? "/somepath" : "C:/somepath"
- end
-
- it "should have a method for finding a template" do
- Puppet::Parser::Files.should respond_to(:find_template)
- end
-
- it "should have a method for finding manifests" do
- Puppet::Parser::Files.should respond_to(:find_manifests)
- end
-
- describe "when searching for templates" do
- it "should return fully-qualified templates directly" do
- Puppet::Parser::Files.expects(:modulepath).never
- Puppet::Parser::Files.find_template(@basepath + "/my/template").should == @basepath + "/my/template"
- end
-
- it "should return the template from the first found module" do
- mod = mock 'module'
- Puppet::Node::Environment.new.expects(:module).with("mymod").returns mod
-
- mod.expects(:template).returns("/one/mymod/templates/mytemplate")
- Puppet::Parser::Files.find_template("mymod/mytemplate").should == "/one/mymod/templates/mytemplate"
- end
-
- it "should return the file in the templatedir if it exists" do
- Puppet.settings.expects(:value).with(:templatedir, nil).returns("/my/templates")
- Puppet[:modulepath] = "/one:/two"
- File.stubs(:directory?).returns(true)
- FileTest.stubs(:exist?).returns(true)
- Puppet::Parser::Files.find_template("mymod/mytemplate").should == "/my/templates/mymod/mytemplate"
- end
-
- it "should not raise an error if no valid templatedir exists and the template exists in a module" do
- mod = mock 'module'
- Puppet::Node::Environment.new.expects(:module).with("mymod").returns mod
-
- mod.expects(:template).returns("/one/mymod/templates/mytemplate")
- Puppet::Parser::Files.stubs(:templatepath).with(nil).returns(nil)
-
- Puppet::Parser::Files.find_template("mymod/mytemplate").should == "/one/mymod/templates/mytemplate"
- end
-
- it "should return unqualified templates if they exist in the template dir" do
- FileTest.stubs(:exist?).returns true
- Puppet::Parser::Files.stubs(:templatepath).with(nil).returns(["/my/templates"])
- Puppet::Parser::Files.find_template("mytemplate").should == "/my/templates/mytemplate"
- end
-
- it "should only return templates if they actually exist" do
- FileTest.expects(:exist?).with("/my/templates/mytemplate").returns true
- Puppet::Parser::Files.stubs(:templatepath).with(nil).returns(["/my/templates"])
- Puppet::Parser::Files.find_template("mytemplate").should == "/my/templates/mytemplate"
- end
-
- it "should return nil when asked for a template that doesn't exist" do
- FileTest.expects(:exist?).with("/my/templates/mytemplate").returns false
- Puppet::Parser::Files.stubs(:templatepath).with(nil).returns(["/my/templates"])
- Puppet::Parser::Files.find_template("mytemplate").should be_nil
- end
-
- it "should search in the template directories before modules" do
- FileTest.stubs(:exist?).returns true
- Puppet::Parser::Files.stubs(:templatepath).with(nil).returns(["/my/templates"])
- Puppet::Module.expects(:find).never
- Puppet::Parser::Files.find_template("mytemplate")
- end
-
- it "should accept relative templatedirs" do
- FileTest.stubs(:exist?).returns true
- Puppet[:templatedir] = "my/templates"
- File.expects(:directory?).with(File.join(Dir.getwd,"my/templates")).returns(true)
- Puppet::Parser::Files.find_template("mytemplate").should == File.join(Dir.getwd,"my/templates/mytemplate")
- end
-
- it "should use the environment templatedir if no module is found and an environment is specified" do
- FileTest.stubs(:exist?).returns true
- Puppet::Parser::Files.stubs(:templatepath).with("myenv").returns(["/myenv/templates"])
- Puppet::Parser::Files.find_template("mymod/mytemplate", "myenv").should == "/myenv/templates/mymod/mytemplate"
- end
-
- it "should use first dir from environment templatedir if no module is found and an environment is specified" do
- FileTest.stubs(:exist?).returns true
- Puppet::Parser::Files.stubs(:templatepath).with("myenv").returns(["/myenv/templates", "/two/templates"])
- Puppet::Parser::Files.find_template("mymod/mytemplate", "myenv").should == "/myenv/templates/mymod/mytemplate"
- end
-
- it "should use a valid dir when templatedir is a path for unqualified templates and the first dir contains template" do
- Puppet::Parser::Files.stubs(:templatepath).returns(["/one/templates", "/two/templates"])
- FileTest.expects(:exist?).with("/one/templates/mytemplate").returns(true)
- Puppet::Parser::Files.find_template("mytemplate").should == "/one/templates/mytemplate"
- end
-
- it "should use a valid dir when templatedir is a path for unqualified templates and only second dir contains template" do
- Puppet::Parser::Files.stubs(:templatepath).returns(["/one/templates", "/two/templates"])
- FileTest.expects(:exist?).with("/one/templates/mytemplate").returns(false)
- FileTest.expects(:exist?).with("/two/templates/mytemplate").returns(true)
- Puppet::Parser::Files.find_template("mytemplate").should == "/two/templates/mytemplate"
- end
-
- it "should use the node environment if specified" do
- mod = mock 'module'
- Puppet::Node::Environment.new("myenv").expects(:module).with("mymod").returns mod
-
- mod.expects(:template).returns("/my/modules/mymod/templates/envtemplate")
-
- Puppet::Parser::Files.find_template("mymod/envtemplate", "myenv").should == "/my/modules/mymod/templates/envtemplate"
- end
-
- it "should return nil if no template can be found" do
- Puppet::Parser::Files.find_template("foomod/envtemplate", "myenv").should be_nil
- end
-
- after { Puppet.settings.clear }
- end
-
- describe "when searching for manifests" do
- it "should ignore invalid modules" do
- mod = mock 'module'
- Puppet::Node::Environment.new.expects(:module).with("mymod").raises(Puppet::Module::InvalidName, "name is invalid")
- Puppet.expects(:value).with(:modulepath).never
- Dir.stubs(:glob).returns %w{foo}
-
- Puppet::Parser::Files.find_manifests("mymod/init.pp")
- end
- end
-
- describe "when searching for manifests when no module is found" do
- before do
- File.stubs(:find).returns(nil)
- end
-
- it "should not look for modules when paths are fully qualified" do
- Puppet.expects(:value).with(:modulepath).never
- file = @basepath + "/fully/qualified/file.pp"
- Dir.stubs(:glob).with(file).returns([file])
- Puppet::Parser::Files.find_manifests(file)
- end
-
- it "should return nil and an array of fully qualified files" do
- file = @basepath + "/fully/qualified/file.pp"
- Dir.stubs(:glob).with(file).returns([file])
- Puppet::Parser::Files.find_manifests(file).should == [nil, [file]]
- end
-
- it "should match against provided fully qualified patterns" do
- pattern = @basepath + "/fully/qualified/pattern/*"
- Dir.expects(:glob).with(pattern+'{,.pp,.rb}').returns(%w{my file list})
- Puppet::Parser::Files.find_manifests(pattern)[1].should == %w{my file list}
- end
-
- it "should look for files relative to the current directory" do
- cwd = Dir.getwd
- Dir.expects(:glob).with("#{cwd}/foobar/init.pp").returns(["#{cwd}/foobar/init.pp"])
- Puppet::Parser::Files.find_manifests("foobar/init.pp")[1].should == ["#{cwd}/foobar/init.pp"]
- end
-
- it "should only return files, not directories" do
- pattern = @basepath + "/fully/qualified/pattern/*"
- file = @basepath + "/my/file"
- dir = @basepath + "/my/directory"
- Dir.expects(:glob).with(pattern+'{,.pp,.rb}').returns([file, dir])
- FileTest.expects(:directory?).with(file).returns(false)
- FileTest.expects(:directory?).with(dir).returns(true)
- Puppet::Parser::Files.find_manifests(pattern)[1].should == [file]
- end
- end
-
- describe "when searching for manifests in a found module" do
- it "should return the name of the module and the manifests from the first found module" do
- mod = Puppet::Module.new("mymod")
- Puppet::Node::Environment.new.expects(:module).with("mymod").returns mod
- mod.expects(:match_manifests).with("init.pp").returns(%w{/one/mymod/manifests/init.pp})
- Puppet::Parser::Files.find_manifests("mymod/init.pp").should == ["mymod", ["/one/mymod/manifests/init.pp"]]
- end
-
- it "should use the node environment if specified" do
- mod = Puppet::Module.new("mymod")
- Puppet::Node::Environment.new("myenv").expects(:module).with("mymod").returns mod
- mod.expects(:match_manifests).with("init.pp").returns(%w{/one/mymod/manifests/init.pp})
- Puppet::Parser::Files.find_manifests("mymod/init.pp", :environment => "myenv")[1].should == ["/one/mymod/manifests/init.pp"]
- end
-
- after { Puppet.settings.clear }
+ File.stubs(:find).returns(nil)
+ end
+
+ it "should not look for modules when paths are fully qualified" do
+ Puppet.expects(:value).with(:modulepath).never
+ file = @basepath + "/fully/qualified/file.pp"
+ Dir.stubs(:glob).with(file).returns([file])
+ Puppet::Parser::Files.find_manifests(file)
+ end
+
+ it "should return nil and an array of fully qualified files" do
+ file = @basepath + "/fully/qualified/file.pp"
+ Dir.stubs(:glob).with(file).returns([file])
+ Puppet::Parser::Files.find_manifests(file).should == [nil, [file]]
+ end
+
+ it "should match against provided fully qualified patterns" do
+ pattern = @basepath + "/fully/qualified/pattern/*"
+ Dir.expects(:glob).with(pattern+'{,.pp,.rb}').returns(%w{my file list})
+ Puppet::Parser::Files.find_manifests(pattern)[1].should == %w{my file list}
+ end
+
+ it "should look for files relative to the current directory" do
+ cwd = Dir.getwd
+ Dir.expects(:glob).with("#{cwd}/foobar/init.pp").returns(["#{cwd}/foobar/init.pp"])
+ Puppet::Parser::Files.find_manifests("foobar/init.pp")[1].should == ["#{cwd}/foobar/init.pp"]
end
+
+ it "should only return files, not directories" do
+ pattern = @basepath + "/fully/qualified/pattern/*"
+ file = @basepath + "/my/file"
+ dir = @basepath + "/my/directory"
+ Dir.expects(:glob).with(pattern+'{,.pp,.rb}').returns([file, dir])
+ FileTest.expects(:directory?).with(file).returns(false)
+ FileTest.expects(:directory?).with(dir).returns(true)
+ Puppet::Parser::Files.find_manifests(pattern)[1].should == [file]
+ end
+ end
+
+ describe "when searching for manifests in a found module" do
+ it "should return the name of the module and the manifests from the first found module" do
+ mod = Puppet::Module.new("mymod")
+ Puppet::Node::Environment.new.expects(:module).with("mymod").returns mod
+ mod.expects(:match_manifests).with("init.pp").returns(%w{/one/mymod/manifests/init.pp})
+ Puppet::Parser::Files.find_manifests("mymod/init.pp").should == ["mymod", ["/one/mymod/manifests/init.pp"]]
+ end
+
+ it "should use the node environment if specified" do
+ mod = Puppet::Module.new("mymod")
+ Puppet::Node::Environment.new("myenv").expects(:module).with("mymod").returns mod
+ mod.expects(:match_manifests).with("init.pp").returns(%w{/one/mymod/manifests/init.pp})
+ Puppet::Parser::Files.find_manifests("mymod/init.pp", :environment => "myenv")[1].should == ["/one/mymod/manifests/init.pp"]
+ end
+
+ after { Puppet.settings.clear }
+ end
end
diff --git a/spec/unit/parser/functions/defined_spec.rb b/spec/unit/parser/functions/defined_spec.rb
index 90f2f52..cf3f66e 100755
--- a/spec/unit/parser/functions/defined_spec.rb
+++ b/spec/unit/parser/functions/defined_spec.rb
@@ -4,47 +4,47 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe "the 'defined' function" do
- before :each do
- Puppet::Node::Environment.stubs(:current).returns(nil)
- @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("foo"))
- @scope = Puppet::Parser::Scope.new(:compiler => @compiler)
- end
-
- it "should exist" do
- Puppet::Parser::Functions.function("defined").should == "function_defined"
- end
-
- it "should be true when the name is defined as a class" do
- @scope.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "yayness")
- @scope.function_defined("yayness").should be_true
- end
-
- it "should be true when the name is defined as a definition" do
- @scope.known_resource_types.add Puppet::Resource::Type.new(:definition, "yayness")
- @scope.function_defined("yayness").should be_true
- end
-
- it "should be true when the name is defined as a builtin type" do
- @scope.function_defined("file").should be_true
- end
-
-
- it "should be true when any of the provided names are defined" do
- @scope.known_resource_types.add Puppet::Resource::Type.new(:definition, "yayness")
- @scope.function_defined(["meh", "yayness", "booness"]).should be_true
- end
-
- it "should be false when a single given name is not defined" do
- @scope.function_defined("meh").should be_false
- end
-
- it "should be false when none of the names are defined" do
- @scope.function_defined(["meh", "yayness", "booness"]).should be_false
- end
-
- it "should be true when a resource reference is provided and the resource is in the catalog" do
- resource = Puppet::Resource.new("file", "/my/file")
- @compiler.add_resource(@scope, resource)
- @scope.function_defined(resource).should be_true
- end
+ before :each do
+ Puppet::Node::Environment.stubs(:current).returns(nil)
+ @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("foo"))
+ @scope = Puppet::Parser::Scope.new(:compiler => @compiler)
+ end
+
+ it "should exist" do
+ Puppet::Parser::Functions.function("defined").should == "function_defined"
+ end
+
+ it "should be true when the name is defined as a class" do
+ @scope.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "yayness")
+ @scope.function_defined("yayness").should be_true
+ end
+
+ it "should be true when the name is defined as a definition" do
+ @scope.known_resource_types.add Puppet::Resource::Type.new(:definition, "yayness")
+ @scope.function_defined("yayness").should be_true
+ end
+
+ it "should be true when the name is defined as a builtin type" do
+ @scope.function_defined("file").should be_true
+ end
+
+
+ it "should be true when any of the provided names are defined" do
+ @scope.known_resource_types.add Puppet::Resource::Type.new(:definition, "yayness")
+ @scope.function_defined(["meh", "yayness", "booness"]).should be_true
+ end
+
+ it "should be false when a single given name is not defined" do
+ @scope.function_defined("meh").should be_false
+ end
+
+ it "should be false when none of the names are defined" do
+ @scope.function_defined(["meh", "yayness", "booness"]).should be_false
+ end
+
+ it "should be true when a resource reference is provided and the resource is in the catalog" do
+ resource = Puppet::Resource.new("file", "/my/file")
+ @compiler.add_resource(@scope, resource)
+ @scope.function_defined(resource).should be_true
+ end
end
diff --git a/spec/unit/parser/functions/fqdn_rand_spec.rb b/spec/unit/parser/functions/fqdn_rand_spec.rb
index 07390ed..81c12c6 100644
--- a/spec/unit/parser/functions/fqdn_rand_spec.rb
+++ b/spec/unit/parser/functions/fqdn_rand_spec.rb
@@ -4,59 +4,59 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe "the fqdn_rand function" do
- before :each do
- @scope = Puppet::Parser::Scope.new
- end
-
- it "should exist" do
- Puppet::Parser::Functions.function("fqdn_rand").should == "function_fqdn_rand"
- end
-
- it "should handle 0 arguments" do
- @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1")
- lambda { @scope.function_fqdn_rand([]) }.should_not raise_error(Puppet::ParseError)
- end
-
- it "should handle 1 argument'}" do
- @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1")
- lambda { @scope.function_fqdn_rand([3]) }.should_not raise_error(Puppet::ParseError)
- end
-
-
- (1..10).each { |n|
- it "should handle #{n} additional arguments" do
- @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1")
- lambda { @scope.function_fqdn_rand([3,1,2,3,4,5,6,7,8,9,10][0..n]) }.should_not raise_error(Puppet::ParseError)
- end
- it "should handle #{n} additional string arguments" do
- @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1")
- lambda { @scope.function_fqdn_rand([3,%w{ 1 2 3 4 5 6 7 8 9 10}].flatten[0..n]) }.should_not raise_error(Puppet::ParseError)
- end
- }
-
- it "should return a value less than max" do
- @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1")
- @scope.function_fqdn_rand([3]).should satisfy {|n| n.to_i < 3 }
- end
-
- it "should return the same values on subsequent invocations for the same host" do
- @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1").twice
- @scope.function_fqdn_rand([3,4]).should eql(@scope.function_fqdn_rand([3, 4]))
- end
-
- it "should return different sequences of value for different hosts" do
- @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1")
- val1 = @scope.function_fqdn_rand([10000000,4])
- @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.2")
- val2 = @scope.function_fqdn_rand([10000000,4])
- val1.should_not eql(val2)
- end
-
- it "should return different values for the same hosts with different seeds" do
- @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1")
- val1 = @scope.function_fqdn_rand([10000000,4])
- @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1")
- val2 = @scope.function_fqdn_rand([10000000,42])
- val1.should_not eql(val2)
- end
+ before :each do
+ @scope = Puppet::Parser::Scope.new
+ end
+
+ it "should exist" do
+ Puppet::Parser::Functions.function("fqdn_rand").should == "function_fqdn_rand"
+ end
+
+ it "should handle 0 arguments" do
+ @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1")
+ lambda { @scope.function_fqdn_rand([]) }.should_not raise_error(Puppet::ParseError)
+ end
+
+ it "should handle 1 argument'}" do
+ @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1")
+ lambda { @scope.function_fqdn_rand([3]) }.should_not raise_error(Puppet::ParseError)
+ end
+
+
+ (1..10).each { |n|
+ it "should handle #{n} additional arguments" do
+ @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1")
+ lambda { @scope.function_fqdn_rand([3,1,2,3,4,5,6,7,8,9,10][0..n]) }.should_not raise_error(Puppet::ParseError)
+ end
+ it "should handle #{n} additional string arguments" do
+ @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1")
+ lambda { @scope.function_fqdn_rand([3,%w{ 1 2 3 4 5 6 7 8 9 10}].flatten[0..n]) }.should_not raise_error(Puppet::ParseError)
+ end
+ }
+
+ it "should return a value less than max" do
+ @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1")
+ @scope.function_fqdn_rand([3]).should satisfy {|n| n.to_i < 3 }
+ end
+
+ it "should return the same values on subsequent invocations for the same host" do
+ @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1").twice
+ @scope.function_fqdn_rand([3,4]).should eql(@scope.function_fqdn_rand([3, 4]))
+ end
+
+ it "should return different sequences of value for different hosts" do
+ @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1")
+ val1 = @scope.function_fqdn_rand([10000000,4])
+ @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.2")
+ val2 = @scope.function_fqdn_rand([10000000,4])
+ val1.should_not eql(val2)
+ end
+
+ it "should return different values for the same hosts with different seeds" do
+ @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1")
+ val1 = @scope.function_fqdn_rand([10000000,4])
+ @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1")
+ val2 = @scope.function_fqdn_rand([10000000,42])
+ val1.should_not eql(val2)
+ end
end
diff --git a/spec/unit/parser/functions/generate_spec.rb b/spec/unit/parser/functions/generate_spec.rb
index 27a11aa..27aabe2 100755
--- a/spec/unit/parser/functions/generate_spec.rb
+++ b/spec/unit/parser/functions/generate_spec.rb
@@ -4,38 +4,38 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe "the generate function" do
- before :each do
- @scope = Puppet::Parser::Scope.new
- end
-
- it "should exist" do
- Puppet::Parser::Functions.function("generate").should == "function_generate"
- end
-
- it "should accept a fully-qualified path as a command" do
- command = File::SEPARATOR + "command"
- Puppet::Util.expects(:execute).with([command]).returns("yay")
- lambda { @scope.function_generate([command]) }.should_not raise_error(Puppet::ParseError)
- end
-
- it "should not accept a relative path as a command" do
- command = "command"
- lambda { @scope.function_generate([command]) }.should raise_error(Puppet::ParseError)
- end
-
- # Really not sure how to implement this test, just sure it needs
- # to be implemented.
- it "should not accept a command containing illegal characters"
-
- it "should not accept a command containing '..'" do
- command = File::SEPARATOR + "command#{File::SEPARATOR}..#{File::SEPARATOR}"
- lambda { @scope.function_generate([command]) }.should raise_error(Puppet::ParseError)
- end
-
- it "should execute the generate script with the correct working directory" do
- command = File::SEPARATOR + "command"
- Dir.expects(:chdir).with(File.dirname(command)).yields
- Puppet::Util.expects(:execute).with([command]).returns("yay")
- lambda { @scope.function_generate([command]) }.should_not raise_error(Puppet::ParseError)
- end
+ before :each do
+ @scope = Puppet::Parser::Scope.new
+ end
+
+ it "should exist" do
+ Puppet::Parser::Functions.function("generate").should == "function_generate"
+ end
+
+ it "should accept a fully-qualified path as a command" do
+ command = File::SEPARATOR + "command"
+ Puppet::Util.expects(:execute).with([command]).returns("yay")
+ lambda { @scope.function_generate([command]) }.should_not raise_error(Puppet::ParseError)
+ end
+
+ it "should not accept a relative path as a command" do
+ command = "command"
+ lambda { @scope.function_generate([command]) }.should raise_error(Puppet::ParseError)
+ end
+
+ # Really not sure how to implement this test, just sure it needs
+ # to be implemented.
+ it "should not accept a command containing illegal characters"
+
+ it "should not accept a command containing '..'" do
+ command = File::SEPARATOR + "command#{File::SEPARATOR}..#{File::SEPARATOR}"
+ lambda { @scope.function_generate([command]) }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should execute the generate script with the correct working directory" do
+ command = File::SEPARATOR + "command"
+ Dir.expects(:chdir).with(File.dirname(command)).yields
+ Puppet::Util.expects(:execute).with([command]).returns("yay")
+ lambda { @scope.function_generate([command]) }.should_not raise_error(Puppet::ParseError)
+ end
end
diff --git a/spec/unit/parser/functions/inline_template_spec.rb b/spec/unit/parser/functions/inline_template_spec.rb
index 1da8551..62f389e 100755
--- a/spec/unit/parser/functions/inline_template_spec.rb
+++ b/spec/unit/parser/functions/inline_template_spec.rb
@@ -4,56 +4,56 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe "the inline_template function" do
- before :each do
- @scope = Puppet::Parser::Scope.new
- end
+ before :each do
+ @scope = Puppet::Parser::Scope.new
+ end
- it "should exist" do
- Puppet::Parser::Functions.function("inline_template").should == "function_inline_template"
- end
+ it "should exist" do
+ Puppet::Parser::Functions.function("inline_template").should == "function_inline_template"
+ end
- it "should create a TemplateWrapper when called" do
- tw = stub_everything 'template_wrapper'
+ it "should create a TemplateWrapper when called" do
+ tw = stub_everything 'template_wrapper'
- Puppet::Parser::TemplateWrapper.expects(:new).returns(tw)
+ Puppet::Parser::TemplateWrapper.expects(:new).returns(tw)
- @scope.function_inline_template("test")
- end
+ @scope.function_inline_template("test")
+ end
- it "should pass the template string to TemplateWrapper.result" do
- tw = stub_everything 'template_wrapper'
- Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw)
+ it "should pass the template string to TemplateWrapper.result" do
+ tw = stub_everything 'template_wrapper'
+ Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw)
- tw.expects(:result).with("test")
+ tw.expects(:result).with("test")
- @scope.function_inline_template("test")
- end
+ @scope.function_inline_template("test")
+ end
- it "should return what TemplateWrapper.result returns" do
- tw = stub_everything 'template_wrapper'
- Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw)
+ it "should return what TemplateWrapper.result returns" do
+ tw = stub_everything 'template_wrapper'
+ Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw)
- tw.expects(:result).returns("template contents evaluated")
+ tw.expects(:result).returns("template contents evaluated")
- @scope.function_inline_template("test").should == "template contents evaluated"
- end
+ @scope.function_inline_template("test").should == "template contents evaluated"
+ end
- it "should concatenate template wrapper outputs for multiple templates" do
- tw1 = stub_everything "template_wrapper1"
- tw2 = stub_everything "template_wrapper2"
- Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw1,tw2)
- tw1.stubs(:result).returns("result1")
- tw2.stubs(:result).returns("result2")
+ it "should concatenate template wrapper outputs for multiple templates" do
+ tw1 = stub_everything "template_wrapper1"
+ tw2 = stub_everything "template_wrapper2"
+ Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw1,tw2)
+ tw1.stubs(:result).returns("result1")
+ tw2.stubs(:result).returns("result2")
- @scope.function_inline_template(["1","2"]).should == "result1result2"
- end
+ @scope.function_inline_template(["1","2"]).should == "result1result2"
+ end
- it "should raise an error if the template raises an error" do
- tw = stub_everything 'template_wrapper'
- Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw)
- tw.stubs(:result).raises
+ it "should raise an error if the template raises an error" do
+ tw = stub_everything 'template_wrapper'
+ Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw)
+ tw.stubs(:result).raises
- lambda { @scope.function_inline_template("1") }.should raise_error(Puppet::ParseError)
- end
+ lambda { @scope.function_inline_template("1") }.should raise_error(Puppet::ParseError)
+ end
end
\ No newline at end of file
diff --git a/spec/unit/parser/functions/realize_spec.rb b/spec/unit/parser/functions/realize_spec.rb
index 4a55ad4..82f4fa2 100755
--- a/spec/unit/parser/functions/realize_spec.rb
+++ b/spec/unit/parser/functions/realize_spec.rb
@@ -4,48 +4,48 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe "the realize function" do
- before :each do
- @collector = stub_everything 'collector'
- @scope = Puppet::Parser::Scope.new
- @compiler = stub 'compiler'
- @compiler.stubs(:add_collection).with(@collector)
- @scope.stubs(:compiler).returns(@compiler)
- end
+ before :each do
+ @collector = stub_everything 'collector'
+ @scope = Puppet::Parser::Scope.new
+ @compiler = stub 'compiler'
+ @compiler.stubs(:add_collection).with(@collector)
+ @scope.stubs(:compiler).returns(@compiler)
+ end
- it "should exist" do
- Puppet::Parser::Functions.function("realize").should == "function_realize"
- end
+ it "should exist" do
+ Puppet::Parser::Functions.function("realize").should == "function_realize"
+ end
- it "should create a Collector when called" do
+ it "should create a Collector when called" do
- Puppet::Parser::Collector.expects(:new).returns(@collector)
+ Puppet::Parser::Collector.expects(:new).returns(@collector)
- @scope.function_realize("test")
- end
+ @scope.function_realize("test")
+ end
- it "should assign the passed-in resources to the collector" do
- Puppet::Parser::Collector.stubs(:new).returns(@collector)
+ it "should assign the passed-in resources to the collector" do
+ Puppet::Parser::Collector.stubs(:new).returns(@collector)
- @collector.expects(:resources=).with(["test"])
+ @collector.expects(:resources=).with(["test"])
- @scope.function_realize("test")
- end
+ @scope.function_realize("test")
+ end
- it "should flatten the resources assigned to the collector" do
- Puppet::Parser::Collector.stubs(:new).returns(@collector)
+ it "should flatten the resources assigned to the collector" do
+ Puppet::Parser::Collector.stubs(:new).returns(@collector)
- @collector.expects(:resources=).with(["test"])
+ @collector.expects(:resources=).with(["test"])
- @scope.function_realize([["test"]])
- end
+ @scope.function_realize([["test"]])
+ end
- it "should let the compiler know this collector" do
- Puppet::Parser::Collector.stubs(:new).returns(@collector)
- @collector.stubs(:resources=).with(["test"])
+ it "should let the compiler know this collector" do
+ Puppet::Parser::Collector.stubs(:new).returns(@collector)
+ @collector.stubs(:resources=).with(["test"])
- @compiler.expects(:add_collection).with(@collector)
+ @compiler.expects(:add_collection).with(@collector)
- @scope.function_realize("test")
- end
+ @scope.function_realize("test")
+ end
end
diff --git a/spec/unit/parser/functions/regsubst_spec.rb b/spec/unit/parser/functions/regsubst_spec.rb
index d87b4d9..47126dd 100755
--- a/spec/unit/parser/functions/regsubst_spec.rb
+++ b/spec/unit/parser/functions/regsubst_spec.rb
@@ -4,189 +4,189 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe "the regsubst function" do
- before :each do
- @scope = Puppet::Parser::Scope.new
- end
+ before :each do
+ @scope = Puppet::Parser::Scope.new
+ end
- it "should exist" do
- Puppet::Parser::Functions.function("regsubst").should == "function_regsubst"
- end
+ it "should exist" do
+ Puppet::Parser::Functions.function("regsubst").should == "function_regsubst"
+ end
- it "should raise a ParseError if there is less than 3 arguments" do
- lambda { @scope.function_regsubst(["foo", "bar"]) }.should( raise_error(Puppet::ParseError))
- end
+ it "should raise a ParseError if there is less than 3 arguments" do
+ lambda { @scope.function_regsubst(["foo", "bar"]) }.should( raise_error(Puppet::ParseError))
+ end
- it "should raise a ParseError if there is more than 5 arguments" do
- lambda { @scope.function_regsubst(["foo", "bar", "gazonk", "del", "x", "y"]) }.should( raise_error(Puppet::ParseError))
- end
+ it "should raise a ParseError if there is more than 5 arguments" do
+ lambda { @scope.function_regsubst(["foo", "bar", "gazonk", "del", "x", "y"]) }.should( raise_error(Puppet::ParseError))
+ end
- it "should raise a ParseError when given a bad flag" do
- lambda { @scope.function_regsubst(["foo", "bar", "gazonk", "X"]) }.should( raise_error(Puppet::ParseError))
- end
+ it "should raise a ParseError when given a bad flag" do
+ lambda { @scope.function_regsubst(["foo", "bar", "gazonk", "X"]) }.should( raise_error(Puppet::ParseError))
+ end
- it "should raise a ParseError for non-string and non-array target" do
- lambda { @scope.function_regsubst([4711, "bar", "gazonk"]) }.should( raise_error(Puppet::ParseError))
- end
+ it "should raise a ParseError for non-string and non-array target" do
+ lambda { @scope.function_regsubst([4711, "bar", "gazonk"]) }.should( raise_error(Puppet::ParseError))
+ end
- it "should raise a ParseError for array target with non-string element" do
- lambda { @scope.function_regsubst([["x", ["y"], "z"], "bar", "gazonk"]) }.should( raise_error(Puppet::ParseError))
- end
+ it "should raise a ParseError for array target with non-string element" do
+ lambda { @scope.function_regsubst([["x", ["y"], "z"], "bar", "gazonk"]) }.should( raise_error(Puppet::ParseError))
+ end
- it "should raise a ParseError for a bad regular expression" do
- lambda { @scope.function_regsubst(["foo", "(bar", "gazonk"]) }.should(
- raise_error(Puppet::ParseError))
- end
+ it "should raise a ParseError for a bad regular expression" do
+ lambda { @scope.function_regsubst(["foo", "(bar", "gazonk"]) }.should(
+ raise_error(Puppet::ParseError))
+ end
- it "should raise a ParseError for a non-string regular expression" do
- lambda { @scope.function_regsubst(["foo", ["bar"], "gazonk"]) }.should( raise_error(Puppet::ParseError))
- end
+ it "should raise a ParseError for a non-string regular expression" do
+ lambda { @scope.function_regsubst(["foo", ["bar"], "gazonk"]) }.should( raise_error(Puppet::ParseError))
+ end
- it "should handle groups" do
+ it "should handle groups" do
- result = @scope.function_regsubst(
+ result = @scope.function_regsubst(
- [ '130.236.254.10',
+ [ '130.236.254.10',
- '^([0-9]+)[.]([0-9]+)[.]([0-9]+)[.]([0-9]+)$',
- '\4-\3-\2-\1'
- ])
- result.should(eql("10-254-236-130"))
- end
+ '^([0-9]+)[.]([0-9]+)[.]([0-9]+)[.]([0-9]+)$',
+ '\4-\3-\2-\1'
+ ])
+ result.should(eql("10-254-236-130"))
+ end
- it "should handle simple regexps" do
+ it "should handle simple regexps" do
- result = @scope.function_regsubst(
+ result = @scope.function_regsubst(
- [ "the monkey breaks banana trees",
- "b[an]*a",
+ [ "the monkey breaks banana trees",
+ "b[an]*a",
- "coconut"
- ])
- result.should(eql("the monkey breaks coconut trees"))
- end
+ "coconut"
+ ])
+ result.should(eql("the monkey breaks coconut trees"))
+ end
- it "should handle case-sensitive regexps" do
+ it "should handle case-sensitive regexps" do
- result = @scope.function_regsubst(
+ result = @scope.function_regsubst(
- [ "the monkey breaks baNAna trees",
- "b[an]+a",
+ [ "the monkey breaks baNAna trees",
+ "b[an]+a",
- "coconut"
- ])
- result.should(eql("the monkey breaks baNAna trees"))
- end
+ "coconut"
+ ])
+ result.should(eql("the monkey breaks baNAna trees"))
+ end
- it "should handle case-insensitive regexps" do
+ it "should handle case-insensitive regexps" do
- result = @scope.function_regsubst(
+ result = @scope.function_regsubst(
- [ "the monkey breaks baNAna trees",
- "b[an]+a",
- "coconut",
+ [ "the monkey breaks baNAna trees",
+ "b[an]+a",
+ "coconut",
- "I"
- ])
- result.should(eql("the monkey breaks coconut trees"))
- end
+ "I"
+ ])
+ result.should(eql("the monkey breaks coconut trees"))
+ end
- it "should handle global substitutions" do
+ it "should handle global substitutions" do
- result = @scope.function_regsubst(
+ result = @scope.function_regsubst(
- [ "the monkey breaks\tbanana trees",
- "[ \t]",
- "--",
+ [ "the monkey breaks\tbanana trees",
+ "[ \t]",
+ "--",
- "G"
- ])
- result.should(eql("the--monkey--breaks--banana--trees"))
- end
+ "G"
+ ])
+ result.should(eql("the--monkey--breaks--banana--trees"))
+ end
- it "should handle global substitutions with groups" do
+ it "should handle global substitutions with groups" do
- result = @scope.function_regsubst(
+ result = @scope.function_regsubst(
- [ '130.236.254.10',
+ [ '130.236.254.10',
- '([0-9]+)',
- '<\1>',
- 'G'
- ])
- result.should(eql('<130>.<236>.<254>.<10>'))
- end
+ '([0-9]+)',
+ '<\1>',
+ 'G'
+ ])
+ result.should(eql('<130>.<236>.<254>.<10>'))
+ end
- it "should apply on all elements of an array" do
- data = ['130.236.254.10', 'foo.example.com', 'coconut', '10.20.30.40']
- result = @scope.function_regsubst([ data, '[.]', '-'])
- result.should(eql( ['130-236.254.10', 'foo-example.com', 'coconut', '10-20.30.40']))
- end
+ it "should apply on all elements of an array" do
+ data = ['130.236.254.10', 'foo.example.com', 'coconut', '10.20.30.40']
+ result = @scope.function_regsubst([ data, '[.]', '-'])
+ result.should(eql( ['130-236.254.10', 'foo-example.com', 'coconut', '10-20.30.40']))
+ end
- it "should apply global substitutions on all elements of an array" do
- data = ['130.236.254.10', 'foo.example.com', 'coconut', '10.20.30.40']
- result = @scope.function_regsubst([ data, '[.]', '-', 'G'])
- result.should(eql( ['130-236-254-10', 'foo-example-com', 'coconut', '10-20-30-40']))
- end
+ it "should apply global substitutions on all elements of an array" do
+ data = ['130.236.254.10', 'foo.example.com', 'coconut', '10.20.30.40']
+ result = @scope.function_regsubst([ data, '[.]', '-', 'G'])
+ result.should(eql( ['130-236-254-10', 'foo-example-com', 'coconut', '10-20-30-40']))
+ end
- it "should handle groups on all elements of an array" do
- data = ['130.236.254.10', 'foo.example.com', 'coconut', '10.20.30.40']
+ it "should handle groups on all elements of an array" do
+ data = ['130.236.254.10', 'foo.example.com', 'coconut', '10.20.30.40']
- result = @scope.function_regsubst(
+ result = @scope.function_regsubst(
- [ data,
+ [ data,
- '^([0-9]+)[.]([0-9]+)[.]([0-9]+)[.]([0-9]+)$',
- '\4-\3-\2-\1'
- ])
- result.should(eql( ['10-254-236-130', 'foo.example.com', 'coconut', '40-30-20-10']))
- end
+ '^([0-9]+)[.]([0-9]+)[.]([0-9]+)[.]([0-9]+)$',
+ '\4-\3-\2-\1'
+ ])
+ result.should(eql( ['10-254-236-130', 'foo.example.com', 'coconut', '40-30-20-10']))
+ end
- it "should handle global substitutions with groups on all elements of an array" do
- data = ['130.236.254.10', 'foo.example.com', 'coconut', '10.20.30.40']
+ it "should handle global substitutions with groups on all elements of an array" do
+ data = ['130.236.254.10', 'foo.example.com', 'coconut', '10.20.30.40']
- result = @scope.function_regsubst(
+ result = @scope.function_regsubst(
- [ data,
+ [ data,
- '([^.]+)',
- '<\1>',
- 'G'
- ])
+ '([^.]+)',
+ '<\1>',
+ 'G'
+ ])
- result.should(eql(
+ result.should(eql(
- ['<130>.<236>.<254>.<10>', '<foo>.<example>.<com>',
+ ['<130>.<236>.<254>.<10>', '<foo>.<example>.<com>',
- '<coconut>', '<10>.<20>.<30>.<40>']))
- end
+ '<coconut>', '<10>.<20>.<30>.<40>']))
+ end
- it "should return an array (not a string) for a single element array parameter" do
- data = ['130.236.254.10']
+ it "should return an array (not a string) for a single element array parameter" do
+ data = ['130.236.254.10']
- result = @scope.function_regsubst(
+ result = @scope.function_regsubst(
- [ data,
+ [ data,
- '([^.]+)',
- '<\1>',
- 'G'
- ])
- result.should(eql(['<130>.<236>.<254>.<10>']))
- end
+ '([^.]+)',
+ '<\1>',
+ 'G'
+ ])
+ result.should(eql(['<130>.<236>.<254>.<10>']))
+ end
- it "should return a string (not a one element array) for a simple string parameter" do
- data = '130.236.254.10'
+ it "should return a string (not a one element array) for a simple string parameter" do
+ data = '130.236.254.10'
- result = @scope.function_regsubst(
+ result = @scope.function_regsubst(
- [ data,
+ [ data,
- '([^.]+)',
- '<\1>',
- 'G'
- ])
- result.should(eql('<130>.<236>.<254>.<10>'))
- end
+ '([^.]+)',
+ '<\1>',
+ 'G'
+ ])
+ result.should(eql('<130>.<236>.<254>.<10>'))
+ end
end
diff --git a/spec/unit/parser/functions/require_spec.rb b/spec/unit/parser/functions/require_spec.rb
index 48769d1..bd42fa5 100755
--- a/spec/unit/parser/functions/require_spec.rb
+++ b/spec/unit/parser/functions/require_spec.rb
@@ -4,71 +4,71 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe "the require function" do
- before :each do
- @catalog = stub 'catalog'
- @compiler = stub 'compiler', :catalog => @catalog
+ before :each do
+ @catalog = stub 'catalog'
+ @compiler = stub 'compiler', :catalog => @catalog
- @scope = Puppet::Parser::Scope.new
- @scope.stubs(:findresource)
- @scope.stubs(:compiler).returns(@compiler)
- @klass = stub 'class', :name => "myclass"
- @scope.stubs(:find_hostclass).returns(@klass)
+ @scope = Puppet::Parser::Scope.new
+ @scope.stubs(:findresource)
+ @scope.stubs(:compiler).returns(@compiler)
+ @klass = stub 'class', :name => "myclass"
+ @scope.stubs(:find_hostclass).returns(@klass)
- @resource = Puppet::Parser::Resource.new(:file, "/my/file", :scope => @scope, :source => "source")
- @resource.stubs(:metaparam_compatibility_mode?).returns false
- @scope.stubs(:resource).returns @resource
- end
+ @resource = Puppet::Parser::Resource.new(:file, "/my/file", :scope => @scope, :source => "source")
+ @resource.stubs(:metaparam_compatibility_mode?).returns false
+ @scope.stubs(:resource).returns @resource
+ end
- it "should exist" do
- Puppet::Parser::Functions.function("require").should == "function_require"
- end
+ it "should exist" do
+ Puppet::Parser::Functions.function("require").should == "function_require"
+ end
- it "should delegate to the 'include' puppet function" do
- @scope.expects(:function_include).with("myclass")
+ it "should delegate to the 'include' puppet function" do
+ @scope.expects(:function_include).with("myclass")
- @scope.function_require("myclass")
- end
+ @scope.function_require("myclass")
+ end
- it "should set the 'require' prarameter on the resource to a resource reference" do
- @scope.stubs(:function_include)
- @scope.function_require("myclass")
+ it "should set the 'require' prarameter on the resource to a resource reference" do
+ @scope.stubs(:function_include)
+ @scope.function_require("myclass")
- @resource["require"].should be_instance_of(Array)
- @resource["require"][0].should be_instance_of(Puppet::Resource)
- end
+ @resource["require"].should be_instance_of(Array)
+ @resource["require"][0].should be_instance_of(Puppet::Resource)
+ end
- it "should verify the 'include' function is loaded" do
- Puppet::Parser::Functions.expects(:function).with(:include).returns(:function_include)
- @scope.stubs(:function_include)
- @scope.function_require("myclass")
- end
+ it "should verify the 'include' function is loaded" do
+ Puppet::Parser::Functions.expects(:function).with(:include).returns(:function_include)
+ @scope.stubs(:function_include)
+ @scope.function_require("myclass")
+ end
- it "should include the class but not add a dependency if used on a client not at least version 0.25" do
- @resource.expects(:metaparam_compatibility_mode?).returns true
- @scope.expects(:warning)
- @resource.expects(:set_parameter).never
- @scope.expects(:function_include)
+ it "should include the class but not add a dependency if used on a client not at least version 0.25" do
+ @resource.expects(:metaparam_compatibility_mode?).returns true
+ @scope.expects(:warning)
+ @resource.expects(:set_parameter).never
+ @scope.expects(:function_include)
- @scope.function_require("myclass")
- end
+ @scope.function_require("myclass")
+ end
- it "should lookup the absolute class path" do
- @scope.stubs(:function_include)
+ it "should lookup the absolute class path" do
+ @scope.stubs(:function_include)
- @scope.expects(:find_hostclass).with("myclass").returns(@klass)
- @klass.expects(:name).returns("myclass")
+ @scope.expects(:find_hostclass).with("myclass").returns(@klass)
+ @klass.expects(:name).returns("myclass")
- @scope.function_require("myclass")
- end
+ @scope.function_require("myclass")
+ end
- it "should append the required class to the require parameter" do
- @scope.stubs(:function_include)
+ it "should append the required class to the require parameter" do
+ @scope.stubs(:function_include)
- one = Puppet::Resource.new(:file, "/one")
- @resource[:require] = one
- @scope.function_require("myclass")
+ one = Puppet::Resource.new(:file, "/one")
+ @resource[:require] = one
+ @scope.function_require("myclass")
- @resource[:require].should be_include(one)
- @resource[:require].detect { |r| r.to_s == "Class[Myclass]" }.should be_instance_of(Puppet::Resource)
- end
+ @resource[:require].should be_include(one)
+ @resource[:require].detect { |r| r.to_s == "Class[Myclass]" }.should be_instance_of(Puppet::Resource)
+ end
end
diff --git a/spec/unit/parser/functions/shellquote_spec.rb b/spec/unit/parser/functions/shellquote_spec.rb
index e4eeaeb..46b9f8d 100755
--- a/spec/unit/parser/functions/shellquote_spec.rb
+++ b/spec/unit/parser/functions/shellquote_spec.rb
@@ -4,78 +4,78 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe "the shellquote function" do
- before :each do
- @scope = Puppet::Parser::Scope.new
- end
-
- it "should exist" do
- Puppet::Parser::Functions.function("shellquote").should == "function_shellquote"
- end
-
-
- it "should handle no arguments" do
- result = @scope.function_shellquote([])
- result.should(eql(""))
- end
-
- it "should handle several simple arguments" do
- result = @scope.function_shellquote( ['foo', 'bar at example.com', 'localhost:/dev/null', 'xyzzy+-4711,23'])
- result.should(eql( 'foo bar at example.com localhost:/dev/null xyzzy+-4711,23'))
- end
-
- it "should handle array arguments" do
-
- result = @scope.function_shellquote(
-
- ['foo', ['bar at example.com', 'localhost:/dev/null'],
-
- 'xyzzy+-4711,23'])
- result.should(eql(
- 'foo bar at example.com localhost:/dev/null xyzzy+-4711,23'))
- end
-
- it "should quote unsafe characters" do
- result = @scope.function_shellquote( ['/etc/passwd ', '(ls)', '*', '[?]', "'&'"])
- result.should(eql( '"/etc/passwd " "(ls)" "*" "[?]" "\'&\'"'))
- end
-
- it "should deal with double quotes" do
- result = @scope.function_shellquote(
- ['"foo"bar"'])
- result.should(eql(
- '\'"foo"bar"\''))
- end
-
- it "should cope with dollar signs" do
- result = @scope.function_shellquote( ['$PATH', 'foo$bar', '"x$"'])
- result.should(eql( "'$PATH' 'foo$bar' '\"x$\"'"))
- end
-
- it "should deal with apostrophes (single quotes)" do
- result = @scope.function_shellquote(
- ["'foo'bar'", "`$'EDITOR'`"])
- result.should(eql(
- '"\'foo\'bar\'" "\\`\\$\'EDITOR\'\\`"'))
- end
-
- it "should cope with grave accents (backquotes)" do
- result = @scope.function_shellquote( ['`echo *`', '`ls "$MAILPATH"`'])
- result.should(eql( "'`echo *`' '`ls \"$MAILPATH\"`'"))
- end
-
- it "should deal with both single and double quotes" do
- result = @scope.function_shellquote( ['\'foo"bar"xyzzy\'', '"foo\'bar\'xyzzy"'])
- result.should(eql( '"\'foo\\"bar\\"xyzzy\'" "\\"foo\'bar\'xyzzy\\""'))
- end
-
- it "should handle multiple quotes *and* dollars and backquotes" do
- result = @scope.function_shellquote( ['\'foo"$x`bar`"xyzzy\''])
- result.should(eql( '"\'foo\\"\\$x\\`bar\\`\\"xyzzy\'"'))
- end
-
- it "should handle linefeeds" do
- result = @scope.function_shellquote( ["foo \n bar"])
- result.should(eql( "\"foo \n bar\""))
- end
+ before :each do
+ @scope = Puppet::Parser::Scope.new
+ end
+
+ it "should exist" do
+ Puppet::Parser::Functions.function("shellquote").should == "function_shellquote"
+ end
+
+
+ it "should handle no arguments" do
+ result = @scope.function_shellquote([])
+ result.should(eql(""))
+ end
+
+ it "should handle several simple arguments" do
+ result = @scope.function_shellquote( ['foo', 'bar at example.com', 'localhost:/dev/null', 'xyzzy+-4711,23'])
+ result.should(eql( 'foo bar at example.com localhost:/dev/null xyzzy+-4711,23'))
+ end
+
+ it "should handle array arguments" do
+
+ result = @scope.function_shellquote(
+
+ ['foo', ['bar at example.com', 'localhost:/dev/null'],
+
+ 'xyzzy+-4711,23'])
+ result.should(eql(
+ 'foo bar at example.com localhost:/dev/null xyzzy+-4711,23'))
+ end
+
+ it "should quote unsafe characters" do
+ result = @scope.function_shellquote( ['/etc/passwd ', '(ls)', '*', '[?]', "'&'"])
+ result.should(eql( '"/etc/passwd " "(ls)" "*" "[?]" "\'&\'"'))
+ end
+
+ it "should deal with double quotes" do
+ result = @scope.function_shellquote(
+ ['"foo"bar"'])
+ result.should(eql(
+ '\'"foo"bar"\''))
+ end
+
+ it "should cope with dollar signs" do
+ result = @scope.function_shellquote( ['$PATH', 'foo$bar', '"x$"'])
+ result.should(eql( "'$PATH' 'foo$bar' '\"x$\"'"))
+ end
+
+ it "should deal with apostrophes (single quotes)" do
+ result = @scope.function_shellquote(
+ ["'foo'bar'", "`$'EDITOR'`"])
+ result.should(eql(
+ '"\'foo\'bar\'" "\\`\\$\'EDITOR\'\\`"'))
+ end
+
+ it "should cope with grave accents (backquotes)" do
+ result = @scope.function_shellquote( ['`echo *`', '`ls "$MAILPATH"`'])
+ result.should(eql( "'`echo *`' '`ls \"$MAILPATH\"`'"))
+ end
+
+ it "should deal with both single and double quotes" do
+ result = @scope.function_shellquote( ['\'foo"bar"xyzzy\'', '"foo\'bar\'xyzzy"'])
+ result.should(eql( '"\'foo\\"bar\\"xyzzy\'" "\\"foo\'bar\'xyzzy\\""'))
+ end
+
+ it "should handle multiple quotes *and* dollars and backquotes" do
+ result = @scope.function_shellquote( ['\'foo"$x`bar`"xyzzy\''])
+ result.should(eql( '"\'foo\\"\\$x\\`bar\\`\\"xyzzy\'"'))
+ end
+
+ it "should handle linefeeds" do
+ result = @scope.function_shellquote( ["foo \n bar"])
+ result.should(eql( "\"foo \n bar\""))
+ end
end
diff --git a/spec/unit/parser/functions/split_spec.rb b/spec/unit/parser/functions/split_spec.rb
index d76c253..a1c83bb 100755
--- a/spec/unit/parser/functions/split_spec.rb
+++ b/spec/unit/parser/functions/split_spec.rb
@@ -4,46 +4,46 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe "the split function" do
- before :each do
- @scope = Puppet::Parser::Scope.new
- end
-
- it "should exist" do
- Puppet::Parser::Functions.function("split").should == "function_split"
- end
-
- it "should raise a ParseError if there is less than 2 arguments" do
- lambda { @scope.function_split(["foo"]) }.should( raise_error(Puppet::ParseError))
- end
-
- it "should raise a ParseError if there is more than 2 arguments" do
- lambda { @scope.function_split(["foo", "bar", "gazonk"]) }.should( raise_error(Puppet::ParseError))
- end
-
- it "should raise a RegexpError if the regexp is malformed" do
- lambda { @scope.function_split(["foo", "("]) }.should(
- raise_error(RegexpError))
- end
-
-
- it "should handle simple string without metacharacters" do
- result = @scope.function_split([ "130;236;254;10", ";"])
- result.should(eql(["130", "236", "254", "10"]))
- end
-
- it "should handle simple regexps" do
- result = @scope.function_split([ "130.236;254.;10", "[.;]+"])
- result.should(eql(["130", "236", "254", "10"]))
- end
-
- it "should handle groups" do
- result = @scope.function_split([ "130.236;254.;10", "([.;]+)"])
- result.should(eql(["130", ".", "236", ";", "254", ".;", "10"]))
- end
-
- it "should handle simple string without metacharacters" do
- result = @scope.function_split([ "130.236.254.10", ";"])
- result.should(eql(["130.236.254.10"]))
- end
+ before :each do
+ @scope = Puppet::Parser::Scope.new
+ end
+
+ it "should exist" do
+ Puppet::Parser::Functions.function("split").should == "function_split"
+ end
+
+ it "should raise a ParseError if there is less than 2 arguments" do
+ lambda { @scope.function_split(["foo"]) }.should( raise_error(Puppet::ParseError))
+ end
+
+ it "should raise a ParseError if there is more than 2 arguments" do
+ lambda { @scope.function_split(["foo", "bar", "gazonk"]) }.should( raise_error(Puppet::ParseError))
+ end
+
+ it "should raise a RegexpError if the regexp is malformed" do
+ lambda { @scope.function_split(["foo", "("]) }.should(
+ raise_error(RegexpError))
+ end
+
+
+ it "should handle simple string without metacharacters" do
+ result = @scope.function_split([ "130;236;254;10", ";"])
+ result.should(eql(["130", "236", "254", "10"]))
+ end
+
+ it "should handle simple regexps" do
+ result = @scope.function_split([ "130.236;254.;10", "[.;]+"])
+ result.should(eql(["130", "236", "254", "10"]))
+ end
+
+ it "should handle groups" do
+ result = @scope.function_split([ "130.236;254.;10", "([.;]+)"])
+ result.should(eql(["130", ".", "236", ";", "254", ".;", "10"]))
+ end
+
+ it "should handle simple string without metacharacters" do
+ result = @scope.function_split([ "130.236.254.10", ";"])
+ result.should(eql(["130.236.254.10"]))
+ end
end
diff --git a/spec/unit/parser/functions/sprintf_spec.rb b/spec/unit/parser/functions/sprintf_spec.rb
index 3795479..01545a8 100755
--- a/spec/unit/parser/functions/sprintf_spec.rb
+++ b/spec/unit/parser/functions/sprintf_spec.rb
@@ -4,38 +4,38 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe "the sprintf function" do
- before :each do
- @scope = Puppet::Parser::Scope.new
- end
-
- it "should exist" do
- Puppet::Parser::Functions.function("sprintf").should == "function_sprintf"
- end
-
- it "should raise a ParseError if there is less than 1 argument" do
- lambda { @scope.function_sprintf([]) }.should( raise_error(Puppet::ParseError))
- end
-
- it "should format integers" do
- result = @scope.function_sprintf(["%+05d", "23"])
- result.should(eql("+0023"))
- end
-
- it "should format floats" do
- result = @scope.function_sprintf(["%+.2f", "2.7182818284590451"])
- result.should(eql("+2.72"))
- end
-
- it "should format large floats" do
- result = @scope.function_sprintf(["%+.2e", "27182818284590451"])
- result.should(eql("+2.72e+16"))
- end
-
- it "should perform more complex formatting" do
- result = @scope.function_sprintf(
- [ "<%.8s:%#5o %#8X (%-8s)>",
- "overlongstring", "23", "48879", "foo" ])
- result.should(eql("<overlong: 027 0XBEEF (foo )>"))
- end
+ before :each do
+ @scope = Puppet::Parser::Scope.new
+ end
+
+ it "should exist" do
+ Puppet::Parser::Functions.function("sprintf").should == "function_sprintf"
+ end
+
+ it "should raise a ParseError if there is less than 1 argument" do
+ lambda { @scope.function_sprintf([]) }.should( raise_error(Puppet::ParseError))
+ end
+
+ it "should format integers" do
+ result = @scope.function_sprintf(["%+05d", "23"])
+ result.should(eql("+0023"))
+ end
+
+ it "should format floats" do
+ result = @scope.function_sprintf(["%+.2f", "2.7182818284590451"])
+ result.should(eql("+2.72"))
+ end
+
+ it "should format large floats" do
+ result = @scope.function_sprintf(["%+.2e", "27182818284590451"])
+ result.should(eql("+2.72e+16"))
+ end
+
+ it "should perform more complex formatting" do
+ result = @scope.function_sprintf(
+ [ "<%.8s:%#5o %#8X (%-8s)>",
+ "overlongstring", "23", "48879", "foo" ])
+ result.should(eql("<overlong: 027 0XBEEF (foo )>"))
+ end
end
diff --git a/spec/unit/parser/functions/tag_spec.rb b/spec/unit/parser/functions/tag_spec.rb
index 4f08afe..ff37bad 100755
--- a/spec/unit/parser/functions/tag_spec.rb
+++ b/spec/unit/parser/functions/tag_spec.rb
@@ -4,21 +4,21 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe "the 'tag' function" do
- before :each do
- @scope = Puppet::Parser::Scope.new
- end
+ before :each do
+ @scope = Puppet::Parser::Scope.new
+ end
- it "should exist" do
- Puppet::Parser::Functions.function(:tag).should == "function_tag"
- end
+ it "should exist" do
+ Puppet::Parser::Functions.function(:tag).should == "function_tag"
+ end
- it "should tag the resource with any provided tags" do
- resource = Puppet::Parser::Resource.new(:file, "/file", :scope => @scope)
- @scope.expects(:resource).returns resource
+ it "should tag the resource with any provided tags" do
+ resource = Puppet::Parser::Resource.new(:file, "/file", :scope => @scope)
+ @scope.expects(:resource).returns resource
- @scope.function_tag ["one", "two"]
+ @scope.function_tag ["one", "two"]
- resource.should be_tagged("one")
- resource.should be_tagged("two")
- end
+ resource.should be_tagged("one")
+ resource.should be_tagged("two")
+ end
end
diff --git a/spec/unit/parser/functions/template_spec.rb b/spec/unit/parser/functions/template_spec.rb
index 87c7d5d..096b059 100755
--- a/spec/unit/parser/functions/template_spec.rb
+++ b/spec/unit/parser/functions/template_spec.rb
@@ -4,59 +4,59 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe "the template function" do
- before :each do
- @scope = Puppet::Parser::Scope.new
- end
+ before :each do
+ @scope = Puppet::Parser::Scope.new
+ end
- it "should exist" do
- Puppet::Parser::Functions.function("template").should == "function_template"
- end
+ it "should exist" do
+ Puppet::Parser::Functions.function("template").should == "function_template"
+ end
- it "should create a TemplateWrapper when called" do
- tw = stub_everything 'template_wrapper'
+ it "should create a TemplateWrapper when called" do
+ tw = stub_everything 'template_wrapper'
- Puppet::Parser::TemplateWrapper.expects(:new).returns(tw)
+ Puppet::Parser::TemplateWrapper.expects(:new).returns(tw)
- @scope.function_template("test")
- end
+ @scope.function_template("test")
+ end
- it "should give the template filename to the TemplateWrapper" do
- tw = stub_everything 'template_wrapper'
- Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw)
+ it "should give the template filename to the TemplateWrapper" do
+ tw = stub_everything 'template_wrapper'
+ Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw)
- tw.expects(:file=).with("test")
+ tw.expects(:file=).with("test")
- @scope.function_template("test")
- end
+ @scope.function_template("test")
+ end
- it "should return what TemplateWrapper.result returns" do
- tw = stub_everything 'template_wrapper'
- Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw)
- tw.stubs(:file=).with("test")
+ it "should return what TemplateWrapper.result returns" do
+ tw = stub_everything 'template_wrapper'
+ Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw)
+ tw.stubs(:file=).with("test")
- tw.expects(:result).returns("template contents evaluated")
+ tw.expects(:result).returns("template contents evaluated")
- @scope.function_template("test").should == "template contents evaluated"
- end
+ @scope.function_template("test").should == "template contents evaluated"
+ end
- it "should concatenate template wrapper outputs for multiple templates" do
- tw1 = stub_everything "template_wrapper1"
- tw2 = stub_everything "template_wrapper2"
- Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw1,tw2)
- tw1.stubs(:file=).with("1")
- tw2.stubs(:file=).with("2")
- tw1.stubs(:result).returns("result1")
- tw2.stubs(:result).returns("result2")
+ it "should concatenate template wrapper outputs for multiple templates" do
+ tw1 = stub_everything "template_wrapper1"
+ tw2 = stub_everything "template_wrapper2"
+ Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw1,tw2)
+ tw1.stubs(:file=).with("1")
+ tw2.stubs(:file=).with("2")
+ tw1.stubs(:result).returns("result1")
+ tw2.stubs(:result).returns("result2")
- @scope.function_template(["1","2"]).should == "result1result2"
- end
+ @scope.function_template(["1","2"]).should == "result1result2"
+ end
- it "should raise an error if the template raises an error" do
- tw = stub_everything 'template_wrapper'
- Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw)
- tw.stubs(:result).raises
+ it "should raise an error if the template raises an error" do
+ tw = stub_everything 'template_wrapper'
+ Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw)
+ tw.stubs(:result).raises
- lambda { @scope.function_template("1") }.should raise_error(Puppet::ParseError)
- end
+ lambda { @scope.function_template("1") }.should raise_error(Puppet::ParseError)
+ end
end
\ No newline at end of file
diff --git a/spec/unit/parser/functions/versioncmp_spec.rb b/spec/unit/parser/functions/versioncmp_spec.rb
index d57ea57..380c630 100755
--- a/spec/unit/parser/functions/versioncmp_spec.rb
+++ b/spec/unit/parser/functions/versioncmp_spec.rb
@@ -4,26 +4,26 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe "the versioncmp function" do
- before :each do
- @scope = Puppet::Parser::Scope.new
- end
+ before :each do
+ @scope = Puppet::Parser::Scope.new
+ end
- it "should exist" do
- Puppet::Parser::Functions.function("versioncmp").should == "function_versioncmp"
- end
+ it "should exist" do
+ Puppet::Parser::Functions.function("versioncmp").should == "function_versioncmp"
+ end
- it "should raise a ParseError if there is less than 2 arguments" do
- lambda { @scope.function_versioncmp(["1.2"]) }.should raise_error(Puppet::ParseError)
- end
+ it "should raise a ParseError if there is less than 2 arguments" do
+ lambda { @scope.function_versioncmp(["1.2"]) }.should raise_error(Puppet::ParseError)
+ end
- it "should raise a ParseError if there is more than 2 arguments" do
- lambda { @scope.function_versioncmp(["1.2", "2.4.5", "3.5.6"]) }.should raise_error(Puppet::ParseError)
- end
+ it "should raise a ParseError if there is more than 2 arguments" do
+ lambda { @scope.function_versioncmp(["1.2", "2.4.5", "3.5.6"]) }.should raise_error(Puppet::ParseError)
+ end
- it "should call Puppet::Util::Package.versioncmp (included in scope)" do
- Puppet::Util::Package.expects(:versioncmp).with("1.2", "1.3").returns(-1)
+ it "should call Puppet::Util::Package.versioncmp (included in scope)" do
+ Puppet::Util::Package.expects(:versioncmp).with("1.2", "1.3").returns(-1)
- @scope.function_versioncmp(["1.2", "1.3"])
- end
+ @scope.function_versioncmp(["1.2", "1.3"])
+ end
end
diff --git a/spec/unit/parser/functions_spec.rb b/spec/unit/parser/functions_spec.rb
index ee551a1..18aee4b 100644
--- a/spec/unit/parser/functions_spec.rb
+++ b/spec/unit/parser/functions_spec.rb
@@ -4,99 +4,99 @@ require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::Parser::Functions do
- after(:each) do
- # Rationale:
- # our various tests will almost all register to Pupet::Parser::Functions
- # a new function called "name". All tests are required to stub Puppet::Parser::Scope
- # so that +no+ new real ruby method are defined.
- # After each test, we want to leave the whole Puppet::Parser::Functions environment
- # as it was before we were called, hence we call rmfunction (which might not succeed
- # if the function hasn't been registered in the test). It is also important in this
- # section to stub +remove_method+ here so that we don't pollute the scope.
- Puppet::Parser::Scope.stubs(:remove_method)
- begin
- Puppet::Parser::Functions.rmfunction("name")
- rescue
- end
+ after(:each) do
+ # Rationale:
+ # our various tests will almost all register to Pupet::Parser::Functions
+ # a new function called "name". All tests are required to stub Puppet::Parser::Scope
+ # so that +no+ new real ruby method are defined.
+ # After each test, we want to leave the whole Puppet::Parser::Functions environment
+ # as it was before we were called, hence we call rmfunction (which might not succeed
+ # if the function hasn't been registered in the test). It is also important in this
+ # section to stub +remove_method+ here so that we don't pollute the scope.
+ Puppet::Parser::Scope.stubs(:remove_method)
+ begin
+ Puppet::Parser::Functions.rmfunction("name")
+ rescue
end
+ end
- it "should have a method for returning an environment-specific module" do
- Puppet::Parser::Functions.environment_module("myenv").should be_instance_of(Module)
- end
+ it "should have a method for returning an environment-specific module" do
+ Puppet::Parser::Functions.environment_module("myenv").should be_instance_of(Module)
+ end
- it "should use the current default environment if no environment is provided" do
- Puppet::Parser::Functions.environment_module.should be_instance_of(Module)
- end
+ it "should use the current default environment if no environment is provided" do
+ Puppet::Parser::Functions.environment_module.should be_instance_of(Module)
+ end
- describe "when calling newfunction" do
- before do
- @module = Module.new
- Puppet::Parser::Functions.stubs(:environment_module).returns @module
- end
+ describe "when calling newfunction" do
+ before do
+ @module = Module.new
+ Puppet::Parser::Functions.stubs(:environment_module).returns @module
+ end
- it "should create the function in the environment module" do
- @module.expects(:define_method).with { |name,block| name == "function_name" }
+ it "should create the function in the environment module" do
+ @module.expects(:define_method).with { |name,block| name == "function_name" }
- Puppet::Parser::Functions.newfunction("name", :type => :rvalue)
- end
+ Puppet::Parser::Functions.newfunction("name", :type => :rvalue)
+ end
- it "should raise an error if the function already exists" do
- @module.expects(:define_method).with { |name,block| name == "function_name" }.once
- Puppet::Parser::Functions.newfunction("name", :type => :rvalue)
+ it "should raise an error if the function already exists" do
+ @module.expects(:define_method).with { |name,block| name == "function_name" }.once
+ Puppet::Parser::Functions.newfunction("name", :type => :rvalue)
- lambda { Puppet::Parser::Functions.newfunction("name", :type => :rvalue) }.should raise_error
- end
+ lambda { Puppet::Parser::Functions.newfunction("name", :type => :rvalue) }.should raise_error
+ end
- it "should raise an error if the function type is not correct" do
- @module.expects(:define_method).with { |name,block| name == "function_name" }.never
+ it "should raise an error if the function type is not correct" do
+ @module.expects(:define_method).with { |name,block| name == "function_name" }.never
- lambda { Puppet::Parser::Functions.newfunction("name", :type => :unknown) }.should raise_error
- end
+ lambda { Puppet::Parser::Functions.newfunction("name", :type => :unknown) }.should raise_error
end
+ end
- describe "when calling rmfunction" do
- before do
- @module = Module.new
- Puppet::Parser::Functions.stubs(:environment_module).returns @module
- end
+ describe "when calling rmfunction" do
+ before do
+ @module = Module.new
+ Puppet::Parser::Functions.stubs(:environment_module).returns @module
+ end
- it "should remove the function in the scope class" do
- @module.expects(:define_method).with { |name,block| name == "function_name" }
- Puppet::Parser::Functions.newfunction("name", :type => :rvalue)
+ it "should remove the function in the scope class" do
+ @module.expects(:define_method).with { |name,block| name == "function_name" }
+ Puppet::Parser::Functions.newfunction("name", :type => :rvalue)
- @module.expects(:remove_method).with("function_name").once
+ @module.expects(:remove_method).with("function_name").once
- Puppet::Parser::Functions.rmfunction("name")
- end
+ Puppet::Parser::Functions.rmfunction("name")
+ end
- it "should raise an error if the function doesn't exists" do
- lambda { Puppet::Parser::Functions.rmfunction("name") }.should raise_error
- end
+ it "should raise an error if the function doesn't exists" do
+ lambda { Puppet::Parser::Functions.rmfunction("name") }.should raise_error
end
+ end
- describe "when calling function to test function existance" do
- before do
- @module = Module.new
- Puppet::Parser::Functions.stubs(:environment_module).returns @module
- end
+ describe "when calling function to test function existance" do
+ before do
+ @module = Module.new
+ Puppet::Parser::Functions.stubs(:environment_module).returns @module
+ end
- it "should return false if the function doesn't exist" do
- Puppet::Parser::Functions.autoloader.stubs(:load)
+ it "should return false if the function doesn't exist" do
+ Puppet::Parser::Functions.autoloader.stubs(:load)
- Puppet::Parser::Functions.function("name").should be_false
- end
+ Puppet::Parser::Functions.function("name").should be_false
+ end
- it "should return its name if the function exists" do
- @module.expects(:define_method).with { |name,block| name == "function_name" }
- Puppet::Parser::Functions.newfunction("name", :type => :rvalue)
+ it "should return its name if the function exists" do
+ @module.expects(:define_method).with { |name,block| name == "function_name" }
+ Puppet::Parser::Functions.newfunction("name", :type => :rvalue)
- Puppet::Parser::Functions.function("name").should == "function_name"
- end
+ Puppet::Parser::Functions.function("name").should == "function_name"
+ end
- it "should try to autoload the function if it doesn't exist yet" do
- Puppet::Parser::Functions.autoloader.expects(:load)
+ it "should try to autoload the function if it doesn't exist yet" do
+ Puppet::Parser::Functions.autoloader.expects(:load)
- Puppet::Parser::Functions.function("name")
- end
+ Puppet::Parser::Functions.function("name")
end
+ end
end
diff --git a/spec/unit/parser/lexer_spec.rb b/spec/unit/parser/lexer_spec.rb
index c31b1b2..81e76a3 100755
--- a/spec/unit/parser/lexer_spec.rb
+++ b/spec/unit/parser/lexer_spec.rb
@@ -6,635 +6,635 @@ require 'puppet/parser/lexer'
# This is a special matcher to match easily lexer output
Spec::Matchers.define :be_like do |*expected|
- match do |actual|
- expected.zip(actual).all? { |e,a| !e or a[0] == e or (e.is_a? Array and a[0] == e[0] and (a[1] == e[1] or (a[1].is_a?(Hash) and a[1][:value] == e[1]))) }
- end
+ match do |actual|
+ expected.zip(actual).all? { |e,a| !e or a[0] == e or (e.is_a? Array and a[0] == e[0] and (a[1] == e[1] or (a[1].is_a?(Hash) and a[1][:value] == e[1]))) }
+ end
end
__ = nil
describe Puppet::Parser::Lexer do
- describe "when reading strings" do
- before { @lexer = Puppet::Parser::Lexer.new }
- it "should increment the line count for every carriage return in the string" do
- @lexer.line = 10
- @lexer.string = "this\nis\natest'"
- @lexer.slurpstring("'")
-
- @lexer.line.should == 12
- end
-
- it "should not increment the line count for escapes in the string" do
- @lexer.line = 10
- @lexer.string = "this\\nis\\natest'"
- @lexer.slurpstring("'")
-
- @lexer.line.should == 10
- end
- end
-end
+ describe "when reading strings" do
+ before { @lexer = Puppet::Parser::Lexer.new }
+ it "should increment the line count for every carriage return in the string" do
+ @lexer.line = 10
+ @lexer.string = "this\nis\natest'"
+ @lexer.slurpstring("'")
-describe Puppet::Parser::Lexer::Token do
- before do
- @token = Puppet::Parser::Lexer::Token.new(%r{something}, :NAME)
+ @lexer.line.should == 12
end
- [:regex, :name, :string, :skip, :incr_line, :skip_text, :accumulate].each do |param|
- it "should have a #{param.to_s} reader" do
- @token.should be_respond_to(param)
- end
+ it "should not increment the line count for escapes in the string" do
+ @lexer.line = 10
+ @lexer.string = "this\\nis\\natest'"
+ @lexer.slurpstring("'")
- it "should have a #{param.to_s} writer" do
- @token.should be_respond_to(param.to_s + "=")
- end
+ @lexer.line.should == 10
end
+ end
end
-describe Puppet::Parser::Lexer::Token, "when initializing" do
- it "should create a regex if the first argument is a string" do
- Puppet::Parser::Lexer::Token.new("something", :NAME).regex.should == %r{something}
- end
+describe Puppet::Parser::Lexer::Token do
+ before do
+ @token = Puppet::Parser::Lexer::Token.new(%r{something}, :NAME)
+ end
- it "should set the string if the first argument is one" do
- Puppet::Parser::Lexer::Token.new("something", :NAME).string.should == "something"
+ [:regex, :name, :string, :skip, :incr_line, :skip_text, :accumulate].each do |param|
+ it "should have a #{param.to_s} reader" do
+ @token.should be_respond_to(param)
end
- it "should set the regex if the first argument is one" do
- Puppet::Parser::Lexer::Token.new(%r{something}, :NAME).regex.should == %r{something}
+ it "should have a #{param.to_s} writer" do
+ @token.should be_respond_to(param.to_s + "=")
end
+ end
end
-describe Puppet::Parser::Lexer::TokenList do
- before do
- @list = Puppet::Parser::Lexer::TokenList.new
- end
-
- it "should have a method for retrieving tokens by the name" do
- token = @list.add_token :name, "whatever"
- @list[:name].should equal(token)
- end
-
- it "should have a method for retrieving string tokens by the string" do
- token = @list.add_token :name, "whatever"
- @list.lookup("whatever").should equal(token)
- end
-
- it "should add tokens to the list when directed" do
- token = @list.add_token :name, "whatever"
- @list[:name].should equal(token)
- end
-
- it "should have a method for adding multiple tokens at once" do
- @list.add_tokens "whatever" => :name, "foo" => :bar
- @list[:name].should_not be_nil
- @list[:bar].should_not be_nil
- end
-
- it "should fail to add tokens sharing a name with an existing token" do
- @list.add_token :name, "whatever"
- lambda { @list.add_token :name, "whatever" }.should raise_error(ArgumentError)
- end
-
- it "should set provided options on tokens being added" do
- token = @list.add_token :name, "whatever", :skip_text => true
- token.skip_text.should == true
- end
-
- it "should define any provided blocks as a :convert method" do
- token = @list.add_token(:name, "whatever") do "foo" end
- token.convert.should == "foo"
- end
-
- it "should store all string tokens in the :string_tokens list" do
- one = @list.add_token(:name, "1")
- @list.string_tokens.should be_include(one)
- end
-
- it "should store all regex tokens in the :regex_tokens list" do
- one = @list.add_token(:name, %r{one})
- @list.regex_tokens.should be_include(one)
- end
+describe Puppet::Parser::Lexer::Token, "when initializing" do
+ it "should create a regex if the first argument is a string" do
+ Puppet::Parser::Lexer::Token.new("something", :NAME).regex.should == %r{something}
+ end
- it "should not store string tokens in the :regex_tokens list" do
- one = @list.add_token(:name, "1")
- @list.regex_tokens.should_not be_include(one)
- end
+ it "should set the string if the first argument is one" do
+ Puppet::Parser::Lexer::Token.new("something", :NAME).string.should == "something"
+ end
- it "should not store regex tokens in the :string_tokens list" do
- one = @list.add_token(:name, %r{one})
- @list.string_tokens.should_not be_include(one)
- end
+ it "should set the regex if the first argument is one" do
+ Puppet::Parser::Lexer::Token.new(%r{something}, :NAME).regex.should == %r{something}
+ end
+end
- it "should sort the string tokens inversely by length when asked" do
- one = @list.add_token(:name, "1")
- two = @list.add_token(:other, "12")
- @list.sort_tokens
- @list.string_tokens.should == [two, one]
- end
+describe Puppet::Parser::Lexer::TokenList do
+ before do
+ @list = Puppet::Parser::Lexer::TokenList.new
+ end
+
+ it "should have a method for retrieving tokens by the name" do
+ token = @list.add_token :name, "whatever"
+ @list[:name].should equal(token)
+ end
+
+ it "should have a method for retrieving string tokens by the string" do
+ token = @list.add_token :name, "whatever"
+ @list.lookup("whatever").should equal(token)
+ end
+
+ it "should add tokens to the list when directed" do
+ token = @list.add_token :name, "whatever"
+ @list[:name].should equal(token)
+ end
+
+ it "should have a method for adding multiple tokens at once" do
+ @list.add_tokens "whatever" => :name, "foo" => :bar
+ @list[:name].should_not be_nil
+ @list[:bar].should_not be_nil
+ end
+
+ it "should fail to add tokens sharing a name with an existing token" do
+ @list.add_token :name, "whatever"
+ lambda { @list.add_token :name, "whatever" }.should raise_error(ArgumentError)
+ end
+
+ it "should set provided options on tokens being added" do
+ token = @list.add_token :name, "whatever", :skip_text => true
+ token.skip_text.should == true
+ end
+
+ it "should define any provided blocks as a :convert method" do
+ token = @list.add_token(:name, "whatever") do "foo" end
+ token.convert.should == "foo"
+ end
+
+ it "should store all string tokens in the :string_tokens list" do
+ one = @list.add_token(:name, "1")
+ @list.string_tokens.should be_include(one)
+ end
+
+ it "should store all regex tokens in the :regex_tokens list" do
+ one = @list.add_token(:name, %r{one})
+ @list.regex_tokens.should be_include(one)
+ end
+
+ it "should not store string tokens in the :regex_tokens list" do
+ one = @list.add_token(:name, "1")
+ @list.regex_tokens.should_not be_include(one)
+ end
+
+ it "should not store regex tokens in the :string_tokens list" do
+ one = @list.add_token(:name, %r{one})
+ @list.string_tokens.should_not be_include(one)
+ end
+
+ it "should sort the string tokens inversely by length when asked" do
+ one = @list.add_token(:name, "1")
+ two = @list.add_token(:other, "12")
+ @list.sort_tokens
+ @list.string_tokens.should == [two, one]
+ end
end
describe Puppet::Parser::Lexer::TOKENS do
- before do
- @lexer = Puppet::Parser::Lexer.new
- end
-
- {
- :LBRACK => '[',
- :RBRACK => ']',
- :LBRACE => '{',
- :RBRACE => '}',
- :LPAREN => '(',
- :RPAREN => ')',
- :EQUALS => '=',
- :ISEQUAL => '==',
- :GREATEREQUAL => '>=',
- :GREATERTHAN => '>',
- :LESSTHAN => '<',
- :LESSEQUAL => '<=',
- :NOTEQUAL => '!=',
- :NOT => '!',
- :COMMA => ',',
- :DOT => '.',
- :COLON => ':',
- :AT => '@',
- :LLCOLLECT => '<<|',
- :RRCOLLECT => '|>>',
- :LCOLLECT => '<|',
- :RCOLLECT => '|>',
- :SEMIC => ';',
- :QMARK => '?',
- :BACKSLASH => '\\',
- :FARROW => '=>',
- :PARROW => '+>',
- :APPENDS => '+=',
- :PLUS => '+',
- :MINUS => '-',
- :DIV => '/',
- :TIMES => '*',
- :LSHIFT => '<<',
- :RSHIFT => '>>',
- :MATCH => '=~',
- :NOMATCH => '!~',
- :IN_EDGE => '->',
- :OUT_EDGE => '<-',
- :IN_EDGE_SUB => '~>',
- :OUT_EDGE_SUB => '<~',
- }.each do |name, string|
- it "should have a token named #{name.to_s}" do
- Puppet::Parser::Lexer::TOKENS[name].should_not be_nil
- end
-
- it "should match '#{string}' for the token #{name.to_s}" do
- Puppet::Parser::Lexer::TOKENS[name].string.should == string
- end
- end
-
- {
- "case" => :CASE,
- "class" => :CLASS,
- "default" => :DEFAULT,
- "define" => :DEFINE,
- "import" => :IMPORT,
- "if" => :IF,
- "elsif" => :ELSIF,
- "else" => :ELSE,
- "inherits" => :INHERITS,
- "node" => :NODE,
- "and" => :AND,
- "or" => :OR,
- "undef" => :UNDEF,
- "false" => :FALSE,
- "true" => :TRUE,
- "in" => :IN,
- }.each do |string, name|
- it "should have a keyword named #{name.to_s}" do
- Puppet::Parser::Lexer::KEYWORDS[name].should_not be_nil
- end
-
- it "should have the keyword for #{name.to_s} set to #{string}" do
- Puppet::Parser::Lexer::KEYWORDS[name].string.should == string
- end
- end
-
- # These tokens' strings don't matter, just that the tokens exist.
- [:STRING, :DQPRE, :DQMID, :DQPOST, :BOOLEAN, :NAME, :NUMBER, :COMMENT, :MLCOMMENT, :RETURN, :SQUOTE, :DQUOTE, :VARIABLE].each do |name|
- it "should have a token named #{name.to_s}" do
- Puppet::Parser::Lexer::TOKENS[name].should_not be_nil
- end
- end
+ before do
+ @lexer = Puppet::Parser::Lexer.new
+ end
+
+ {
+ :LBRACK => '[',
+ :RBRACK => ']',
+ :LBRACE => '{',
+ :RBRACE => '}',
+ :LPAREN => '(',
+ :RPAREN => ')',
+ :EQUALS => '=',
+ :ISEQUAL => '==',
+ :GREATEREQUAL => '>=',
+ :GREATERTHAN => '>',
+ :LESSTHAN => '<',
+ :LESSEQUAL => '<=',
+ :NOTEQUAL => '!=',
+ :NOT => '!',
+ :COMMA => ',',
+ :DOT => '.',
+ :COLON => ':',
+ :AT => '@',
+ :LLCOLLECT => '<<|',
+ :RRCOLLECT => '|>>',
+ :LCOLLECT => '<|',
+ :RCOLLECT => '|>',
+ :SEMIC => ';',
+ :QMARK => '?',
+ :BACKSLASH => '\\',
+ :FARROW => '=>',
+ :PARROW => '+>',
+ :APPENDS => '+=',
+ :PLUS => '+',
+ :MINUS => '-',
+ :DIV => '/',
+ :TIMES => '*',
+ :LSHIFT => '<<',
+ :RSHIFT => '>>',
+ :MATCH => '=~',
+ :NOMATCH => '!~',
+ :IN_EDGE => '->',
+ :OUT_EDGE => '<-',
+ :IN_EDGE_SUB => '~>',
+ :OUT_EDGE_SUB => '<~',
+ }.each do |name, string|
+ it "should have a token named #{name.to_s}" do
+ Puppet::Parser::Lexer::TOKENS[name].should_not be_nil
+ end
+
+ it "should match '#{string}' for the token #{name.to_s}" do
+ Puppet::Parser::Lexer::TOKENS[name].string.should == string
+ end
+ end
+
+ {
+ "case" => :CASE,
+ "class" => :CLASS,
+ "default" => :DEFAULT,
+ "define" => :DEFINE,
+ "import" => :IMPORT,
+ "if" => :IF,
+ "elsif" => :ELSIF,
+ "else" => :ELSE,
+ "inherits" => :INHERITS,
+ "node" => :NODE,
+ "and" => :AND,
+ "or" => :OR,
+ "undef" => :UNDEF,
+ "false" => :FALSE,
+ "true" => :TRUE,
+ "in" => :IN,
+ }.each do |string, name|
+ it "should have a keyword named #{name.to_s}" do
+ Puppet::Parser::Lexer::KEYWORDS[name].should_not be_nil
+ end
+
+ it "should have the keyword for #{name.to_s} set to #{string}" do
+ Puppet::Parser::Lexer::KEYWORDS[name].string.should == string
+ end
+ end
+
+ # These tokens' strings don't matter, just that the tokens exist.
+ [:STRING, :DQPRE, :DQMID, :DQPOST, :BOOLEAN, :NAME, :NUMBER, :COMMENT, :MLCOMMENT, :RETURN, :SQUOTE, :DQUOTE, :VARIABLE].each do |name|
+ it "should have a token named #{name.to_s}" do
+ Puppet::Parser::Lexer::TOKENS[name].should_not be_nil
+ end
+ end
end
describe Puppet::Parser::Lexer::TOKENS[:CLASSNAME] do
- before { @token = Puppet::Parser::Lexer::TOKENS[:CLASSNAME] }
+ before { @token = Puppet::Parser::Lexer::TOKENS[:CLASSNAME] }
- it "should match against lower-case alpha-numeric terms separated by double colons" do
- @token.regex.should =~ "one::two"
- end
+ it "should match against lower-case alpha-numeric terms separated by double colons" do
+ @token.regex.should =~ "one::two"
+ end
- it "should match against many lower-case alpha-numeric terms separated by double colons" do
- @token.regex.should =~ "one::two::three::four::five"
- end
+ it "should match against many lower-case alpha-numeric terms separated by double colons" do
+ @token.regex.should =~ "one::two::three::four::five"
+ end
- it "should match against lower-case alpha-numeric terms prefixed by double colons" do
- @token.regex.should =~ "::one"
- end
+ it "should match against lower-case alpha-numeric terms prefixed by double colons" do
+ @token.regex.should =~ "::one"
+ end
end
describe Puppet::Parser::Lexer::TOKENS[:CLASSREF] do
- before { @token = Puppet::Parser::Lexer::TOKENS[:CLASSREF] }
+ before { @token = Puppet::Parser::Lexer::TOKENS[:CLASSREF] }
- it "should match against single upper-case alpha-numeric terms" do
- @token.regex.should =~ "One"
- end
+ it "should match against single upper-case alpha-numeric terms" do
+ @token.regex.should =~ "One"
+ end
- it "should match against upper-case alpha-numeric terms separated by double colons" do
- @token.regex.should =~ "One::Two"
- end
+ it "should match against upper-case alpha-numeric terms separated by double colons" do
+ @token.regex.should =~ "One::Two"
+ end
- it "should match against many upper-case alpha-numeric terms separated by double colons" do
- @token.regex.should =~ "One::Two::Three::Four::Five"
- end
+ it "should match against many upper-case alpha-numeric terms separated by double colons" do
+ @token.regex.should =~ "One::Two::Three::Four::Five"
+ end
- it "should match against upper-case alpha-numeric terms prefixed by double colons" do
- @token.regex.should =~ "::One"
- end
+ it "should match against upper-case alpha-numeric terms prefixed by double colons" do
+ @token.regex.should =~ "::One"
+ end
end
describe Puppet::Parser::Lexer::TOKENS[:NAME] do
- before { @token = Puppet::Parser::Lexer::TOKENS[:NAME] }
-
- it "should match against lower-case alpha-numeric terms" do
- @token.regex.should =~ "one-two"
- end
-
- it "should return itself and the value if the matched term is not a keyword" do
- Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(nil)
- @token.convert(stub("lexer"), "myval").should == [Puppet::Parser::Lexer::TOKENS[:NAME], "myval"]
- end
-
- it "should return the keyword token and the value if the matched term is a keyword" do
- keyword = stub 'keyword', :name => :testing
- Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(keyword)
- @token.convert(stub("lexer"), "myval").should == [keyword, "myval"]
- end
-
- it "should return the BOOLEAN token and 'true' if the matched term is the string 'true'" do
- keyword = stub 'keyword', :name => :TRUE
- Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(keyword)
- @token.convert(stub('lexer'), "true").should == [Puppet::Parser::Lexer::TOKENS[:BOOLEAN], true]
- end
-
- it "should return the BOOLEAN token and 'false' if the matched term is the string 'false'" do
- keyword = stub 'keyword', :name => :FALSE
- Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(keyword)
- @token.convert(stub('lexer'), "false").should == [Puppet::Parser::Lexer::TOKENS[:BOOLEAN], false]
- end
+ before { @token = Puppet::Parser::Lexer::TOKENS[:NAME] }
+
+ it "should match against lower-case alpha-numeric terms" do
+ @token.regex.should =~ "one-two"
+ end
+
+ it "should return itself and the value if the matched term is not a keyword" do
+ Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(nil)
+ @token.convert(stub("lexer"), "myval").should == [Puppet::Parser::Lexer::TOKENS[:NAME], "myval"]
+ end
+
+ it "should return the keyword token and the value if the matched term is a keyword" do
+ keyword = stub 'keyword', :name => :testing
+ Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(keyword)
+ @token.convert(stub("lexer"), "myval").should == [keyword, "myval"]
+ end
+
+ it "should return the BOOLEAN token and 'true' if the matched term is the string 'true'" do
+ keyword = stub 'keyword', :name => :TRUE
+ Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(keyword)
+ @token.convert(stub('lexer'), "true").should == [Puppet::Parser::Lexer::TOKENS[:BOOLEAN], true]
+ end
+
+ it "should return the BOOLEAN token and 'false' if the matched term is the string 'false'" do
+ keyword = stub 'keyword', :name => :FALSE
+ Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(keyword)
+ @token.convert(stub('lexer'), "false").should == [Puppet::Parser::Lexer::TOKENS[:BOOLEAN], false]
+ end
end
describe Puppet::Parser::Lexer::TOKENS[:NUMBER] do
- before do
- @token = Puppet::Parser::Lexer::TOKENS[:NUMBER]
- @regex = @token.regex
- end
-
- it "should match against numeric terms" do
- @regex.should =~ "2982383139"
- end
-
- it "should match against float terms" do
- @regex.should =~ "29823.235"
- end
-
- it "should match against hexadecimal terms" do
- @regex.should =~ "0xBEEF0023"
- end
-
- it "should match against float with exponent terms" do
- @regex.should =~ "10e23"
- end
-
- it "should match against float terms with negative exponents" do
- @regex.should =~ "10e-23"
- end
-
- it "should match against float terms with fractional parts and exponent" do
- @regex.should =~ "1.234e23"
- end
-
- it "should return the NAME token and the value" do
- @token.convert(stub("lexer"), "myval").should == [Puppet::Parser::Lexer::TOKENS[:NAME], "myval"]
- end
+ before do
+ @token = Puppet::Parser::Lexer::TOKENS[:NUMBER]
+ @regex = @token.regex
+ end
+
+ it "should match against numeric terms" do
+ @regex.should =~ "2982383139"
+ end
+
+ it "should match against float terms" do
+ @regex.should =~ "29823.235"
+ end
+
+ it "should match against hexadecimal terms" do
+ @regex.should =~ "0xBEEF0023"
+ end
+
+ it "should match against float with exponent terms" do
+ @regex.should =~ "10e23"
+ end
+
+ it "should match against float terms with negative exponents" do
+ @regex.should =~ "10e-23"
+ end
+
+ it "should match against float terms with fractional parts and exponent" do
+ @regex.should =~ "1.234e23"
+ end
+
+ it "should return the NAME token and the value" do
+ @token.convert(stub("lexer"), "myval").should == [Puppet::Parser::Lexer::TOKENS[:NAME], "myval"]
+ end
end
describe Puppet::Parser::Lexer::TOKENS[:COMMENT] do
- before { @token = Puppet::Parser::Lexer::TOKENS[:COMMENT] }
+ before { @token = Puppet::Parser::Lexer::TOKENS[:COMMENT] }
- it "should match against lines starting with '#'" do
- @token.regex.should =~ "# this is a comment"
- end
+ it "should match against lines starting with '#'" do
+ @token.regex.should =~ "# this is a comment"
+ end
- it "should be marked to get skipped" do
- @token.skip?.should be_true
- end
+ it "should be marked to get skipped" do
+ @token.skip?.should be_true
+ end
- it "should be marked to accumulate" do
- @token.accumulate?.should be_true
- end
+ it "should be marked to accumulate" do
+ @token.accumulate?.should be_true
+ end
- it "'s block should return the comment without the #" do
- @token.convert(@lexer,"# this is a comment")[1].should == "this is a comment"
- end
+ it "'s block should return the comment without the #" do
+ @token.convert(@lexer,"# this is a comment")[1].should == "this is a comment"
+ end
end
describe Puppet::Parser::Lexer::TOKENS[:MLCOMMENT] do
- before do
- @token = Puppet::Parser::Lexer::TOKENS[:MLCOMMENT]
- @lexer = stub 'lexer', :line => 0
- end
+ before do
+ @token = Puppet::Parser::Lexer::TOKENS[:MLCOMMENT]
+ @lexer = stub 'lexer', :line => 0
+ end
- it "should match against lines enclosed with '/*' and '*/'" do
- @token.regex.should =~ "/* this is a comment */"
- end
+ it "should match against lines enclosed with '/*' and '*/'" do
+ @token.regex.should =~ "/* this is a comment */"
+ end
- it "should match multiple lines enclosed with '/*' and '*/'" do
- @token.regex.should =~ """/*
- this is a comment
- */"""
- end
+ it "should match multiple lines enclosed with '/*' and '*/'" do
+ @token.regex.should =~ """/*
+ this is a comment
+ */"""
+ end
- it "should increase the lexer current line number by the amount of lines spanned by the comment" do
- @lexer.expects(:line=).with(2)
- @token.convert(@lexer, "1\n2\n3")
- end
+ it "should increase the lexer current line number by the amount of lines spanned by the comment" do
+ @lexer.expects(:line=).with(2)
+ @token.convert(@lexer, "1\n2\n3")
+ end
- it "should not greedily match comments" do
- match = @token.regex.match("/* first */ word /* second */")
- match[1].should == " first "
- end
+ it "should not greedily match comments" do
+ match = @token.regex.match("/* first */ word /* second */")
+ match[1].should == " first "
+ end
- it "should be marked to accumulate" do
- @token.accumulate?.should be_true
- end
+ it "should be marked to accumulate" do
+ @token.accumulate?.should be_true
+ end
- it "'s block should return the comment without the comment marks" do
- @lexer.stubs(:line=).with(0)
+ it "'s block should return the comment without the comment marks" do
+ @lexer.stubs(:line=).with(0)
- @token.convert(@lexer,"/* this is a comment */")[1].should == "this is a comment"
- end
+ @token.convert(@lexer,"/* this is a comment */")[1].should == "this is a comment"
+ end
end
describe Puppet::Parser::Lexer::TOKENS[:RETURN] do
- before { @token = Puppet::Parser::Lexer::TOKENS[:RETURN] }
+ before { @token = Puppet::Parser::Lexer::TOKENS[:RETURN] }
- it "should match against carriage returns" do
- @token.regex.should =~ "\n"
- end
+ it "should match against carriage returns" do
+ @token.regex.should =~ "\n"
+ end
- it "should be marked to initiate text skipping" do
- @token.skip_text.should be_true
- end
+ it "should be marked to initiate text skipping" do
+ @token.skip_text.should be_true
+ end
- it "should be marked to increment the line" do
- @token.incr_line.should be_true
- end
+ it "should be marked to increment the line" do
+ @token.incr_line.should be_true
+ end
end
def tokens_scanned_from(s)
- lexer = Puppet::Parser::Lexer.new
- lexer.string = s
- lexer.fullscan[0..-2]
+ lexer = Puppet::Parser::Lexer.new
+ lexer.string = s
+ lexer.fullscan[0..-2]
end
describe Puppet::Parser::Lexer,"when lexing strings" do
- {
- %q{'single quoted string')} => [[:STRING,'single quoted string']],
- %q{"double quoted string"} => [[:STRING,'double quoted string']],
- %q{'single quoted string with an escaped "\\'"'} => [[:STRING,'single quoted string with an escaped "\'"']],
- %q{"string with an escaped '\\"'"} => [[:STRING,"string with an escaped '\"'"]],
- %q{"string with an escaped '\\$'"} => [[:STRING,"string with an escaped '$'"]],
- %q{"string with $v (but no braces)"} => [[:DQPRE,"string with "],[:VARIABLE,'v'],[:DQPOST,' (but no braces)']],
- %q["string with ${v} in braces"] => [[:DQPRE,"string with "],[:VARIABLE,'v'],[:DQPOST,' in braces']],
- %q["string with ${qualified::var} in braces"] => [[:DQPRE,"string with "],[:VARIABLE,'qualified::var'],[:DQPOST,' in braces']],
- %q{"string with $v and $v (but no braces)"} => [[:DQPRE,"string with "],[:VARIABLE,"v"],[:DQMID," and "],[:VARIABLE,"v"],[:DQPOST," (but no braces)"]],
- %q["string with ${v} and ${v} in braces"] => [[:DQPRE,"string with "],[:VARIABLE,"v"],[:DQMID," and "],[:VARIABLE,"v"],[:DQPOST," in braces"]],
- %q["string with ${'a nested single quoted string'} inside it."] => [[:DQPRE,"string with "],[:STRING,'a nested single quoted string'],[:DQPOST,' inside it.']],
- %q["string with ${['an array ',$v2]} in it."] => [[:DQPRE,"string with "],:LBRACK,[:STRING,"an array "],:COMMA,[:VARIABLE,"v2"],:RBRACK,[:DQPOST," in it."]],
- %q{a simple "scanner" test} => [[:NAME,"a"],[:NAME,"simple"], [:STRING,"scanner"],[:NAME,"test"]],
- %q{a simple 'single quote scanner' test} => [[:NAME,"a"],[:NAME,"simple"], [:STRING,"single quote scanner"],[:NAME,"test"]],
- %q{a harder 'a $b \c"'} => [[:NAME,"a"],[:NAME,"harder"], [:STRING,'a $b \c"']],
- %q{a harder "scanner test"} => [[:NAME,"a"],[:NAME,"harder"], [:STRING,"scanner test"]],
- %q{a hardest "scanner \"test\""} => [[:NAME,"a"],[:NAME,"hardest"],[:STRING,'scanner "test"']],
- %Q{a hardestest "scanner \\"test\\"\n"} => [[:NAME,"a"],[:NAME,"hardestest"],[:STRING,%Q{scanner "test"\n}]],
- %q{function("call")} => [[:NAME,"function"],[:LPAREN,"("],[:STRING,'call'],[:RPAREN,")"]],
- %q["string with ${(3+5)/4} nested math."] => [[:DQPRE,"string with "],:LPAREN,[:NAME,"3"],:PLUS,[:NAME,"5"],:RPAREN,:DIV,[:NAME,"4"],[:DQPOST," nested math."]]
- }.each { |src,expected_result|
- it "should handle #{src} correctly" do
- tokens_scanned_from(src).should be_like(*expected_result)
- end
- }
+ {
+ %q{'single quoted string')} => [[:STRING,'single quoted string']],
+ %q{"double quoted string"} => [[:STRING,'double quoted string']],
+ %q{'single quoted string with an escaped "\\'"'} => [[:STRING,'single quoted string with an escaped "\'"']],
+ %q{"string with an escaped '\\"'"} => [[:STRING,"string with an escaped '\"'"]],
+ %q{"string with an escaped '\\$'"} => [[:STRING,"string with an escaped '$'"]],
+ %q{"string with $v (but no braces)"} => [[:DQPRE,"string with "],[:VARIABLE,'v'],[:DQPOST,' (but no braces)']],
+ %q["string with ${v} in braces"] => [[:DQPRE,"string with "],[:VARIABLE,'v'],[:DQPOST,' in braces']],
+ %q["string with ${qualified::var} in braces"] => [[:DQPRE,"string with "],[:VARIABLE,'qualified::var'],[:DQPOST,' in braces']],
+ %q{"string with $v and $v (but no braces)"} => [[:DQPRE,"string with "],[:VARIABLE,"v"],[:DQMID," and "],[:VARIABLE,"v"],[:DQPOST," (but no braces)"]],
+ %q["string with ${v} and ${v} in braces"] => [[:DQPRE,"string with "],[:VARIABLE,"v"],[:DQMID," and "],[:VARIABLE,"v"],[:DQPOST," in braces"]],
+ %q["string with ${'a nested single quoted string'} inside it."] => [[:DQPRE,"string with "],[:STRING,'a nested single quoted string'],[:DQPOST,' inside it.']],
+ %q["string with ${['an array ',$v2]} in it."] => [[:DQPRE,"string with "],:LBRACK,[:STRING,"an array "],:COMMA,[:VARIABLE,"v2"],:RBRACK,[:DQPOST," in it."]],
+ %q{a simple "scanner" test} => [[:NAME,"a"],[:NAME,"simple"], [:STRING,"scanner"],[:NAME,"test"]],
+ %q{a simple 'single quote scanner' test} => [[:NAME,"a"],[:NAME,"simple"], [:STRING,"single quote scanner"],[:NAME,"test"]],
+ %q{a harder 'a $b \c"'} => [[:NAME,"a"],[:NAME,"harder"], [:STRING,'a $b \c"']],
+ %q{a harder "scanner test"} => [[:NAME,"a"],[:NAME,"harder"], [:STRING,"scanner test"]],
+ %q{a hardest "scanner \"test\""} => [[:NAME,"a"],[:NAME,"hardest"],[:STRING,'scanner "test"']],
+ %Q{a hardestest "scanner \\"test\\"\n"} => [[:NAME,"a"],[:NAME,"hardestest"],[:STRING,%Q{scanner "test"\n}]],
+ %q{function("call")} => [[:NAME,"function"],[:LPAREN,"("],[:STRING,'call'],[:RPAREN,")"]],
+ %q["string with ${(3+5)/4} nested math."] => [[:DQPRE,"string with "],:LPAREN,[:NAME,"3"],:PLUS,[:NAME,"5"],:RPAREN,:DIV,[:NAME,"4"],[:DQPOST," nested math."]]
+ }.each { |src,expected_result|
+ it "should handle #{src} correctly" do
+ tokens_scanned_from(src).should be_like(*expected_result)
+ end
+ }
end
describe Puppet::Parser::Lexer::TOKENS[:DOLLAR_VAR] do
- before { @token = Puppet::Parser::Lexer::TOKENS[:DOLLAR_VAR] }
+ before { @token = Puppet::Parser::Lexer::TOKENS[:DOLLAR_VAR] }
- it "should match against alpha words prefixed with '$'" do
- @token.regex.should =~ '$this_var'
- end
+ it "should match against alpha words prefixed with '$'" do
+ @token.regex.should =~ '$this_var'
+ end
- it "should return the VARIABLE token and the variable name stripped of the '$'" do
- @token.convert(stub("lexer"), "$myval").should == [Puppet::Parser::Lexer::TOKENS[:VARIABLE], "myval"]
- end
+ it "should return the VARIABLE token and the variable name stripped of the '$'" do
+ @token.convert(stub("lexer"), "$myval").should == [Puppet::Parser::Lexer::TOKENS[:VARIABLE], "myval"]
+ end
end
describe Puppet::Parser::Lexer::TOKENS[:REGEX] do
- before { @token = Puppet::Parser::Lexer::TOKENS[:REGEX] }
+ before { @token = Puppet::Parser::Lexer::TOKENS[:REGEX] }
- it "should match against any expression enclosed in //" do
- @token.regex.should =~ '/this is a regex/'
+ it "should match against any expression enclosed in //" do
+ @token.regex.should =~ '/this is a regex/'
+ end
+
+ it 'should not match if there is \n in the regex' do
+ @token.regex.should_not =~ "/this is \n a regex/"
+ end
+
+ describe "when scanning" do
+ it "should not consider escaped slashes to be the end of a regex" do
+ tokens_scanned_from("$x =~ /this \\/ foo/").should be_like(__,__,[:REGEX,%r{this / foo}])
end
- it 'should not match if there is \n in the regex' do
- @token.regex.should_not =~ "/this is \n a regex/"
+ it "should not lex chained division as a regex" do
+ tokens_scanned_from("$x = $a/$b/$c").collect { |name, data| name }.should_not be_include( :REGEX )
end
- describe "when scanning" do
- it "should not consider escaped slashes to be the end of a regex" do
- tokens_scanned_from("$x =~ /this \\/ foo/").should be_like(__,__,[:REGEX,%r{this / foo}])
- end
-
- it "should not lex chained division as a regex" do
- tokens_scanned_from("$x = $a/$b/$c").collect { |name, data| name }.should_not be_include( :REGEX )
- end
-
- it "should accept a regular expression after NODE" do
- tokens_scanned_from("node /www.*\.mysite\.org/").should be_like(__,[:REGEX,Regexp.new("www.*\.mysite\.org")])
- end
-
- it "should accept regular expressions in a CASE" do
- s = %q{case $variable {
- "something": {$othervar = 4096 / 2}
- /regex/: {notice("this notably sucks")}
- }
- }
- tokens_scanned_from(s).should be_like(
- :CASE,:VARIABLE,:LBRACE,:STRING,:COLON,:LBRACE,:VARIABLE,:EQUALS,:NAME,:DIV,:NAME,:RBRACE,[:REGEX,/regex/],:COLON,:LBRACE,:NAME,:LPAREN,:STRING,:RPAREN,:RBRACE,:RBRACE
- )
- end
+ it "should accept a regular expression after NODE" do
+ tokens_scanned_from("node /www.*\.mysite\.org/").should be_like(__,[:REGEX,Regexp.new("www.*\.mysite\.org")])
+ end
+ it "should accept regular expressions in a CASE" do
+ s = %q{case $variable {
+ "something": {$othervar = 4096 / 2}
+ /regex/: {notice("this notably sucks")}
+ }
+ }
+ tokens_scanned_from(s).should be_like(
+ :CASE,:VARIABLE,:LBRACE,:STRING,:COLON,:LBRACE,:VARIABLE,:EQUALS,:NAME,:DIV,:NAME,:RBRACE,[:REGEX,/regex/],:COLON,:LBRACE,:NAME,:LPAREN,:STRING,:RPAREN,:RBRACE,:RBRACE
+ )
end
+ end
- it "should return the REGEX token and a Regexp" do
- @token.convert(stub("lexer"), "/myregex/").should == [Puppet::Parser::Lexer::TOKENS[:REGEX], Regexp.new(/myregex/)]
- end
+
+ it "should return the REGEX token and a Regexp" do
+ @token.convert(stub("lexer"), "/myregex/").should == [Puppet::Parser::Lexer::TOKENS[:REGEX], Regexp.new(/myregex/)]
+ end
end
describe Puppet::Parser::Lexer, "when lexing comments" do
- before { @lexer = Puppet::Parser::Lexer.new }
+ before { @lexer = Puppet::Parser::Lexer.new }
- it "should accumulate token in munge_token" do
- token = stub 'token', :skip => true, :accumulate? => true, :incr_line => nil, :skip_text => false
+ it "should accumulate token in munge_token" do
+ token = stub 'token', :skip => true, :accumulate? => true, :incr_line => nil, :skip_text => false
- token.stubs(:convert).with(@lexer, "# this is a comment").returns([token, " this is a comment"])
- @lexer.munge_token(token, "# this is a comment")
- @lexer.munge_token(token, "# this is a comment")
+ token.stubs(:convert).with(@lexer, "# this is a comment").returns([token, " this is a comment"])
+ @lexer.munge_token(token, "# this is a comment")
+ @lexer.munge_token(token, "# this is a comment")
- @lexer.getcomment.should == " this is a comment\n this is a comment\n"
- end
+ @lexer.getcomment.should == " this is a comment\n this is a comment\n"
+ end
- it "should add a new comment stack level on LBRACE" do
- @lexer.string = "{"
+ it "should add a new comment stack level on LBRACE" do
+ @lexer.string = "{"
- @lexer.expects(:commentpush)
+ @lexer.expects(:commentpush)
- @lexer.fullscan
- end
+ @lexer.fullscan
+ end
- it "should return the current comments on getcomment" do
- @lexer.string = "# comment"
- @lexer.fullscan
+ it "should return the current comments on getcomment" do
+ @lexer.string = "# comment"
+ @lexer.fullscan
- @lexer.getcomment.should == "comment\n"
- end
+ @lexer.getcomment.should == "comment\n"
+ end
- it "should discard the previous comments on blank line" do
- @lexer.string = "# 1\n\n# 2"
- @lexer.fullscan
+ it "should discard the previous comments on blank line" do
+ @lexer.string = "# 1\n\n# 2"
+ @lexer.fullscan
- @lexer.getcomment.should == "2\n"
- end
+ @lexer.getcomment.should == "2\n"
+ end
- it "should skip whitespace before lexing the next token after a non-token" do
- tokens_scanned_from("/* 1\n\n */ \ntest").should be_like([:NAME, "test"])
- end
+ it "should skip whitespace before lexing the next token after a non-token" do
+ tokens_scanned_from("/* 1\n\n */ \ntest").should be_like([:NAME, "test"])
+ end
- it "should not return comments seen after the current line" do
- @lexer.string = "# 1\n\n# 2"
- @lexer.fullscan
+ it "should not return comments seen after the current line" do
+ @lexer.string = "# 1\n\n# 2"
+ @lexer.fullscan
- @lexer.getcomment(1).should == ""
- end
+ @lexer.getcomment(1).should == ""
+ end
- it "should return a comment seen before the current line" do
- @lexer.string = "# 1\n# 2"
- @lexer.fullscan
+ it "should return a comment seen before the current line" do
+ @lexer.string = "# 1\n# 2"
+ @lexer.fullscan
- @lexer.getcomment(2).should == "1\n2\n"
- end
+ @lexer.getcomment(2).should == "1\n2\n"
+ end
end
# FIXME: We need to rewrite all of these tests, but I just don't want to take the time right now.
describe "Puppet::Parser::Lexer in the old tests" do
- before { @lexer = Puppet::Parser::Lexer.new }
+ before { @lexer = Puppet::Parser::Lexer.new }
- it "should do simple lexing" do
- {
- %q{\\} => [[:BACKSLASH,"\\"]],
- %q{simplest scanner test} => [[:NAME,"simplest"],[:NAME,"scanner"],[:NAME,"test"]],
- %Q{returned scanner test\n} => [[:NAME,"returned"],[:NAME,"scanner"],[:NAME,"test"]]
- }.each { |source,expected|
- tokens_scanned_from(source).should be_like(*expected)
- }
- end
+ it "should do simple lexing" do
+ {
+ %q{\\} => [[:BACKSLASH,"\\"]],
+ %q{simplest scanner test} => [[:NAME,"simplest"],[:NAME,"scanner"],[:NAME,"test"]],
+ %Q{returned scanner test\n} => [[:NAME,"returned"],[:NAME,"scanner"],[:NAME,"test"]]
+ }.each { |source,expected|
+ tokens_scanned_from(source).should be_like(*expected)
+ }
+ end
- it "should fail usefully" do
- lambda { tokens_scanned_from('^') }.should raise_error(RuntimeError)
- end
+ it "should fail usefully" do
+ lambda { tokens_scanned_from('^') }.should raise_error(RuntimeError)
+ end
- it "should fail if the string is not set" do
- lambda { @lexer.fullscan }.should raise_error(Puppet::LexError)
- end
+ it "should fail if the string is not set" do
+ lambda { @lexer.fullscan }.should raise_error(Puppet::LexError)
+ end
- it "should correctly identify keywords" do
- tokens_scanned_from("case").should be_like([:CASE, "case"])
- end
+ it "should correctly identify keywords" do
+ tokens_scanned_from("case").should be_like([:CASE, "case"])
+ end
- it "should correctly parse class references" do
- %w{Many Different Words A Word}.each { |t| tokens_scanned_from(t).should be_like([:CLASSREF,t])}
- end
+ it "should correctly parse class references" do
+ %w{Many Different Words A Word}.each { |t| tokens_scanned_from(t).should be_like([:CLASSREF,t])}
+ end
- # #774
- it "should correctly parse namespaced class refernces token" do
- %w{Foo ::Foo Foo::Bar ::Foo::Bar}.each { |t| tokens_scanned_from(t).should be_like([:CLASSREF, t]) }
- end
+ # #774
+ it "should correctly parse namespaced class refernces token" do
+ %w{Foo ::Foo Foo::Bar ::Foo::Bar}.each { |t| tokens_scanned_from(t).should be_like([:CLASSREF, t]) }
+ end
- it "should correctly parse names" do
- %w{this is a bunch of names}.each { |t| tokens_scanned_from(t).should be_like([:NAME,t]) }
- end
+ it "should correctly parse names" do
+ %w{this is a bunch of names}.each { |t| tokens_scanned_from(t).should be_like([:NAME,t]) }
+ end
- it "should correctly parse names with numerals" do
- %w{1name name1 11names names11}.each { |t| tokens_scanned_from(t).should be_like([:NAME,t]) }
- end
+ it "should correctly parse names with numerals" do
+ %w{1name name1 11names names11}.each { |t| tokens_scanned_from(t).should be_like([:NAME,t]) }
+ end
- it "should correctly parse empty strings" do
- lambda { tokens_scanned_from('$var = ""') }.should_not raise_error
- end
+ it "should correctly parse empty strings" do
+ lambda { tokens_scanned_from('$var = ""') }.should_not raise_error
+ end
- it "should correctly parse virtual resources" do
- tokens_scanned_from("@type {").should be_like([:AT, "@"], [:NAME, "type"], [:LBRACE, "{"])
- end
+ it "should correctly parse virtual resources" do
+ tokens_scanned_from("@type {").should be_like([:AT, "@"], [:NAME, "type"], [:LBRACE, "{"])
+ end
- it "should correctly deal with namespaces" do
- @lexer.string = %{class myclass}
- @lexer.fullscan
- @lexer.namespace.should == "myclass"
+ it "should correctly deal with namespaces" do
+ @lexer.string = %{class myclass}
+ @lexer.fullscan
+ @lexer.namespace.should == "myclass"
- @lexer.namepop
- @lexer.namespace.should == ""
+ @lexer.namepop
+ @lexer.namespace.should == ""
- @lexer.string = "class base { class sub { class more"
- @lexer.fullscan
- @lexer.namespace.should == "base::sub::more"
+ @lexer.string = "class base { class sub { class more"
+ @lexer.fullscan
+ @lexer.namespace.should == "base::sub::more"
- @lexer.namepop
- @lexer.namespace.should == "base::sub"
- end
+ @lexer.namepop
+ @lexer.namespace.should == "base::sub"
+ end
- it "should correctly handle fully qualified names" do
- @lexer.string = "class base { class sub::more {"
- @lexer.fullscan
- @lexer.namespace.should == "base::sub::more"
+ it "should correctly handle fully qualified names" do
+ @lexer.string = "class base { class sub::more {"
+ @lexer.fullscan
+ @lexer.namespace.should == "base::sub::more"
- @lexer.namepop
- @lexer.namespace.should == "base"
- end
+ @lexer.namepop
+ @lexer.namespace.should == "base"
+ end
- it "should correctly lex variables" do
- ["$variable", "$::variable", "$qualified::variable", "$further::qualified::variable"].each do |string|
- tokens_scanned_from(string).should be_like([:VARIABLE,string.sub(/^\$/,'')])
- end
+ it "should correctly lex variables" do
+ ["$variable", "$::variable", "$qualified::variable", "$further::qualified::variable"].each do |string|
+ tokens_scanned_from(string).should be_like([:VARIABLE,string.sub(/^\$/,'')])
end
+ end
end
require 'puppettest/support/utils'
describe "Puppet::Parser::Lexer in the old tests when lexing example files" do
- extend PuppetTest
- extend PuppetTest::Support::Utils
- textfiles do |file|
- it "should correctly lex #{file}" do
- lexer = Puppet::Parser::Lexer.new
- lexer.file = file
- lambda { lexer.fullscan }.should_not raise_error
- end
- end
+ extend PuppetTest
+ extend PuppetTest::Support::Utils
+ textfiles do |file|
+ it "should correctly lex #{file}" do
+ lexer = Puppet::Parser::Lexer.new
+ lexer.file = file
+ lambda { lexer.fullscan }.should_not raise_error
+ end
+ end
end
diff --git a/spec/unit/parser/parser_spec.rb b/spec/unit/parser/parser_spec.rb
index 42d515d..0657ab3 100755
--- a/spec/unit/parser/parser_spec.rb
+++ b/spec/unit/parser/parser_spec.rb
@@ -4,409 +4,409 @@ require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::Parser do
- ast = Puppet::Parser::AST
-
- before :each do
- @known_resource_types = Puppet::Resource::TypeCollection.new("development")
- @parser = Puppet::Parser::Parser.new "development"
- @parser.stubs(:known_resource_types).returns @known_resource_types
- @true_ast = Puppet::Parser::AST::Boolean.new :value => true
+ ast = Puppet::Parser::AST
+
+ before :each do
+ @known_resource_types = Puppet::Resource::TypeCollection.new("development")
+ @parser = Puppet::Parser::Parser.new "development"
+ @parser.stubs(:known_resource_types).returns @known_resource_types
+ @true_ast = Puppet::Parser::AST::Boolean.new :value => true
+ end
+
+ it "should require an environment at initialization" do
+ lambda { Puppet::Parser::Parser.new }.should raise_error(ArgumentError)
+ end
+
+ it "should set the environment" do
+ env = Puppet::Node::Environment.new
+ Puppet::Parser::Parser.new(env).environment.should == env
+ end
+
+ it "should convert the environment into an environment instance if a string is provided" do
+ env = Puppet::Node::Environment.new("testing")
+ Puppet::Parser::Parser.new("testing").environment.should == env
+ end
+
+ it "should be able to look up the environment-specific resource type collection" do
+ rtc = Puppet::Node::Environment.new("development").known_resource_types
+ parser = Puppet::Parser::Parser.new "development"
+ parser.known_resource_types.should equal(rtc)
+ end
+
+ it "should delegate importing to the known resource type loader" do
+ parser = Puppet::Parser::Parser.new "development"
+ parser.known_resource_types.loader.expects(:import).with("newfile", "current_file")
+ parser.lexer.expects(:file).returns "current_file"
+ parser.import("newfile")
+ end
+
+ describe "when parsing files" do
+ before do
+ FileTest.stubs(:exist?).returns true
+ File.stubs(:read).returns ""
+ @parser.stubs(:watch_file)
end
- it "should require an environment at initialization" do
- lambda { Puppet::Parser::Parser.new }.should raise_error(ArgumentError)
+ it "should treat files ending in 'rb' as ruby files" do
+ @parser.expects(:parse_ruby_file)
+ @parser.file = "/my/file.rb"
+ @parser.parse
end
- it "should set the environment" do
- env = Puppet::Node::Environment.new
- Puppet::Parser::Parser.new(env).environment.should == env
- end
+ describe "in ruby" do
+ it "should use the ruby interpreter to load the file" do
+ @parser.file = "/my/file.rb"
+ @parser.expects(:require).with "/my/file.rb"
- it "should convert the environment into an environment instance if a string is provided" do
- env = Puppet::Node::Environment.new("testing")
- Puppet::Parser::Parser.new("testing").environment.should == env
+ @parser.parse_ruby_file
+ end
end
+ end
- it "should be able to look up the environment-specific resource type collection" do
- rtc = Puppet::Node::Environment.new("development").known_resource_types
- parser = Puppet::Parser::Parser.new "development"
- parser.known_resource_types.should equal(rtc)
- end
+ describe "when parsing append operator" do
- it "should delegate importing to the known resource type loader" do
- parser = Puppet::Parser::Parser.new "development"
- parser.known_resource_types.loader.expects(:import).with("newfile", "current_file")
- parser.lexer.expects(:file).returns "current_file"
- parser.import("newfile")
+ it "should not raise syntax errors" do
+ lambda { @parser.parse("$var += something") }.should_not raise_error
end
- describe "when parsing files" do
- before do
- FileTest.stubs(:exist?).returns true
- File.stubs(:read).returns ""
- @parser.stubs(:watch_file)
- end
-
- it "should treat files ending in 'rb' as ruby files" do
- @parser.expects(:parse_ruby_file)
- @parser.file = "/my/file.rb"
- @parser.parse
- end
-
- describe "in ruby" do
- it "should use the ruby interpreter to load the file" do
- @parser.file = "/my/file.rb"
- @parser.expects(:require).with "/my/file.rb"
-
- @parser.parse_ruby_file
- end
- end
+ it "shouldraise syntax error on incomplete syntax " do
+ lambda { @parser.parse("$var += ") }.should raise_error
end
- describe "when parsing append operator" do
-
- it "should not raise syntax errors" do
- lambda { @parser.parse("$var += something") }.should_not raise_error
- end
-
- it "shouldraise syntax error on incomplete syntax " do
- lambda { @parser.parse("$var += ") }.should raise_error
- end
+ it "should call ast::VarDef with append=true" do
+ ast::VarDef.expects(:new).with { |h| h[:append] == true }
+ @parser.parse("$var += 2")
+ end
- it "should call ast::VarDef with append=true" do
- ast::VarDef.expects(:new).with { |h| h[:append] == true }
- @parser.parse("$var += 2")
- end
+ it "should work with arrays too" do
+ ast::VarDef.expects(:new).with { |h| h[:append] == true }
+ @parser.parse("$var += ['test']")
+ end
- it "should work with arrays too" do
- ast::VarDef.expects(:new).with { |h| h[:append] == true }
- @parser.parse("$var += ['test']")
- end
+ end
+ describe "when parsing 'if'" do
+ it "not, it should create the correct ast objects" do
+ ast::Not.expects(:new).with { |h| h[:value].is_a?(ast::Boolean) }
+ @parser.parse("if ! true { $var = 1 }")
end
- describe "when parsing 'if'" do
- it "not, it should create the correct ast objects" do
- ast::Not.expects(:new).with { |h| h[:value].is_a?(ast::Boolean) }
- @parser.parse("if ! true { $var = 1 }")
- end
+ it "boolean operation, it should create the correct ast objects" do
+ ast::BooleanOperator.expects(:new).with {
+ |h| h[:rval].is_a?(ast::Boolean) and h[:lval].is_a?(ast::Boolean) and h[:operator]=="or"
+ }
+ @parser.parse("if true or true { $var = 1 }")
- it "boolean operation, it should create the correct ast objects" do
- ast::BooleanOperator.expects(:new).with {
- |h| h[:rval].is_a?(ast::Boolean) and h[:lval].is_a?(ast::Boolean) and h[:operator]=="or"
- }
- @parser.parse("if true or true { $var = 1 }")
+ end
- end
+ it "comparison operation, it should create the correct ast objects" do
+ ast::ComparisonOperator.expects(:new).with {
+ |h| h[:lval].is_a?(ast::Name) and h[:rval].is_a?(ast::Name) and h[:operator]=="<"
+ }
+ @parser.parse("if 1 < 2 { $var = 1 }")
- it "comparison operation, it should create the correct ast objects" do
- ast::ComparisonOperator.expects(:new).with {
- |h| h[:lval].is_a?(ast::Name) and h[:rval].is_a?(ast::Name) and h[:operator]=="<"
- }
- @parser.parse("if 1 < 2 { $var = 1 }")
+ end
- end
+ end
+
+ describe "when parsing if complex expressions" do
+ it "should create a correct ast tree" do
+ aststub = stub_everything 'ast'
+ ast::ComparisonOperator.expects(:new).with {
+ |h| h[:rval].is_a?(ast::Name) and h[:lval].is_a?(ast::Name) and h[:operator]==">"
+ }.returns(aststub)
+ ast::ComparisonOperator.expects(:new).with {
+ |h| h[:rval].is_a?(ast::Name) and h[:lval].is_a?(ast::Name) and h[:operator]=="=="
+ }.returns(aststub)
+ ast::BooleanOperator.expects(:new).with {
+ |h| h[:rval]==aststub and h[:lval]==aststub and h[:operator]=="and"
+ }
+ @parser.parse("if (1 > 2) and (1 == 2) { $var = 1 }")
+ end
+ it "should raise an error on incorrect expression" do
+ lambda { @parser.parse("if (1 > 2 > ) or (1 == 2) { $var = 1 }") }.should raise_error
end
- describe "when parsing if complex expressions" do
- it "should create a correct ast tree" do
- aststub = stub_everything 'ast'
- ast::ComparisonOperator.expects(:new).with {
- |h| h[:rval].is_a?(ast::Name) and h[:lval].is_a?(ast::Name) and h[:operator]==">"
- }.returns(aststub)
- ast::ComparisonOperator.expects(:new).with {
- |h| h[:rval].is_a?(ast::Name) and h[:lval].is_a?(ast::Name) and h[:operator]=="=="
- }.returns(aststub)
- ast::BooleanOperator.expects(:new).with {
- |h| h[:rval]==aststub and h[:lval]==aststub and h[:operator]=="and"
- }
- @parser.parse("if (1 > 2) and (1 == 2) { $var = 1 }")
- end
+ end
- it "should raise an error on incorrect expression" do
- lambda { @parser.parse("if (1 > 2 > ) or (1 == 2) { $var = 1 }") }.should raise_error
- end
+ describe "when parsing resource references" do
+ it "should not raise syntax errors" do
+ lambda { @parser.parse('exec { test: param => File["a"] }') }.should_not raise_error
end
- describe "when parsing resource references" do
+ it "should not raise syntax errors with multiple references" do
+ lambda { @parser.parse('exec { test: param => File["a","b"] }') }.should_not raise_error
+ end
- it "should not raise syntax errors" do
- lambda { @parser.parse('exec { test: param => File["a"] }') }.should_not raise_error
- end
+ it "should create an ast::ResourceReference" do
+ ast::Resource.stubs(:new)
+ ast::ResourceReference.expects(:new).with { |arg|
+ arg[:line]==1 and arg[:type]=="File" and arg[:title].is_a?(ast::ASTArray)
+ }
+ @parser.parse('exec { test: command => File["a","b"] }')
+ end
+ end
- it "should not raise syntax errors with multiple references" do
- lambda { @parser.parse('exec { test: param => File["a","b"] }') }.should_not raise_error
- end
+ describe "when parsing resource overrides" do
- it "should create an ast::ResourceReference" do
- ast::Resource.stubs(:new)
- ast::ResourceReference.expects(:new).with { |arg|
- arg[:line]==1 and arg[:type]=="File" and arg[:title].is_a?(ast::ASTArray)
- }
- @parser.parse('exec { test: command => File["a","b"] }')
- end
+ it "should not raise syntax errors" do
+ lambda { @parser.parse('Resource["title"] { param => value }') }.should_not raise_error
end
- describe "when parsing resource overrides" do
+ it "should not raise syntax errors with multiple overrides" do
+ lambda { @parser.parse('Resource["title1","title2"] { param => value }') }.should_not raise_error
+ end
- it "should not raise syntax errors" do
- lambda { @parser.parse('Resource["title"] { param => value }') }.should_not raise_error
- end
+ it "should create an ast::ResourceOverride" do
+ ast::ResourceOverride.expects(:new).with { |arg|
+ arg[:line]==1 and arg[:object].is_a?(ast::ResourceReference) and arg[:parameters].is_a?(ast::ResourceParam)
+ }
+ @parser.parse('Resource["title1","title2"] { param => value }')
+ end
- it "should not raise syntax errors with multiple overrides" do
- lambda { @parser.parse('Resource["title1","title2"] { param => value }') }.should_not raise_error
- end
+ end
- it "should create an ast::ResourceOverride" do
- ast::ResourceOverride.expects(:new).with { |arg|
- arg[:line]==1 and arg[:object].is_a?(ast::ResourceReference) and arg[:parameters].is_a?(ast::ResourceParam)
- }
- @parser.parse('Resource["title1","title2"] { param => value }')
- end
+ describe "when parsing if statements" do
+ it "should not raise errors with empty if" do
+ lambda { @parser.parse("if true { }") }.should_not raise_error
end
- describe "when parsing if statements" do
+ it "should not raise errors with empty else" do
+ lambda { @parser.parse("if false { notice('if') } else { }") }.should_not raise_error
+ end
- it "should not raise errors with empty if" do
- lambda { @parser.parse("if true { }") }.should_not raise_error
- end
+ it "should not raise errors with empty if and else" do
+ lambda { @parser.parse("if false { } else { }") }.should_not raise_error
+ end
- it "should not raise errors with empty else" do
- lambda { @parser.parse("if false { notice('if') } else { }") }.should_not raise_error
- end
+ it "should create a nop node for empty branch" do
+ ast::Nop.expects(:new)
+ @parser.parse("if true { }")
+ end
- it "should not raise errors with empty if and else" do
- lambda { @parser.parse("if false { } else { }") }.should_not raise_error
- end
+ it "should create a nop node for empty else branch" do
+ ast::Nop.expects(:new)
+ @parser.parse("if true { notice('test') } else { }")
+ end
- it "should create a nop node for empty branch" do
- ast::Nop.expects(:new)
- @parser.parse("if true { }")
- end
+ it "should build a chain of 'ifs' if there's an 'elsif'" do
+ ast = @parser.parse(<<-PP)
+ if true { notice('test') } elsif true {} else { }
+ PP
+ end
- it "should create a nop node for empty else branch" do
- ast::Nop.expects(:new)
- @parser.parse("if true { notice('test') } else { }")
- end
+ end
- it "should build a chain of 'ifs' if there's an 'elsif'" do
- ast = @parser.parse(<<-PP)
- if true { notice('test') } elsif true {} else { }
- PP
- end
+ describe "when parsing function calls" do
+ it "should not raise errors with no arguments" do
+ lambda { @parser.parse("tag()") }.should_not raise_error
end
- describe "when parsing function calls" do
+ it "should not raise errors with rvalue function with no args" do
+ lambda { @parser.parse("$a = template()") }.should_not raise_error
+ end
- it "should not raise errors with no arguments" do
- lambda { @parser.parse("tag()") }.should_not raise_error
- end
+ it "should not raise errors with arguments" do
+ lambda { @parser.parse("notice(1)") }.should_not raise_error
+ end
- it "should not raise errors with rvalue function with no args" do
- lambda { @parser.parse("$a = template()") }.should_not raise_error
- end
+ it "should not raise errors with multiple arguments" do
+ lambda { @parser.parse("notice(1,2)") }.should_not raise_error
+ end
- it "should not raise errors with arguments" do
- lambda { @parser.parse("notice(1)") }.should_not raise_error
- end
+ it "should not raise errors with multiple arguments and a trailing comma" do
+ lambda { @parser.parse("notice(1,2,)") }.should_not raise_error
+ end
- it "should not raise errors with multiple arguments" do
- lambda { @parser.parse("notice(1,2)") }.should_not raise_error
- end
+ end
- it "should not raise errors with multiple arguments and a trailing comma" do
- lambda { @parser.parse("notice(1,2,)") }.should_not raise_error
- end
+ describe "when parsing arrays with trailing comma" do
+ it "should not raise errors with a trailing comma" do
+ lambda { @parser.parse("$a = [1,2,]") }.should_not raise_error
end
+ end
- describe "when parsing arrays with trailing comma" do
-
- it "should not raise errors with a trailing comma" do
- lambda { @parser.parse("$a = [1,2,]") }.should_not raise_error
- end
+ describe "when providing AST context" do
+ before do
+ @lexer = stub 'lexer', :line => 50, :file => "/foo/bar", :getcomment => "whev"
+ @parser.stubs(:lexer).returns @lexer
end
- describe "when providing AST context" do
- before do
- @lexer = stub 'lexer', :line => 50, :file => "/foo/bar", :getcomment => "whev"
- @parser.stubs(:lexer).returns @lexer
- end
+ it "should include the lexer's line" do
+ @parser.ast_context[:line].should == 50
+ end
- it "should include the lexer's line" do
- @parser.ast_context[:line].should == 50
- end
+ it "should include the lexer's file" do
+ @parser.ast_context[:file].should == "/foo/bar"
+ end
- it "should include the lexer's file" do
- @parser.ast_context[:file].should == "/foo/bar"
- end
+ it "should include the docs if directed to do so" do
+ @parser.ast_context(true)[:doc].should == "whev"
+ end
- it "should include the docs if directed to do so" do
- @parser.ast_context(true)[:doc].should == "whev"
- end
+ it "should not include the docs when told not to" do
+ @parser.ast_context(false)[:doc].should be_nil
+ end
- it "should not include the docs when told not to" do
- @parser.ast_context(false)[:doc].should be_nil
- end
+ it "should not include the docs by default" do
+ @parser.ast_context[:doc].should be_nil
+ end
+ end
- it "should not include the docs by default" do
- @parser.ast_context[:doc].should be_nil
- end
+ describe "when building ast nodes" do
+ before do
+ @lexer = stub 'lexer', :line => 50, :file => "/foo/bar", :getcomment => "whev"
+ @parser.stubs(:lexer).returns @lexer
+ @class = stub 'class', :use_docs => false
end
- describe "when building ast nodes" do
- before do
- @lexer = stub 'lexer', :line => 50, :file => "/foo/bar", :getcomment => "whev"
- @parser.stubs(:lexer).returns @lexer
- @class = stub 'class', :use_docs => false
- end
+ it "should return a new instance of the provided class created with the provided options" do
+ @class.expects(:new).with { |opts| opts[:foo] == "bar" }
+ @parser.ast(@class, :foo => "bar")
+ end
- it "should return a new instance of the provided class created with the provided options" do
- @class.expects(:new).with { |opts| opts[:foo] == "bar" }
- @parser.ast(@class, :foo => "bar")
- end
+ it "should merge the ast context into the provided options" do
+ @class.expects(:new).with { |opts| opts[:file] == "/foo" }
+ @parser.expects(:ast_context).returns :file => "/foo"
+ @parser.ast(@class, :foo => "bar")
+ end
- it "should merge the ast context into the provided options" do
- @class.expects(:new).with { |opts| opts[:file] == "/foo" }
- @parser.expects(:ast_context).returns :file => "/foo"
- @parser.ast(@class, :foo => "bar")
- end
+ it "should prefer provided options over AST context" do
+ @class.expects(:new).with { |opts| opts[:file] == "/bar" }
+ @parser.expects(:ast_context).returns :file => "/foo"
+ @parser.ast(@class, :file => "/bar")
+ end
- it "should prefer provided options over AST context" do
- @class.expects(:new).with { |opts| opts[:file] == "/bar" }
- @parser.expects(:ast_context).returns :file => "/foo"
- @parser.ast(@class, :file => "/bar")
- end
+ it "should include docs when the AST class uses them" do
+ @class.expects(:use_docs).returns true
+ @class.stubs(:new)
+ @parser.expects(:ast_context).with(true).returns({})
+ @parser.ast(@class, :file => "/bar")
+ end
+ end
- it "should include docs when the AST class uses them" do
- @class.expects(:use_docs).returns true
- @class.stubs(:new)
- @parser.expects(:ast_context).with(true).returns({})
- @parser.ast(@class, :file => "/bar")
- end
+ describe "when creating a node" do
+ before :each do
+ @lexer = stub 'lexer'
+ @lexer.stubs(:getcomment)
+ @parser.stubs(:lexer).returns(@lexer)
+ @node = stub_everything 'node'
+ @parser.stubs(:ast_context).returns({})
+ @parser.stubs(:node).returns(nil)
+
+ @nodename = stub 'nodename', :is_a? => false, :value => "foo"
+ @nodename.stubs(:is_a?).with(Puppet::Parser::AST::HostName).returns(true)
end
- describe "when creating a node" do
- before :each do
- @lexer = stub 'lexer'
- @lexer.stubs(:getcomment)
- @parser.stubs(:lexer).returns(@lexer)
- @node = stub_everything 'node'
- @parser.stubs(:ast_context).returns({})
- @parser.stubs(:node).returns(nil)
+ it "should return an array of nodes" do
+ @parser.newnode(@nodename).should be_instance_of(Array)
+ end
+ end
- @nodename = stub 'nodename', :is_a? => false, :value => "foo"
- @nodename.stubs(:is_a?).with(Puppet::Parser::AST::HostName).returns(true)
- end
+ describe "when retrieving a specific node" do
+ it "should delegate to the known_resource_types node" do
+ @known_resource_types.expects(:node).with("node")
- it "should return an array of nodes" do
- @parser.newnode(@nodename).should be_instance_of(Array)
- end
+ @parser.node("node")
end
+ end
- describe "when retrieving a specific node" do
- it "should delegate to the known_resource_types node" do
- @known_resource_types.expects(:node).with("node")
+ describe "when retrieving a specific class" do
+ it "should delegate to the loaded code" do
+ @known_resource_types.expects(:hostclass).with("class")
- @parser.node("node")
- end
+ @parser.hostclass("class")
end
+ end
- describe "when retrieving a specific class" do
- it "should delegate to the loaded code" do
- @known_resource_types.expects(:hostclass).with("class")
+ describe "when retrieving a specific definitions" do
+ it "should delegate to the loaded code" do
+ @known_resource_types.expects(:definition).with("define")
- @parser.hostclass("class")
- end
+ @parser.definition("define")
end
+ end
- describe "when retrieving a specific definitions" do
- it "should delegate to the loaded code" do
- @known_resource_types.expects(:definition).with("define")
+ describe "when determining the configuration version" do
+ it "should determine it from the resource type collection" do
+ @parser.known_resource_types.expects(:version).returns "foo"
+ @parser.version.should == "foo"
+ end
+ end
- @parser.definition("define")
- end
- end
-
- describe "when determining the configuration version" do
- it "should determine it from the resource type collection" do
- @parser.known_resource_types.expects(:version).returns "foo"
- @parser.version.should == "foo"
- end
+ describe "when looking up definitions" do
+ it "should use the known resource types to check for them by name" do
+ @parser.known_resource_types.stubs(:find_or_load).with("namespace","name",:definition).returns(:this_value)
+ @parser.find_definition("namespace","name").should == :this_value
end
+ end
- describe "when looking up definitions" do
- it "should use the known resource types to check for them by name" do
- @parser.known_resource_types.stubs(:find_or_load).with("namespace","name",:definition).returns(:this_value)
- @parser.find_definition("namespace","name").should == :this_value
- end
+ describe "when looking up hostclasses" do
+ it "should use the known resource types to check for them by name" do
+ @parser.known_resource_types.stubs(:find_or_load).with("namespace","name",:hostclass).returns(:this_value)
+ @parser.find_hostclass("namespace","name").should == :this_value
end
-
- describe "when looking up hostclasses" do
- it "should use the known resource types to check for them by name" do
- @parser.known_resource_types.stubs(:find_or_load).with("namespace","name",:hostclass).returns(:this_value)
- @parser.find_hostclass("namespace","name").should == :this_value
- end
+ end
+
+ describe "when parsing classes" do
+ before :each do
+ @krt = Puppet::Resource::TypeCollection.new("development")
+ @parser = Puppet::Parser::Parser.new "development"
+ @parser.stubs(:known_resource_types).returns @krt
end
- describe "when parsing classes" do
- before :each do
- @krt = Puppet::Resource::TypeCollection.new("development")
- @parser = Puppet::Parser::Parser.new "development"
- @parser.stubs(:known_resource_types).returns @krt
- end
-
- it "should create new classes" do
- @parser.parse("class foobar {}")
- @krt.hostclass("foobar").should be_instance_of(Puppet::Resource::Type)
- end
+ it "should create new classes" do
+ @parser.parse("class foobar {}")
+ @krt.hostclass("foobar").should be_instance_of(Puppet::Resource::Type)
+ end
- it "should correctly set the parent class when one is provided" do
- @parser.parse("class foobar inherits yayness {}")
- @krt.hostclass("foobar").parent.should == "yayness"
- end
+ it "should correctly set the parent class when one is provided" do
+ @parser.parse("class foobar inherits yayness {}")
+ @krt.hostclass("foobar").parent.should == "yayness"
+ end
- it "should correctly set the parent class for multiple classes at a time" do
- @parser.parse("class foobar inherits yayness {}\nclass boo inherits bar {}")
- @krt.hostclass("foobar").parent.should == "yayness"
- @krt.hostclass("boo").parent.should == "bar"
- end
+ it "should correctly set the parent class for multiple classes at a time" do
+ @parser.parse("class foobar inherits yayness {}\nclass boo inherits bar {}")
+ @krt.hostclass("foobar").parent.should == "yayness"
+ @krt.hostclass("boo").parent.should == "bar"
+ end
- it "should define the code when some is provided" do
- @parser.parse("class foobar { $var = val }")
- @krt.hostclass("foobar").code.should_not be_nil
- end
+ it "should define the code when some is provided" do
+ @parser.parse("class foobar { $var = val }")
+ @krt.hostclass("foobar").code.should_not be_nil
+ end
- it "should define parameters when provided" do
- @parser.parse("class foobar($biz,$baz) {}")
- @krt.hostclass("foobar").arguments.should == {"biz" => nil, "baz" => nil}
- end
+ it "should define parameters when provided" do
+ @parser.parse("class foobar($biz,$baz) {}")
+ @krt.hostclass("foobar").arguments.should == {"biz" => nil, "baz" => nil}
end
+ end
- describe "when parsing resources" do
- before :each do
- @krt = Puppet::Resource::TypeCollection.new("development")
- @parser = Puppet::Parser::Parser.new "development"
- @parser.stubs(:known_resource_types).returns @krt
- end
+ describe "when parsing resources" do
+ before :each do
+ @krt = Puppet::Resource::TypeCollection.new("development")
+ @parser = Puppet::Parser::Parser.new "development"
+ @parser.stubs(:known_resource_types).returns @krt
+ end
- it "should be able to parse class resources" do
- @krt.add(Puppet::Resource::Type.new(:hostclass, "foobar", :arguments => {"biz" => nil}))
- lambda { @parser.parse("class { foobar: biz => stuff }") }.should_not raise_error
- end
+ it "should be able to parse class resources" do
+ @krt.add(Puppet::Resource::Type.new(:hostclass, "foobar", :arguments => {"biz" => nil}))
+ lambda { @parser.parse("class { foobar: biz => stuff }") }.should_not raise_error
+ end
- it "should correctly mark exported resources as exported" do
- @parser.parse("@@file { '/file': }")
- @krt.hostclass("").code[0].exported.should be_true
- end
+ it "should correctly mark exported resources as exported" do
+ @parser.parse("@@file { '/file': }")
+ @krt.hostclass("").code[0].exported.should be_true
+ end
- it "should correctly mark virtual resources as virtual" do
- @parser.parse("@file { '/file': }")
- @krt.hostclass("").code[0].virtual.should be_true
- end
+ it "should correctly mark virtual resources as virtual" do
+ @parser.parse("@file { '/file': }")
+ @krt.hostclass("").code[0].virtual.should be_true
end
+ end
end
diff --git a/spec/unit/parser/relationship_spec.rb b/spec/unit/parser/relationship_spec.rb
index bd4ff56..57f1a77 100644
--- a/spec/unit/parser/relationship_spec.rb
+++ b/spec/unit/parser/relationship_spec.rb
@@ -5,66 +5,66 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/parser/relationship'
describe Puppet::Parser::Relationship do
+ before do
+ @source = Puppet::Resource.new(:mytype, "source")
+ @target = Puppet::Resource.new(:mytype, "target")
+ @dep = Puppet::Parser::Relationship.new(@source, @target, :relationship)
+ end
+
+ describe "when evaluating" do
before do
- @source = Puppet::Resource.new(:mytype, "source")
- @target = Puppet::Resource.new(:mytype, "target")
- @dep = Puppet::Parser::Relationship.new(@source, @target, :relationship)
+ @catalog = Puppet::Resource::Catalog.new
+ @catalog.add_resource(@source)
+ @catalog.add_resource(@target)
end
- describe "when evaluating" do
- before do
- @catalog = Puppet::Resource::Catalog.new
- @catalog.add_resource(@source)
- @catalog.add_resource(@target)
- end
-
- it "should fail if the source resource cannot be found" do
- @catalog = Puppet::Resource::Catalog.new
- @catalog.add_resource @target
- lambda { @dep.evaluate(@catalog) }.should raise_error(ArgumentError)
- end
+ it "should fail if the source resource cannot be found" do
+ @catalog = Puppet::Resource::Catalog.new
+ @catalog.add_resource @target
+ lambda { @dep.evaluate(@catalog) }.should raise_error(ArgumentError)
+ end
- it "should fail if the target resource cannot be found" do
- @catalog = Puppet::Resource::Catalog.new
- @catalog.add_resource @source
- lambda { @dep.evaluate(@catalog) }.should raise_error(ArgumentError)
- end
+ it "should fail if the target resource cannot be found" do
+ @catalog = Puppet::Resource::Catalog.new
+ @catalog.add_resource @source
+ lambda { @dep.evaluate(@catalog) }.should raise_error(ArgumentError)
+ end
- it "should add the target as a 'before' value if the type is 'relationship'" do
- @dep.type = :relationship
- @dep.evaluate(@catalog)
- @source[:before].should be_include("Mytype[target]")
- end
+ it "should add the target as a 'before' value if the type is 'relationship'" do
+ @dep.type = :relationship
+ @dep.evaluate(@catalog)
+ @source[:before].should be_include("Mytype[target]")
+ end
- it "should add the target as a 'notify' value if the type is 'subscription'" do
- @dep.type = :subscription
- @dep.evaluate(@catalog)
- @source[:notify].should be_include("Mytype[target]")
- end
+ it "should add the target as a 'notify' value if the type is 'subscription'" do
+ @dep.type = :subscription
+ @dep.evaluate(@catalog)
+ @source[:notify].should be_include("Mytype[target]")
+ end
- it "should supplement rather than clobber existing relationship values" do
- @source[:before] = "File[/bar]"
- @dep.evaluate(@catalog)
- @source[:before].should be_include("Mytype[target]")
- @source[:before].should be_include("File[/bar]")
- end
+ it "should supplement rather than clobber existing relationship values" do
+ @source[:before] = "File[/bar]"
+ @dep.evaluate(@catalog)
+ @source[:before].should be_include("Mytype[target]")
+ @source[:before].should be_include("File[/bar]")
+ end
- it "should use the collected retargets if the target is a Collector" do
- orig_target = @target
- @target = Puppet::Parser::Collector.new(stub("scope"), :file, "equery", "vquery", :virtual)
- @target.collected[:foo] = @target
- @dep.evaluate(@catalog)
+ it "should use the collected retargets if the target is a Collector" do
+ orig_target = @target
+ @target = Puppet::Parser::Collector.new(stub("scope"), :file, "equery", "vquery", :virtual)
+ @target.collected[:foo] = @target
+ @dep.evaluate(@catalog)
- @source[:before].should be_include("Mytype[target]")
- end
+ @source[:before].should be_include("Mytype[target]")
+ end
- it "should use the collected resources if the source is a Collector" do
- orig_source = @source
- @source = Puppet::Parser::Collector.new(stub("scope"), :file, "equery", "vquery", :virtual)
- @source.collected[:foo] = @source
- @dep.evaluate(@catalog)
+ it "should use the collected resources if the source is a Collector" do
+ orig_source = @source
+ @source = Puppet::Parser::Collector.new(stub("scope"), :file, "equery", "vquery", :virtual)
+ @source.collected[:foo] = @source
+ @dep.evaluate(@catalog)
- orig_source[:before].should be_include("Mytype[target]")
- end
+ orig_source[:before].should be_include("Mytype[target]")
end
+ end
end
diff --git a/spec/unit/parser/resource_spec.rb b/spec/unit/parser/resource_spec.rb
index 31bde27..da49940 100755
--- a/spec/unit/parser/resource_spec.rb
+++ b/spec/unit/parser/resource_spec.rb
@@ -6,559 +6,559 @@ require File.dirname(__FILE__) + '/../../spec_helper'
# not moved all tests over yet.
describe Puppet::Parser::Resource do
- before do
- @node = Puppet::Node.new("yaynode")
- @known_resource_types = Puppet::Resource::TypeCollection.new("env")
- @compiler = Puppet::Parser::Compiler.new(@node)
- @compiler.environment.stubs(:known_resource_types).returns @known_resource_types
- @source = newclass ""
- @scope = @compiler.topscope
+ before do
+ @node = Puppet::Node.new("yaynode")
+ @known_resource_types = Puppet::Resource::TypeCollection.new("env")
+ @compiler = Puppet::Parser::Compiler.new(@node)
+ @compiler.environment.stubs(:known_resource_types).returns @known_resource_types
+ @source = newclass ""
+ @scope = @compiler.topscope
+ end
+
+ def mkresource(args = {})
+ args[:source] ||= @source
+ args[:scope] ||= @scope
+
+ params = args[:parameters] || {:one => "yay", :three => "rah"}
+ if args[:parameters] == :none
+ args.delete(:parameters)
+ elsif not args[:parameters].is_a? Array
+ args[:parameters] = paramify(args[:source], params)
end
- def mkresource(args = {})
- args[:source] ||= @source
- args[:scope] ||= @scope
+ Puppet::Parser::Resource.new("resource", "testing", args)
+ end
+
+ def param(name, value, source)
+ Puppet::Parser::Resource::Param.new(:name => name, :value => value, :source => source)
+ end
- params = args[:parameters] || {:one => "yay", :three => "rah"}
- if args[:parameters] == :none
- args.delete(:parameters)
- elsif not args[:parameters].is_a? Array
- args[:parameters] = paramify(args[:source], params)
- end
+ def paramify(source, hash)
+ hash.collect do |name, value|
+ Puppet::Parser::Resource::Param.new(
+ :name => name, :value => value, :source => source
+ )
+ end
+ end
+
+ def newclass(name)
+ @known_resource_types.add Puppet::Resource::Type.new(:hostclass, name)
+ end
+
+ def newdefine(name)
+ @known_resource_types.add Puppet::Resource::Type.new(:definition, name)
+ end
+
+ def newnode(name)
+ @known_resource_types.add Puppet::Resource::Type.new(:node, name)
+ end
+
+ it "should use the file lookup module" do
+ Puppet::Parser::Resource.ancestors.should be_include(Puppet::FileCollection::Lookup)
+ end
+
+ it "should get its environment from its scope" do
+ scope = stub 'scope', :source => stub("source")
+ scope.expects(:environment).returns "foo"
+ Puppet::Parser::Resource.new("file", "whatever", :scope => scope).environment.should == "foo"
+ end
+
+ it "should get its namespaces from its scope" do
+ scope = stub 'scope', :source => stub("source")
+ scope.expects(:namespaces).returns %w{one two}
+ Puppet::Parser::Resource.new("file", "whatever", :scope => scope).namespaces.should == %w{one two}
+ end
+
+ it "should use the resource type collection helper module" do
+ Puppet::Parser::Resource.ancestors.should be_include(Puppet::Resource::TypeCollectionHelper)
+ end
+
+ it "should use the scope's environment as its environment" do
+ @scope.expects(:environment).returns "myenv"
+ Puppet::Parser::Resource.new("file", "whatever", :scope => @scope).environment.should == "myenv"
+ end
+
+ it "should be isomorphic if it is builtin and models an isomorphic type" do
+ Puppet::Type.type(:file).expects(:isomorphic?).returns(true)
+ @resource = Puppet::Parser::Resource.new("file", "whatever", :scope => @scope, :source => @source).isomorphic?.should be_true
+ end
+
+ it "should not be isomorphic if it is builtin and models a non-isomorphic type" do
+ Puppet::Type.type(:file).expects(:isomorphic?).returns(false)
+ @resource = Puppet::Parser::Resource.new("file", "whatever", :scope => @scope, :source => @source).isomorphic?.should be_false
+ end
+
+ it "should be isomorphic if it is not builtin" do
+ newdefine "whatever"
+ @resource = Puppet::Parser::Resource.new("whatever", "whatever", :scope => @scope, :source => @source).isomorphic?.should be_true
+ end
+
+ it "should have a array-indexing method for retrieving parameter values" do
+ @resource = mkresource
+ @resource[:one].should == "yay"
+ end
+
+ it "should use a Puppet::Resource for converting to a ral resource" do
+ trans = mock 'resource', :to_ral => "yay"
+ @resource = mkresource
+ @resource.expects(:to_resource).returns trans
+ @resource.to_ral.should == "yay"
+ end
+
+ it "should be able to use the indexing operator to access parameters" do
+ resource = Puppet::Parser::Resource.new("resource", "testing", :source => "source", :scope => @scope)
+ resource["foo"] = "bar"
+ resource["foo"].should == "bar"
+ end
+
+ it "should return the title when asked for a parameter named 'title'" do
+ Puppet::Parser::Resource.new("resource", "testing", :source => @source, :scope => @scope)[:title].should == "testing"
+ end
+
+ describe "when initializing" do
+ before do
+ @arguments = {:scope => @scope}
+ end
+
+ it "should fail unless #{name.to_s} is specified" do
+ lambda { Puppet::Parser::Resource.new('file', '/my/file') }.should raise_error(ArgumentError)
+ end
- Puppet::Parser::Resource.new("resource", "testing", args)
+ it "should set the reference correctly" do
+ res = Puppet::Parser::Resource.new("resource", "testing", @arguments)
+ res.ref.should == "Resource[testing]"
end
- def param(name, value, source)
- Puppet::Parser::Resource::Param.new(:name => name, :value => value, :source => source)
+ it "should be tagged with user tags" do
+ tags = [ "tag1", "tag2" ]
+ @arguments[:parameters] = [ param(:tag, tags , :source) ]
+ res = Puppet::Parser::Resource.new("resource", "testing", @arguments)
+ (res.tags & tags).should == tags
end
+ end
- def paramify(source, hash)
- hash.collect do |name, value|
- Puppet::Parser::Resource::Param.new(
- :name => name, :value => value, :source => source
- )
- end
+ describe "when evaluating" do
+ it "should evaluate the associated AST definition" do
+ definition = newdefine "mydefine"
+ res = Puppet::Parser::Resource.new("mydefine", "whatever", :scope => @scope, :source => @source)
+ definition.expects(:evaluate_code).with(res)
+
+ res.evaluate
end
- def newclass(name)
- @known_resource_types.add Puppet::Resource::Type.new(:hostclass, name)
+ it "should evaluate the associated AST class" do
+ @class = newclass "myclass"
+ res = Puppet::Parser::Resource.new("class", "myclass", :scope => @scope, :source => @source)
+ @class.expects(:evaluate_code).with(res)
+ res.evaluate
end
- def newdefine(name)
- @known_resource_types.add Puppet::Resource::Type.new(:definition, name)
+ it "should evaluate the associated AST node" do
+ nodedef = newnode("mynode")
+ res = Puppet::Parser::Resource.new("node", "mynode", :scope => @scope, :source => @source)
+ nodedef.expects(:evaluate_code).with(res)
+ res.evaluate
end
+ end
+
+ describe "when finishing" do
+ before do
+ @class = newclass "myclass"
+ @nodedef = newnode("mynode")
- def newnode(name)
- @known_resource_types.add Puppet::Resource::Type.new(:node, name)
+ @resource = Puppet::Parser::Resource.new("file", "whatever", :scope => @scope, :source => @source)
end
- it "should use the file lookup module" do
- Puppet::Parser::Resource.ancestors.should be_include(Puppet::FileCollection::Lookup)
+ it "should do nothing if it has already been finished" do
+ @resource.finish
+ @resource.expects(:add_metaparams).never
+ @resource.finish
end
- it "should get its environment from its scope" do
- scope = stub 'scope', :source => stub("source")
- scope.expects(:environment).returns "foo"
- Puppet::Parser::Resource.new("file", "whatever", :scope => scope).environment.should == "foo"
+ it "should add all defaults available from the scope" do
+ @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => param(:owner, "default", @resource.source))
+ @resource.finish
+
+ @resource[:owner].should == "default"
end
- it "should get its namespaces from its scope" do
- scope = stub 'scope', :source => stub("source")
- scope.expects(:namespaces).returns %w{one two}
- Puppet::Parser::Resource.new("file", "whatever", :scope => scope).namespaces.should == %w{one two}
+ it "should not replace existing parameters with defaults" do
+ @resource.set_parameter :owner, "oldvalue"
+ @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => :replaced)
+ @resource.finish
+
+ @resource[:owner].should == "oldvalue"
end
- it "should use the resource type collection helper module" do
- Puppet::Parser::Resource.ancestors.should be_include(Puppet::Resource::TypeCollectionHelper)
+ it "should add a copy of each default, rather than the actual default parameter instance" do
+ newparam = param(:owner, "default", @resource.source)
+ other = newparam.dup
+ other.value = "other"
+ newparam.expects(:dup).returns(other)
+ @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => newparam)
+ @resource.finish
+
+ @resource[:owner].should == "other"
end
- it "should use the scope's environment as its environment" do
- @scope.expects(:environment).returns "myenv"
- Puppet::Parser::Resource.new("file", "whatever", :scope => @scope).environment.should == "myenv"
+ it "should be running in metaparam compatibility mode if running a version below 0.25" do
+ catalog = stub 'catalog', :client_version => "0.24.8"
+ @resource.stubs(:catalog).returns catalog
+ @resource.should be_metaparam_compatibility_mode
end
- it "should be isomorphic if it is builtin and models an isomorphic type" do
- Puppet::Type.type(:file).expects(:isomorphic?).returns(true)
- @resource = Puppet::Parser::Resource.new("file", "whatever", :scope => @scope, :source => @source).isomorphic?.should be_true
+ it "should be running in metaparam compatibility mode if running no client version is available" do
+ catalog = stub 'catalog', :client_version => nil
+ @resource.stubs(:catalog).returns catalog
+ @resource.should be_metaparam_compatibility_mode
end
- it "should not be isomorphic if it is builtin and models a non-isomorphic type" do
- Puppet::Type.type(:file).expects(:isomorphic?).returns(false)
- @resource = Puppet::Parser::Resource.new("file", "whatever", :scope => @scope, :source => @source).isomorphic?.should be_false
+ it "should not be running in metaparam compatibility mode if running a version at or above 0.25" do
+ catalog = stub 'catalog', :client_version => "0.25.0"
+ @resource.stubs(:catalog).returns catalog
+ @resource.should_not be_metaparam_compatibility_mode
end
- it "should be isomorphic if it is not builtin" do
- newdefine "whatever"
- @resource = Puppet::Parser::Resource.new("whatever", "whatever", :scope => @scope, :source => @source).isomorphic?.should be_true
+ it "should not copy relationship metaparams when not in metaparam compatibility mode" do
+ @scope.setvar("require", "bar")
+
+ @resource.stubs(:metaparam_compatibility_mode?).returns false
+ @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
+
+ @resource["require"].should be_nil
end
- it "should have a array-indexing method for retrieving parameter values" do
- @resource = mkresource
- @resource[:one].should == "yay"
+ it "should copy relationship metaparams when in metaparam compatibility mode" do
+ @scope.setvar("require", "bar")
+
+ @resource.stubs(:metaparam_compatibility_mode?).returns true
+ @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
+
+ @resource["require"].should == "bar"
end
- it "should use a Puppet::Resource for converting to a ral resource" do
- trans = mock 'resource', :to_ral => "yay"
- @resource = mkresource
- @resource.expects(:to_resource).returns trans
- @resource.to_ral.should == "yay"
+ it "should stack relationship metaparams when in metaparam compatibility mode" do
+ @resource.set_parameter("require", "foo")
+ @scope.setvar("require", "bar")
+
+ @resource.stubs(:metaparam_compatibility_mode?).returns true
+ @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
+
+ @resource["require"].should == ["foo", "bar"]
end
+ end
- it "should be able to use the indexing operator to access parameters" do
- resource = Puppet::Parser::Resource.new("resource", "testing", :source => "source", :scope => @scope)
- resource["foo"] = "bar"
- resource["foo"].should == "bar"
+ describe "when being tagged" do
+ before do
+ @scope_resource = stub 'scope_resource', :tags => %w{srone srtwo}
+ @scope.stubs(:resource).returns @scope_resource
+ @resource = Puppet::Parser::Resource.new("file", "yay", :scope => @scope, :source => mock('source'))
end
- it "should return the title when asked for a parameter named 'title'" do
- Puppet::Parser::Resource.new("resource", "testing", :source => @source, :scope => @scope)[:title].should == "testing"
+ it "should get tagged with the resource type" do
+ @resource.tags.should be_include("file")
end
- describe "when initializing" do
- before do
- @arguments = {:scope => @scope}
- end
+ it "should get tagged with the title" do
+ @resource.tags.should be_include("yay")
+ end
- it "should fail unless #{name.to_s} is specified" do
- lambda { Puppet::Parser::Resource.new('file', '/my/file') }.should raise_error(ArgumentError)
- end
+ it "should get tagged with each name in the title if the title is a qualified class name" do
+ resource = Puppet::Parser::Resource.new("file", "one::two", :scope => @scope, :source => mock('source'))
+ resource.tags.should be_include("one")
+ resource.tags.should be_include("two")
+ end
- it "should set the reference correctly" do
- res = Puppet::Parser::Resource.new("resource", "testing", @arguments)
- res.ref.should == "Resource[testing]"
- end
+ it "should get tagged with each name in the type if the type is a qualified class name" do
+ resource = Puppet::Parser::Resource.new("one::two", "whatever", :scope => @scope, :source => mock('source'))
+ resource.tags.should be_include("one")
+ resource.tags.should be_include("two")
+ end
- it "should be tagged with user tags" do
- tags = [ "tag1", "tag2" ]
- @arguments[:parameters] = [ param(:tag, tags , :source) ]
- res = Puppet::Parser::Resource.new("resource", "testing", @arguments)
- (res.tags & tags).should == tags
- end
+ it "should not get tagged with non-alphanumeric titles" do
+ resource = Puppet::Parser::Resource.new("file", "this is a test", :scope => @scope, :source => mock('source'))
+ resource.tags.should_not be_include("this is a test")
end
- describe "when evaluating" do
- it "should evaluate the associated AST definition" do
- definition = newdefine "mydefine"
- res = Puppet::Parser::Resource.new("mydefine", "whatever", :scope => @scope, :source => @source)
- definition.expects(:evaluate_code).with(res)
+ it "should fail on tags containing '*' characters" do
+ lambda { @resource.tag("bad*tag") }.should raise_error(Puppet::ParseError)
+ end
- res.evaluate
- end
+ it "should fail on tags starting with '-' characters" do
+ lambda { @resource.tag("-badtag") }.should raise_error(Puppet::ParseError)
+ end
- it "should evaluate the associated AST class" do
- @class = newclass "myclass"
- res = Puppet::Parser::Resource.new("class", "myclass", :scope => @scope, :source => @source)
- @class.expects(:evaluate_code).with(res)
- res.evaluate
- end
+ it "should fail on tags containing ' ' characters" do
+ lambda { @resource.tag("bad tag") }.should raise_error(Puppet::ParseError)
+ end
- it "should evaluate the associated AST node" do
- nodedef = newnode("mynode")
- res = Puppet::Parser::Resource.new("node", "mynode", :scope => @scope, :source => @source)
- nodedef.expects(:evaluate_code).with(res)
- res.evaluate
- end
+ it "should allow alpha tags" do
+ lambda { @resource.tag("good_tag") }.should_not raise_error(Puppet::ParseError)
end
+ end
- describe "when finishing" do
- before do
- @class = newclass "myclass"
- @nodedef = newnode("mynode")
+ describe "when merging overrides" do
+ before do
+ @source = "source1"
+ @resource = mkresource :source => @source
+ @override = mkresource :source => @source
+ end
- @resource = Puppet::Parser::Resource.new("file", "whatever", :scope => @scope, :source => @source)
- end
+ it "should fail when the override was not created by a parent class" do
+ @override.source = "source2"
+ @override.source.expects(:child_of?).with("source1").returns(false)
+ lambda { @resource.merge(@override) }.should raise_error(Puppet::ParseError)
+ end
- it "should do nothing if it has already been finished" do
- @resource.finish
- @resource.expects(:add_metaparams).never
- @resource.finish
- end
+ it "should succeed when the override was created in the current scope" do
+ @resource.source = "source3"
+ @override.source = @resource.source
+ @override.source.expects(:child_of?).with("source3").never
+ params = {:a => :b, :c => :d}
+ @override.expects(:parameters).returns(params)
+ @resource.expects(:override_parameter).with(:b)
+ @resource.expects(:override_parameter).with(:d)
+ @resource.merge(@override)
+ end
- it "should add all defaults available from the scope" do
- @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => param(:owner, "default", @resource.source))
- @resource.finish
+ it "should succeed when a parent class created the override" do
+ @resource.source = "source3"
+ @override.source = "source4"
+ @override.source.expects(:child_of?).with("source3").returns(true)
+ params = {:a => :b, :c => :d}
+ @override.expects(:parameters).returns(params)
+ @resource.expects(:override_parameter).with(:b)
+ @resource.expects(:override_parameter).with(:d)
+ @resource.merge(@override)
+ end
- @resource[:owner].should == "default"
- end
+ it "should add new parameters when the parameter is not set" do
+ @source.stubs(:child_of?).returns true
+ @override.set_parameter(:testing, "value")
+ @resource.merge(@override)
- it "should not replace existing parameters with defaults" do
- @resource.set_parameter :owner, "oldvalue"
- @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => :replaced)
- @resource.finish
+ @resource[:testing].should == "value"
+ end
- @resource[:owner].should == "oldvalue"
- end
+ it "should replace existing parameter values" do
+ @source.stubs(:child_of?).returns true
+ @resource.set_parameter(:testing, "old")
+ @override.set_parameter(:testing, "value")
- it "should add a copy of each default, rather than the actual default parameter instance" do
- newparam = param(:owner, "default", @resource.source)
- other = newparam.dup
- other.value = "other"
- newparam.expects(:dup).returns(other)
- @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => newparam)
- @resource.finish
+ @resource.merge(@override)
- @resource[:owner].should == "other"
- end
-
- it "should be running in metaparam compatibility mode if running a version below 0.25" do
- catalog = stub 'catalog', :client_version => "0.24.8"
- @resource.stubs(:catalog).returns catalog
- @resource.should be_metaparam_compatibility_mode
- end
-
- it "should be running in metaparam compatibility mode if running no client version is available" do
- catalog = stub 'catalog', :client_version => nil
- @resource.stubs(:catalog).returns catalog
- @resource.should be_metaparam_compatibility_mode
- end
-
- it "should not be running in metaparam compatibility mode if running a version at or above 0.25" do
- catalog = stub 'catalog', :client_version => "0.25.0"
- @resource.stubs(:catalog).returns catalog
- @resource.should_not be_metaparam_compatibility_mode
- end
-
- it "should not copy relationship metaparams when not in metaparam compatibility mode" do
- @scope.setvar("require", "bar")
-
- @resource.stubs(:metaparam_compatibility_mode?).returns false
- @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
-
- @resource["require"].should be_nil
- end
-
- it "should copy relationship metaparams when in metaparam compatibility mode" do
- @scope.setvar("require", "bar")
-
- @resource.stubs(:metaparam_compatibility_mode?).returns true
- @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
-
- @resource["require"].should == "bar"
- end
-
- it "should stack relationship metaparams when in metaparam compatibility mode" do
- @resource.set_parameter("require", "foo")
- @scope.setvar("require", "bar")
-
- @resource.stubs(:metaparam_compatibility_mode?).returns true
- @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
-
- @resource["require"].should == ["foo", "bar"]
- end
- end
-
- describe "when being tagged" do
- before do
- @scope_resource = stub 'scope_resource', :tags => %w{srone srtwo}
- @scope.stubs(:resource).returns @scope_resource
- @resource = Puppet::Parser::Resource.new("file", "yay", :scope => @scope, :source => mock('source'))
- end
-
- it "should get tagged with the resource type" do
- @resource.tags.should be_include("file")
- end
-
- it "should get tagged with the title" do
- @resource.tags.should be_include("yay")
- end
-
- it "should get tagged with each name in the title if the title is a qualified class name" do
- resource = Puppet::Parser::Resource.new("file", "one::two", :scope => @scope, :source => mock('source'))
- resource.tags.should be_include("one")
- resource.tags.should be_include("two")
- end
-
- it "should get tagged with each name in the type if the type is a qualified class name" do
- resource = Puppet::Parser::Resource.new("one::two", "whatever", :scope => @scope, :source => mock('source'))
- resource.tags.should be_include("one")
- resource.tags.should be_include("two")
- end
-
- it "should not get tagged with non-alphanumeric titles" do
- resource = Puppet::Parser::Resource.new("file", "this is a test", :scope => @scope, :source => mock('source'))
- resource.tags.should_not be_include("this is a test")
- end
-
- it "should fail on tags containing '*' characters" do
- lambda { @resource.tag("bad*tag") }.should raise_error(Puppet::ParseError)
- end
-
- it "should fail on tags starting with '-' characters" do
- lambda { @resource.tag("-badtag") }.should raise_error(Puppet::ParseError)
- end
-
- it "should fail on tags containing ' ' characters" do
- lambda { @resource.tag("bad tag") }.should raise_error(Puppet::ParseError)
- end
-
- it "should allow alpha tags" do
- lambda { @resource.tag("good_tag") }.should_not raise_error(Puppet::ParseError)
- end
+ @resource[:testing].should == "value"
end
- describe "when merging overrides" do
- before do
- @source = "source1"
- @resource = mkresource :source => @source
- @override = mkresource :source => @source
- end
+ it "should add values to the parameter when the override was created with the '+>' syntax" do
+ @source.stubs(:child_of?).returns true
+ param = Puppet::Parser::Resource::Param.new(:name => :testing, :value => "testing", :source => @resource.source)
+ param.add = true
- it "should fail when the override was not created by a parent class" do
- @override.source = "source2"
- @override.source.expects(:child_of?).with("source1").returns(false)
- lambda { @resource.merge(@override) }.should raise_error(Puppet::ParseError)
- end
+ @override.set_parameter(param)
- it "should succeed when the override was created in the current scope" do
- @resource.source = "source3"
- @override.source = @resource.source
- @override.source.expects(:child_of?).with("source3").never
- params = {:a => :b, :c => :d}
- @override.expects(:parameters).returns(params)
- @resource.expects(:override_parameter).with(:b)
- @resource.expects(:override_parameter).with(:d)
- @resource.merge(@override)
- end
+ @resource.set_parameter(:testing, "other")
+
+ @resource.merge(@override)
+
+ @resource[:testing].should == %w{other testing}
+ end
- it "should succeed when a parent class created the override" do
- @resource.source = "source3"
- @override.source = "source4"
- @override.source.expects(:child_of?).with("source3").returns(true)
- params = {:a => :b, :c => :d}
- @override.expects(:parameters).returns(params)
- @resource.expects(:override_parameter).with(:b)
- @resource.expects(:override_parameter).with(:d)
- @resource.merge(@override)
- end
+ it "should not merge parameter values when multiple resources are overriden with '+>' at once " do
+ @resource_2 = mkresource :source => @source
- it "should add new parameters when the parameter is not set" do
- @source.stubs(:child_of?).returns true
- @override.set_parameter(:testing, "value")
- @resource.merge(@override)
+ @resource. set_parameter(:testing, "old_val_1")
+ @resource_2.set_parameter(:testing, "old_val_2")
- @resource[:testing].should == "value"
- end
+ @source.stubs(:child_of?).returns true
+ param = Puppet::Parser::Resource::Param.new(:name => :testing, :value => "new_val", :source => @resource.source)
+ param.add = true
+ @override.set_parameter(param)
- it "should replace existing parameter values" do
- @source.stubs(:child_of?).returns true
- @resource.set_parameter(:testing, "old")
- @override.set_parameter(:testing, "value")
+ @resource. merge(@override)
+ @resource_2.merge(@override)
- @resource.merge(@override)
+ @resource [:testing].should == %w{old_val_1 new_val}
+ @resource_2[:testing].should == %w{old_val_2 new_val}
+ end
- @resource[:testing].should == "value"
- end
+ it "should promote tag overrides to real tags" do
+ @source.stubs(:child_of?).returns true
+ param = Puppet::Parser::Resource::Param.new(:name => :tag, :value => "testing", :source => @resource.source)
- it "should add values to the parameter when the override was created with the '+>' syntax" do
- @source.stubs(:child_of?).returns true
- param = Puppet::Parser::Resource::Param.new(:name => :testing, :value => "testing", :source => @resource.source)
- param.add = true
+ @override.set_parameter(param)
- @override.set_parameter(param)
+ @resource.merge(@override)
- @resource.set_parameter(:testing, "other")
+ @resource.tagged?("testing").should be_true
+ end
- @resource.merge(@override)
+ end
- @resource[:testing].should == %w{other testing}
- end
+ it "should be able to be converted to a normal resource" do
+ @source = stub 'scope', :name => "myscope"
+ @resource = mkresource :source => @source
+ @resource.should respond_to(:to_resource)
+ end
- it "should not merge parameter values when multiple resources are overriden with '+>' at once " do
- @resource_2 = mkresource :source => @source
+ it "should use its resource converter to convert to a transportable resource" do
+ @source = stub 'scope', :name => "myscope"
+ @resource = mkresource :source => @source
- @resource. set_parameter(:testing, "old_val_1")
- @resource_2.set_parameter(:testing, "old_val_2")
+ newresource = Puppet::Resource.new(:file, "/my")
+ Puppet::Resource.expects(:new).returns(newresource)
- @source.stubs(:child_of?).returns true
- param = Puppet::Parser::Resource::Param.new(:name => :testing, :value => "new_val", :source => @resource.source)
- param.add = true
- @override.set_parameter(param)
+ newresource.expects(:to_trans).returns "mytrans"
- @resource. merge(@override)
- @resource_2.merge(@override)
+ @resource.to_trans.should == "mytrans"
+ end
- @resource [:testing].should == %w{old_val_1 new_val}
- @resource_2[:testing].should == %w{old_val_2 new_val}
- end
+ it "should return nil if converted to a transportable resource and it is virtual" do
+ @source = stub 'scope', :name => "myscope"
+ @resource = mkresource :source => @source
- it "should promote tag overrides to real tags" do
- @source.stubs(:child_of?).returns true
- param = Puppet::Parser::Resource::Param.new(:name => :tag, :value => "testing", :source => @resource.source)
+ @resource.expects(:virtual?).returns true
+ @resource.to_trans.should be_nil
+ end
- @override.set_parameter(param)
+ describe "when being converted to a resource" do
+ before do
+ @parser_resource = mkresource :scope => @scope, :parameters => {:foo => "bar", :fee => "fum"}
+ end
- @resource.merge(@override)
+ it "should create an instance of Puppet::Resource" do
+ @parser_resource.to_resource.should be_instance_of(Puppet::Resource)
+ end
- @resource.tagged?("testing").should be_true
- end
+ it "should set the type correctly on the Puppet::Resource" do
+ @parser_resource.to_resource.type.should == @parser_resource.type
+ end
+ it "should set the title correctly on the Puppet::Resource" do
+ @parser_resource.to_resource.title.should == @parser_resource.title
end
- it "should be able to be converted to a normal resource" do
- @source = stub 'scope', :name => "myscope"
- @resource = mkresource :source => @source
- @resource.should respond_to(:to_resource)
+ it "should copy over all of the parameters" do
+ result = @parser_resource.to_resource.to_hash
+
+ # The name will be in here, also.
+ result[:foo].should == "bar"
+ result[:fee].should == "fum"
end
- it "should use its resource converter to convert to a transportable resource" do
- @source = stub 'scope', :name => "myscope"
- @resource = mkresource :source => @source
-
- newresource = Puppet::Resource.new(:file, "/my")
- Puppet::Resource.expects(:new).returns(newresource)
+ it "should copy over the tags" do
+ @parser_resource.tag "foo"
+ @parser_resource.tag "bar"
- newresource.expects(:to_trans).returns "mytrans"
+ @parser_resource.to_resource.tags.should == @parser_resource.tags
+ end
- @resource.to_trans.should == "mytrans"
+ it "should copy over the line" do
+ @parser_resource.line = 40
+ @parser_resource.to_resource.line.should == 40
end
- it "should return nil if converted to a transportable resource and it is virtual" do
- @source = stub 'scope', :name => "myscope"
- @resource = mkresource :source => @source
+ it "should copy over the file" do
+ @parser_resource.file = "/my/file"
+ @parser_resource.to_resource.file.should == "/my/file"
+ end
- @resource.expects(:virtual?).returns true
- @resource.to_trans.should be_nil
+ it "should copy over the 'exported' value" do
+ @parser_resource.exported = true
+ @parser_resource.to_resource.exported.should be_true
end
- describe "when being converted to a resource" do
- before do
- @parser_resource = mkresource :scope => @scope, :parameters => {:foo => "bar", :fee => "fum"}
- end
+ it "should copy over the 'virtual' value" do
+ @parser_resource.virtual = true
+ @parser_resource.to_resource.virtual.should be_true
+ end
- it "should create an instance of Puppet::Resource" do
- @parser_resource.to_resource.should be_instance_of(Puppet::Resource)
- end
+ it "should convert any parser resource references to Puppet::Resource instances" do
+ ref = Puppet::Resource.new("file", "/my/file")
+ @parser_resource = mkresource :source => @source, :parameters => {:foo => "bar", :fee => ref}
+ result = @parser_resource.to_resource
+ result[:fee].should == Puppet::Resource.new(:file, "/my/file")
+ end
- it "should set the type correctly on the Puppet::Resource" do
- @parser_resource.to_resource.type.should == @parser_resource.type
- end
+ it "should convert any parser resource references to Puppet::Resource instances even if they are in an array" do
+ ref = Puppet::Resource.new("file", "/my/file")
+ @parser_resource = mkresource :source => @source, :parameters => {:foo => "bar", :fee => ["a", ref]}
+ result = @parser_resource.to_resource
+ result[:fee].should == ["a", Puppet::Resource.new(:file, "/my/file")]
+ end
- it "should set the title correctly on the Puppet::Resource" do
- @parser_resource.to_resource.title.should == @parser_resource.title
- end
+ it "should convert any parser resource references to Puppet::Resource instances even if they are in an array of array, and even deeper" do
+ ref1 = Puppet::Resource.new("file", "/my/file1")
+ ref2 = Puppet::Resource.new("file", "/my/file2")
+ @parser_resource = mkresource :source => @source, :parameters => {:foo => "bar", :fee => ["a", [ref1,ref2]]}
+ result = @parser_resource.to_resource
+ result[:fee].should == ["a", Puppet::Resource.new(:file, "/my/file1"), Puppet::Resource.new(:file, "/my/file2")]
+ end
- it "should copy over all of the parameters" do
- result = @parser_resource.to_resource.to_hash
+ it "should fail if the same param is declared twice" do
+ lambda do
+ @parser_resource = mkresource :source => @source, :parameters => [
+ Puppet::Parser::Resource::Param.new(
+ :name => :foo, :value => "bar", :source => @source
+ ),
+ Puppet::Parser::Resource::Param.new(
+ :name => :foo, :value => "baz", :source => @source
+ )
+ ]
+ end.should raise_error(Puppet::ParseError)
+ end
+ end
+
+ describe "when validating" do
+ it "should check each parameter" do
+ resource = Puppet::Parser::Resource.new :foo, "bar", :scope => @scope, :source => stub("source")
+ resource[:one] = :two
+ resource[:three] = :four
+ resource.expects(:validate_parameter).with(:one)
+ resource.expects(:validate_parameter).with(:three)
+ resource.send(:validate)
+ end
- # The name will be in here, also.
- result[:foo].should == "bar"
- result[:fee].should == "fum"
- end
+ it "should raise a parse error when there's a failure" do
+ resource = Puppet::Parser::Resource.new :foo, "bar", :scope => @scope, :source => stub("source")
+ resource[:one] = :two
+ resource.expects(:validate_parameter).with(:one).raises ArgumentError
+ lambda { resource.send(:validate) }.should raise_error(Puppet::ParseError)
+ end
+ end
- it "should copy over the tags" do
- @parser_resource.tag "foo"
- @parser_resource.tag "bar"
+ describe "when setting parameters" do
+ before do
+ @source = newclass "foobar"
+ @resource = Puppet::Parser::Resource.new :foo, "bar", :scope => @scope, :source => @source
+ end
- @parser_resource.to_resource.tags.should == @parser_resource.tags
- end
+ it "should accept Param instances and add them to the parameter list" do
+ param = Puppet::Parser::Resource::Param.new :name => "foo", :value => "bar", :source => @source
+ @resource.set_parameter(param)
+ @resource["foo"].should == "bar"
+ end
- it "should copy over the line" do
- @parser_resource.line = 40
- @parser_resource.to_resource.line.should == 40
- end
+ it "should fail when provided a parameter name but no value" do
+ lambda { @resource.set_parameter("myparam") }.should raise_error(ArgumentError)
+ end
- it "should copy over the file" do
- @parser_resource.file = "/my/file"
- @parser_resource.to_resource.file.should == "/my/file"
- end
+ it "should allow parameters to be set to 'false'" do
+ @resource.set_parameter("myparam", false)
+ @resource["myparam"].should be_false
+ end
- it "should copy over the 'exported' value" do
- @parser_resource.exported = true
- @parser_resource.to_resource.exported.should be_true
- end
-
- it "should copy over the 'virtual' value" do
- @parser_resource.virtual = true
- @parser_resource.to_resource.virtual.should be_true
- end
-
- it "should convert any parser resource references to Puppet::Resource instances" do
- ref = Puppet::Resource.new("file", "/my/file")
- @parser_resource = mkresource :source => @source, :parameters => {:foo => "bar", :fee => ref}
- result = @parser_resource.to_resource
- result[:fee].should == Puppet::Resource.new(:file, "/my/file")
- end
-
- it "should convert any parser resource references to Puppet::Resource instances even if they are in an array" do
- ref = Puppet::Resource.new("file", "/my/file")
- @parser_resource = mkresource :source => @source, :parameters => {:foo => "bar", :fee => ["a", ref]}
- result = @parser_resource.to_resource
- result[:fee].should == ["a", Puppet::Resource.new(:file, "/my/file")]
- end
-
- it "should convert any parser resource references to Puppet::Resource instances even if they are in an array of array, and even deeper" do
- ref1 = Puppet::Resource.new("file", "/my/file1")
- ref2 = Puppet::Resource.new("file", "/my/file2")
- @parser_resource = mkresource :source => @source, :parameters => {:foo => "bar", :fee => ["a", [ref1,ref2]]}
- result = @parser_resource.to_resource
- result[:fee].should == ["a", Puppet::Resource.new(:file, "/my/file1"), Puppet::Resource.new(:file, "/my/file2")]
- end
-
- it "should fail if the same param is declared twice" do
- lambda do
- @parser_resource = mkresource :source => @source, :parameters => [
- Puppet::Parser::Resource::Param.new(
- :name => :foo, :value => "bar", :source => @source
- ),
- Puppet::Parser::Resource::Param.new(
- :name => :foo, :value => "baz", :source => @source
- )
- ]
- end.should raise_error(Puppet::ParseError)
- end
- end
-
- describe "when validating" do
- it "should check each parameter" do
- resource = Puppet::Parser::Resource.new :foo, "bar", :scope => @scope, :source => stub("source")
- resource[:one] = :two
- resource[:three] = :four
- resource.expects(:validate_parameter).with(:one)
- resource.expects(:validate_parameter).with(:three)
- resource.send(:validate)
- end
-
- it "should raise a parse error when there's a failure" do
- resource = Puppet::Parser::Resource.new :foo, "bar", :scope => @scope, :source => stub("source")
- resource[:one] = :two
- resource.expects(:validate_parameter).with(:one).raises ArgumentError
- lambda { resource.send(:validate) }.should raise_error(Puppet::ParseError)
- end
- end
-
- describe "when setting parameters" do
- before do
- @source = newclass "foobar"
- @resource = Puppet::Parser::Resource.new :foo, "bar", :scope => @scope, :source => @source
- end
-
- it "should accept Param instances and add them to the parameter list" do
- param = Puppet::Parser::Resource::Param.new :name => "foo", :value => "bar", :source => @source
- @resource.set_parameter(param)
- @resource["foo"].should == "bar"
- end
-
- it "should fail when provided a parameter name but no value" do
- lambda { @resource.set_parameter("myparam") }.should raise_error(ArgumentError)
- end
-
- it "should allow parameters to be set to 'false'" do
- @resource.set_parameter("myparam", false)
- @resource["myparam"].should be_false
- end
-
- it "should use its source when provided a parameter name and value" do
- @resource.set_parameter("myparam", "myvalue")
- @resource["myparam"].should == "myvalue"
- end
- end
-
- # part of #629 -- the undef keyword. Make sure 'undef' params get skipped.
- it "should not include 'undef' parameters when converting itself to a hash" do
- resource = Puppet::Parser::Resource.new "file", "/tmp/testing", :source => mock("source"), :scope => mock("scope")
- resource[:owner] = :undef
- resource[:mode] = "755"
- resource.to_hash[:owner].should be_nil
+ it "should use its source when provided a parameter name and value" do
+ @resource.set_parameter("myparam", "myvalue")
+ @resource["myparam"].should == "myvalue"
end
+ end
+
+ # part of #629 -- the undef keyword. Make sure 'undef' params get skipped.
+ it "should not include 'undef' parameters when converting itself to a hash" do
+ resource = Puppet::Parser::Resource.new "file", "/tmp/testing", :source => mock("source"), :scope => mock("scope")
+ resource[:owner] = :undef
+ resource[:mode] = "755"
+ resource.to_hash[:owner].should be_nil
+ end
end
diff --git a/spec/unit/parser/scope_spec.rb b/spec/unit/parser/scope_spec.rb
index 035d49c..9895f44 100755
--- a/spec/unit/parser/scope_spec.rb
+++ b/spec/unit/parser/scope_spec.rb
@@ -3,627 +3,627 @@
require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::Parser::Scope do
- before :each do
- @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("foo"))
- @scope.parent = @topscope
+ before :each do
+ @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("foo"))
+ @scope.parent = @topscope
+ end
+
+ it "should be able to store references to class scopes" do
+ lambda { @scope.class_set "myname", "myscope" }.should_not raise_error
+ end
+
+ it "should be able to retrieve class scopes by name" do
+ @scope.class_set "myname", "myscope"
+ @scope.class_scope("myname").should == "myscope"
+ end
+
+ it "should be able to retrieve class scopes by object" do
+ klass = mock 'ast_class'
+ klass.expects(:name).returns("myname")
+ @scope.class_set "myname", "myscope"
+ @scope.class_scope(klass).should == "myscope"
+ end
+
+ it "should be able to retrieve its parent module name from the source of its parent type" do
+ @topscope.source = Puppet::Resource::Type.new(:hostclass, :foo)
+ @topscope.source.module_name = "foo"
+
+ @scope.parent_module_name.should == "foo"
+ end
+
+ it "should return a nil parent module name if it has no parent" do
+ @topscope.parent_module_name.should be_nil
+ end
+
+ it "should return a nil parent module name if its parent has no source" do
+ @scope.parent_module_name.should be_nil
+ end
+
+ it "should get its environment from its compiler" do
+ env = stub 'environment'
+ compiler = stub 'compiler', :environment => env
+ scope = Puppet::Parser::Scope.new :compiler => compiler
+ scope.environment.should equal(env)
+ end
+
+ it "should use the resource type collection helper to find its known resource types" do
+ Puppet::Parser::Scope.ancestors.should include(Puppet::Resource::TypeCollectionHelper)
+ end
+
+ describe "when initializing" do
+ it "should extend itself with its environment's Functions module as well as the default" do
+ env = Puppet::Node::Environment.new("myenv")
+ compiler = stub 'compiler', :environment => env
+ mod = Module.new
+ root_mod = Module.new
+ Puppet::Parser::Functions.expects(:environment_module).with(Puppet::Node::Environment.root).returns root_mod
+ Puppet::Parser::Functions.expects(:environment_module).with(env).returns mod
+
+ Puppet::Parser::Scope.new(:compiler => compiler).singleton_class.ancestors.should be_include(mod)
end
- it "should be able to store references to class scopes" do
- lambda { @scope.class_set "myname", "myscope" }.should_not raise_error
- end
+ it "should extend itself with the default Functions module if it has no environment" do
+ mod = Module.new
+ Puppet::Parser::Functions.expects(:environment_module).with(Puppet::Node::Environment.root).returns(mod)
- it "should be able to retrieve class scopes by name" do
- @scope.class_set "myname", "myscope"
- @scope.class_scope("myname").should == "myscope"
- end
+ Puppet::Parser::Functions.expects(:environment_module).with(nil).returns mod
- it "should be able to retrieve class scopes by object" do
- klass = mock 'ast_class'
- klass.expects(:name).returns("myname")
- @scope.class_set "myname", "myscope"
- @scope.class_scope(klass).should == "myscope"
+ Puppet::Parser::Scope.new.singleton_class.ancestors.should be_include(mod)
end
+ end
- it "should be able to retrieve its parent module name from the source of its parent type" do
- @topscope.source = Puppet::Resource::Type.new(:hostclass, :foo)
- @topscope.source.module_name = "foo"
-
- @scope.parent_module_name.should == "foo"
+ describe "when looking up a variable" do
+ it "should default to an empty string" do
+ @scope.lookupvar("var").should == ""
end
- it "should return a nil parent module name if it has no parent" do
- @topscope.parent_module_name.should be_nil
+ it "should return an string when asked for a string" do
+ @scope.lookupvar("var", true).should == ""
end
- it "should return a nil parent module name if its parent has no source" do
- @scope.parent_module_name.should be_nil
+ it "should return ':undefined' for unset variables when asked not to return a string" do
+ @scope.lookupvar("var", false).should == :undefined
end
- it "should get its environment from its compiler" do
- env = stub 'environment'
- compiler = stub 'compiler', :environment => env
- scope = Puppet::Parser::Scope.new :compiler => compiler
- scope.environment.should equal(env)
+ it "should be able to look up values" do
+ @scope.setvar("var", "yep")
+ @scope.lookupvar("var").should == "yep"
end
- it "should use the resource type collection helper to find its known resource types" do
- Puppet::Parser::Scope.ancestors.should include(Puppet::Resource::TypeCollectionHelper)
+ it "should be able to look up hashes" do
+ @scope.setvar("var", {"a" => "b"})
+ @scope.lookupvar("var").should == {"a" => "b"}
end
- describe "when initializing" do
- it "should extend itself with its environment's Functions module as well as the default" do
- env = Puppet::Node::Environment.new("myenv")
- compiler = stub 'compiler', :environment => env
- mod = Module.new
- root_mod = Module.new
- Puppet::Parser::Functions.expects(:environment_module).with(Puppet::Node::Environment.root).returns root_mod
- Puppet::Parser::Functions.expects(:environment_module).with(env).returns mod
-
- Puppet::Parser::Scope.new(:compiler => compiler).singleton_class.ancestors.should be_include(mod)
- end
-
- it "should extend itself with the default Functions module if it has no environment" do
- mod = Module.new
- Puppet::Parser::Functions.expects(:environment_module).with(Puppet::Node::Environment.root).returns(mod)
-
- Puppet::Parser::Functions.expects(:environment_module).with(nil).returns mod
-
- Puppet::Parser::Scope.new.singleton_class.ancestors.should be_include(mod)
- end
+ it "should be able to look up variables in parent scopes" do
+ @topscope.setvar("var", "parentval")
+ @scope.lookupvar("var").should == "parentval"
end
- describe "when looking up a variable" do
- it "should default to an empty string" do
- @scope.lookupvar("var").should == ""
- end
-
- it "should return an string when asked for a string" do
- @scope.lookupvar("var", true).should == ""
- end
-
- it "should return ':undefined' for unset variables when asked not to return a string" do
- @scope.lookupvar("var", false).should == :undefined
- end
-
- it "should be able to look up values" do
- @scope.setvar("var", "yep")
- @scope.lookupvar("var").should == "yep"
- end
-
- it "should be able to look up hashes" do
- @scope.setvar("var", {"a" => "b"})
- @scope.lookupvar("var").should == {"a" => "b"}
- end
-
- it "should be able to look up variables in parent scopes" do
- @topscope.setvar("var", "parentval")
- @scope.lookupvar("var").should == "parentval"
- end
-
- it "should prefer its own values to parent values" do
- @topscope.setvar("var", "parentval")
- @scope.setvar("var", "childval")
- @scope.lookupvar("var").should == "childval"
- end
+ it "should prefer its own values to parent values" do
+ @topscope.setvar("var", "parentval")
+ @scope.setvar("var", "childval")
+ @scope.lookupvar("var").should == "childval"
+ end
- describe "and the variable is qualified" do
- before do
- @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("foonode"))
- @scope.compiler = @compiler
- @known_resource_types = @scope.known_resource_types
- end
+ describe "and the variable is qualified" do
+ before do
+ @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("foonode"))
+ @scope.compiler = @compiler
+ @known_resource_types = @scope.known_resource_types
+ end
- def newclass(name)
- @known_resource_types.add Puppet::Resource::Type.new(:hostclass, name)
- end
+ def newclass(name)
+ @known_resource_types.add Puppet::Resource::Type.new(:hostclass, name)
+ end
- def create_class_scope(name)
- klass = newclass(name)
- Puppet::Parser::Resource.new("class", name, :scope => @scope, :source => mock('source')).evaluate
+ def create_class_scope(name)
+ klass = newclass(name)
+ Puppet::Parser::Resource.new("class", name, :scope => @scope, :source => mock('source')).evaluate
- @scope.class_scope(klass)
- end
+ @scope.class_scope(klass)
+ end
- it "should be able to look up explicitly fully qualified variables from main" do
- other_scope = create_class_scope("")
+ it "should be able to look up explicitly fully qualified variables from main" do
+ other_scope = create_class_scope("")
- other_scope.setvar("othervar", "otherval")
+ other_scope.setvar("othervar", "otherval")
- @scope.lookupvar("::othervar").should == "otherval"
- end
+ @scope.lookupvar("::othervar").should == "otherval"
+ end
- it "should be able to look up explicitly fully qualified variables from other scopes" do
- other_scope = create_class_scope("other")
+ it "should be able to look up explicitly fully qualified variables from other scopes" do
+ other_scope = create_class_scope("other")
- other_scope.setvar("var", "otherval")
+ other_scope.setvar("var", "otherval")
- @scope.lookupvar("::other::var").should == "otherval"
- end
+ @scope.lookupvar("::other::var").should == "otherval"
+ end
- it "should be able to look up deeply qualified variables" do
- other_scope = create_class_scope("other::deep::klass")
+ it "should be able to look up deeply qualified variables" do
+ other_scope = create_class_scope("other::deep::klass")
- other_scope.setvar("var", "otherval")
+ other_scope.setvar("var", "otherval")
- @scope.lookupvar("other::deep::klass::var").should == "otherval"
- end
+ @scope.lookupvar("other::deep::klass::var").should == "otherval"
+ end
- it "should return an empty string for qualified variables that cannot be found in other classes" do
- other_scope = create_class_scope("other::deep::klass")
+ it "should return an empty string for qualified variables that cannot be found in other classes" do
+ other_scope = create_class_scope("other::deep::klass")
- @scope.lookupvar("other::deep::klass::var").should == ""
- end
+ @scope.lookupvar("other::deep::klass::var").should == ""
+ end
- it "should warn and return an empty string for qualified variables whose classes have not been evaluated" do
- klass = newclass("other::deep::klass")
- @scope.expects(:warning)
- @scope.lookupvar("other::deep::klass::var").should == ""
- end
+ it "should warn and return an empty string for qualified variables whose classes have not been evaluated" do
+ klass = newclass("other::deep::klass")
+ @scope.expects(:warning)
+ @scope.lookupvar("other::deep::klass::var").should == ""
+ end
- it "should warn and return an empty string for qualified variables whose classes do not exist" do
- @scope.expects(:warning)
- @scope.lookupvar("other::deep::klass::var").should == ""
- end
+ it "should warn and return an empty string for qualified variables whose classes do not exist" do
+ @scope.expects(:warning)
+ @scope.lookupvar("other::deep::klass::var").should == ""
+ end
- it "should return ':undefined' when asked for a non-string qualified variable from a class that does not exist" do
- @scope.stubs(:warning)
- @scope.lookupvar("other::deep::klass::var", false).should == :undefined
- end
+ it "should return ':undefined' when asked for a non-string qualified variable from a class that does not exist" do
+ @scope.stubs(:warning)
+ @scope.lookupvar("other::deep::klass::var", false).should == :undefined
+ end
- it "should return ':undefined' when asked for a non-string qualified variable from a class that has not been evaluated" do
- @scope.stubs(:warning)
- klass = newclass("other::deep::klass")
- @scope.lookupvar("other::deep::klass::var", false).should == :undefined
- end
- end
+ it "should return ':undefined' when asked for a non-string qualified variable from a class that has not been evaluated" do
+ @scope.stubs(:warning)
+ klass = newclass("other::deep::klass")
+ @scope.lookupvar("other::deep::klass::var", false).should == :undefined
+ end
end
+ end
- describe "when setvar is called with append=true" do
- it "should raise error if the variable is already defined in this scope" do
- @scope.setvar("var","1", :append => false)
- lambda { @scope.setvar("var","1", :append => true) }.should raise_error(Puppet::ParseError)
- end
-
- it "should lookup current variable value" do
- @scope.expects(:lookupvar).with("var").returns("2")
- @scope.setvar("var","1", :append => true)
- end
-
- it "should store the concatenated string '42'" do
- @topscope.setvar("var","4", :append => false)
- @scope.setvar("var","2", :append => true)
- @scope.lookupvar("var").should == "42"
- end
-
- it "should store the concatenated array [4,2]" do
- @topscope.setvar("var",[4], :append => false)
- @scope.setvar("var",[2], :append => true)
- @scope.lookupvar("var").should == [4,2]
- end
+ describe "when setvar is called with append=true" do
+ it "should raise error if the variable is already defined in this scope" do
+ @scope.setvar("var","1", :append => false)
+ lambda { @scope.setvar("var","1", :append => true) }.should raise_error(Puppet::ParseError)
+ end
- it "should store the merged hash {a => b, c => d}" do
- @topscope.setvar("var",{"a" => "b"}, :append => false)
- @scope.setvar("var",{"c" => "d"}, :append => true)
- @scope.lookupvar("var").should == {"a" => "b", "c" => "d"}
- end
+ it "should lookup current variable value" do
+ @scope.expects(:lookupvar).with("var").returns("2")
+ @scope.setvar("var","1", :append => true)
+ end
- it "should raise an error when appending a hash with something other than another hash" do
- @topscope.setvar("var",{"a" => "b"}, :append => false)
- lambda { @scope.setvar("var","not a hash", :append => true) }.should raise_error
- end
+ it "should store the concatenated string '42'" do
+ @topscope.setvar("var","4", :append => false)
+ @scope.setvar("var","2", :append => true)
+ @scope.lookupvar("var").should == "42"
end
- describe "when calling number?" do
- it "should return nil if called with anything not a number" do
- Puppet::Parser::Scope.number?([2]).should be_nil
- end
+ it "should store the concatenated array [4,2]" do
+ @topscope.setvar("var",[4], :append => false)
+ @scope.setvar("var",[2], :append => true)
+ @scope.lookupvar("var").should == [4,2]
+ end
- it "should return a Fixnum for a Fixnum" do
- Puppet::Parser::Scope.number?(2).should be_an_instance_of(Fixnum)
- end
+ it "should store the merged hash {a => b, c => d}" do
+ @topscope.setvar("var",{"a" => "b"}, :append => false)
+ @scope.setvar("var",{"c" => "d"}, :append => true)
+ @scope.lookupvar("var").should == {"a" => "b", "c" => "d"}
+ end
- it "should return a Float for a Float" do
- Puppet::Parser::Scope.number?(2.34).should be_an_instance_of(Float)
- end
+ it "should raise an error when appending a hash with something other than another hash" do
+ @topscope.setvar("var",{"a" => "b"}, :append => false)
+ lambda { @scope.setvar("var","not a hash", :append => true) }.should raise_error
+ end
+ end
- it "should return 234 for '234'" do
- Puppet::Parser::Scope.number?("234").should == 234
- end
+ describe "when calling number?" do
+ it "should return nil if called with anything not a number" do
+ Puppet::Parser::Scope.number?([2]).should be_nil
+ end
- it "should return nil for 'not a number'" do
- Puppet::Parser::Scope.number?("not a number").should be_nil
- end
+ it "should return a Fixnum for a Fixnum" do
+ Puppet::Parser::Scope.number?(2).should be_an_instance_of(Fixnum)
+ end
- it "should return 23.4 for '23.4'" do
- Puppet::Parser::Scope.number?("23.4").should == 23.4
- end
+ it "should return a Float for a Float" do
+ Puppet::Parser::Scope.number?(2.34).should be_an_instance_of(Float)
+ end
- it "should return 23.4e13 for '23.4e13'" do
- Puppet::Parser::Scope.number?("23.4e13").should == 23.4e13
- end
+ it "should return 234 for '234'" do
+ Puppet::Parser::Scope.number?("234").should == 234
+ end
- it "should understand negative numbers" do
- Puppet::Parser::Scope.number?("-234").should == -234
- end
+ it "should return nil for 'not a number'" do
+ Puppet::Parser::Scope.number?("not a number").should be_nil
+ end
- it "should know how to convert exponential float numbers ala '23e13'" do
- Puppet::Parser::Scope.number?("23e13").should == 23e13
- end
+ it "should return 23.4 for '23.4'" do
+ Puppet::Parser::Scope.number?("23.4").should == 23.4
+ end
- it "should understand hexadecimal numbers" do
- Puppet::Parser::Scope.number?("0x234").should == 0x234
- end
+ it "should return 23.4e13 for '23.4e13'" do
+ Puppet::Parser::Scope.number?("23.4e13").should == 23.4e13
+ end
- it "should understand octal numbers" do
- Puppet::Parser::Scope.number?("0755").should == 0755
- end
+ it "should understand negative numbers" do
+ Puppet::Parser::Scope.number?("-234").should == -234
+ end
- it "should return nil on malformed integers" do
- Puppet::Parser::Scope.number?("0.24.5").should be_nil
- end
+ it "should know how to convert exponential float numbers ala '23e13'" do
+ Puppet::Parser::Scope.number?("23e13").should == 23e13
+ end
- it "should convert strings with leading 0 to integer if they are not octal" do
- Puppet::Parser::Scope.number?("0788").should == 788
- end
+ it "should understand hexadecimal numbers" do
+ Puppet::Parser::Scope.number?("0x234").should == 0x234
+ end
- it "should convert strings of negative integers" do
- Puppet::Parser::Scope.number?("-0788").should == -788
- end
+ it "should understand octal numbers" do
+ Puppet::Parser::Scope.number?("0755").should == 0755
+ end
- it "should return nil on malformed hexadecimal numbers" do
- Puppet::Parser::Scope.number?("0x89g").should be_nil
- end
+ it "should return nil on malformed integers" do
+ Puppet::Parser::Scope.number?("0.24.5").should be_nil
end
- describe "when using ephemeral variables" do
- it "should store the variable value" do
- @scope.setvar("1", :value, :ephemeral => true)
+ it "should convert strings with leading 0 to integer if they are not octal" do
+ Puppet::Parser::Scope.number?("0788").should == 788
+ end
- @scope.lookupvar("1").should == :value
- end
+ it "should convert strings of negative integers" do
+ Puppet::Parser::Scope.number?("-0788").should == -788
+ end
- it "should remove the variable value when unset_ephemeral_var is called" do
- @scope.setvar("1", :value, :ephemeral => true)
- @scope.stubs(:parent).returns(nil)
+ it "should return nil on malformed hexadecimal numbers" do
+ Puppet::Parser::Scope.number?("0x89g").should be_nil
+ end
+ end
- @scope.unset_ephemeral_var
+ describe "when using ephemeral variables" do
+ it "should store the variable value" do
+ @scope.setvar("1", :value, :ephemeral => true)
- @scope.lookupvar("1", false).should == :undefined
- end
+ @scope.lookupvar("1").should == :value
+ end
- it "should not remove classic variables when unset_ephemeral_var is called" do
- @scope.setvar("myvar", :value1)
- @scope.setvar("1", :value2, :ephemeral => true)
- @scope.stubs(:parent).returns(nil)
+ it "should remove the variable value when unset_ephemeral_var is called" do
+ @scope.setvar("1", :value, :ephemeral => true)
+ @scope.stubs(:parent).returns(nil)
- @scope.unset_ephemeral_var
+ @scope.unset_ephemeral_var
- @scope.lookupvar("myvar", false).should == :value1
- end
+ @scope.lookupvar("1", false).should == :undefined
+ end
- it "should raise an error when setting it again" do
- @scope.setvar("1", :value2, :ephemeral => true)
- lambda { @scope.setvar("1", :value3, :ephemeral => true) }.should raise_error
- end
+ it "should not remove classic variables when unset_ephemeral_var is called" do
+ @scope.setvar("myvar", :value1)
+ @scope.setvar("1", :value2, :ephemeral => true)
+ @scope.stubs(:parent).returns(nil)
- it "should declare ephemeral number only variable names" do
- @scope.ephemeral?("0").should be_true
- end
+ @scope.unset_ephemeral_var
- it "should not declare ephemeral other variable names" do
- @scope.ephemeral?("abc0").should be_nil
- end
+ @scope.lookupvar("myvar", false).should == :value1
+ end
- describe "with more than one level" do
- it "should prefer latest ephemeral scopes" do
- @scope.setvar("0", :earliest, :ephemeral => true)
- @scope.new_ephemeral
- @scope.setvar("0", :latest, :ephemeral => true)
- @scope.lookupvar("0", false).should == :latest
- end
-
- it "should be able to report the current level" do
- @scope.ephemeral_level.should == 1
- @scope.new_ephemeral
- @scope.ephemeral_level.should == 2
- end
-
- it "should check presence of an ephemeral variable accross multiple levels" do
- @scope.new_ephemeral
- @scope.setvar("1", :value1, :ephemeral => true)
- @scope.new_ephemeral
- @scope.setvar("0", :value2, :ephemeral => true)
- @scope.new_ephemeral
- @scope.ephemeral_include?("1").should be_true
- end
-
- it "should return false when an ephemeral variable doesn't exist in any ephemeral scope" do
- @scope.new_ephemeral
- @scope.setvar("1", :value1, :ephemeral => true)
- @scope.new_ephemeral
- @scope.setvar("0", :value2, :ephemeral => true)
- @scope.new_ephemeral
- @scope.ephemeral_include?("2").should be_false
- end
-
- it "should get ephemeral values from earlier scope when not in later" do
- @scope.setvar("1", :value1, :ephemeral => true)
- @scope.new_ephemeral
- @scope.setvar("0", :value2, :ephemeral => true)
- @scope.lookupvar("1", false).should == :value1
- end
-
- describe "when calling unset_ephemeral_var without a level" do
- it "should remove all the variables values" do
- @scope.setvar("1", :value1, :ephemeral => true)
- @scope.new_ephemeral
- @scope.setvar("1", :value2, :ephemeral => true)
-
- @scope.unset_ephemeral_var
-
- @scope.lookupvar("1", false).should == :undefined
- end
- end
-
- describe "when calling unset_ephemeral_var with a level" do
- it "should remove ephemeral scopes up to this level" do
- @scope.setvar("1", :value1, :ephemeral => true)
- @scope.new_ephemeral
- @scope.setvar("1", :value2, :ephemeral => true)
- @scope.new_ephemeral
- @scope.setvar("1", :value3, :ephemeral => true)
-
- @scope.unset_ephemeral_var(2)
-
- @scope.lookupvar("1", false).should == :value2
- end
- end
- end
+ it "should raise an error when setting it again" do
+ @scope.setvar("1", :value2, :ephemeral => true)
+ lambda { @scope.setvar("1", :value3, :ephemeral => true) }.should raise_error
end
- describe "when interpolating string" do
- (0..9).each do |n|
- it "should allow $#{n} to match" do
- @scope.setvar(n.to_s, "value", :ephemeral => true)
+ it "should declare ephemeral number only variable names" do
+ @scope.ephemeral?("0").should be_true
+ end
- @scope.strinterp("$#{n}").should == "value"
- end
- end
+ it "should not declare ephemeral other variable names" do
+ @scope.ephemeral?("abc0").should be_nil
+ end
- (0..9).each do |n|
- it "should not allow $#{n} to match if not ephemeral" do
- @scope.setvar(n.to_s, "value", :ephemeral => false)
+ describe "with more than one level" do
+ it "should prefer latest ephemeral scopes" do
+ @scope.setvar("0", :earliest, :ephemeral => true)
+ @scope.new_ephemeral
+ @scope.setvar("0", :latest, :ephemeral => true)
+ @scope.lookupvar("0", false).should == :latest
+ end
+
+ it "should be able to report the current level" do
+ @scope.ephemeral_level.should == 1
+ @scope.new_ephemeral
+ @scope.ephemeral_level.should == 2
+ end
+
+ it "should check presence of an ephemeral variable accross multiple levels" do
+ @scope.new_ephemeral
+ @scope.setvar("1", :value1, :ephemeral => true)
+ @scope.new_ephemeral
+ @scope.setvar("0", :value2, :ephemeral => true)
+ @scope.new_ephemeral
+ @scope.ephemeral_include?("1").should be_true
+ end
+
+ it "should return false when an ephemeral variable doesn't exist in any ephemeral scope" do
+ @scope.new_ephemeral
+ @scope.setvar("1", :value1, :ephemeral => true)
+ @scope.new_ephemeral
+ @scope.setvar("0", :value2, :ephemeral => true)
+ @scope.new_ephemeral
+ @scope.ephemeral_include?("2").should be_false
+ end
+
+ it "should get ephemeral values from earlier scope when not in later" do
+ @scope.setvar("1", :value1, :ephemeral => true)
+ @scope.new_ephemeral
+ @scope.setvar("0", :value2, :ephemeral => true)
+ @scope.lookupvar("1", false).should == :value1
+ end
+
+ describe "when calling unset_ephemeral_var without a level" do
+ it "should remove all the variables values" do
+ @scope.setvar("1", :value1, :ephemeral => true)
+ @scope.new_ephemeral
+ @scope.setvar("1", :value2, :ephemeral => true)
+
+ @scope.unset_ephemeral_var
+
+ @scope.lookupvar("1", false).should == :undefined
+ end
+ end
+
+ describe "when calling unset_ephemeral_var with a level" do
+ it "should remove ephemeral scopes up to this level" do
+ @scope.setvar("1", :value1, :ephemeral => true)
+ @scope.new_ephemeral
+ @scope.setvar("1", :value2, :ephemeral => true)
+ @scope.new_ephemeral
+ @scope.setvar("1", :value3, :ephemeral => true)
+
+ @scope.unset_ephemeral_var(2)
+
+ @scope.lookupvar("1", false).should == :value2
+ end
+ end
+ end
+ end
- @scope.strinterp("$#{n}").should_not == "value"
- end
- end
+ describe "when interpolating string" do
+ (0..9).each do |n|
+ it "should allow $#{n} to match" do
+ @scope.setvar(n.to_s, "value", :ephemeral => true)
- it "should not allow $10 to match" do
- @scope.setvar("10", "value", :ephemeral => true)
+ @scope.strinterp("$#{n}").should == "value"
+ end
+ end
- @scope.strinterp('==$10==').should_not == "==value=="
- end
+ (0..9).each do |n|
+ it "should not allow $#{n} to match if not ephemeral" do
+ @scope.setvar(n.to_s, "value", :ephemeral => false)
- it "should not allow ${10} to match" do
- @scope.setvar("10", "value", :ephemeral => true)
+ @scope.strinterp("$#{n}").should_not == "value"
+ end
+ end
- @scope.strinterp('==${10}==').should == "==value=="
- end
+ it "should not allow $10 to match" do
+ @scope.setvar("10", "value", :ephemeral => true)
- describe "with qualified variables" do
- before do
- @scopes = {}
- klass = @scope.known_resource_types.add(Puppet::Resource::Type.new(:hostclass, ""))
- Puppet::Parser::Resource.new("class", :main, :scope => @scope, :source => mock('source')).evaluate
- @scopes[""] = @scope.class_scope(klass)
- @scopes[""].setvar("test", "value")
-
- %w{one one::two one::two::three}.each do |name|
- klass = @scope.known_resource_types.add(Puppet::Resource::Type.new(:hostclass, name))
- Puppet::Parser::Resource.new("class", name, :scope => @scope, :source => mock('source')).evaluate
- @scopes[name] = @scope.class_scope(klass)
- @scopes[name].setvar("test", "value-#{name.sub(/.+::/,'')}")
- end
- end
- {
- "===${one::two::three::test}===" => "===value-three===",
- "===$one::two::three::test===" => "===value-three===",
- "===${one::two::test}===" => "===value-two===",
- "===$one::two::test===" => "===value-two===",
- "===${one::test}===" => "===value-one===",
- "===$one::test===" => "===value-one===",
- "===${::test}===" => "===value===",
- "===$::test===" => "===value==="
- }.each do |input, output|
- it "should parse '#{input}' correctly" do
- @scope.strinterp(input).should == output
- end
- end
- end
+ @scope.strinterp('==$10==').should_not == "==value=="
+ end
- tests = {
- "===${test}===" => "===value===",
- "===${test} ${test} ${test}===" => "===value value value===",
- "===$test ${test} $test===" => "===value value value===",
- "===\\$test===" => "===$test===",
- '===\\$test string===' => "===$test string===",
- '===$test string===' => "===value string===",
- '===a testing $===' => "===a testing $===",
- '===a testing \$===' => "===a testing $===",
- "===an escaped \\\n carriage return===" => "===an escaped carriage return===",
- '\$' => "$",
- '\s' => "\s",
- '\t' => "\t",
- '\n' => "\n"
- }
-
- tests.each do |input, output|
- it "should parse '#{input}' correctly" do
- @scope.setvar("test", "value")
- @scope.strinterp(input).should == output
- end
- end
+ it "should not allow ${10} to match" do
+ @scope.setvar("10", "value", :ephemeral => true)
- # #523
- %w{d f h l w z}.each do |l|
- it "should parse '#{l}' when escaped" do
- string = "\\#{l}"
- @scope.strinterp(string).should == string
- end
- end
+ @scope.strinterp('==${10}==').should == "==value=="
end
- def test_strinterp
- # Make and evaluate our classes so the qualified lookups work
- parser = mkparser
- klass = parser.newclass("")
- scope = mkscope(:parser => parser)
- Puppet::Parser::Resource.new(:type => "class", :title => :main, :scope => scope, :source => mock('source')).evaluate
+ describe "with qualified variables" do
+ before do
+ @scopes = {}
+ klass = @scope.known_resource_types.add(Puppet::Resource::Type.new(:hostclass, ""))
+ Puppet::Parser::Resource.new("class", :main, :scope => @scope, :source => mock('source')).evaluate
+ @scopes[""] = @scope.class_scope(klass)
+ @scopes[""].setvar("test", "value")
- assert_nothing_raised {
- scope.setvar("test","value")
- }
+ %w{one one::two one::two::three}.each do |name|
+ klass = @scope.known_resource_types.add(Puppet::Resource::Type.new(:hostclass, name))
+ Puppet::Parser::Resource.new("class", name, :scope => @scope, :source => mock('source')).evaluate
+ @scopes[name] = @scope.class_scope(klass)
+ @scopes[name].setvar("test", "value-#{name.sub(/.+::/,'')}")
+ end
+ end
+ {
+ "===${one::two::three::test}===" => "===value-three===",
+ "===$one::two::three::test===" => "===value-three===",
+ "===${one::two::test}===" => "===value-two===",
+ "===$one::two::test===" => "===value-two===",
+ "===${one::test}===" => "===value-one===",
+ "===$one::test===" => "===value-one===",
+ "===${::test}===" => "===value===",
+ "===$::test===" => "===value==="
+ }.each do |input, output|
+ it "should parse '#{input}' correctly" do
+ @scope.strinterp(input).should == output
+ end
+ end
+ end
- scopes = {"" => scope}
+ tests = {
+ "===${test}===" => "===value===",
+ "===${test} ${test} ${test}===" => "===value value value===",
+ "===$test ${test} $test===" => "===value value value===",
+ "===\\$test===" => "===$test===",
+ '===\\$test string===' => "===$test string===",
+ '===$test string===' => "===value string===",
+ '===a testing $===' => "===a testing $===",
+ '===a testing \$===' => "===a testing $===",
+ "===an escaped \\\n carriage return===" => "===an escaped carriage return===",
+ '\$' => "$",
+ '\s' => "\s",
+ '\t' => "\t",
+ '\n' => "\n"
+ }
+
+ tests.each do |input, output|
+ it "should parse '#{input}' correctly" do
+ @scope.setvar("test", "value")
+ @scope.strinterp(input).should == output
+ end
+ end
- %w{one one::two one::two::three}.each do |name|
- klass = parser.newclass(name)
- Puppet::Parser::Resource.new(:type => "class", :title => name, :scope => scope, :source => mock('source')).evaluate
- scopes[name] = scope.class_scope(klass)
- scopes[name].setvar("test", "value-#{name.sub(/.+::/,'')}")
- end
+ # #523
+ %w{d f h l w z}.each do |l|
+ it "should parse '#{l}' when escaped" do
+ string = "\\#{l}"
+ @scope.strinterp(string).should == string
+ end
+ end
+ end
+
+ def test_strinterp
+ # Make and evaluate our classes so the qualified lookups work
+ parser = mkparser
+ klass = parser.newclass("")
+ scope = mkscope(:parser => parser)
+ Puppet::Parser::Resource.new(:type => "class", :title => :main, :scope => scope, :source => mock('source')).evaluate
+
+ assert_nothing_raised {
+ scope.setvar("test","value")
+ }
+
+ scopes = {"" => scope}
+
+ %w{one one::two one::two::three}.each do |name|
+ klass = parser.newclass(name)
+ Puppet::Parser::Resource.new(:type => "class", :title => name, :scope => scope, :source => mock('source')).evaluate
+ scopes[name] = scope.class_scope(klass)
+ scopes[name].setvar("test", "value-#{name.sub(/.+::/,'')}")
+ end
- assert_equal("value", scope.lookupvar("::test"), "did not look up qualified value correctly")
- tests.each do |input, output|
- assert_nothing_raised("Failed to scan #{input.inspect}") do
- assert_equal(output, scope.strinterp(input), 'did not parserret %s correctly' % input.inspect)
- end
- end
+ assert_equal("value", scope.lookupvar("::test"), "did not look up qualified value correctly")
+ tests.each do |input, output|
+ assert_nothing_raised("Failed to scan #{input.inspect}") do
+ assert_equal(output, scope.strinterp(input), 'did not parserret %s correctly' % input.inspect)
+ end
+ end
- logs = []
- Puppet::Util::Log.close
- Puppet::Util::Log.newdestination(logs)
+ logs = []
+ Puppet::Util::Log.close
+ Puppet::Util::Log.newdestination(logs)
- # #523
- %w{d f h l w z}.each do |l|
- string = "\\#{l}"
- assert_nothing_raised do
+ # #523
+ %w{d f h l w z}.each do |l|
+ string = "\\#{l}"
+ assert_nothing_raised do
- assert_equal(
- string, scope.strinterp(string),
+ assert_equal(
+ string, scope.strinterp(string),
- 'did not parserret %s correctly' % string)
- end
+ 'did not parserret %s correctly' % string)
+ end
- assert(
- logs.detect { |m| m.message =~ /Unrecognised escape/ },
+ assert(
+ logs.detect { |m| m.message =~ /Unrecognised escape/ },
- "Did not get warning about escape sequence with #{string}")
- logs.clear
- end
+ "Did not get warning about escape sequence with #{string}")
+ logs.clear
end
+ end
- describe "when setting ephemeral vars from matches" do
- before :each do
- @match = stub 'match', :is_a? => true
- @match.stubs(:[]).with(0).returns("this is a string")
- @match.stubs(:captures).returns([])
- @scope.stubs(:setvar)
- end
-
- it "should accept only MatchData" do
- lambda { @scope.ephemeral_from("match") }.should raise_error
- end
-
- it "should set $0 with the full match" do
- @scope.expects(:setvar).with { |*arg| arg[0] == "0" and arg[1] == "this is a string" and arg[2][:ephemeral] }
-
- @scope.ephemeral_from(@match)
- end
+ describe "when setting ephemeral vars from matches" do
+ before :each do
+ @match = stub 'match', :is_a? => true
+ @match.stubs(:[]).with(0).returns("this is a string")
+ @match.stubs(:captures).returns([])
+ @scope.stubs(:setvar)
+ end
- it "should set every capture as ephemeral var" do
- @match.stubs(:captures).returns([:capture1,:capture2])
- @scope.expects(:setvar).with { |*arg| arg[0] == "1" and arg[1] == :capture1 and arg[2][:ephemeral] }
- @scope.expects(:setvar).with { |*arg| arg[0] == "2" and arg[1] == :capture2 and arg[2][:ephemeral] }
+ it "should accept only MatchData" do
+ lambda { @scope.ephemeral_from("match") }.should raise_error
+ end
- @scope.ephemeral_from(@match)
- end
+ it "should set $0 with the full match" do
+ @scope.expects(:setvar).with { |*arg| arg[0] == "0" and arg[1] == "this is a string" and arg[2][:ephemeral] }
- it "should create a new ephemeral level" do
- @scope.expects(:new_ephemeral)
- @scope.ephemeral_from(@match)
- end
+ @scope.ephemeral_from(@match)
end
- describe "when unsetting variables" do
- it "should be able to unset normal variables" do
- @scope.setvar("foo", "bar")
- @scope.unsetvar("foo")
- @scope.lookupvar("foo").should == ""
- end
+ it "should set every capture as ephemeral var" do
+ @match.stubs(:captures).returns([:capture1,:capture2])
+ @scope.expects(:setvar).with { |*arg| arg[0] == "1" and arg[1] == :capture1 and arg[2][:ephemeral] }
+ @scope.expects(:setvar).with { |*arg| arg[0] == "2" and arg[1] == :capture2 and arg[2][:ephemeral] }
- it "should be able to unset ephemeral variables" do
- @scope.setvar("0", "bar", :ephemeral => true)
- @scope.unsetvar("0")
- @scope.lookupvar("0").should == ""
- end
+ @scope.ephemeral_from(@match)
+ end
- it "should not unset ephemeral variables in previous ephemeral scope" do
- @scope.setvar("0", "bar", :ephemeral => true)
- @scope.new_ephemeral
- @scope.unsetvar("0")
- @scope.lookupvar("0").should == "bar"
- end
+ it "should create a new ephemeral level" do
+ @scope.expects(:new_ephemeral)
+ @scope.ephemeral_from(@match)
end
+ end
- it "should use its namespaces to find hostclasses" do
- klass = @scope.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "a::b::c")
- @scope.add_namespace "a::b"
- @scope.find_hostclass("c").should equal(klass)
+ describe "when unsetting variables" do
+ it "should be able to unset normal variables" do
+ @scope.setvar("foo", "bar")
+ @scope.unsetvar("foo")
+ @scope.lookupvar("foo").should == ""
end
- it "should use its namespaces to find definitions" do
- define = @scope.known_resource_types.add Puppet::Resource::Type.new(:definition, "a::b::c")
- @scope.add_namespace "a::b"
- @scope.find_definition("c").should equal(define)
+ it "should be able to unset ephemeral variables" do
+ @scope.setvar("0", "bar", :ephemeral => true)
+ @scope.unsetvar("0")
+ @scope.lookupvar("0").should == ""
end
- describe "when managing defaults" do
- it "should be able to set and lookup defaults" do
- param = Puppet::Parser::Resource::Param.new(:name => :myparam, :value => "myvalue", :source => stub("source"))
- @scope.setdefaults(:mytype, param)
- @scope.lookupdefaults(:mytype).should == {:myparam => param}
- end
+ it "should not unset ephemeral variables in previous ephemeral scope" do
+ @scope.setvar("0", "bar", :ephemeral => true)
+ @scope.new_ephemeral
+ @scope.unsetvar("0")
+ @scope.lookupvar("0").should == "bar"
+ end
+ end
+
+ it "should use its namespaces to find hostclasses" do
+ klass = @scope.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "a::b::c")
+ @scope.add_namespace "a::b"
+ @scope.find_hostclass("c").should equal(klass)
+ end
+
+ it "should use its namespaces to find definitions" do
+ define = @scope.known_resource_types.add Puppet::Resource::Type.new(:definition, "a::b::c")
+ @scope.add_namespace "a::b"
+ @scope.find_definition("c").should equal(define)
+ end
+
+ describe "when managing defaults" do
+ it "should be able to set and lookup defaults" do
+ param = Puppet::Parser::Resource::Param.new(:name => :myparam, :value => "myvalue", :source => stub("source"))
+ @scope.setdefaults(:mytype, param)
+ @scope.lookupdefaults(:mytype).should == {:myparam => param}
+ end
- it "should fail if a default is already defined and a new default is being defined" do
- param = Puppet::Parser::Resource::Param.new(:name => :myparam, :value => "myvalue", :source => stub("source"))
- @scope.setdefaults(:mytype, param)
- lambda { @scope.setdefaults(:mytype, param) }.should raise_error(Puppet::ParseError)
- end
+ it "should fail if a default is already defined and a new default is being defined" do
+ param = Puppet::Parser::Resource::Param.new(:name => :myparam, :value => "myvalue", :source => stub("source"))
+ @scope.setdefaults(:mytype, param)
+ lambda { @scope.setdefaults(:mytype, param) }.should raise_error(Puppet::ParseError)
+ end
- it "should return multiple defaults at once" do
- param1 = Puppet::Parser::Resource::Param.new(:name => :myparam, :value => "myvalue", :source => stub("source"))
- @scope.setdefaults(:mytype, param1)
- param2 = Puppet::Parser::Resource::Param.new(:name => :other, :value => "myvalue", :source => stub("source"))
- @scope.setdefaults(:mytype, param2)
+ it "should return multiple defaults at once" do
+ param1 = Puppet::Parser::Resource::Param.new(:name => :myparam, :value => "myvalue", :source => stub("source"))
+ @scope.setdefaults(:mytype, param1)
+ param2 = Puppet::Parser::Resource::Param.new(:name => :other, :value => "myvalue", :source => stub("source"))
+ @scope.setdefaults(:mytype, param2)
- @scope.lookupdefaults(:mytype).should == {:myparam => param1, :other => param2}
- end
+ @scope.lookupdefaults(:mytype).should == {:myparam => param1, :other => param2}
+ end
- it "should look up defaults defined in parent scopes" do
- param1 = Puppet::Parser::Resource::Param.new(:name => :myparam, :value => "myvalue", :source => stub("source"))
- @scope.setdefaults(:mytype, param1)
+ it "should look up defaults defined in parent scopes" do
+ param1 = Puppet::Parser::Resource::Param.new(:name => :myparam, :value => "myvalue", :source => stub("source"))
+ @scope.setdefaults(:mytype, param1)
- child_scope = @scope.newscope
- param2 = Puppet::Parser::Resource::Param.new(:name => :other, :value => "myvalue", :source => stub("source"))
- child_scope.setdefaults(:mytype, param2)
+ child_scope = @scope.newscope
+ param2 = Puppet::Parser::Resource::Param.new(:name => :other, :value => "myvalue", :source => stub("source"))
+ child_scope.setdefaults(:mytype, param2)
- child_scope.lookupdefaults(:mytype).should == {:myparam => param1, :other => param2}
- end
+ child_scope.lookupdefaults(:mytype).should == {:myparam => param1, :other => param2}
end
+ end
end
diff --git a/spec/unit/parser/templatewrapper_spec.rb b/spec/unit/parser/templatewrapper_spec.rb
index a684727..d4d1d1b 100755
--- a/spec/unit/parser/templatewrapper_spec.rb
+++ b/spec/unit/parser/templatewrapper_spec.rb
@@ -3,142 +3,142 @@
require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::Parser::TemplateWrapper do
- before(:each) do
- @known_resource_types = Puppet::Resource::TypeCollection.new("env")
- @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode"))
- @compiler.environment.stubs(:known_resource_types).returns @known_resource_types
- @scope = Puppet::Parser::Scope.new :compiler => @compiler
-
- @file = "fake_template"
- Puppet::Parser::Files.stubs(:find_template).returns("/tmp/fake_template")
- FileTest.stubs(:exists?).returns("true")
- File.stubs(:read).with("/tmp/fake_template").returns("template content")
- @tw = Puppet::Parser::TemplateWrapper.new(@scope)
- end
-
- it "should create a new object TemplateWrapper from a scope" do
- tw = Puppet::Parser::TemplateWrapper.new(@scope)
-
- tw.should be_a_kind_of(Puppet::Parser::TemplateWrapper)
- end
-
- it "should check template file existance and read its content" do
- Puppet::Parser::Files.expects(:find_template).with("fake_template", @scope.environment.to_s).returns("/tmp/fake_template")
- File.expects(:read).with("/tmp/fake_template").returns("template content")
-
- @tw.file = @file
- end
-
- it "should mark the file for watching" do
- Puppet::Parser::Files.expects(:find_template).returns("/tmp/fake_template")
- File.stubs(:read)
-
- @known_resource_types.expects(:watch_file).with("/tmp/fake_template")
- @tw.file = @file
- end
-
- it "should fail if a template cannot be found" do
- Puppet::Parser::Files.expects(:find_template).returns nil
-
- lambda { @tw.file = @file }.should raise_error(Puppet::ParseError)
- end
-
- it "should turn into a string like template[name] for file based template" do
- @tw.file = @file
- @tw.to_s.should eql("template[/tmp/fake_template]")
- end
-
- it "should turn into a string like template[inline] for string-based template" do
- @tw.to_s.should eql("template[inline]")
- end
-
- it "should return the processed template contents with a call to result" do
- template_mock = mock("template", :result => "woot!")
- File.expects(:read).with("/tmp/fake_template").returns("template contents")
- ERB.expects(:new).with("template contents", 0, "-").returns(template_mock)
-
- @tw.file = @file
- @tw.result.should eql("woot!")
- end
-
- it "should return the processed template contents with a call to result and a string" do
- template_mock = mock("template", :result => "woot!")
- ERB.expects(:new).with("template contents", 0, "-").returns(template_mock)
-
- @tw.result("template contents").should eql("woot!")
- end
-
- it "should return the contents of a variable if called via method_missing" do
- @scope.expects(:lookupvar).with("chicken", false).returns("is good")
- tw = Puppet::Parser::TemplateWrapper.new(@scope)
- tw.chicken.should eql("is good")
- end
-
- it "should throw an exception if a variable is called via method_missing and it does not exist" do
- @scope.expects(:lookupvar).with("chicken", false).returns(:undefined)
- tw = Puppet::Parser::TemplateWrapper.new(@scope)
- lambda { tw.chicken }.should raise_error(Puppet::ParseError)
- end
-
- it "should allow you to check whether a variable is defined with has_variable?" do
- @scope.expects(:lookupvar).with("chicken", false).returns("is good")
- tw = Puppet::Parser::TemplateWrapper.new(@scope)
- tw.has_variable?("chicken").should eql(true)
- end
-
- it "should allow you to check whether a variable is not defined with has_variable?" do
- @scope.expects(:lookupvar).with("chicken", false).returns(:undefined)
- tw = Puppet::Parser::TemplateWrapper.new(@scope)
- tw.has_variable?("chicken").should eql(false)
- end
-
- it "should allow you to retrieve the defined classes with classes" do
- catalog = mock 'catalog', :classes => ["class1", "class2"]
- @scope.expects(:catalog).returns( catalog )
- tw = Puppet::Parser::TemplateWrapper.new(@scope)
- tw.classes.should == ["class1", "class2"]
- end
-
- it "should allow you to retrieve all the tags with all_tags" do
- catalog = mock 'catalog', :tags => ["tag1", "tag2"]
- @scope.expects(:catalog).returns( catalog )
- tw = Puppet::Parser::TemplateWrapper.new(@scope)
- tw.all_tags.should == ["tag1","tag2"]
- end
-
- it "should allow you to retrieve the tags defined in the current scope" do
- @scope.expects(:tags).returns( ["tag1", "tag2"] )
- tw = Puppet::Parser::TemplateWrapper.new(@scope)
- tw.tags.should == ["tag1","tag2"]
- end
-
- it "should set all of the scope's variables as instance variables" do
- template_mock = mock("template", :result => "woot!")
- ERB.expects(:new).with("template contents", 0, "-").returns(template_mock)
-
- @scope.expects(:to_hash).returns("one" => "foo")
- @tw.result("template contents")
-
- @tw.instance_variable_get("@one").should == "foo"
- end
-
- it "should not error out if one of the variables is a symbol" do
- template_mock = mock("template", :result => "woot!")
- ERB.expects(:new).with("template contents", 0, "-").returns(template_mock)
-
- @scope.expects(:to_hash).returns(:_timestamp => "1234")
- @tw.result("template contents")
- end
-
- %w{! . ; :}.each do |badchar|
- it "should translate #{badchar} to _ when setting the instance variables" do
- template_mock = mock("template", :result => "woot!")
- ERB.expects(:new).with("template contents", 0, "-").returns(template_mock)
-
- @scope.expects(:to_hash).returns("one#{badchar}" => "foo")
- @tw.result("template contents")
-
- @tw.instance_variable_get("@one_").should == "foo"
- end
- end
+ before(:each) do
+ @known_resource_types = Puppet::Resource::TypeCollection.new("env")
+ @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode"))
+ @compiler.environment.stubs(:known_resource_types).returns @known_resource_types
+ @scope = Puppet::Parser::Scope.new :compiler => @compiler
+
+ @file = "fake_template"
+ Puppet::Parser::Files.stubs(:find_template).returns("/tmp/fake_template")
+ FileTest.stubs(:exists?).returns("true")
+ File.stubs(:read).with("/tmp/fake_template").returns("template content")
+ @tw = Puppet::Parser::TemplateWrapper.new(@scope)
+ end
+
+ it "should create a new object TemplateWrapper from a scope" do
+ tw = Puppet::Parser::TemplateWrapper.new(@scope)
+
+ tw.should be_a_kind_of(Puppet::Parser::TemplateWrapper)
+ end
+
+ it "should check template file existance and read its content" do
+ Puppet::Parser::Files.expects(:find_template).with("fake_template", @scope.environment.to_s).returns("/tmp/fake_template")
+ File.expects(:read).with("/tmp/fake_template").returns("template content")
+
+ @tw.file = @file
+ end
+
+ it "should mark the file for watching" do
+ Puppet::Parser::Files.expects(:find_template).returns("/tmp/fake_template")
+ File.stubs(:read)
+
+ @known_resource_types.expects(:watch_file).with("/tmp/fake_template")
+ @tw.file = @file
+ end
+
+ it "should fail if a template cannot be found" do
+ Puppet::Parser::Files.expects(:find_template).returns nil
+
+ lambda { @tw.file = @file }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should turn into a string like template[name] for file based template" do
+ @tw.file = @file
+ @tw.to_s.should eql("template[/tmp/fake_template]")
+ end
+
+ it "should turn into a string like template[inline] for string-based template" do
+ @tw.to_s.should eql("template[inline]")
+ end
+
+ it "should return the processed template contents with a call to result" do
+ template_mock = mock("template", :result => "woot!")
+ File.expects(:read).with("/tmp/fake_template").returns("template contents")
+ ERB.expects(:new).with("template contents", 0, "-").returns(template_mock)
+
+ @tw.file = @file
+ @tw.result.should eql("woot!")
+ end
+
+ it "should return the processed template contents with a call to result and a string" do
+ template_mock = mock("template", :result => "woot!")
+ ERB.expects(:new).with("template contents", 0, "-").returns(template_mock)
+
+ @tw.result("template contents").should eql("woot!")
+ end
+
+ it "should return the contents of a variable if called via method_missing" do
+ @scope.expects(:lookupvar).with("chicken", false).returns("is good")
+ tw = Puppet::Parser::TemplateWrapper.new(@scope)
+ tw.chicken.should eql("is good")
+ end
+
+ it "should throw an exception if a variable is called via method_missing and it does not exist" do
+ @scope.expects(:lookupvar).with("chicken", false).returns(:undefined)
+ tw = Puppet::Parser::TemplateWrapper.new(@scope)
+ lambda { tw.chicken }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should allow you to check whether a variable is defined with has_variable?" do
+ @scope.expects(:lookupvar).with("chicken", false).returns("is good")
+ tw = Puppet::Parser::TemplateWrapper.new(@scope)
+ tw.has_variable?("chicken").should eql(true)
+ end
+
+ it "should allow you to check whether a variable is not defined with has_variable?" do
+ @scope.expects(:lookupvar).with("chicken", false).returns(:undefined)
+ tw = Puppet::Parser::TemplateWrapper.new(@scope)
+ tw.has_variable?("chicken").should eql(false)
+ end
+
+ it "should allow you to retrieve the defined classes with classes" do
+ catalog = mock 'catalog', :classes => ["class1", "class2"]
+ @scope.expects(:catalog).returns( catalog )
+ tw = Puppet::Parser::TemplateWrapper.new(@scope)
+ tw.classes.should == ["class1", "class2"]
+ end
+
+ it "should allow you to retrieve all the tags with all_tags" do
+ catalog = mock 'catalog', :tags => ["tag1", "tag2"]
+ @scope.expects(:catalog).returns( catalog )
+ tw = Puppet::Parser::TemplateWrapper.new(@scope)
+ tw.all_tags.should == ["tag1","tag2"]
+ end
+
+ it "should allow you to retrieve the tags defined in the current scope" do
+ @scope.expects(:tags).returns( ["tag1", "tag2"] )
+ tw = Puppet::Parser::TemplateWrapper.new(@scope)
+ tw.tags.should == ["tag1","tag2"]
+ end
+
+ it "should set all of the scope's variables as instance variables" do
+ template_mock = mock("template", :result => "woot!")
+ ERB.expects(:new).with("template contents", 0, "-").returns(template_mock)
+
+ @scope.expects(:to_hash).returns("one" => "foo")
+ @tw.result("template contents")
+
+ @tw.instance_variable_get("@one").should == "foo"
+ end
+
+ it "should not error out if one of the variables is a symbol" do
+ template_mock = mock("template", :result => "woot!")
+ ERB.expects(:new).with("template contents", 0, "-").returns(template_mock)
+
+ @scope.expects(:to_hash).returns(:_timestamp => "1234")
+ @tw.result("template contents")
+ end
+
+ %w{! . ; :}.each do |badchar|
+ it "should translate #{badchar} to _ when setting the instance variables" do
+ template_mock = mock("template", :result => "woot!")
+ ERB.expects(:new).with("template contents", 0, "-").returns(template_mock)
+
+ @scope.expects(:to_hash).returns("one#{badchar}" => "foo")
+ @tw.result("template contents")
+
+ @tw.instance_variable_get("@one_").should == "foo"
+ end
+ end
end
diff --git a/spec/unit/parser/type_loader_spec.rb b/spec/unit/parser/type_loader_spec.rb
index 2cd837c..db72a23 100644
--- a/spec/unit/parser/type_loader_spec.rb
+++ b/spec/unit/parser/type_loader_spec.rb
@@ -6,196 +6,196 @@ require 'puppet/parser/type_loader'
require 'puppet_spec/files'
describe Puppet::Parser::TypeLoader do
- include PuppetSpec::Files
+ include PuppetSpec::Files
+ before do
+ @loader = Puppet::Parser::TypeLoader.new(:myenv)
+ end
+
+ it "should support an environment" do
+ loader = Puppet::Parser::TypeLoader.new(:myenv)
+ loader.environment.name.should == :myenv
+ end
+
+ it "should include the Environment Helper" do
+ @loader.class.ancestors.should be_include(Puppet::Node::Environment::Helper)
+ end
+
+ it "should delegate its known resource types to its environment" do
+ @loader.known_resource_types.should be_instance_of(Puppet::Resource::TypeCollection)
+ end
+
+ describe "when loading names from namespaces" do
+ it "should do nothing if the name to import is an empty string" do
+ @loader.expects(:name2files).never
+ @loader.load_until(["foo"], "") { |f| false }.should be_nil
+ end
+
+ it "should turn the provided namespaces and name into a list of files" do
+ @loader.expects(:name2files).with(["foo"], "bar").returns []
+ @loader.load_until(["foo"], "bar") { |f| false }
+ end
+
+ it "should attempt to import each generated name" do
+ @loader.expects(:name2files).returns %w{foo bar}
+ @loader.expects(:import).with("foo")
+ @loader.expects(:import).with("bar")
+ @loader.load_until(["foo"], "bar") { |f| false }
+ end
+
+ it "should yield after each import" do
+ yielded = []
+ @loader.expects(:name2files).returns %w{foo bar}
+ @loader.expects(:import).with("foo")
+ @loader.expects(:import).with("bar")
+ @loader.load_until(["foo"], "bar") { |f| yielded << f; false }
+ yielded.should == %w{foo bar}
+ end
+
+ it "should stop importing when the yielded block returns true" do
+ yielded = []
+ @loader.expects(:name2files).returns %w{foo bar baz}
+ @loader.expects(:import).with("foo")
+ @loader.expects(:import).with("bar")
+ @loader.expects(:import).with("baz").never
+ @loader.load_until(["foo"], "bar") { |f| true if f == "bar" }
+ end
+
+ it "should return the result of the block" do
+ yielded = []
+ @loader.expects(:name2files).returns %w{foo bar baz}
+ @loader.expects(:import).with("foo")
+ @loader.expects(:import).with("bar")
+ @loader.expects(:import).with("baz").never
+ @loader.load_until(["foo"], "bar") { |f| 10 if f == "bar" }.should == 10
+ end
+
+ it "should return nil if the block never returns true" do
+ @loader.expects(:name2files).returns %w{foo bar}
+ @loader.expects(:import).with("foo")
+ @loader.expects(:import).with("bar")
+ @loader.load_until(["foo"], "bar") { |f| false }.should be_nil
+ end
+
+ it "should know when a given name has been loaded" do
+ @loader.expects(:name2files).returns %w{file}
+ @loader.expects(:import).with("file")
+ @loader.load_until(["foo"], "bar") { |f| true }
+ @loader.should be_loaded("file")
+ end
+
+ it "should set the module name on any created resource types" do
+ type = Puppet::Resource::Type.new(:hostclass, "mytype")
+
+ Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{one}]
+ @loader.stubs(:parse_file)
+ @loader.load_until(["foo"], "one") { |f| type }
+
+ type.module_name.should == "modname"
+ end
+ end
+
+ describe "when mapping names to files" do
+ {
+ [["foo"], "::bar::baz"] => %w{bar/baz},
+ [[""], "foo::bar"] => %w{foo foo/bar},
+ [%w{foo}, "bar"] => %w{foo foo/bar bar},
+ [%w{a b}, "bar"] => %w{a a/bar b b/bar bar},
+ [%w{a::b::c}, "bar"] => %w{a a/b/c/bar bar},
+ [%w{a::b}, "foo::bar"] => %w{a a/b/foo/bar foo/bar}
+ }.each do |inputs, outputs|
+ it "should produce #{outputs.inspect} from the #{inputs[0].inspect} namespace and #{inputs[1]} name" do
+ @loader.name2files(*inputs).should == outputs
+ end
+ end
+ end
+
+ describe "when importing" do
+ before do
+ Puppet::Parser::Files.stubs(:find_manifests).returns ["modname", %w{file}]
+ @loader.stubs(:parse_file)
+ end
+
+ it "should return immediately when imports are being ignored" do
+ Puppet::Parser::Files.expects(:find_manifests).never
+ Puppet[:ignoreimport] = true
+ @loader.import("foo").should be_nil
+ end
+
+ it "should find all manifests matching the file or pattern" do
+ Puppet::Parser::Files.expects(:find_manifests).with { |pat, opts| pat == "myfile" }.returns ["modname", %w{one}]
+ @loader.import("myfile")
+ end
+
+ it "should use the directory of the current file if one is set" do
+ Puppet::Parser::Files.expects(:find_manifests).with { |pat, opts| opts[:cwd] == "/current" }.returns ["modname", %w{one}]
+ @loader.import("myfile", "/current/file")
+ end
+
+ it "should pass the environment when looking for files" do
+ Puppet::Parser::Files.expects(:find_manifests).with { |pat, opts| opts[:environment] == @loader.environment }.returns ["modname", %w{one}]
+ @loader.import("myfile")
+ end
+
+ it "should fail if no files are found" do
+ Puppet::Parser::Files.expects(:find_manifests).returns [nil, []]
+ lambda { @loader.import("myfile") }.should raise_error(Puppet::ImportError)
+ end
+
+ it "should parse each found file" do
+ Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{/one}]
+ @loader.expects(:parse_file).with("/one")
+ @loader.import("myfile")
+ end
+
+ it "should make each file qualified before attempting to parse it" do
+ Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{one}]
+ @loader.expects(:parse_file).with("/current/one")
+ @loader.import("myfile", "/current/file")
+ end
+
+ it "should know when a given file has been imported" do
+ Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{/one}]
+ @loader.import("myfile")
+
+ @loader.should be_imported("/one")
+ end
+
+ it "should not attempt to import files that have already been imported" do
+ Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{/one}]
+ @loader.expects(:parse_file).once
+ @loader.import("myfile")
+
+ # This will fail if it tries to reimport the file.
+ @loader.import("myfile")
+ end
+ end
+
+ describe "when parsing a file" do
before do
- @loader = Puppet::Parser::TypeLoader.new(:myenv)
- end
-
- it "should support an environment" do
- loader = Puppet::Parser::TypeLoader.new(:myenv)
- loader.environment.name.should == :myenv
- end
-
- it "should include the Environment Helper" do
- @loader.class.ancestors.should be_include(Puppet::Node::Environment::Helper)
- end
-
- it "should delegate its known resource types to its environment" do
- @loader.known_resource_types.should be_instance_of(Puppet::Resource::TypeCollection)
- end
-
- describe "when loading names from namespaces" do
- it "should do nothing if the name to import is an empty string" do
- @loader.expects(:name2files).never
- @loader.load_until(["foo"], "") { |f| false }.should be_nil
- end
-
- it "should turn the provided namespaces and name into a list of files" do
- @loader.expects(:name2files).with(["foo"], "bar").returns []
- @loader.load_until(["foo"], "bar") { |f| false }
- end
-
- it "should attempt to import each generated name" do
- @loader.expects(:name2files).returns %w{foo bar}
- @loader.expects(:import).with("foo")
- @loader.expects(:import).with("bar")
- @loader.load_until(["foo"], "bar") { |f| false }
- end
-
- it "should yield after each import" do
- yielded = []
- @loader.expects(:name2files).returns %w{foo bar}
- @loader.expects(:import).with("foo")
- @loader.expects(:import).with("bar")
- @loader.load_until(["foo"], "bar") { |f| yielded << f; false }
- yielded.should == %w{foo bar}
- end
-
- it "should stop importing when the yielded block returns true" do
- yielded = []
- @loader.expects(:name2files).returns %w{foo bar baz}
- @loader.expects(:import).with("foo")
- @loader.expects(:import).with("bar")
- @loader.expects(:import).with("baz").never
- @loader.load_until(["foo"], "bar") { |f| true if f == "bar" }
- end
-
- it "should return the result of the block" do
- yielded = []
- @loader.expects(:name2files).returns %w{foo bar baz}
- @loader.expects(:import).with("foo")
- @loader.expects(:import).with("bar")
- @loader.expects(:import).with("baz").never
- @loader.load_until(["foo"], "bar") { |f| 10 if f == "bar" }.should == 10
- end
-
- it "should return nil if the block never returns true" do
- @loader.expects(:name2files).returns %w{foo bar}
- @loader.expects(:import).with("foo")
- @loader.expects(:import).with("bar")
- @loader.load_until(["foo"], "bar") { |f| false }.should be_nil
- end
-
- it "should know when a given name has been loaded" do
- @loader.expects(:name2files).returns %w{file}
- @loader.expects(:import).with("file")
- @loader.load_until(["foo"], "bar") { |f| true }
- @loader.should be_loaded("file")
- end
-
- it "should set the module name on any created resource types" do
- type = Puppet::Resource::Type.new(:hostclass, "mytype")
-
- Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{one}]
- @loader.stubs(:parse_file)
- @loader.load_until(["foo"], "one") { |f| type }
-
- type.module_name.should == "modname"
- end
- end
-
- describe "when mapping names to files" do
- {
- [["foo"], "::bar::baz"] => %w{bar/baz},
- [[""], "foo::bar"] => %w{foo foo/bar},
- [%w{foo}, "bar"] => %w{foo foo/bar bar},
- [%w{a b}, "bar"] => %w{a a/bar b b/bar bar},
- [%w{a::b::c}, "bar"] => %w{a a/b/c/bar bar},
- [%w{a::b}, "foo::bar"] => %w{a a/b/foo/bar foo/bar}
- }.each do |inputs, outputs|
- it "should produce #{outputs.inspect} from the #{inputs[0].inspect} namespace and #{inputs[1]} name" do
- @loader.name2files(*inputs).should == outputs
- end
- end
- end
-
- describe "when importing" do
- before do
- Puppet::Parser::Files.stubs(:find_manifests).returns ["modname", %w{file}]
- @loader.stubs(:parse_file)
- end
-
- it "should return immediately when imports are being ignored" do
- Puppet::Parser::Files.expects(:find_manifests).never
- Puppet[:ignoreimport] = true
- @loader.import("foo").should be_nil
- end
-
- it "should find all manifests matching the file or pattern" do
- Puppet::Parser::Files.expects(:find_manifests).with { |pat, opts| pat == "myfile" }.returns ["modname", %w{one}]
- @loader.import("myfile")
- end
-
- it "should use the directory of the current file if one is set" do
- Puppet::Parser::Files.expects(:find_manifests).with { |pat, opts| opts[:cwd] == "/current" }.returns ["modname", %w{one}]
- @loader.import("myfile", "/current/file")
- end
-
- it "should pass the environment when looking for files" do
- Puppet::Parser::Files.expects(:find_manifests).with { |pat, opts| opts[:environment] == @loader.environment }.returns ["modname", %w{one}]
- @loader.import("myfile")
- end
-
- it "should fail if no files are found" do
- Puppet::Parser::Files.expects(:find_manifests).returns [nil, []]
- lambda { @loader.import("myfile") }.should raise_error(Puppet::ImportError)
- end
-
- it "should parse each found file" do
- Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{/one}]
- @loader.expects(:parse_file).with("/one")
- @loader.import("myfile")
- end
-
- it "should make each file qualified before attempting to parse it" do
- Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{one}]
- @loader.expects(:parse_file).with("/current/one")
- @loader.import("myfile", "/current/file")
- end
-
- it "should know when a given file has been imported" do
- Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{/one}]
- @loader.import("myfile")
-
- @loader.should be_imported("/one")
- end
-
- it "should not attempt to import files that have already been imported" do
- Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{/one}]
- @loader.expects(:parse_file).once
- @loader.import("myfile")
-
- # This will fail if it tries to reimport the file.
- @loader.import("myfile")
- end
- end
-
- describe "when parsing a file" do
- before do
- @parser = Puppet::Parser::Parser.new(@loader.environment)
- @parser.stubs(:parse)
- @parser.stubs(:file=)
- Puppet::Parser::Parser.stubs(:new).with(@loader.environment).returns @parser
- end
-
- it "should create a new parser instance for each file using the current environment" do
- Puppet::Parser::Parser.expects(:new).with(@loader.environment).returns @parser
- @loader.parse_file("/my/file")
- end
-
- it "should assign the parser its file and parse" do
- @parser.expects(:file=).with("/my/file")
- @parser.expects(:parse)
- @loader.parse_file("/my/file")
- end
- end
-
- it "should be able to add classes to the current resource type collection" do
- file = tmpfile("simple_file")
- File.open(file, "w") { |f| f.puts "class foo {}" }
- @loader.import(file)
-
- @loader.known_resource_types.hostclass("foo").should be_instance_of(Puppet::Resource::Type)
+ @parser = Puppet::Parser::Parser.new(@loader.environment)
+ @parser.stubs(:parse)
+ @parser.stubs(:file=)
+ Puppet::Parser::Parser.stubs(:new).with(@loader.environment).returns @parser
end
+
+ it "should create a new parser instance for each file using the current environment" do
+ Puppet::Parser::Parser.expects(:new).with(@loader.environment).returns @parser
+ @loader.parse_file("/my/file")
+ end
+
+ it "should assign the parser its file and parse" do
+ @parser.expects(:file=).with("/my/file")
+ @parser.expects(:parse)
+ @loader.parse_file("/my/file")
+ end
+ end
+
+ it "should be able to add classes to the current resource type collection" do
+ file = tmpfile("simple_file")
+ File.open(file, "w") { |f| f.puts "class foo {}" }
+ @loader.import(file)
+
+ @loader.known_resource_types.hostclass("foo").should be_instance_of(Puppet::Resource::Type)
+ end
end
diff --git a/spec/unit/property/ensure_spec.rb b/spec/unit/property/ensure_spec.rb
index aa31abb..f2722de 100644
--- a/spec/unit/property/ensure_spec.rb
+++ b/spec/unit/property/ensure_spec.rb
@@ -7,7 +7,7 @@ require 'puppet/property/ensure'
klass = Puppet::Property::Ensure
describe klass do
- it "should be a subclass of Property" do
- klass.superclass.must == Puppet::Property
- end
+ it "should be a subclass of Property" do
+ klass.superclass.must == Puppet::Property
+ end
end
diff --git a/spec/unit/property/keyvalue_spec.rb b/spec/unit/property/keyvalue_spec.rb
index 6f9eef5..7666def 100644
--- a/spec/unit/property/keyvalue_spec.rb
+++ b/spec/unit/property/keyvalue_spec.rb
@@ -8,161 +8,161 @@ klass = Puppet::Property::KeyValue
describe klass do
- it "should be a subclass of Property" do
- klass.superclass.must == Puppet::Property
+ it "should be a subclass of Property" do
+ klass.superclass.must == Puppet::Property
+ end
+
+ describe "as an instance" do
+ before do
+ # Wow that's a messy interface to the resource.
+ klass.initvars
+ @resource = stub 'resource', :[]= => nil, :property => nil
+ @property = klass.new(:resource => @resource)
end
- describe "as an instance" do
- before do
- # Wow that's a messy interface to the resource.
- klass.initvars
- @resource = stub 'resource', :[]= => nil, :property => nil
- @property = klass.new(:resource => @resource)
- end
-
- it "should have a , as default delimiter" do
- @property.delimiter.should == ";"
- end
-
- it "should have a = as default separator" do
- @property.separator.should == "="
- end
-
- it "should have a :membership as default membership" do
- @property.membership.should == :key_value_membership
- end
-
- it "should return the same value passed into should_to_s" do
- @property.should_to_s({:foo => "baz", :bar => "boo"}) == "foo=baz;bar=boo"
- end
-
- it "should return the passed in array values joined with the delimiter from is_to_s" do
- @property.is_to_s({"foo" => "baz" , "bar" => "boo"}).should == "foo=baz;bar=boo"
- end
-
- describe "when calling inclusive?" do
- it "should use the membership method to look up on the @resource" do
- @property.expects(:membership).returns(:key_value_membership)
- @resource.expects(:[]).with(:key_value_membership)
- @property.inclusive?
- end
-
- it "should return true when @resource[membership] == inclusive" do
- @property.stubs(:membership).returns(:key_value_membership)
- @resource.stubs(:[]).with(:key_value_membership).returns(:inclusive)
- @property.inclusive?.must == true
- end
-
- it "should return false when @resource[membership] != inclusive" do
- @property.stubs(:membership).returns(:key_value_membership)
- @resource.stubs(:[]).with(:key_value_membership).returns(:minimum)
- @property.inclusive?.must == false
- end
- end
-
- describe "when calling process_current_hash" do
- it "should return {} if hash is :absent" do
- @property.process_current_hash(:absent).must == {}
- end
-
- it "should set every key to nil if inclusive?" do
- @property.stubs(:inclusive?).returns(true)
- @property.process_current_hash({:foo => "bar", :do => "re"}).must == { :foo => nil, :do => nil }
- end
-
- it "should return the hash if !inclusive?" do
- @property.stubs(:inclusive?).returns(false)
- @property.process_current_hash({:foo => "bar", :do => "re"}).must == {:foo => "bar", :do => "re"}
- end
- end
-
- describe "when calling should" do
- it "should return nil if @should is nil" do
- @property.should.must == nil
- end
-
- it "should call process_current_hash" do
- @property.should = ["foo=baz", "bar=boo"]
- @property.stubs(:retrieve).returns({:do => "re", :mi => "fa" })
- @property.expects(:process_current_hash).returns({})
- @property.should
- end
-
- it "should return the hashed values of @should and the nilled values of retrieve if inclusive" do
- @property.should = ["foo=baz", "bar=boo"]
- @property.expects(:retrieve).returns({:do => "re", :mi => "fa" })
- @property.expects(:inclusive?).returns(true)
- @property.should.must == { :foo => "baz", :bar => "boo", :do => nil, :mi => nil }
- end
-
- it "should return the hashed @should + the unique values of retrieve if !inclusive" do
- @property.should = ["foo=baz", "bar=boo"]
- @property.expects(:retrieve).returns({:foo => "diff", :do => "re", :mi => "fa"})
- @property.expects(:inclusive?).returns(false)
- @property.should.must == { :foo => "baz", :bar => "boo", :do => "re", :mi => "fa" }
- end
- end
-
- describe "when calling retrieve" do
- before do
- @provider = mock("provider")
- @property.stubs(:provider).returns(@provider)
- end
-
- it "should send 'name' to the provider" do
- @provider.expects(:send).with(:keys)
- @property.expects(:name).returns(:keys)
- @property.retrieve
- end
-
- it "should return a hash with the provider returned info" do
- @provider.stubs(:send).with(:keys).returns({"do" => "re", "mi" => "fa" })
- @property.stubs(:name).returns(:keys)
- @property.retrieve == {"do" => "re", "mi" => "fa" }
- end
-
- it "should return :absent when the provider returns :absent" do
- @provider.stubs(:send).with(:keys).returns(:absent)
- @property.stubs(:name).returns(:keys)
- @property.retrieve == :absent
- end
- end
-
- describe "when calling hashify" do
- it "should return the array hashified" do
- @property.hashify(["foo=baz", "bar=boo"]).must == { :foo => "baz", :bar => "boo" }
- end
- end
-
- describe "when calling insync?" do
- before do
- @provider = mock("provider")
- @property.stubs(:provider).returns(@provider)
- @property.stubs(:name).returns(:prop_name)
- end
-
- it "should return true unless @should is defined and not nil" do
- @property.insync?("foo") == true
- end
-
- it "should return true if the passed in values is nil" do
- @property.should = "foo"
- @property.insync?(nil) == true
- end
-
- it "should return true if hashified should value == (retrieved) value passed in" do
- @provider.stubs(:prop_name).returns({ :foo => "baz", :bar => "boo" })
- @property.should = ["foo=baz", "bar=boo"]
- @property.expects(:inclusive?).returns(true)
- @property.insync?({ :foo => "baz", :bar => "boo" }).must == true
- end
-
- it "should return false if prepared value != should value" do
- @provider.stubs(:prop_name).returns({ "foo" => "bee", "bar" => "boo" })
- @property.should = ["foo=baz", "bar=boo"]
- @property.expects(:inclusive?).returns(true)
- @property.insync?({ "foo" => "bee", "bar" => "boo" }).must == false
- end
- end
+ it "should have a , as default delimiter" do
+ @property.delimiter.should == ";"
end
+
+ it "should have a = as default separator" do
+ @property.separator.should == "="
+ end
+
+ it "should have a :membership as default membership" do
+ @property.membership.should == :key_value_membership
+ end
+
+ it "should return the same value passed into should_to_s" do
+ @property.should_to_s({:foo => "baz", :bar => "boo"}) == "foo=baz;bar=boo"
+ end
+
+ it "should return the passed in array values joined with the delimiter from is_to_s" do
+ @property.is_to_s({"foo" => "baz" , "bar" => "boo"}).should == "foo=baz;bar=boo"
+ end
+
+ describe "when calling inclusive?" do
+ it "should use the membership method to look up on the @resource" do
+ @property.expects(:membership).returns(:key_value_membership)
+ @resource.expects(:[]).with(:key_value_membership)
+ @property.inclusive?
+ end
+
+ it "should return true when @resource[membership] == inclusive" do
+ @property.stubs(:membership).returns(:key_value_membership)
+ @resource.stubs(:[]).with(:key_value_membership).returns(:inclusive)
+ @property.inclusive?.must == true
+ end
+
+ it "should return false when @resource[membership] != inclusive" do
+ @property.stubs(:membership).returns(:key_value_membership)
+ @resource.stubs(:[]).with(:key_value_membership).returns(:minimum)
+ @property.inclusive?.must == false
+ end
+ end
+
+ describe "when calling process_current_hash" do
+ it "should return {} if hash is :absent" do
+ @property.process_current_hash(:absent).must == {}
+ end
+
+ it "should set every key to nil if inclusive?" do
+ @property.stubs(:inclusive?).returns(true)
+ @property.process_current_hash({:foo => "bar", :do => "re"}).must == { :foo => nil, :do => nil }
+ end
+
+ it "should return the hash if !inclusive?" do
+ @property.stubs(:inclusive?).returns(false)
+ @property.process_current_hash({:foo => "bar", :do => "re"}).must == {:foo => "bar", :do => "re"}
+ end
+ end
+
+ describe "when calling should" do
+ it "should return nil if @should is nil" do
+ @property.should.must == nil
+ end
+
+ it "should call process_current_hash" do
+ @property.should = ["foo=baz", "bar=boo"]
+ @property.stubs(:retrieve).returns({:do => "re", :mi => "fa" })
+ @property.expects(:process_current_hash).returns({})
+ @property.should
+ end
+
+ it "should return the hashed values of @should and the nilled values of retrieve if inclusive" do
+ @property.should = ["foo=baz", "bar=boo"]
+ @property.expects(:retrieve).returns({:do => "re", :mi => "fa" })
+ @property.expects(:inclusive?).returns(true)
+ @property.should.must == { :foo => "baz", :bar => "boo", :do => nil, :mi => nil }
+ end
+
+ it "should return the hashed @should + the unique values of retrieve if !inclusive" do
+ @property.should = ["foo=baz", "bar=boo"]
+ @property.expects(:retrieve).returns({:foo => "diff", :do => "re", :mi => "fa"})
+ @property.expects(:inclusive?).returns(false)
+ @property.should.must == { :foo => "baz", :bar => "boo", :do => "re", :mi => "fa" }
+ end
+ end
+
+ describe "when calling retrieve" do
+ before do
+ @provider = mock("provider")
+ @property.stubs(:provider).returns(@provider)
+ end
+
+ it "should send 'name' to the provider" do
+ @provider.expects(:send).with(:keys)
+ @property.expects(:name).returns(:keys)
+ @property.retrieve
+ end
+
+ it "should return a hash with the provider returned info" do
+ @provider.stubs(:send).with(:keys).returns({"do" => "re", "mi" => "fa" })
+ @property.stubs(:name).returns(:keys)
+ @property.retrieve == {"do" => "re", "mi" => "fa" }
+ end
+
+ it "should return :absent when the provider returns :absent" do
+ @provider.stubs(:send).with(:keys).returns(:absent)
+ @property.stubs(:name).returns(:keys)
+ @property.retrieve == :absent
+ end
+ end
+
+ describe "when calling hashify" do
+ it "should return the array hashified" do
+ @property.hashify(["foo=baz", "bar=boo"]).must == { :foo => "baz", :bar => "boo" }
+ end
+ end
+
+ describe "when calling insync?" do
+ before do
+ @provider = mock("provider")
+ @property.stubs(:provider).returns(@provider)
+ @property.stubs(:name).returns(:prop_name)
+ end
+
+ it "should return true unless @should is defined and not nil" do
+ @property.insync?("foo") == true
+ end
+
+ it "should return true if the passed in values is nil" do
+ @property.should = "foo"
+ @property.insync?(nil) == true
+ end
+
+ it "should return true if hashified should value == (retrieved) value passed in" do
+ @provider.stubs(:prop_name).returns({ :foo => "baz", :bar => "boo" })
+ @property.should = ["foo=baz", "bar=boo"]
+ @property.expects(:inclusive?).returns(true)
+ @property.insync?({ :foo => "baz", :bar => "boo" }).must == true
+ end
+
+ it "should return false if prepared value != should value" do
+ @provider.stubs(:prop_name).returns({ "foo" => "bee", "bar" => "boo" })
+ @property.should = ["foo=baz", "bar=boo"]
+ @property.expects(:inclusive?).returns(true)
+ @property.insync?({ "foo" => "bee", "bar" => "boo" }).must == false
+ end
+ end
+ end
end
diff --git a/spec/unit/property/list_spec.rb b/spec/unit/property/list_spec.rb
index 588e71c..3e8cc54 100644
--- a/spec/unit/property/list_spec.rb
+++ b/spec/unit/property/list_spec.rb
@@ -8,159 +8,159 @@ list_class = Puppet::Property::List
describe list_class do
- it "should be a subclass of Property" do
- list_class.superclass.must == Puppet::Property
+ it "should be a subclass of Property" do
+ list_class.superclass.must == Puppet::Property
+ end
+
+ describe "as an instance" do
+ before do
+ # Wow that's a messy interface to the resource.
+ list_class.initvars
+ @resource = stub 'resource', :[]= => nil, :property => nil
+ @property = list_class.new(:resource => @resource)
end
- describe "as an instance" do
- before do
- # Wow that's a messy interface to the resource.
- list_class.initvars
- @resource = stub 'resource', :[]= => nil, :property => nil
- @property = list_class.new(:resource => @resource)
- end
-
- it "should have a , as default delimiter" do
- @property.delimiter.should == ","
- end
-
- it "should have a :membership as default membership" do
- @property.membership.should == :membership
- end
-
- it "should return the same value passed into should_to_s" do
- @property.should_to_s("foo") == "foo"
- end
-
- it "should return the passed in array values joined with the delimiter from is_to_s" do
- @property.is_to_s(["foo","bar"]).should == "foo,bar"
- end
-
- it "should be able to correctly convert ':absent' to a string" do
- @property.is_to_s(:absent).should == "absent"
- end
-
- describe "when adding should to current" do
- it "should add the arrays when current is an array" do
- @property.add_should_with_current(["foo"], ["bar"]).should == ["foo", "bar"]
- end
-
- it "should return should if current is not a array" do
- @property.add_should_with_current(["foo"], :absent).should == ["foo"]
- end
-
- it "should return only the uniq elements" do
- @property.add_should_with_current(["foo", "bar"], ["foo", "baz"]).should == ["foo", "bar", "baz"]
- end
- end
-
- describe "when calling inclusive?" do
- it "should use the membership method to look up on the @resource" do
- @property.expects(:membership).returns(:membership)
- @resource.expects(:[]).with(:membership)
- @property.inclusive?
- end
-
- it "should return true when @resource[membership] == inclusive" do
- @property.stubs(:membership).returns(:membership)
- @resource.stubs(:[]).with(:membership).returns(:inclusive)
- @property.inclusive?.must == true
- end
-
- it "should return false when @resource[membership] != inclusive" do
- @property.stubs(:membership).returns(:membership)
- @resource.stubs(:[]).with(:membership).returns(:minimum)
- @property.inclusive?.must == false
- end
- end
-
- describe "when calling should" do
- it "should return nil if @should is nil" do
- @property.should.must == nil
- end
-
- it "should return the sorted values of @should as a string if inclusive" do
- @property.should = ["foo", "bar"]
- @property.expects(:inclusive?).returns(true)
- @property.should.must == "bar,foo"
- end
-
- it "should return the uniq sorted values of @should + retrieve as a string if !inclusive" do
- @property.should = ["foo", "bar"]
- @property.expects(:inclusive?).returns(false)
- @property.expects(:retrieve).returns(["foo","baz"])
- @property.should.must == "bar,baz,foo"
- end
- end
-
- describe "when calling retrieve" do
- before do
- @provider = mock("provider")
- @property.stubs(:provider).returns(@provider)
- end
-
- it "should send 'name' to the provider" do
- @provider.expects(:send).with(:group)
- @property.expects(:name).returns(:group)
- @property.retrieve
- end
-
- it "should return an array with the provider returned info" do
- @provider.stubs(:send).with(:group).returns("foo,bar,baz")
- @property.stubs(:name).returns(:group)
- @property.retrieve == ["foo", "bar", "baz"]
- end
-
- it "should return :absent when the provider returns :absent" do
- @provider.stubs(:send).with(:group).returns(:absent)
- @property.stubs(:name).returns(:group)
- @property.retrieve == :absent
- end
- end
-
- describe "when calling insync?" do
- it "should return true unless @should is defined and not nil" do
- @property.must be_insync("foo")
- end
-
- it "should return true unless the passed in values is not nil" do
- @property.should = "foo"
- @property.must be_insync(nil)
- end
-
- it "should call prepare_is_for_comparison with value passed in and should" do
- @property.should = "foo"
- @property.expects(:prepare_is_for_comparison).with("bar")
- @property.expects(:should)
- @property.insync?("bar")
- end
-
- it "should return true if 'is' value is array of comma delimited should values" do
- @property.should = "bar,foo"
- @property.expects(:inclusive?).returns(true)
- @property.must be_insync(["bar","foo"])
- end
-
- it "should return true if 'is' value is :absent and should value is empty string" do
- @property.should = ""
- @property.expects(:inclusive?).returns(true)
- @property.must be_insync([])
- end
-
- it "should return false if prepared value != should value" do
- @property.should = "bar,baz,foo"
- @property.expects(:inclusive?).returns(true)
- @property.must_not be_insync(["bar","foo"])
- end
- end
-
- describe "when calling dearrayify" do
- it "should sort and join the array with 'delimiter'" do
- array = mock "array"
- array.expects(:sort).returns(array)
- array.expects(:join).with(@property.delimiter)
- @property.dearrayify(array)
- end
- end
+ it "should have a , as default delimiter" do
+ @property.delimiter.should == ","
end
+
+ it "should have a :membership as default membership" do
+ @property.membership.should == :membership
+ end
+
+ it "should return the same value passed into should_to_s" do
+ @property.should_to_s("foo") == "foo"
+ end
+
+ it "should return the passed in array values joined with the delimiter from is_to_s" do
+ @property.is_to_s(["foo","bar"]).should == "foo,bar"
+ end
+
+ it "should be able to correctly convert ':absent' to a string" do
+ @property.is_to_s(:absent).should == "absent"
+ end
+
+ describe "when adding should to current" do
+ it "should add the arrays when current is an array" do
+ @property.add_should_with_current(["foo"], ["bar"]).should == ["foo", "bar"]
+ end
+
+ it "should return should if current is not a array" do
+ @property.add_should_with_current(["foo"], :absent).should == ["foo"]
+ end
+
+ it "should return only the uniq elements" do
+ @property.add_should_with_current(["foo", "bar"], ["foo", "baz"]).should == ["foo", "bar", "baz"]
+ end
+ end
+
+ describe "when calling inclusive?" do
+ it "should use the membership method to look up on the @resource" do
+ @property.expects(:membership).returns(:membership)
+ @resource.expects(:[]).with(:membership)
+ @property.inclusive?
+ end
+
+ it "should return true when @resource[membership] == inclusive" do
+ @property.stubs(:membership).returns(:membership)
+ @resource.stubs(:[]).with(:membership).returns(:inclusive)
+ @property.inclusive?.must == true
+ end
+
+ it "should return false when @resource[membership] != inclusive" do
+ @property.stubs(:membership).returns(:membership)
+ @resource.stubs(:[]).with(:membership).returns(:minimum)
+ @property.inclusive?.must == false
+ end
+ end
+
+ describe "when calling should" do
+ it "should return nil if @should is nil" do
+ @property.should.must == nil
+ end
+
+ it "should return the sorted values of @should as a string if inclusive" do
+ @property.should = ["foo", "bar"]
+ @property.expects(:inclusive?).returns(true)
+ @property.should.must == "bar,foo"
+ end
+
+ it "should return the uniq sorted values of @should + retrieve as a string if !inclusive" do
+ @property.should = ["foo", "bar"]
+ @property.expects(:inclusive?).returns(false)
+ @property.expects(:retrieve).returns(["foo","baz"])
+ @property.should.must == "bar,baz,foo"
+ end
+ end
+
+ describe "when calling retrieve" do
+ before do
+ @provider = mock("provider")
+ @property.stubs(:provider).returns(@provider)
+ end
+
+ it "should send 'name' to the provider" do
+ @provider.expects(:send).with(:group)
+ @property.expects(:name).returns(:group)
+ @property.retrieve
+ end
+
+ it "should return an array with the provider returned info" do
+ @provider.stubs(:send).with(:group).returns("foo,bar,baz")
+ @property.stubs(:name).returns(:group)
+ @property.retrieve == ["foo", "bar", "baz"]
+ end
+
+ it "should return :absent when the provider returns :absent" do
+ @provider.stubs(:send).with(:group).returns(:absent)
+ @property.stubs(:name).returns(:group)
+ @property.retrieve == :absent
+ end
+ end
+
+ describe "when calling insync?" do
+ it "should return true unless @should is defined and not nil" do
+ @property.must be_insync("foo")
+ end
+
+ it "should return true unless the passed in values is not nil" do
+ @property.should = "foo"
+ @property.must be_insync(nil)
+ end
+
+ it "should call prepare_is_for_comparison with value passed in and should" do
+ @property.should = "foo"
+ @property.expects(:prepare_is_for_comparison).with("bar")
+ @property.expects(:should)
+ @property.insync?("bar")
+ end
+
+ it "should return true if 'is' value is array of comma delimited should values" do
+ @property.should = "bar,foo"
+ @property.expects(:inclusive?).returns(true)
+ @property.must be_insync(["bar","foo"])
+ end
+
+ it "should return true if 'is' value is :absent and should value is empty string" do
+ @property.should = ""
+ @property.expects(:inclusive?).returns(true)
+ @property.must be_insync([])
+ end
+
+ it "should return false if prepared value != should value" do
+ @property.should = "bar,baz,foo"
+ @property.expects(:inclusive?).returns(true)
+ @property.must_not be_insync(["bar","foo"])
+ end
+ end
+
+ describe "when calling dearrayify" do
+ it "should sort and join the array with 'delimiter'" do
+ array = mock "array"
+ array.expects(:sort).returns(array)
+ array.expects(:join).with(@property.delimiter)
+ @property.dearrayify(array)
+ end
+ end
+ end
end
diff --git a/spec/unit/property/ordered_list_spec.rb b/spec/unit/property/ordered_list_spec.rb
index 51c59a7..7c8eceb 100644
--- a/spec/unit/property/ordered_list_spec.rb
+++ b/spec/unit/property/ordered_list_spec.rb
@@ -8,57 +8,57 @@ ordered_list_class = Puppet::Property::OrderedList
describe ordered_list_class do
- it "should be a subclass of List" do
- ordered_list_class.superclass.must == Puppet::Property::List
- end
+ it "should be a subclass of List" do
+ ordered_list_class.superclass.must == Puppet::Property::List
+ end
- describe "as an instance" do
- before do
- # Wow that's a messy interface to the resource.
- ordered_list_class.initvars
- @resource = stub 'resource', :[]= => nil, :property => nil
- @property = ordered_list_class.new(:resource => @resource)
- end
+ describe "as an instance" do
+ before do
+ # Wow that's a messy interface to the resource.
+ ordered_list_class.initvars
+ @resource = stub 'resource', :[]= => nil, :property => nil
+ @property = ordered_list_class.new(:resource => @resource)
+ end
- describe "when adding should to current" do
- it "should add the arrays when current is an array" do
- @property.add_should_with_current(["should"], ["current"]).should == ["should", "current"]
- end
+ describe "when adding should to current" do
+ it "should add the arrays when current is an array" do
+ @property.add_should_with_current(["should"], ["current"]).should == ["should", "current"]
+ end
- it "should return 'should' if current is not a array" do
- @property.add_should_with_current(["should"], :absent).should == ["should"]
- end
+ it "should return 'should' if current is not a array" do
+ @property.add_should_with_current(["should"], :absent).should == ["should"]
+ end
- it "should return only the uniq elements leading with the order of 'should'" do
- @property.add_should_with_current(["this", "is", "should"], ["is", "this", "current"]).should == ["this", "is", "should", "current"]
- end
- end
+ it "should return only the uniq elements leading with the order of 'should'" do
+ @property.add_should_with_current(["this", "is", "should"], ["is", "this", "current"]).should == ["this", "is", "should", "current"]
+ end
+ end
- describe "when calling should" do
- it "should return nil if @should is nil" do
- @property.should.must == nil
- end
+ describe "when calling should" do
+ it "should return nil if @should is nil" do
+ @property.should.must == nil
+ end
- it "should return the values of @should (without sorting) as a string if inclusive" do
- @property.should = ["foo", "bar"]
- @property.expects(:inclusive?).returns(true)
- @property.should.must == "foo,bar"
- end
+ it "should return the values of @should (without sorting) as a string if inclusive" do
+ @property.should = ["foo", "bar"]
+ @property.expects(:inclusive?).returns(true)
+ @property.should.must == "foo,bar"
+ end
- it "should return the uniq values of @should + retrieve as a string if !inclusive with the @ values leading" do
- @property.should = ["foo", "bar"]
- @property.expects(:inclusive?).returns(false)
- @property.expects(:retrieve).returns(["foo","baz"])
- @property.should.must == "foo,bar,baz"
- end
- end
+ it "should return the uniq values of @should + retrieve as a string if !inclusive with the @ values leading" do
+ @property.should = ["foo", "bar"]
+ @property.expects(:inclusive?).returns(false)
+ @property.expects(:retrieve).returns(["foo","baz"])
+ @property.should.must == "foo,bar,baz"
+ end
+ end
- describe "when calling dearrayify" do
- it "should join the array with the delimiter" do
- array = mock "array"
- array.expects(:join).with(@property.delimiter)
- @property.dearrayify(array)
- end
- end
+ describe "when calling dearrayify" do
+ it "should join the array with the delimiter" do
+ array = mock "array"
+ array.expects(:join).with(@property.delimiter)
+ @property.dearrayify(array)
+ end
end
+ end
end
diff --git a/spec/unit/property_spec.rb b/spec/unit/property_spec.rb
index 5c47bcf..56e643b 100755
--- a/spec/unit/property_spec.rb
+++ b/spec/unit/property_spec.rb
@@ -4,407 +4,407 @@ require File.dirname(__FILE__) + '/../spec_helper'
require 'puppet/property'
describe Puppet::Property do
- before do
- @class = Class.new(Puppet::Property) do
- @name = :foo
- end
- @class.initvars
- @provider = mock 'provider'
- @resource = stub 'resource', :provider => @provider
- @resource.stub_everything
- @property = @class.new :resource => @resource
+ before do
+ @class = Class.new(Puppet::Property) do
+ @name = :foo
end
-
- it "should return its name as a string when converted to a string" do
- @property.to_s.should == @property.name.to_s
+ @class.initvars
+ @provider = mock 'provider'
+ @resource = stub 'resource', :provider => @provider
+ @resource.stub_everything
+ @property = @class.new :resource => @resource
+ end
+
+ it "should return its name as a string when converted to a string" do
+ @property.to_s.should == @property.name.to_s
+ end
+
+ it "should be able to look up the modified name for a given value" do
+ @class.newvalue(:foo)
+ @class.value_name("foo").should == :foo
+ end
+
+ it "should be able to look up the modified name for a given value matching a regex" do
+ @class.newvalue(%r{.})
+ @class.value_name("foo").should == %r{.}
+ end
+
+ it "should be able to look up a given value option" do
+ @class.newvalue(:foo, :event => :whatever)
+ @class.value_option(:foo, :event).should == :whatever
+ end
+
+ it "should be able to specify required features" do
+ @class.should respond_to(:required_features=)
+ end
+
+ {"one" => [:one],:one => [:one],%w{a} => [:a],[:b] => [:b],%w{one two} => [:one,:two],[:a,:b] => [:a,:b]}.each { |in_value,out_value|
+ it "should always convert required features into an array of symbols (e.g. #{in_value.inspect} --> #{out_value.inspect})" do
+ @class.required_features = in_value
+ @class.required_features.should == out_value
end
+ }
- it "should be able to look up the modified name for a given value" do
- @class.newvalue(:foo)
- @class.value_name("foo").should == :foo
- end
+ it "should be able to shadow metaparameters" do
+ @property.must respond_to(:shadow)
+ end
- it "should be able to look up the modified name for a given value matching a regex" do
- @class.newvalue(%r{.})
- @class.value_name("foo").should == %r{.}
+ describe "when returning the default event name" do
+ before do
+ @resource = stub 'resource'
+ @instance = @class.new(:resource => @resource)
+ @instance.stubs(:should).returns "myval"
end
- it "should be able to look up a given value option" do
- @class.newvalue(:foo, :event => :whatever)
- @class.value_option(:foo, :event).should == :whatever
- end
+ it "should use the current 'should' value to pick the event name" do
+ @instance.expects(:should).returns "myvalue"
+ @class.expects(:value_option).with('myvalue', :event).returns :event_name
- it "should be able to specify required features" do
- @class.should respond_to(:required_features=)
+ @instance.event_name
end
- {"one" => [:one],:one => [:one],%w{a} => [:a],[:b] => [:b],%w{one two} => [:one,:two],[:a,:b] => [:a,:b]}.each { |in_value,out_value|
- it "should always convert required features into an array of symbols (e.g. #{in_value.inspect} --> #{out_value.inspect})" do
- @class.required_features = in_value
- @class.required_features.should == out_value
- end
- }
+ it "should return any event defined with the specified value" do
+ @instance.expects(:should).returns :myval
+ @class.expects(:value_option).with(:myval, :event).returns :event_name
- it "should be able to shadow metaparameters" do
- @property.must respond_to(:shadow)
+ @instance.event_name.should == :event_name
end
- describe "when returning the default event name" do
- before do
- @resource = stub 'resource'
- @instance = @class.new(:resource => @resource)
- @instance.stubs(:should).returns "myval"
- end
-
- it "should use the current 'should' value to pick the event name" do
- @instance.expects(:should).returns "myvalue"
- @class.expects(:value_option).with('myvalue', :event).returns :event_name
-
- @instance.event_name
- end
-
- it "should return any event defined with the specified value" do
- @instance.expects(:should).returns :myval
- @class.expects(:value_option).with(:myval, :event).returns :event_name
-
- @instance.event_name.should == :event_name
- end
-
- describe "and the property is 'ensure'" do
- before do
- @instance.stubs(:name).returns :ensure
- @resource.expects(:type).returns :mytype
- end
-
- it "should use <type>_created if the 'should' value is 'present'" do
- @instance.expects(:should).returns :present
- @instance.event_name.should == :mytype_created
- end
-
- it "should use <type>_removed if the 'should' value is 'absent'" do
- @instance.expects(:should).returns :absent
- @instance.event_name.should == :mytype_removed
- end
+ describe "and the property is 'ensure'" do
+ before do
+ @instance.stubs(:name).returns :ensure
+ @resource.expects(:type).returns :mytype
+ end
+
+ it "should use <type>_created if the 'should' value is 'present'" do
+ @instance.expects(:should).returns :present
+ @instance.event_name.should == :mytype_created
+ end
+
+ it "should use <type>_removed if the 'should' value is 'absent'" do
+ @instance.expects(:should).returns :absent
+ @instance.event_name.should == :mytype_removed
+ end
+
+ it "should use <type>_changed if the 'should' value is not 'absent' or 'present'" do
+ @instance.expects(:should).returns :foo
+ @instance.event_name.should == :mytype_changed
+ end
+
+ it "should use <type>_changed if the 'should value is nil" do
+ @instance.expects(:should).returns nil
+ @instance.event_name.should == :mytype_changed
+ end
+ end
- it "should use <type>_changed if the 'should' value is not 'absent' or 'present'" do
- @instance.expects(:should).returns :foo
- @instance.event_name.should == :mytype_changed
- end
+ it "should use <property>_changed if the property is not 'ensure'" do
+ @instance.stubs(:name).returns :myparam
+ @instance.expects(:should).returns :foo
+ @instance.event_name.should == :myparam_changed
+ end
- it "should use <type>_changed if the 'should value is nil" do
- @instance.expects(:should).returns nil
- @instance.event_name.should == :mytype_changed
- end
- end
+ it "should use <property>_changed if no 'should' value is set" do
+ @instance.stubs(:name).returns :myparam
+ @instance.expects(:should).returns nil
+ @instance.event_name.should == :myparam_changed
+ end
+ end
- it "should use <property>_changed if the property is not 'ensure'" do
- @instance.stubs(:name).returns :myparam
- @instance.expects(:should).returns :foo
- @instance.event_name.should == :myparam_changed
- end
+ describe "when creating an event" do
+ before do
+ @event = Puppet::Transaction::Event.new
- it "should use <property>_changed if no 'should' value is set" do
- @instance.stubs(:name).returns :myparam
- @instance.expects(:should).returns nil
- @instance.event_name.should == :myparam_changed
- end
+ # Use a real resource so we can test the event creation integration
+ @resource = Puppet::Type.type(:mount).new :name => "foo"
+ @instance = @class.new(:resource => @resource)
+ @instance.stubs(:should).returns "myval"
end
- describe "when creating an event" do
- before do
- @event = Puppet::Transaction::Event.new
+ it "should use an event from the resource as the base event" do
+ event = Puppet::Transaction::Event.new
+ @resource.expects(:event).returns event
- # Use a real resource so we can test the event creation integration
- @resource = Puppet::Type.type(:mount).new :name => "foo"
- @instance = @class.new(:resource => @resource)
- @instance.stubs(:should).returns "myval"
- end
+ @instance.event.should equal(event)
+ end
- it "should use an event from the resource as the base event" do
- event = Puppet::Transaction::Event.new
- @resource.expects(:event).returns event
+ it "should have the default event name" do
+ @instance.expects(:event_name).returns :my_event
+ @instance.event.name.should == :my_event
+ end
- @instance.event.should equal(event)
- end
+ it "should have the property's name" do
+ @instance.event.property.should == @instance.name.to_s
+ end
- it "should have the default event name" do
- @instance.expects(:event_name).returns :my_event
- @instance.event.name.should == :my_event
- end
+ it "should have the 'should' value set" do
+ @instance.stubs(:should).returns "foo"
+ @instance.event.desired_value.should == "foo"
+ end
- it "should have the property's name" do
- @instance.event.property.should == @instance.name.to_s
- end
-
- it "should have the 'should' value set" do
- @instance.stubs(:should).returns "foo"
- @instance.event.desired_value.should == "foo"
- end
-
- it "should provide its path as the source description" do
- @instance.stubs(:path).returns "/my/param"
- @instance.event.source_description.should == "/my/param"
- end
+ it "should provide its path as the source description" do
+ @instance.stubs(:path).returns "/my/param"
+ @instance.event.source_description.should == "/my/param"
end
+ end
- describe "when shadowing metaparameters" do
- before do
- @shadow_class = Class.new(Puppet::Property) do
- @name = :alias
- end
- @shadow_class.initvars
- end
+ describe "when shadowing metaparameters" do
+ before do
+ @shadow_class = Class.new(Puppet::Property) do
+ @name = :alias
+ end
+ @shadow_class.initvars
+ end
- it "should create an instance of the metaparameter at initialization" do
- Puppet::Type.metaparamclass(:alias).expects(:new).with(:resource => @resource)
+ it "should create an instance of the metaparameter at initialization" do
+ Puppet::Type.metaparamclass(:alias).expects(:new).with(:resource => @resource)
- @shadow_class.new :resource => @resource
- end
+ @shadow_class.new :resource => @resource
+ end
- it "should munge values using the shadow's munge method" do
- shadow = mock 'shadow'
- Puppet::Type.metaparamclass(:alias).expects(:new).returns shadow
+ it "should munge values using the shadow's munge method" do
+ shadow = mock 'shadow'
+ Puppet::Type.metaparamclass(:alias).expects(:new).returns shadow
- shadow.expects(:munge).with "foo"
+ shadow.expects(:munge).with "foo"
- property = @shadow_class.new :resource => @resource
- property.munge("foo")
- end
+ property = @shadow_class.new :resource => @resource
+ property.munge("foo")
end
+ end
- describe "when defining new values" do
- it "should define a method for each value created with a block that's not a regex" do
- @class.newvalue(:foo) { }
- @property.must respond_to(:set_foo)
- end
+ describe "when defining new values" do
+ it "should define a method for each value created with a block that's not a regex" do
+ @class.newvalue(:foo) { }
+ @property.must respond_to(:set_foo)
end
+ end
- describe "when assigning the value" do
- it "should just set the 'should' value" do
- @property.value = "foo"
- @property.should.must == "foo"
- end
+ describe "when assigning the value" do
+ it "should just set the 'should' value" do
+ @property.value = "foo"
+ @property.should.must == "foo"
+ end
- it "should validate each value separately" do
- @property.expects(:validate).with("one")
- @property.expects(:validate).with("two")
+ it "should validate each value separately" do
+ @property.expects(:validate).with("one")
+ @property.expects(:validate).with("two")
- @property.value = %w{one two}
- end
+ @property.value = %w{one two}
+ end
- it "should munge each value separately and use any result as the actual value" do
- @property.expects(:munge).with("one").returns :one
- @property.expects(:munge).with("two").returns :two
+ it "should munge each value separately and use any result as the actual value" do
+ @property.expects(:munge).with("one").returns :one
+ @property.expects(:munge).with("two").returns :two
- # Do this so we get the whole array back.
- @class.array_matching = :all
+ # Do this so we get the whole array back.
+ @class.array_matching = :all
- @property.value = %w{one two}
- @property.should.must == [:one, :two]
- end
+ @property.value = %w{one two}
+ @property.should.must == [:one, :two]
+ end
- it "should return any set value" do
- (@property.value = :one).should == :one
- end
+ it "should return any set value" do
+ (@property.value = :one).should == :one
end
+ end
- describe "when returning the value" do
- it "should return nil if no value is set" do
- @property.should.must be_nil
- end
+ describe "when returning the value" do
+ it "should return nil if no value is set" do
+ @property.should.must be_nil
+ end
- it "should return the first set 'should' value if :array_matching is set to :first" do
- @class.array_matching = :first
- @property.should = %w{one two}
- @property.should.must == "one"
- end
+ it "should return the first set 'should' value if :array_matching is set to :first" do
+ @class.array_matching = :first
+ @property.should = %w{one two}
+ @property.should.must == "one"
+ end
- it "should return all set 'should' values as an array if :array_matching is set to :all" do
- @class.array_matching = :all
- @property.should = %w{one two}
- @property.should.must == %w{one two}
- end
+ it "should return all set 'should' values as an array if :array_matching is set to :all" do
+ @class.array_matching = :all
+ @property.should = %w{one two}
+ @property.should.must == %w{one two}
+ end
- it "should default to :first array_matching" do
- @class.array_matching.should == :first
- end
+ it "should default to :first array_matching" do
+ @class.array_matching.should == :first
+ end
- it "should unmunge the returned value if :array_matching is set to :first" do
- @property.class.unmunge do |v| v.to_sym end
- @class.array_matching = :first
- @property.should = %w{one two}
+ it "should unmunge the returned value if :array_matching is set to :first" do
+ @property.class.unmunge do |v| v.to_sym end
+ @class.array_matching = :first
+ @property.should = %w{one two}
- @property.should.must == :one
- end
+ @property.should.must == :one
+ end
- it "should unmunge all the returned values if :array_matching is set to :all" do
- @property.class.unmunge do |v| v.to_sym end
- @class.array_matching = :all
- @property.should = %w{one two}
+ it "should unmunge all the returned values if :array_matching is set to :all" do
+ @property.class.unmunge do |v| v.to_sym end
+ @class.array_matching = :all
+ @property.should = %w{one two}
- @property.should.must == [:one, :two]
- end
+ @property.should.must == [:one, :two]
end
+ end
- describe "when validating values" do
- it "should do nothing if no values or regexes have been defined" do
- lambda { @property.should = "foo" }.should_not raise_error
- end
+ describe "when validating values" do
+ it "should do nothing if no values or regexes have been defined" do
+ lambda { @property.should = "foo" }.should_not raise_error
+ end
- it "should fail if the value is not a defined value or alias and does not match a regex" do
- @class.newvalue(:foo)
+ it "should fail if the value is not a defined value or alias and does not match a regex" do
+ @class.newvalue(:foo)
- lambda { @property.should = "bar" }.should raise_error
- end
+ lambda { @property.should = "bar" }.should raise_error
+ end
- it "should succeeed if the value is one of the defined values" do
- @class.newvalue(:foo)
+ it "should succeeed if the value is one of the defined values" do
+ @class.newvalue(:foo)
- lambda { @property.should = :foo }.should_not raise_error
- end
+ lambda { @property.should = :foo }.should_not raise_error
+ end
- it "should succeeed if the value is one of the defined values even if the definition uses a symbol and the validation uses a string" do
- @class.newvalue(:foo)
+ it "should succeeed if the value is one of the defined values even if the definition uses a symbol and the validation uses a string" do
+ @class.newvalue(:foo)
- lambda { @property.should = "foo" }.should_not raise_error
- end
+ lambda { @property.should = "foo" }.should_not raise_error
+ end
- it "should succeeed if the value is one of the defined values even if the definition uses a string and the validation uses a symbol" do
- @class.newvalue("foo")
+ it "should succeeed if the value is one of the defined values even if the definition uses a string and the validation uses a symbol" do
+ @class.newvalue("foo")
- lambda { @property.should = :foo }.should_not raise_error
- end
+ lambda { @property.should = :foo }.should_not raise_error
+ end
- it "should succeed if the value is one of the defined aliases" do
- @class.newvalue("foo")
- @class.aliasvalue("bar", "foo")
+ it "should succeed if the value is one of the defined aliases" do
+ @class.newvalue("foo")
+ @class.aliasvalue("bar", "foo")
- lambda { @property.should = :bar }.should_not raise_error
- end
+ lambda { @property.should = :bar }.should_not raise_error
+ end
- it "should succeed if the value matches one of the regexes" do
- @class.newvalue(/./)
+ it "should succeed if the value matches one of the regexes" do
+ @class.newvalue(/./)
- lambda { @property.should = "bar" }.should_not raise_error
- end
+ lambda { @property.should = "bar" }.should_not raise_error
+ end
- it "should validate that all required features are present" do
- @class.newvalue(:foo, :required_features => [:a, :b])
+ it "should validate that all required features are present" do
+ @class.newvalue(:foo, :required_features => [:a, :b])
- @provider.expects(:satisfies?).with([:a, :b]).returns true
+ @provider.expects(:satisfies?).with([:a, :b]).returns true
- @property.should = :foo
- end
+ @property.should = :foo
+ end
- it "should fail if required features are missing" do
- @class.newvalue(:foo, :required_features => [:a, :b])
+ it "should fail if required features are missing" do
+ @class.newvalue(:foo, :required_features => [:a, :b])
- @provider.expects(:satisfies?).with([:a, :b]).returns false
+ @provider.expects(:satisfies?).with([:a, :b]).returns false
- lambda { @property.should = :foo }.should raise_error(Puppet::Error)
- end
+ lambda { @property.should = :foo }.should raise_error(Puppet::Error)
+ end
- it "should internally raise an ArgumentError if required features are missing" do
- @class.newvalue(:foo, :required_features => [:a, :b])
+ it "should internally raise an ArgumentError if required features are missing" do
+ @class.newvalue(:foo, :required_features => [:a, :b])
- @provider.expects(:satisfies?).with([:a, :b]).returns false
+ @provider.expects(:satisfies?).with([:a, :b]).returns false
- lambda { @property.validate_features_per_value :foo }.should raise_error(ArgumentError)
- end
+ lambda { @property.validate_features_per_value :foo }.should raise_error(ArgumentError)
+ end
- it "should validate that all required features are present for regexes" do
- value = @class.newvalue(/./, :required_features => [:a, :b])
+ it "should validate that all required features are present for regexes" do
+ value = @class.newvalue(/./, :required_features => [:a, :b])
- @provider.expects(:satisfies?).with([:a, :b]).returns true
+ @provider.expects(:satisfies?).with([:a, :b]).returns true
- @property.should = "foo"
- end
+ @property.should = "foo"
+ end
- it "should support specifying an individual required feature" do
- value = @class.newvalue(/./, :required_features => :a)
+ it "should support specifying an individual required feature" do
+ value = @class.newvalue(/./, :required_features => :a)
- @provider.expects(:satisfies?).returns true
+ @provider.expects(:satisfies?).returns true
- @property.should = "foo"
- end
+ @property.should = "foo"
end
+ end
- describe "when munging values" do
- it "should do nothing if no values or regexes have been defined" do
- @property.munge("foo").should == "foo"
- end
-
- it "should return return any matching defined values" do
- @class.newvalue(:foo)
- @property.munge("foo").should == :foo
- end
-
- it "should return any matching aliases" do
- @class.newvalue(:foo)
- @class.aliasvalue(:bar, :foo)
- @property.munge("bar").should == :foo
- end
+ describe "when munging values" do
+ it "should do nothing if no values or regexes have been defined" do
+ @property.munge("foo").should == "foo"
+ end
- it "should return the value if it matches a regex" do
- @class.newvalue(/./)
- @property.munge("bar").should == "bar"
- end
+ it "should return return any matching defined values" do
+ @class.newvalue(:foo)
+ @property.munge("foo").should == :foo
+ end
- it "should return the value if no other option is matched" do
- @class.newvalue(:foo)
- @property.munge("bar").should == "bar"
- end
+ it "should return any matching aliases" do
+ @class.newvalue(:foo)
+ @class.aliasvalue(:bar, :foo)
+ @property.munge("bar").should == :foo
end
- describe "when syncing the 'should' value" do
- it "should set the value" do
- @class.newvalue(:foo)
- @property.should = :foo
- @property.expects(:set).with(:foo)
- @property.sync
- end
+ it "should return the value if it matches a regex" do
+ @class.newvalue(/./)
+ @property.munge("bar").should == "bar"
end
- describe "when setting a value" do
- it "should catch exceptions and raise Puppet::Error" do
- @class.newvalue(:foo) { raise "eh" }
- lambda { @property.set(:foo) }.should raise_error(Puppet::Error)
- end
+ it "should return the value if no other option is matched" do
+ @class.newvalue(:foo)
+ @property.munge("bar").should == "bar"
+ end
+ end
+
+ describe "when syncing the 'should' value" do
+ it "should set the value" do
+ @class.newvalue(:foo)
+ @property.should = :foo
+ @property.expects(:set).with(:foo)
+ @property.sync
+ end
+ end
- describe "that was defined without a block" do
- it "should call the settor on the provider" do
- @class.newvalue(:bar)
- @provider.expects(:foo=).with :bar
- @property.set(:bar)
- end
- end
+ describe "when setting a value" do
+ it "should catch exceptions and raise Puppet::Error" do
+ @class.newvalue(:foo) { raise "eh" }
+ lambda { @property.set(:foo) }.should raise_error(Puppet::Error)
+ end
- describe "that was defined with a block" do
- it "should call the method created for the value if the value is not a regex" do
- @class.newvalue(:bar) {}
- @property.expects(:set_bar)
- @property.set(:bar)
- end
+ describe "that was defined without a block" do
+ it "should call the settor on the provider" do
+ @class.newvalue(:bar)
+ @provider.expects(:foo=).with :bar
+ @property.set(:bar)
+ end
+ end
- it "should call the provided block if the value is a regex" do
- @class.newvalue(/./) { self.test }
- @property.expects(:test)
- @property.set("foo")
- end
- end
+ describe "that was defined with a block" do
+ it "should call the method created for the value if the value is not a regex" do
+ @class.newvalue(:bar) {}
+ @property.expects(:set_bar)
+ @property.set(:bar)
+ end
+
+ it "should call the provided block if the value is a regex" do
+ @class.newvalue(/./) { self.test }
+ @property.expects(:test)
+ @property.set("foo")
+ end
end
+ end
- describe "when producing a change log" do
- it "should say 'defined' when the current value is 'absent'" do
- @property.change_to_s(:absent, "foo").should =~ /^defined/
- end
+ describe "when producing a change log" do
+ it "should say 'defined' when the current value is 'absent'" do
+ @property.change_to_s(:absent, "foo").should =~ /^defined/
+ end
- it "should say 'undefined' when the new value is 'absent'" do
- @property.change_to_s("foo", :absent).should =~ /^undefined/
- end
+ it "should say 'undefined' when the new value is 'absent'" do
+ @property.change_to_s("foo", :absent).should =~ /^undefined/
+ end
- it "should say 'changed' when neither value is 'absent'" do
- @property.change_to_s("foo", "bar").should =~ /changed/
- end
+ it "should say 'changed' when neither value is 'absent'" do
+ @property.change_to_s("foo", "bar").should =~ /changed/
end
+ end
end
diff --git a/spec/unit/provider/augeas/augeas_spec.rb b/spec/unit/provider/augeas/augeas_spec.rb
index 47655a7..07b6320 100644
--- a/spec/unit/provider/augeas/augeas_spec.rb
+++ b/spec/unit/provider/augeas/augeas_spec.rb
@@ -6,408 +6,408 @@ provider_class = Puppet::Type.type(:augeas).provider(:augeas)
describe provider_class do
- describe "command parsing" do
- before do
- @resource = stub("resource")
- @provider = provider_class.new(@resource)
- end
-
- it "should break apart a single line into three tokens and clean up the context" do
- @resource.stubs(:[]).returns("/context")
- tokens = @provider.parse_commands("set Jar/Jar Binks")
- tokens.size.should == 1
- tokens[0].size.should == 3
- tokens[0][0].should == "set"
- tokens[0][1].should == "/context/Jar/Jar"
- tokens[0][2].should == "Binks"
- end
-
- it "should break apart a multiple line into six tokens" do
- @resource.stubs(:[]).returns("")
- tokens = @provider.parse_commands("set /Jar/Jar Binks\nrm anakin")
- tokens.size.should == 2
- tokens[0].size.should == 3
- tokens[1].size.should == 2
- tokens[0][0].should == "set"
- tokens[0][1].should == "/Jar/Jar"
- tokens[0][2].should == "Binks"
- tokens[1][0].should == "rm"
- tokens[1][1].should == "anakin"
- end
-
- it "should strip whitespace and ignore blank lines" do
- @resource.stubs(:[]).returns("")
- tokens = @provider.parse_commands(" set /Jar/Jar Binks \t\n \n\n rm anakin ")
- tokens.size.should == 2
- tokens[0].size.should == 3
- tokens[1].size.should == 2
- tokens[0][0].should == "set"
- tokens[0][1].should == "/Jar/Jar"
- tokens[0][2].should == "Binks"
- tokens[1][0].should == "rm"
- tokens[1][1].should == "anakin"
- end
-
- it "should handle arrays" do
- @resource.stubs(:[]).returns("/foo/")
- commands = ["set /Jar/Jar Binks", "rm anakin"]
- tokens = @provider.parse_commands(commands)
- tokens.size.should == 2
- tokens[0].size.should == 3
- tokens[1].size.should == 2
- tokens[0][0].should == "set"
- tokens[0][1].should == "/Jar/Jar"
- tokens[0][2].should == "Binks"
- tokens[1][0].should == "rm"
- tokens[1][1].should == "/foo/anakin"
- end
-
- # This is not supported in the new parsing class
- #it "should concat the last values" do
- # provider = provider_class.new
- # tokens = provider.parse_commands("set /Jar/Jar Binks is my copilot")
- # tokens.size.should == 1
- # tokens[0].size.should == 3
- # tokens[0][0].should == "set"
- # tokens[0][1].should == "/Jar/Jar"
- # tokens[0][2].should == "Binks is my copilot"
- #end
-
- it "should accept spaces in the value and single ticks" do
- @resource.stubs(:[]).returns("/foo/")
- tokens = @provider.parse_commands("set JarJar 'Binks is my copilot'")
- tokens.size.should == 1
- tokens[0].size.should == 3
- tokens[0][0].should == "set"
- tokens[0][1].should == "/foo/JarJar"
- tokens[0][2].should == "Binks is my copilot"
- end
-
- it "should accept spaces in the value and double ticks" do
- @resource.stubs(:[]).returns("/foo/")
- tokens = @provider.parse_commands('set /JarJar "Binks is my copilot"')
- tokens.size.should == 1
- tokens[0].size.should == 3
- tokens[0][0].should == "set"
- tokens[0][1].should == '/JarJar'
- tokens[0][2].should == 'Binks is my copilot'
- end
-
- it "should accept mixed ticks" do
- @resource.stubs(:[]).returns("/foo/")
- tokens = @provider.parse_commands('set JarJar "Some \'Test\'"')
- tokens.size.should == 1
- tokens[0].size.should == 3
- tokens[0][0].should == "set"
- tokens[0][1].should == '/foo/JarJar'
- tokens[0][2].should == "Some \'Test\'"
- end
-
- it "should handle predicates with literals" do
- @resource.stubs(:[]).returns("/foo/")
- tokens = @provider.parse_commands("rm */*[module='pam_console.so']")
- tokens.should == [["rm", "/foo/*/*[module='pam_console.so']"]]
- end
-
- it "should handle whitespace in predicates" do
- @resource.stubs(:[]).returns("/foo/")
- tokens = @provider.parse_commands("ins 42 before /files/etc/hosts/*/ipaddr[ . = '127.0.0.1' ]")
- tokens.should == [["ins", "42", "before","/files/etc/hosts/*/ipaddr[ . = '127.0.0.1' ]"]]
- end
-
- it "should handle multiple predicates" do
- @resource.stubs(:[]).returns("/foo/")
- tokens = @provider.parse_commands("clear pam.d/*/*[module = 'system-auth'][type = 'account']")
- tokens.should == [["clear", "/foo/pam.d/*/*[module = 'system-auth'][type = 'account']"]]
- end
-
- it "should handle nested predicates" do
- @resource.stubs(:[]).returns("/foo/")
- args = ["clear", "/foo/pam.d/*/*[module[ ../type = 'type] = 'system-auth'][type[last()] = 'account']"]
- tokens = @provider.parse_commands(args.join(" "))
- tokens.should == [ args ]
- end
-
- it "should handle escaped doublequotes in doublequoted string" do
- @resource.stubs(:[]).returns("/foo/")
- tokens = @provider.parse_commands("set /foo \"''\\\"''\"")
- tokens.should == [[ "set", "/foo", "''\\\"''" ]]
- end
-
- it "should allow escaped spaces and brackets in paths" do
- @resource.stubs(:[]).returns("/foo/")
- args = [ "set", "/white\\ space/\\[section", "value" ]
- tokens = @provider.parse_commands(args.join(" \t "))
- tokens.should == [ args ]
- end
-
- it "should allow single quoted escaped spaces in paths" do
- @resource.stubs(:[]).returns("/foo/")
- args = [ "set", "'/white\\ space/key'", "value" ]
- tokens = @provider.parse_commands(args.join(" \t "))
- tokens.should == [[ "set", "/white\\ space/key", "value" ]]
- end
-
- it "should allow double quoted escaped spaces in paths" do
- @resource.stubs(:[]).returns("/foo/")
- args = [ "set", '"/white\\ space/key"', "value" ]
- tokens = @provider.parse_commands(args.join(" \t "))
- tokens.should == [[ "set", "/white\\ space/key", "value" ]]
- end
-
- it "should remove trailing slashes" do
- @resource.stubs(:[]).returns("/foo/")
- tokens = @provider.parse_commands("set foo/ bar")
- tokens.should == [[ "set", "/foo/foo", "bar" ]]
- end
- end
-
- describe "get filters" do
- before do
- augeas_stub = stub("augeas", :get => "value")
- @provider = provider_class.new
- @provider.aug= augeas_stub
- end
-
- it "should return false for a = nonmatch" do
- command = ["get", "fake value", "==", "value"]
- @provider.process_get(command).should == true
- end
-
- it "should return true for a != match" do
- command = ["get", "fake value", "!=", "value"]
- @provider.process_get(command).should == false
- end
-
- it "should return true for a =~ match" do
- command = ["get", "fake value", "=~", "val*"]
- @provider.process_get(command).should == true
- end
-
- it "should return false for a == nonmatch" do
- command = ["get", "fake value", "=~", "num*"]
- @provider.process_get(command).should == false
- end
- end
-
- describe "match filters" do
- before do
- resource = stub("resource", :[] => "")
- augeas_stub = stub("augeas", :match => ["set", "of", "values"])
- @provider = provider_class.new(resource)
- @provider.aug= augeas_stub
- end
-
- it "should return true for size match" do
- command = ["match", "fake value", "size == 3"]
- @provider.process_match(command).should == true
- end
-
- it "should return false for a size non match" do
- command = ["match", "fake value", "size < 3"]
- @provider.process_match(command).should == false
- end
-
- it "should return true for includes match" do
- command = ["match", "fake value", "include values"]
- @provider.process_match(command).should == true
- end
-
- it "should return false for includes non match" do
- command = ["match", "fake value", "include JarJar"]
- @provider.process_match(command).should == false
- end
-
- it "should return true for includes match" do
- command = ["match", "fake value", "not_include JarJar"]
- @provider.process_match(command).should == true
- end
-
- it "should return false for includes non match" do
- command = ["match", "fake value", "not_include values"]
- @provider.process_match(command).should == false
- end
-
- it "should return true for an array match" do
- command = ["match", "fake value", "== ['set', 'of', 'values']"]
- @provider.process_match(command).should == true
- end
-
- it "should return false for an array non match" do
- command = ["match", "fake value", "== ['this', 'should', 'not', 'match']"]
- @provider.process_match(command).should == false
- end
-
- it "should return false for an array match with noteq" do
- command = ["match", "fake value", "!= ['set', 'of', 'values']"]
- @provider.process_match(command).should == false
- end
-
- it "should return true for an array non match with noteq" do
- command = ["match", "fake value", "!= ['this', 'should', 'not', 'match']"]
- @provider.process_match(command).should == true
- end
- end
-
- describe "need to run" do
- it "should handle no filters" do
- resource = stub("resource")
- resource.stubs(:[]).returns(false).then.returns("").then.returns("")
- augeas_stub = stub("augeas", :match => ["set", "of", "values"])
- augeas_stub.stubs("close")
- provider = provider_class.new(resource)
- provider.aug= augeas_stub
- provider.stubs(:get_augeas_version).returns("0.3.5")
- provider.need_to_run?.should == true
- end
-
- it "should return true when a get filter matches" do
- resource = stub("resource")
- resource.stubs(:[]).returns(false).then.returns("get path == value").then.returns("")
- provider = provider_class.new(resource)
- augeas_stub = stub("augeas", :get => "value")
- augeas_stub.stubs("close")
- provider.aug= augeas_stub
- provider.stubs(:get_augeas_version).returns("0.3.5")
- provider.need_to_run?.should == true
- end
-
- it "should return false when a get filter does not match" do
- resource = stub("resource")
- resource.stubs(:[]).returns(false).then.returns("get path == another value").then.returns("")
- provider = provider_class.new(resource)
- augeas_stub = stub("augeas", :get => "value")
- augeas_stub.stubs("close")
- provider.aug= augeas_stub
- provider.stubs(:get_augeas_version).returns("0.3.5")
- provider.need_to_run?.should == false
- end
-
- it "should return true when a match filter matches" do
- resource = stub("resource")
- resource.stubs(:[]).returns(false).then.returns("match path size == 3").then.returns("")
- provider = provider_class.new(resource)
- augeas_stub = stub("augeas", :match => ["set", "of", "values"])
- augeas_stub.stubs("close")
- provider.aug= augeas_stub
- provider.stubs(:get_augeas_version).returns("0.3.5")
- provider.need_to_run?.should == true
- end
-
- it "should return false when a match filter does not match" do
- resource = stub("resource")
- resource.stubs(:[]).returns(false).then.returns("match path size == 2").then.returns("")
- provider = provider_class.new(resource)
- augeas_stub = stub("augeas", :match => ["set", "of", "values"])
- augeas_stub.stubs("close")
- provider.aug= augeas_stub
- provider.stubs(:get_augeas_version).returns("0.3.5")
- provider.need_to_run?.should == false
- end
-
- #This is a copy of the last one, with setting the force to true
- it "setting force should not change the above logic" do
- resource = stub("resource")
- resource.stubs(:[]).returns(true).then.returns("match path size == 2").then.returns("")
- provider = provider_class.new(resource)
- augeas_stub = stub("augeas", :match => ["set", "of", "values"])
- augeas_stub.stubs("close")
- provider.aug= augeas_stub
- provider.stubs(:get_augeas_version).returns("0.3.5")
- provider.need_to_run?.should == false
- end
- end
-
- describe "augeas execution integration" do
-
- before do
- @resource = stub("resource")
- @provider = provider_class.new(@resource)
- @augeas = stub("augeas")
- @provider.aug= @augeas
- @provider.stubs(:get_augeas_version).returns("0.3.5")
- end
-
- it "should handle set commands" do
- command = "set JarJar Binks"
- context = "/some/path/"
- @resource.expects(:[]).times(2).returns(command).then.returns(context)
- @augeas.expects(:set).with("/some/path/JarJar", "Binks").returns(true)
- @augeas.expects(:save).returns(true)
- @augeas.expects(:close)
- @provider.execute_changes.should == :executed
- end
-
- it "should handle rm commands" do
- command = "rm /Jar/Jar"
- context = ""
- @resource.expects(:[]).times(2).returns(command).then.returns(context)
- @augeas.expects(:rm).with("/Jar/Jar")
- @augeas.expects(:save).returns(true)
- @augeas.expects(:close)
- @provider.execute_changes.should == :executed
- end
-
- it "should handle remove commands" do
- command = "remove /Jar/Jar"
- context = ""
- @resource.expects(:[]).times(2).returns(command).then.returns(context)
- @augeas.expects(:rm).with("/Jar/Jar")
- @augeas.expects(:save).returns(true)
- @augeas.expects(:close)
- @provider.execute_changes.should == :executed
- end
-
- it "should handle clear commands" do
- command = "clear Jar/Jar"
- context = "/foo/"
- @resource.expects(:[]).times(2).returns(command).then.returns(context)
- @augeas.expects(:clear).with("/foo/Jar/Jar").returns(true)
- @augeas.expects(:save).returns(true)
- @augeas.expects(:close)
- @provider.execute_changes.should == :executed
- end
-
-
- it "should handle ins commands with before" do
- command = "ins Binks before Jar/Jar"
- context = "/foo"
- @resource.expects(:[]).times(2).returns(command).then.returns(context)
- @augeas.expects(:insert).with("/foo/Jar/Jar", "Binks", true)
- @augeas.expects(:save).returns(true)
- @augeas.expects(:close)
- @provider.execute_changes.should == :executed
- end
-
- it "should handle ins commands with after" do
- command = "ins Binks after /Jar/Jar"
- context = "/foo"
- @resource.expects(:[]).times(2).returns(command).then.returns(context)
- @augeas.expects(:insert).with("/Jar/Jar", "Binks", false)
- @augeas.expects(:save).returns(true)
- @augeas.expects(:close)
- @provider.execute_changes.should == :executed
- end
-
- it "should handle ins with no context" do
- command = "ins Binks after /Jar/Jar"
- context = "" # this is the default
- @resource.expects(:[]).times(2).returns(command).then.returns(context)
- @augeas.expects(:insert).with("/Jar/Jar", "Binks", false)
- @augeas.expects(:save).returns(true)
- @augeas.expects(:close)
- @provider.execute_changes.should == :executed
- end
-
- it "should handle multiple commands" do
- command = ["ins Binks after /Jar/Jar", "clear Jar/Jar"]
- context = "/foo/"
- @resource.expects(:[]).times(2).returns(command).then.returns(context)
- @augeas.expects(:insert).with("/Jar/Jar", "Binks", false)
- @augeas.expects(:clear).with("/foo/Jar/Jar").returns(true)
- @augeas.expects(:save).returns(true)
- @augeas.expects(:close)
- @provider.execute_changes.should == :executed
- end
+ describe "command parsing" do
+ before do
+ @resource = stub("resource")
+ @provider = provider_class.new(@resource)
end
+
+ it "should break apart a single line into three tokens and clean up the context" do
+ @resource.stubs(:[]).returns("/context")
+ tokens = @provider.parse_commands("set Jar/Jar Binks")
+ tokens.size.should == 1
+ tokens[0].size.should == 3
+ tokens[0][0].should == "set"
+ tokens[0][1].should == "/context/Jar/Jar"
+ tokens[0][2].should == "Binks"
+ end
+
+ it "should break apart a multiple line into six tokens" do
+ @resource.stubs(:[]).returns("")
+ tokens = @provider.parse_commands("set /Jar/Jar Binks\nrm anakin")
+ tokens.size.should == 2
+ tokens[0].size.should == 3
+ tokens[1].size.should == 2
+ tokens[0][0].should == "set"
+ tokens[0][1].should == "/Jar/Jar"
+ tokens[0][2].should == "Binks"
+ tokens[1][0].should == "rm"
+ tokens[1][1].should == "anakin"
+ end
+
+ it "should strip whitespace and ignore blank lines" do
+ @resource.stubs(:[]).returns("")
+ tokens = @provider.parse_commands(" set /Jar/Jar Binks \t\n \n\n rm anakin ")
+ tokens.size.should == 2
+ tokens[0].size.should == 3
+ tokens[1].size.should == 2
+ tokens[0][0].should == "set"
+ tokens[0][1].should == "/Jar/Jar"
+ tokens[0][2].should == "Binks"
+ tokens[1][0].should == "rm"
+ tokens[1][1].should == "anakin"
+ end
+
+ it "should handle arrays" do
+ @resource.stubs(:[]).returns("/foo/")
+ commands = ["set /Jar/Jar Binks", "rm anakin"]
+ tokens = @provider.parse_commands(commands)
+ tokens.size.should == 2
+ tokens[0].size.should == 3
+ tokens[1].size.should == 2
+ tokens[0][0].should == "set"
+ tokens[0][1].should == "/Jar/Jar"
+ tokens[0][2].should == "Binks"
+ tokens[1][0].should == "rm"
+ tokens[1][1].should == "/foo/anakin"
+ end
+
+ # This is not supported in the new parsing class
+ #it "should concat the last values" do
+ # provider = provider_class.new
+ # tokens = provider.parse_commands("set /Jar/Jar Binks is my copilot")
+ # tokens.size.should == 1
+ # tokens[0].size.should == 3
+ # tokens[0][0].should == "set"
+ # tokens[0][1].should == "/Jar/Jar"
+ # tokens[0][2].should == "Binks is my copilot"
+ #end
+
+ it "should accept spaces in the value and single ticks" do
+ @resource.stubs(:[]).returns("/foo/")
+ tokens = @provider.parse_commands("set JarJar 'Binks is my copilot'")
+ tokens.size.should == 1
+ tokens[0].size.should == 3
+ tokens[0][0].should == "set"
+ tokens[0][1].should == "/foo/JarJar"
+ tokens[0][2].should == "Binks is my copilot"
+ end
+
+ it "should accept spaces in the value and double ticks" do
+ @resource.stubs(:[]).returns("/foo/")
+ tokens = @provider.parse_commands('set /JarJar "Binks is my copilot"')
+ tokens.size.should == 1
+ tokens[0].size.should == 3
+ tokens[0][0].should == "set"
+ tokens[0][1].should == '/JarJar'
+ tokens[0][2].should == 'Binks is my copilot'
+ end
+
+ it "should accept mixed ticks" do
+ @resource.stubs(:[]).returns("/foo/")
+ tokens = @provider.parse_commands('set JarJar "Some \'Test\'"')
+ tokens.size.should == 1
+ tokens[0].size.should == 3
+ tokens[0][0].should == "set"
+ tokens[0][1].should == '/foo/JarJar'
+ tokens[0][2].should == "Some \'Test\'"
+ end
+
+ it "should handle predicates with literals" do
+ @resource.stubs(:[]).returns("/foo/")
+ tokens = @provider.parse_commands("rm */*[module='pam_console.so']")
+ tokens.should == [["rm", "/foo/*/*[module='pam_console.so']"]]
+ end
+
+ it "should handle whitespace in predicates" do
+ @resource.stubs(:[]).returns("/foo/")
+ tokens = @provider.parse_commands("ins 42 before /files/etc/hosts/*/ipaddr[ . = '127.0.0.1' ]")
+ tokens.should == [["ins", "42", "before","/files/etc/hosts/*/ipaddr[ . = '127.0.0.1' ]"]]
+ end
+
+ it "should handle multiple predicates" do
+ @resource.stubs(:[]).returns("/foo/")
+ tokens = @provider.parse_commands("clear pam.d/*/*[module = 'system-auth'][type = 'account']")
+ tokens.should == [["clear", "/foo/pam.d/*/*[module = 'system-auth'][type = 'account']"]]
+ end
+
+ it "should handle nested predicates" do
+ @resource.stubs(:[]).returns("/foo/")
+ args = ["clear", "/foo/pam.d/*/*[module[ ../type = 'type] = 'system-auth'][type[last()] = 'account']"]
+ tokens = @provider.parse_commands(args.join(" "))
+ tokens.should == [ args ]
+ end
+
+ it "should handle escaped doublequotes in doublequoted string" do
+ @resource.stubs(:[]).returns("/foo/")
+ tokens = @provider.parse_commands("set /foo \"''\\\"''\"")
+ tokens.should == [[ "set", "/foo", "''\\\"''" ]]
+ end
+
+ it "should allow escaped spaces and brackets in paths" do
+ @resource.stubs(:[]).returns("/foo/")
+ args = [ "set", "/white\\ space/\\[section", "value" ]
+ tokens = @provider.parse_commands(args.join(" \t "))
+ tokens.should == [ args ]
+ end
+
+ it "should allow single quoted escaped spaces in paths" do
+ @resource.stubs(:[]).returns("/foo/")
+ args = [ "set", "'/white\\ space/key'", "value" ]
+ tokens = @provider.parse_commands(args.join(" \t "))
+ tokens.should == [[ "set", "/white\\ space/key", "value" ]]
+ end
+
+ it "should allow double quoted escaped spaces in paths" do
+ @resource.stubs(:[]).returns("/foo/")
+ args = [ "set", '"/white\\ space/key"', "value" ]
+ tokens = @provider.parse_commands(args.join(" \t "))
+ tokens.should == [[ "set", "/white\\ space/key", "value" ]]
+ end
+
+ it "should remove trailing slashes" do
+ @resource.stubs(:[]).returns("/foo/")
+ tokens = @provider.parse_commands("set foo/ bar")
+ tokens.should == [[ "set", "/foo/foo", "bar" ]]
+ end
+ end
+
+ describe "get filters" do
+ before do
+ augeas_stub = stub("augeas", :get => "value")
+ @provider = provider_class.new
+ @provider.aug= augeas_stub
+ end
+
+ it "should return false for a = nonmatch" do
+ command = ["get", "fake value", "==", "value"]
+ @provider.process_get(command).should == true
+ end
+
+ it "should return true for a != match" do
+ command = ["get", "fake value", "!=", "value"]
+ @provider.process_get(command).should == false
+ end
+
+ it "should return true for a =~ match" do
+ command = ["get", "fake value", "=~", "val*"]
+ @provider.process_get(command).should == true
+ end
+
+ it "should return false for a == nonmatch" do
+ command = ["get", "fake value", "=~", "num*"]
+ @provider.process_get(command).should == false
+ end
+ end
+
+ describe "match filters" do
+ before do
+ resource = stub("resource", :[] => "")
+ augeas_stub = stub("augeas", :match => ["set", "of", "values"])
+ @provider = provider_class.new(resource)
+ @provider.aug= augeas_stub
+ end
+
+ it "should return true for size match" do
+ command = ["match", "fake value", "size == 3"]
+ @provider.process_match(command).should == true
+ end
+
+ it "should return false for a size non match" do
+ command = ["match", "fake value", "size < 3"]
+ @provider.process_match(command).should == false
+ end
+
+ it "should return true for includes match" do
+ command = ["match", "fake value", "include values"]
+ @provider.process_match(command).should == true
+ end
+
+ it "should return false for includes non match" do
+ command = ["match", "fake value", "include JarJar"]
+ @provider.process_match(command).should == false
+ end
+
+ it "should return true for includes match" do
+ command = ["match", "fake value", "not_include JarJar"]
+ @provider.process_match(command).should == true
+ end
+
+ it "should return false for includes non match" do
+ command = ["match", "fake value", "not_include values"]
+ @provider.process_match(command).should == false
+ end
+
+ it "should return true for an array match" do
+ command = ["match", "fake value", "== ['set', 'of', 'values']"]
+ @provider.process_match(command).should == true
+ end
+
+ it "should return false for an array non match" do
+ command = ["match", "fake value", "== ['this', 'should', 'not', 'match']"]
+ @provider.process_match(command).should == false
+ end
+
+ it "should return false for an array match with noteq" do
+ command = ["match", "fake value", "!= ['set', 'of', 'values']"]
+ @provider.process_match(command).should == false
+ end
+
+ it "should return true for an array non match with noteq" do
+ command = ["match", "fake value", "!= ['this', 'should', 'not', 'match']"]
+ @provider.process_match(command).should == true
+ end
+ end
+
+ describe "need to run" do
+ it "should handle no filters" do
+ resource = stub("resource")
+ resource.stubs(:[]).returns(false).then.returns("").then.returns("")
+ augeas_stub = stub("augeas", :match => ["set", "of", "values"])
+ augeas_stub.stubs("close")
+ provider = provider_class.new(resource)
+ provider.aug= augeas_stub
+ provider.stubs(:get_augeas_version).returns("0.3.5")
+ provider.need_to_run?.should == true
+ end
+
+ it "should return true when a get filter matches" do
+ resource = stub("resource")
+ resource.stubs(:[]).returns(false).then.returns("get path == value").then.returns("")
+ provider = provider_class.new(resource)
+ augeas_stub = stub("augeas", :get => "value")
+ augeas_stub.stubs("close")
+ provider.aug= augeas_stub
+ provider.stubs(:get_augeas_version).returns("0.3.5")
+ provider.need_to_run?.should == true
+ end
+
+ it "should return false when a get filter does not match" do
+ resource = stub("resource")
+ resource.stubs(:[]).returns(false).then.returns("get path == another value").then.returns("")
+ provider = provider_class.new(resource)
+ augeas_stub = stub("augeas", :get => "value")
+ augeas_stub.stubs("close")
+ provider.aug= augeas_stub
+ provider.stubs(:get_augeas_version).returns("0.3.5")
+ provider.need_to_run?.should == false
+ end
+
+ it "should return true when a match filter matches" do
+ resource = stub("resource")
+ resource.stubs(:[]).returns(false).then.returns("match path size == 3").then.returns("")
+ provider = provider_class.new(resource)
+ augeas_stub = stub("augeas", :match => ["set", "of", "values"])
+ augeas_stub.stubs("close")
+ provider.aug= augeas_stub
+ provider.stubs(:get_augeas_version).returns("0.3.5")
+ provider.need_to_run?.should == true
+ end
+
+ it "should return false when a match filter does not match" do
+ resource = stub("resource")
+ resource.stubs(:[]).returns(false).then.returns("match path size == 2").then.returns("")
+ provider = provider_class.new(resource)
+ augeas_stub = stub("augeas", :match => ["set", "of", "values"])
+ augeas_stub.stubs("close")
+ provider.aug= augeas_stub
+ provider.stubs(:get_augeas_version).returns("0.3.5")
+ provider.need_to_run?.should == false
+ end
+
+ #This is a copy of the last one, with setting the force to true
+ it "setting force should not change the above logic" do
+ resource = stub("resource")
+ resource.stubs(:[]).returns(true).then.returns("match path size == 2").then.returns("")
+ provider = provider_class.new(resource)
+ augeas_stub = stub("augeas", :match => ["set", "of", "values"])
+ augeas_stub.stubs("close")
+ provider.aug= augeas_stub
+ provider.stubs(:get_augeas_version).returns("0.3.5")
+ provider.need_to_run?.should == false
+ end
+ end
+
+ describe "augeas execution integration" do
+
+ before do
+ @resource = stub("resource")
+ @provider = provider_class.new(@resource)
+ @augeas = stub("augeas")
+ @provider.aug= @augeas
+ @provider.stubs(:get_augeas_version).returns("0.3.5")
+ end
+
+ it "should handle set commands" do
+ command = "set JarJar Binks"
+ context = "/some/path/"
+ @resource.expects(:[]).times(2).returns(command).then.returns(context)
+ @augeas.expects(:set).with("/some/path/JarJar", "Binks").returns(true)
+ @augeas.expects(:save).returns(true)
+ @augeas.expects(:close)
+ @provider.execute_changes.should == :executed
+ end
+
+ it "should handle rm commands" do
+ command = "rm /Jar/Jar"
+ context = ""
+ @resource.expects(:[]).times(2).returns(command).then.returns(context)
+ @augeas.expects(:rm).with("/Jar/Jar")
+ @augeas.expects(:save).returns(true)
+ @augeas.expects(:close)
+ @provider.execute_changes.should == :executed
+ end
+
+ it "should handle remove commands" do
+ command = "remove /Jar/Jar"
+ context = ""
+ @resource.expects(:[]).times(2).returns(command).then.returns(context)
+ @augeas.expects(:rm).with("/Jar/Jar")
+ @augeas.expects(:save).returns(true)
+ @augeas.expects(:close)
+ @provider.execute_changes.should == :executed
+ end
+
+ it "should handle clear commands" do
+ command = "clear Jar/Jar"
+ context = "/foo/"
+ @resource.expects(:[]).times(2).returns(command).then.returns(context)
+ @augeas.expects(:clear).with("/foo/Jar/Jar").returns(true)
+ @augeas.expects(:save).returns(true)
+ @augeas.expects(:close)
+ @provider.execute_changes.should == :executed
+ end
+
+
+ it "should handle ins commands with before" do
+ command = "ins Binks before Jar/Jar"
+ context = "/foo"
+ @resource.expects(:[]).times(2).returns(command).then.returns(context)
+ @augeas.expects(:insert).with("/foo/Jar/Jar", "Binks", true)
+ @augeas.expects(:save).returns(true)
+ @augeas.expects(:close)
+ @provider.execute_changes.should == :executed
+ end
+
+ it "should handle ins commands with after" do
+ command = "ins Binks after /Jar/Jar"
+ context = "/foo"
+ @resource.expects(:[]).times(2).returns(command).then.returns(context)
+ @augeas.expects(:insert).with("/Jar/Jar", "Binks", false)
+ @augeas.expects(:save).returns(true)
+ @augeas.expects(:close)
+ @provider.execute_changes.should == :executed
+ end
+
+ it "should handle ins with no context" do
+ command = "ins Binks after /Jar/Jar"
+ context = "" # this is the default
+ @resource.expects(:[]).times(2).returns(command).then.returns(context)
+ @augeas.expects(:insert).with("/Jar/Jar", "Binks", false)
+ @augeas.expects(:save).returns(true)
+ @augeas.expects(:close)
+ @provider.execute_changes.should == :executed
+ end
+
+ it "should handle multiple commands" do
+ command = ["ins Binks after /Jar/Jar", "clear Jar/Jar"]
+ context = "/foo/"
+ @resource.expects(:[]).times(2).returns(command).then.returns(context)
+ @augeas.expects(:insert).with("/Jar/Jar", "Binks", false)
+ @augeas.expects(:clear).with("/foo/Jar/Jar").returns(true)
+ @augeas.expects(:save).returns(true)
+ @augeas.expects(:close)
+ @provider.execute_changes.should == :executed
+ end
+ end
end
diff --git a/spec/unit/provider/confine/exists_spec.rb b/spec/unit/provider/confine/exists_spec.rb
index a3539c4..c3958e3 100755
--- a/spec/unit/provider/confine/exists_spec.rb
+++ b/spec/unit/provider/confine/exists_spec.rb
@@ -5,77 +5,77 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/provider/confine/exists'
describe Puppet::Provider::Confine::Exists do
- before do
- @confine = Puppet::Provider::Confine::Exists.new("/my/file")
- @confine.label = "eh"
+ before do
+ @confine = Puppet::Provider::Confine::Exists.new("/my/file")
+ @confine.label = "eh"
+ end
+
+ it "should be named :exists" do
+ Puppet::Provider::Confine::Exists.name.should == :exists
+ end
+
+ it "should use the 'pass?' method to test validity" do
+ @confine.expects(:pass?).with("/my/file")
+ @confine.valid?
+ end
+
+ it "should return false if the value is false" do
+ @confine.pass?(false).should be_false
+ end
+
+ it "should return false if the value does not point to a file" do
+ FileTest.expects(:exist?).with("/my/file").returns false
+ @confine.pass?("/my/file").should be_false
+ end
+
+ it "should return true if the value points to a file" do
+ FileTest.expects(:exist?).with("/my/file").returns true
+ @confine.pass?("/my/file").should be_true
+ end
+
+ it "should produce a message saying that a file is missing" do
+ @confine.message("/my/file").should be_include("does not exist")
+ end
+
+ describe "and the confine is for binaries" do
+ before { @confine.stubs(:for_binary).returns true }
+ it "should use its 'binary' method to look up the full path of the file" do
+ @confine.expects(:binary).returns nil
+ @confine.pass?("/my/file")
end
- it "should be named :exists" do
- Puppet::Provider::Confine::Exists.name.should == :exists
+ it "should return false if no binary can be found" do
+ @confine.expects(:binary).with("/my/file").returns nil
+ @confine.pass?("/my/file").should be_false
end
- it "should use the 'pass?' method to test validity" do
- @confine.expects(:pass?).with("/my/file")
- @confine.valid?
+ it "should return true if the binary can be found and the file exists" do
+ @confine.expects(:binary).with("/my/file").returns "/my/file"
+ FileTest.expects(:exist?).with("/my/file").returns true
+ @confine.pass?("/my/file").should be_true
end
- it "should return false if the value is false" do
- @confine.pass?(false).should be_false
+ it "should return false if the binary can be found but the file does not exist" do
+ @confine.expects(:binary).with("/my/file").returns "/my/file"
+ FileTest.expects(:exist?).with("/my/file").returns true
+ @confine.pass?("/my/file").should be_true
end
+ end
- it "should return false if the value does not point to a file" do
- FileTest.expects(:exist?).with("/my/file").returns false
- @confine.pass?("/my/file").should be_false
- end
-
- it "should return true if the value points to a file" do
- FileTest.expects(:exist?).with("/my/file").returns true
- @confine.pass?("/my/file").should be_true
- end
-
- it "should produce a message saying that a file is missing" do
- @confine.message("/my/file").should be_include("does not exist")
- end
+ it "should produce a summary containing all missing files" do
+ FileTest.stubs(:exist?).returns true
+ FileTest.expects(:exist?).with("/two").returns false
+ FileTest.expects(:exist?).with("/four").returns false
- describe "and the confine is for binaries" do
- before { @confine.stubs(:for_binary).returns true }
- it "should use its 'binary' method to look up the full path of the file" do
- @confine.expects(:binary).returns nil
- @confine.pass?("/my/file")
- end
-
- it "should return false if no binary can be found" do
- @confine.expects(:binary).with("/my/file").returns nil
- @confine.pass?("/my/file").should be_false
- end
-
- it "should return true if the binary can be found and the file exists" do
- @confine.expects(:binary).with("/my/file").returns "/my/file"
- FileTest.expects(:exist?).with("/my/file").returns true
- @confine.pass?("/my/file").should be_true
- end
-
- it "should return false if the binary can be found but the file does not exist" do
- @confine.expects(:binary).with("/my/file").returns "/my/file"
- FileTest.expects(:exist?).with("/my/file").returns true
- @confine.pass?("/my/file").should be_true
- end
- end
-
- it "should produce a summary containing all missing files" do
- FileTest.stubs(:exist?).returns true
- FileTest.expects(:exist?).with("/two").returns false
- FileTest.expects(:exist?).with("/four").returns false
+ confine = Puppet::Provider::Confine::Exists.new %w{/one /two /three /four}
+ confine.summary.should == %w{/two /four}
+ end
- confine = Puppet::Provider::Confine::Exists.new %w{/one /two /three /four}
- confine.summary.should == %w{/two /four}
- end
+ it "should summarize multiple instances by returning a flattened array of their summaries" do
+ c1 = mock '1', :summary => %w{one}
+ c2 = mock '2', :summary => %w{two}
+ c3 = mock '3', :summary => %w{three}
- it "should summarize multiple instances by returning a flattened array of their summaries" do
- c1 = mock '1', :summary => %w{one}
- c2 = mock '2', :summary => %w{two}
- c3 = mock '3', :summary => %w{three}
-
- Puppet::Provider::Confine::Exists.summarize([c1, c2, c3]).should == %w{one two three}
- end
+ Puppet::Provider::Confine::Exists.summarize([c1, c2, c3]).should == %w{one two three}
+ end
end
diff --git a/spec/unit/provider/confine/false_spec.rb b/spec/unit/provider/confine/false_spec.rb
index 425aa30..999fc47 100755
--- a/spec/unit/provider/confine/false_spec.rb
+++ b/spec/unit/provider/confine/false_spec.rb
@@ -5,49 +5,49 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/provider/confine/false'
describe Puppet::Provider::Confine::False do
- it "should be named :false" do
- Puppet::Provider::Confine::False.name.should == :false
+ it "should be named :false" do
+ Puppet::Provider::Confine::False.name.should == :false
+ end
+
+ it "should require a value" do
+ lambda { Puppet::Provider::Confine.new }.should raise_error(ArgumentError)
+ end
+
+ describe "when testing values" do
+ before { @confine = Puppet::Provider::Confine::False.new("foo") }
+
+ it "should use the 'pass?' method to test validity" do
+ @confine = Puppet::Provider::Confine::False.new("foo")
+ @confine.label = "eh"
+ @confine.expects(:pass?).with("foo")
+ @confine.valid?
end
- it "should require a value" do
- lambda { Puppet::Provider::Confine.new }.should raise_error(ArgumentError)
+ it "should return true if the value is false" do
+ @confine.pass?(false).should be_true
end
- describe "when testing values" do
- before { @confine = Puppet::Provider::Confine::False.new("foo") }
-
- it "should use the 'pass?' method to test validity" do
- @confine = Puppet::Provider::Confine::False.new("foo")
- @confine.label = "eh"
- @confine.expects(:pass?).with("foo")
- @confine.valid?
- end
-
- it "should return true if the value is false" do
- @confine.pass?(false).should be_true
- end
-
- it "should return false if the value is not false" do
- @confine.pass?("else").should be_false
- end
-
- it "should produce a message that a value is true" do
- @confine = Puppet::Provider::Confine::False.new("foo")
- @confine.message("eh").should be_include("true")
- end
+ it "should return false if the value is not false" do
+ @confine.pass?("else").should be_false
end
- it "should be able to produce a summary with the number of incorrectly true values" do
- confine = Puppet::Provider::Confine::False.new %w{one two three four}
- confine.expects(:pass?).times(4).returns(true).returns(false).returns(true).returns(false)
- confine.summary.should == 2
+ it "should produce a message that a value is true" do
+ @confine = Puppet::Provider::Confine::False.new("foo")
+ @confine.message("eh").should be_include("true")
end
+ end
- it "should summarize multiple instances by summing their summaries" do
- c1 = mock '1', :summary => 1
- c2 = mock '2', :summary => 2
- c3 = mock '3', :summary => 3
+ it "should be able to produce a summary with the number of incorrectly true values" do
+ confine = Puppet::Provider::Confine::False.new %w{one two three four}
+ confine.expects(:pass?).times(4).returns(true).returns(false).returns(true).returns(false)
+ confine.summary.should == 2
+ end
- Puppet::Provider::Confine::False.summarize([c1, c2, c3]).should == 6
- end
+ it "should summarize multiple instances by summing their summaries" do
+ c1 = mock '1', :summary => 1
+ c2 = mock '2', :summary => 2
+ c3 = mock '3', :summary => 3
+
+ Puppet::Provider::Confine::False.summarize([c1, c2, c3]).should == 6
+ end
end
diff --git a/spec/unit/provider/confine/feature_spec.rb b/spec/unit/provider/confine/feature_spec.rb
index 1db81ba..e8368ef 100755
--- a/spec/unit/provider/confine/feature_spec.rb
+++ b/spec/unit/provider/confine/feature_spec.rb
@@ -5,56 +5,56 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/provider/confine/feature'
describe Puppet::Provider::Confine::Feature do
- it "should be named :feature" do
- Puppet::Provider::Confine::Feature.name.should == :feature
+ it "should be named :feature" do
+ Puppet::Provider::Confine::Feature.name.should == :feature
+ end
+
+ it "should require a value" do
+ lambda { Puppet::Provider::Confine::Feature.new }.should raise_error(ArgumentError)
+ end
+
+ it "should always convert values to an array" do
+ Puppet::Provider::Confine::Feature.new("/some/file").values.should be_instance_of(Array)
+ end
+
+ describe "when testing values" do
+ before do
+ @features = mock 'features'
+ Puppet.stubs(:features).returns @features
+ @confine = Puppet::Provider::Confine::Feature.new("myfeature")
+ @confine.label = "eh"
end
- it "should require a value" do
- lambda { Puppet::Provider::Confine::Feature.new }.should raise_error(ArgumentError)
+ it "should use the Puppet features instance to test validity" do
+ @features.expects(:myfeature?)
+ @confine.valid?
end
- it "should always convert values to an array" do
- Puppet::Provider::Confine::Feature.new("/some/file").values.should be_instance_of(Array)
+ it "should return true if the feature is present" do
+ @features.expects(:myfeature?).returns true
+ @confine.pass?("myfeature").should be_true
end
- describe "when testing values" do
- before do
- @features = mock 'features'
- Puppet.stubs(:features).returns @features
- @confine = Puppet::Provider::Confine::Feature.new("myfeature")
- @confine.label = "eh"
- end
-
- it "should use the Puppet features instance to test validity" do
- @features.expects(:myfeature?)
- @confine.valid?
- end
-
- it "should return true if the feature is present" do
- @features.expects(:myfeature?).returns true
- @confine.pass?("myfeature").should be_true
- end
-
- it "should return false if the value is false" do
- @features.expects(:myfeature?).returns false
- @confine.pass?("myfeature").should be_false
- end
-
- it "should log that a feature is missing" do
- @confine.message("myfeat").should be_include("missing")
- end
+ it "should return false if the value is false" do
+ @features.expects(:myfeature?).returns false
+ @confine.pass?("myfeature").should be_false
end
- it "should summarize multiple instances by returning a flattened array of all missing features" do
- confines = []
- confines << Puppet::Provider::Confine::Feature.new(%w{one two})
- confines << Puppet::Provider::Confine::Feature.new(%w{two})
- confines << Puppet::Provider::Confine::Feature.new(%w{three four})
+ it "should log that a feature is missing" do
+ @confine.message("myfeat").should be_include("missing")
+ end
+ end
- features = mock 'feature'
- features.stub_everything
- Puppet.stubs(:features).returns features
+ it "should summarize multiple instances by returning a flattened array of all missing features" do
+ confines = []
+ confines << Puppet::Provider::Confine::Feature.new(%w{one two})
+ confines << Puppet::Provider::Confine::Feature.new(%w{two})
+ confines << Puppet::Provider::Confine::Feature.new(%w{three four})
- Puppet::Provider::Confine::Feature.summarize(confines).sort.should == %w{one two three four}.sort
- end
+ features = mock 'feature'
+ features.stub_everything
+ Puppet.stubs(:features).returns features
+
+ Puppet::Provider::Confine::Feature.summarize(confines).sort.should == %w{one two three four}.sort
+ end
end
diff --git a/spec/unit/provider/confine/true_spec.rb b/spec/unit/provider/confine/true_spec.rb
index 2675afe..23041e6 100755
--- a/spec/unit/provider/confine/true_spec.rb
+++ b/spec/unit/provider/confine/true_spec.rb
@@ -5,49 +5,49 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/provider/confine/true'
describe Puppet::Provider::Confine::True do
- it "should be named :true" do
- Puppet::Provider::Confine::True.name.should == :true
+ it "should be named :true" do
+ Puppet::Provider::Confine::True.name.should == :true
+ end
+
+ it "should require a value" do
+ lambda { Puppet::Provider::Confine::True.new }.should raise_error(ArgumentError)
+ end
+
+ describe "when testing values" do
+ before do
+ @confine = Puppet::Provider::Confine::True.new("foo")
+ @confine.label = "eh"
end
- it "should require a value" do
- lambda { Puppet::Provider::Confine::True.new }.should raise_error(ArgumentError)
+ it "should use the 'pass?' method to test validity" do
+ @confine.expects(:pass?).with("foo")
+ @confine.valid?
end
- describe "when testing values" do
- before do
- @confine = Puppet::Provider::Confine::True.new("foo")
- @confine.label = "eh"
- end
-
- it "should use the 'pass?' method to test validity" do
- @confine.expects(:pass?).with("foo")
- @confine.valid?
- end
-
- it "should return true if the value is not false" do
- @confine.pass?("else").should be_true
- end
-
- it "should return false if the value is false" do
- @confine.pass?(nil).should be_false
- end
+ it "should return true if the value is not false" do
+ @confine.pass?("else").should be_true
+ end
- it "should produce the message that a value is false" do
- @confine.message("eh").should be_include("false")
- end
+ it "should return false if the value is false" do
+ @confine.pass?(nil).should be_false
end
- it "should produce the number of false values when asked for a summary" do
- @confine = Puppet::Provider::Confine::True.new %w{one two three four}
- @confine.expects(:pass?).times(4).returns(true).returns(false).returns(true).returns(false)
- @confine.summary.should == 2
+ it "should produce the message that a value is false" do
+ @confine.message("eh").should be_include("false")
end
+ end
- it "should summarize multiple instances by summing their summaries" do
- c1 = mock '1', :summary => 1
- c2 = mock '2', :summary => 2
- c3 = mock '3', :summary => 3
+ it "should produce the number of false values when asked for a summary" do
+ @confine = Puppet::Provider::Confine::True.new %w{one two three four}
+ @confine.expects(:pass?).times(4).returns(true).returns(false).returns(true).returns(false)
+ @confine.summary.should == 2
+ end
- Puppet::Provider::Confine::True.summarize([c1, c2, c3]).should == 6
- end
+ it "should summarize multiple instances by summing their summaries" do
+ c1 = mock '1', :summary => 1
+ c2 = mock '2', :summary => 2
+ c3 = mock '3', :summary => 3
+
+ Puppet::Provider::Confine::True.summarize([c1, c2, c3]).should == 6
+ end
end
diff --git a/spec/unit/provider/confine/variable_spec.rb b/spec/unit/provider/confine/variable_spec.rb
index e554ac0..eda2dd4 100755
--- a/spec/unit/provider/confine/variable_spec.rb
+++ b/spec/unit/provider/confine/variable_spec.rb
@@ -5,103 +5,103 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/provider/confine/variable'
describe Puppet::Provider::Confine::Variable do
- it "should be named :variable" do
- Puppet::Provider::Confine::Variable.name.should == :variable
+ it "should be named :variable" do
+ Puppet::Provider::Confine::Variable.name.should == :variable
+ end
+
+ it "should require a value" do
+ lambda { Puppet::Provider::Confine::Variable.new }.should raise_error(ArgumentError)
+ end
+
+ it "should always convert values to an array" do
+ Puppet::Provider::Confine::Variable.new("/some/file").values.should be_instance_of(Array)
+ end
+
+ it "should have an accessor for its name" do
+ Puppet::Provider::Confine::Variable.new(:bar).should respond_to(:name)
+ end
+
+ describe "when testing values" do
+ before do
+ @confine = Puppet::Provider::Confine::Variable.new("foo")
+ @confine.name = :myvar
end
- it "should require a value" do
- lambda { Puppet::Provider::Confine::Variable.new }.should raise_error(ArgumentError)
+ it "should use settings if the variable name is a valid setting" do
+ Puppet.settings.expects(:valid?).with(:myvar).returns true
+ Puppet.settings.expects(:value).with(:myvar).returns "foo"
+ @confine.valid?
end
- it "should always convert values to an array" do
- Puppet::Provider::Confine::Variable.new("/some/file").values.should be_instance_of(Array)
+ it "should use Facter if the variable name is not a valid setting" do
+ Puppet.settings.expects(:valid?).with(:myvar).returns false
+ Facter.expects(:value).with(:myvar).returns "foo"
+ @confine.valid?
end
- it "should have an accessor for its name" do
- Puppet::Provider::Confine::Variable.new(:bar).should respond_to(:name)
+ it "should be valid if the value matches the facter value" do
+ @confine.expects(:test_value).returns "foo"
+
+ @confine.should be_valid
+ end
+
+ it "should return false if the value does not match the facter value" do
+ @confine.expects(:test_value).returns "fee"
+
+ @confine.should_not be_valid
+ end
+
+ it "should be case insensitive" do
+ @confine.expects(:test_value).returns "FOO"
+
+ @confine.should be_valid
end
- describe "when testing values" do
- before do
- @confine = Puppet::Provider::Confine::Variable.new("foo")
- @confine.name = :myvar
- end
-
- it "should use settings if the variable name is a valid setting" do
- Puppet.settings.expects(:valid?).with(:myvar).returns true
- Puppet.settings.expects(:value).with(:myvar).returns "foo"
- @confine.valid?
- end
-
- it "should use Facter if the variable name is not a valid setting" do
- Puppet.settings.expects(:valid?).with(:myvar).returns false
- Facter.expects(:value).with(:myvar).returns "foo"
- @confine.valid?
- end
-
- it "should be valid if the value matches the facter value" do
- @confine.expects(:test_value).returns "foo"
-
- @confine.should be_valid
- end
-
- it "should return false if the value does not match the facter value" do
- @confine.expects(:test_value).returns "fee"
-
- @confine.should_not be_valid
- end
-
- it "should be case insensitive" do
- @confine.expects(:test_value).returns "FOO"
-
- @confine.should be_valid
- end
-
- it "should not care whether the value is a string or symbol" do
- @confine.expects(:test_value).returns "FOO"
-
- @confine.should be_valid
- end
-
- it "should produce a message that the fact value is not correct" do
- @confine = Puppet::Provider::Confine::Variable.new(%w{bar bee})
- @confine.name = "eh"
- message = @confine.message("value")
- message.should be_include("facter")
- message.should be_include("bar,bee")
- end
-
- it "should be valid if the test value matches any of the provided values" do
- @confine = Puppet::Provider::Confine::Variable.new(%w{bar bee})
- @confine.expects(:test_value).returns "bee"
- @confine.should be_valid
- end
+ it "should not care whether the value is a string or symbol" do
+ @confine.expects(:test_value).returns "FOO"
+
+ @confine.should be_valid
+ end
+
+ it "should produce a message that the fact value is not correct" do
+ @confine = Puppet::Provider::Confine::Variable.new(%w{bar bee})
+ @confine.name = "eh"
+ message = @confine.message("value")
+ message.should be_include("facter")
+ message.should be_include("bar,bee")
end
- describe "when summarizing multiple instances" do
- it "should return a hash of failing variables and their values" do
- c1 = Puppet::Provider::Confine::Variable.new("one")
- c1.name = "uno"
- c1.expects(:valid?).returns false
- c2 = Puppet::Provider::Confine::Variable.new("two")
- c2.name = "dos"
- c2.expects(:valid?).returns true
- c3 = Puppet::Provider::Confine::Variable.new("three")
- c3.name = "tres"
- c3.expects(:valid?).returns false
-
- Puppet::Provider::Confine::Variable.summarize([c1, c2, c3]).should == {"uno" => %w{one}, "tres" => %w{three}}
- end
-
- it "should combine the values of multiple confines with the same fact" do
- c1 = Puppet::Provider::Confine::Variable.new("one")
- c1.name = "uno"
- c1.expects(:valid?).returns false
- c2 = Puppet::Provider::Confine::Variable.new("two")
- c2.name = "uno"
- c2.expects(:valid?).returns false
-
- Puppet::Provider::Confine::Variable.summarize([c1, c2]).should == {"uno" => %w{one two}}
- end
+ it "should be valid if the test value matches any of the provided values" do
+ @confine = Puppet::Provider::Confine::Variable.new(%w{bar bee})
+ @confine.expects(:test_value).returns "bee"
+ @confine.should be_valid
+ end
+ end
+
+ describe "when summarizing multiple instances" do
+ it "should return a hash of failing variables and their values" do
+ c1 = Puppet::Provider::Confine::Variable.new("one")
+ c1.name = "uno"
+ c1.expects(:valid?).returns false
+ c2 = Puppet::Provider::Confine::Variable.new("two")
+ c2.name = "dos"
+ c2.expects(:valid?).returns true
+ c3 = Puppet::Provider::Confine::Variable.new("three")
+ c3.name = "tres"
+ c3.expects(:valid?).returns false
+
+ Puppet::Provider::Confine::Variable.summarize([c1, c2, c3]).should == {"uno" => %w{one}, "tres" => %w{three}}
+ end
+
+ it "should combine the values of multiple confines with the same fact" do
+ c1 = Puppet::Provider::Confine::Variable.new("one")
+ c1.name = "uno"
+ c1.expects(:valid?).returns false
+ c2 = Puppet::Provider::Confine::Variable.new("two")
+ c2.name = "uno"
+ c2.expects(:valid?).returns false
+
+ Puppet::Provider::Confine::Variable.summarize([c1, c2]).should == {"uno" => %w{one two}}
end
+ end
end
diff --git a/spec/unit/provider/confine_collection_spec.rb b/spec/unit/provider/confine_collection_spec.rb
index 444281c..e5f7f03 100755
--- a/spec/unit/provider/confine_collection_spec.rb
+++ b/spec/unit/provider/confine_collection_spec.rb
@@ -5,130 +5,130 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/provider/confine_collection'
describe Puppet::Provider::ConfineCollection do
- it "should be able to add confines" do
- Puppet::Provider::ConfineCollection.new("label").should respond_to(:confine)
- end
+ it "should be able to add confines" do
+ Puppet::Provider::ConfineCollection.new("label").should respond_to(:confine)
+ end
+
+ it "should require a label at initialization" do
+ lambda { Puppet::Provider::ConfineCollection.new }.should raise_error(ArgumentError)
+ end
+
+ it "should make its label available" do
+ Puppet::Provider::ConfineCollection.new("mylabel").label.should == "mylabel"
+ end
+
+ describe "when creating confine instances" do
+ it "should create an instance of the named test with the provided values" do
+ test_class = mock 'test_class'
+ test_class.expects(:new).with(%w{my values}).returns(stub('confine', :label= => nil))
+ Puppet::Provider::Confine.expects(:test).with(:foo).returns test_class
- it "should require a label at initialization" do
- lambda { Puppet::Provider::ConfineCollection.new }.should raise_error(ArgumentError)
+ Puppet::Provider::ConfineCollection.new("label").confine :foo => %w{my values}
end
- it "should make its label available" do
- Puppet::Provider::ConfineCollection.new("mylabel").label.should == "mylabel"
+ it "should copy its label to the confine instance" do
+ confine = mock 'confine'
+ test_class = mock 'test_class'
+ test_class.expects(:new).returns confine
+ Puppet::Provider::Confine.expects(:test).returns test_class
+
+ confine.expects(:label=).with("label")
+
+ Puppet::Provider::ConfineCollection.new("label").confine :foo => %w{my values}
end
- describe "when creating confine instances" do
- it "should create an instance of the named test with the provided values" do
- test_class = mock 'test_class'
- test_class.expects(:new).with(%w{my values}).returns(stub('confine', :label= => nil))
- Puppet::Provider::Confine.expects(:test).with(:foo).returns test_class
-
- Puppet::Provider::ConfineCollection.new("label").confine :foo => %w{my values}
- end
-
- it "should copy its label to the confine instance" do
- confine = mock 'confine'
- test_class = mock 'test_class'
- test_class.expects(:new).returns confine
- Puppet::Provider::Confine.expects(:test).returns test_class
-
- confine.expects(:label=).with("label")
-
- Puppet::Provider::ConfineCollection.new("label").confine :foo => %w{my values}
- end
-
- describe "and the test cannot be found" do
- it "should create a Facter test with the provided values and set the name to the test name" do
- confine = Puppet::Provider::Confine.test(:variable).new(%w{my values})
- confine.expects(:name=).with(:foo)
- confine.class.expects(:new).with(%w{my values}).returns confine
- Puppet::Provider::ConfineCollection.new("label").confine(:foo => %w{my values})
- end
- end
-
- describe "and the 'for_binary' option was provided" do
- it "should mark the test as a binary confine" do
- confine = Puppet::Provider::Confine.test(:exists).new(:bar)
- confine.expects(:for_binary=).with true
- Puppet::Provider::Confine.test(:exists).expects(:new).with(:bar).returns confine
- Puppet::Provider::ConfineCollection.new("label").confine :exists => :bar, :for_binary => true
- end
- end
+ describe "and the test cannot be found" do
+ it "should create a Facter test with the provided values and set the name to the test name" do
+ confine = Puppet::Provider::Confine.test(:variable).new(%w{my values})
+ confine.expects(:name=).with(:foo)
+ confine.class.expects(:new).with(%w{my values}).returns confine
+ Puppet::Provider::ConfineCollection.new("label").confine(:foo => %w{my values})
+ end
end
- it "should be valid if no confines are present" do
- Puppet::Provider::ConfineCollection.new("label").should be_valid
+ describe "and the 'for_binary' option was provided" do
+ it "should mark the test as a binary confine" do
+ confine = Puppet::Provider::Confine.test(:exists).new(:bar)
+ confine.expects(:for_binary=).with true
+ Puppet::Provider::Confine.test(:exists).expects(:new).with(:bar).returns confine
+ Puppet::Provider::ConfineCollection.new("label").confine :exists => :bar, :for_binary => true
+ end
end
+ end
- it "should be valid if all confines pass" do
- c1 = stub 'c1', :valid? => true, :label= => nil
- c2 = stub 'c2', :valid? => true, :label= => nil
+ it "should be valid if no confines are present" do
+ Puppet::Provider::ConfineCollection.new("label").should be_valid
+ end
- Puppet::Provider::Confine.test(:true).expects(:new).returns(c1)
- Puppet::Provider::Confine.test(:false).expects(:new).returns(c2)
+ it "should be valid if all confines pass" do
+ c1 = stub 'c1', :valid? => true, :label= => nil
+ c2 = stub 'c2', :valid? => true, :label= => nil
- confiner = Puppet::Provider::ConfineCollection.new("label")
- confiner.confine :true => :bar, :false => :bee
+ Puppet::Provider::Confine.test(:true).expects(:new).returns(c1)
+ Puppet::Provider::Confine.test(:false).expects(:new).returns(c2)
- confiner.should be_valid
- end
+ confiner = Puppet::Provider::ConfineCollection.new("label")
+ confiner.confine :true => :bar, :false => :bee
- it "should not be valid if any confines fail" do
- c1 = stub 'c1', :valid? => true, :label= => nil
- c2 = stub 'c2', :valid? => false, :label= => nil
+ confiner.should be_valid
+ end
- Puppet::Provider::Confine.test(:true).expects(:new).returns(c1)
- Puppet::Provider::Confine.test(:false).expects(:new).returns(c2)
+ it "should not be valid if any confines fail" do
+ c1 = stub 'c1', :valid? => true, :label= => nil
+ c2 = stub 'c2', :valid? => false, :label= => nil
- confiner = Puppet::Provider::ConfineCollection.new("label")
- confiner.confine :true => :bar, :false => :bee
+ Puppet::Provider::Confine.test(:true).expects(:new).returns(c1)
+ Puppet::Provider::Confine.test(:false).expects(:new).returns(c2)
- confiner.should_not be_valid
- end
+ confiner = Puppet::Provider::ConfineCollection.new("label")
+ confiner.confine :true => :bar, :false => :bee
- describe "when providing a summary" do
- before do
- @confiner = Puppet::Provider::ConfineCollection.new("label")
- end
+ confiner.should_not be_valid
+ end
- it "should return a hash" do
- @confiner.summary.should be_instance_of(Hash)
- end
+ describe "when providing a summary" do
+ before do
+ @confiner = Puppet::Provider::ConfineCollection.new("label")
+ end
- it "should return an empty hash if the confiner is valid" do
- @confiner.summary.should == {}
- end
+ it "should return a hash" do
+ @confiner.summary.should be_instance_of(Hash)
+ end
- it "should add each test type's summary to the hash" do
- @confiner.confine :true => :bar, :false => :bee
- Puppet::Provider::Confine.test(:true).expects(:summarize).returns :tsumm
- Puppet::Provider::Confine.test(:false).expects(:summarize).returns :fsumm
+ it "should return an empty hash if the confiner is valid" do
+ @confiner.summary.should == {}
+ end
- @confiner.summary.should == {:true => :tsumm, :false => :fsumm}
- end
+ it "should add each test type's summary to the hash" do
+ @confiner.confine :true => :bar, :false => :bee
+ Puppet::Provider::Confine.test(:true).expects(:summarize).returns :tsumm
+ Puppet::Provider::Confine.test(:false).expects(:summarize).returns :fsumm
- it "should not include tests that return 0" do
- @confiner.confine :true => :bar, :false => :bee
- Puppet::Provider::Confine.test(:true).expects(:summarize).returns 0
- Puppet::Provider::Confine.test(:false).expects(:summarize).returns :fsumm
+ @confiner.summary.should == {:true => :tsumm, :false => :fsumm}
+ end
- @confiner.summary.should == {:false => :fsumm}
- end
+ it "should not include tests that return 0" do
+ @confiner.confine :true => :bar, :false => :bee
+ Puppet::Provider::Confine.test(:true).expects(:summarize).returns 0
+ Puppet::Provider::Confine.test(:false).expects(:summarize).returns :fsumm
- it "should not include tests that return empty arrays" do
- @confiner.confine :true => :bar, :false => :bee
- Puppet::Provider::Confine.test(:true).expects(:summarize).returns []
- Puppet::Provider::Confine.test(:false).expects(:summarize).returns :fsumm
+ @confiner.summary.should == {:false => :fsumm}
+ end
+
+ it "should not include tests that return empty arrays" do
+ @confiner.confine :true => :bar, :false => :bee
+ Puppet::Provider::Confine.test(:true).expects(:summarize).returns []
+ Puppet::Provider::Confine.test(:false).expects(:summarize).returns :fsumm
- @confiner.summary.should == {:false => :fsumm}
- end
+ @confiner.summary.should == {:false => :fsumm}
+ end
- it "should not include tests that return empty hashes" do
- @confiner.confine :true => :bar, :false => :bee
- Puppet::Provider::Confine.test(:true).expects(:summarize).returns({})
- Puppet::Provider::Confine.test(:false).expects(:summarize).returns :fsumm
+ it "should not include tests that return empty hashes" do
+ @confiner.confine :true => :bar, :false => :bee
+ Puppet::Provider::Confine.test(:true).expects(:summarize).returns({})
+ Puppet::Provider::Confine.test(:false).expects(:summarize).returns :fsumm
- @confiner.summary.should == {:false => :fsumm}
- end
+ @confiner.summary.should == {:false => :fsumm}
end
+ end
end
diff --git a/spec/unit/provider/confine_spec.rb b/spec/unit/provider/confine_spec.rb
index 2e06372..1fa7f3d 100755
--- a/spec/unit/provider/confine_spec.rb
+++ b/spec/unit/provider/confine_spec.rb
@@ -5,74 +5,74 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/provider/confine'
describe Puppet::Provider::Confine do
- it "should require a value" do
- lambda { Puppet::Provider::Confine.new }.should raise_error(ArgumentError)
+ it "should require a value" do
+ lambda { Puppet::Provider::Confine.new }.should raise_error(ArgumentError)
+ end
+
+ it "should always convert values to an array" do
+ Puppet::Provider::Confine.new("/some/file").values.should be_instance_of(Array)
+ end
+
+ it "should have a 'true' test" do
+ Puppet::Provider::Confine.test(:true).should be_instance_of(Class)
+ end
+
+ it "should have a 'false' test" do
+ Puppet::Provider::Confine.test(:false).should be_instance_of(Class)
+ end
+
+ it "should have a 'feature' test" do
+ Puppet::Provider::Confine.test(:feature).should be_instance_of(Class)
+ end
+
+ it "should have an 'exists' test" do
+ Puppet::Provider::Confine.test(:exists).should be_instance_of(Class)
+ end
+
+ it "should have a 'variable' test" do
+ Puppet::Provider::Confine.test(:variable).should be_instance_of(Class)
+ end
+
+ describe "when testing all values" do
+ before do
+ @confine = Puppet::Provider::Confine.new(%w{a b c})
+ @confine.label = "foo"
end
- it "should always convert values to an array" do
- Puppet::Provider::Confine.new("/some/file").values.should be_instance_of(Array)
+ it "should be invalid if any values fail" do
+ @confine.stubs(:pass?).returns true
+ @confine.expects(:pass?).with("b").returns false
+ @confine.should_not be_valid
end
- it "should have a 'true' test" do
- Puppet::Provider::Confine.test(:true).should be_instance_of(Class)
+ it "should be valid if all values pass" do
+ @confine.stubs(:pass?).returns true
+ @confine.should be_valid
end
- it "should have a 'false' test" do
- Puppet::Provider::Confine.test(:false).should be_instance_of(Class)
+ it "should short-cut at the first failing value" do
+ @confine.expects(:pass?).once.returns false
+ @confine.valid?
end
- it "should have a 'feature' test" do
- Puppet::Provider::Confine.test(:feature).should be_instance_of(Class)
+ it "should log failing confines with the label and message" do
+ @confine.stubs(:pass?).returns false
+ @confine.expects(:message).returns "My message"
+ @confine.expects(:label).returns "Mylabel"
+ Puppet.expects(:debug).with("Mylabel: My message")
+ @confine.valid?
end
+ end
- it "should have an 'exists' test" do
- Puppet::Provider::Confine.test(:exists).should be_instance_of(Class)
- end
-
- it "should have a 'variable' test" do
- Puppet::Provider::Confine.test(:variable).should be_instance_of(Class)
- end
-
- describe "when testing all values" do
- before do
- @confine = Puppet::Provider::Confine.new(%w{a b c})
- @confine.label = "foo"
- end
-
- it "should be invalid if any values fail" do
- @confine.stubs(:pass?).returns true
- @confine.expects(:pass?).with("b").returns false
- @confine.should_not be_valid
- end
-
- it "should be valid if all values pass" do
- @confine.stubs(:pass?).returns true
- @confine.should be_valid
- end
-
- it "should short-cut at the first failing value" do
- @confine.expects(:pass?).once.returns false
- @confine.valid?
- end
-
- it "should log failing confines with the label and message" do
- @confine.stubs(:pass?).returns false
- @confine.expects(:message).returns "My message"
- @confine.expects(:label).returns "Mylabel"
- Puppet.expects(:debug).with("Mylabel: My message")
- @confine.valid?
- end
- end
-
- describe "when testing the result of the values" do
- before { @confine = Puppet::Provider::Confine.new(%w{a b c d}) }
+ describe "when testing the result of the values" do
+ before { @confine = Puppet::Provider::Confine.new(%w{a b c d}) }
- it "should return an array with the result of the test for each value" do
- @confine.stubs(:pass?).returns true
- @confine.expects(:pass?).with("b").returns false
- @confine.expects(:pass?).with("d").returns false
+ it "should return an array with the result of the test for each value" do
+ @confine.stubs(:pass?).returns true
+ @confine.expects(:pass?).with("b").returns false
+ @confine.expects(:pass?).with("d").returns false
- @confine.result.should == [true, false, true, false]
- end
+ @confine.result.should == [true, false, true, false]
end
+ end
end
diff --git a/spec/unit/provider/confiner_spec.rb b/spec/unit/provider/confiner_spec.rb
index 0a0d67f..d513c72 100755
--- a/spec/unit/provider/confiner_spec.rb
+++ b/spec/unit/provider/confiner_spec.rb
@@ -5,59 +5,59 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/provider/confiner'
describe Puppet::Provider::Confiner do
+ before do
+ @object = Object.new
+ @object.extend(Puppet::Provider::Confiner)
+ end
+
+ it "should have a method for defining confines" do
+ @object.should respond_to(:confine)
+ end
+
+ it "should have a method for returning its confine collection" do
+ @object.should respond_to(:confine_collection)
+ end
+
+ it "should have a method for testing suitability" do
+ @object.should respond_to(:suitable?)
+ end
+
+ it "should delegate its confine method to its confine collection" do
+ coll = mock 'collection'
+ @object.stubs(:confine_collection).returns coll
+ coll.expects(:confine).with(:foo => :bar, :bee => :baz)
+ @object.confine(:foo => :bar, :bee => :baz)
+ end
+
+ it "should create a new confine collection if one does not exist" do
+ Puppet::Provider::ConfineCollection.expects(:new).with("mylabel").returns "mycoll"
+ @object.expects(:to_s).returns "mylabel"
+ @object.confine_collection.should == "mycoll"
+ end
+
+ it "should reuse the confine collection" do
+ @object.confine_collection.should equal(@object.confine_collection)
+ end
+
+ describe "when testing suitability" do
before do
- @object = Object.new
- @object.extend(Puppet::Provider::Confiner)
+ @coll = mock 'collection'
+ @object.stubs(:confine_collection).returns @coll
end
- it "should have a method for defining confines" do
- @object.should respond_to(:confine)
+ it "should return true if the confine collection is valid" do
+ @coll.expects(:valid?).returns true
+ @object.should be_suitable
end
- it "should have a method for returning its confine collection" do
- @object.should respond_to(:confine_collection)
+ it "should return false if the confine collection is invalid" do
+ @coll.expects(:valid?).returns false
+ @object.should_not be_suitable
end
- it "should have a method for testing suitability" do
- @object.should respond_to(:suitable?)
- end
-
- it "should delegate its confine method to its confine collection" do
- coll = mock 'collection'
- @object.stubs(:confine_collection).returns coll
- coll.expects(:confine).with(:foo => :bar, :bee => :baz)
- @object.confine(:foo => :bar, :bee => :baz)
- end
-
- it "should create a new confine collection if one does not exist" do
- Puppet::Provider::ConfineCollection.expects(:new).with("mylabel").returns "mycoll"
- @object.expects(:to_s).returns "mylabel"
- @object.confine_collection.should == "mycoll"
- end
-
- it "should reuse the confine collection" do
- @object.confine_collection.should equal(@object.confine_collection)
- end
-
- describe "when testing suitability" do
- before do
- @coll = mock 'collection'
- @object.stubs(:confine_collection).returns @coll
- end
-
- it "should return true if the confine collection is valid" do
- @coll.expects(:valid?).returns true
- @object.should be_suitable
- end
-
- it "should return false if the confine collection is invalid" do
- @coll.expects(:valid?).returns false
- @object.should_not be_suitable
- end
-
- it "should return the summary of the confine collection if a long result is asked for" do
- @coll.expects(:summary).returns "myresult"
- @object.suitable?(false).should == "myresult"
- end
+ it "should return the summary of the confine collection if a long result is asked for" do
+ @coll.expects(:summary).returns "myresult"
+ @object.suitable?(false).should == "myresult"
end
+ end
end
diff --git a/spec/unit/provider/group/groupadd_spec.rb b/spec/unit/provider/group/groupadd_spec.rb
index fb4b811..33d9acd 100755
--- a/spec/unit/provider/group/groupadd_spec.rb
+++ b/spec/unit/provider/group/groupadd_spec.rb
@@ -5,27 +5,27 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
provider_class = Puppet::Type.type(:group).provider(:groupadd)
describe provider_class do
- before do
- @resource = stub("resource", :name => "mygroup")
- @provider = provider_class.new(@resource)
- end
+ before do
+ @resource = stub("resource", :name => "mygroup")
+ @provider = provider_class.new(@resource)
+ end
- # #1360
- it "should add -o when allowdupe is enabled and the group is being created" do
- @resource.stubs(:should).returns "fakeval"
- @resource.stubs(:[]).returns "fakeval"
- @resource.expects(:allowdupe?).returns true
- @provider.expects(:execute).with { |args| args.include?("-o") }
+ # #1360
+ it "should add -o when allowdupe is enabled and the group is being created" do
+ @resource.stubs(:should).returns "fakeval"
+ @resource.stubs(:[]).returns "fakeval"
+ @resource.expects(:allowdupe?).returns true
+ @provider.expects(:execute).with { |args| args.include?("-o") }
- @provider.create
- end
+ @provider.create
+ end
- it "should add -o when allowdupe is enabled and the gid is being modified" do
- @resource.stubs(:should).returns "fakeval"
- @resource.stubs(:[]).returns "fakeval"
- @resource.expects(:allowdupe?).returns true
- @provider.expects(:execute).with { |args| args.include?("-o") }
+ it "should add -o when allowdupe is enabled and the gid is being modified" do
+ @resource.stubs(:should).returns "fakeval"
+ @resource.stubs(:[]).returns "fakeval"
+ @resource.expects(:allowdupe?).returns true
+ @provider.expects(:execute).with { |args| args.include?("-o") }
- @provider.gid = 150
- end
+ @provider.gid = 150
+ end
end
diff --git a/spec/unit/provider/group/ldap_spec.rb b/spec/unit/provider/group/ldap_spec.rb
index ab2bd72..b8c54be 100755
--- a/spec/unit/provider/group/ldap_spec.rb
+++ b/spec/unit/provider/group/ldap_spec.rb
@@ -8,98 +8,98 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
provider_class = Puppet::Type.type(:group).provider(:ldap)
describe provider_class do
- it "should have the Ldap provider class as its baseclass" do
- provider_class.superclass.should equal(Puppet::Provider::Ldap)
+ it "should have the Ldap provider class as its baseclass" do
+ provider_class.superclass.should equal(Puppet::Provider::Ldap)
+ end
+
+ it "should manage :posixGroup objectclass" do
+ provider_class.manager.objectclasses.should == [:posixGroup]
+ end
+
+ it "should use 'ou=Groups' as its relative base" do
+ provider_class.manager.location.should == "ou=Groups"
+ end
+
+ it "should use :cn as its rdn" do
+ provider_class.manager.rdn.should == :cn
+ end
+
+ it "should map :name to 'cn'" do
+ provider_class.manager.ldap_name(:name).should == 'cn'
+ end
+
+ it "should map :gid to 'gidNumber'" do
+ provider_class.manager.ldap_name(:gid).should == 'gidNumber'
+ end
+
+ it "should map :members to 'memberUid', to be used by the user ldap provider" do
+ provider_class.manager.ldap_name(:members).should == 'memberUid'
+ end
+
+ describe "when being created" do
+ before do
+ # So we don't try to actually talk to ldap
+ @connection = mock 'connection'
+ provider_class.manager.stubs(:connect).yields @connection
end
- it "should manage :posixGroup objectclass" do
- provider_class.manager.objectclasses.should == [:posixGroup]
- end
+ describe "with no gid specified" do
+ it "should pick the first available GID after the largest existing GID" do
+ low = {:name=>["luke"], :gid=>["600"]}
+ high = {:name=>["testing"], :gid=>["640"]}
+ provider_class.manager.expects(:search).returns([low, high])
- it "should use 'ou=Groups' as its relative base" do
- provider_class.manager.location.should == "ou=Groups"
- end
+ resource = stub 'resource', :should => %w{whatever}
+ resource.stubs(:should).with(:gid).returns nil
+ resource.stubs(:should).with(:ensure).returns :present
+ instance = provider_class.new(:name => "luke", :ensure => :absent)
+ instance.stubs(:resource).returns resource
- it "should use :cn as its rdn" do
- provider_class.manager.rdn.should == :cn
- end
+ @connection.expects(:add).with { |dn, attrs| attrs["gidNumber"] == ["641"] }
- it "should map :name to 'cn'" do
- provider_class.manager.ldap_name(:name).should == 'cn'
- end
+ instance.create
+ instance.flush
+ end
- it "should map :gid to 'gidNumber'" do
- provider_class.manager.ldap_name(:gid).should == 'gidNumber'
- end
+ it "should pick '501' as its GID if no groups are found" do
+ provider_class.manager.expects(:search).returns nil
+
+ resource = stub 'resource', :should => %w{whatever}
+ resource.stubs(:should).with(:gid).returns nil
+ resource.stubs(:should).with(:ensure).returns :present
+ instance = provider_class.new(:name => "luke", :ensure => :absent)
+ instance.stubs(:resource).returns resource
- it "should map :members to 'memberUid', to be used by the user ldap provider" do
- provider_class.manager.ldap_name(:members).should == 'memberUid'
+ @connection.expects(:add).with { |dn, attrs| attrs["gidNumber"] == ["501"] }
+
+ instance.create
+ instance.flush
+ end
end
+ end
+
+ it "should have a method for converting group names to GIDs" do
+ provider_class.should respond_to(:name2id)
+ end
- describe "when being created" do
- before do
- # So we don't try to actually talk to ldap
- @connection = mock 'connection'
- provider_class.manager.stubs(:connect).yields @connection
- end
-
- describe "with no gid specified" do
- it "should pick the first available GID after the largest existing GID" do
- low = {:name=>["luke"], :gid=>["600"]}
- high = {:name=>["testing"], :gid=>["640"]}
- provider_class.manager.expects(:search).returns([low, high])
-
- resource = stub 'resource', :should => %w{whatever}
- resource.stubs(:should).with(:gid).returns nil
- resource.stubs(:should).with(:ensure).returns :present
- instance = provider_class.new(:name => "luke", :ensure => :absent)
- instance.stubs(:resource).returns resource
-
- @connection.expects(:add).with { |dn, attrs| attrs["gidNumber"] == ["641"] }
-
- instance.create
- instance.flush
- end
-
- it "should pick '501' as its GID if no groups are found" do
- provider_class.manager.expects(:search).returns nil
-
- resource = stub 'resource', :should => %w{whatever}
- resource.stubs(:should).with(:gid).returns nil
- resource.stubs(:should).with(:ensure).returns :present
- instance = provider_class.new(:name => "luke", :ensure => :absent)
- instance.stubs(:resource).returns resource
-
- @connection.expects(:add).with { |dn, attrs| attrs["gidNumber"] == ["501"] }
-
- instance.create
- instance.flush
- end
- end
+ describe "when converting from a group name to GID" do
+ it "should use the ldap manager to look up the GID" do
+ provider_class.manager.expects(:search).with("cn=foo")
+ provider_class.name2id("foo")
end
- it "should have a method for converting group names to GIDs" do
- provider_class.should respond_to(:name2id)
+ it "should return nil if no group is found" do
+ provider_class.manager.expects(:search).with("cn=foo").returns nil
+ provider_class.name2id("foo").should be_nil
+ provider_class.manager.expects(:search).with("cn=bar").returns []
+ provider_class.name2id("bar").should be_nil
end
- describe "when converting from a group name to GID" do
- it "should use the ldap manager to look up the GID" do
- provider_class.manager.expects(:search).with("cn=foo")
- provider_class.name2id("foo")
- end
-
- it "should return nil if no group is found" do
- provider_class.manager.expects(:search).with("cn=foo").returns nil
- provider_class.name2id("foo").should be_nil
- provider_class.manager.expects(:search).with("cn=bar").returns []
- provider_class.name2id("bar").should be_nil
- end
-
- # We shouldn't ever actually have more than one gid, but it doesn't hurt
- # to test for the possibility.
- it "should return the first gid from the first returned group" do
- provider_class.manager.expects(:search).with("cn=foo").returns [{:name => "foo", :gid => [10, 11]}, {:name => :bar, :gid => [20, 21]}]
- provider_class.name2id("foo").should == 10
- end
+ # We shouldn't ever actually have more than one gid, but it doesn't hurt
+ # to test for the possibility.
+ it "should return the first gid from the first returned group" do
+ provider_class.manager.expects(:search).with("cn=foo").returns [{:name => "foo", :gid => [10, 11]}, {:name => :bar, :gid => [20, 21]}]
+ provider_class.name2id("foo").should == 10
end
+ end
end
diff --git a/spec/unit/provider/ldap_spec.rb b/spec/unit/provider/ldap_spec.rb
index 6c58208..588cafc 100755
--- a/spec/unit/provider/ldap_spec.rb
+++ b/spec/unit/provider/ldap_spec.rb
@@ -8,241 +8,241 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/provider/ldap'
describe Puppet::Provider::Ldap do
- before do
- @class = Class.new(Puppet::Provider::Ldap)
+ before do
+ @class = Class.new(Puppet::Provider::Ldap)
+ end
+
+ it "should be able to define its manager" do
+ manager = mock 'manager'
+ Puppet::Util::Ldap::Manager.expects(:new).returns manager
+ @class.stubs :mk_resource_methods
+ manager.expects(:manages).with(:one)
+ @class.manages(:one).should equal(manager)
+ @class.manager.should equal(manager)
+ end
+
+ it "should be able to prefetch instances from ldap" do
+ @class.should respond_to(:prefetch)
+ end
+
+ it "should create its resource getter/setter methods when the manager is defined" do
+ manager = mock 'manager'
+ Puppet::Util::Ldap::Manager.expects(:new).returns manager
+ @class.expects :mk_resource_methods
+ manager.stubs(:manages)
+ @class.manages(:one).should equal(manager)
+ end
+
+ it "should have an instances method" do
+ @class.should respond_to(:instances)
+ end
+
+ describe "when providing a list of instances" do
+ it "should convert all results returned from the manager's :search method into provider instances" do
+ manager = mock 'manager'
+ @class.stubs(:manager).returns manager
+
+ manager.expects(:search).returns %w{one two three}
+
+ @class.expects(:new).with("one").returns(1)
+ @class.expects(:new).with("two").returns(2)
+ @class.expects(:new).with("three").returns(3)
+
+ @class.instances.should == [1,2,3]
end
+ end
- it "should be able to define its manager" do
- manager = mock 'manager'
- Puppet::Util::Ldap::Manager.expects(:new).returns manager
- @class.stubs :mk_resource_methods
- manager.expects(:manages).with(:one)
- @class.manages(:one).should equal(manager)
- @class.manager.should equal(manager)
- end
+ it "should have a prefetch method" do
+ @class.should respond_to(:prefetch)
+ end
- it "should be able to prefetch instances from ldap" do
- @class.should respond_to(:prefetch)
- end
+ describe "when prefetching" do
+ before do
+ @manager = mock 'manager'
+ @class.stubs(:manager).returns @manager
- it "should create its resource getter/setter methods when the manager is defined" do
- manager = mock 'manager'
- Puppet::Util::Ldap::Manager.expects(:new).returns manager
- @class.expects :mk_resource_methods
- manager.stubs(:manages)
- @class.manages(:one).should equal(manager)
- end
+ @resource = mock 'resource'
- it "should have an instances method" do
- @class.should respond_to(:instances)
+ @resources = {"one" => @resource}
end
- describe "when providing a list of instances" do
- it "should convert all results returned from the manager's :search method into provider instances" do
- manager = mock 'manager'
- @class.stubs(:manager).returns manager
-
- manager.expects(:search).returns %w{one two three}
+ it "should find an entry for each passed resource" do
+ @manager.expects(:find).with("one").returns nil
- @class.expects(:new).with("one").returns(1)
- @class.expects(:new).with("two").returns(2)
- @class.expects(:new).with("three").returns(3)
-
- @class.instances.should == [1,2,3]
- end
- end
-
- it "should have a prefetch method" do
- @class.should respond_to(:prefetch)
+ @class.stubs(:new)
+ @resource.stubs(:provider=)
+ @class.prefetch(@resources)
end
- describe "when prefetching" do
- before do
- @manager = mock 'manager'
- @class.stubs(:manager).returns @manager
+ describe "resources that do not exist" do
+ it "should create a provider with :ensure => :absent" do
+ result = mock 'result'
+ @manager.expects(:find).with("one").returns nil
- @resource = mock 'resource'
+ @class.expects(:new).with(:ensure => :absent).returns "myprovider"
- @resources = {"one" => @resource}
- end
+ @resource.expects(:provider=).with("myprovider")
- it "should find an entry for each passed resource" do
- @manager.expects(:find).with("one").returns nil
+ @class.prefetch(@resources)
+ end
+ end
- @class.stubs(:new)
- @resource.stubs(:provider=)
- @class.prefetch(@resources)
- end
+ describe "resources that exist" do
+ it "should create a provider with the results of the find" do
+ @manager.expects(:find).with("one").returns("one" => "two")
- describe "resources that do not exist" do
- it "should create a provider with :ensure => :absent" do
- result = mock 'result'
- @manager.expects(:find).with("one").returns nil
+ @class.expects(:new).with("one" => "two", :ensure => :present).returns "myprovider"
- @class.expects(:new).with(:ensure => :absent).returns "myprovider"
+ @resource.expects(:provider=).with("myprovider")
- @resource.expects(:provider=).with("myprovider")
+ @class.prefetch(@resources)
+ end
- @class.prefetch(@resources)
- end
- end
+ it "should set :ensure to :present in the returned values" do
+ @manager.expects(:find).with("one").returns("one" => "two")
- describe "resources that exist" do
- it "should create a provider with the results of the find" do
- @manager.expects(:find).with("one").returns("one" => "two")
+ @class.expects(:new).with("one" => "two", :ensure => :present).returns "myprovider"
- @class.expects(:new).with("one" => "two", :ensure => :present).returns "myprovider"
+ @resource.expects(:provider=).with("myprovider")
- @resource.expects(:provider=).with("myprovider")
+ @class.prefetch(@resources)
+ end
+ end
+ end
- @class.prefetch(@resources)
- end
+ describe "when being initialized" do
+ it "should fail if no manager has been defined" do
+ lambda { @class.new }.should raise_error(Puppet::DevError)
+ end
- it "should set :ensure to :present in the returned values" do
- @manager.expects(:find).with("one").returns("one" => "two")
+ it "should fail if the manager is invalid" do
+ manager = stub "manager", :valid? => false
+ @class.stubs(:manager).returns manager
+ lambda { @class.new }.should raise_error(Puppet::DevError)
+ end
- @class.expects(:new).with("one" => "two", :ensure => :present).returns "myprovider"
+ describe "with a hash" do
+ before do
+ @manager = stub "manager", :valid? => true
+ @class.stubs(:manager).returns @manager
+
+ @resource_class = mock 'resource_class'
+ @class.stubs(:resource_type).returns @resource_class
+
+ @property_class = stub 'property_class', :array_matching => :all, :superclass => Puppet::Property
+ @resource_class.stubs(:attrclass).with(:one).returns(@property_class)
+ @resource_class.stubs(:valid_parameter?).returns true
+ end
+
+ it "should store a copy of the hash as its ldap_properties" do
+ instance = @class.new(:one => :two)
+ instance.ldap_properties.should == {:one => :two}
+ end
+
+ it "should only store the first value of each value array for those attributes that do not match all values" do
+ @property_class.expects(:array_matching).returns :first
+ instance = @class.new(:one => %w{two three})
+ instance.properties.should == {:one => "two"}
+ end
+
+ it "should store the whole value array for those attributes that match all values" do
+ @property_class.expects(:array_matching).returns :all
+ instance = @class.new(:one => %w{two three})
+ instance.properties.should == {:one => %w{two three}}
+ end
+
+ it "should only use the first value for attributes that are not properties" do
+ # Yay. hackish, but easier than mocking everything.
+ @resource_class.expects(:attrclass).with(:a).returns Puppet::Type.type(:user).attrclass(:name)
+ @property_class.stubs(:array_matching).returns :all
+
+ instance = @class.new(:one => %w{two three}, :a => %w{b c})
+ instance.properties.should == {:one => %w{two three}, :a => "b"}
+ end
+
+ it "should discard any properties not valid in the resource class" do
+ @resource_class.expects(:valid_parameter?).with(:a).returns false
+ @property_class.stubs(:array_matching).returns :all
+
+ instance = @class.new(:one => %w{two three}, :a => %w{b})
+ instance.properties.should == {:one => %w{two three}}
+ end
+ end
+ end
- @resource.expects(:provider=).with("myprovider")
+ describe "when an instance" do
+ before do
+ @manager = stub "manager", :valid? => true
+ @class.stubs(:manager).returns @manager
+ @instance = @class.new
- @class.prefetch(@resources)
- end
- end
+ @property_class = stub 'property_class', :array_matching => :all, :superclass => Puppet::Property
+ @resource_class = stub 'resource_class', :attrclass => @property_class, :valid_parameter? => true, :validproperties => [:one, :two]
+ @class.stubs(:resource_type).returns @resource_class
end
- describe "when being initialized" do
- it "should fail if no manager has been defined" do
- lambda { @class.new }.should raise_error(Puppet::DevError)
- end
+ it "should have a method for creating the ldap entry" do
+ @instance.should respond_to(:create)
+ end
- it "should fail if the manager is invalid" do
- manager = stub "manager", :valid? => false
- @class.stubs(:manager).returns manager
- lambda { @class.new }.should raise_error(Puppet::DevError)
- end
+ it "should have a method for removing the ldap entry" do
+ @instance.should respond_to(:delete)
+ end
- describe "with a hash" do
- before do
- @manager = stub "manager", :valid? => true
- @class.stubs(:manager).returns @manager
+ it "should have a method for returning the class's manager" do
+ @instance.manager.should equal(@manager)
+ end
- @resource_class = mock 'resource_class'
- @class.stubs(:resource_type).returns @resource_class
+ it "should indicate when the ldap entry already exists" do
+ @instance = @class.new(:ensure => :present)
+ @instance.exists?.should be_true
+ end
- @property_class = stub 'property_class', :array_matching => :all, :superclass => Puppet::Property
- @resource_class.stubs(:attrclass).with(:one).returns(@property_class)
- @resource_class.stubs(:valid_parameter?).returns true
- end
+ it "should indicate when the ldap entry does not exist" do
+ @instance = @class.new(:ensure => :absent)
+ @instance.exists?.should be_false
+ end
- it "should store a copy of the hash as its ldap_properties" do
- instance = @class.new(:one => :two)
- instance.ldap_properties.should == {:one => :two}
- end
+ describe "is being flushed" do
+ it "should call the manager's :update method with its name, current attributes, and desired attributes" do
+ @instance.stubs(:name).returns "myname"
+ @instance.stubs(:ldap_properties).returns(:one => :two)
+ @instance.stubs(:properties).returns(:three => :four)
+ @manager.expects(:update).with(@instance.name, {:one => :two}, {:three => :four})
+ @instance.flush
+ end
+ end
- it "should only store the first value of each value array for those attributes that do not match all values" do
- @property_class.expects(:array_matching).returns :first
- instance = @class.new(:one => %w{two three})
- instance.properties.should == {:one => "two"}
- end
-
- it "should store the whole value array for those attributes that match all values" do
- @property_class.expects(:array_matching).returns :all
- instance = @class.new(:one => %w{two three})
- instance.properties.should == {:one => %w{two three}}
- end
+ describe "is being created" do
+ before do
+ @rclass = mock 'resource_class'
+ @rclass.stubs(:validproperties).returns([:one, :two])
+ @resource = mock 'resource'
+ @resource.stubs(:class).returns @rclass
+ @resource.stubs(:should).returns nil
+ @instance.stubs(:resource).returns @resource
+ end
+
+ it "should set its :ensure value to :present" do
+ @instance.create
+ @instance.properties[:ensure].should == :present
+ end
+
+ it "should set all of the other attributes from the resource" do
+ @resource.expects(:should).with(:one).returns "oneval"
+ @resource.expects(:should).with(:two).returns "twoval"
+
+ @instance.create
+ @instance.properties[:one].should == "oneval"
+ @instance.properties[:two].should == "twoval"
+ end
+ end
- it "should only use the first value for attributes that are not properties" do
- # Yay. hackish, but easier than mocking everything.
- @resource_class.expects(:attrclass).with(:a).returns Puppet::Type.type(:user).attrclass(:name)
- @property_class.stubs(:array_matching).returns :all
-
- instance = @class.new(:one => %w{two three}, :a => %w{b c})
- instance.properties.should == {:one => %w{two three}, :a => "b"}
- end
-
- it "should discard any properties not valid in the resource class" do
- @resource_class.expects(:valid_parameter?).with(:a).returns false
- @property_class.stubs(:array_matching).returns :all
-
- instance = @class.new(:one => %w{two three}, :a => %w{b})
- instance.properties.should == {:one => %w{two three}}
- end
- end
- end
-
- describe "when an instance" do
- before do
- @manager = stub "manager", :valid? => true
- @class.stubs(:manager).returns @manager
- @instance = @class.new
-
- @property_class = stub 'property_class', :array_matching => :all, :superclass => Puppet::Property
- @resource_class = stub 'resource_class', :attrclass => @property_class, :valid_parameter? => true, :validproperties => [:one, :two]
- @class.stubs(:resource_type).returns @resource_class
- end
-
- it "should have a method for creating the ldap entry" do
- @instance.should respond_to(:create)
- end
-
- it "should have a method for removing the ldap entry" do
- @instance.should respond_to(:delete)
- end
-
- it "should have a method for returning the class's manager" do
- @instance.manager.should equal(@manager)
- end
-
- it "should indicate when the ldap entry already exists" do
- @instance = @class.new(:ensure => :present)
- @instance.exists?.should be_true
- end
-
- it "should indicate when the ldap entry does not exist" do
- @instance = @class.new(:ensure => :absent)
- @instance.exists?.should be_false
- end
-
- describe "is being flushed" do
- it "should call the manager's :update method with its name, current attributes, and desired attributes" do
- @instance.stubs(:name).returns "myname"
- @instance.stubs(:ldap_properties).returns(:one => :two)
- @instance.stubs(:properties).returns(:three => :four)
- @manager.expects(:update).with(@instance.name, {:one => :two}, {:three => :four})
- @instance.flush
- end
- end
-
- describe "is being created" do
- before do
- @rclass = mock 'resource_class'
- @rclass.stubs(:validproperties).returns([:one, :two])
- @resource = mock 'resource'
- @resource.stubs(:class).returns @rclass
- @resource.stubs(:should).returns nil
- @instance.stubs(:resource).returns @resource
- end
-
- it "should set its :ensure value to :present" do
- @instance.create
- @instance.properties[:ensure].should == :present
- end
-
- it "should set all of the other attributes from the resource" do
- @resource.expects(:should).with(:one).returns "oneval"
- @resource.expects(:should).with(:two).returns "twoval"
-
- @instance.create
- @instance.properties[:one].should == "oneval"
- @instance.properties[:two].should == "twoval"
- end
- end
-
- describe "is being deleted" do
- it "should set its :ensure value to :absent" do
- @instance.delete
- @instance.properties[:ensure].should == :absent
- end
- end
+ describe "is being deleted" do
+ it "should set its :ensure value to :absent" do
+ @instance.delete
+ @instance.properties[:ensure].should == :absent
+ end
end
+ end
end
diff --git a/spec/unit/provider/macauthorization_spec.rb b/spec/unit/provider/macauthorization_spec.rb
index b462be1..d9e04e9 100755
--- a/spec/unit/provider/macauthorization_spec.rb
+++ b/spec/unit/provider/macauthorization_spec.rb
@@ -12,136 +12,136 @@ provider_class = Puppet::Type.type(:macauthorization).provider(:macauthorization
describe provider_class do
- before :each do
- # Create a mock resource
- @resource = stub 'resource'
+ before :each do
+ # Create a mock resource
+ @resource = stub 'resource'
- @authname = "foo.spam.eggs.puppettest"
- @authplist = {}
+ @authname = "foo.spam.eggs.puppettest"
+ @authplist = {}
- @rules = {@authname => @authplist}
+ @rules = {@authname => @authplist}
- authdb = {}
- authdb["rules"] = { "foorule" => "foo" }
- authdb["rights"] = { "fooright" => "foo" }
+ authdb = {}
+ authdb["rules"] = { "foorule" => "foo" }
+ authdb["rights"] = { "fooright" => "foo" }
- # Stub out Plist::parse_xml
- Plist.stubs(:parse_xml).returns(authdb)
+ # Stub out Plist::parse_xml
+ Plist.stubs(:parse_xml).returns(authdb)
- # A catch all; no parameters set
- @resource.stubs(:[]).returns(nil)
+ # A catch all; no parameters set
+ @resource.stubs(:[]).returns(nil)
- # But set name, ensure
- @resource.stubs(:[]).with(:name).returns @authname
- @resource.stubs(:[]).with(:ensure).returns :present
- @resource.stubs(:ref).returns "MacAuthorization[#{@authname}]"
+ # But set name, ensure
+ @resource.stubs(:[]).with(:name).returns @authname
+ @resource.stubs(:[]).with(:ensure).returns :present
+ @resource.stubs(:ref).returns "MacAuthorization[#{@authname}]"
- @provider = provider_class.new(@resource)
- end
+ @provider = provider_class.new(@resource)
+ end
+
+ it "should have a create method" do
+ @provider.should respond_to(:create)
+ end
+
+ it "should have a destroy method" do
+ @provider.should respond_to(:destroy)
+ end
+
+ it "should have an exists? method" do
+ @provider.should respond_to(:exists?)
+ end
- it "should have a create method" do
- @provider.should respond_to(:create)
+ it "should have a flush method" do
+ @provider.should respond_to(:flush)
+ end
+
+ properties = [ :allow_root, :authenticate_user, :auth_class, :comment,
+ :group, :k_of_n, :mechanisms, :rule, :session_owner,
+ :shared, :timeout, :tries, :auth_type ]
+
+ properties.each do |prop|
+ it "should have a #{prop.to_s} method" do
+ @provider.should respond_to(prop.to_s)
end
- it "should have a destroy method" do
- @provider.should respond_to(:destroy)
+ it "should have a #{prop.to_s}= method" do
+ @provider.should respond_to(prop.to_s + "=")
end
+ end
- it "should have an exists? method" do
- @provider.should respond_to(:exists?)
+ describe "when destroying a right" do
+ before :each do
+ @resource.stubs(:[]).with(:auth_type).returns(:right)
end
- it "should have a flush method" do
- @provider.should respond_to(:flush)
+ it "should call the internal method destroy_right" do
+ @provider.expects(:destroy_right)
+ @provider.destroy
+ end
+ it "should call the external command 'security authorizationdb remove @authname" do
+ @provider.expects(:security).with("authorizationdb", :remove, @authname)
+ @provider.destroy
end
+ end
- properties = [ :allow_root, :authenticate_user, :auth_class, :comment,
- :group, :k_of_n, :mechanisms, :rule, :session_owner,
- :shared, :timeout, :tries, :auth_type ]
+ describe "when destroying a rule" do
+ before :each do
+ @resource.stubs(:[]).with(:auth_type).returns(:rule)
+ end
- properties.each do |prop|
- it "should have a #{prop.to_s} method" do
- @provider.should respond_to(prop.to_s)
- end
+ it "should call the internal method destroy_rule" do
+ @provider.expects(:destroy_rule)
+ @provider.destroy
+ end
+ end
- it "should have a #{prop.to_s}= method" do
- @provider.should respond_to(prop.to_s + "=")
- end
+ describe "when flushing a right" do
+ before :each do
+ @resource.stubs(:[]).with(:auth_type).returns(:right)
end
- describe "when destroying a right" do
- before :each do
- @resource.stubs(:[]).with(:auth_type).returns(:right)
- end
-
- it "should call the internal method destroy_right" do
- @provider.expects(:destroy_right)
- @provider.destroy
- end
- it "should call the external command 'security authorizationdb remove @authname" do
- @provider.expects(:security).with("authorizationdb", :remove, @authname)
- @provider.destroy
- end
+ it "should call the internal method flush_right" do
+ @provider.expects(:flush_right)
+ @provider.flush
end
- describe "when destroying a rule" do
- before :each do
- @resource.stubs(:[]).with(:auth_type).returns(:rule)
- end
+ it "should call the internal method set_right" do
+ @provider.expects(:set_right)
+ @provider.flush
+ end
- it "should call the internal method destroy_rule" do
- @provider.expects(:destroy_rule)
- @provider.destroy
- end
+ it "should read and write to the auth database with the right arguments" do
+ @provider.expects(:execute).with { |cmds, args|
+ cmds.include?("read") and
+ cmds.include?(@authname) and
+ args[:combine] == false
+ }.once
+
+ @provider.expects(:execute).with { |cmds, args|
+ cmds.include?("write") and
+ cmds.include?(@authname) and
+ args[:combine] == false and
+ args[:stdinfile] != nil
+ }.once
+ @provider.flush
end
- describe "when flushing a right" do
- before :each do
- @resource.stubs(:[]).with(:auth_type).returns(:right)
- end
-
- it "should call the internal method flush_right" do
- @provider.expects(:flush_right)
- @provider.flush
- end
-
- it "should call the internal method set_right" do
- @provider.expects(:set_right)
- @provider.flush
- end
-
- it "should read and write to the auth database with the right arguments" do
- @provider.expects(:execute).with { |cmds, args|
- cmds.include?("read") and
- cmds.include?(@authname) and
- args[:combine] == false
- }.once
-
- @provider.expects(:execute).with { |cmds, args|
- cmds.include?("write") and
- cmds.include?(@authname) and
- args[:combine] == false and
- args[:stdinfile] != nil
- }.once
- @provider.flush
- end
+ end
+ describe "when flushing a rule" do
+ before :each do
+ @resource.stubs(:[]).with(:auth_type).returns(:rule)
end
- describe "when flushing a rule" do
- before :each do
- @resource.stubs(:[]).with(:auth_type).returns(:rule)
- end
-
- it "should call the internal method flush_rule" do
- @provider.expects(:flush_rule)
- @provider.flush
- end
+ it "should call the internal method flush_rule" do
+ @provider.expects(:flush_rule)
+ @provider.flush
+ end
- it "should call the internal method set_rule" do
- @provider.expects(:set_rule)
- @provider.flush
- end
+ it "should call the internal method set_rule" do
+ @provider.expects(:set_rule)
+ @provider.flush
end
+ end
end
diff --git a/spec/unit/provider/mcx/mcxcontent_spec.rb b/spec/unit/provider/mcx/mcxcontent_spec.rb
index d8f431a..d3fb043 100755
--- a/spec/unit/provider/mcx/mcxcontent_spec.rb
+++ b/spec/unit/provider/mcx/mcxcontent_spec.rb
@@ -25,151 +25,151 @@ provider_class = Puppet::Type.type(:mcx).provider(:mcxcontent)
# describe creates a new ExampleGroup object.
describe provider_class do
- # :each executes before each test.
- # :all executes once for the test group and before :each.
+ # :each executes before each test.
+ # :all executes once for the test group and before :each.
+ before :each do
+ # Create a mock resource
+ @resource = stub 'resource'
+
+ @provider = provider_class.new
+ @attached_to = "/Users/foobar"
+ @ds_path = "/Local/Default/Users/foobar"
+
+ # A catch all; no parameters set
+ @resource.stubs(:[]).returns(nil)
+
+ # But set name, ensure and enable
+ @resource.stubs(:[]).with(:name).returns @attached_to
+ @resource.stubs(:[]).with(:ensure).returns :present
+ @resource.stubs(:ref).returns "Mcx[#{@attached_to}]"
+
+ # stub out the provider methods that actually touch the filesystem
+ # or execute commands
+ @provider.class.stubs(:execute).returns('')
+ @provider.stubs(:execute).returns('')
+ @provider.stubs(:resource).returns @resource
+ end
+
+ it "should have a create method." do
+ @provider.should respond_to(:create)
+ end
+
+ it "should have a destroy method." do
+ @provider.should respond_to(:destroy)
+ end
+
+ it "should have an exists? method." do
+ @provider.should respond_to(:exists?)
+ end
+
+ it "should have an content method." do
+ @provider.should respond_to(:content)
+ end
+
+ it "should have an content= method." do
+ @provider.should respond_to(:content=)
+ end
+
+ describe "when managing the resource" do
+ it "should execute external command dscl from :create" do
+ @provider.class.expects(:dscl).returns('').once
+ @provider.create
+ end
+ it "should execute external command dscl from :destroy" do
+ @provider.class.expects(:dscl).with('localhost', '-mcxdelete', @ds_path).returns('').once
+ @provider.destroy
+ end
+ it "should execute external command dscl from :exists?" do
+ @provider.class.expects(:dscl).with('localhost', '-mcxexport', @ds_path).returns('').once
+ @provider.exists?
+ end
+ it "should execute external command dscl from :content" do
+ @provider.class.expects(:dscl).with('localhost', '-mcxexport', @ds_path).returns('')
+ @provider.content
+ end
+ it "should execute external command dscl from :content=" do
+ @provider.class.expects(:dscl).returns('')
+ @provider.content=''
+ end
+ end
+
+ describe "when creating and parsing the name for ds_type" do
before :each do
- # Create a mock resource
- @resource = stub 'resource'
-
- @provider = provider_class.new
- @attached_to = "/Users/foobar"
- @ds_path = "/Local/Default/Users/foobar"
-
- # A catch all; no parameters set
- @resource.stubs(:[]).returns(nil)
-
- # But set name, ensure and enable
- @resource.stubs(:[]).with(:name).returns @attached_to
- @resource.stubs(:[]).with(:ensure).returns :present
- @resource.stubs(:ref).returns "Mcx[#{@attached_to}]"
-
- # stub out the provider methods that actually touch the filesystem
- # or execute commands
- @provider.class.stubs(:execute).returns('')
- @provider.stubs(:execute).returns('')
- @provider.stubs(:resource).returns @resource
- end
-
- it "should have a create method." do
- @provider.should respond_to(:create)
- end
-
- it "should have a destroy method." do
- @provider.should respond_to(:destroy)
- end
-
- it "should have an exists? method." do
- @provider.should respond_to(:exists?)
- end
-
- it "should have an content method." do
- @provider.should respond_to(:content)
- end
-
- it "should have an content= method." do
- @provider.should respond_to(:content=)
- end
-
- describe "when managing the resource" do
- it "should execute external command dscl from :create" do
- @provider.class.expects(:dscl).returns('').once
- @provider.create
- end
- it "should execute external command dscl from :destroy" do
- @provider.class.expects(:dscl).with('localhost', '-mcxdelete', @ds_path).returns('').once
- @provider.destroy
- end
- it "should execute external command dscl from :exists?" do
- @provider.class.expects(:dscl).with('localhost', '-mcxexport', @ds_path).returns('').once
- @provider.exists?
- end
- it "should execute external command dscl from :content" do
- @provider.class.expects(:dscl).with('localhost', '-mcxexport', @ds_path).returns('')
- @provider.content
- end
- it "should execute external command dscl from :content=" do
- @provider.class.expects(:dscl).returns('')
- @provider.content=''
- end
- end
-
- describe "when creating and parsing the name for ds_type" do
- before :each do
- @resource.stubs(:[]).with(:name).returns "/Foo/bar"
- end
- it "should not accept /Foo/bar" do
- lambda { @provider.create }.should raise_error(MCXContentProviderException)
- end
- it "should accept /Foo/bar with ds_type => user" do
- @resource.stubs(:[]).with(:ds_type).returns "user"
- lambda { @provider.create }.should_not raise_error(MCXContentProviderException)
- end
- it "should accept /Foo/bar with ds_type => group" do
- @resource.stubs(:[]).with(:ds_type).returns "group"
- lambda { @provider.create }.should_not raise_error(MCXContentProviderException)
- end
- it "should accept /Foo/bar with ds_type => computer" do
- @resource.stubs(:[]).with(:ds_type).returns "computer"
- lambda { @provider.create }.should_not raise_error(MCXContentProviderException)
- end
- it "should accept :name => /Foo/bar with ds_type => computerlist" do
- @resource.stubs(:[]).with(:ds_type).returns "computerlist"
- lambda { @provider.create }.should_not raise_error(MCXContentProviderException)
- end
- end
-
- describe "when creating and :name => foobar" do
- before :each do
- @resource.stubs(:[]).with(:name).returns "foobar"
- end
- it "should not accept unspecified :ds_type and :ds_name" do
- lambda { @provider.create }.should raise_error(MCXContentProviderException)
- end
- it "should not accept unspecified :ds_type" do
- @resource.stubs(:[]).with(:ds_type).returns "user"
- lambda { @provider.create }.should raise_error(MCXContentProviderException)
- end
- it "should not accept unspecified :ds_name" do
- @resource.stubs(:[]).with(:ds_name).returns "foo"
- lambda { @provider.create }.should raise_error(MCXContentProviderException)
- end
- it "should accept :ds_type => user, ds_name => foo" do
- @resource.stubs(:[]).with(:ds_type).returns "user"
- @resource.stubs(:[]).with(:ds_name).returns "foo"
- lambda { @provider.create }.should_not raise_error(MCXContentProviderException)
- end
- it "should accept :ds_type => group, ds_name => foo" do
- @resource.stubs(:[]).with(:ds_type).returns "group"
- @resource.stubs(:[]).with(:ds_name).returns "foo"
- lambda { @provider.create }.should_not raise_error(MCXContentProviderException)
- end
- it "should accept :ds_type => computer, ds_name => foo" do
- @resource.stubs(:[]).with(:ds_type).returns "computer"
- @resource.stubs(:[]).with(:ds_name).returns "foo"
- lambda { @provider.create }.should_not raise_error(MCXContentProviderException)
- end
- it "should accept :ds_type => computerlist, ds_name => foo" do
- @resource.stubs(:[]).with(:ds_type).returns "computerlist"
- @resource.stubs(:[]).with(:ds_name).returns "foo"
- lambda { @provider.create }.should_not raise_error(MCXContentProviderException)
- end
- it "should not accept :ds_type => bogustype, ds_name => foo" do
- @resource.stubs(:[]).with(:ds_type).returns "bogustype"
- @resource.stubs(:[]).with(:ds_name).returns "foo"
- lambda { @provider.create }.should raise_error(MCXContentProviderException)
- end
- end
-
- describe "when gathering existing instances" do
- it "should define an instances class method." do
- @provider.class.should respond_to(:instances)
- end
- it "should call external command dscl -list /Local/Default/<ds_type> on each known ds_type" do
- @provider.class.expects(:dscl).with('localhost', '-list', "/Local/Default/Users").returns('')
- @provider.class.expects(:dscl).with('localhost', '-list', "/Local/Default/Groups").returns('')
- @provider.class.expects(:dscl).with('localhost', '-list', "/Local/Default/Computers").returns('')
- @provider.class.expects(:dscl).with('localhost', '-list', "/Local/Default/ComputerLists").returns('')
- @provider.class.instances
- end
+ @resource.stubs(:[]).with(:name).returns "/Foo/bar"
+ end
+ it "should not accept /Foo/bar" do
+ lambda { @provider.create }.should raise_error(MCXContentProviderException)
+ end
+ it "should accept /Foo/bar with ds_type => user" do
+ @resource.stubs(:[]).with(:ds_type).returns "user"
+ lambda { @provider.create }.should_not raise_error(MCXContentProviderException)
+ end
+ it "should accept /Foo/bar with ds_type => group" do
+ @resource.stubs(:[]).with(:ds_type).returns "group"
+ lambda { @provider.create }.should_not raise_error(MCXContentProviderException)
+ end
+ it "should accept /Foo/bar with ds_type => computer" do
+ @resource.stubs(:[]).with(:ds_type).returns "computer"
+ lambda { @provider.create }.should_not raise_error(MCXContentProviderException)
+ end
+ it "should accept :name => /Foo/bar with ds_type => computerlist" do
+ @resource.stubs(:[]).with(:ds_type).returns "computerlist"
+ lambda { @provider.create }.should_not raise_error(MCXContentProviderException)
+ end
+ end
+
+ describe "when creating and :name => foobar" do
+ before :each do
+ @resource.stubs(:[]).with(:name).returns "foobar"
+ end
+ it "should not accept unspecified :ds_type and :ds_name" do
+ lambda { @provider.create }.should raise_error(MCXContentProviderException)
+ end
+ it "should not accept unspecified :ds_type" do
+ @resource.stubs(:[]).with(:ds_type).returns "user"
+ lambda { @provider.create }.should raise_error(MCXContentProviderException)
+ end
+ it "should not accept unspecified :ds_name" do
+ @resource.stubs(:[]).with(:ds_name).returns "foo"
+ lambda { @provider.create }.should raise_error(MCXContentProviderException)
+ end
+ it "should accept :ds_type => user, ds_name => foo" do
+ @resource.stubs(:[]).with(:ds_type).returns "user"
+ @resource.stubs(:[]).with(:ds_name).returns "foo"
+ lambda { @provider.create }.should_not raise_error(MCXContentProviderException)
+ end
+ it "should accept :ds_type => group, ds_name => foo" do
+ @resource.stubs(:[]).with(:ds_type).returns "group"
+ @resource.stubs(:[]).with(:ds_name).returns "foo"
+ lambda { @provider.create }.should_not raise_error(MCXContentProviderException)
+ end
+ it "should accept :ds_type => computer, ds_name => foo" do
+ @resource.stubs(:[]).with(:ds_type).returns "computer"
+ @resource.stubs(:[]).with(:ds_name).returns "foo"
+ lambda { @provider.create }.should_not raise_error(MCXContentProviderException)
+ end
+ it "should accept :ds_type => computerlist, ds_name => foo" do
+ @resource.stubs(:[]).with(:ds_type).returns "computerlist"
+ @resource.stubs(:[]).with(:ds_name).returns "foo"
+ lambda { @provider.create }.should_not raise_error(MCXContentProviderException)
+ end
+ it "should not accept :ds_type => bogustype, ds_name => foo" do
+ @resource.stubs(:[]).with(:ds_type).returns "bogustype"
+ @resource.stubs(:[]).with(:ds_name).returns "foo"
+ lambda { @provider.create }.should raise_error(MCXContentProviderException)
+ end
+ end
+
+ describe "when gathering existing instances" do
+ it "should define an instances class method." do
+ @provider.class.should respond_to(:instances)
+ end
+ it "should call external command dscl -list /Local/Default/<ds_type> on each known ds_type" do
+ @provider.class.expects(:dscl).with('localhost', '-list', "/Local/Default/Users").returns('')
+ @provider.class.expects(:dscl).with('localhost', '-list', "/Local/Default/Groups").returns('')
+ @provider.class.expects(:dscl).with('localhost', '-list', "/Local/Default/Computers").returns('')
+ @provider.class.expects(:dscl).with('localhost', '-list', "/Local/Default/ComputerLists").returns('')
+ @provider.class.instances
end
+ end
end
diff --git a/spec/unit/provider/mount/parsed_spec.rb b/spec/unit/provider/mount/parsed_spec.rb
index dfc2c0e..7d2e8a8 100755
--- a/spec/unit/provider/mount/parsed_spec.rb
+++ b/spec/unit/provider/mount/parsed_spec.rb
@@ -9,185 +9,185 @@ require 'puppettest/support/utils'
require 'puppettest/fileparsing'
module ParsedMountTesting
- include PuppetTest::Support::Utils
- include PuppetTest::FileParsing
-
- def fake_fstab
- os = Facter['operatingsystem']
- if os == "Solaris"
- name = "solaris.fstab"
- elsif os == "FreeBSD"
- name = "freebsd.fstab"
- else
- # Catchall for other fstabs
- name = "linux.fstab"
- end
- oldpath = @provider_class.default_target
- fakefile(File::join("data/types/mount", name))
+ include PuppetTest::Support::Utils
+ include PuppetTest::FileParsing
+
+ def fake_fstab
+ os = Facter['operatingsystem']
+ if os == "Solaris"
+ name = "solaris.fstab"
+ elsif os == "FreeBSD"
+ name = "freebsd.fstab"
+ else
+ # Catchall for other fstabs
+ name = "linux.fstab"
end
+ oldpath = @provider_class.default_target
+ fakefile(File::join("data/types/mount", name))
+ end
- def mkmountargs
- mount = nil
-
- if defined?(@pcount)
- @pcount += 1
- else
- @pcount = 1
- end
- args = {
- :name => "/fspuppet#{@pcount}",
- :device => "/dev/dsk#{@pcount}",
- }
+ def mkmountargs
+ mount = nil
- @provider_class.fields(:parsed).each do |field|
- args[field] = "fake#{field}#{@pcount}" unless args.include? field
- end
+ if defined?(@pcount)
+ @pcount += 1
+ else
+ @pcount = 1
+ end
+ args = {
+ :name => "/fspuppet#{@pcount}",
+ :device => "/dev/dsk#{@pcount}",
+ }
- args
+ @provider_class.fields(:parsed).each do |field|
+ args[field] = "fake#{field}#{@pcount}" unless args.include? field
end
- def mkmount
- hash = mkmountargs
- #hash[:provider] = @provider_class.name
+ args
+ end
- fakeresource = stub :type => :mount, :name => hash[:name]
- fakeresource.stubs(:[]).with(:name).returns(hash[:name])
- fakeresource.stubs(:should).with(:target).returns(nil)
+ def mkmount
+ hash = mkmountargs
+ #hash[:provider] = @provider_class.name
- mount = @provider_class.new(fakeresource)
- hash[:record_type] = :parsed
- hash[:ensure] = :present
- mount.property_hash = hash
+ fakeresource = stub :type => :mount, :name => hash[:name]
+ fakeresource.stubs(:[]).with(:name).returns(hash[:name])
+ fakeresource.stubs(:should).with(:target).returns(nil)
- mount
- end
+ mount = @provider_class.new(fakeresource)
+ hash[:record_type] = :parsed
+ hash[:ensure] = :present
+ mount.property_hash = hash
- # Here we just create a fake host type that answers to all of the methods
- # but does not modify our actual system.
- def mkfaketype
- @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
- end
+ mount
+ end
+
+ # Here we just create a fake host type that answers to all of the methods
+ # but does not modify our actual system.
+ def mkfaketype
+ @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
+ end
end
provider_class = Puppet::Type.type(:mount).provider(:parsed)
describe provider_class do
- before :each do
- @mount_class = Puppet::Type.type(:mount)
- @provider_class = @mount_class.provider(:parsed)
- end
+ before :each do
+ @mount_class = Puppet::Type.type(:mount)
+ @provider_class = @mount_class.provider(:parsed)
+ end
- describe provider_class do
- include ParsedMountTesting
+ describe provider_class do
+ include ParsedMountTesting
- it "should be able to parse all of the example mount tabs" do
- tab = fake_fstab
- @provider = @provider_class
+ it "should be able to parse all of the example mount tabs" do
+ tab = fake_fstab
+ @provider = @provider_class
- # LAK:FIXME Again, a relatively bad test, but I don't know how to rspec-ify this.
- # I suppose this is more of an integration test? I dunno.
- fakedataparse(tab) do
- # Now just make we've got some mounts we know will be there
- hashes = @provider_class.target_records(tab).find_all { |i| i.is_a? Hash }
- (hashes.length > 0).should be_true
- root = hashes.find { |i| i[:name] == "/" }
+ # LAK:FIXME Again, a relatively bad test, but I don't know how to rspec-ify this.
+ # I suppose this is more of an integration test? I dunno.
+ fakedataparse(tab) do
+ # Now just make we've got some mounts we know will be there
+ hashes = @provider_class.target_records(tab).find_all { |i| i.is_a? Hash }
+ (hashes.length > 0).should be_true
+ root = hashes.find { |i| i[:name] == "/" }
- proc { @provider_class.to_file(hashes) }.should_not raise_error
- end
- end
+ proc { @provider_class.to_file(hashes) }.should_not raise_error
+ end
+ end
- # LAK:FIXME I can't mock Facter because this test happens at parse-time.
- it "should default to /etc/vfstab on Solaris and /etc/fstab everywhere else" do
- should = case Facter.value(:operatingsystem)
- when "Solaris"; "/etc/vfstab"
- else
- "/etc/fstab"
- end
- Puppet::Type.type(:mount).provider(:parsed).default_target.should == should
+ # LAK:FIXME I can't mock Facter because this test happens at parse-time.
+ it "should default to /etc/vfstab on Solaris and /etc/fstab everywhere else" do
+ should = case Facter.value(:operatingsystem)
+ when "Solaris"; "/etc/vfstab"
+ else
+ "/etc/fstab"
end
+ Puppet::Type.type(:mount).provider(:parsed).default_target.should == should
+ end
- it "should not crash on incomplete lines in fstab" do
- parse = @provider_class.parse <<-FSTAB
+ it "should not crash on incomplete lines in fstab" do
+ parse = @provider_class.parse <<-FSTAB
/dev/incomplete
/dev/device name
- FSTAB
+ FSTAB
- lambda{ @provider_class.to_line(parse[0]) }.should_not raise_error
- end
+ lambda{ @provider_class.to_line(parse[0]) }.should_not raise_error
end
+ end
- describe provider_class, " when mounting an absent filesystem" do
- include ParsedMountTesting
+ describe provider_class, " when mounting an absent filesystem" do
+ include ParsedMountTesting
- # #730 - Make sure 'flush' is called when a mount is moving from absent to mounted
- it "should flush the fstab to disk" do
- mount = mkmount
+ # #730 - Make sure 'flush' is called when a mount is moving from absent to mounted
+ it "should flush the fstab to disk" do
+ mount = mkmount
- # Mark the mount as absent
- mount.property_hash[:ensure] = :absent
+ # Mark the mount as absent
+ mount.property_hash[:ensure] = :absent
- mount.stubs(:mountcmd) # just so we don't actually try to mount anything
+ mount.stubs(:mountcmd) # just so we don't actually try to mount anything
- mount.expects(:flush)
- mount.mount
- end
+ mount.expects(:flush)
+ mount.mount
+ end
+ end
+
+ describe provider_class, " when modifying the filesystem tab" do
+ include ParsedMountTesting
+ before do
+ Puppet.settings.stubs(:use)
+ # Never write to disk, only to RAM.
+ #@provider_class.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
+ @provider_class.stubs(:target_object).returns(Puppet::Util::FileType.filetype(:ram).new("eh"))
+ @provider_class.clear
+
+ @mount = mkmount
+ @target = @provider_class.default_target
end
- describe provider_class, " when modifying the filesystem tab" do
- include ParsedMountTesting
- before do
- Puppet.settings.stubs(:use)
- # Never write to disk, only to RAM.
- #@provider_class.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
- @provider_class.stubs(:target_object).returns(Puppet::Util::FileType.filetype(:ram).new("eh"))
- @provider_class.clear
-
- @mount = mkmount
- @target = @provider_class.default_target
- end
-
- it "should write the mount to disk when :flush is called" do
- old_text = @provider_class.target_object(@provider_class.default_target).read
+ it "should write the mount to disk when :flush is called" do
+ old_text = @provider_class.target_object(@provider_class.default_target).read
- @mount.flush
+ @mount.flush
- text = @provider_class.target_object(@provider_class.default_target).read
- text.should == old_text + @mount.class.to_line(@mount.property_hash) + "\n"
- end
+ text = @provider_class.target_object(@provider_class.default_target).read
+ text.should == old_text + @mount.class.to_line(@mount.property_hash) + "\n"
end
+ end
- describe provider_class, " when parsing information about the root filesystem" do
- confine "Mount type not tested on Darwin" => Facter["operatingsystem"].value != "Darwin"
- include ParsedMountTesting
+ describe provider_class, " when parsing information about the root filesystem" do
+ confine "Mount type not tested on Darwin" => Facter["operatingsystem"].value != "Darwin"
+ include ParsedMountTesting
- before do
- @mount = @mount_class.new :name => "/"
- @provider = @mount.provider
- end
+ before do
+ @mount = @mount_class.new :name => "/"
+ @provider = @mount.provider
+ end
- it "should have a filesystem tab" do
- FileTest.should be_exist(@provider_class.default_target)
- end
+ it "should have a filesystem tab" do
+ FileTest.should be_exist(@provider_class.default_target)
+ end
- it "should find the root filesystem" do
- @provider_class.prefetch("/" => @mount)
- @mount.provider.property_hash[:ensure].should == :present
- end
+ it "should find the root filesystem" do
+ @provider_class.prefetch("/" => @mount)
+ @mount.provider.property_hash[:ensure].should == :present
+ end
- it "should determine that the root fs is mounted" do
- @provider_class.prefetch("/" => @mount)
- @mount.provider.should be_mounted
- end
+ it "should determine that the root fs is mounted" do
+ @provider_class.prefetch("/" => @mount)
+ @mount.provider.should be_mounted
end
+ end
- describe provider_class, " when mounting and unmounting" do
- include ParsedMountTesting
+ describe provider_class, " when mounting and unmounting" do
+ include ParsedMountTesting
- it "should call the 'mount' command to mount the filesystem"
+ it "should call the 'mount' command to mount the filesystem"
- it "should call the 'unmount' command to unmount the filesystem"
+ it "should call the 'unmount' command to unmount the filesystem"
- it "should specify the filesystem when remounting a filesystem"
- end
+ it "should specify the filesystem when remounting a filesystem"
+ end
end
diff --git a/spec/unit/provider/mount_spec.rb b/spec/unit/provider/mount_spec.rb
index 41abcd4..55a52b4 100755
--- a/spec/unit/provider/mount_spec.rb
+++ b/spec/unit/provider/mount_spec.rb
@@ -5,126 +5,126 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/provider/mount'
describe Puppet::Provider::Mount do
- before :each do
- @mounter = Object.new
- @mounter.extend(Puppet::Provider::Mount)
+ before :each do
+ @mounter = Object.new
+ @mounter.extend(Puppet::Provider::Mount)
- @name = "/"
+ @name = "/"
- @resource = stub 'resource'
- @resource.stubs(:[]).with(:name).returns(@name)
+ @resource = stub 'resource'
+ @resource.stubs(:[]).with(:name).returns(@name)
- @mounter.stubs(:resource).returns(@resource)
+ @mounter.stubs(:resource).returns(@resource)
+ end
+
+ describe Puppet::Provider::Mount, " when mounting" do
+
+ it "should use the 'mountcmd' method to mount" do
+ @mounter.stubs(:options).returns(nil)
+ @mounter.expects(:mountcmd)
+
+ @mounter.mount
end
- describe Puppet::Provider::Mount, " when mounting" do
+ it "should flush before mounting if a flush method exists" do
+ @mounter.meta_def(:flush) { }
+ @mounter.expects(:flush)
+ @mounter.stubs(:mountcmd)
+ @mounter.stubs(:options).returns(nil)
- it "should use the 'mountcmd' method to mount" do
- @mounter.stubs(:options).returns(nil)
- @mounter.expects(:mountcmd)
+ @mounter.mount
+ end
- @mounter.mount
- end
+ it "should add the options following '-o' if they exist and are not set to :absent" do
+ @mounter.stubs(:options).returns("ro")
+ @mounter.expects(:mountcmd).with { |*ary| ary[0] == "-o" and ary[1] == "ro" }
- it "should flush before mounting if a flush method exists" do
- @mounter.meta_def(:flush) { }
- @mounter.expects(:flush)
- @mounter.stubs(:mountcmd)
- @mounter.stubs(:options).returns(nil)
+ @mounter.mount
+ end
- @mounter.mount
- end
+ it "should specify the filesystem name to the mount command" do
+ @mounter.stubs(:options).returns(nil)
+ @mounter.expects(:mountcmd).with { |*ary| ary[-1] == @name }
- it "should add the options following '-o' if they exist and are not set to :absent" do
- @mounter.stubs(:options).returns("ro")
- @mounter.expects(:mountcmd).with { |*ary| ary[0] == "-o" and ary[1] == "ro" }
+ @mounter.mount
+ end
+ end
- @mounter.mount
- end
+ describe Puppet::Provider::Mount, " when remounting" do
- it "should specify the filesystem name to the mount command" do
- @mounter.stubs(:options).returns(nil)
- @mounter.expects(:mountcmd).with { |*ary| ary[-1] == @name }
+ it "should use '-o remount' if the resource specifies it supports remounting" do
+ @mounter.stubs(:info)
+ @resource.stubs(:[]).with(:remounts).returns(:true)
+ @mounter.expects(:mountcmd).with("-o", "remount", @name)
+ @mounter.remount
+ end
- @mounter.mount
- end
+ it "should unmount and mount if the resource does not specify it supports remounting" do
+ @mounter.stubs(:info)
+ @resource.stubs(:[]).with(:remounts).returns(false)
+ @mounter.expects(:unmount)
+ @mounter.expects(:mount)
+ @mounter.remount
end
- describe Puppet::Provider::Mount, " when remounting" do
-
- it "should use '-o remount' if the resource specifies it supports remounting" do
- @mounter.stubs(:info)
- @resource.stubs(:[]).with(:remounts).returns(:true)
- @mounter.expects(:mountcmd).with("-o", "remount", @name)
- @mounter.remount
- end
-
- it "should unmount and mount if the resource does not specify it supports remounting" do
- @mounter.stubs(:info)
- @resource.stubs(:[]).with(:remounts).returns(false)
- @mounter.expects(:unmount)
- @mounter.expects(:mount)
- @mounter.remount
- end
-
- it "should log that it is remounting" do
- @resource.stubs(:[]).with(:remounts).returns(:true)
- @mounter.stubs(:mountcmd)
- @mounter.expects(:info).with("Remounting")
- @mounter.remount
- end
+ it "should log that it is remounting" do
+ @resource.stubs(:[]).with(:remounts).returns(:true)
+ @mounter.stubs(:mountcmd)
+ @mounter.expects(:info).with("Remounting")
+ @mounter.remount
end
+ end
- describe Puppet::Provider::Mount, " when unmounting" do
+ describe Puppet::Provider::Mount, " when unmounting" do
- it "should call the :umount command with the resource name" do
- @mounter.expects(:umount).with(@name)
- @mounter.unmount
- end
+ it "should call the :umount command with the resource name" do
+ @mounter.expects(:umount).with(@name)
+ @mounter.unmount
end
+ end
- describe Puppet::Provider::Mount, " when determining if it is mounted" do
+ describe Puppet::Provider::Mount, " when determining if it is mounted" do
- it "should parse the results of running the mount command with no arguments" do
- Facter.stubs(:value).returns("whatever")
- @mounter.expects(:mountcmd).returns("")
+ it "should parse the results of running the mount command with no arguments" do
+ Facter.stubs(:value).returns("whatever")
+ @mounter.expects(:mountcmd).returns("")
- @mounter.mounted?
- end
+ @mounter.mounted?
+ end
- it "should match ' on /private/var/automount<name>' if the operating system is Darwin" do
- Facter.stubs(:value).with("operatingsystem").returns("Darwin")
- @mounter.expects(:mountcmd).returns("/dev/whatever on /private/var/automount/\ndevfs on /dev")
+ it "should match ' on /private/var/automount<name>' if the operating system is Darwin" do
+ Facter.stubs(:value).with("operatingsystem").returns("Darwin")
+ @mounter.expects(:mountcmd).returns("/dev/whatever on /private/var/automount/\ndevfs on /dev")
- @mounter.should be_mounted
- end
+ @mounter.should be_mounted
+ end
- it "should match ' on <name>' if the operating system is Darwin" do
- Facter.stubs(:value).with("operatingsystem").returns("Darwin")
- @mounter.expects(:mountcmd).returns("/dev/disk03 on / (local, journaled)\ndevfs on /dev")
+ it "should match ' on <name>' if the operating system is Darwin" do
+ Facter.stubs(:value).with("operatingsystem").returns("Darwin")
+ @mounter.expects(:mountcmd).returns("/dev/disk03 on / (local, journaled)\ndevfs on /dev")
- @mounter.should be_mounted
- end
+ @mounter.should be_mounted
+ end
- it "should match '^<name> on' if the operating system is Solaris" do
- Facter.stubs(:value).with("operatingsystem").returns("Solaris")
- @mounter.expects(:mountcmd).returns("/ on /dev/dsk/whatever\n/var on /dev/dsk/other")
+ it "should match '^<name> on' if the operating system is Solaris" do
+ Facter.stubs(:value).with("operatingsystem").returns("Solaris")
+ @mounter.expects(:mountcmd).returns("/ on /dev/dsk/whatever\n/var on /dev/dsk/other")
- @mounter.should be_mounted
- end
+ @mounter.should be_mounted
+ end
- it "should match ' on <name>' if the operating system is not Darwin or Solaris" do
- Facter.stubs(:value).with("operatingsystem").returns("Debian")
- @mounter.expects(:mountcmd).returns("/dev/dsk/whatever on / and stuff\n/dev/other/disk on /var and stuff")
+ it "should match ' on <name>' if the operating system is not Darwin or Solaris" do
+ Facter.stubs(:value).with("operatingsystem").returns("Debian")
+ @mounter.expects(:mountcmd).returns("/dev/dsk/whatever on / and stuff\n/dev/other/disk on /var and stuff")
- @mounter.should be_mounted
- end
+ @mounter.should be_mounted
+ end
- it "should not be considered mounted if it did not match the mount output" do
- Facter.stubs(:value).with("operatingsystem").returns("Debian")
- @mounter.expects(:mountcmd).returns("/dev/dsk/whatever on /something/else and stuff\n/dev/other/disk on /var and stuff")
+ it "should not be considered mounted if it did not match the mount output" do
+ Facter.stubs(:value).with("operatingsystem").returns("Debian")
+ @mounter.expects(:mountcmd).returns("/dev/dsk/whatever on /something/else and stuff\n/dev/other/disk on /var and stuff")
- @mounter.should_not be_mounted
- end
+ @mounter.should_not be_mounted
end
+ end
end
diff --git a/spec/unit/provider/naginator_spec.rb b/spec/unit/provider/naginator_spec.rb
index d0d43aa..7219575 100755
--- a/spec/unit/provider/naginator_spec.rb
+++ b/spec/unit/provider/naginator_spec.rb
@@ -5,54 +5,54 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/provider/naginator'
describe Puppet::Provider::Naginator do
- before do
- @resource_type = stub 'resource_type', :name => :nagios_test
- @class = Class.new(Puppet::Provider::Naginator)
+ before do
+ @resource_type = stub 'resource_type', :name => :nagios_test
+ @class = Class.new(Puppet::Provider::Naginator)
- @class.stubs(:resource_type).returns @resource_type
- end
+ @class.stubs(:resource_type).returns @resource_type
+ end
- it "should be able to look up the associated Nagios type" do
- nagios_type = mock "nagios_type"
- nagios_type.stubs :attr_accessor
- Nagios::Base.expects(:type).with(:test).returns nagios_type
+ it "should be able to look up the associated Nagios type" do
+ nagios_type = mock "nagios_type"
+ nagios_type.stubs :attr_accessor
+ Nagios::Base.expects(:type).with(:test).returns nagios_type
- @class.nagios_type.should equal(nagios_type)
- end
+ @class.nagios_type.should equal(nagios_type)
+ end
- it "should use the Nagios type to determine whether an attribute is valid" do
- nagios_type = mock "nagios_type"
- nagios_type.stubs :attr_accessor
- Nagios::Base.expects(:type).with(:test).returns nagios_type
+ it "should use the Nagios type to determine whether an attribute is valid" do
+ nagios_type = mock "nagios_type"
+ nagios_type.stubs :attr_accessor
+ Nagios::Base.expects(:type).with(:test).returns nagios_type
- nagios_type.expects(:parameters).returns [:foo, :bar]
+ nagios_type.expects(:parameters).returns [:foo, :bar]
- @class.valid_attr?(:test, :foo).should be_true
- end
+ @class.valid_attr?(:test, :foo).should be_true
+ end
- it "should use Naginator to parse configuration snippets" do
- parser = mock 'parser'
- parser.expects(:parse).with("my text").returns "my instances"
- Nagios::Parser.expects(:new).returns(parser)
+ it "should use Naginator to parse configuration snippets" do
+ parser = mock 'parser'
+ parser.expects(:parse).with("my text").returns "my instances"
+ Nagios::Parser.expects(:new).returns(parser)
- @class.parse("my text").should == "my instances"
- end
+ @class.parse("my text").should == "my instances"
+ end
- it "should join Nagios::Base records with '\\n' when asked to convert them to text" do
- @class.expects(:header).returns "myheader\n"
+ it "should join Nagios::Base records with '\\n' when asked to convert them to text" do
+ @class.expects(:header).returns "myheader\n"
- @class.to_file([:one, :two]).should == "myheader\none\ntwo"
- end
+ @class.to_file([:one, :two]).should == "myheader\none\ntwo"
+ end
- it "should be able to prefetch instance from configuration files" do
- @class.should respond_to(:prefetch)
- end
+ it "should be able to prefetch instance from configuration files" do
+ @class.should respond_to(:prefetch)
+ end
- it "should be able to generate a list of instances" do
- @class.should respond_to(:instances)
- end
+ it "should be able to generate a list of instances" do
+ @class.should respond_to(:instances)
+ end
- it "should never skip records" do
- @class.should_not be_skip_record("foo")
- end
+ it "should never skip records" do
+ @class.should_not be_skip_record("foo")
+ end
end
diff --git a/spec/unit/provider/package/aix_spec.rb b/spec/unit/provider/package/aix_spec.rb
index 691749d..26732a3 100755
--- a/spec/unit/provider/package/aix_spec.rb
+++ b/spec/unit/provider/package/aix_spec.rb
@@ -5,62 +5,62 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
provider_class = Puppet::Type.type(:package).provider(:aix)
describe provider_class do
- before(:each) do
- # Create a mock resource
- @resource = stub 'resource'
+ before(:each) do
+ # Create a mock resource
+ @resource = stub 'resource'
- # A catch all; no parameters set
- @resource.stubs(:[]).returns(nil)
+ # A catch all; no parameters set
+ @resource.stubs(:[]).returns(nil)
- # But set name and source
- @resource.stubs(:[]).with(:name).returns "mypackage"
- @resource.stubs(:[]).with(:source).returns "mysource"
- @resource.stubs(:[]).with(:ensure).returns :installed
+ # But set name and source
+ @resource.stubs(:[]).with(:name).returns "mypackage"
+ @resource.stubs(:[]).with(:source).returns "mysource"
+ @resource.stubs(:[]).with(:ensure).returns :installed
- @provider = provider_class.new
- @provider.resource = @resource
- end
-
- [:install, :uninstall, :latest, :query, :update].each do |method|
- it "should have a #{method} method" do
- @provider.should respond_to(method)
- end
- end
+ @provider = provider_class.new
+ @provider.resource = @resource
+ end
- it "should uninstall a package" do
- @provider.expects(:installp).with('-gu', 'mypackage')
- @provider.uninstall
+ [:install, :uninstall, :latest, :query, :update].each do |method|
+ it "should have a #{method} method" do
+ @provider.should respond_to(method)
end
+ end
- describe "when installing" do
- it "should install a package" do
- @resource.stubs(:should).with(:ensure).returns(:installed)
- @provider.expects(:installp).with('-acgwXY', '-d', 'mysource', 'mypackage')
- @provider.install
- end
+ it "should uninstall a package" do
+ @provider.expects(:installp).with('-gu', 'mypackage')
+ @provider.uninstall
+ end
- it "should install a specific package version" do
- @resource.stubs(:should).with(:ensure).returns("1.2.3.4")
- @provider.expects(:installp).with('-acgwXY', '-d', 'mysource', 'mypackage 1.2.3.4')
- @provider.install
- end
+ describe "when installing" do
+ it "should install a package" do
+ @resource.stubs(:should).with(:ensure).returns(:installed)
+ @provider.expects(:installp).with('-acgwXY', '-d', 'mysource', 'mypackage')
+ @provider.install
end
- describe "when finding the latest version" do
- it "should return the current version when no later version is present" do
- @provider.stubs(:latest_info).returns(nil)
- @provider.stubs(:properties).returns( { :ensure => "1.2.3.4" } )
- @provider.latest.should == "1.2.3.4"
- end
+ it "should install a specific package version" do
+ @resource.stubs(:should).with(:ensure).returns("1.2.3.4")
+ @provider.expects(:installp).with('-acgwXY', '-d', 'mysource', 'mypackage 1.2.3.4')
+ @provider.install
+ end
+ end
- it "should return the latest version of a package" do
- @provider.stubs(:latest_info).returns( { :version => "1.2.3.5" } )
- @provider.latest.should == "1.2.3.5"
- end
+ describe "when finding the latest version" do
+ it "should return the current version when no later version is present" do
+ @provider.stubs(:latest_info).returns(nil)
+ @provider.stubs(:properties).returns( { :ensure => "1.2.3.4" } )
+ @provider.latest.should == "1.2.3.4"
end
- it "update should install a package" do
- @provider.expects(:install).with(false)
- @provider.update
+ it "should return the latest version of a package" do
+ @provider.stubs(:latest_info).returns( { :version => "1.2.3.5" } )
+ @provider.latest.should == "1.2.3.5"
end
+ end
+
+ it "update should install a package" do
+ @provider.expects(:install).with(false)
+ @provider.update
+ end
end
diff --git a/spec/unit/provider/package/apt_spec.rb b/spec/unit/provider/package/apt_spec.rb
index 54f2c07..3c6bf62 100755
--- a/spec/unit/provider/package/apt_spec.rb
+++ b/spec/unit/provider/package/apt_spec.rb
@@ -5,141 +5,141 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
provider = Puppet::Type.type(:package).provider(:apt)
describe provider do
- before do
- @resource = stub 'resource', :[] => "asdf"
- @provider = provider.new(@resource)
+ before do
+ @resource = stub 'resource', :[] => "asdf"
+ @provider = provider.new(@resource)
- @fakeresult = "install ok installed asdf 1.0\n"
- end
+ @fakeresult = "install ok installed asdf 1.0\n"
+ end
- it "should be versionable" do
- provider.should be_versionable
- end
+ it "should be versionable" do
+ provider.should be_versionable
+ end
- it "should use :install to update" do
- @provider.expects(:install)
- @provider.update
- end
+ it "should use :install to update" do
+ @provider.expects(:install)
+ @provider.update
+ end
- it "should use 'apt-get remove' to uninstall" do
- @provider.expects(:aptget).with("-y", "-q", :remove, "asdf")
+ it "should use 'apt-get remove' to uninstall" do
+ @provider.expects(:aptget).with("-y", "-q", :remove, "asdf")
- @provider.uninstall
- end
+ @provider.uninstall
+ end
- it "should use 'apt-get purge' and 'dpkg purge' to purge" do
- @provider.expects(:aptget).with("-y", "-q", :remove, "--purge", "asdf")
- @provider.expects(:dpkg).with("--purge", "asdf")
+ it "should use 'apt-get purge' and 'dpkg purge' to purge" do
+ @provider.expects(:aptget).with("-y", "-q", :remove, "--purge", "asdf")
+ @provider.expects(:dpkg).with("--purge", "asdf")
- @provider.purge
- end
+ @provider.purge
+ end
- it "should use 'apt-cache policy' to determine the latest version of a package" do
- @provider.expects(:aptcache).with(:policy, "asdf").returns "asdf:
+ it "should use 'apt-cache policy' to determine the latest version of a package" do
+ @provider.expects(:aptcache).with(:policy, "asdf").returns "asdf:
Installed: 1:1.0
Candidate: 1:1.1
Version table:
1:1.0
- 650 http://ftp.osuosl.org testing/main Packages
+ 650 http://ftp.osuosl.org testing/main Packages
*** 1:1.1
- 100 /var/lib/dpkg/status"
+ 100 /var/lib/dpkg/status"
- @provider.latest.should == "1:1.1"
- end
+ @provider.latest.should == "1:1.1"
+ end
- it "should print and error and return nil if no policy is found" do
- @provider.expects(:aptcache).with(:policy, "asdf").returns "asdf:"
+ it "should print and error and return nil if no policy is found" do
+ @provider.expects(:aptcache).with(:policy, "asdf").returns "asdf:"
- @provider.expects(:err)
- @provider.latest.should be_nil
- end
+ @provider.expects(:err)
+ @provider.latest.should be_nil
+ end
- it "should be able to preseed" do
- @provider.should respond_to(:run_preseed)
- end
+ it "should be able to preseed" do
+ @provider.should respond_to(:run_preseed)
+ end
- it "should preseed with the provided responsefile when preseeding is called for" do
- @resource.expects(:[]).with(:responsefile).returns "/my/file"
- FileTest.expects(:exist?).with("/my/file").returns true
+ it "should preseed with the provided responsefile when preseeding is called for" do
+ @resource.expects(:[]).with(:responsefile).returns "/my/file"
+ FileTest.expects(:exist?).with("/my/file").returns true
- @provider.expects(:info)
- @provider.expects(:preseed).with("/my/file")
+ @provider.expects(:info)
+ @provider.expects(:preseed).with("/my/file")
- @provider.run_preseed
- end
+ @provider.run_preseed
+ end
- it "should not preseed if no responsefile is provided" do
- @resource.expects(:[]).with(:responsefile).returns nil
+ it "should not preseed if no responsefile is provided" do
+ @resource.expects(:[]).with(:responsefile).returns nil
- @provider.expects(:info)
- @provider.expects(:preseed).never
+ @provider.expects(:info)
+ @provider.expects(:preseed).never
- @provider.run_preseed
- end
+ @provider.run_preseed
+ end
- it "should fail if a cdrom is listed in the sources list and :allowcdrom is not specified"
+ it "should fail if a cdrom is listed in the sources list and :allowcdrom is not specified"
- describe "when installing" do
- it "should preseed if a responsefile is provided" do
- @resource.expects(:[]).with(:responsefile).returns "/my/file"
- @provider.expects(:run_preseed)
+ describe "when installing" do
+ it "should preseed if a responsefile is provided" do
+ @resource.expects(:[]).with(:responsefile).returns "/my/file"
+ @provider.expects(:run_preseed)
- @provider.stubs(:aptget)
- @provider.install
- end
+ @provider.stubs(:aptget)
+ @provider.install
+ end
- it "should check for a cdrom" do
- @provider.expects(:checkforcdrom)
+ it "should check for a cdrom" do
+ @provider.expects(:checkforcdrom)
- @provider.stubs(:aptget)
- @provider.install
- end
+ @provider.stubs(:aptget)
+ @provider.install
+ end
- it "should use 'apt-get install' with the package name if no version is asked for" do
- @resource.expects(:[]).with(:ensure).returns :installed
- @provider.expects(:aptget).with { |*command| command[-1] == "asdf" and command[-2] == :install }
+ it "should use 'apt-get install' with the package name if no version is asked for" do
+ @resource.expects(:[]).with(:ensure).returns :installed
+ @provider.expects(:aptget).with { |*command| command[-1] == "asdf" and command[-2] == :install }
- @provider.install
- end
+ @provider.install
+ end
- it "should specify the package version if one is asked for" do
- @resource.expects(:[]).with(:ensure).returns "1.0"
- @provider.expects(:aptget).with { |*command| command[-1] == "asdf=1.0" }
+ it "should specify the package version if one is asked for" do
+ @resource.expects(:[]).with(:ensure).returns "1.0"
+ @provider.expects(:aptget).with { |*command| command[-1] == "asdf=1.0" }
- @provider.install
- end
+ @provider.install
+ end
- it "should use --force-yes if a package version is specified" do
- @resource.expects(:[]).with(:ensure).returns "1.0"
- @provider.expects(:aptget).with { |*command| command.include?("--force-yes") }
+ it "should use --force-yes if a package version is specified" do
+ @resource.expects(:[]).with(:ensure).returns "1.0"
+ @provider.expects(:aptget).with { |*command| command.include?("--force-yes") }
- @provider.install
- end
+ @provider.install
+ end
- it "should do a quiet install" do
- @provider.expects(:aptget).with { |*command| command.include?("-q") }
+ it "should do a quiet install" do
+ @provider.expects(:aptget).with { |*command| command.include?("-q") }
- @provider.install
- end
+ @provider.install
+ end
- it "should default to 'yes' for all questions" do
- @provider.expects(:aptget).with { |*command| command.include?("-y") }
+ it "should default to 'yes' for all questions" do
+ @provider.expects(:aptget).with { |*command| command.include?("-y") }
- @provider.install
- end
+ @provider.install
+ end
- it "should keep config files if asked" do
- @resource.expects(:[]).with(:configfiles).returns :keep
- @provider.expects(:aptget).with { |*command| command.include?("DPkg::Options::=--force-confold") }
+ it "should keep config files if asked" do
+ @resource.expects(:[]).with(:configfiles).returns :keep
+ @provider.expects(:aptget).with { |*command| command.include?("DPkg::Options::=--force-confold") }
- @provider.install
- end
+ @provider.install
+ end
- it "should replace config files if asked" do
- @resource.expects(:[]).with(:configfiles).returns :replace
- @provider.expects(:aptget).with { |*command| command.include?("DPkg::Options::=--force-confnew") }
+ it "should replace config files if asked" do
+ @resource.expects(:[]).with(:configfiles).returns :replace
+ @provider.expects(:aptget).with { |*command| command.include?("DPkg::Options::=--force-confnew") }
- @provider.install
- end
+ @provider.install
end
+ end
end
diff --git a/spec/unit/provider/package/dpkg_spec.rb b/spec/unit/provider/package/dpkg_spec.rb
index 68ffb19..47ac976 100755
--- a/spec/unit/provider/package/dpkg_spec.rb
+++ b/spec/unit/provider/package/dpkg_spec.rb
@@ -5,221 +5,221 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
provider = Puppet::Type.type(:package).provider(:dpkg)
describe provider do
- before do
- @resource = stub 'resource', :[] => "asdf"
- @provider = provider.new(@resource)
- @provider.expects(:execute).never # forbid "manual" executions
-
- @fakeresult = "install ok installed asdf 1.0\n"
- end
-
- it "should have documentation" do
- provider.doc.should be_instance_of(String)
- end
-
- describe "when listing all instances" do
- before do
- provider.stubs(:command).with(:dpkgquery).returns "myquery"
- end
+ before do
+ @resource = stub 'resource', :[] => "asdf"
+ @provider = provider.new(@resource)
+ @provider.expects(:execute).never # forbid "manual" executions
- it "should use dpkg-query" do
- provider.expects(:command).with(:dpkgquery).returns "myquery"
- provider.expects(:execpipe).with("myquery -W --showformat '${Status} ${Package} ${Version}\\n'").returns @fakeresult
+ @fakeresult = "install ok installed asdf 1.0\n"
+ end
- provider.instances
- end
+ it "should have documentation" do
+ provider.doc.should be_instance_of(String)
+ end
- it "should create and return an instance with each parsed line from dpkg-query" do
- pipe = mock 'pipe'
- pipe.expects(:each).yields @fakeresult
- provider.expects(:execpipe).yields pipe
+ describe "when listing all instances" do
+ before do
+ provider.stubs(:command).with(:dpkgquery).returns "myquery"
+ end
- asdf = mock 'pkg1'
- provider.expects(:new).with(:ensure => "1.0", :error => "ok", :desired => "install", :name => "asdf", :status => "installed", :provider => :dpkg).returns asdf
+ it "should use dpkg-query" do
+ provider.expects(:command).with(:dpkgquery).returns "myquery"
+ provider.expects(:execpipe).with("myquery -W --showformat '${Status} ${Package} ${Version}\\n'").returns @fakeresult
- provider.instances.should == [asdf]
- end
+ provider.instances
+ end
- it "should warn on and ignore any lines it does not understand" do
- pipe = mock 'pipe'
- pipe.expects(:each).yields "foobar"
- provider.expects(:execpipe).yields pipe
+ it "should create and return an instance with each parsed line from dpkg-query" do
+ pipe = mock 'pipe'
+ pipe.expects(:each).yields @fakeresult
+ provider.expects(:execpipe).yields pipe
- Puppet.expects(:warning)
- provider.expects(:new).never
+ asdf = mock 'pkg1'
+ provider.expects(:new).with(:ensure => "1.0", :error => "ok", :desired => "install", :name => "asdf", :status => "installed", :provider => :dpkg).returns asdf
- provider.instances.should == []
- end
+ provider.instances.should == [asdf]
end
- describe "when querying the current state" do
- it "should use dpkg-query" do
- @provider.expects(:dpkgquery).with("-W", "--showformat",'${Status} ${Package} ${Version}\\n', "asdf").returns @fakeresult
+ it "should warn on and ignore any lines it does not understand" do
+ pipe = mock 'pipe'
+ pipe.expects(:each).yields "foobar"
+ provider.expects(:execpipe).yields pipe
- @provider.query
- end
+ Puppet.expects(:warning)
+ provider.expects(:new).never
- it "should consider the package purged if dpkg-query fails" do
- @provider.expects(:dpkgquery).raises Puppet::ExecutionFailure.new("eh")
+ provider.instances.should == []
+ end
+ end
- @provider.query[:ensure].should == :purged
- end
+ describe "when querying the current state" do
+ it "should use dpkg-query" do
+ @provider.expects(:dpkgquery).with("-W", "--showformat",'${Status} ${Package} ${Version}\\n', "asdf").returns @fakeresult
- it "should return a hash of the found status with the desired state, error state, status, name, and 'ensure'" do
- @provider.expects(:dpkgquery).returns @fakeresult
+ @provider.query
+ end
- @provider.query.should == {:ensure => "1.0", :error => "ok", :desired => "install", :name => "asdf", :status => "installed", :provider => :dpkg}
- end
+ it "should consider the package purged if dpkg-query fails" do
+ @provider.expects(:dpkgquery).raises Puppet::ExecutionFailure.new("eh")
- it "should consider the package absent if the dpkg-query result cannot be interpreted" do
- @provider.expects(:dpkgquery).returns "somebaddata"
+ @provider.query[:ensure].should == :purged
+ end
- @provider.query[:ensure].should == :absent
- end
+ it "should return a hash of the found status with the desired state, error state, status, name, and 'ensure'" do
+ @provider.expects(:dpkgquery).returns @fakeresult
- it "should fail if an error is discovered" do
- @provider.expects(:dpkgquery).returns @fakeresult.sub("ok", "error")
+ @provider.query.should == {:ensure => "1.0", :error => "ok", :desired => "install", :name => "asdf", :status => "installed", :provider => :dpkg}
+ end
- lambda { @provider.query }.should raise_error(Puppet::Error)
- end
+ it "should consider the package absent if the dpkg-query result cannot be interpreted" do
+ @provider.expects(:dpkgquery).returns "somebaddata"
- it "should consider the package purged if it is marked 'not-installed'" do
- @provider.expects(:dpkgquery).returns @fakeresult.sub("installed", "not-installed")
+ @provider.query[:ensure].should == :absent
+ end
- @provider.query[:ensure].should == :purged
- end
+ it "should fail if an error is discovered" do
+ @provider.expects(:dpkgquery).returns @fakeresult.sub("ok", "error")
- it "should consider the package absent if it is marked 'config-files'" do
- @provider.expects(:dpkgquery).returns @fakeresult.sub("installed", "config-files")
- @provider.query[:ensure].should == :absent
- end
+ lambda { @provider.query }.should raise_error(Puppet::Error)
+ end
- it "should consider the package absent if it is marked 'half-installed'" do
- @provider.expects(:dpkgquery).returns @fakeresult.sub("installed", "half-installed")
- @provider.query[:ensure].should == :absent
- end
+ it "should consider the package purged if it is marked 'not-installed'" do
+ @provider.expects(:dpkgquery).returns @fakeresult.sub("installed", "not-installed")
- it "should consider the package absent if it is marked 'unpacked'" do
- @provider.expects(:dpkgquery).returns @fakeresult.sub("installed", "unpacked")
- @provider.query[:ensure].should == :absent
- end
+ @provider.query[:ensure].should == :purged
+ end
- it "should consider the package absent if it is marked 'half-configured'" do
- @provider.expects(:dpkgquery).returns @fakeresult.sub("installed", "half-configured")
- @provider.query[:ensure].should == :absent
- end
+ it "should consider the package absent if it is marked 'config-files'" do
+ @provider.expects(:dpkgquery).returns @fakeresult.sub("installed", "config-files")
+ @provider.query[:ensure].should == :absent
+ end
- it "should consider the package held if its state is 'hold'" do
- @provider.expects(:dpkgquery).returns @fakeresult.sub("install", "hold")
- @provider.query[:ensure].should == :held
- end
+ it "should consider the package absent if it is marked 'half-installed'" do
+ @provider.expects(:dpkgquery).returns @fakeresult.sub("installed", "half-installed")
+ @provider.query[:ensure].should == :absent
end
- it "should be able to install" do
- @provider.should respond_to(:install)
+ it "should consider the package absent if it is marked 'unpacked'" do
+ @provider.expects(:dpkgquery).returns @fakeresult.sub("installed", "unpacked")
+ @provider.query[:ensure].should == :absent
end
- describe "when installing" do
- before do
- @resource.stubs(:[]).with(:source).returns "mypkg"
- end
+ it "should consider the package absent if it is marked 'half-configured'" do
+ @provider.expects(:dpkgquery).returns @fakeresult.sub("installed", "half-configured")
+ @provider.query[:ensure].should == :absent
+ end
- it "should fail to install if no source is specified in the resource" do
- @resource.expects(:[]).with(:source).returns nil
+ it "should consider the package held if its state is 'hold'" do
+ @provider.expects(:dpkgquery).returns @fakeresult.sub("install", "hold")
+ @provider.query[:ensure].should == :held
+ end
+ end
- lambda { @provider.install }.should raise_error(ArgumentError)
- end
+ it "should be able to install" do
+ @provider.should respond_to(:install)
+ end
- it "should use 'dpkg -i' to install the package" do
- @resource.expects(:[]).with(:source).returns "mypackagefile"
- @provider.expects(:unhold)
- @provider.expects(:dpkg).with { |*command| command[-1] == "mypackagefile" and command[-2] == "-i" }
+ describe "when installing" do
+ before do
+ @resource.stubs(:[]).with(:source).returns "mypkg"
+ end
- @provider.install
- end
+ it "should fail to install if no source is specified in the resource" do
+ @resource.expects(:[]).with(:source).returns nil
- it "should keep old config files if told to do so" do
- @resource.expects(:[]).with(:configfiles).returns :keep
- @provider.expects(:unhold)
- @provider.expects(:dpkg).with { |*command| command[0] == "--force-confold" }
+ lambda { @provider.install }.should raise_error(ArgumentError)
+ end
- @provider.install
- end
+ it "should use 'dpkg -i' to install the package" do
+ @resource.expects(:[]).with(:source).returns "mypackagefile"
+ @provider.expects(:unhold)
+ @provider.expects(:dpkg).with { |*command| command[-1] == "mypackagefile" and command[-2] == "-i" }
- it "should replace old config files if told to do so" do
- @resource.expects(:[]).with(:configfiles).returns :replace
- @provider.expects(:unhold)
- @provider.expects(:dpkg).with { |*command| command[0] == "--force-confnew" }
+ @provider.install
+ end
- @provider.install
- end
+ it "should keep old config files if told to do so" do
+ @resource.expects(:[]).with(:configfiles).returns :keep
+ @provider.expects(:unhold)
+ @provider.expects(:dpkg).with { |*command| command[0] == "--force-confold" }
- it "should ensure any hold is removed" do
- @provider.expects(:unhold).once
- @provider.expects(:dpkg)
- @provider.install
- end
+ @provider.install
end
- describe "when holding or unholding" do
- before do
- @tempfile = stub 'tempfile', :print => nil, :close => nil, :flush => nil, :path => "/other/file"
- @tempfile.stubs(:write)
- Tempfile.stubs(:new).returns @tempfile
- end
-
- it "should install first if holding" do
- @provider.stubs(:execute)
- @provider.expects(:install).once
- @provider.hold
- end
+ it "should replace old config files if told to do so" do
+ @resource.expects(:[]).with(:configfiles).returns :replace
+ @provider.expects(:unhold)
+ @provider.expects(:dpkg).with { |*command| command[0] == "--force-confnew" }
- it "should execute dpkg --set-selections when holding" do
- @provider.stubs(:install)
- @provider.expects(:execute).with([:dpkg, '--set-selections'], {:stdinfile => @tempfile.path}).once
- @provider.hold
- end
+ @provider.install
+ end
- it "should execute dpkg --set-selections when unholding" do
- @provider.stubs(:install)
- @provider.expects(:execute).with([:dpkg, '--set-selections'], {:stdinfile => @tempfile.path}).once
- @provider.hold
- end
+ it "should ensure any hold is removed" do
+ @provider.expects(:unhold).once
+ @provider.expects(:dpkg)
+ @provider.install
end
+ end
- it "should use :install to update" do
- @provider.expects(:install)
- @provider.update
+ describe "when holding or unholding" do
+ before do
+ @tempfile = stub 'tempfile', :print => nil, :close => nil, :flush => nil, :path => "/other/file"
+ @tempfile.stubs(:write)
+ Tempfile.stubs(:new).returns @tempfile
end
- describe "when determining latest available version" do
- it "should return the version found by dpkg-deb" do
- @resource.expects(:[]).with(:source).returns "myfile"
- @provider.expects(:dpkg_deb).with { |*command| command[-1] == "myfile" }.returns "asdf\t1.0"
- @provider.latest.should == "1.0"
- end
+ it "should install first if holding" do
+ @provider.stubs(:execute)
+ @provider.expects(:install).once
+ @provider.hold
+ end
- it "should warn if the package file contains a different package" do
- @provider.expects(:dpkg_deb).returns("foo\tversion")
- @provider.expects(:warning)
- @provider.latest
- end
+ it "should execute dpkg --set-selections when holding" do
+ @provider.stubs(:install)
+ @provider.expects(:execute).with([:dpkg, '--set-selections'], {:stdinfile => @tempfile.path}).once
+ @provider.hold
+ end
- it "should cope with names containing ++" do
- @resource = stub 'resource', :[] => "asdf++"
- @provider = provider.new(@resource)
- @provider.expects(:dpkg_deb).returns "asdf++\t1.0"
- @provider.latest.should == "1.0"
- end
+ it "should execute dpkg --set-selections when unholding" do
+ @provider.stubs(:install)
+ @provider.expects(:execute).with([:dpkg, '--set-selections'], {:stdinfile => @tempfile.path}).once
+ @provider.hold
+ end
+ end
+
+ it "should use :install to update" do
+ @provider.expects(:install)
+ @provider.update
+ end
+
+ describe "when determining latest available version" do
+ it "should return the version found by dpkg-deb" do
+ @resource.expects(:[]).with(:source).returns "myfile"
+ @provider.expects(:dpkg_deb).with { |*command| command[-1] == "myfile" }.returns "asdf\t1.0"
+ @provider.latest.should == "1.0"
end
- it "should use 'dpkg -r' to uninstall" do
- @provider.expects(:dpkg).with("-r", "asdf")
- @provider.uninstall
+ it "should warn if the package file contains a different package" do
+ @provider.expects(:dpkg_deb).returns("foo\tversion")
+ @provider.expects(:warning)
+ @provider.latest
end
- it "should use 'dpkg --purge' to purge" do
- @provider.expects(:dpkg).with("--purge", "asdf")
- @provider.purge
+ it "should cope with names containing ++" do
+ @resource = stub 'resource', :[] => "asdf++"
+ @provider = provider.new(@resource)
+ @provider.expects(:dpkg_deb).returns "asdf++\t1.0"
+ @provider.latest.should == "1.0"
end
+ end
+
+ it "should use 'dpkg -r' to uninstall" do
+ @provider.expects(:dpkg).with("-r", "asdf")
+ @provider.uninstall
+ end
+
+ it "should use 'dpkg --purge' to purge" do
+ @provider.expects(:dpkg).with("--purge", "asdf")
+ @provider.purge
+ end
end
diff --git a/spec/unit/provider/package/gem_spec.rb b/spec/unit/provider/package/gem_spec.rb
index 3dc1fa3..063e147 100644
--- a/spec/unit/provider/package/gem_spec.rb
+++ b/spec/unit/provider/package/gem_spec.rb
@@ -5,83 +5,83 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
provider_class = Puppet::Type.type(:package).provider(:gem)
describe provider_class do
- it "should have an install method" do
- @provider = provider_class.new
- @provider.should respond_to(:install)
+ it "should have an install method" do
+ @provider = provider_class.new
+ @provider.should respond_to(:install)
+ end
+
+ describe "when installing" do
+ before do
+ # Create a mock resource
+ @resource = stub 'resource'
+
+ # A catch all; no parameters set
+ @resource.stubs(:[]).returns nil
+
+ # We have to set a name, though
+ @resource.stubs(:[]).with(:name).returns "myresource"
+ @resource.stubs(:[]).with(:ensure).returns :installed
+
+ @provider = provider_class.new
+ @provider.stubs(:resource).returns @resource
end
- describe "when installing" do
- before do
- # Create a mock resource
- @resource = stub 'resource'
+ it "should use the path to the gem" do
+ provider_class.stubs(:command).with(:gemcmd).returns "/my/gem"
+ @provider.expects(:execute).with { |args| args[0] == "/my/gem" }.returns ""
+ @provider.install
+ end
- # A catch all; no parameters set
- @resource.stubs(:[]).returns nil
+ it "should specify that the gem is being installed" do
+ @provider.expects(:execute).with { |args| args[1] == "install" }.returns ""
+ @provider.install
+ end
- # We have to set a name, though
- @resource.stubs(:[]).with(:name).returns "myresource"
- @resource.stubs(:[]).with(:ensure).returns :installed
+ it "should specify that dependencies should be included" do
+ @provider.expects(:execute).with { |args| args[2] == "--include-dependencies" }.returns ""
+ @provider.install
+ end
- @provider = provider_class.new
- @provider.stubs(:resource).returns @resource
- end
+ it "should specify the package name" do
+ @provider.expects(:execute).with { |args| args[3] == "myresource" }.returns ""
+ @provider.install
+ end
- it "should use the path to the gem" do
- provider_class.stubs(:command).with(:gemcmd).returns "/my/gem"
- @provider.expects(:execute).with { |args| args[0] == "/my/gem" }.returns ""
- @provider.install
+ describe "when a source is specified" do
+ describe "as a normal file" do
+ it "should use the file name instead of the gem name" do
+ @resource.stubs(:[]).with(:source).returns "/my/file"
+ @provider.expects(:execute).with { |args| args[3] == "/my/file" }.returns ""
+ @provider.install
end
-
- it "should specify that the gem is being installed" do
- @provider.expects(:execute).with { |args| args[1] == "install" }.returns ""
- @provider.install
+ end
+ describe "as a file url" do
+ it "should use the file name instead of the gem name" do
+ @resource.stubs(:[]).with(:source).returns "file:///my/file"
+ @provider.expects(:execute).with { |args| args[3] == "/my/file" }.returns ""
+ @provider.install
end
-
- it "should specify that dependencies should be included" do
- @provider.expects(:execute).with { |args| args[2] == "--include-dependencies" }.returns ""
- @provider.install
+ end
+ describe "as a puppet url" do
+ it "should fail" do
+ @resource.stubs(:[]).with(:source).returns "puppet://my/file"
+ lambda { @provider.install }.should raise_error(Puppet::Error)
end
-
- it "should specify the package name" do
- @provider.expects(:execute).with { |args| args[3] == "myresource" }.returns ""
- @provider.install
+ end
+ describe "as a non-file and non-puppet url" do
+ it "should treat the source as a gem repository" do
+ @resource.stubs(:[]).with(:source).returns "http://host/my/file"
+ @provider.expects(:execute).with { |args| args[3..5] == ["--source", "http://host/my/file", "myresource"] }.returns ""
+ @provider.install
end
-
- describe "when a source is specified" do
- describe "as a normal file" do
- it "should use the file name instead of the gem name" do
- @resource.stubs(:[]).with(:source).returns "/my/file"
- @provider.expects(:execute).with { |args| args[3] == "/my/file" }.returns ""
- @provider.install
- end
- end
- describe "as a file url" do
- it "should use the file name instead of the gem name" do
- @resource.stubs(:[]).with(:source).returns "file:///my/file"
- @provider.expects(:execute).with { |args| args[3] == "/my/file" }.returns ""
- @provider.install
- end
- end
- describe "as a puppet url" do
- it "should fail" do
- @resource.stubs(:[]).with(:source).returns "puppet://my/file"
- lambda { @provider.install }.should raise_error(Puppet::Error)
- end
- end
- describe "as a non-file and non-puppet url" do
- it "should treat the source as a gem repository" do
- @resource.stubs(:[]).with(:source).returns "http://host/my/file"
- @provider.expects(:execute).with { |args| args[3..5] == ["--source", "http://host/my/file", "myresource"] }.returns ""
- @provider.install
- end
- end
- describe "with an invalid uri" do
- it "should fail" do
- URI.expects(:parse).raises(ArgumentError)
- @resource.stubs(:[]).with(:source).returns "http:::::uppet:/:/my/file"
- lambda { @provider.install }.should raise_error(Puppet::Error)
- end
- end
+ end
+ describe "with an invalid uri" do
+ it "should fail" do
+ URI.expects(:parse).raises(ArgumentError)
+ @resource.stubs(:[]).with(:source).returns "http:::::uppet:/:/my/file"
+ lambda { @provider.install }.should raise_error(Puppet::Error)
end
+ end
end
+ end
end
diff --git a/spec/unit/provider/package/hpux_spec.rb b/spec/unit/provider/package/hpux_spec.rb
index 8343c60..e4ac22e 100644
--- a/spec/unit/provider/package/hpux_spec.rb
+++ b/spec/unit/provider/package/hpux_spec.rb
@@ -5,48 +5,48 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
provider_class = Puppet::Type.type(:package).provider(:hpux)
describe provider_class do
- before(:each) do
- # Create a mock resource
- @resource = stub 'resource'
-
- # A catch all; no parameters set
- @resource.stubs(:[]).returns(nil)
-
- # But set name and source
- @resource.stubs(:[]).with(:name).returns "mypackage"
- @resource.stubs(:[]).with(:source).returns "mysource"
- @resource.stubs(:[]).with(:ensure).returns :installed
-
- @provider = provider_class.new
- @provider.stubs(:resource).returns @resource
- end
-
- it "should have an install method" do
- @provider = provider_class.new
- @provider.should respond_to(:install)
- end
-
- it "should have an uninstall method" do
- @provider = provider_class.new
- @provider.should respond_to(:uninstall)
- end
-
- it "should have a swlist method" do
- @provider = provider_class.new
- @provider.should respond_to(:swlist)
- end
-
- describe "when installing" do
- it "should use a command-line like 'swinstall -x mount_all_filesystems=false -s SOURCE PACKAGE-NAME'" do
- @provider.expects(:swinstall).with('-x', 'mount_all_filesystems=false', '-s', 'mysource', 'mypackage')
- @provider.install
- end
+ before(:each) do
+ # Create a mock resource
+ @resource = stub 'resource'
+
+ # A catch all; no parameters set
+ @resource.stubs(:[]).returns(nil)
+
+ # But set name and source
+ @resource.stubs(:[]).with(:name).returns "mypackage"
+ @resource.stubs(:[]).with(:source).returns "mysource"
+ @resource.stubs(:[]).with(:ensure).returns :installed
+
+ @provider = provider_class.new
+ @provider.stubs(:resource).returns @resource
+ end
+
+ it "should have an install method" do
+ @provider = provider_class.new
+ @provider.should respond_to(:install)
+ end
+
+ it "should have an uninstall method" do
+ @provider = provider_class.new
+ @provider.should respond_to(:uninstall)
+ end
+
+ it "should have a swlist method" do
+ @provider = provider_class.new
+ @provider.should respond_to(:swlist)
+ end
+
+ describe "when installing" do
+ it "should use a command-line like 'swinstall -x mount_all_filesystems=false -s SOURCE PACKAGE-NAME'" do
+ @provider.expects(:swinstall).with('-x', 'mount_all_filesystems=false', '-s', 'mysource', 'mypackage')
+ @provider.install
end
+ end
- describe "when uninstalling" do
- it "should use a command-line like 'swremove -x mount_all_filesystems=false PACKAGE-NAME'" do
- @provider.expects(:swremove).with('-x', 'mount_all_filesystems=false', 'mypackage')
- @provider.uninstall
- end
+ describe "when uninstalling" do
+ it "should use a command-line like 'swremove -x mount_all_filesystems=false PACKAGE-NAME'" do
+ @provider.expects(:swremove).with('-x', 'mount_all_filesystems=false', 'mypackage')
+ @provider.uninstall
end
+ end
end
diff --git a/spec/unit/provider/package/nim_spec.rb b/spec/unit/provider/package/nim_spec.rb
index 5d9083b..53a9cc8 100755
--- a/spec/unit/provider/package/nim_spec.rb
+++ b/spec/unit/provider/package/nim_spec.rb
@@ -5,38 +5,38 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
provider_class = Puppet::Type.type(:package).provider(:nim)
describe provider_class do
- before(:each) do
- # Create a mock resource
- @resource = stub 'resource'
-
- # A catch all; no parameters set
- @resource.stubs(:[]).returns(nil)
-
- # But set name and source
- @resource.stubs(:[]).with(:name).returns "mypackage"
- @resource.stubs(:[]).with(:source).returns "mysource"
- @resource.stubs(:[]).with(:ensure).returns :installed
-
- @provider = provider_class.new
- @provider.resource = @resource
- end
-
- it "should have an install method" do
- @provider = provider_class.new
- @provider.should respond_to(:install)
+ before(:each) do
+ # Create a mock resource
+ @resource = stub 'resource'
+
+ # A catch all; no parameters set
+ @resource.stubs(:[]).returns(nil)
+
+ # But set name and source
+ @resource.stubs(:[]).with(:name).returns "mypackage"
+ @resource.stubs(:[]).with(:source).returns "mysource"
+ @resource.stubs(:[]).with(:ensure).returns :installed
+
+ @provider = provider_class.new
+ @provider.resource = @resource
+ end
+
+ it "should have an install method" do
+ @provider = provider_class.new
+ @provider.should respond_to(:install)
+ end
+
+ describe "when installing" do
+ it "should install a package" do
+ @resource.stubs(:should).with(:ensure).returns(:installed)
+ @provider.expects(:nimclient).with("-o", "cust", "-a", "installp_flags=acgwXY", "-a", "lpp_source=mysource", "-a", "filesets='mypackage'")
+ @provider.install
end
- describe "when installing" do
- it "should install a package" do
- @resource.stubs(:should).with(:ensure).returns(:installed)
- @provider.expects(:nimclient).with("-o", "cust", "-a", "installp_flags=acgwXY", "-a", "lpp_source=mysource", "-a", "filesets='mypackage'")
- @provider.install
- end
-
- it "should install a versioned package" do
- @resource.stubs(:should).with(:ensure).returns("1.2.3.4")
- @provider.expects(:nimclient).with("-o", "cust", "-a", "installp_flags=acgwXY", "-a", "lpp_source=mysource", "-a", "filesets='mypackage 1.2.3.4'")
- @provider.install
- end
+ it "should install a versioned package" do
+ @resource.stubs(:should).with(:ensure).returns("1.2.3.4")
+ @provider.expects(:nimclient).with("-o", "cust", "-a", "installp_flags=acgwXY", "-a", "lpp_source=mysource", "-a", "filesets='mypackage 1.2.3.4'")
+ @provider.install
end
+ end
end
diff --git a/spec/unit/provider/package/pkg_spec.rb b/spec/unit/provider/package/pkg_spec.rb
index b29405e..1544b8b 100644
--- a/spec/unit/provider/package/pkg_spec.rb
+++ b/spec/unit/provider/package/pkg_spec.rb
@@ -5,59 +5,59 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
provider = Puppet::Type.type(:package).provider(:pkg)
describe provider do
- before do
- @resource = stub 'resource', :[] => "dummy"
- @provider = provider.new(@resource)
-
- @fakeresult = "install ok installed dummy 1.0\n"
- end
-
- def self.it_should_respond_to(*actions)
- actions.each do |action|
- it "should respond to :#{action}" do
- @provider.should respond_to(action)
- end
- end
- end
-
- it_should_respond_to :install, :uninstall, :update, :query, :latest
-
- it "should be versionable" do
- provider.should_not be_versionable
- end
-
- it "should use :install to update" do
- @provider.expects(:install)
- @provider.update
- end
-
- it "should parse a line correctly" do
- result = provider.parse_line("dummy 1.0 at 1.0-1.0 installed ----")
- result.should == {:name => "dummy", :version => "1.0 at 1.0-1.0",
- :ensure => :present, :status => "installed",
- :provider => :pkg, :error => "ok"}
- end
-
- it "should fail to parse an incorrect line" do
- result = provider.parse_line("foo")
- result.should be_nil
- end
-
- it "should fail to list a missing package" do
- @provider.expects(:pkg).with(:list, "-H", "dummy").returns "1"
- @provider.query.should == {:status=>"missing", :ensure=>:absent,
- :name=>"dummy", :error=>"ok"}
- end
-
- it "should fail to list a package when it can't parse the output line" do
- @provider.expects(:pkg).with(:list, "-H", "dummy").returns "failed"
- @provider.query.should == {:status=>"missing", :ensure=>:absent, :name=>"dummy", :error=>"ok"}
- end
-
- it "should list package correctly" do
- @provider.expects(:pkg).with(:list, "-H", "dummy").returns "dummy 1.0 at 1.0-1.0 installed ----"
- @provider.query.should == {:name => "dummy", :version => "1.0 at 1.0-1.0",
- :ensure => :present, :status => "installed",
- :provider => :pkg, :error => "ok"}
- end
+ before do
+ @resource = stub 'resource', :[] => "dummy"
+ @provider = provider.new(@resource)
+
+ @fakeresult = "install ok installed dummy 1.0\n"
+ end
+
+ def self.it_should_respond_to(*actions)
+ actions.each do |action|
+ it "should respond to :#{action}" do
+ @provider.should respond_to(action)
+ end
+ end
+ end
+
+ it_should_respond_to :install, :uninstall, :update, :query, :latest
+
+ it "should be versionable" do
+ provider.should_not be_versionable
+ end
+
+ it "should use :install to update" do
+ @provider.expects(:install)
+ @provider.update
+ end
+
+ it "should parse a line correctly" do
+ result = provider.parse_line("dummy 1.0 at 1.0-1.0 installed ----")
+ result.should == {:name => "dummy", :version => "1.0 at 1.0-1.0",
+ :ensure => :present, :status => "installed",
+ :provider => :pkg, :error => "ok"}
+ end
+
+ it "should fail to parse an incorrect line" do
+ result = provider.parse_line("foo")
+ result.should be_nil
+ end
+
+ it "should fail to list a missing package" do
+ @provider.expects(:pkg).with(:list, "-H", "dummy").returns "1"
+ @provider.query.should == {:status=>"missing", :ensure=>:absent,
+ :name=>"dummy", :error=>"ok"}
+ end
+
+ it "should fail to list a package when it can't parse the output line" do
+ @provider.expects(:pkg).with(:list, "-H", "dummy").returns "failed"
+ @provider.query.should == {:status=>"missing", :ensure=>:absent, :name=>"dummy", :error=>"ok"}
+ end
+
+ it "should list package correctly" do
+ @provider.expects(:pkg).with(:list, "-H", "dummy").returns "dummy 1.0 at 1.0-1.0 installed ----"
+ @provider.query.should == {:name => "dummy", :version => "1.0 at 1.0-1.0",
+ :ensure => :present, :status => "installed",
+ :provider => :pkg, :error => "ok"}
+ end
end
diff --git a/spec/unit/provider/package/pkgdmg_spec.rb b/spec/unit/provider/package/pkgdmg_spec.rb
index d4c5a92..1fd5b4a 100755
--- a/spec/unit/provider/package/pkgdmg_spec.rb
+++ b/spec/unit/provider/package/pkgdmg_spec.rb
@@ -5,80 +5,80 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
provider = Puppet::Type.type(:package).provider(:pkgdmg)
describe provider do
- before do
- @resource = stub 'resource', :[] => "dummypkgdmg"
- @provider = provider.new(@resource)
-
- @fakemountpoint = "/tmp/dmg.foo"
- @fakepkgfile = "/tmp/test.pkg"
- @fakehdiutilinfo = {"system-entities" => [{"mount-point" => @fakemountpoint}] }
- @fakehdiutilplist = Plist::Emit.dump(@fakehdiutilinfo)
-
- @hdiutilmountargs = ["mount", "-plist", "-nobrowse", "-readonly",
- "-noidme", "-mountrandom", "/tmp"]
+ before do
+ @resource = stub 'resource', :[] => "dummypkgdmg"
+ @provider = provider.new(@resource)
+
+ @fakemountpoint = "/tmp/dmg.foo"
+ @fakepkgfile = "/tmp/test.pkg"
+ @fakehdiutilinfo = {"system-entities" => [{"mount-point" => @fakemountpoint}] }
+ @fakehdiutilplist = Plist::Emit.dump(@fakehdiutilinfo)
+
+ @hdiutilmountargs = ["mount", "-plist", "-nobrowse", "-readonly",
+ "-noidme", "-mountrandom", "/tmp"]
+ end
+
+ it "should not be versionable" do
+ provider.versionable?.should be_false
+ end
+
+ it "should not be uninstallable" do
+ provider.uninstallable?.should be_false
+ end
+
+ describe "when installing it should fail when" do
+ it "no source is specified" do
+ @resource.stubs(:[]).with(:source).returns nil
+ lambda { @provider.install }.should raise_error(Puppet::Error)
end
- it "should not be versionable" do
- provider.versionable?.should be_false
+ it "no name is specified" do
+ @resource.stubs(:[]).with(:name).returns nil
+ lambda { @provider.install }.should raise_error(Puppet::Error)
end
- it "should not be uninstallable" do
- provider.uninstallable?.should be_false
+ it "the source does not end in .dmg or .pkg" do
+ @resource.stubs(:[]).with(:source).returns "notendingindotdmgorpkg"
+ lambda { @provider.install }.should raise_error(Puppet::Error)
end
- describe "when installing it should fail when" do
- it "no source is specified" do
- @resource.stubs(:[]).with(:source).returns nil
- lambda { @provider.install }.should raise_error(Puppet::Error)
- end
-
- it "no name is specified" do
- @resource.stubs(:[]).with(:name).returns nil
- lambda { @provider.install }.should raise_error(Puppet::Error)
- end
-
- it "the source does not end in .dmg or .pkg" do
- @resource.stubs(:[]).with(:source).returns "notendingindotdmgorpkg"
- lambda { @provider.install }.should raise_error(Puppet::Error)
- end
-
- it "a disk image with no system entities is mounted" do
- @provider.stubs(:[]).with(:hdiutil).returns ""
- lambda { @provider.install }.should raise_error(Puppet::Error)
- end
+ it "a disk image with no system entities is mounted" do
+ @provider.stubs(:[]).with(:hdiutil).returns ""
+ lambda { @provider.install }.should raise_error(Puppet::Error)
end
+ end
- # These tests shouldn't be this messy. The pkgdmg provider needs work...
- describe "when installing a pkgdmg" do
- before do
- fh = mock 'filehandle'
- fh.stubs(:path).yields "/tmp/foo"
- @resource.stubs(:[]).with(:source).returns "foo.dmg"
- File.stubs(:open).yields fh
- end
-
- it "should call hdiutil to mount and eject the disk image" do
- Dir.stubs(:entries).returns []
- @provider.class.expects(:hdiutil).with("eject", @fakemountpoint).returns 0
- @provider.class.expects(:hdiutil).with("mount", "-plist", "-nobrowse", "-readonly", "-noidme", "-mountrandom", "/tmp", nil).returns @fakehdiutilplist
- @provider.install
- end
+ # These tests shouldn't be this messy. The pkgdmg provider needs work...
+ describe "when installing a pkgdmg" do
+ before do
+ fh = mock 'filehandle'
+ fh.stubs(:path).yields "/tmp/foo"
+ @resource.stubs(:[]).with(:source).returns "foo.dmg"
+ File.stubs(:open).yields fh
+ end
- it "should call installpkg if a pkg/mpkg is found on the dmg" do
- Dir.stubs(:entries).returns ["foo.pkg"]
- @provider.class.stubs(:hdiutil).returns @fakehdiutilplist
- @provider.class.expects(:installpkg).with("#{@fakemountpoint}/foo.pkg", @resource[:name], "foo.dmg").returns ""
- @provider.install
- end
+ it "should call hdiutil to mount and eject the disk image" do
+ Dir.stubs(:entries).returns []
+ @provider.class.expects(:hdiutil).with("eject", @fakemountpoint).returns 0
+ @provider.class.expects(:hdiutil).with("mount", "-plist", "-nobrowse", "-readonly", "-noidme", "-mountrandom", "/tmp", nil).returns @fakehdiutilplist
+ @provider.install
end
- describe "when installing flat pkg file" do
- it "should call installpkg if a flat pkg file is found instead of a .dmg image" do
- @resource.stubs(:[]).with(:source).returns "/tmp/test.pkg"
- @resource.stubs(:[]).with(:name).returns "testpkg"
- @provider.class.expects(:installpkgdmg).with("#{@fakepkgfile}", "testpkg").returns ""
- @provider.install
- end
+ it "should call installpkg if a pkg/mpkg is found on the dmg" do
+ Dir.stubs(:entries).returns ["foo.pkg"]
+ @provider.class.stubs(:hdiutil).returns @fakehdiutilplist
+ @provider.class.expects(:installpkg).with("#{@fakemountpoint}/foo.pkg", @resource[:name], "foo.dmg").returns ""
+ @provider.install
end
+ end
+
+ describe "when installing flat pkg file" do
+ it "should call installpkg if a flat pkg file is found instead of a .dmg image" do
+ @resource.stubs(:[]).with(:source).returns "/tmp/test.pkg"
+ @resource.stubs(:[]).with(:name).returns "testpkg"
+ @provider.class.expects(:installpkgdmg).with("#{@fakepkgfile}", "testpkg").returns ""
+ @provider.install
+ end
+ end
end
diff --git a/spec/unit/provider/package/zypper_spec.rb b/spec/unit/provider/package/zypper_spec.rb
index b7f3687..5ac13b6 100644
--- a/spec/unit/provider/package/zypper_spec.rb
+++ b/spec/unit/provider/package/zypper_spec.rb
@@ -5,77 +5,77 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
provider_class = Puppet::Type.type(:package).provider(:zypper)
describe provider_class do
- before(:each) do
- # Create a mock resource
- @resource = stub 'resource'
-
- # A catch all; no parameters set
- @resource.stubs(:[]).returns(nil)
-
- # But set name and source
- @resource.stubs(:[]).with(:name).returns "mypackage"
- @resource.stubs(:[]).with(:ensure).returns :installed
- @resource.stubs(:command).with(:zypper).returns "/usr/bin/zypper"
-
- @provider = provider_class.new(@resource)
- end
-
- it "should have an install method" do
- @provider = provider_class.new
- @provider.should respond_to(:install)
- end
-
- it "should have a latest method" do
- @provider = provider_class.new
- @provider.should respond_to(:uninstall)
- end
-
- it "should have an update method" do
- @provider = provider_class.new
- @provider.should respond_to(:update)
- end
-
- it "should have a latest method" do
- @provider = provider_class.new
- @provider.should respond_to(:latest)
+ before(:each) do
+ # Create a mock resource
+ @resource = stub 'resource'
+
+ # A catch all; no parameters set
+ @resource.stubs(:[]).returns(nil)
+
+ # But set name and source
+ @resource.stubs(:[]).with(:name).returns "mypackage"
+ @resource.stubs(:[]).with(:ensure).returns :installed
+ @resource.stubs(:command).with(:zypper).returns "/usr/bin/zypper"
+
+ @provider = provider_class.new(@resource)
+ end
+
+ it "should have an install method" do
+ @provider = provider_class.new
+ @provider.should respond_to(:install)
+ end
+
+ it "should have a latest method" do
+ @provider = provider_class.new
+ @provider.should respond_to(:uninstall)
+ end
+
+ it "should have an update method" do
+ @provider = provider_class.new
+ @provider.should respond_to(:update)
+ end
+
+ it "should have a latest method" do
+ @provider = provider_class.new
+ @provider.should respond_to(:latest)
+ end
+
+ describe "when installing" do
+ it "should use a command-line with versioned package'" do
+ @resource.stubs(:should).with(:ensure).returns "1.2.3-4.5.6"
+ @provider.expects(:zypper).with('--quiet', :install, '-l', '-y', 'mypackage-1.2.3-4.5.6')
+ @provider.expects(:query).returns "mypackage 0 1.2.3 4.5.6 x86_64"
+ @provider.install
end
- describe "when installing" do
- it "should use a command-line with versioned package'" do
- @resource.stubs(:should).with(:ensure).returns "1.2.3-4.5.6"
- @provider.expects(:zypper).with('--quiet', :install, '-l', '-y', 'mypackage-1.2.3-4.5.6')
- @provider.expects(:query).returns "mypackage 0 1.2.3 4.5.6 x86_64"
- @provider.install
- end
-
- it "should use a command-line without versioned package" do
- @resource.stubs(:should).with(:ensure).returns :latest
- @provider.expects(:zypper).with('--quiet', :install, '-l', '-y', 'mypackage')
- @provider.expects(:query).returns "mypackage 0 1.2.3 4.5.6 x86_64"
- @provider.install
- end
+ it "should use a command-line without versioned package" do
+ @resource.stubs(:should).with(:ensure).returns :latest
+ @provider.expects(:zypper).with('--quiet', :install, '-l', '-y', 'mypackage')
+ @provider.expects(:query).returns "mypackage 0 1.2.3 4.5.6 x86_64"
+ @provider.install
end
+ end
- describe "when updating" do
- it "should call install method of instance" do
- @provider.expects(:install)
- @provider.update
- end
+ describe "when updating" do
+ it "should call install method of instance" do
+ @provider.expects(:install)
+ @provider.update
end
+ end
- describe "when getting latest version" do
- it "should return a version string" do
+ describe "when getting latest version" do
+ it "should return a version string" do
- fake_data = "Loading repository data...
+ fake_data = "Loading repository data...
Reading installed packages...
S | Repository | Name | Version | Arch
--+----------------+-----------------------+-----------------+-------
v | SLES11-Updates | cups | 1.1.1 | x86_64
v | SLES11-Updates | mypackage | 1.3.9h-8.20.1 | x86_64"
- @provider.expects(:zypper).with("list-updates").returns fake_data
- @provider.latest.should == "1.3.9h-8.20.1"
- end
+ @provider.expects(:zypper).with("list-updates").returns fake_data
+ @provider.latest.should == "1.3.9h-8.20.1"
end
+ end
end
diff --git a/spec/unit/provider/parsedfile_spec.rb b/spec/unit/provider/parsedfile_spec.rb
index f20b6b2..d40f773 100755
--- a/spec/unit/provider/parsedfile_spec.rb
+++ b/spec/unit/provider/parsedfile_spec.rb
@@ -6,90 +6,90 @@ require 'puppet/provider/parsedfile'
# Most of the tests for this are still in test/ral/provider/parsedfile.rb.
describe Puppet::Provider::ParsedFile do
- before do
- @class = Class.new(Puppet::Provider::ParsedFile)
- end
+ before do
+ @class = Class.new(Puppet::Provider::ParsedFile)
+ end
- describe "when looking up records loaded from disk" do
- it "should return nil if no records have been loaded" do
- @class.record?("foo").should be_nil
- end
+ describe "when looking up records loaded from disk" do
+ it "should return nil if no records have been loaded" do
+ @class.record?("foo").should be_nil
+ end
+ end
+
+ describe "when generating a list of instances" do
+ it "should return an instance for each record parsed from all of the registered targets" do
+ @class.expects(:targets).returns %w{/one /two}
+ @class.stubs(:skip_record?).returns false
+ one = [:uno1, :uno2]
+ two = [:dos1, :dos2]
+ @class.expects(:prefetch_target).with("/one").returns one
+ @class.expects(:prefetch_target).with("/two").returns two
+
+ results = []
+ (one + two).each do |inst|
+ results << inst.to_s + "_instance"
+ @class.expects(:new).with(inst).returns(results[-1])
+ end
+
+ @class.instances.should == results
end
- describe "when generating a list of instances" do
- it "should return an instance for each record parsed from all of the registered targets" do
- @class.expects(:targets).returns %w{/one /two}
- @class.stubs(:skip_record?).returns false
- one = [:uno1, :uno2]
- two = [:dos1, :dos2]
- @class.expects(:prefetch_target).with("/one").returns one
- @class.expects(:prefetch_target).with("/two").returns two
-
- results = []
- (one + two).each do |inst|
- results << inst.to_s + "_instance"
- @class.expects(:new).with(inst).returns(results[-1])
- end
-
- @class.instances.should == results
- end
-
- it "should skip specified records" do
- @class.expects(:targets).returns %w{/one}
- @class.expects(:skip_record?).with(:uno).returns false
- @class.expects(:skip_record?).with(:dos).returns true
- one = [:uno, :dos]
- @class.expects(:prefetch_target).returns one
-
- @class.expects(:new).with(:uno).returns "eh"
- @class.expects(:new).with(:dos).never
-
- @class.instances
- end
+ it "should skip specified records" do
+ @class.expects(:targets).returns %w{/one}
+ @class.expects(:skip_record?).with(:uno).returns false
+ @class.expects(:skip_record?).with(:dos).returns true
+ one = [:uno, :dos]
+ @class.expects(:prefetch_target).returns one
+
+ @class.expects(:new).with(:uno).returns "eh"
+ @class.expects(:new).with(:dos).never
+
+ @class.instances
end
+ end
- describe "when flushing a file's records to disk" do
- before do
- # This way we start with some @records, like we would in real life.
- @class.stubs(:retrieve).returns []
- @class.default_target = "/foo/bar"
- @class.initvars
- @class.prefetch
+ describe "when flushing a file's records to disk" do
+ before do
+ # This way we start with some @records, like we would in real life.
+ @class.stubs(:retrieve).returns []
+ @class.default_target = "/foo/bar"
+ @class.initvars
+ @class.prefetch
- @filetype = Puppet::Util::FileType.filetype(:flat).new("/my/file")
- Puppet::Util::FileType.filetype(:flat).stubs(:new).with("/my/file").returns @filetype
+ @filetype = Puppet::Util::FileType.filetype(:flat).new("/my/file")
+ Puppet::Util::FileType.filetype(:flat).stubs(:new).with("/my/file").returns @filetype
- @filetype.stubs(:write)
- end
+ @filetype.stubs(:write)
+ end
- it "should back up the file being written if the filetype can be backed up" do
- @filetype.expects(:backup)
+ it "should back up the file being written if the filetype can be backed up" do
+ @filetype.expects(:backup)
- @class.flush_target("/my/file")
- end
+ @class.flush_target("/my/file")
+ end
- it "should not try to back up the file if the filetype cannot be backed up" do
- @filetype = Puppet::Util::FileType.filetype(:ram).new("/my/file")
- Puppet::Util::FileType.filetype(:flat).expects(:new).returns @filetype
+ it "should not try to back up the file if the filetype cannot be backed up" do
+ @filetype = Puppet::Util::FileType.filetype(:ram).new("/my/file")
+ Puppet::Util::FileType.filetype(:flat).expects(:new).returns @filetype
- @filetype.stubs(:write)
+ @filetype.stubs(:write)
- @class.flush_target("/my/file")
- end
+ @class.flush_target("/my/file")
+ end
- it "should not back up the file more than once between calls to 'prefetch'" do
- @filetype.expects(:backup).once
+ it "should not back up the file more than once between calls to 'prefetch'" do
+ @filetype.expects(:backup).once
- @class.flush_target("/my/file")
- @class.flush_target("/my/file")
- end
+ @class.flush_target("/my/file")
+ @class.flush_target("/my/file")
+ end
- it "should back the file up again once the file has been reread" do
- @filetype.expects(:backup).times(2)
+ it "should back the file up again once the file has been reread" do
+ @filetype.expects(:backup).times(2)
- @class.flush_target("/my/file")
- @class.prefetch
- @class.flush_target("/my/file")
- end
+ @class.flush_target("/my/file")
+ @class.prefetch
+ @class.flush_target("/my/file")
end
+ end
end
diff --git a/spec/unit/provider/selboolean_spec.rb b/spec/unit/provider/selboolean_spec.rb
index 2004485..b37b44b 100755
--- a/spec/unit/provider/selboolean_spec.rb
+++ b/spec/unit/provider/selboolean_spec.rb
@@ -5,33 +5,33 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
provider_class = Puppet::Type.type(:selboolean).provider(:getsetsebool)
describe provider_class do
- before :each do
- @resource = stub("resource", :name => "foo")
- @resource.stubs(:[]).returns "foo"
- @provider = provider_class.new(@resource)
- end
-
- it "should return :on when getsebool returns on" do
- @provider.expects(:getsebool).with("foo").returns "foo --> on\n"
- @provider.value.should == :on
- end
-
- it "should return :off when getsebool returns on" do
- @provider.expects(:getsebool).with("foo").returns "foo --> off\n"
- @provider.value.should == :off
- end
-
- it "should call execpipe when updating boolean setting" do
- @provider.expects(:command).with(:setsebool).returns "/usr/sbin/setsebool"
- @provider.expects(:execpipe).with("/usr/sbin/setsebool foo off")
- @provider.value = :off
- end
-
- it "should call execpipe with -P when updating persistent boolean setting" do
- @resource.stubs(:[]).with(:persistent).returns :true
- @provider.expects(:command).with(:setsebool).returns "/usr/sbin/setsebool"
- @provider.expects(:execpipe).with("/usr/sbin/setsebool -P foo off")
- @provider.value = :off
- end
+ before :each do
+ @resource = stub("resource", :name => "foo")
+ @resource.stubs(:[]).returns "foo"
+ @provider = provider_class.new(@resource)
+ end
+
+ it "should return :on when getsebool returns on" do
+ @provider.expects(:getsebool).with("foo").returns "foo --> on\n"
+ @provider.value.should == :on
+ end
+
+ it "should return :off when getsebool returns on" do
+ @provider.expects(:getsebool).with("foo").returns "foo --> off\n"
+ @provider.value.should == :off
+ end
+
+ it "should call execpipe when updating boolean setting" do
+ @provider.expects(:command).with(:setsebool).returns "/usr/sbin/setsebool"
+ @provider.expects(:execpipe).with("/usr/sbin/setsebool foo off")
+ @provider.value = :off
+ end
+
+ it "should call execpipe with -P when updating persistent boolean setting" do
+ @resource.stubs(:[]).with(:persistent).returns :true
+ @provider.expects(:command).with(:setsebool).returns "/usr/sbin/setsebool"
+ @provider.expects(:execpipe).with("/usr/sbin/setsebool -P foo off")
+ @provider.value = :off
+ end
end
diff --git a/spec/unit/provider/selmodule_spec.rb b/spec/unit/provider/selmodule_spec.rb
index ed20ea9..fda6d0d 100755
--- a/spec/unit/provider/selmodule_spec.rb
+++ b/spec/unit/provider/selmodule_spec.rb
@@ -10,57 +10,57 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
provider_class = Puppet::Type.type(:selmodule).provider(:semodule)
describe provider_class do
- before :each do
- @resource = stub("resource", :name => "foo")
- @resource.stubs(:[]).returns "foo"
- @provider = provider_class.new(@resource)
- end
-
- describe "exists? method" do
- it "should find a module if it is already loaded" do
- @provider.expects(:command).with(:semodule).returns "/usr/sbin/semodule"
- @provider.expects(:execpipe).with("/usr/sbin/semodule --list").yields ["bar\t1.2.3\n", "foo\t4.4.4\n", "bang\t1.0.0\n"]
- @provider.exists?.should == :true
- end
+ before :each do
+ @resource = stub("resource", :name => "foo")
+ @resource.stubs(:[]).returns "foo"
+ @provider = provider_class.new(@resource)
+ end
- it "should return nil if not loaded" do
- @provider.expects(:command).with(:semodule).returns "/usr/sbin/semodule"
- @provider.expects(:execpipe).with("/usr/sbin/semodule --list").yields ["bar\t1.2.3\n", "bang\t1.0.0\n"]
- @provider.exists?.should be_nil
- end
+ describe "exists? method" do
+ it "should find a module if it is already loaded" do
+ @provider.expects(:command).with(:semodule).returns "/usr/sbin/semodule"
+ @provider.expects(:execpipe).with("/usr/sbin/semodule --list").yields ["bar\t1.2.3\n", "foo\t4.4.4\n", "bang\t1.0.0\n"]
+ @provider.exists?.should == :true
+ end
- it "should return nil if no modules are loaded" do
- @provider.expects(:command).with(:semodule).returns "/usr/sbin/semodule"
- @provider.expects(:execpipe).with("/usr/sbin/semodule --list").yields []
- @provider.exists?.should be_nil
- end
+ it "should return nil if not loaded" do
+ @provider.expects(:command).with(:semodule).returns "/usr/sbin/semodule"
+ @provider.expects(:execpipe).with("/usr/sbin/semodule --list").yields ["bar\t1.2.3\n", "bang\t1.0.0\n"]
+ @provider.exists?.should be_nil
end
- describe "selmodversion_file" do
- it "should return 1.5.0 for the example policy file" do
- @provider.expects(:selmod_name_to_filename).returns "#{File.dirname(__FILE__)}/selmodule-example.pp"
- @provider.selmodversion_file.should == "1.5.0"
- end
+ it "should return nil if no modules are loaded" do
+ @provider.expects(:command).with(:semodule).returns "/usr/sbin/semodule"
+ @provider.expects(:execpipe).with("/usr/sbin/semodule --list").yields []
+ @provider.exists?.should be_nil
end
+ end
- describe "syncversion" do
- it "should return :true if loaded and file modules are in sync" do
- @provider.expects(:selmodversion_loaded).returns "1.5.0"
- @provider.expects(:selmodversion_file).returns "1.5.0"
- @provider.syncversion.should == :true
- end
+ describe "selmodversion_file" do
+ it "should return 1.5.0 for the example policy file" do
+ @provider.expects(:selmod_name_to_filename).returns "#{File.dirname(__FILE__)}/selmodule-example.pp"
+ @provider.selmodversion_file.should == "1.5.0"
+ end
+ end
- it "should return :false if loaded and file modules are not in sync" do
- @provider.expects(:selmodversion_loaded).returns "1.4.0"
- @provider.expects(:selmodversion_file).returns "1.5.0"
- @provider.syncversion.should == :false
- end
+ describe "syncversion" do
+ it "should return :true if loaded and file modules are in sync" do
+ @provider.expects(:selmodversion_loaded).returns "1.5.0"
+ @provider.expects(:selmodversion_file).returns "1.5.0"
+ @provider.syncversion.should == :true
+ end
- it "should return before checking file version if no loaded policy" do
- @provider.expects(:selmodversion_loaded).returns nil
- @provider.syncversion.should == :false
- end
+ it "should return :false if loaded and file modules are not in sync" do
+ @provider.expects(:selmodversion_loaded).returns "1.4.0"
+ @provider.expects(:selmodversion_file).returns "1.5.0"
+ @provider.syncversion.should == :false
+ end
+ it "should return before checking file version if no loaded policy" do
+ @provider.expects(:selmodversion_loaded).returns nil
+ @provider.syncversion.should == :false
end
+ end
+
end
diff --git a/spec/unit/provider/service/daemontools_spec.rb b/spec/unit/provider/service/daemontools_spec.rb
index 2d61d23..5e8b8d0 100755
--- a/spec/unit/provider/service/daemontools_spec.rb
+++ b/spec/unit/provider/service/daemontools_spec.rb
@@ -10,157 +10,157 @@ provider_class = Puppet::Type.type(:service).provider(:daemontools)
describe provider_class do
- before(:each) do
- # Create a mock resource
- @resource = stub 'resource'
+ before(:each) do
+ # Create a mock resource
+ @resource = stub 'resource'
- @provider = provider_class.new
- @servicedir = "/etc/service"
- @provider.servicedir=@servicedir
- @daemondir = "/var/lib/service"
- @provider.class.defpath=@daemondir
+ @provider = provider_class.new
+ @servicedir = "/etc/service"
+ @provider.servicedir=@servicedir
+ @daemondir = "/var/lib/service"
+ @provider.class.defpath=@daemondir
- # A catch all; no parameters set
- @resource.stubs(:[]).returns(nil)
+ # A catch all; no parameters set
+ @resource.stubs(:[]).returns(nil)
- # But set name, source and path (because we won't run
- # the thing that will fetch the resource path from the provider)
- @resource.stubs(:[]).with(:name).returns "myservice"
- @resource.stubs(:[]).with(:ensure).returns :enabled
- @resource.stubs(:[]).with(:path).returns @daemondir
- @resource.stubs(:ref).returns "Service[myservice]"
+ # But set name, source and path (because we won't run
+ # the thing that will fetch the resource path from the provider)
+ @resource.stubs(:[]).with(:name).returns "myservice"
+ @resource.stubs(:[]).with(:ensure).returns :enabled
+ @resource.stubs(:[]).with(:path).returns @daemondir
+ @resource.stubs(:ref).returns "Service[myservice]"
- @provider.resource = @resource
+ @provider.resource = @resource
- @provider.stubs(:command).with(:svc).returns "svc"
- @provider.stubs(:command).with(:svstat).returns "svstat"
+ @provider.stubs(:command).with(:svc).returns "svc"
+ @provider.stubs(:command).with(:svstat).returns "svstat"
- @provider.stubs(:svc)
- @provider.stubs(:svstat)
- end
+ @provider.stubs(:svc)
+ @provider.stubs(:svstat)
+ end
- it "should have a restart method" do
- @provider.should respond_to(:restart)
- end
+ it "should have a restart method" do
+ @provider.should respond_to(:restart)
+ end
- it "should have a start method" do
- @provider.should respond_to(:start)
- end
+ it "should have a start method" do
+ @provider.should respond_to(:start)
+ end
- it "should have a stop method" do
- @provider.should respond_to(:stop)
- end
+ it "should have a stop method" do
+ @provider.should respond_to(:stop)
+ end
- it "should have an enabled? method" do
- @provider.should respond_to(:enabled?)
- end
+ it "should have an enabled? method" do
+ @provider.should respond_to(:enabled?)
+ end
- it "should have an enable method" do
- @provider.should respond_to(:enable)
- end
+ it "should have an enable method" do
+ @provider.should respond_to(:enable)
+ end
- it "should have a disable method" do
- @provider.should respond_to(:disable)
- end
+ it "should have a disable method" do
+ @provider.should respond_to(:disable)
+ end
- describe "when starting" do
- it "should use 'svc' to start the service" do
- @provider.stubs(:enabled?).returns :true
- @provider.expects(:svc).with("-u", "/etc/service/myservice")
+ describe "when starting" do
+ it "should use 'svc' to start the service" do
+ @provider.stubs(:enabled?).returns :true
+ @provider.expects(:svc).with("-u", "/etc/service/myservice")
- @provider.start
- end
+ @provider.start
+ end
- it "should enable the service if it is not enabled" do
- @provider.stubs(:svc)
+ it "should enable the service if it is not enabled" do
+ @provider.stubs(:svc)
- @provider.expects(:enabled?).returns :false
- @provider.expects(:enable)
+ @provider.expects(:enabled?).returns :false
+ @provider.expects(:enable)
- @provider.start
- end
+ @provider.start
end
+ end
- describe "when stopping" do
- it "should use 'svc' to stop the service" do
- @provider.stubs(:disable)
- @provider.expects(:svc).with("-d", "/etc/service/myservice")
+ describe "when stopping" do
+ it "should use 'svc' to stop the service" do
+ @provider.stubs(:disable)
+ @provider.expects(:svc).with("-d", "/etc/service/myservice")
- @provider.stop
- end
+ @provider.stop
end
+ end
- describe "when restarting" do
- it "should use 'svc' to restart the service" do
- @provider.expects(:svc).with("-t", "/etc/service/myservice")
+ describe "when restarting" do
+ it "should use 'svc' to restart the service" do
+ @provider.expects(:svc).with("-t", "/etc/service/myservice")
- @provider.restart
- end
+ @provider.restart
end
+ end
- describe "when enabling" do
- it "should create a symlink between daemon dir and service dir" do
- FileTest.stubs(:symlink?).returns(false)
- File.expects(:symlink).with(File.join(@daemondir,"myservice"), File.join(@servicedir,"myservice")).returns(0)
- @provider.enable
- end
+ describe "when enabling" do
+ it "should create a symlink between daemon dir and service dir" do
+ FileTest.stubs(:symlink?).returns(false)
+ File.expects(:symlink).with(File.join(@daemondir,"myservice"), File.join(@servicedir,"myservice")).returns(0)
+ @provider.enable
+ end
+ end
+
+ describe "when disabling" do
+ it "should remove the symlink between daemon dir and service dir" do
+ FileTest.stubs(:directory?).returns(false)
+ FileTest.stubs(:symlink?).returns(true)
+ File.expects(:unlink).with(File.join(@servicedir,"myservice"))
+ @provider.stubs(:texecute).returns("")
+ @provider.disable
end
- describe "when disabling" do
- it "should remove the symlink between daemon dir and service dir" do
- FileTest.stubs(:directory?).returns(false)
- FileTest.stubs(:symlink?).returns(true)
- File.expects(:unlink).with(File.join(@servicedir,"myservice"))
- @provider.stubs(:texecute).returns("")
- @provider.disable
- end
-
- it "should stop the service" do
- FileTest.stubs(:directory?).returns(false)
- FileTest.stubs(:symlink?).returns(true)
- File.stubs(:unlink)
- @provider.expects(:stop)
- @provider.disable
- end
+ it "should stop the service" do
+ FileTest.stubs(:directory?).returns(false)
+ FileTest.stubs(:symlink?).returns(true)
+ File.stubs(:unlink)
+ @provider.expects(:stop)
+ @provider.disable
end
+ end
- describe "when checking if the service is enabled?" do
- it "should return true if it is running" do
- @provider.stubs(:status).returns(:running)
+ describe "when checking if the service is enabled?" do
+ it "should return true if it is running" do
+ @provider.stubs(:status).returns(:running)
- @provider.enabled?.should == :true
- end
+ @provider.enabled?.should == :true
+ end
- [true, false].each do |t|
- it "should return #{t} if the symlink exists" do
- @provider.stubs(:status).returns(:stopped)
- FileTest.stubs(:symlink?).returns(t)
+ [true, false].each do |t|
+ it "should return #{t} if the symlink exists" do
+ @provider.stubs(:status).returns(:stopped)
+ FileTest.stubs(:symlink?).returns(t)
- @provider.enabled?.should == "#{t}".to_sym
- end
- end
+ @provider.enabled?.should == "#{t}".to_sym
+ end
end
+ end
- describe "when checking status" do
- it "should call the external command 'svstat /etc/service/myservice'" do
- @provider.expects(:svstat).with(File.join(@servicedir,"myservice"))
- @provider.status
- end
+ describe "when checking status" do
+ it "should call the external command 'svstat /etc/service/myservice'" do
+ @provider.expects(:svstat).with(File.join(@servicedir,"myservice"))
+ @provider.status
end
+ end
- describe "when checking status" do
- it "and svstat fails, properly raise a Puppet::Error" do
- @provider.expects(:svstat).with(File.join(@servicedir,"myservice")).raises(Puppet::ExecutionFailure, "failure")
- lambda { @provider.status }.should raise_error(Puppet::Error, 'Could not get status for service Service[myservice]: failure')
- end
- it "and svstat returns up, then return :running" do
- @provider.expects(:svstat).with(File.join(@servicedir,"myservice")).returns("/etc/service/myservice: up (pid 454) 954326 seconds")
- @provider.status.should == :running
- end
- it "and svstat returns not running, then return :stopped" do
- @provider.expects(:svstat).with(File.join(@servicedir,"myservice")).returns("/etc/service/myservice: supervise not running")
- @provider.status.should == :stopped
- end
+ describe "when checking status" do
+ it "and svstat fails, properly raise a Puppet::Error" do
+ @provider.expects(:svstat).with(File.join(@servicedir,"myservice")).raises(Puppet::ExecutionFailure, "failure")
+ lambda { @provider.status }.should raise_error(Puppet::Error, 'Could not get status for service Service[myservice]: failure')
+ end
+ it "and svstat returns up, then return :running" do
+ @provider.expects(:svstat).with(File.join(@servicedir,"myservice")).returns("/etc/service/myservice: up (pid 454) 954326 seconds")
+ @provider.status.should == :running
+ end
+ it "and svstat returns not running, then return :stopped" do
+ @provider.expects(:svstat).with(File.join(@servicedir,"myservice")).returns("/etc/service/myservice: supervise not running")
+ @provider.status.should == :stopped
end
+ end
end
diff --git a/spec/unit/provider/service/debian_spec.rb b/spec/unit/provider/service/debian_spec.rb
index 1d30eb8..8dee2ee 100755
--- a/spec/unit/provider/service/debian_spec.rb
+++ b/spec/unit/provider/service/debian_spec.rb
@@ -9,81 +9,81 @@ provider_class = Puppet::Type.type(:service).provider(:debian)
describe provider_class do
- before(:each) do
- # Create a mock resource
- @resource = stub 'resource'
+ before(:each) do
+ # Create a mock resource
+ @resource = stub 'resource'
- @provider = provider_class.new
+ @provider = provider_class.new
- # A catch all; no parameters set
- @resource.stubs(:[]).returns(nil)
+ # A catch all; no parameters set
+ @resource.stubs(:[]).returns(nil)
- # But set name, source and path
- @resource.stubs(:[]).with(:name).returns "myservice"
- @resource.stubs(:[]).with(:ensure).returns :enabled
- @resource.stubs(:ref).returns "Service[myservice]"
+ # But set name, source and path
+ @resource.stubs(:[]).with(:name).returns "myservice"
+ @resource.stubs(:[]).with(:ensure).returns :enabled
+ @resource.stubs(:ref).returns "Service[myservice]"
- @provider.resource = @resource
+ @provider.resource = @resource
- @provider.stubs(:command).with(:update_rc).returns "update_rc"
- @provider.stubs(:command).with(:invoke_rc).returns "invoke_rc"
+ @provider.stubs(:command).with(:update_rc).returns "update_rc"
+ @provider.stubs(:command).with(:invoke_rc).returns "invoke_rc"
- @provider.stubs(:update_rc)
- @provider.stubs(:invoke_rc)
- end
+ @provider.stubs(:update_rc)
+ @provider.stubs(:invoke_rc)
+ end
+
+ it "should have an enabled? method" do
+ @provider.should respond_to(:enabled?)
+ end
+
+ it "should have an enable method" do
+ @provider.should respond_to(:enable)
+ end
+
+ it "should have a disable method" do
+ @provider.should respond_to(:disable)
+ end
- it "should have an enabled? method" do
- @provider.should respond_to(:enabled?)
+ describe "when enabling" do
+ it "should call update-rc.d twice" do
+ @provider.expects(:update_rc).twice
+ @provider.enable
end
+ end
- it "should have an enable method" do
- @provider.should respond_to(:enable)
+ describe "when disabling" do
+ it "should call update-rc.d twice" do
+ @provider.expects(:update_rc).twice
+ @provider.disable
end
+ end
- it "should have a disable method" do
- @provider.should respond_to(:disable)
+ describe "when checking whether it is enabled" do
+ it "should call Kernel.system() with the appropriate parameters" do
+ @provider.expects(:system).with("/usr/sbin/invoke-rc.d", "--quiet", "--query", @resource[:name], "start").once
+ @provider.enabled?
end
- describe "when enabling" do
- it "should call update-rc.d twice" do
- @provider.expects(:update_rc).twice
- @provider.enable
- end
+ it "should return true when invoke-rc.d exits with 104 status" do
+ @provider.stubs(:system)
+ $CHILD_STATUS.stubs(:exitstatus).returns(104)
+ @provider.enabled?.should == :true
end
- describe "when disabling" do
- it "should call update-rc.d twice" do
- @provider.expects(:update_rc).twice
- @provider.disable
- end
+ it "should return true when invoke-rc.d exits with 106 status" do
+ @provider.stubs(:system)
+ $CHILD_STATUS.stubs(:exitstatus).returns(106)
+ @provider.enabled?.should == :true
end
- describe "when checking whether it is enabled" do
- it "should call Kernel.system() with the appropriate parameters" do
- @provider.expects(:system).with("/usr/sbin/invoke-rc.d", "--quiet", "--query", @resource[:name], "start").once
- @provider.enabled?
- end
-
- it "should return true when invoke-rc.d exits with 104 status" do
- @provider.stubs(:system)
- $CHILD_STATUS.stubs(:exitstatus).returns(104)
- @provider.enabled?.should == :true
- end
-
- it "should return true when invoke-rc.d exits with 106 status" do
- @provider.stubs(:system)
- $CHILD_STATUS.stubs(:exitstatus).returns(106)
- @provider.enabled?.should == :true
- end
-
- # pick a range of non-[104.106] numbers, strings and booleans to test with.
- [-100, -1, 0, 1, 100, "foo", "", :true, :false].each do |exitstatus|
- it "should return false when invoke-rc.d exits with #{exitstatus} status" do
- @provider.stubs(:system)
- $CHILD_STATUS.stubs(:exitstatus).returns(exitstatus)
- @provider.enabled?.should == :false
- end
- end
+ # pick a range of non-[104.106] numbers, strings and booleans to test with.
+ [-100, -1, 0, 1, 100, "foo", "", :true, :false].each do |exitstatus|
+ it "should return false when invoke-rc.d exits with #{exitstatus} status" do
+ @provider.stubs(:system)
+ $CHILD_STATUS.stubs(:exitstatus).returns(exitstatus)
+ @provider.enabled?.should == :false
+ end
end
+ end
end
diff --git a/spec/unit/provider/service/init_spec.rb b/spec/unit/provider/service/init_spec.rb
index b8c2794..bbc88ff 100755
--- a/spec/unit/provider/service/init_spec.rb
+++ b/spec/unit/provider/service/init_spec.rb
@@ -9,160 +9,160 @@ provider_class = Puppet::Type.type(:service).provider(:init)
describe provider_class do
- before :each do
- @class = Puppet::Type.type(:service).provider(:init)
- @resource = stub 'resource'
- @resource.stubs(:[]).returns(nil)
- @resource.stubs(:[]).with(:name).returns "myservice"
+ before :each do
+ @class = Puppet::Type.type(:service).provider(:init)
+ @resource = stub 'resource'
+ @resource.stubs(:[]).returns(nil)
+ @resource.stubs(:[]).with(:name).returns "myservice"
# @resource.stubs(:[]).with(:ensure).returns :enabled
- @resource.stubs(:[]).with(:path).returns ["/service/path","/alt/service/path"]
+ @resource.stubs(:[]).with(:path).returns ["/service/path","/alt/service/path"]
# @resource.stubs(:ref).returns "Service[myservice]"
- File.stubs(:directory?).returns(true)
+ File.stubs(:directory?).returns(true)
+
+ @provider = provider_class.new
+ @provider.resource = @resource
+ end
- @provider = provider_class.new
- @provider.resource = @resource
+ describe "when getting all service instances" do
+ before :each do
+ @services = ['one', 'two', 'three', 'four']
+ Dir.stubs(:entries).returns @services
+ FileTest.stubs(:directory?).returns(true)
+ FileTest.stubs(:executable?).returns(true)
+ @class.stubs(:defpath).returns('tmp')
+ end
+ it "should return instances for all services" do
+ @services.each do |inst|
+ @class.expects(:new).with{|hash| hash[:name] == inst}.returns("#{inst}_instance")
+ end
+ results = @services.collect {|x| "#{x}_instance"}
+ @class.instances.should == results
+ end
+ it "should omit an array of services from exclude list" do
+ exclude = ['two', 'four']
+ (@services-exclude).each do |inst|
+ @class.expects(:new).with{|hash| hash[:name] == inst}.returns("#{inst}_instance")
+ end
+ results = (@services-exclude).collect {|x| "#{x}_instance"}
+ @class.get_services(@class.defpath, exclude).should == results
end
+ it "should omit a single service from the exclude list" do
+ exclude = 'two'
+ (@services-exclude.to_a).each do |inst|
+ @class.expects(:new).with{|hash| hash[:name] == inst}.returns("#{inst}_instance")
+ end
+ results = @services.reject{|x| x==exclude }.collect {|x| "#{x}_instance"}
+ @class.get_services(@class.defpath, exclude).should == results
+ end
+ it "should use defpath" do
+ @services.each do |inst|
+ @class.expects(:new).with{|hash| hash[:path] == @class.defpath}.returns("#{inst}_instance")
+ end
+ results = @services.sort.collect {|x| "#{x}_instance"}
+ @class.instances.sort.should == results
+ end
+ it "should set hasstatus to true for providers" do
+ @services.each do |inst|
+ @class.expects(:new).with{|hash| hash[:name] == inst && hash[:hasstatus] == true}.returns("#{inst}_instance")
+ end
+ results = @services.collect {|x| "#{x}_instance"}
+ @class.instances.should == results
+ end
+ end
- describe "when getting all service instances" do
- before :each do
- @services = ['one', 'two', 'three', 'four']
- Dir.stubs(:entries).returns @services
- FileTest.stubs(:directory?).returns(true)
- FileTest.stubs(:executable?).returns(true)
- @class.stubs(:defpath).returns('tmp')
- end
- it "should return instances for all services" do
- @services.each do |inst|
- @class.expects(:new).with{|hash| hash[:name] == inst}.returns("#{inst}_instance")
- end
- results = @services.collect {|x| "#{x}_instance"}
- @class.instances.should == results
- end
- it "should omit an array of services from exclude list" do
- exclude = ['two', 'four']
- (@services-exclude).each do |inst|
- @class.expects(:new).with{|hash| hash[:name] == inst}.returns("#{inst}_instance")
- end
- results = (@services-exclude).collect {|x| "#{x}_instance"}
- @class.get_services(@class.defpath, exclude).should == results
- end
- it "should omit a single service from the exclude list" do
- exclude = 'two'
- (@services-exclude.to_a).each do |inst|
- @class.expects(:new).with{|hash| hash[:name] == inst}.returns("#{inst}_instance")
- end
- results = @services.reject{|x| x==exclude }.collect {|x| "#{x}_instance"}
- @class.get_services(@class.defpath, exclude).should == results
- end
- it "should use defpath" do
- @services.each do |inst|
- @class.expects(:new).with{|hash| hash[:path] == @class.defpath}.returns("#{inst}_instance")
- end
- results = @services.sort.collect {|x| "#{x}_instance"}
- @class.instances.sort.should == results
- end
- it "should set hasstatus to true for providers" do
- @services.each do |inst|
- @class.expects(:new).with{|hash| hash[:name] == inst && hash[:hasstatus] == true}.returns("#{inst}_instance")
- end
- results = @services.collect {|x| "#{x}_instance"}
- @class.instances.should == results
- end
+ describe "when searching for the init script" do
+ it "should discard paths that do not exist" do
+ File.stubs(:exist?).returns(false)
+ File.stubs(:directory?).returns(false)
+ @provider.paths.should be_empty
end
- describe "when searching for the init script" do
- it "should discard paths that do not exist" do
- File.stubs(:exist?).returns(false)
- File.stubs(:directory?).returns(false)
- @provider.paths.should be_empty
- end
+ it "should discard paths that are not directories" do
+ File.stubs(:exist?).returns(true)
+ File.stubs(:directory?).returns(false)
+ @provider.paths.should be_empty
+ end
- it "should discard paths that are not directories" do
- File.stubs(:exist?).returns(true)
- File.stubs(:directory?).returns(false)
- @provider.paths.should be_empty
- end
+ it "should be able to find the init script in the service path" do
+ File.expects(:stat).with("/service/path/myservice").returns true
+ @provider.initscript.should == "/service/path/myservice"
+ end
+ it "should be able to find the init script in the service path" do
+ File.expects(:stat).with("/alt/service/path/myservice").returns true
+ @provider.initscript.should == "/alt/service/path/myservice"
+ end
+ it "should fail if the service isn't there" do
+ lambda { @provider.initscript }.should raise_error(Puppet::Error, "Could not find init script for 'myservice'")
+ end
+ end
- it "should be able to find the init script in the service path" do
- File.expects(:stat).with("/service/path/myservice").returns true
- @provider.initscript.should == "/service/path/myservice"
- end
- it "should be able to find the init script in the service path" do
- File.expects(:stat).with("/alt/service/path/myservice").returns true
- @provider.initscript.should == "/alt/service/path/myservice"
+ describe "if the init script is present" do
+ before :each do
+ File.stubs(:stat).with("/service/path/myservice").returns true
+ end
+
+ [:start, :stop, :status, :restart].each do |method|
+ it "should have a #{method} method" do
+ @provider.should respond_to(method)
+ end
+ describe "when running #{method}" do
+
+ it "should use any provided explicit command" do
+ @resource.stubs(:[]).with(method).returns "/user/specified/command"
+ @provider.expects(:execute).with { |command, *args| command == ["/user/specified/command"] }
+ @provider.send(method)
end
- it "should fail if the service isn't there" do
- lambda { @provider.initscript }.should raise_error(Puppet::Error, "Could not find init script for 'myservice'")
+
+ it "should pass #{method} to the init script when no explicit command is provided" do
+ @resource.stubs(:[]).with("has#{method}".intern).returns :true
+ @provider.expects(:execute).with { |command, *args| command == ["/service/path/myservice",method]}
+ @provider.send(method)
end
+ end
end
- describe "if the init script is present" do
+ describe "when checking status" do
+ describe "when hasstatus is :true" do
before :each do
- File.stubs(:stat).with("/service/path/myservice").returns true
+ @resource.stubs(:[]).with(:hasstatus).returns :true
end
-
- [:start, :stop, :status, :restart].each do |method|
- it "should have a #{method} method" do
- @provider.should respond_to(method)
- end
- describe "when running #{method}" do
-
- it "should use any provided explicit command" do
- @resource.stubs(:[]).with(method).returns "/user/specified/command"
- @provider.expects(:execute).with { |command, *args| command == ["/user/specified/command"] }
- @provider.send(method)
- end
-
- it "should pass #{method} to the init script when no explicit command is provided" do
- @resource.stubs(:[]).with("has#{method}".intern).returns :true
- @provider.expects(:execute).with { |command, *args| command == ["/service/path/myservice",method]}
- @provider.send(method)
- end
- end
+ it "should execute the command" do
+ @provider.expects(:texecute).with(:status, ['/service/path/myservice', :status], false).returns("")
+ @provider.status
end
-
- describe "when checking status" do
- describe "when hasstatus is :true" do
- before :each do
- @resource.stubs(:[]).with(:hasstatus).returns :true
- end
- it "should execute the command" do
- @provider.expects(:texecute).with(:status, ['/service/path/myservice', :status], false).returns("")
- @provider.status
- end
- it "should consider the process running if the command returns 0" do
- @provider.expects(:texecute).with(:status, ['/service/path/myservice', :status], false).returns("")
- $CHILD_STATUS.stubs(:exitstatus).returns(0)
- @provider.status.should == :running
- end
- [-10,-1,1,10].each { |ec|
- it "should consider the process stopped if the command returns something non-0" do
- @provider.expects(:texecute).with(:status, ['/service/path/myservice', :status], false).returns("")
- $CHILD_STATUS.stubs(:exitstatus).returns(ec)
- @provider.status.should == :stopped
- end
- }
- end
- describe "when hasstatus is not :true" do
- it "should consider the service :running if it has a pid" do
- @provider.expects(:getpid).returns "1234"
- @provider.status.should == :running
- end
- it "should consider the service :stopped if it doesn't have a pid" do
- @provider.expects(:getpid).returns nil
- @provider.status.should == :stopped
- end
- end
+ it "should consider the process running if the command returns 0" do
+ @provider.expects(:texecute).with(:status, ['/service/path/myservice', :status], false).returns("")
+ $CHILD_STATUS.stubs(:exitstatus).returns(0)
+ @provider.status.should == :running
end
-
- describe "when restarting and hasrestart is not :true" do
- it "should stop and restart the process" do
- @provider.expects(:texecute).with(:stop, ['/service/path/myservice', :stop ], true).returns("")
- @provider.expects(:texecute).with(:start,['/service/path/myservice', :start], true).returns("")
- $CHILD_STATUS.stubs(:exitstatus).returns(0)
- @provider.restart
- end
+ [-10,-1,1,10].each { |ec|
+ it "should consider the process stopped if the command returns something non-0" do
+ @provider.expects(:texecute).with(:status, ['/service/path/myservice', :status], false).returns("")
+ $CHILD_STATUS.stubs(:exitstatus).returns(ec)
+ @provider.status.should == :stopped
+ end
+ }
+ end
+ describe "when hasstatus is not :true" do
+ it "should consider the service :running if it has a pid" do
+ @provider.expects(:getpid).returns "1234"
+ @provider.status.should == :running
+ end
+ it "should consider the service :stopped if it doesn't have a pid" do
+ @provider.expects(:getpid).returns nil
+ @provider.status.should == :stopped
end
+ end
+ end
+ describe "when restarting and hasrestart is not :true" do
+ it "should stop and restart the process" do
+ @provider.expects(:texecute).with(:stop, ['/service/path/myservice', :stop ], true).returns("")
+ @provider.expects(:texecute).with(:start,['/service/path/myservice', :start], true).returns("")
+ $CHILD_STATUS.stubs(:exitstatus).returns(0)
+ @provider.restart
+ end
end
+
+ end
end
diff --git a/spec/unit/provider/service/launchd_spec.rb b/spec/unit/provider/service/launchd_spec.rb
index 62570e2..320ee3a 100755
--- a/spec/unit/provider/service/launchd_spec.rb
+++ b/spec/unit/provider/service/launchd_spec.rb
@@ -11,190 +11,190 @@ provider_class = Puppet::Type.type(:service).provider(:launchd)
describe provider_class do
- before :each do
- # Create a mock resource
- @resource = stub 'resource'
+ before :each do
+ # Create a mock resource
+ @resource = stub 'resource'
- @provider = provider_class.new
- @joblabel = "com.foo.food"
- @jobplist = {}
+ @provider = provider_class.new
+ @joblabel = "com.foo.food"
+ @jobplist = {}
+
+ # A catch all; no parameters set
+ @resource.stubs(:[]).returns(nil)
- # A catch all; no parameters set
- @resource.stubs(:[]).returns(nil)
-
- # But set name, ensure and enable
- @resource.stubs(:[]).with(:name).returns @joblabel
- @resource.stubs(:[]).with(:ensure).returns :enabled
- @resource.stubs(:[]).with(:enable).returns :true
- @resource.stubs(:ref).returns "Service[#{@joblabel}]"
-
- # stub out the provider methods that actually touch the filesystem
- # or execute commands
- @provider.stubs(:plist_from_label).returns([@joblabel, @jobplist])
- @provider.stubs(:execute).returns("")
- @provider.stubs(:resource).returns @resource
-
- # We stub this out for the normal case as 10.6 is "special".
- provider_class.stubs(:get_macosx_version_major).returns("10.5")
-
- end
-
- it "should have a start method for #{@provider.object_id}" do
- @provider.should respond_to(:start)
- end
-
- it "should have a stop method" do
- @provider.should respond_to(:stop)
- end
-
- it "should have an enabled? method" do
- @provider.should respond_to(:enabled?)
- end
-
- it "should have an enable method" do
- @provider.should respond_to(:enable)
- end
-
- it "should have a disable method" do
- @provider.should respond_to(:disable)
- end
-
- it "should have a status method" do
- @provider.should respond_to(:status)
- end
-
-
- describe "when checking status" do
- it "should call the external command 'launchctl list' once" do
- @provider.expects(:launchctl).with(:list).returns("rotating-strawberry-madonnas")
- @provider.status
- end
- it "should return stopped if not listed in launchctl list output" do
- @provider.stubs(:launchctl).with(:list).returns("rotating-strawberry-madonnas")
- @provider.status.should == :stopped
- end
- it "should return running if listed in launchctl list output" do
- @provider.stubs(:launchctl).with(:list).returns(@joblabel)
- @provider.status.should == :running
- end
- end
-
- describe "when checking whether the service is enabled" do
- it "should return true if the job plist says disabled is false" do
- @provider.stubs(:plist_from_label).returns(["foo", {"Disabled" => false}])
- @provider.enabled?.should == :true
- end
- it "should return true if the job plist has no disabled key" do
- @provider.stubs(:plist_from_label).returns(["foo", {}])
- @provider.enabled?.should == :true
- end
- it "should return false if the job plist says disabled is true" do
- @provider.stubs(:plist_from_label).returns(["foo", {"Disabled" => true}])
- @provider.enabled?.should == :false
- end
- end
-
- describe "when checking whether the service is enabled on OS X 10.6" do
- it "should return true if the job plist says disabled is true and the global overrides says disabled is false" do
- provider_class.stubs(:get_macosx_version_major).returns("10.6")
- @provider.stubs(:plist_from_label).returns(["foo", {"Disabled" => true}])
- Plist.stubs(:parse_xml).returns({@resource[:name] => {"Disabled" => false}})
- @provider.enabled?.should == :true
- end
- it "should return false if the job plist says disabled is false and the global overrides says disabled is true" do
- provider_class.stubs(:get_macosx_version_major).returns("10.6")
- @provider.stubs(:plist_from_label).returns(["foo", {"Disabled" => false}])
- Plist.stubs(:parse_xml).returns({@resource[:name] => {"Disabled" => true}})
- @provider.enabled?.should == :false
- end
- it "should return true if the job plist and the global overrides have no disabled keys" do
- provider_class.stubs(:get_macosx_version_major).returns("10.6")
- @provider.stubs(:plist_from_label).returns(["foo", {}])
- Plist.stubs(:parse_xml).returns({})
- @provider.enabled?.should == :true
- end
- end
-
- describe "when starting the service" do
- it "should look for the relevant plist once" do
- @provider.expects(:plist_from_label).once
- @provider.start
- end
- it "should execute 'launchctl load' once without writing to the plist if the job is enabled" do
- @provider.stubs(:enabled?).returns :true
- @provider.expects(:execute).with([:launchctl, :load, @resource[:name]]).once
- @provider.start
- end
- it "should execute 'launchctl load' with writing to the plist once if the job is disabled" do
- @provider.stubs(:enabled?).returns :false
- @provider.expects(:execute).with([:launchctl, :load, "-w", @resource[:name]]).once
- @provider.start
- end
- it "should disable the job once if the job is disabled and should be disabled at boot" do
- @provider.stubs(:enabled?).returns :false
- @resource.stubs(:[]).with(:enable).returns :false
- @provider.expects(:disable).once
- @provider.start
- end
- end
-
- describe "when stopping the service" do
- it "should look for the relevant plist once" do
- @provider.expects(:plist_from_label).once
- @provider.stop
- end
- it "should execute 'launchctl unload' once without writing to the plist if the job is disabled" do
- @provider.stubs(:enabled?).returns :false
- @provider.expects(:execute).with([:launchctl, :unload, @resource[:name]]).once
- @provider.stop
- end
- it "should execute 'launchctl unload' with writing to the plist once if the job is enabled" do
- @provider.stubs(:enabled?).returns :true
- @provider.expects(:execute).with([:launchctl, :unload, "-w", @resource[:name]]).once
- @provider.stop
- end
- it "should enable the job once if the job is enabled and should be enabled at boot" do
- @provider.stubs(:enabled?).returns :true
- @resource.stubs(:[]).with(:enable).returns :true
- @provider.expects(:enable).once
- @provider.stop
- end
- end
-
- describe "when enabling the service" do
- it "should look for the relevant plist once" do
- @provider.expects(:plist_from_label).once
- @provider.stop
- end
- it "should check if the job is enabled once" do
- @provider.expects(:enabled?).once
- @provider.stop
- end
- end
-
- describe "when disabling the service" do
- it "should look for the relevant plist once" do
- @provider.expects(:plist_from_label).once
- @provider.stop
- end
- end
-
- describe "when enabling the service on OS X 10.6" do
- it "should write to the global launchd overrides file once" do
- provider_class.stubs(:get_macosx_version_major).returns("10.6")
- Plist.stubs(:parse_xml).returns({})
- Plist::Emit.expects(:save_plist).once
- @provider.enable
- end
- end
-
- describe "when disabling the service on OS X 10.6" do
- it "should write to the global launchd overrides file once" do
- provider_class.stubs(:get_macosx_version_major).returns("10.6")
- Plist.stubs(:parse_xml).returns({})
- Plist::Emit.expects(:save_plist).once
- @provider.enable
- end
- end
+ # But set name, ensure and enable
+ @resource.stubs(:[]).with(:name).returns @joblabel
+ @resource.stubs(:[]).with(:ensure).returns :enabled
+ @resource.stubs(:[]).with(:enable).returns :true
+ @resource.stubs(:ref).returns "Service[#{@joblabel}]"
+
+ # stub out the provider methods that actually touch the filesystem
+ # or execute commands
+ @provider.stubs(:plist_from_label).returns([@joblabel, @jobplist])
+ @provider.stubs(:execute).returns("")
+ @provider.stubs(:resource).returns @resource
+
+ # We stub this out for the normal case as 10.6 is "special".
+ provider_class.stubs(:get_macosx_version_major).returns("10.5")
+
+ end
+
+ it "should have a start method for #{@provider.object_id}" do
+ @provider.should respond_to(:start)
+ end
+
+ it "should have a stop method" do
+ @provider.should respond_to(:stop)
+ end
+
+ it "should have an enabled? method" do
+ @provider.should respond_to(:enabled?)
+ end
+
+ it "should have an enable method" do
+ @provider.should respond_to(:enable)
+ end
+
+ it "should have a disable method" do
+ @provider.should respond_to(:disable)
+ end
+
+ it "should have a status method" do
+ @provider.should respond_to(:status)
+ end
+
+
+ describe "when checking status" do
+ it "should call the external command 'launchctl list' once" do
+ @provider.expects(:launchctl).with(:list).returns("rotating-strawberry-madonnas")
+ @provider.status
+ end
+ it "should return stopped if not listed in launchctl list output" do
+ @provider.stubs(:launchctl).with(:list).returns("rotating-strawberry-madonnas")
+ @provider.status.should == :stopped
+ end
+ it "should return running if listed in launchctl list output" do
+ @provider.stubs(:launchctl).with(:list).returns(@joblabel)
+ @provider.status.should == :running
+ end
+ end
+
+ describe "when checking whether the service is enabled" do
+ it "should return true if the job plist says disabled is false" do
+ @provider.stubs(:plist_from_label).returns(["foo", {"Disabled" => false}])
+ @provider.enabled?.should == :true
+ end
+ it "should return true if the job plist has no disabled key" do
+ @provider.stubs(:plist_from_label).returns(["foo", {}])
+ @provider.enabled?.should == :true
+ end
+ it "should return false if the job plist says disabled is true" do
+ @provider.stubs(:plist_from_label).returns(["foo", {"Disabled" => true}])
+ @provider.enabled?.should == :false
+ end
+ end
+
+ describe "when checking whether the service is enabled on OS X 10.6" do
+ it "should return true if the job plist says disabled is true and the global overrides says disabled is false" do
+ provider_class.stubs(:get_macosx_version_major).returns("10.6")
+ @provider.stubs(:plist_from_label).returns(["foo", {"Disabled" => true}])
+ Plist.stubs(:parse_xml).returns({@resource[:name] => {"Disabled" => false}})
+ @provider.enabled?.should == :true
+ end
+ it "should return false if the job plist says disabled is false and the global overrides says disabled is true" do
+ provider_class.stubs(:get_macosx_version_major).returns("10.6")
+ @provider.stubs(:plist_from_label).returns(["foo", {"Disabled" => false}])
+ Plist.stubs(:parse_xml).returns({@resource[:name] => {"Disabled" => true}})
+ @provider.enabled?.should == :false
+ end
+ it "should return true if the job plist and the global overrides have no disabled keys" do
+ provider_class.stubs(:get_macosx_version_major).returns("10.6")
+ @provider.stubs(:plist_from_label).returns(["foo", {}])
+ Plist.stubs(:parse_xml).returns({})
+ @provider.enabled?.should == :true
+ end
+ end
+
+ describe "when starting the service" do
+ it "should look for the relevant plist once" do
+ @provider.expects(:plist_from_label).once
+ @provider.start
+ end
+ it "should execute 'launchctl load' once without writing to the plist if the job is enabled" do
+ @provider.stubs(:enabled?).returns :true
+ @provider.expects(:execute).with([:launchctl, :load, @resource[:name]]).once
+ @provider.start
+ end
+ it "should execute 'launchctl load' with writing to the plist once if the job is disabled" do
+ @provider.stubs(:enabled?).returns :false
+ @provider.expects(:execute).with([:launchctl, :load, "-w", @resource[:name]]).once
+ @provider.start
+ end
+ it "should disable the job once if the job is disabled and should be disabled at boot" do
+ @provider.stubs(:enabled?).returns :false
+ @resource.stubs(:[]).with(:enable).returns :false
+ @provider.expects(:disable).once
+ @provider.start
+ end
+ end
+
+ describe "when stopping the service" do
+ it "should look for the relevant plist once" do
+ @provider.expects(:plist_from_label).once
+ @provider.stop
+ end
+ it "should execute 'launchctl unload' once without writing to the plist if the job is disabled" do
+ @provider.stubs(:enabled?).returns :false
+ @provider.expects(:execute).with([:launchctl, :unload, @resource[:name]]).once
+ @provider.stop
+ end
+ it "should execute 'launchctl unload' with writing to the plist once if the job is enabled" do
+ @provider.stubs(:enabled?).returns :true
+ @provider.expects(:execute).with([:launchctl, :unload, "-w", @resource[:name]]).once
+ @provider.stop
+ end
+ it "should enable the job once if the job is enabled and should be enabled at boot" do
+ @provider.stubs(:enabled?).returns :true
+ @resource.stubs(:[]).with(:enable).returns :true
+ @provider.expects(:enable).once
+ @provider.stop
+ end
+ end
+
+ describe "when enabling the service" do
+ it "should look for the relevant plist once" do
+ @provider.expects(:plist_from_label).once
+ @provider.stop
+ end
+ it "should check if the job is enabled once" do
+ @provider.expects(:enabled?).once
+ @provider.stop
+ end
+ end
+
+ describe "when disabling the service" do
+ it "should look for the relevant plist once" do
+ @provider.expects(:plist_from_label).once
+ @provider.stop
+ end
+ end
+
+ describe "when enabling the service on OS X 10.6" do
+ it "should write to the global launchd overrides file once" do
+ provider_class.stubs(:get_macosx_version_major).returns("10.6")
+ Plist.stubs(:parse_xml).returns({})
+ Plist::Emit.expects(:save_plist).once
+ @provider.enable
+ end
+ end
+
+ describe "when disabling the service on OS X 10.6" do
+ it "should write to the global launchd overrides file once" do
+ provider_class.stubs(:get_macosx_version_major).returns("10.6")
+ Plist.stubs(:parse_xml).returns({})
+ Plist::Emit.expects(:save_plist).once
+ @provider.enable
+ end
+ end
end
diff --git a/spec/unit/provider/service/redhat_spec.rb b/spec/unit/provider/service/redhat_spec.rb
index 82596fd..fd58227 100755
--- a/spec/unit/provider/service/redhat_spec.rb
+++ b/spec/unit/provider/service/redhat_spec.rb
@@ -8,114 +8,114 @@ provider_class = Puppet::Type.type(:service).provider(:redhat)
describe provider_class do
+ before :each do
+ @class = Puppet::Type.type(:service).provider(:redhat)
+ @resource = stub 'resource'
+ @resource.stubs(:[]).returns(nil)
+ @resource.stubs(:[]).with(:name).returns "myservice"
+ @provider = provider_class.new
+ @resource.stubs(:provider).returns @provider
+ @provider.resource = @resource
+ @provider.stubs(:get).with(:hasstatus).returns false
+ FileTest.stubs(:file?).with('/sbin/service').returns true
+ FileTest.stubs(:executable?).with('/sbin/service').returns true
+ end
+
+ # test self.instances
+ describe "when getting all service instances" do
before :each do
- @class = Puppet::Type.type(:service).provider(:redhat)
- @resource = stub 'resource'
- @resource.stubs(:[]).returns(nil)
- @resource.stubs(:[]).with(:name).returns "myservice"
- @provider = provider_class.new
- @resource.stubs(:provider).returns @provider
- @provider.resource = @resource
- @provider.stubs(:get).with(:hasstatus).returns false
- FileTest.stubs(:file?).with('/sbin/service').returns true
- FileTest.stubs(:executable?).with('/sbin/service').returns true
+ @services = ['one', 'two', 'three', 'four', 'kudzu', 'functions', 'halt', 'killall', 'single', 'linuxconf']
+ @not_services = ['functions', 'halt', 'killall', 'single', 'linuxconf']
+ Dir.stubs(:entries).returns @services
+ FileTest.stubs(:directory?).returns(true)
+ FileTest.stubs(:executable?).returns(true)
end
-
- # test self.instances
- describe "when getting all service instances" do
- before :each do
- @services = ['one', 'two', 'three', 'four', 'kudzu', 'functions', 'halt', 'killall', 'single', 'linuxconf']
- @not_services = ['functions', 'halt', 'killall', 'single', 'linuxconf']
- Dir.stubs(:entries).returns @services
- FileTest.stubs(:directory?).returns(true)
- FileTest.stubs(:executable?).returns(true)
- end
- it "should return instances for all services" do
- (@services- at not_services).each do |inst|
- @class.expects(:new).with{|hash| hash[:name] == inst && hash[:path] == '/etc/init.d'}.returns("#{inst}_instance")
- end
- results = (@services- at not_services).collect {|x| "#{x}_instance"}
- @class.instances.should == results
- end
- it "should call service status when initialized from provider" do
- @resource.stubs(:[]).with(:status).returns nil
- @provider.stubs(:get).with(:hasstatus).returns true
- @provider.expects(:execute).with{|command, *args| command == ['/sbin/service', 'myservice', 'status']}
- @provider.send(:status)
- end
+ it "should return instances for all services" do
+ (@services- at not_services).each do |inst|
+ @class.expects(:new).with{|hash| hash[:name] == inst && hash[:path] == '/etc/init.d'}.returns("#{inst}_instance")
+ end
+ results = (@services- at not_services).collect {|x| "#{x}_instance"}
+ @class.instances.should == results
end
-
- it "should have an enabled? method" do
- @provider.should respond_to(:enabled?)
+ it "should call service status when initialized from provider" do
+ @resource.stubs(:[]).with(:status).returns nil
+ @provider.stubs(:get).with(:hasstatus).returns true
+ @provider.expects(:execute).with{|command, *args| command == ['/sbin/service', 'myservice', 'status']}
+ @provider.send(:status)
end
+ end
- it "should have an enable method" do
- @provider.should respond_to(:enable)
- end
+ it "should have an enabled? method" do
+ @provider.should respond_to(:enabled?)
+ end
- it "should have a disable method" do
- @provider.should respond_to(:disable)
- end
+ it "should have an enable method" do
+ @provider.should respond_to(:enable)
+ end
- [:start, :stop, :status, :restart].each do |method|
- it "should have a #{method} method" do
- @provider.should respond_to(method)
- end
- describe "when running #{method}" do
+ it "should have a disable method" do
+ @provider.should respond_to(:disable)
+ end
+
+ [:start, :stop, :status, :restart].each do |method|
+ it "should have a #{method} method" do
+ @provider.should respond_to(method)
+ end
+ describe "when running #{method}" do
- it "should use any provided explicit command" do
- @resource.stubs(:[]).with(method).returns "/user/specified/command"
- @provider.expects(:execute).with { |command, *args| command == ["/user/specified/command"] }
- @provider.send(method)
- end
+ it "should use any provided explicit command" do
+ @resource.stubs(:[]).with(method).returns "/user/specified/command"
+ @provider.expects(:execute).with { |command, *args| command == ["/user/specified/command"] }
+ @provider.send(method)
+ end
- it "should execute the service script with #{method} when no explicit command is provided" do
- @resource.stubs(:[]).with("has#{method}".intern).returns :true
- @provider.expects(:execute).with { |command, *args| command == ['/sbin/service', 'myservice', method.to_s]}
- @provider.send(method)
- end
- end
+ it "should execute the service script with #{method} when no explicit command is provided" do
+ @resource.stubs(:[]).with("has#{method}".intern).returns :true
+ @provider.expects(:execute).with { |command, *args| command == ['/sbin/service', 'myservice', method.to_s]}
+ @provider.send(method)
+ end
end
+ end
- describe "when checking status" do
- describe "when hasstatus is :true" do
- before :each do
- @resource.stubs(:[]).with(:hasstatus).returns :true
- end
- it "should execute the service script with fail_on_failure false" do
- @provider.expects(:texecute).with(:status, ['/sbin/service', 'myservice', 'status'], false)
- @provider.status
- end
- it "should consider the process running if the command returns 0" do
- @provider.expects(:texecute).with(:status, ['/sbin/service', 'myservice', 'status'], false)
- $CHILD_STATUS.stubs(:exitstatus).returns(0)
- @provider.status.should == :running
- end
- [-10,-1,1,10].each { |ec|
- it "should consider the process stopped if the command returns something non-0" do
- @provider.expects(:texecute).with(:status, ['/sbin/service', 'myservice', 'status'], false)
- $CHILD_STATUS.stubs(:exitstatus).returns(ec)
- @provider.status.should == :stopped
- end
- }
- end
- describe "when hasstatus is not :true" do
- it "should consider the service :running if it has a pid" do
- @provider.expects(:getpid).returns "1234"
- @provider.status.should == :running
- end
- it "should consider the service :stopped if it doesn't have a pid" do
- @provider.expects(:getpid).returns nil
- @provider.status.should == :stopped
- end
+ describe "when checking status" do
+ describe "when hasstatus is :true" do
+ before :each do
+ @resource.stubs(:[]).with(:hasstatus).returns :true
+ end
+ it "should execute the service script with fail_on_failure false" do
+ @provider.expects(:texecute).with(:status, ['/sbin/service', 'myservice', 'status'], false)
+ @provider.status
+ end
+ it "should consider the process running if the command returns 0" do
+ @provider.expects(:texecute).with(:status, ['/sbin/service', 'myservice', 'status'], false)
+ $CHILD_STATUS.stubs(:exitstatus).returns(0)
+ @provider.status.should == :running
+ end
+ [-10,-1,1,10].each { |ec|
+ it "should consider the process stopped if the command returns something non-0" do
+ @provider.expects(:texecute).with(:status, ['/sbin/service', 'myservice', 'status'], false)
+ $CHILD_STATUS.stubs(:exitstatus).returns(ec)
+ @provider.status.should == :stopped
end
+ }
+ end
+ describe "when hasstatus is not :true" do
+ it "should consider the service :running if it has a pid" do
+ @provider.expects(:getpid).returns "1234"
+ @provider.status.should == :running
+ end
+ it "should consider the service :stopped if it doesn't have a pid" do
+ @provider.expects(:getpid).returns nil
+ @provider.status.should == :stopped
+ end
end
+ end
- describe "when restarting and hasrestart is not :true" do
- it "should stop and restart the process with the server script" do
- @provider.expects(:texecute).with(:stop, ['/sbin/service', 'myservice', 'stop'], true)
- @provider.expects(:texecute).with(:start, ['/sbin/service', 'myservice', 'start'], true)
- @provider.restart
- end
+ describe "when restarting and hasrestart is not :true" do
+ it "should stop and restart the process with the server script" do
+ @provider.expects(:texecute).with(:stop, ['/sbin/service', 'myservice', 'stop'], true)
+ @provider.expects(:texecute).with(:start, ['/sbin/service', 'myservice', 'start'], true)
+ @provider.restart
end
+ end
end
diff --git a/spec/unit/provider/service/runit_spec.rb b/spec/unit/provider/service/runit_spec.rb
index 42309ee..80ce456 100755
--- a/spec/unit/provider/service/runit_spec.rb
+++ b/spec/unit/provider/service/runit_spec.rb
@@ -10,131 +10,131 @@ provider_class = Puppet::Type.type(:service).provider(:runit)
describe provider_class do
- before(:each) do
- # Create a mock resource
- @resource = stub 'resource'
+ before(:each) do
+ # Create a mock resource
+ @resource = stub 'resource'
- @provider = provider_class.new
- @servicedir = "/etc/service"
- @provider.servicedir=@servicedir
- @daemondir = "/etc/sv"
- @provider.class.defpath=@daemondir
+ @provider = provider_class.new
+ @servicedir = "/etc/service"
+ @provider.servicedir=@servicedir
+ @daemondir = "/etc/sv"
+ @provider.class.defpath=@daemondir
- # A catch all; no parameters set
- @resource.stubs(:[]).returns(nil)
+ # A catch all; no parameters set
+ @resource.stubs(:[]).returns(nil)
- # But set name, source and path (because we won't run
- # the thing that will fetch the resource path from the provider)
- @resource.stubs(:[]).with(:name).returns "myservice"
- @resource.stubs(:[]).with(:ensure).returns :enabled
- @resource.stubs(:[]).with(:path).returns @daemondir
- @resource.stubs(:ref).returns "Service[myservice]"
+ # But set name, source and path (because we won't run
+ # the thing that will fetch the resource path from the provider)
+ @resource.stubs(:[]).with(:name).returns "myservice"
+ @resource.stubs(:[]).with(:ensure).returns :enabled
+ @resource.stubs(:[]).with(:path).returns @daemondir
+ @resource.stubs(:ref).returns "Service[myservice]"
- @provider.stubs(:sv)
+ @provider.stubs(:sv)
- @provider.stubs(:resource).returns @resource
- end
+ @provider.stubs(:resource).returns @resource
+ end
- it "should have a restart method" do
- @provider.should respond_to(:restart)
- end
+ it "should have a restart method" do
+ @provider.should respond_to(:restart)
+ end
- it "should have a restartcmd method" do
- @provider.should respond_to(:restartcmd)
- end
+ it "should have a restartcmd method" do
+ @provider.should respond_to(:restartcmd)
+ end
- it "should have a start method" do
- @provider.should respond_to(:start)
- end
+ it "should have a start method" do
+ @provider.should respond_to(:start)
+ end
- it "should have a stop method" do
- @provider.should respond_to(:stop)
- end
+ it "should have a stop method" do
+ @provider.should respond_to(:stop)
+ end
- it "should have an enabled? method" do
- @provider.should respond_to(:enabled?)
- end
+ it "should have an enabled? method" do
+ @provider.should respond_to(:enabled?)
+ end
- it "should have an enable method" do
- @provider.should respond_to(:enable)
- end
+ it "should have an enable method" do
+ @provider.should respond_to(:enable)
+ end
- it "should have a disable method" do
- @provider.should respond_to(:disable)
- end
-
- describe "when starting" do
- it "should enable the service if it is not enabled" do
- @provider.stubs(:sv)
+ it "should have a disable method" do
+ @provider.should respond_to(:disable)
+ end
- @provider.expects(:enabled?).returns :false
- @provider.expects(:enable)
+ describe "when starting" do
+ it "should enable the service if it is not enabled" do
+ @provider.stubs(:sv)
- @provider.start
- end
+ @provider.expects(:enabled?).returns :false
+ @provider.expects(:enable)
- it "should execute external command 'sv start /etc/service/myservice'" do
- @provider.stubs(:enabled?).returns :true
- @provider.expects(:sv).with("start", "/etc/service/myservice")
- @provider.start
- end
+ @provider.start
end
- describe "when stopping" do
- it "should execute external command 'sv stop /etc/service/myservice'" do
- @provider.expects(:sv).with("stop", "/etc/service/myservice")
- @provider.stop
- end
+ it "should execute external command 'sv start /etc/service/myservice'" do
+ @provider.stubs(:enabled?).returns :true
+ @provider.expects(:sv).with("start", "/etc/service/myservice")
+ @provider.start
end
+ end
- describe "when restarting" do
- it "should call 'sv restart /etc/service/myservice'" do
- @provider.expects(:sv).with("restart","/etc/service/myservice")
- @provider.restart
- end
+ describe "when stopping" do
+ it "should execute external command 'sv stop /etc/service/myservice'" do
+ @provider.expects(:sv).with("stop", "/etc/service/myservice")
+ @provider.stop
end
+ end
- describe "when enabling" do
- it "should create a symlink between daemon dir and service dir" do
- FileTest.stubs(:symlink?).returns(false)
- File.expects(:symlink).with(File.join(@daemondir,"myservice"), File.join(@servicedir,"myservice")).returns(0)
- @provider.enable
- end
+ describe "when restarting" do
+ it "should call 'sv restart /etc/service/myservice'" do
+ @provider.expects(:sv).with("restart","/etc/service/myservice")
+ @provider.restart
end
+ end
- describe "when disabling" do
- it "should remove the '/etc/service/myservice' symlink" do
- FileTest.stubs(:directory?).returns(false)
- FileTest.stubs(:symlink?).returns(true)
- File.expects(:unlink).with(File.join(@servicedir,"myservice")).returns(0)
- @provider.disable
- end
+ describe "when enabling" do
+ it "should create a symlink between daemon dir and service dir" do
+ FileTest.stubs(:symlink?).returns(false)
+ File.expects(:symlink).with(File.join(@daemondir,"myservice"), File.join(@servicedir,"myservice")).returns(0)
+ @provider.enable
+ end
+ end
+
+ describe "when disabling" do
+ it "should remove the '/etc/service/myservice' symlink" do
+ FileTest.stubs(:directory?).returns(false)
+ FileTest.stubs(:symlink?).returns(true)
+ File.expects(:unlink).with(File.join(@servicedir,"myservice")).returns(0)
+ @provider.disable
end
+ end
- describe "when checking status" do
- it "should call the external command 'sv status /etc/sv/myservice'" do
- @provider.expects(:sv).with('status',File.join(@daemondir,"myservice"))
- @provider.status
- end
+ describe "when checking status" do
+ it "should call the external command 'sv status /etc/sv/myservice'" do
+ @provider.expects(:sv).with('status',File.join(@daemondir,"myservice"))
+ @provider.status
end
+ end
- describe "when checking status" do
- it "and sv status fails, properly raise a Puppet::Error" do
- @provider.expects(:sv).with('status',File.join(@daemondir,"myservice")).raises(Puppet::ExecutionFailure, "fail: /etc/sv/myservice: file not found")
- lambda { @provider.status }.should raise_error(Puppet::Error, 'Could not get status for service Service[myservice]: fail: /etc/sv/myservice: file not found')
- end
- it "and sv status returns up, then return :running" do
- @provider.expects(:sv).with('status',File.join(@daemondir,"myservice")).returns("run: /etc/sv/myservice: (pid 9029) 6s")
- @provider.status.should == :running
- end
- it "and sv status returns not running, then return :stopped" do
- @provider.expects(:sv).with('status',File.join(@daemondir,"myservice")).returns("fail: /etc/sv/myservice: runsv not running")
- @provider.status.should == :stopped
- end
- it "and sv status returns a warning, then return :stopped" do
- @provider.expects(:sv).with('status',File.join(@daemondir,"myservice")).returns("warning: /etc/sv/myservice: unable to open supervise/ok: file does not exist")
- @provider.status.should == :stopped
- end
+ describe "when checking status" do
+ it "and sv status fails, properly raise a Puppet::Error" do
+ @provider.expects(:sv).with('status',File.join(@daemondir,"myservice")).raises(Puppet::ExecutionFailure, "fail: /etc/sv/myservice: file not found")
+ lambda { @provider.status }.should raise_error(Puppet::Error, 'Could not get status for service Service[myservice]: fail: /etc/sv/myservice: file not found')
+ end
+ it "and sv status returns up, then return :running" do
+ @provider.expects(:sv).with('status',File.join(@daemondir,"myservice")).returns("run: /etc/sv/myservice: (pid 9029) 6s")
+ @provider.status.should == :running
+ end
+ it "and sv status returns not running, then return :stopped" do
+ @provider.expects(:sv).with('status',File.join(@daemondir,"myservice")).returns("fail: /etc/sv/myservice: runsv not running")
+ @provider.status.should == :stopped
+ end
+ it "and sv status returns a warning, then return :stopped" do
+ @provider.expects(:sv).with('status',File.join(@daemondir,"myservice")).returns("warning: /etc/sv/myservice: unable to open supervise/ok: file does not exist")
+ @provider.status.should == :stopped
end
+ end
end
diff --git a/spec/unit/provider/service/src_spec.rb b/spec/unit/provider/service/src_spec.rb
index eaa968f..eff98f0 100755
--- a/spec/unit/provider/service/src_spec.rb
+++ b/spec/unit/provider/service/src_spec.rb
@@ -9,89 +9,89 @@ provider_class = Puppet::Type.type(:service).provider(:src)
describe provider_class do
- before :each do
- @resource = stub 'resource'
- @resource.stubs(:[]).returns(nil)
- @resource.stubs(:[]).with(:name).returns "myservice"
-
- @provider = provider_class.new
- @provider.resource = @resource
-
- @provider.stubs(:command).with(:stopsrc).returns "/usr/bin/stopsrc"
- @provider.stubs(:command).with(:startsrc).returns "/usr/bin/startsrc"
- @provider.stubs(:command).with(:lssrc).returns "/usr/bin/lssrc"
- @provider.stubs(:command).with(:refresh).returns "/usr/bin/refresh"
-
- @provider.stubs(:stopsrc)
- @provider.stubs(:startsrc)
- @provider.stubs(:lssrc)
- @provider.stubs(:refresh)
+ before :each do
+ @resource = stub 'resource'
+ @resource.stubs(:[]).returns(nil)
+ @resource.stubs(:[]).with(:name).returns "myservice"
+
+ @provider = provider_class.new
+ @provider.resource = @resource
+
+ @provider.stubs(:command).with(:stopsrc).returns "/usr/bin/stopsrc"
+ @provider.stubs(:command).with(:startsrc).returns "/usr/bin/startsrc"
+ @provider.stubs(:command).with(:lssrc).returns "/usr/bin/lssrc"
+ @provider.stubs(:command).with(:refresh).returns "/usr/bin/refresh"
+
+ @provider.stubs(:stopsrc)
+ @provider.stubs(:startsrc)
+ @provider.stubs(:lssrc)
+ @provider.stubs(:refresh)
+ end
+
+ [:start, :stop, :status, :restart].each do |method|
+ it "should have a #{method} method" do
+ @provider.should respond_to(method)
end
+ end
- [:start, :stop, :status, :restart].each do |method|
- it "should have a #{method} method" do
- @provider.should respond_to(method)
- end
- end
+ it "should execute the startsrc command" do
+ @provider.expects(:execute).with(['/usr/bin/startsrc', '-s', "myservice"], {:squelch => true, :failonfail => true})
+ @provider.start
+ end
- it "should execute the startsrc command" do
- @provider.expects(:execute).with(['/usr/bin/startsrc', '-s', "myservice"], {:squelch => true, :failonfail => true})
- @provider.start
- end
+ it "should execute the stopsrc command" do
+ @provider.expects(:execute).with(['/usr/bin/stopsrc', '-s', "myservice"], {:squelch => true, :failonfail => true})
+ @provider.stop
+ end
- it "should execute the stopsrc command" do
- @provider.expects(:execute).with(['/usr/bin/stopsrc', '-s', "myservice"], {:squelch => true, :failonfail => true})
- @provider.stop
- end
-
- it "should execute status and return running if the subsystem is active" do
- sample_output = <<_EOF_
+ it "should execute status and return running if the subsystem is active" do
+ sample_output = <<_EOF_
Subsystem Group PID Status
myservice tcpip 1234 active
_EOF_
- @provider.expects(:execute).with(['/usr/bin/lssrc', '-s', "myservice"]).returns sample_output
- @provider.status.should == :running
- end
+ @provider.expects(:execute).with(['/usr/bin/lssrc', '-s', "myservice"]).returns sample_output
+ @provider.status.should == :running
+ end
- it "should execute status and return stopped if the subsystem is inoperative" do
- sample_output = <<_EOF_
+ it "should execute status and return stopped if the subsystem is inoperative" do
+ sample_output = <<_EOF_
Subsystem Group PID Status
myservice tcpip inoperative
_EOF_
- @provider.expects(:execute).with(['/usr/bin/lssrc', '-s', "myservice"]).returns sample_output
- @provider.status.should == :stopped
- end
+ @provider.expects(:execute).with(['/usr/bin/lssrc', '-s', "myservice"]).returns sample_output
+ @provider.status.should == :stopped
+ end
- it "should execute status and return nil if the status is not known" do
- sample_output = <<_EOF_
+ it "should execute status and return nil if the status is not known" do
+ sample_output = <<_EOF_
Subsystem Group PID Status
myservice tcpip randomdata
_EOF_
- @provider.expects(:execute).with(['/usr/bin/lssrc', '-s', "myservice"]).returns sample_output
- @provider.status.should == nil
- end
+ @provider.expects(:execute).with(['/usr/bin/lssrc', '-s', "myservice"]).returns sample_output
+ @provider.status.should == nil
+ end
- it "should execute restart which runs refresh" do
- sample_output = <<_EOF_
+ it "should execute restart which runs refresh" do
+ sample_output = <<_EOF_
#subsysname:synonym:cmdargs:path:uid:auditid:standin:standout:standerr:action:multi:contact:svrkey:svrmtype:priority:signorm:sigforce:display:waittime:grpname:
myservice:::/usr/sbin/inetd:0:0:/dev/console:/dev/console:/dev/console:-O:-Q:-K:0:0:20:0:0:-d:20:tcpip:
_EOF_
- @provider.expects(:execute).with(['/usr/bin/lssrc', '-Ss', "myservice"]).returns sample_output
- @provider.expects(:execute).with(['/usr/bin/refresh', '-s', "myservice"])
- @provider.restart
- end
+ @provider.expects(:execute).with(['/usr/bin/lssrc', '-Ss', "myservice"]).returns sample_output
+ @provider.expects(:execute).with(['/usr/bin/refresh', '-s', "myservice"])
+ @provider.restart
+ end
- it "should execute restart which runs stopsrc then startsrc" do
- sample_output = <<_EOF_
+ it "should execute restart which runs stopsrc then startsrc" do
+ sample_output = <<_EOF_
#subsysname:synonym:cmdargs:path:uid:auditid:standin:standout:standerr:action:multi:contact:svrkey:svrmtype:priority:signorm:sigforce:display:waittime:grpname:
myservice::--no-daemonize:/usr/sbin/puppetd:0:0:/dev/null:/var/log/puppet.log:/var/log/puppet.log:-O:-Q:-S:0:0:20:15:9:-d:20::"
_EOF_
- @provider.expects(:execute).with(['/usr/bin/lssrc', '-Ss', "myservice"]).returns sample_output
- @provider.expects(:execute).with(['/usr/bin/stopsrc', '-s', "myservice"], {:squelch => true, :failonfail => true})
- @provider.expects(:execute).with(['/usr/bin/startsrc', '-s', "myservice"], {:squelch => true, :failonfail => true})
- @provider.restart
- end
+ @provider.expects(:execute).with(['/usr/bin/lssrc', '-Ss', "myservice"]).returns sample_output
+ @provider.expects(:execute).with(['/usr/bin/stopsrc', '-s', "myservice"], {:squelch => true, :failonfail => true})
+ @provider.expects(:execute).with(['/usr/bin/startsrc', '-s', "myservice"], {:squelch => true, :failonfail => true})
+ @provider.restart
+ end
end
diff --git a/spec/unit/provider/ssh_authorized_key/parsed_spec.rb b/spec/unit/provider/ssh_authorized_key/parsed_spec.rb
index 3b14ad3..059d010 100755
--- a/spec/unit/provider/ssh_authorized_key/parsed_spec.rb
+++ b/spec/unit/provider/ssh_authorized_key/parsed_spec.rb
@@ -10,219 +10,219 @@ require 'puppettest/fileparsing'
provider_class = Puppet::Type.type(:ssh_authorized_key).provider(:parsed)
describe provider_class do
- include PuppetSpec::Files
- include PuppetTest
- include PuppetTest::FileParsing
-
- before :each do
- @sshauthkey_class = Puppet::Type.type(:ssh_authorized_key)
- @provider = @sshauthkey_class.provider(:parsed)
- @keyfile = File.join(Dir.tmpdir, 'authorized_keys')
- @provider.any_instance.stubs(:target).returns @keyfile
- @user = 'random_bob'
- Puppet::Util.stubs(:uid).with(@user).returns 12345
+ include PuppetSpec::Files
+ include PuppetTest
+ include PuppetTest::FileParsing
+
+ before :each do
+ @sshauthkey_class = Puppet::Type.type(:ssh_authorized_key)
+ @provider = @sshauthkey_class.provider(:parsed)
+ @keyfile = File.join(Dir.tmpdir, 'authorized_keys')
+ @provider.any_instance.stubs(:target).returns @keyfile
+ @user = 'random_bob'
+ Puppet::Util.stubs(:uid).with(@user).returns 12345
+ end
+
+ after :each do
+ @provider.initvars
+ end
+
+ def mkkey(args)
+ fakeresource = fakeresource(:ssh_authorized_key, args[:name])
+ fakeresource.stubs(:should).with(:user).returns @user
+ fakeresource.stubs(:should).with(:target).returns @keyfile
+
+ key = @provider.new(fakeresource)
+ args.each do |p,v|
+ key.send(p.to_s + "=", v)
end
- after :each do
- @provider.initvars
+ key
+ end
+
+ def genkey(key)
+ @provider.stubs(:filetype).returns(Puppet::Util::FileType::FileTypeRam)
+ File.stubs(:chown)
+ File.stubs(:chmod)
+ Puppet::Util::SUIDManager.stubs(:asuser).yields
+ key.flush
+ @provider.target_object(@keyfile).read
+ end
+
+ PuppetTest.fakedata("data/providers/ssh_authorized_key/parsed").each { |file|
+ it "should be able to parse example data in #{file}" do
+ fakedataparse(file)
end
+ }
- def mkkey(args)
- fakeresource = fakeresource(:ssh_authorized_key, args[:name])
- fakeresource.stubs(:should).with(:user).returns @user
- fakeresource.stubs(:should).with(:target).returns @keyfile
+ it "should be able to generate a basic authorized_keys file" do
- key = @provider.new(fakeresource)
- args.each do |p,v|
- key.send(p.to_s + "=", v)
- end
+ key = mkkey(
+ {
+ :name => "Just Testing",
+ :key => "AAAAfsfddsjldjgksdflgkjsfdlgkj",
+ :type => "ssh-dss",
+ :ensure => :present,
- key
- end
+ :options => [:absent]
+ })
- def genkey(key)
- @provider.stubs(:filetype).returns(Puppet::Util::FileType::FileTypeRam)
- File.stubs(:chown)
- File.stubs(:chmod)
- Puppet::Util::SUIDManager.stubs(:asuser).yields
- key.flush
- @provider.target_object(@keyfile).read
- end
+ genkey(key).should == "ssh-dss AAAAfsfddsjldjgksdflgkjsfdlgkj Just Testing\n"
+ end
- PuppetTest.fakedata("data/providers/ssh_authorized_key/parsed").each { |file|
- it "should be able to parse example data in #{file}" do
- fakedataparse(file)
- end
- }
+ it "should be able to generate a authorized_keys file with options" do
- it "should be able to generate a basic authorized_keys file" do
+ key = mkkey(
+ {
+ :name => "root at localhost",
+ :key => "AAAAfsfddsjldjgksdflgkjsfdlgkj",
+ :type => "ssh-rsa",
+ :ensure => :present,
- key = mkkey(
- {
- :name => "Just Testing",
- :key => "AAAAfsfddsjldjgksdflgkjsfdlgkj",
- :type => "ssh-dss",
- :ensure => :present,
+ :options => ['from="192.168.1.1"', "no-pty", "no-X11-forwarding"]
+ })
- :options => [:absent]
- })
+ genkey(key).should == "from=\"192.168.1.1\",no-pty,no-X11-forwarding ssh-rsa AAAAfsfddsjldjgksdflgkjsfdlgkj root at localhost\n"
+ end
- genkey(key).should == "ssh-dss AAAAfsfddsjldjgksdflgkjsfdlgkj Just Testing\n"
- end
+ it "should be able to parse options containing commas via its parse_options method" do
+ options = %w{from="host1.reductlivelabs.com,host.reductivelabs.com" command="/usr/local/bin/run" ssh-pty}
+ optionstr = options.join(", ")
- it "should be able to generate a authorized_keys file with options" do
+ @provider.parse_options(optionstr).should == options
+ end
- key = mkkey(
- {
- :name => "root at localhost",
- :key => "AAAAfsfddsjldjgksdflgkjsfdlgkj",
- :type => "ssh-rsa",
- :ensure => :present,
+ it "should use '' as name for entries that lack a comment" do
+ line = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAut8aOSxenjOqF527dlsdHWV4MNoAsX14l9M297+SQXaQ5Z3BedIxZaoQthkDALlV/25A1COELrg9J2MqJNQc8Xe9XQOIkBQWWinUlD/BXwoOTWEy8C8zSZPHZ3getMMNhGTBO+q/O+qiJx3y5cA4MTbw2zSxukfWC87qWwcZ64UUlegIM056vPsdZWFclS9hsROVEa57YUMrehQ1EGxT4Z5j6zIopufGFiAPjZigq/vqgcAqhAKP6yu4/gwO6S9tatBeEjZ8fafvj1pmvvIplZeMr96gHE7xS3pEEQqnB3nd4RY7AF6j9kFixnsytAUO7STPh/M3pLiVQBN89TvWPQ=="
- :options => ['from="192.168.1.1"', "no-pty", "no-X11-forwarding"]
- })
+ @provider.parse(line)[0][:name].should == ""
+ end
+end
- genkey(key).should == "from=\"192.168.1.1\",no-pty,no-X11-forwarding ssh-rsa AAAAfsfddsjldjgksdflgkjsfdlgkj root at localhost\n"
- end
+describe provider_class do
+ before :each do
+ @resource = stub("resource", :name => "foo")
+ @resource.stubs(:[]).returns "foo"
- it "should be able to parse options containing commas via its parse_options method" do
- options = %w{from="host1.reductlivelabs.com,host.reductivelabs.com" command="/usr/local/bin/run" ssh-pty}
- optionstr = options.join(", ")
+ @provider = provider_class.new(@resource)
+ provider_class.stubs(:filetype).returns(Puppet::Util::FileType::FileTypeRam)
+ Puppet::Util::SUIDManager.stubs(:asuser).yields
+ end
- @provider.parse_options(optionstr).should == options
+ describe "when flushing" do
+ before :each do
+ # Stub file and directory operations
+ Dir.stubs(:mkdir)
+ File.stubs(:chmod)
+ File.stubs(:chown)
end
- it "should use '' as name for entries that lack a comment" do
- line = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAut8aOSxenjOqF527dlsdHWV4MNoAsX14l9M297+SQXaQ5Z3BedIxZaoQthkDALlV/25A1COELrg9J2MqJNQc8Xe9XQOIkBQWWinUlD/BXwoOTWEy8C8zSZPHZ3getMMNhGTBO+q/O+qiJx3y5cA4MTbw2zSxukfWC87qWwcZ64UUlegIM056vPsdZWFclS9hsROVEa57YUMrehQ1EGxT4Z5j6zIopufGFiAPjZigq/vqgcAqhAKP6yu4/gwO6S9tatBeEjZ8fafvj1pmvvIplZeMr96gHE7xS3pEEQqnB3nd4RY7AF6j9kFixnsytAUO7STPh/M3pLiVQBN89TvWPQ=="
+ describe "and both a user and a target have been specified" do
+ before :each do
+ Puppet::Util.stubs(:uid).with("random_bob").returns 12345
+ @resource.stubs(:should).with(:user).returns "random_bob"
+ target = "/tmp/.ssh_dir/place_to_put_authorized_keys"
+ @resource.stubs(:should).with(:target).returns target
+ end
+
+ it "should create the directory" do
+ File.stubs(:exist?).with("/tmp/.ssh_dir").returns false
+ Dir.expects(:mkdir).with("/tmp/.ssh_dir", 0700)
+ @provider.flush
+ end
+
+ it "should chown the directory to the user" do
+ uid = Puppet::Util.uid("random_bob")
+ File.expects(:chown).with(uid, nil, "/tmp/.ssh_dir")
+ @provider.flush
+ end
+
+ it "should chown the key file to the user" do
+ uid = Puppet::Util.uid("random_bob")
+ File.expects(:chown).with(uid, nil, "/tmp/.ssh_dir/place_to_put_authorized_keys")
+ @provider.flush
+ end
+
+ it "should chmod the key file to 0600" do
+ File.expects(:chmod).with(0600, "/tmp/.ssh_dir/place_to_put_authorized_keys")
+ @provider.flush
+ end
+ end
- @provider.parse(line)[0][:name].should == ""
+ describe "and a user has been specified with no target" do
+ before :each do
+ @resource.stubs(:should).with(:user).returns "nobody"
+ @resource.stubs(:should).with(:target).returns nil
+ #
+ # I'd like to use random_bob here and something like
+ #
+ # File.stubs(:expand_path).with("~random_bob/.ssh").returns "/users/r/random_bob/.ssh"
+ #
+ # but mocha objects strenuously to stubbing File.expand_path
+ # so I'm left with using nobody.
+ @dir = File.expand_path("~nobody/.ssh")
+ end
+
+ it "should create the directory if it doesn't exist" do
+ File.stubs(:exist?).with(@dir).returns false
+ Dir.expects(:mkdir).with(@dir,0700)
+ @provider.flush
+ end
+
+ it "should not create or chown the directory if it already exist" do
+ File.stubs(:exist?).with(@dir).returns false
+ Dir.expects(:mkdir).never
+ @provider.flush
+ end
+
+ it "should chown the directory to the user if it creates it" do
+ File.stubs(:exist?).with(@dir).returns false
+ Dir.stubs(:mkdir).with(@dir,0700)
+ uid = Puppet::Util.uid("nobody")
+ File.expects(:chown).with(uid, nil, @dir)
+ @provider.flush
+ end
+
+ it "should not create or chown the directory if it already exist" do
+ File.stubs(:exist?).with(@dir).returns false
+ Dir.expects(:mkdir).never
+ File.expects(:chown).never
+ @provider.flush
+ end
+
+ it "should chown the key file to the user" do
+ uid = Puppet::Util.uid("nobody")
+ File.expects(:chown).with(uid, nil, File.expand_path("~nobody/.ssh/authorized_keys"))
+ @provider.flush
+ end
+
+ it "should chmod the key file to 0600" do
+ File.expects(:chmod).with(0600, File.expand_path("~nobody/.ssh/authorized_keys"))
+ @provider.flush
+ end
end
-end
-describe provider_class do
- before :each do
- @resource = stub("resource", :name => "foo")
- @resource.stubs(:[]).returns "foo"
+ describe "and a target has been specified with no user" do
+ before :each do
+ @resource.stubs(:should).with(:user).returns nil
+ @resource.stubs(:should).with(:target).returns("/tmp/.ssh_dir/place_to_put_authorized_keys")
+ end
- @provider = provider_class.new(@resource)
- provider_class.stubs(:filetype).returns(Puppet::Util::FileType::FileTypeRam)
- Puppet::Util::SUIDManager.stubs(:asuser).yields
+ it "should raise an error" do
+ proc { @provider.flush }.should raise_error
+ end
end
- describe "when flushing" do
- before :each do
- # Stub file and directory operations
- Dir.stubs(:mkdir)
- File.stubs(:chmod)
- File.stubs(:chown)
- end
-
- describe "and both a user and a target have been specified" do
- before :each do
- Puppet::Util.stubs(:uid).with("random_bob").returns 12345
- @resource.stubs(:should).with(:user).returns "random_bob"
- target = "/tmp/.ssh_dir/place_to_put_authorized_keys"
- @resource.stubs(:should).with(:target).returns target
- end
-
- it "should create the directory" do
- File.stubs(:exist?).with("/tmp/.ssh_dir").returns false
- Dir.expects(:mkdir).with("/tmp/.ssh_dir", 0700)
- @provider.flush
- end
-
- it "should chown the directory to the user" do
- uid = Puppet::Util.uid("random_bob")
- File.expects(:chown).with(uid, nil, "/tmp/.ssh_dir")
- @provider.flush
- end
-
- it "should chown the key file to the user" do
- uid = Puppet::Util.uid("random_bob")
- File.expects(:chown).with(uid, nil, "/tmp/.ssh_dir/place_to_put_authorized_keys")
- @provider.flush
- end
-
- it "should chmod the key file to 0600" do
- File.expects(:chmod).with(0600, "/tmp/.ssh_dir/place_to_put_authorized_keys")
- @provider.flush
- end
- end
-
- describe "and a user has been specified with no target" do
- before :each do
- @resource.stubs(:should).with(:user).returns "nobody"
- @resource.stubs(:should).with(:target).returns nil
- #
- # I'd like to use random_bob here and something like
- #
- # File.stubs(:expand_path).with("~random_bob/.ssh").returns "/users/r/random_bob/.ssh"
- #
- # but mocha objects strenuously to stubbing File.expand_path
- # so I'm left with using nobody.
- @dir = File.expand_path("~nobody/.ssh")
- end
-
- it "should create the directory if it doesn't exist" do
- File.stubs(:exist?).with(@dir).returns false
- Dir.expects(:mkdir).with(@dir,0700)
- @provider.flush
- end
-
- it "should not create or chown the directory if it already exist" do
- File.stubs(:exist?).with(@dir).returns false
- Dir.expects(:mkdir).never
- @provider.flush
- end
-
- it "should chown the directory to the user if it creates it" do
- File.stubs(:exist?).with(@dir).returns false
- Dir.stubs(:mkdir).with(@dir,0700)
- uid = Puppet::Util.uid("nobody")
- File.expects(:chown).with(uid, nil, @dir)
- @provider.flush
- end
-
- it "should not create or chown the directory if it already exist" do
- File.stubs(:exist?).with(@dir).returns false
- Dir.expects(:mkdir).never
- File.expects(:chown).never
- @provider.flush
- end
-
- it "should chown the key file to the user" do
- uid = Puppet::Util.uid("nobody")
- File.expects(:chown).with(uid, nil, File.expand_path("~nobody/.ssh/authorized_keys"))
- @provider.flush
- end
-
- it "should chmod the key file to 0600" do
- File.expects(:chmod).with(0600, File.expand_path("~nobody/.ssh/authorized_keys"))
- @provider.flush
- end
- end
-
- describe "and a target has been specified with no user" do
- before :each do
- @resource.stubs(:should).with(:user).returns nil
- @resource.stubs(:should).with(:target).returns("/tmp/.ssh_dir/place_to_put_authorized_keys")
- end
-
- it "should raise an error" do
- proc { @provider.flush }.should raise_error
- end
- end
-
- describe "and a invalid user has been specified with no target" do
- before :each do
- @resource.stubs(:should).with(:user).returns "thisusershouldnotexist"
- @resource.stubs(:should).with(:target).returns nil
- end
-
- it "should catch an exception and raise a Puppet error" do
- lambda { @provider.flush }.should raise_error(Puppet::Error)
- end
- end
+ describe "and a invalid user has been specified with no target" do
+ before :each do
+ @resource.stubs(:should).with(:user).returns "thisusershouldnotexist"
+ @resource.stubs(:should).with(:target).returns nil
+ end
+ it "should catch an exception and raise a Puppet error" do
+ lambda { @provider.flush }.should raise_error(Puppet::Error)
+ end
end
+
+ end
end
diff --git a/spec/unit/provider/sshkey/parsed_spec.rb b/spec/unit/provider/sshkey/parsed_spec.rb
index 4180ffb..1a54709 100755
--- a/spec/unit/provider/sshkey/parsed_spec.rb
+++ b/spec/unit/provider/sshkey/parsed_spec.rb
@@ -5,34 +5,34 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
provider_class = Puppet::Type.type(:sshkey).provider(:parsed)
describe provider_class do
- before do
- @sshkey_class = Puppet::Type.type(:sshkey)
- @provider_class = @sshkey_class.provider(:parsed)
- @key = 'AAAAB3NzaC1yc2EAAAABIwAAAQEAzwHhxXvIrtfIwrudFqc8yQcIfMudrgpnuh1F3AV6d2BrLgu/yQE7W5UyJMUjfj427sQudRwKW45O0Jsnr33F4mUw+GIMlAAmp9g24/OcrTiB8ZUKIjoPy/cO4coxGi8/NECtRzpD/ZUPFh6OEpyOwJPMb7/EC2Az6Otw4StHdXUYw22zHazBcPFnv6zCgPx1hA7QlQDWTu4YcL0WmTYQCtMUb3FUqrcFtzGDD0ytosgwSd+JyN5vj5UwIABjnNOHPZ62EY1OFixnfqX/+dUwrFSs5tPgBF/KkC6R7tmbUfnBON6RrGEmu+ajOTOLy23qUZB4CQ53V7nyAWhzqSK+hw=='
- end
-
- it "should parse the name from the first field" do
- @provider_class.parse_line('test ssh-rsa '+ at key)[:name].should == "test"
- end
-
- it "should parse the first component of the first field as the name" do
- @provider_class.parse_line('test,alias ssh-rsa '+ at key)[:name].should == "test"
- end
-
- it "should parse host_aliases from the remaining components of the first field" do
- @provider_class.parse_line('test,alias ssh-rsa '+ at key)[:host_aliases].should == ["alias"]
- end
-
- it "should parse multiple host_aliases" do
- @provider_class.parse_line('test,alias1,alias2,alias3 ssh-rsa '+ at key)[:host_aliases].should == ["alias1","alias2","alias3"]
- end
-
- it "should not drop an empty host_alias" do
- @provider_class.parse_line('test,alias, ssh-rsa '+ at key)[:host_aliases].should == ["alias",""]
- end
-
- it "should recognise when there are no host aliases" do
- @provider_class.parse_line('test ssh-rsa '+ at key)[:host_aliases].should == []
- end
+ before do
+ @sshkey_class = Puppet::Type.type(:sshkey)
+ @provider_class = @sshkey_class.provider(:parsed)
+ @key = 'AAAAB3NzaC1yc2EAAAABIwAAAQEAzwHhxXvIrtfIwrudFqc8yQcIfMudrgpnuh1F3AV6d2BrLgu/yQE7W5UyJMUjfj427sQudRwKW45O0Jsnr33F4mUw+GIMlAAmp9g24/OcrTiB8ZUKIjoPy/cO4coxGi8/NECtRzpD/ZUPFh6OEpyOwJPMb7/EC2Az6Otw4StHdXUYw22zHazBcPFnv6zCgPx1hA7QlQDWTu4YcL0WmTYQCtMUb3FUqrcFtzGDD0ytosgwSd+JyN5vj5UwIABjnNOHPZ62EY1OFixnfqX/+dUwrFSs5tPgBF/KkC6R7tmbUfnBON6RrGEmu+ajOTOLy23qUZB4CQ53V7nyAWhzqSK+hw=='
+ end
+
+ it "should parse the name from the first field" do
+ @provider_class.parse_line('test ssh-rsa '+ at key)[:name].should == "test"
+ end
+
+ it "should parse the first component of the first field as the name" do
+ @provider_class.parse_line('test,alias ssh-rsa '+ at key)[:name].should == "test"
+ end
+
+ it "should parse host_aliases from the remaining components of the first field" do
+ @provider_class.parse_line('test,alias ssh-rsa '+ at key)[:host_aliases].should == ["alias"]
+ end
+
+ it "should parse multiple host_aliases" do
+ @provider_class.parse_line('test,alias1,alias2,alias3 ssh-rsa '+ at key)[:host_aliases].should == ["alias1","alias2","alias3"]
+ end
+
+ it "should not drop an empty host_alias" do
+ @provider_class.parse_line('test,alias, ssh-rsa '+ at key)[:host_aliases].should == ["alias",""]
+ end
+
+ it "should recognise when there are no host aliases" do
+ @provider_class.parse_line('test ssh-rsa '+ at key)[:host_aliases].should == []
+ end
end
diff --git a/spec/unit/provider/user/hpux_spec.rb b/spec/unit/provider/user/hpux_spec.rb
index 4129a7a..f53f6c3 100755
--- a/spec/unit/provider/user/hpux_spec.rb
+++ b/spec/unit/provider/user/hpux_spec.rb
@@ -5,21 +5,21 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
provider_class = Puppet::Type.type(:user).provider(:hpuxuseradd)
describe provider_class do
- # left from the useradd test... I have no clue what I'm doing.
- before do
- @resource = stub("resource", :name => "myuser", :managehome? => nil, :should => "fakeval", :[] => "fakeval")
- @provider = provider_class.new(@resource)
- end
+ # left from the useradd test... I have no clue what I'm doing.
+ before do
+ @resource = stub("resource", :name => "myuser", :managehome? => nil, :should => "fakeval", :[] => "fakeval")
+ @provider = provider_class.new(@resource)
+ end
- it "should add -F when modifying a user" do
- @resource.expects(:allowdupe?).returns true
- @provider.expects(:execute).with { |args| args.include?("-F") }
- @provider.uid = 1000
- end
+ it "should add -F when modifying a user" do
+ @resource.expects(:allowdupe?).returns true
+ @provider.expects(:execute).with { |args| args.include?("-F") }
+ @provider.uid = 1000
+ end
- it "should add -F when deleting a user" do
- @provider.stubs(:exists?).returns(true)
- @provider.expects(:execute).with { |args| args.include?("-F") }
- @provider.delete
- end
+ it "should add -F when deleting a user" do
+ @provider.stubs(:exists?).returns(true)
+ @provider.expects(:execute).with { |args| args.include?("-F") }
+ @provider.delete
+ end
end
diff --git a/spec/unit/provider/user/ldap_spec.rb b/spec/unit/provider/user/ldap_spec.rb
index adc2180..b663570 100755
--- a/spec/unit/provider/user/ldap_spec.rb
+++ b/spec/unit/provider/user/ldap_spec.rb
@@ -8,272 +8,272 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
provider_class = Puppet::Type.type(:user).provider(:ldap)
describe provider_class do
- it "should have the Ldap provider class as its baseclass" do
- provider_class.superclass.should equal(Puppet::Provider::Ldap)
+ it "should have the Ldap provider class as its baseclass" do
+ provider_class.superclass.should equal(Puppet::Provider::Ldap)
+ end
+
+ it "should manage :posixAccount and :person objectclasses" do
+ provider_class.manager.objectclasses.should == [:posixAccount, :person]
+ end
+
+ it "should use 'ou=People' as its relative base" do
+ provider_class.manager.location.should == "ou=People"
+ end
+
+ it "should use :uid as its rdn" do
+ provider_class.manager.rdn.should == :uid
+ end
+
+ it "should be able to manage passwords" do
+ provider_class.should be_manages_passwords
+ end
+
+ it "should use the ldap group provider to convert group names to numbers" do
+ provider = provider_class.new(:name => "foo")
+ Puppet::Type.type(:group).provider(:ldap).expects(:name2id).with("bar").returns 10
+
+ provider.gid = 'bar'
+ provider.gid.should == 10
+ end
+
+ {:name => "uid",
+ :password => "userPassword",
+ :comment => "cn",
+ :uid => "uidNumber",
+ :gid => "gidNumber",
+ :home => "homeDirectory",
+ :shell => "loginShell"
+ }.each do |puppet, ldap|
+ it "should map :#{puppet.to_s} to '#{ldap}'" do
+ provider_class.manager.ldap_name(puppet).should == ldap
end
+ end
- it "should manage :posixAccount and :person objectclasses" do
- provider_class.manager.objectclasses.should == [:posixAccount, :person]
+ describe "when being created" do
+ before do
+ # So we don't try to actually talk to ldap
+ @connection = mock 'connection'
+ provider_class.manager.stubs(:connect).yields @connection
end
- it "should use 'ou=People' as its relative base" do
- provider_class.manager.location.should == "ou=People"
- end
+ it "should generate the sn as the last field of the cn" do
+ resource = stub 'resource', :should => %w{whatever}
+ resource.stubs(:should).with(:comment).returns ["Luke Kanies"]
+ resource.stubs(:should).with(:ensure).returns :present
+ instance = provider_class.new(:name => "luke", :ensure => :absent)
+ instance.stubs(:resource).returns resource
- it "should use :uid as its rdn" do
- provider_class.manager.rdn.should == :uid
- end
+ @connection.expects(:add).with { |dn, attrs| attrs["sn"] == ["Kanies"] }
- it "should be able to manage passwords" do
- provider_class.should be_manages_passwords
+ instance.create
+ instance.flush
end
- it "should use the ldap group provider to convert group names to numbers" do
- provider = provider_class.new(:name => "foo")
- Puppet::Type.type(:group).provider(:ldap).expects(:name2id).with("bar").returns 10
+ describe "with no uid specified" do
+ it "should pick the first available UID after the largest existing UID" do
+ low = {:name=>["luke"], :shell=>:absent, :uid=>["600"], :home=>["/h"], :gid=>["1000"], :password=>["blah"], :comment=>["l k"]}
+ high = {:name=>["testing"], :shell=>:absent, :uid=>["640"], :home=>["/h"], :gid=>["1000"], :password=>["blah"], :comment=>["t u"]}
+ provider_class.manager.expects(:search).returns([low, high])
- provider.gid = 'bar'
- provider.gid.should == 10
- end
+ resource = stub 'resource', :should => %w{whatever}
+ resource.stubs(:should).with(:uid).returns nil
+ resource.stubs(:should).with(:ensure).returns :present
+ instance = provider_class.new(:name => "luke", :ensure => :absent)
+ instance.stubs(:resource).returns resource
- {:name => "uid",
- :password => "userPassword",
- :comment => "cn",
- :uid => "uidNumber",
- :gid => "gidNumber",
- :home => "homeDirectory",
- :shell => "loginShell"
- }.each do |puppet, ldap|
- it "should map :#{puppet.to_s} to '#{ldap}'" do
- provider_class.manager.ldap_name(puppet).should == ldap
- end
- end
+ @connection.expects(:add).with { |dn, attrs| attrs["uidNumber"] == ["641"] }
+
+ instance.create
+ instance.flush
+ end
+
+ it "should pick 501 of no users exist" do
+ provider_class.manager.expects(:search).returns nil
- describe "when being created" do
- before do
- # So we don't try to actually talk to ldap
- @connection = mock 'connection'
- provider_class.manager.stubs(:connect).yields @connection
- end
-
- it "should generate the sn as the last field of the cn" do
- resource = stub 'resource', :should => %w{whatever}
- resource.stubs(:should).with(:comment).returns ["Luke Kanies"]
- resource.stubs(:should).with(:ensure).returns :present
- instance = provider_class.new(:name => "luke", :ensure => :absent)
- instance.stubs(:resource).returns resource
-
- @connection.expects(:add).with { |dn, attrs| attrs["sn"] == ["Kanies"] }
-
- instance.create
- instance.flush
- end
-
- describe "with no uid specified" do
- it "should pick the first available UID after the largest existing UID" do
- low = {:name=>["luke"], :shell=>:absent, :uid=>["600"], :home=>["/h"], :gid=>["1000"], :password=>["blah"], :comment=>["l k"]}
- high = {:name=>["testing"], :shell=>:absent, :uid=>["640"], :home=>["/h"], :gid=>["1000"], :password=>["blah"], :comment=>["t u"]}
- provider_class.manager.expects(:search).returns([low, high])
-
- resource = stub 'resource', :should => %w{whatever}
- resource.stubs(:should).with(:uid).returns nil
- resource.stubs(:should).with(:ensure).returns :present
- instance = provider_class.new(:name => "luke", :ensure => :absent)
- instance.stubs(:resource).returns resource
-
- @connection.expects(:add).with { |dn, attrs| attrs["uidNumber"] == ["641"] }
-
- instance.create
- instance.flush
- end
-
- it "should pick 501 of no users exist" do
- provider_class.manager.expects(:search).returns nil
-
- resource = stub 'resource', :should => %w{whatever}
- resource.stubs(:should).with(:uid).returns nil
- resource.stubs(:should).with(:ensure).returns :present
- instance = provider_class.new(:name => "luke", :ensure => :absent)
- instance.stubs(:resource).returns resource
-
- @connection.expects(:add).with { |dn, attrs| attrs["uidNumber"] == ["501"] }
-
- instance.create
- instance.flush
- end
- end
+ resource = stub 'resource', :should => %w{whatever}
+ resource.stubs(:should).with(:uid).returns nil
+ resource.stubs(:should).with(:ensure).returns :present
+ instance = provider_class.new(:name => "luke", :ensure => :absent)
+ instance.stubs(:resource).returns resource
+
+ @connection.expects(:add).with { |dn, attrs| attrs["uidNumber"] == ["501"] }
+
+ instance.create
+ instance.flush
+ end
end
+ end
- describe "when flushing" do
- before do
- provider_class.stubs(:suitable?).returns true
+ describe "when flushing" do
+ before do
+ provider_class.stubs(:suitable?).returns true
- @instance = provider_class.new(:name => "myname", :groups => %w{whatever}, :uid => "400")
- end
+ @instance = provider_class.new(:name => "myname", :groups => %w{whatever}, :uid => "400")
+ end
- it "should remove the :groups value before updating" do
- @instance.class.manager.expects(:update).with { |name, ldap, puppet| puppet[:groups].nil? }
+ it "should remove the :groups value before updating" do
+ @instance.class.manager.expects(:update).with { |name, ldap, puppet| puppet[:groups].nil? }
- @instance.flush
- end
+ @instance.flush
+ end
- it "should empty the property hash" do
- @instance.class.manager.stubs(:update)
+ it "should empty the property hash" do
+ @instance.class.manager.stubs(:update)
- @instance.flush
+ @instance.flush
- @instance.uid.should == :absent
- end
+ @instance.uid.should == :absent
+ end
- it "should empty the ldap property hash" do
- @instance.class.manager.stubs(:update)
+ it "should empty the ldap property hash" do
+ @instance.class.manager.stubs(:update)
- @instance.flush
+ @instance.flush
- @instance.ldap_properties[:uid].should be_nil
- end
+ @instance.ldap_properties[:uid].should be_nil
end
+ end
- describe "when checking group membership" do
- before do
- @groups = Puppet::Type.type(:group).provider(:ldap)
- @group_manager = @groups.manager
- provider_class.stubs(:suitable?).returns true
+ describe "when checking group membership" do
+ before do
+ @groups = Puppet::Type.type(:group).provider(:ldap)
+ @group_manager = @groups.manager
+ provider_class.stubs(:suitable?).returns true
- @instance = provider_class.new(:name => "myname")
- end
+ @instance = provider_class.new(:name => "myname")
+ end
- it "should show its group membership as the sorted list of all groups returned by an ldap query of group memberships" do
- one = {:name => "one"}
- two = {:name => "two"}
- @group_manager.expects(:search).with("memberUid=myname").returns([two, one])
+ it "should show its group membership as the sorted list of all groups returned by an ldap query of group memberships" do
+ one = {:name => "one"}
+ two = {:name => "two"}
+ @group_manager.expects(:search).with("memberUid=myname").returns([two, one])
- @instance.groups.should == "one,two"
- end
+ @instance.groups.should == "one,two"
+ end
- it "should show its group membership as :absent if no matching groups are found in ldap" do
- @group_manager.expects(:search).with("memberUid=myname").returns(nil)
+ it "should show its group membership as :absent if no matching groups are found in ldap" do
+ @group_manager.expects(:search).with("memberUid=myname").returns(nil)
- @instance.groups.should == :absent
- end
+ @instance.groups.should == :absent
+ end
- it "should cache the group value" do
- @group_manager.expects(:search).with("memberUid=myname").once.returns nil
+ it "should cache the group value" do
+ @group_manager.expects(:search).with("memberUid=myname").once.returns nil
- @instance.groups
- @instance.groups.should == :absent
- end
+ @instance.groups
+ @instance.groups.should == :absent
end
+ end
- describe "when modifying group membership" do
- before do
- @groups = Puppet::Type.type(:group).provider(:ldap)
- @group_manager = @groups.manager
- provider_class.stubs(:suitable?).returns true
+ describe "when modifying group membership" do
+ before do
+ @groups = Puppet::Type.type(:group).provider(:ldap)
+ @group_manager = @groups.manager
+ provider_class.stubs(:suitable?).returns true
- @one = {:name => "one", :gid => "500"}
- @group_manager.stubs(:find).with("one").returns(@one)
+ @one = {:name => "one", :gid => "500"}
+ @group_manager.stubs(:find).with("one").returns(@one)
- @two = {:name => "one", :gid => "600"}
- @group_manager.stubs(:find).with("two").returns(@two)
+ @two = {:name => "one", :gid => "600"}
+ @group_manager.stubs(:find).with("two").returns(@two)
- @instance = provider_class.new(:name => "myname")
+ @instance = provider_class.new(:name => "myname")
- @instance.stubs(:groups).returns :absent
- end
+ @instance.stubs(:groups).returns :absent
+ end
- it "should fail if the group does not exist" do
- @group_manager.expects(:find).with("mygroup").returns nil
+ it "should fail if the group does not exist" do
+ @group_manager.expects(:find).with("mygroup").returns nil
- lambda { @instance.groups = "mygroup" }.should raise_error(Puppet::Error)
- end
+ lambda { @instance.groups = "mygroup" }.should raise_error(Puppet::Error)
+ end
- it "should only pass the attributes it cares about to the group manager" do
- @group_manager.expects(:update).with { |name, attrs| attrs[:gid].nil? }
+ it "should only pass the attributes it cares about to the group manager" do
+ @group_manager.expects(:update).with { |name, attrs| attrs[:gid].nil? }
- @instance.groups = "one"
- end
+ @instance.groups = "one"
+ end
- it "should always include :ensure => :present in the current values" do
- @group_manager.expects(:update).with { |name, is, should| is[:ensure] == :present }
+ it "should always include :ensure => :present in the current values" do
+ @group_manager.expects(:update).with { |name, is, should| is[:ensure] == :present }
- @instance.groups = "one"
- end
+ @instance.groups = "one"
+ end
- it "should always include :ensure => :present in the desired values" do
- @group_manager.expects(:update).with { |name, is, should| should[:ensure] == :present }
+ it "should always include :ensure => :present in the desired values" do
+ @group_manager.expects(:update).with { |name, is, should| should[:ensure] == :present }
- @instance.groups = "one"
- end
+ @instance.groups = "one"
+ end
- it "should always pass the group's original member list" do
- @one[:members] = %w{yay ness}
- @group_manager.expects(:update).with { |name, is, should| is[:members] == %w{yay ness} }
+ it "should always pass the group's original member list" do
+ @one[:members] = %w{yay ness}
+ @group_manager.expects(:update).with { |name, is, should| is[:members] == %w{yay ness} }
- @instance.groups = "one"
- end
+ @instance.groups = "one"
+ end
- it "should find the group again when resetting its member list, so it has the full member list" do
- @group_manager.expects(:find).with("one").returns(@one)
+ it "should find the group again when resetting its member list, so it has the full member list" do
+ @group_manager.expects(:find).with("one").returns(@one)
- @group_manager.stubs(:update)
+ @group_manager.stubs(:update)
- @instance.groups = "one"
- end
+ @instance.groups = "one"
+ end
- describe "for groups that have no members" do
- it "should create a new members attribute with its value being the user's name" do
- @group_manager.expects(:update).with { |name, is, should| should[:members] == %w{myname} }
+ describe "for groups that have no members" do
+ it "should create a new members attribute with its value being the user's name" do
+ @group_manager.expects(:update).with { |name, is, should| should[:members] == %w{myname} }
- @instance.groups = "one"
- end
- end
+ @instance.groups = "one"
+ end
+ end
- describe "for groups it is being removed from" do
- it "should replace the group's member list with one missing the user's name" do
- @one[:members] = %w{myname a}
- @two[:members] = %w{myname b}
+ describe "for groups it is being removed from" do
+ it "should replace the group's member list with one missing the user's name" do
+ @one[:members] = %w{myname a}
+ @two[:members] = %w{myname b}
- @group_manager.expects(:update).with { |name, is, should| name == "two" and should[:members] == %w{b} }
+ @group_manager.expects(:update).with { |name, is, should| name == "two" and should[:members] == %w{b} }
- @instance.stubs(:groups).returns "one,two"
- @instance.groups = "one"
- end
+ @instance.stubs(:groups).returns "one,two"
+ @instance.groups = "one"
+ end
- it "should mark the member list as empty if there are no remaining members" do
- @one[:members] = %w{myname}
- @two[:members] = %w{myname b}
+ it "should mark the member list as empty if there are no remaining members" do
+ @one[:members] = %w{myname}
+ @two[:members] = %w{myname b}
- @group_manager.expects(:update).with { |name, is, should| name == "one" and should[:members] == :absent }
+ @group_manager.expects(:update).with { |name, is, should| name == "one" and should[:members] == :absent }
- @instance.stubs(:groups).returns "one,two"
- @instance.groups = "two"
- end
- end
+ @instance.stubs(:groups).returns "one,two"
+ @instance.groups = "two"
+ end
+ end
- describe "for groups that already have members" do
- it "should replace each group's member list with a new list including the user's name" do
- @one[:members] = %w{a b}
- @group_manager.expects(:update).with { |name, is, should| should[:members] == %w{a b myname} }
- @two[:members] = %w{b c}
- @group_manager.expects(:update).with { |name, is, should| should[:members] == %w{b c myname} }
+ describe "for groups that already have members" do
+ it "should replace each group's member list with a new list including the user's name" do
+ @one[:members] = %w{a b}
+ @group_manager.expects(:update).with { |name, is, should| should[:members] == %w{a b myname} }
+ @two[:members] = %w{b c}
+ @group_manager.expects(:update).with { |name, is, should| should[:members] == %w{b c myname} }
- @instance.groups = "one,two"
- end
- end
+ @instance.groups = "one,two"
+ end
+ end
- describe "for groups of which it is a member" do
- it "should do nothing" do
- @one[:members] = %w{a b}
- @group_manager.expects(:update).with { |name, is, should| should[:members] == %w{a b myname} }
+ describe "for groups of which it is a member" do
+ it "should do nothing" do
+ @one[:members] = %w{a b}
+ @group_manager.expects(:update).with { |name, is, should| should[:members] == %w{a b myname} }
- @two[:members] = %w{c myname}
- @group_manager.expects(:update).with { |name, *other| name == "two" }.never
+ @two[:members] = %w{c myname}
+ @group_manager.expects(:update).with { |name, *other| name == "two" }.never
- @instance.stubs(:groups).returns "two"
+ @instance.stubs(:groups).returns "two"
- @instance.groups = "one,two"
- end
- end
+ @instance.groups = "one,two"
+ end
end
+ end
end
diff --git a/spec/unit/provider/user/user_role_add_spec.rb b/spec/unit/provider/user/user_role_add_spec.rb
index 4dbfb83..211f426 100644
--- a/spec/unit/provider/user/user_role_add_spec.rb
+++ b/spec/unit/provider/user/user_role_add_spec.rb
@@ -5,245 +5,245 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
provider_class = Puppet::Type.type(:user).provider(:user_role_add)
describe provider_class do
+ before do
+ @resource = stub("resource", :name => "myuser", :managehome? => nil)
+ @resource.stubs(:should).returns "fakeval"
+ @resource.stubs(:[]).returns "fakeval"
+ @resource.stubs(:allowdupe?).returns false
+ @provider = provider_class.new(@resource)
+ end
+
+ describe "when calling command" do
before do
- @resource = stub("resource", :name => "myuser", :managehome? => nil)
- @resource.stubs(:should).returns "fakeval"
- @resource.stubs(:[]).returns "fakeval"
- @resource.stubs(:allowdupe?).returns false
- @provider = provider_class.new(@resource)
- end
-
- describe "when calling command" do
- before do
- klass = stub("provider")
- klass.stubs(:command).with(:foo).returns("userfoo")
- klass.stubs(:command).with(:role_foo).returns("rolefoo")
- @provider.stubs(:class).returns(klass)
- end
-
- it "should use the command if not a role and ensure!=role" do
- @provider.stubs(:is_role?).returns(false)
- @provider.stubs(:exists?).returns(false)
- @resource.stubs(:[]).with(:ensure).returns(:present)
- @provider.command(:foo).should == "userfoo"
- end
-
- it "should use the role command when a role" do
- @provider.stubs(:is_role?).returns(true)
- @provider.command(:foo).should == "rolefoo"
- end
-
- it "should use the role command when !exists and ensure=role" do
- @provider.stubs(:is_role?).returns(false)
- @provider.stubs(:exists?).returns(false)
- @resource.stubs(:[]).with(:ensure).returns(:role)
- @provider.command(:foo).should == "rolefoo"
- end
- end
-
- describe "when calling transition" do
- it "should return the type set to whatever is passed in" do
- @provider.expects(:command).with(:modify).returns("foomod")
- @provider.transition("bar").include?("type=bar")
- end
- end
-
- describe "when calling create" do
- before do
- @provider.stubs(:password=)
- end
-
- it "should use the add command when the user is not a role" do
- @provider.stubs(:is_role?).returns(false)
- @provider.expects(:addcmd).returns("useradd")
- @provider.expects(:run)
- @provider.create
- end
-
- it "should use transition(normal) when the user is a role" do
- @provider.stubs(:is_role?).returns(true)
- @provider.expects(:transition).with("normal")
- @provider.expects(:run)
- @provider.create
- end
- end
-
- describe "when calling destroy" do
- it "should use the delete command if the user exists and is not a role" do
- @provider.stubs(:exists?).returns(true)
- @provider.stubs(:is_role?).returns(false)
- @provider.expects(:deletecmd)
- @provider.expects(:run)
- @provider.destroy
- end
-
- it "should use the delete command if the user is a role" do
- @provider.stubs(:exists?).returns(true)
- @provider.stubs(:is_role?).returns(true)
- @provider.expects(:deletecmd)
- @provider.expects(:run)
- @provider.destroy
- end
- end
-
- describe "when calling create_role" do
- it "should use the transition(role) if the user exists" do
- @provider.stubs(:exists?).returns(true)
- @provider.stubs(:is_role?).returns(false)
- @provider.expects(:transition).with("role")
- @provider.expects(:run)
- @provider.create_role
- end
-
- it "should use the add command when role doesn't exists" do
- @provider.stubs(:exists?).returns(false)
- @provider.expects(:addcmd)
- @provider.expects(:run)
- @provider.create_role
- end
- end
-
- describe "when allow duplicate is enabled" do
- before do
- @resource.expects(:allowdupe?).returns true
- @provider.stubs(:is_role?).returns(false)
- @provider.expects(:execute).with { |args| args.include?("-o") }
- end
-
- it "should add -o when the user is being created" do
- @provider.stubs(:password=)
- @provider.create
- end
-
- it "should add -o when the uid is being modified" do
- @provider.uid = 150
- end
- end
-
- [:roles, :auths, :profiles].each do |val|
- describe "when getting #{val}" do
- it "should get the user_attributes" do
- @provider.expects(:user_attributes)
- @provider.send(val)
- end
-
- it "should get the #{val} attribute" do
- attributes = mock("attributes")
- attributes.expects(:[]).with(val)
- @provider.stubs(:user_attributes).returns(attributes)
- @provider.send(val)
- end
- end
- end
-
- describe "when getting the keys" do
- it "should get the user_attributes" do
- @provider.expects(:user_attributes)
- @provider.keys
- end
-
- it "should call removed_managed_attributes" do
- @provider.stubs(:user_attributes).returns({ :type => "normal", :foo => "something" })
- @provider.expects(:remove_managed_attributes)
- @provider.keys
- end
-
- it "should removed managed attribute (type, auths, roles, etc)" do
- @provider.stubs(:user_attributes).returns({ :type => "normal", :foo => "something" })
- @provider.keys.should == { :foo => "something" }
- end
- end
-
- describe "when adding properties" do
- it "should call build_keys_cmd" do
- @resource.stubs(:should).returns ""
- @resource.expects(:should).with(:keys).returns({ :foo => "bar" })
- @provider.expects(:build_keys_cmd).returns([])
- @provider.add_properties
- end
-
- it "should add the elements of the keys hash to an array" do
- @resource.stubs(:should).returns ""
- @resource.expects(:should).with(:keys).returns({ :foo => "bar"})
- @provider.add_properties.must == ["-K", "foo=bar"]
- end
- end
-
- describe "when calling build_keys_cmd" do
- it "should build cmd array with keypairs seperated by -K ending with user" do
- @provider.build_keys_cmd({"foo" => "bar", "baz" => "boo"}).should.eql? ["-K", "foo=bar", "-K", "baz=boo"]
- end
- end
-
- describe "when setting the keys" do
- before do
- @provider.stubs(:is_role?).returns(false)
- end
-
- it "should run a command" do
- @provider.expects(:run)
- @provider.keys=({})
- end
-
- it "should build the command" do
- @resource.stubs(:[]).with(:name).returns("someuser")
- @provider.stubs(:command).returns("usermod")
- @provider.expects(:build_keys_cmd).returns(["-K", "foo=bar"])
- @provider.expects(:run).with(["usermod", "-K", "foo=bar", "someuser"], "modify attribute key pairs")
- @provider.keys=({})
- end
- end
-
- describe "when getting the hashed password" do
- before do
- @array = mock "array"
- end
-
- it "should readlines of /etc/shadow" do
- File.expects(:readlines).with("/etc/shadow").returns([])
- @provider.password
- end
-
- it "should reject anything that doesn't start with alpha numerics" do
- @array.expects(:reject).returns([])
- File.stubs(:readlines).with("/etc/shadow").returns(@array)
- @provider.password
- end
-
- it "should collect splitting on ':'" do
- @array.stubs(:reject).returns(@array)
- @array.expects(:collect).returns([])
- File.stubs(:readlines).with("/etc/shadow").returns(@array)
- @provider.password
- end
-
- it "should find the matching user" do
- @resource.stubs(:[]).with(:name).returns("username")
- @array.stubs(:reject).returns(@array)
- @array.stubs(:collect).returns([["username", "hashedpassword"], ["someoneelse", "theirpassword"]])
- File.stubs(:readlines).with("/etc/shadow").returns(@array)
- @provider.password.must == "hashedpassword"
- end
-
- it "should get the right password" do
- @resource.stubs(:[]).with(:name).returns("username")
- File.stubs(:readlines).with("/etc/shadow").returns(["#comment", " nonsense", " ", "username:hashedpassword:stuff:foo:bar:::", "other:pword:yay:::"])
- @provider.password.must == "hashedpassword"
- end
- end
-
- describe "when setting the password" do
- #how can you mock these blocks up?
- it "should open /etc/shadow for reading and /etc/shadow_tmp for writing" do
- File.expects(:open).with("/etc/shadow", "r")
- File.stubs(:rename)
- @provider.password=("hashedpassword")
- end
-
- it "should rename the /etc/shadow_tmp to /etc/shadow" do
- File.stubs(:open).with("/etc/shadow", "r")
- File.expects(:rename).with("/etc/shadow_tmp", "/etc/shadow")
- @provider.password=("hashedpassword")
- end
+ klass = stub("provider")
+ klass.stubs(:command).with(:foo).returns("userfoo")
+ klass.stubs(:command).with(:role_foo).returns("rolefoo")
+ @provider.stubs(:class).returns(klass)
end
+
+ it "should use the command if not a role and ensure!=role" do
+ @provider.stubs(:is_role?).returns(false)
+ @provider.stubs(:exists?).returns(false)
+ @resource.stubs(:[]).with(:ensure).returns(:present)
+ @provider.command(:foo).should == "userfoo"
+ end
+
+ it "should use the role command when a role" do
+ @provider.stubs(:is_role?).returns(true)
+ @provider.command(:foo).should == "rolefoo"
+ end
+
+ it "should use the role command when !exists and ensure=role" do
+ @provider.stubs(:is_role?).returns(false)
+ @provider.stubs(:exists?).returns(false)
+ @resource.stubs(:[]).with(:ensure).returns(:role)
+ @provider.command(:foo).should == "rolefoo"
+ end
+ end
+
+ describe "when calling transition" do
+ it "should return the type set to whatever is passed in" do
+ @provider.expects(:command).with(:modify).returns("foomod")
+ @provider.transition("bar").include?("type=bar")
+ end
+ end
+
+ describe "when calling create" do
+ before do
+ @provider.stubs(:password=)
+ end
+
+ it "should use the add command when the user is not a role" do
+ @provider.stubs(:is_role?).returns(false)
+ @provider.expects(:addcmd).returns("useradd")
+ @provider.expects(:run)
+ @provider.create
+ end
+
+ it "should use transition(normal) when the user is a role" do
+ @provider.stubs(:is_role?).returns(true)
+ @provider.expects(:transition).with("normal")
+ @provider.expects(:run)
+ @provider.create
+ end
+ end
+
+ describe "when calling destroy" do
+ it "should use the delete command if the user exists and is not a role" do
+ @provider.stubs(:exists?).returns(true)
+ @provider.stubs(:is_role?).returns(false)
+ @provider.expects(:deletecmd)
+ @provider.expects(:run)
+ @provider.destroy
+ end
+
+ it "should use the delete command if the user is a role" do
+ @provider.stubs(:exists?).returns(true)
+ @provider.stubs(:is_role?).returns(true)
+ @provider.expects(:deletecmd)
+ @provider.expects(:run)
+ @provider.destroy
+ end
+ end
+
+ describe "when calling create_role" do
+ it "should use the transition(role) if the user exists" do
+ @provider.stubs(:exists?).returns(true)
+ @provider.stubs(:is_role?).returns(false)
+ @provider.expects(:transition).with("role")
+ @provider.expects(:run)
+ @provider.create_role
+ end
+
+ it "should use the add command when role doesn't exists" do
+ @provider.stubs(:exists?).returns(false)
+ @provider.expects(:addcmd)
+ @provider.expects(:run)
+ @provider.create_role
+ end
+ end
+
+ describe "when allow duplicate is enabled" do
+ before do
+ @resource.expects(:allowdupe?).returns true
+ @provider.stubs(:is_role?).returns(false)
+ @provider.expects(:execute).with { |args| args.include?("-o") }
+ end
+
+ it "should add -o when the user is being created" do
+ @provider.stubs(:password=)
+ @provider.create
+ end
+
+ it "should add -o when the uid is being modified" do
+ @provider.uid = 150
+ end
+ end
+
+ [:roles, :auths, :profiles].each do |val|
+ describe "when getting #{val}" do
+ it "should get the user_attributes" do
+ @provider.expects(:user_attributes)
+ @provider.send(val)
+ end
+
+ it "should get the #{val} attribute" do
+ attributes = mock("attributes")
+ attributes.expects(:[]).with(val)
+ @provider.stubs(:user_attributes).returns(attributes)
+ @provider.send(val)
+ end
+ end
+ end
+
+ describe "when getting the keys" do
+ it "should get the user_attributes" do
+ @provider.expects(:user_attributes)
+ @provider.keys
+ end
+
+ it "should call removed_managed_attributes" do
+ @provider.stubs(:user_attributes).returns({ :type => "normal", :foo => "something" })
+ @provider.expects(:remove_managed_attributes)
+ @provider.keys
+ end
+
+ it "should removed managed attribute (type, auths, roles, etc)" do
+ @provider.stubs(:user_attributes).returns({ :type => "normal", :foo => "something" })
+ @provider.keys.should == { :foo => "something" }
+ end
+ end
+
+ describe "when adding properties" do
+ it "should call build_keys_cmd" do
+ @resource.stubs(:should).returns ""
+ @resource.expects(:should).with(:keys).returns({ :foo => "bar" })
+ @provider.expects(:build_keys_cmd).returns([])
+ @provider.add_properties
+ end
+
+ it "should add the elements of the keys hash to an array" do
+ @resource.stubs(:should).returns ""
+ @resource.expects(:should).with(:keys).returns({ :foo => "bar"})
+ @provider.add_properties.must == ["-K", "foo=bar"]
+ end
+ end
+
+ describe "when calling build_keys_cmd" do
+ it "should build cmd array with keypairs seperated by -K ending with user" do
+ @provider.build_keys_cmd({"foo" => "bar", "baz" => "boo"}).should.eql? ["-K", "foo=bar", "-K", "baz=boo"]
+ end
+ end
+
+ describe "when setting the keys" do
+ before do
+ @provider.stubs(:is_role?).returns(false)
+ end
+
+ it "should run a command" do
+ @provider.expects(:run)
+ @provider.keys=({})
+ end
+
+ it "should build the command" do
+ @resource.stubs(:[]).with(:name).returns("someuser")
+ @provider.stubs(:command).returns("usermod")
+ @provider.expects(:build_keys_cmd).returns(["-K", "foo=bar"])
+ @provider.expects(:run).with(["usermod", "-K", "foo=bar", "someuser"], "modify attribute key pairs")
+ @provider.keys=({})
+ end
+ end
+
+ describe "when getting the hashed password" do
+ before do
+ @array = mock "array"
+ end
+
+ it "should readlines of /etc/shadow" do
+ File.expects(:readlines).with("/etc/shadow").returns([])
+ @provider.password
+ end
+
+ it "should reject anything that doesn't start with alpha numerics" do
+ @array.expects(:reject).returns([])
+ File.stubs(:readlines).with("/etc/shadow").returns(@array)
+ @provider.password
+ end
+
+ it "should collect splitting on ':'" do
+ @array.stubs(:reject).returns(@array)
+ @array.expects(:collect).returns([])
+ File.stubs(:readlines).with("/etc/shadow").returns(@array)
+ @provider.password
+ end
+
+ it "should find the matching user" do
+ @resource.stubs(:[]).with(:name).returns("username")
+ @array.stubs(:reject).returns(@array)
+ @array.stubs(:collect).returns([["username", "hashedpassword"], ["someoneelse", "theirpassword"]])
+ File.stubs(:readlines).with("/etc/shadow").returns(@array)
+ @provider.password.must == "hashedpassword"
+ end
+
+ it "should get the right password" do
+ @resource.stubs(:[]).with(:name).returns("username")
+ File.stubs(:readlines).with("/etc/shadow").returns(["#comment", " nonsense", " ", "username:hashedpassword:stuff:foo:bar:::", "other:pword:yay:::"])
+ @provider.password.must == "hashedpassword"
+ end
+ end
+
+ describe "when setting the password" do
+ #how can you mock these blocks up?
+ it "should open /etc/shadow for reading and /etc/shadow_tmp for writing" do
+ File.expects(:open).with("/etc/shadow", "r")
+ File.stubs(:rename)
+ @provider.password=("hashedpassword")
+ end
+
+ it "should rename the /etc/shadow_tmp to /etc/shadow" do
+ File.stubs(:open).with("/etc/shadow", "r")
+ File.expects(:rename).with("/etc/shadow_tmp", "/etc/shadow")
+ @provider.password=("hashedpassword")
+ end
+ end
end
diff --git a/spec/unit/provider/user/useradd_spec.rb b/spec/unit/provider/user/useradd_spec.rb
index 463212e..6eb9717 100755
--- a/spec/unit/provider/user/useradd_spec.rb
+++ b/spec/unit/provider/user/useradd_spec.rb
@@ -5,111 +5,111 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
provider_class = Puppet::Type.type(:user).provider(:useradd)
describe provider_class do
- before do
- @resource = stub("resource", :name => "myuser", :managehome? => nil)
- @resource.stubs(:should).returns "fakeval"
- @resource.stubs(:[]).returns "fakeval"
- @provider = provider_class.new(@resource)
+ before do
+ @resource = stub("resource", :name => "myuser", :managehome? => nil)
+ @resource.stubs(:should).returns "fakeval"
+ @resource.stubs(:[]).returns "fakeval"
+ @provider = provider_class.new(@resource)
+ end
+
+ # #1360
+ it "should add -o when allowdupe is enabled and the user is being created" do
+ @resource.expects(:allowdupe?).returns true
+ @provider.expects(:execute).with { |args| args.include?("-o") }
+ @provider.create
+ end
+
+ it "should add -o when allowdupe is enabled and the uid is being modified" do
+ @resource.expects(:allowdupe?).returns true
+ @provider.expects(:execute).with { |args| args.include?("-o") }
+
+ @provider.uid = 150
+ end
+
+ describe "when checking to add allow dup" do
+ it "should check allow dup" do
+ @resource.expects(:allowdupe?)
+ @provider.check_allow_dup
+ end
+
+ it "should return an array with a flag if dup is allowed" do
+ @resource.stubs(:allowdupe?).returns true
+ @provider.check_allow_dup.must == ["-o"]
+ end
+
+ it "should return an empty array if no dup is allowed" do
+ @resource.stubs(:allowdupe?).returns false
+ @provider.check_allow_dup.must == []
+ end
+ end
+
+ describe "when checking manage home" do
+ it "should check manage home" do
+ @resource.expects(:managehome?)
+ @provider.check_manage_home
+ end
+
+ it "should return an array with -m flag if home is managed" do
+ @resource.stubs(:managehome?).returns true
+ @provider.check_manage_home.must == ["-m"]
+ end
+
+ it "should return an array with -M if home is not managed and on Redhat" do
+ Facter.stubs(:value).with("operatingsystem").returns("RedHat")
+ @resource.stubs(:managehome?).returns false
+ @provider.check_manage_home.must == ["-M"]
+ end
+
+ it "should return an empty array if home is not managed and not on Redhat" do
+ Facter.stubs(:value).with("operatingsystem").returns("some OS")
+ @resource.stubs(:managehome?).returns false
+ @provider.check_manage_home.must == []
end
+ end
+
+ describe "when adding properties" do
+ it "should get the valid properties"
+ it "should not add the ensure property"
+ it "should add the flag and value to an array"
+ it "should return and array of flags and values"
+ end
- # #1360
- it "should add -o when allowdupe is enabled and the user is being created" do
- @resource.expects(:allowdupe?).returns true
- @provider.expects(:execute).with { |args| args.include?("-o") }
- @provider.create
+ describe "when calling addcmd" do
+ before do
+ @resource.stubs(:allowdupe?).returns true
+ @resource.stubs(:managehome?).returns true
end
- it "should add -o when allowdupe is enabled and the uid is being modified" do
- @resource.expects(:allowdupe?).returns true
- @provider.expects(:execute).with { |args| args.include?("-o") }
+ it "should call command with :add" do
+ @provider.expects(:command).with(:add)
+ @provider.addcmd
+ end
- @provider.uid = 150
+ it "should add properties" do
+ @provider.expects(:add_properties).returns([])
+ @provider.addcmd
end
- describe "when checking to add allow dup" do
- it "should check allow dup" do
- @resource.expects(:allowdupe?)
- @provider.check_allow_dup
- end
-
- it "should return an array with a flag if dup is allowed" do
- @resource.stubs(:allowdupe?).returns true
- @provider.check_allow_dup.must == ["-o"]
- end
-
- it "should return an empty array if no dup is allowed" do
- @resource.stubs(:allowdupe?).returns false
- @provider.check_allow_dup.must == []
- end
+ it "should check and add if dup allowed" do
+ @provider.expects(:check_allow_dup).returns([])
+ @provider.addcmd
end
- describe "when checking manage home" do
- it "should check manage home" do
- @resource.expects(:managehome?)
- @provider.check_manage_home
- end
-
- it "should return an array with -m flag if home is managed" do
- @resource.stubs(:managehome?).returns true
- @provider.check_manage_home.must == ["-m"]
- end
-
- it "should return an array with -M if home is not managed and on Redhat" do
- Facter.stubs(:value).with("operatingsystem").returns("RedHat")
- @resource.stubs(:managehome?).returns false
- @provider.check_manage_home.must == ["-M"]
- end
-
- it "should return an empty array if home is not managed and not on Redhat" do
- Facter.stubs(:value).with("operatingsystem").returns("some OS")
- @resource.stubs(:managehome?).returns false
- @provider.check_manage_home.must == []
- end
+ it "should check and add if home is managed" do
+ @provider.expects(:check_manage_home).returns([])
+ @provider.addcmd
end
- describe "when adding properties" do
- it "should get the valid properties"
- it "should not add the ensure property"
- it "should add the flag and value to an array"
- it "should return and array of flags and values"
+ it "should add the resource :name" do
+ @resource.expects(:[]).with(:name)
+ @provider.addcmd
end
- describe "when calling addcmd" do
- before do
- @resource.stubs(:allowdupe?).returns true
- @resource.stubs(:managehome?).returns true
- end
-
- it "should call command with :add" do
- @provider.expects(:command).with(:add)
- @provider.addcmd
- end
-
- it "should add properties" do
- @provider.expects(:add_properties).returns([])
- @provider.addcmd
- end
-
- it "should check and add if dup allowed" do
- @provider.expects(:check_allow_dup).returns([])
- @provider.addcmd
- end
-
- it "should check and add if home is managed" do
- @provider.expects(:check_manage_home).returns([])
- @provider.addcmd
- end
-
- it "should add the resource :name" do
- @resource.expects(:[]).with(:name)
- @provider.addcmd
- end
-
- it "should return an array with full command" do
- @provider.stubs(:command).with(:add).returns("useradd")
- @provider.stubs(:add_properties).returns(["-G", "somegroup"])
- @resource.stubs(:[]).with(:name).returns("someuser")
- @provider.addcmd.must == ["useradd", "-G", "somegroup", "-o", "-m", "someuser"]
- end
+ it "should return an array with full command" do
+ @provider.stubs(:command).with(:add).returns("useradd")
+ @provider.stubs(:add_properties).returns(["-G", "somegroup"])
+ @resource.stubs(:[]).with(:name).returns("someuser")
+ @provider.addcmd.must == ["useradd", "-G", "somegroup", "-o", "-m", "someuser"]
end
+ end
end
diff --git a/spec/unit/provider/zfs/solaris_spec.rb b/spec/unit/provider/zfs/solaris_spec.rb
index 8d1d8cc..43a88b1 100755
--- a/spec/unit/provider/zfs/solaris_spec.rb
+++ b/spec/unit/provider/zfs/solaris_spec.rb
@@ -5,95 +5,95 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
provider_class = Puppet::Type.type(:zfs).provider(:solaris)
describe provider_class do
- before do
- @resource = stub("resource", :name => "myzfs")
- @resource.stubs(:[]).with(:name).returns "myzfs"
- @resource.stubs(:[]).returns "shouldvalue"
- @provider = provider_class.new(@resource)
+ before do
+ @resource = stub("resource", :name => "myzfs")
+ @resource.stubs(:[]).with(:name).returns "myzfs"
+ @resource.stubs(:[]).returns "shouldvalue"
+ @provider = provider_class.new(@resource)
+ end
+
+ it "should have a create method" do
+ @provider.should respond_to(:create)
+ end
+
+ it "should have a destroy method" do
+ @provider.should respond_to(:destroy)
+ end
+
+ it "should have an exists? method" do
+ @provider.should respond_to(:exists?)
+ end
+
+ describe "when calling add_properties" do
+ it "should add -o and the key=value for each properties with a value" do
+ @resource.stubs(:[]).with(:quota).returns ""
+ @resource.stubs(:[]).with(:mountpoint).returns "/foo"
+ properties = @provider.add_properties
+ properties.include?("-o").should == true
+ properties.include?("mountpoint=/foo").should == true
+ properties.detect { |a| a.include?("quota") }.should == nil
end
+ end
- it "should have a create method" do
- @provider.should respond_to(:create)
+ describe "when calling create" do
+ it "should call add_properties" do
+ @provider.stubs(:zfs)
+ @provider.expects(:add_properties).returns([])
+ @provider.create
end
- it "should have a destroy method" do
- @provider.should respond_to(:destroy)
+ it "should call zfs with create, properties and this zfs" do
+ @provider.stubs(:add_properties).returns(%w{a b})
+ @provider.expects(:zfs).with(:create, "a", "b", @resource[:name])
+ @provider.create
end
+ end
- it "should have an exists? method" do
- @provider.should respond_to(:exists?)
+ describe "when calling destroy" do
+ it "should call zfs with :destroy and this zfs" do
+ @provider.expects(:zfs).with(:destroy, @resource[:name])
+ @provider.destroy
end
+ end
- describe "when calling add_properties" do
- it "should add -o and the key=value for each properties with a value" do
- @resource.stubs(:[]).with(:quota).returns ""
- @resource.stubs(:[]).with(:mountpoint).returns "/foo"
- properties = @provider.add_properties
- properties.include?("-o").should == true
- properties.include?("mountpoint=/foo").should == true
- properties.detect { |a| a.include?("quota") }.should == nil
- end
+ describe "when calling exist?" do
+ it "should call zfs with :list" do
+ #return stuff because we have to slice and dice it
+ @provider.expects(:zfs).with(:list).returns("NAME USED AVAIL REFER MOUNTPOINT\nmyzfs 100K 27.4M /myzfs")
+ @provider.exists?
end
- describe "when calling create" do
- it "should call add_properties" do
- @provider.stubs(:zfs)
- @provider.expects(:add_properties).returns([])
- @provider.create
- end
-
- it "should call zfs with create, properties and this zfs" do
- @provider.stubs(:add_properties).returns(%w{a b})
- @provider.expects(:zfs).with(:create, "a", "b", @resource[:name])
- @provider.create
- end
+ it "should return true if returned values match the name" do
+ @provider.stubs(:zfs).with(:list).returns("NAME USED AVAIL REFER MOUNTPOINT\n#{@resource[:name]} 100K 27.4M /myzfs")
+ @provider.exists?.should == true
end
- describe "when calling destroy" do
- it "should call zfs with :destroy and this zfs" do
- @provider.expects(:zfs).with(:destroy, @resource[:name])
- @provider.destroy
- end
+ it "should return false if returned values don't match the name" do
+ @provider.stubs(:zfs).with(:list).returns("no soup for you")
+ @provider.exists?.should == false
end
- describe "when calling exist?" do
- it "should call zfs with :list" do
- #return stuff because we have to slice and dice it
- @provider.expects(:zfs).with(:list).returns("NAME USED AVAIL REFER MOUNTPOINT\nmyzfs 100K 27.4M /myzfs")
- @provider.exists?
- end
+ end
- it "should return true if returned values match the name" do
- @provider.stubs(:zfs).with(:list).returns("NAME USED AVAIL REFER MOUNTPOINT\n#{@resource[:name]} 100K 27.4M /myzfs")
- @provider.exists?.should == true
- end
-
- it "should return false if returned values don't match the name" do
- @provider.stubs(:zfs).with(:list).returns("no soup for you")
- @provider.exists?.should == false
- end
+ [:mountpoint, :compression, :copies, :quota, :reservation, :sharenfs, :snapdir].each do |prop|
+ describe "when getting the #{prop} value" do
+ it "should call zfs with :get, #{prop} and this zfs" do
+ @provider.expects(:zfs).with(:get, "-H", "-o", "value", prop, @resource[:name]).returns("value\n")
+ @provider.send(prop)
+ end
+ it "should get the third value of the second line from the output" do
+ @provider.stubs(:zfs).with(:get, "-H", "-o", "value", prop, @resource[:name]).returns("value\n")
+ @provider.send(prop).should == "value"
+ end
end
- [:mountpoint, :compression, :copies, :quota, :reservation, :sharenfs, :snapdir].each do |prop|
- describe "when getting the #{prop} value" do
- it "should call zfs with :get, #{prop} and this zfs" do
- @provider.expects(:zfs).with(:get, "-H", "-o", "value", prop, @resource[:name]).returns("value\n")
- @provider.send(prop)
- end
-
- it "should get the third value of the second line from the output" do
- @provider.stubs(:zfs).with(:get, "-H", "-o", "value", prop, @resource[:name]).returns("value\n")
- @provider.send(prop).should == "value"
- end
- end
-
- describe "when setting the #{prop} value" do
- it "should call zfs with :set, #{prop}=value and this zfs" do
- @provider.expects(:zfs).with(:set, "#{prop}=value", @resource[:name])
- @provider.send("#{prop}=".intern, "value")
- end
- end
+ describe "when setting the #{prop} value" do
+ it "should call zfs with :set, #{prop}=value and this zfs" do
+ @provider.expects(:zfs).with(:set, "#{prop}=value", @resource[:name])
+ @provider.send("#{prop}=".intern, "value")
+ end
end
+ end
end
diff --git a/spec/unit/provider/zone/solaris_spec.rb b/spec/unit/provider/zone/solaris_spec.rb
index 0459e5e..44416aa 100755
--- a/spec/unit/provider/zone/solaris_spec.rb
+++ b/spec/unit/provider/zone/solaris_spec.rb
@@ -5,51 +5,51 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
provider_class = Puppet::Type.type(:zone).provider(:solaris)
describe provider_class do
- before do
- @resource = stub("resource", :name => "mypool")
- @resource.stubs(:[]).returns "shouldvalue"
- @provider = provider_class.new(@resource)
+ before do
+ @resource = stub("resource", :name => "mypool")
+ @resource.stubs(:[]).returns "shouldvalue"
+ @provider = provider_class.new(@resource)
+ end
+
+ describe "when calling configure" do
+ it "should add the create args to the create str" do
+ @resource.stubs(:properties).returns([])
+ @resource.stubs(:[]).with(:create_args).returns("create_args")
+ @provider.expects(:setconfig).with("create -b create_args\nset zonepath=shouldvalue\ncommit\n")
+ @provider.configure
end
+ end
- describe "when calling configure" do
- it "should add the create args to the create str" do
- @resource.stubs(:properties).returns([])
- @resource.stubs(:[]).with(:create_args).returns("create_args")
- @provider.expects(:setconfig).with("create -b create_args\nset zonepath=shouldvalue\ncommit\n")
- @provider.configure
- end
+ describe "when installing" do
+ it "should call zoneadm" do
+ @provider.expects(:zoneadm)
+ @provider.install
end
- describe "when installing" do
- it "should call zoneadm" do
- @provider.expects(:zoneadm)
- @provider.install
- end
-
- describe "when cloning" do
- before { @resource.stubs(:[]).with(:clone).returns(:clone_argument) }
-
- it "sohuld clone with the resource's clone attribute" do
- @provider.expects(:zoneadm).with(:clone, :clone_argument)
- @provider.install
- end
- end
-
- describe "when not cloning" do
- before { @resource.stubs(:[]).with(:clone).returns(nil)}
-
- it "should just install if there are no install args" do
- @resource.stubs(:[]).with(:install_args).returns(nil)
- @provider.expects(:zoneadm).with(:install)
- @provider.install
- end
-
- it "should add the install args to the command if they exist" do
- @resource.stubs(:[]).with(:install_args).returns("install args")
- @provider.expects(:zoneadm).with(:install, ["install", "args"])
- @provider.install
- end
- end
+ describe "when cloning" do
+ before { @resource.stubs(:[]).with(:clone).returns(:clone_argument) }
+
+ it "sohuld clone with the resource's clone attribute" do
+ @provider.expects(:zoneadm).with(:clone, :clone_argument)
+ @provider.install
+ end
+ end
+
+ describe "when not cloning" do
+ before { @resource.stubs(:[]).with(:clone).returns(nil)}
+
+ it "should just install if there are no install args" do
+ @resource.stubs(:[]).with(:install_args).returns(nil)
+ @provider.expects(:zoneadm).with(:install)
+ @provider.install
+ end
+
+ it "should add the install args to the command if they exist" do
+ @resource.stubs(:[]).with(:install_args).returns("install args")
+ @provider.expects(:zoneadm).with(:install, ["install", "args"])
+ @provider.install
+ end
end
+ end
end
diff --git a/spec/unit/provider/zpool/solaris_spec.rb b/spec/unit/provider/zpool/solaris_spec.rb
index b52ddf8..99e6997 100755
--- a/spec/unit/provider/zpool/solaris_spec.rb
+++ b/spec/unit/provider/zpool/solaris_spec.rb
@@ -5,175 +5,175 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
provider_class = Puppet::Type.type(:zpool).provider(:solaris)
describe provider_class do
- before do
- @resource = stub("resource", :name => "mypool")
- @resource.stubs(:[]).returns "shouldvalue"
- @provider = provider_class.new(@resource)
+ before do
+ @resource = stub("resource", :name => "mypool")
+ @resource.stubs(:[]).returns "shouldvalue"
+ @provider = provider_class.new(@resource)
+ end
+
+ describe "when getting the instance" do
+ it "should call process_zpool_data with the result of get_pool_data only once" do
+ @provider.stubs(:get_pool_data).returns(["foo", "disk"])
+ @provider.expects(:process_zpool_data).with(["foo", "disk"]).returns("stuff").once
+ @provider.current_pool
+ @provider.current_pool
end
-
- describe "when getting the instance" do
- it "should call process_zpool_data with the result of get_pool_data only once" do
- @provider.stubs(:get_pool_data).returns(["foo", "disk"])
- @provider.expects(:process_zpool_data).with(["foo", "disk"]).returns("stuff").once
- @provider.current_pool
- @provider.current_pool
- end
+ end
+
+ describe "when calling flush" do
+ it "should need to reload the pool" do
+ @provider.stubs(:get_pool_data)
+ @provider.expects(:process_zpool_data).returns("stuff").times(2)
+ @provider.current_pool
+ @provider.flush
+ @provider.current_pool
end
+ end
- describe "when calling flush" do
- it "should need to reload the pool" do
- @provider.stubs(:get_pool_data)
- @provider.expects(:process_zpool_data).returns("stuff").times(2)
- @provider.current_pool
- @provider.flush
- @provider.current_pool
- end
+ describe "when procesing zpool data" do
+ before do
+ @zpool_data = ["foo", "disk"]
end
- describe "when procesing zpool data" do
- before do
- @zpool_data = ["foo", "disk"]
- end
-
- describe "when there is no data" do
- it "should return a hash with ensure=>:absent" do
- @provider.process_zpool_data([])[:ensure].should == :absent
- end
- end
-
- describe "when there is a spare" do
- it "should add the spare disk to the hash" do
- @zpool_data += ["spares", "spare_disk"]
- @provider.process_zpool_data(@zpool_data)[:spare].should == ["spare_disk"]
- end
- end
+ describe "when there is no data" do
+ it "should return a hash with ensure=>:absent" do
+ @provider.process_zpool_data([])[:ensure].should == :absent
+ end
+ end
- describe "when there are two spares" do
- it "should add the spare disk to the hash as a single string" do
- @zpool_data += ["spares", "spare_disk", "spare_disk2"]
- @provider.process_zpool_data(@zpool_data)[:spare].should == ["spare_disk spare_disk2"]
- end
- end
+ describe "when there is a spare" do
+ it "should add the spare disk to the hash" do
+ @zpool_data += ["spares", "spare_disk"]
+ @provider.process_zpool_data(@zpool_data)[:spare].should == ["spare_disk"]
+ end
+ end
- describe "when there is a log" do
- it "should add the log disk to the hash" do
- @zpool_data += ["logs", "log_disk"]
- @provider.process_zpool_data(@zpool_data)[:log].should == ["log_disk"]
- end
- end
+ describe "when there are two spares" do
+ it "should add the spare disk to the hash as a single string" do
+ @zpool_data += ["spares", "spare_disk", "spare_disk2"]
+ @provider.process_zpool_data(@zpool_data)[:spare].should == ["spare_disk spare_disk2"]
+ end
+ end
- describe "when there are two logs" do
- it "should add the log disks to the hash as a single string" do
- @zpool_data += ["spares", "spare_disk", "spare_disk2"]
- @provider.process_zpool_data(@zpool_data)[:spare].should == ["spare_disk spare_disk2"]
- end
- end
+ describe "when there is a log" do
+ it "should add the log disk to the hash" do
+ @zpool_data += ["logs", "log_disk"]
+ @provider.process_zpool_data(@zpool_data)[:log].should == ["log_disk"]
+ end
+ end
- describe "when the vdev is a single mirror" do
- it "should call create_multi_array with mirror" do
- @zpool_data = ["mirrorpool", "mirror", "disk1", "disk2"]
- @provider.process_zpool_data(@zpool_data)[:mirror].should == ["disk1 disk2"]
- end
- end
+ describe "when there are two logs" do
+ it "should add the log disks to the hash as a single string" do
+ @zpool_data += ["spares", "spare_disk", "spare_disk2"]
+ @provider.process_zpool_data(@zpool_data)[:spare].should == ["spare_disk spare_disk2"]
+ end
+ end
- describe "when the vdev is a double mirror" do
- it "should call create_multi_array with mirror" do
- @zpool_data = ["mirrorpool", "mirror", "disk1", "disk2", "mirror", "disk3", "disk4"]
- @provider.process_zpool_data(@zpool_data)[:mirror].should == ["disk1 disk2", "disk3 disk4"]
- end
- end
+ describe "when the vdev is a single mirror" do
+ it "should call create_multi_array with mirror" do
+ @zpool_data = ["mirrorpool", "mirror", "disk1", "disk2"]
+ @provider.process_zpool_data(@zpool_data)[:mirror].should == ["disk1 disk2"]
+ end
+ end
- describe "when the vdev is a raidz1" do
- it "should call create_multi_array with raidz1" do
- @zpool_data = ["mirrorpool", "raidz1", "disk1", "disk2"]
- @provider.process_zpool_data(@zpool_data)[:raidz].should == ["disk1 disk2"]
- end
- end
+ describe "when the vdev is a double mirror" do
+ it "should call create_multi_array with mirror" do
+ @zpool_data = ["mirrorpool", "mirror", "disk1", "disk2", "mirror", "disk3", "disk4"]
+ @provider.process_zpool_data(@zpool_data)[:mirror].should == ["disk1 disk2", "disk3 disk4"]
+ end
+ end
- describe "when the vdev is a raidz2" do
- it "should call create_multi_array with raidz2 and set the raid_parity" do
- @zpool_data = ["mirrorpool", "raidz2", "disk1", "disk2"]
- pool = @provider.process_zpool_data(@zpool_data)
- pool[:raidz].should == ["disk1 disk2"]
- pool[:raid_parity].should == "raidz2"
- end
- end
+ describe "when the vdev is a raidz1" do
+ it "should call create_multi_array with raidz1" do
+ @zpool_data = ["mirrorpool", "raidz1", "disk1", "disk2"]
+ @provider.process_zpool_data(@zpool_data)[:raidz].should == ["disk1 disk2"]
+ end
end
- describe "when calling the getters and setters" do
- [:disk, :mirror, :raidz, :log, :spare].each do |field|
- describe "when calling #{field}" do
- it "should get the #{field} value from the current_pool hash" do
- pool_hash = mock "pool hash"
- pool_hash.expects(:[]).with(field)
- @provider.stubs(:current_pool).returns(pool_hash)
- @provider.send(field)
- end
- end
-
- describe "when setting the #{field}" do
- it "should warn the #{field} values were not in sync" do
- Puppet.expects(:warning).with("NO CHANGES BEING MADE: zpool #{field} does not match, should be 'shouldvalue' currently is 'currentvalue'")
- @provider.stubs(:current_pool).returns(Hash.new("currentvalue"))
- @provider.send((field.to_s + "=").intern, "shouldvalue")
- end
- end
- end
+ describe "when the vdev is a raidz2" do
+ it "should call create_multi_array with raidz2 and set the raid_parity" do
+ @zpool_data = ["mirrorpool", "raidz2", "disk1", "disk2"]
+ pool = @provider.process_zpool_data(@zpool_data)
+ pool[:raidz].should == ["disk1 disk2"]
+ pool[:raid_parity].should == "raidz2"
+ end
end
+ end
+
+ describe "when calling the getters and setters" do
+ [:disk, :mirror, :raidz, :log, :spare].each do |field|
+ describe "when calling #{field}" do
+ it "should get the #{field} value from the current_pool hash" do
+ pool_hash = mock "pool hash"
+ pool_hash.expects(:[]).with(field)
+ @provider.stubs(:current_pool).returns(pool_hash)
+ @provider.send(field)
+ end
+ end
+
+ describe "when setting the #{field}" do
+ it "should warn the #{field} values were not in sync" do
+ Puppet.expects(:warning).with("NO CHANGES BEING MADE: zpool #{field} does not match, should be 'shouldvalue' currently is 'currentvalue'")
+ @provider.stubs(:current_pool).returns(Hash.new("currentvalue"))
+ @provider.send((field.to_s + "=").intern, "shouldvalue")
+ end
+ end
+ end
+ end
- describe "when calling create" do
- before do
- @resource.stubs(:[]).with(:pool).returns("mypool")
- @provider.stubs(:zpool)
- end
+ describe "when calling create" do
+ before do
+ @resource.stubs(:[]).with(:pool).returns("mypool")
+ @provider.stubs(:zpool)
+ end
- it "should call build_vdevs" do
- @provider.expects(:build_vdevs).returns([])
- @provider.create
- end
+ it "should call build_vdevs" do
+ @provider.expects(:build_vdevs).returns([])
+ @provider.create
+ end
- it "should call build_named with 'spares' and 'log" do
- @provider.expects(:build_named).with("spare").returns([])
- @provider.expects(:build_named).with("log").returns([])
- @provider.create
- end
+ it "should call build_named with 'spares' and 'log" do
+ @provider.expects(:build_named).with("spare").returns([])
+ @provider.expects(:build_named).with("log").returns([])
+ @provider.create
+ end
- it "should call zpool with arguments from build_vdevs and build_named" do
- @provider.expects(:zpool).with(:create, 'mypool', 'shouldvalue', 'spare', 'shouldvalue', 'log', 'shouldvalue')
- @provider.create
- end
+ it "should call zpool with arguments from build_vdevs and build_named" do
+ @provider.expects(:zpool).with(:create, 'mypool', 'shouldvalue', 'spare', 'shouldvalue', 'log', 'shouldvalue')
+ @provider.create
end
+ end
- describe "when calling delete" do
- it "should call zpool with destroy and the pool name" do
- @resource.stubs(:[]).with(:pool).returns("poolname")
- @provider.expects(:zpool).with(:destroy, "poolname")
- @provider.delete
- end
+ describe "when calling delete" do
+ it "should call zpool with destroy and the pool name" do
+ @resource.stubs(:[]).with(:pool).returns("poolname")
+ @provider.expects(:zpool).with(:destroy, "poolname")
+ @provider.delete
end
+ end
- describe "when calling exists?" do
- before do
- @current_pool = Hash.new(:absent)
- @provider.stubs(:get_pool_data).returns([])
- @provider.stubs(:process_zpool_data).returns(@current_pool)
- end
+ describe "when calling exists?" do
+ before do
+ @current_pool = Hash.new(:absent)
+ @provider.stubs(:get_pool_data).returns([])
+ @provider.stubs(:process_zpool_data).returns(@current_pool)
+ end
- it "should get the current pool" do
- @provider.expects(:process_zpool_data).returns(@current_pool)
- @provider.exists?
- end
+ it "should get the current pool" do
+ @provider.expects(:process_zpool_data).returns(@current_pool)
+ @provider.exists?
+ end
- it "should return false if the current_pool is absent" do
- #the before sets it up
- @provider.exists?.should == false
- end
+ it "should return false if the current_pool is absent" do
+ #the before sets it up
+ @provider.exists?.should == false
+ end
- it "should return true if the current_pool has values" do
- @current_pool[:pool] = "mypool"
- @provider.exists?.should == true
- end
+ it "should return true if the current_pool has values" do
+ @current_pool[:pool] = "mypool"
+ @provider.exists?.should == true
end
+ end
end
diff --git a/spec/unit/provider_spec.rb b/spec/unit/provider_spec.rb
index 9d78154..6294065 100755
--- a/spec/unit/provider_spec.rb
+++ b/spec/unit/provider_spec.rb
@@ -3,29 +3,29 @@
require File.dirname(__FILE__) + '/../spec_helper'
describe Puppet::Provider do
- it "should have a specifity class method" do
- Puppet::Provider.should respond_to(:specificity)
- end
+ it "should have a specifity class method" do
+ Puppet::Provider.should respond_to(:specificity)
+ end
- it "should consider two defaults to be higher specificity than one default" do
- one = Class.new(Puppet::Provider)
- one.initvars
- one.defaultfor :operatingsystem => "solaris"
+ it "should consider two defaults to be higher specificity than one default" do
+ one = Class.new(Puppet::Provider)
+ one.initvars
+ one.defaultfor :operatingsystem => "solaris"
- two = Class.new(Puppet::Provider)
- two.initvars
- two.defaultfor :operatingsystem => "solaris", :operatingsystemrelease => "5.10"
+ two = Class.new(Puppet::Provider)
+ two.initvars
+ two.defaultfor :operatingsystem => "solaris", :operatingsystemrelease => "5.10"
- two.specificity.should > one.specificity
- end
+ two.specificity.should > one.specificity
+ end
- it "should consider a subclass more specific than its parent class" do
- one = Class.new(Puppet::Provider)
- one.initvars
+ it "should consider a subclass more specific than its parent class" do
+ one = Class.new(Puppet::Provider)
+ one.initvars
- two = Class.new(one)
- two.initvars
+ two = Class.new(one)
+ two.initvars
- two.specificity.should > one.specificity
- end
+ two.specificity.should > one.specificity
+ end
end
diff --git a/spec/unit/puppet_spec.rb b/spec/unit/puppet_spec.rb
index 0783429..60ac9e9 100755
--- a/spec/unit/puppet_spec.rb
+++ b/spec/unit/puppet_spec.rb
@@ -4,9 +4,9 @@ require File.dirname(__FILE__) + '/../spec_helper'
require 'puppet'
describe Puppet do
- Puppet::Util::Log.eachlevel do |level|
- it "should have a method for sending '#{level}' logs" do
- Puppet.should respond_to(level)
- end
+ Puppet::Util::Log.eachlevel do |level|
+ it "should have a method for sending '#{level}' logs" do
+ Puppet.should respond_to(level)
end
+ end
end
diff --git a/spec/unit/rails/host_spec.rb b/spec/unit/rails/host_spec.rb
index ac08963..324a673 100755
--- a/spec/unit/rails/host_spec.rb
+++ b/spec/unit/rails/host_spec.rb
@@ -3,161 +3,161 @@
require File.dirname(__FILE__) + '/../../spec_helper'
describe "Puppet::Rails::Host" do
- confine "Cannot test without ActiveRecord" => Puppet.features.rails?
+ confine "Cannot test without ActiveRecord" => Puppet.features.rails?
- def column(name, type)
- ActiveRecord::ConnectionAdapters::Column.new(name, nil, type, false)
- end
+ def column(name, type)
+ ActiveRecord::ConnectionAdapters::Column.new(name, nil, type, false)
+ end
- before do
- require 'puppet/rails/host'
+ before do
+ require 'puppet/rails/host'
- # Stub this so we don't need access to the DB.
- Puppet::Rails::Host.stubs(:columns).returns([column("name", "string"), column("environment", "string"), column("ip", "string")])
+ # Stub this so we don't need access to the DB.
+ Puppet::Rails::Host.stubs(:columns).returns([column("name", "string"), column("environment", "string"), column("ip", "string")])
- @node = Puppet::Node.new("foo")
- @node.environment = "production"
- @node.ipaddress = "127.0.0.1"
+ @node = Puppet::Node.new("foo")
+ @node.environment = "production"
+ @node.ipaddress = "127.0.0.1"
- @host = stub 'host', :environment= => nil, :ip= => nil
- end
+ @host = stub 'host', :environment= => nil, :ip= => nil
+ end
- describe "when converting a Puppet::Node instance into a Rails instance" do
- it "should modify any existing instance in the database" do
- Puppet::Rails::Host.expects(:find_by_name).with("foo").returns @host
+ describe "when converting a Puppet::Node instance into a Rails instance" do
+ it "should modify any existing instance in the database" do
+ Puppet::Rails::Host.expects(:find_by_name).with("foo").returns @host
- Puppet::Rails::Host.from_puppet(@node)
- end
+ Puppet::Rails::Host.from_puppet(@node)
+ end
- it "should create a new instance in the database if none can be found" do
- Puppet::Rails::Host.expects(:find_by_name).with("foo").returns nil
- Puppet::Rails::Host.expects(:new).with(:name => "foo").returns @host
+ it "should create a new instance in the database if none can be found" do
+ Puppet::Rails::Host.expects(:find_by_name).with("foo").returns nil
+ Puppet::Rails::Host.expects(:new).with(:name => "foo").returns @host
- Puppet::Rails::Host.from_puppet(@node)
- end
+ Puppet::Rails::Host.from_puppet(@node)
+ end
- it "should copy the environment from the Puppet instance" do
- Puppet::Rails::Host.expects(:find_by_name).with("foo").returns @host
+ it "should copy the environment from the Puppet instance" do
+ Puppet::Rails::Host.expects(:find_by_name).with("foo").returns @host
- @node.environment = "production"
- @host.expects(:environment=).with {|x| x.name.to_s == 'production' }
+ @node.environment = "production"
+ @host.expects(:environment=).with {|x| x.name.to_s == 'production' }
- Puppet::Rails::Host.from_puppet(@node)
- end
+ Puppet::Rails::Host.from_puppet(@node)
+ end
- it "should copy the ipaddress from the Puppet instance" do
- Puppet::Rails::Host.expects(:find_by_name).with("foo").returns @host
+ it "should copy the ipaddress from the Puppet instance" do
+ Puppet::Rails::Host.expects(:find_by_name).with("foo").returns @host
- @node.ipaddress = "192.168.0.1"
- @host.expects(:ip=).with "192.168.0.1"
+ @node.ipaddress = "192.168.0.1"
+ @host.expects(:ip=).with "192.168.0.1"
- Puppet::Rails::Host.from_puppet(@node)
- end
+ Puppet::Rails::Host.from_puppet(@node)
+ end
- it "should not save the Rails instance" do
- Puppet::Rails::Host.expects(:find_by_name).with("foo").returns @host
+ it "should not save the Rails instance" do
+ Puppet::Rails::Host.expects(:find_by_name).with("foo").returns @host
- @host.expects(:save).never
+ @host.expects(:save).never
- Puppet::Rails::Host.from_puppet(@node)
- end
+ Puppet::Rails::Host.from_puppet(@node)
end
+ end
- describe "when converting a Puppet::Rails::Host instance into a Puppet::Node instance" do
- before do
- @host = Puppet::Rails::Host.new(:name => "foo", :environment => "production", :ip => "127.0.0.1")
- @node = Puppet::Node.new("foo")
- Puppet::Node.stubs(:new).with("foo").returns @node
- end
-
- it "should create a new instance with the correct name" do
- Puppet::Node.expects(:new).with("foo").returns @node
-
- @host.to_puppet
- end
+ describe "when converting a Puppet::Rails::Host instance into a Puppet::Node instance" do
+ before do
+ @host = Puppet::Rails::Host.new(:name => "foo", :environment => "production", :ip => "127.0.0.1")
+ @node = Puppet::Node.new("foo")
+ Puppet::Node.stubs(:new).with("foo").returns @node
+ end
- it "should copy the environment from the Rails instance" do
- @host.environment = "prod"
- @node.expects(:environment=).with "prod"
- @host.to_puppet
- end
+ it "should create a new instance with the correct name" do
+ Puppet::Node.expects(:new).with("foo").returns @node
- it "should copy the ipaddress from the Rails instance" do
- @host.ip = "192.168.0.1"
- @node.expects(:ipaddress=).with "192.168.0.1"
- @host.to_puppet
- end
+ @host.to_puppet
end
- describe "when merging catalog resources and database resources" do
- before :each do
- Puppet.settings.stubs(:[]).with(:thin_storeconfigs).returns(false)
- @resource1 = stub_everything 'res1'
- @resource2 = stub_everything 'res2'
- @resources = [ @resource1, @resource2 ]
-
- @dbresource1 = stub_everything 'dbres1'
- @dbresource2 = stub_everything 'dbres2'
- @dbresources = { 1 => @dbresource1, 2 => @dbresource2 }
+ it "should copy the environment from the Rails instance" do
+ @host.environment = "prod"
+ @node.expects(:environment=).with "prod"
+ @host.to_puppet
+ end
- @host = Puppet::Rails::Host.new(:name => "foo", :environment => "production", :ip => "127.0.0.1")
- @host.stubs(:find_resources).returns(@dbresources)
- @host.stubs(:find_resources_parameters_tags)
- @host.stubs(:compare_to_catalog)
- @host.stubs(:id).returns(1)
- end
+ it "should copy the ipaddress from the Rails instance" do
+ @host.ip = "192.168.0.1"
+ @node.expects(:ipaddress=).with "192.168.0.1"
+ @host.to_puppet
+ end
+ end
+
+ describe "when merging catalog resources and database resources" do
+ before :each do
+ Puppet.settings.stubs(:[]).with(:thin_storeconfigs).returns(false)
+ @resource1 = stub_everything 'res1'
+ @resource2 = stub_everything 'res2'
+ @resources = [ @resource1, @resource2 ]
+
+ @dbresource1 = stub_everything 'dbres1'
+ @dbresource2 = stub_everything 'dbres2'
+ @dbresources = { 1 => @dbresource1, 2 => @dbresource2 }
+
+ @host = Puppet::Rails::Host.new(:name => "foo", :environment => "production", :ip => "127.0.0.1")
+ @host.stubs(:find_resources).returns(@dbresources)
+ @host.stubs(:find_resources_parameters_tags)
+ @host.stubs(:compare_to_catalog)
+ @host.stubs(:id).returns(1)
+ end
- it "should find all database resources" do
- @host.expects(:find_resources)
+ it "should find all database resources" do
+ @host.expects(:find_resources)
- @host.merge_resources(@resources)
- end
+ @host.merge_resources(@resources)
+ end
- it "should find all paramaters and tags for those database resources" do
- @host.expects(:find_resources_parameters_tags).with(@dbresources)
+ it "should find all paramaters and tags for those database resources" do
+ @host.expects(:find_resources_parameters_tags).with(@dbresources)
- @host.merge_resources(@resources)
- end
+ @host.merge_resources(@resources)
+ end
- it "should compare all database resources to catalog" do
- @host.expects(:compare_to_catalog).with(@dbresources, @resources)
+ it "should compare all database resources to catalog" do
+ @host.expects(:compare_to_catalog).with(@dbresources, @resources)
- @host.merge_resources(@resources)
- end
+ @host.merge_resources(@resources)
+ end
- it "should compare only exported resources in thin_storeconfigs mode" do
- Puppet.settings.stubs(:[]).with(:thin_storeconfigs).returns(true)
- @resource1.stubs(:exported?).returns(true)
+ it "should compare only exported resources in thin_storeconfigs mode" do
+ Puppet.settings.stubs(:[]).with(:thin_storeconfigs).returns(true)
+ @resource1.stubs(:exported?).returns(true)
- @host.expects(:compare_to_catalog).with(@dbresources, [ @resource1 ])
+ @host.expects(:compare_to_catalog).with(@dbresources, [ @resource1 ])
- @host.merge_resources(@resources)
- end
+ @host.merge_resources(@resources)
end
+ end
- describe "when searching the database for host resources" do
- before :each do
- Puppet.settings.stubs(:[]).with(:thin_storeconfigs).returns(false)
- @resource1 = stub_everything 'res1', :id => 1
- @resource2 = stub_everything 'res2', :id => 2
- @resources = [ @resource1, @resource2 ]
+ describe "when searching the database for host resources" do
+ before :each do
+ Puppet.settings.stubs(:[]).with(:thin_storeconfigs).returns(false)
+ @resource1 = stub_everything 'res1', :id => 1
+ @resource2 = stub_everything 'res2', :id => 2
+ @resources = [ @resource1, @resource2 ]
- @dbresources = stub 'resources'
- @dbresources.stubs(:find).returns(@resources)
+ @dbresources = stub 'resources'
+ @dbresources.stubs(:find).returns(@resources)
- @host = Puppet::Rails::Host.new(:name => "foo", :environment => "production", :ip => "127.0.0.1")
- @host.stubs(:resources).returns(@dbresources)
- end
+ @host = Puppet::Rails::Host.new(:name => "foo", :environment => "production", :ip => "127.0.0.1")
+ @host.stubs(:resources).returns(@dbresources)
+ end
- it "should return a hash keyed by id of all resources" do
- @host.find_resources.should == { 1 => @resource1, 2 => @resource2 }
- end
+ it "should return a hash keyed by id of all resources" do
+ @host.find_resources.should == { 1 => @resource1, 2 => @resource2 }
+ end
- it "should return a hash keyed by id of only exported resources in thin_storeconfigs mode" do
- Puppet.settings.stubs(:[]).with(:thin_storeconfigs).returns(true)
- @dbresources.expects(:find).with { |*h| h[1][:conditions] == { :exported => true } }.returns([])
+ it "should return a hash keyed by id of only exported resources in thin_storeconfigs mode" do
+ Puppet.settings.stubs(:[]).with(:thin_storeconfigs).returns(true)
+ @dbresources.expects(:find).with { |*h| h[1][:conditions] == { :exported => true } }.returns([])
- @host.find_resources
- end
+ @host.find_resources
end
+ end
end
diff --git a/spec/unit/rails/param_value_spec.rb b/spec/unit/rails/param_value_spec.rb
index 070ac82..d6dc7d5 100755
--- a/spec/unit/rails/param_value_spec.rb
+++ b/spec/unit/rails/param_value_spec.rb
@@ -3,47 +3,47 @@
require File.dirname(__FILE__) + '/../../spec_helper'
describe "Puppet::Rails::ParamValue" do
- confine "Cannot test without ActiveRecord" => Puppet.features.rails?
+ confine "Cannot test without ActiveRecord" => Puppet.features.rails?
- def column(name, type)
- ActiveRecord::ConnectionAdapters::Column.new(name, nil, type, false)
- end
+ def column(name, type)
+ ActiveRecord::ConnectionAdapters::Column.new(name, nil, type, false)
+ end
- before do
- require 'puppet/rails/param_value'
+ before do
+ require 'puppet/rails/param_value'
- name = stub 'param_name', :name => "foo"
+ name = stub 'param_name', :name => "foo"
- # Stub this so we don't need access to the DB.
- Puppet::Rails::ParamValue.stubs(:columns).returns([column("value", "string")])
- Puppet::Rails::ParamName.stubs(:find_or_create_by_name).returns(name)
- end
+ # Stub this so we don't need access to the DB.
+ Puppet::Rails::ParamValue.stubs(:columns).returns([column("value", "string")])
+ Puppet::Rails::ParamName.stubs(:find_or_create_by_name).returns(name)
+ end
- describe "when creating initial parameter values" do
- it "should return an array of hashes" do
- Puppet::Rails::ParamValue.from_parser_param(:myparam, %w{a b})[0].should be_instance_of(Hash)
- end
+ describe "when creating initial parameter values" do
+ it "should return an array of hashes" do
+ Puppet::Rails::ParamValue.from_parser_param(:myparam, %w{a b})[0].should be_instance_of(Hash)
+ end
- it "should return hashes for each value with the parameter name set as the ParamName instance" do
- name = stub 'param_name', :name => "foo"
- Puppet::Rails::ParamName.expects(:find_or_create_by_name).returns(name)
+ it "should return hashes for each value with the parameter name set as the ParamName instance" do
+ name = stub 'param_name', :name => "foo"
+ Puppet::Rails::ParamName.expects(:find_or_create_by_name).returns(name)
- result = Puppet::Rails::ParamValue.from_parser_param(:myparam, "a")[0]
- result[:value].should == "a"
- result[:param_name].should == name
- end
+ result = Puppet::Rails::ParamValue.from_parser_param(:myparam, "a")[0]
+ result[:value].should == "a"
+ result[:param_name].should == name
+ end
- it "should return an array of hashes even when only one parameter is provided" do
- Puppet::Rails::ParamValue.from_parser_param(:myparam, "a")[0].should be_instance_of(Hash)
- end
+ it "should return an array of hashes even when only one parameter is provided" do
+ Puppet::Rails::ParamValue.from_parser_param(:myparam, "a")[0].should be_instance_of(Hash)
+ end
- it "should convert all arguments into strings" do
- Puppet::Rails::ParamValue.from_parser_param(:myparam, 50)[0][:value].should == "50"
- end
+ it "should convert all arguments into strings" do
+ Puppet::Rails::ParamValue.from_parser_param(:myparam, 50)[0][:value].should == "50"
+ end
- it "should not convert Resource References into strings" do
- ref = Puppet::Resource.new(:file, "/file")
- Puppet::Rails::ParamValue.from_parser_param(:myparam, ref)[0][:value].should == ref
- end
+ it "should not convert Resource References into strings" do
+ ref = Puppet::Resource.new(:file, "/file")
+ Puppet::Rails::ParamValue.from_parser_param(:myparam, ref)[0][:value].should == ref
end
+ end
end
diff --git a/spec/unit/rails/resource_spec.rb b/spec/unit/rails/resource_spec.rb
index e9162b9..ac74693 100755
--- a/spec/unit/rails/resource_spec.rb
+++ b/spec/unit/rails/resource_spec.rb
@@ -3,105 +3,105 @@
require File.dirname(__FILE__) + '/../../spec_helper'
describe "Puppet::Rails::Resource" do
- confine "Cannot test without ActiveRecord" => Puppet.features.rails?
+ confine "Cannot test without ActiveRecord" => Puppet.features.rails?
- def column(name, type)
- ActiveRecord::ConnectionAdapters::Column.new(name, nil, type, false)
- end
+ def column(name, type)
+ ActiveRecord::ConnectionAdapters::Column.new(name, nil, type, false)
+ end
- before do
- require 'puppet/rails/resource'
+ before do
+ require 'puppet/rails/resource'
- # Stub this so we don't need access to the DB.
- Puppet::Rails::Resource.stubs(:columns).returns([column("title", "string"), column("restype", "string"), column("exported", "boolean")])
- end
+ # Stub this so we don't need access to the DB.
+ Puppet::Rails::Resource.stubs(:columns).returns([column("title", "string"), column("restype", "string"), column("exported", "boolean")])
+ end
- describe "when creating initial resource arguments" do
- it "should set the restype to the resource's type" do
- Puppet::Rails::Resource.rails_resource_initial_args(Puppet::Resource.new(:file, "/file"))[:restype].should == "File"
- end
+ describe "when creating initial resource arguments" do
+ it "should set the restype to the resource's type" do
+ Puppet::Rails::Resource.rails_resource_initial_args(Puppet::Resource.new(:file, "/file"))[:restype].should == "File"
+ end
- it "should set the title to the resource's title" do
- Puppet::Rails::Resource.rails_resource_initial_args(Puppet::Resource.new(:file, "/file"))[:title].should == "/file"
- end
+ it "should set the title to the resource's title" do
+ Puppet::Rails::Resource.rails_resource_initial_args(Puppet::Resource.new(:file, "/file"))[:title].should == "/file"
+ end
- it "should set the line to the resource's line if one is available" do
- resource = Puppet::Resource.new(:file, "/file")
- resource.line = 50
+ it "should set the line to the resource's line if one is available" do
+ resource = Puppet::Resource.new(:file, "/file")
+ resource.line = 50
- Puppet::Rails::Resource.rails_resource_initial_args(resource)[:line].should == 50
- end
+ Puppet::Rails::Resource.rails_resource_initial_args(resource)[:line].should == 50
+ end
- it "should set 'exported' to true of the resource is exported" do
- resource = Puppet::Resource.new(:file, "/file")
- resource.exported = true
+ it "should set 'exported' to true of the resource is exported" do
+ resource = Puppet::Resource.new(:file, "/file")
+ resource.exported = true
- Puppet::Rails::Resource.rails_resource_initial_args(resource)[:exported].should be_true
- end
+ Puppet::Rails::Resource.rails_resource_initial_args(resource)[:exported].should be_true
+ end
- it "should set 'exported' to false of the resource is not exported" do
- resource = Puppet::Resource.new(:file, "/file")
- resource.exported = false
+ it "should set 'exported' to false of the resource is not exported" do
+ resource = Puppet::Resource.new(:file, "/file")
+ resource.exported = false
- Puppet::Rails::Resource.rails_resource_initial_args(resource)[:exported].should be_false
+ Puppet::Rails::Resource.rails_resource_initial_args(resource)[:exported].should be_false
- resource = Puppet::Resource.new(:file, "/file")
- resource.exported = nil
+ resource = Puppet::Resource.new(:file, "/file")
+ resource.exported = nil
- Puppet::Rails::Resource.rails_resource_initial_args(resource)[:exported].should be_false
- end
+ Puppet::Rails::Resource.rails_resource_initial_args(resource)[:exported].should be_false
end
+ end
- describe "when merging in a parser resource" do
- before do
- @parser = mock 'parser resource'
+ describe "when merging in a parser resource" do
+ before do
+ @parser = mock 'parser resource'
- @resource = Puppet::Rails::Resource.new
- [:merge_attributes, :merge_parameters, :merge_tags, :save].each { |m| @resource.stubs(m) }
- end
+ @resource = Puppet::Rails::Resource.new
+ [:merge_attributes, :merge_parameters, :merge_tags, :save].each { |m| @resource.stubs(m) }
+ end
- it "should merge the attributes" do
- @resource.expects(:merge_attributes).with(@parser)
+ it "should merge the attributes" do
+ @resource.expects(:merge_attributes).with(@parser)
- @resource.merge_parser_resource(@parser)
- end
+ @resource.merge_parser_resource(@parser)
+ end
- it "should merge the parameters" do
- @resource.expects(:merge_parameters).with(@parser)
+ it "should merge the parameters" do
+ @resource.expects(:merge_parameters).with(@parser)
- @resource.merge_parser_resource(@parser)
- end
+ @resource.merge_parser_resource(@parser)
+ end
- it "should merge the tags" do
- @resource.expects(:merge_tags).with(@parser)
+ it "should merge the tags" do
+ @resource.expects(:merge_tags).with(@parser)
- @resource.merge_parser_resource(@parser)
- end
+ @resource.merge_parser_resource(@parser)
+ end
- it "should save itself" do
- @resource.expects(:save)
+ it "should save itself" do
+ @resource.expects(:save)
- @resource.merge_parser_resource(@parser)
- end
+ @resource.merge_parser_resource(@parser)
end
+ end
- describe "merge_parameters" do
- it "should replace values that have changed" do
- @resource = Puppet::Rails::Resource.new
- @resource.params_list = [{"name" => "replace", "value" => 1, "id" => 100 }]
+ describe "merge_parameters" do
+ it "should replace values that have changed" do
+ @resource = Puppet::Rails::Resource.new
+ @resource.params_list = [{"name" => "replace", "value" => 1, "id" => 100 }]
- Puppet::Rails::ParamValue.expects(:delete).with([100])
- param_values = stub "param_values"
- param_values.expects(:build).with({:value=>nil, :param_name=>nil, :line=>{"replace"=>2}})
- @resource.stubs(:param_values).returns(param_values)
+ Puppet::Rails::ParamValue.expects(:delete).with([100])
+ param_values = stub "param_values"
+ param_values.expects(:build).with({:value=>nil, :param_name=>nil, :line=>{"replace"=>2}})
+ @resource.stubs(:param_values).returns(param_values)
- Puppet::Rails::ParamName.stubs(:accumulate_by_name)
+ Puppet::Rails::ParamName.stubs(:accumulate_by_name)
- merge_resource = stub "merge_resource"
- merge_resource.expects(:line).returns({ "replace" => 2 })
- merge_resource.stubs(:each).yields([["replace", 2]])
+ merge_resource = stub "merge_resource"
+ merge_resource.expects(:line).returns({ "replace" => 2 })
+ merge_resource.stubs(:each).yields([["replace", 2]])
- @resource.merge_parameters(merge_resource)
- end
+ @resource.merge_parameters(merge_resource)
end
+ end
end
diff --git a/spec/unit/rails_spec.rb b/spec/unit/rails_spec.rb
index f9c68ca..eaa9680 100755
--- a/spec/unit/rails_spec.rb
+++ b/spec/unit/rails_spec.rb
@@ -4,255 +4,255 @@ require File.dirname(__FILE__) + '/../spec_helper'
require 'puppet/rails'
describe Puppet::Rails, "when initializing any connection" do
- confine "Cannot test without ActiveRecord" => Puppet.features.rails?
+ confine "Cannot test without ActiveRecord" => Puppet.features.rails?
- before do
- Puppet.settings.stubs(:use)
- @logger = mock 'logger'
- @logger.stub_everything
- Logger.stubs(:new).returns(@logger)
+ before do
+ Puppet.settings.stubs(:use)
+ @logger = mock 'logger'
+ @logger.stub_everything
+ Logger.stubs(:new).returns(@logger)
- ActiveRecord::Base.stubs(:logger).returns(@logger)
- ActiveRecord::Base.stubs(:connected?).returns(false)
- end
+ ActiveRecord::Base.stubs(:logger).returns(@logger)
+ ActiveRecord::Base.stubs(:connected?).returns(false)
+ end
- it "should use settings" do
- Puppet.settings.expects(:use).with(:main, :rails, :master)
+ it "should use settings" do
+ Puppet.settings.expects(:use).with(:main, :rails, :master)
- Puppet::Rails.connect
- end
+ Puppet::Rails.connect
+ end
- it "should set up a logger with the appropriate Rails log file" do
- logger = mock 'logger'
- Logger.expects(:new).with(Puppet[:railslog]).returns(logger)
- ActiveRecord::Base.expects(:logger=).with(logger)
+ it "should set up a logger with the appropriate Rails log file" do
+ logger = mock 'logger'
+ Logger.expects(:new).with(Puppet[:railslog]).returns(logger)
+ ActiveRecord::Base.expects(:logger=).with(logger)
- Puppet::Rails.connect
- end
+ Puppet::Rails.connect
+ end
- it "should set the log level to whatever the value is in the settings" do
- Puppet.settings.stubs(:use)
- Puppet.settings.stubs(:value).with(:rails_loglevel).returns("debug")
- Puppet.settings.stubs(:value).with(:railslog).returns("/my/file")
- logger = mock 'logger'
- Logger.stubs(:new).returns(logger)
- ActiveRecord::Base.stubs(:logger).returns(logger)
- logger.expects(:level=).with(Logger::DEBUG)
-
- ActiveRecord::Base.stubs(:allow_concurrency=)
- ActiveRecord::Base.stubs(:verify_active_connections!)
- ActiveRecord::Base.stubs(:establish_connection)
- Puppet::Rails.stubs(:database_arguments).returns({})
-
- Puppet::Rails.connect
- end
+ it "should set the log level to whatever the value is in the settings" do
+ Puppet.settings.stubs(:use)
+ Puppet.settings.stubs(:value).with(:rails_loglevel).returns("debug")
+ Puppet.settings.stubs(:value).with(:railslog).returns("/my/file")
+ logger = mock 'logger'
+ Logger.stubs(:new).returns(logger)
+ ActiveRecord::Base.stubs(:logger).returns(logger)
+ logger.expects(:level=).with(Logger::DEBUG)
- describe "on ActiveRecord 2.1.x" do
- confine("ActiveRecord 2.1.x") { ::ActiveRecord::VERSION::MAJOR == 2 and ::ActiveRecord::VERSION::MINOR <= 1 }
+ ActiveRecord::Base.stubs(:allow_concurrency=)
+ ActiveRecord::Base.stubs(:verify_active_connections!)
+ ActiveRecord::Base.stubs(:establish_connection)
+ Puppet::Rails.stubs(:database_arguments).returns({})
- it "should set ActiveRecord::Base.allow_concurrency" do
- ActiveRecord::Base.expects(:allow_concurrency=).with(true)
+ Puppet::Rails.connect
+ end
- Puppet::Rails.connect
- end
- end
+ describe "on ActiveRecord 2.1.x" do
+ confine("ActiveRecord 2.1.x") { ::ActiveRecord::VERSION::MAJOR == 2 and ::ActiveRecord::VERSION::MINOR <= 1 }
- it "should call ActiveRecord::Base.verify_active_connections!" do
- ActiveRecord::Base.expects(:verify_active_connections!)
+ it "should set ActiveRecord::Base.allow_concurrency" do
+ ActiveRecord::Base.expects(:allow_concurrency=).with(true)
- Puppet::Rails.connect
+ Puppet::Rails.connect
end
+ end
- it "should call ActiveRecord::Base.establish_connection with database_arguments" do
- Puppet::Rails.expects(:database_arguments).returns({})
- ActiveRecord::Base.expects(:establish_connection)
+ it "should call ActiveRecord::Base.verify_active_connections!" do
+ ActiveRecord::Base.expects(:verify_active_connections!)
- Puppet::Rails.connect
- end
+ Puppet::Rails.connect
+ end
+
+ it "should call ActiveRecord::Base.establish_connection with database_arguments" do
+ Puppet::Rails.expects(:database_arguments).returns({})
+ ActiveRecord::Base.expects(:establish_connection)
+
+ Puppet::Rails.connect
+ end
end
describe Puppet::Rails, "when initializing a sqlite3 connection" do
- confine "Cannot test without ActiveRecord" => Puppet.features.rails?
-
- it "should provide the adapter, log_level, and database arguments" do
- Puppet.settings.expects(:value).with(:dbadapter).returns("sqlite3")
- Puppet.settings.expects(:value).with(:rails_loglevel).returns("testlevel")
- Puppet.settings.expects(:value).with(:dblocation).returns("testlocation")
-
- Puppet::Rails.database_arguments.should == {
- :adapter => "sqlite3",
- :log_level => "testlevel",
- :database => "testlocation"
- }
- end
+ confine "Cannot test without ActiveRecord" => Puppet.features.rails?
+
+ it "should provide the adapter, log_level, and database arguments" do
+ Puppet.settings.expects(:value).with(:dbadapter).returns("sqlite3")
+ Puppet.settings.expects(:value).with(:rails_loglevel).returns("testlevel")
+ Puppet.settings.expects(:value).with(:dblocation).returns("testlocation")
+
+ Puppet::Rails.database_arguments.should == {
+ :adapter => "sqlite3",
+ :log_level => "testlevel",
+ :database => "testlocation"
+ }
+ end
end
describe Puppet::Rails, "when initializing a mysql connection" do
- confine "Cannot test without ActiveRecord" => Puppet.features.rails?
-
- it "should provide the adapter, log_level, and host, port, username, password, database, and reconnect arguments" do
- Puppet.settings.stubs(:value).with(:dbadapter).returns("mysql")
- Puppet.settings.stubs(:value).with(:rails_loglevel).returns("testlevel")
- Puppet.settings.stubs(:value).with(:dbserver).returns("testserver")
- Puppet.settings.stubs(:value).with(:dbport).returns("")
- Puppet.settings.stubs(:value).with(:dbuser).returns("testuser")
- Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword")
- Puppet.settings.stubs(:value).with(:dbname).returns("testname")
- Puppet.settings.stubs(:value).with(:dbsocket).returns("")
- Puppet.settings.stubs(:value).with(:dbconnections).returns(1)
-
- Puppet::Rails.database_arguments.should == {
- :adapter => "mysql",
- :log_level => "testlevel",
- :host => "testserver",
- :username => "testuser",
- :password => "testpassword",
- :database => "testname",
- :reconnect => true,
- :pool => 1
- }
- end
-
- it "should provide the adapter, log_level, and host, port, username, password, database, socket, connections, and reconnect arguments" do
- Puppet.settings.stubs(:value).with(:dbadapter).returns("mysql")
- Puppet.settings.stubs(:value).with(:rails_loglevel).returns("testlevel")
- Puppet.settings.stubs(:value).with(:dbserver).returns("testserver")
- Puppet.settings.stubs(:value).with(:dbport).returns("9999")
- Puppet.settings.stubs(:value).with(:dbuser).returns("testuser")
- Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword")
- Puppet.settings.stubs(:value).with(:dbname).returns("testname")
- Puppet.settings.stubs(:value).with(:dbsocket).returns("testsocket")
- Puppet.settings.stubs(:value).with(:dbconnections).returns(1)
-
- Puppet::Rails.database_arguments.should == {
- :adapter => "mysql",
- :log_level => "testlevel",
- :host => "testserver",
- :port => "9999",
- :username => "testuser",
- :password => "testpassword",
- :database => "testname",
- :socket => "testsocket",
- :reconnect => true,
- :pool => 1
- }
- end
-
- it "should provide the adapter, log_level, and host, port, username, password, database, socket, and connections arguments" do
- Puppet.settings.stubs(:value).with(:dbadapter).returns("mysql")
- Puppet.settings.stubs(:value).with(:rails_loglevel).returns("testlevel")
- Puppet.settings.stubs(:value).with(:dbserver).returns("testserver")
- Puppet.settings.stubs(:value).with(:dbport).returns("9999")
- Puppet.settings.stubs(:value).with(:dbuser).returns("testuser")
- Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword")
- Puppet.settings.stubs(:value).with(:dbname).returns("testname")
- Puppet.settings.stubs(:value).with(:dbsocket).returns("testsocket")
- Puppet.settings.stubs(:value).with(:dbconnections).returns(1)
-
- Puppet::Rails.database_arguments.should == {
- :adapter => "mysql",
- :log_level => "testlevel",
- :host => "testserver",
- :port => "9999",
- :username => "testuser",
- :password => "testpassword",
- :database => "testname",
- :socket => "testsocket",
- :reconnect => true,
- :pool => 1
- }
- end
+ confine "Cannot test without ActiveRecord" => Puppet.features.rails?
+
+ it "should provide the adapter, log_level, and host, port, username, password, database, and reconnect arguments" do
+ Puppet.settings.stubs(:value).with(:dbadapter).returns("mysql")
+ Puppet.settings.stubs(:value).with(:rails_loglevel).returns("testlevel")
+ Puppet.settings.stubs(:value).with(:dbserver).returns("testserver")
+ Puppet.settings.stubs(:value).with(:dbport).returns("")
+ Puppet.settings.stubs(:value).with(:dbuser).returns("testuser")
+ Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword")
+ Puppet.settings.stubs(:value).with(:dbname).returns("testname")
+ Puppet.settings.stubs(:value).with(:dbsocket).returns("")
+ Puppet.settings.stubs(:value).with(:dbconnections).returns(1)
+
+ Puppet::Rails.database_arguments.should == {
+ :adapter => "mysql",
+ :log_level => "testlevel",
+ :host => "testserver",
+ :username => "testuser",
+ :password => "testpassword",
+ :database => "testname",
+ :reconnect => true,
+ :pool => 1
+ }
+ end
+
+ it "should provide the adapter, log_level, and host, port, username, password, database, socket, connections, and reconnect arguments" do
+ Puppet.settings.stubs(:value).with(:dbadapter).returns("mysql")
+ Puppet.settings.stubs(:value).with(:rails_loglevel).returns("testlevel")
+ Puppet.settings.stubs(:value).with(:dbserver).returns("testserver")
+ Puppet.settings.stubs(:value).with(:dbport).returns("9999")
+ Puppet.settings.stubs(:value).with(:dbuser).returns("testuser")
+ Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword")
+ Puppet.settings.stubs(:value).with(:dbname).returns("testname")
+ Puppet.settings.stubs(:value).with(:dbsocket).returns("testsocket")
+ Puppet.settings.stubs(:value).with(:dbconnections).returns(1)
+
+ Puppet::Rails.database_arguments.should == {
+ :adapter => "mysql",
+ :log_level => "testlevel",
+ :host => "testserver",
+ :port => "9999",
+ :username => "testuser",
+ :password => "testpassword",
+ :database => "testname",
+ :socket => "testsocket",
+ :reconnect => true,
+ :pool => 1
+ }
+ end
+
+ it "should provide the adapter, log_level, and host, port, username, password, database, socket, and connections arguments" do
+ Puppet.settings.stubs(:value).with(:dbadapter).returns("mysql")
+ Puppet.settings.stubs(:value).with(:rails_loglevel).returns("testlevel")
+ Puppet.settings.stubs(:value).with(:dbserver).returns("testserver")
+ Puppet.settings.stubs(:value).with(:dbport).returns("9999")
+ Puppet.settings.stubs(:value).with(:dbuser).returns("testuser")
+ Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword")
+ Puppet.settings.stubs(:value).with(:dbname).returns("testname")
+ Puppet.settings.stubs(:value).with(:dbsocket).returns("testsocket")
+ Puppet.settings.stubs(:value).with(:dbconnections).returns(1)
+
+ Puppet::Rails.database_arguments.should == {
+ :adapter => "mysql",
+ :log_level => "testlevel",
+ :host => "testserver",
+ :port => "9999",
+ :username => "testuser",
+ :password => "testpassword",
+ :database => "testname",
+ :socket => "testsocket",
+ :reconnect => true,
+ :pool => 1
+ }
+ end
end
describe Puppet::Rails, "when initializing a postgresql connection" do
- confine "Cannot test without ActiveRecord" => Puppet.features.rails?
-
- it "should provide the adapter, log_level, and host, port, username, password, connections, and database arguments" do
- Puppet.settings.stubs(:value).with(:dbadapter).returns("postgresql")
- Puppet.settings.stubs(:value).with(:rails_loglevel).returns("testlevel")
- Puppet.settings.stubs(:value).with(:dbserver).returns("testserver")
- Puppet.settings.stubs(:value).with(:dbport).returns("9999")
- Puppet.settings.stubs(:value).with(:dbuser).returns("testuser")
- Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword")
- Puppet.settings.stubs(:value).with(:dbname).returns("testname")
- Puppet.settings.stubs(:value).with(:dbsocket).returns("")
- Puppet.settings.stubs(:value).with(:dbconnections).returns(1)
-
- Puppet::Rails.database_arguments.should == {
- :adapter => "postgresql",
- :log_level => "testlevel",
- :host => "testserver",
- :port => "9999",
- :username => "testuser",
- :password => "testpassword",
- :database => "testname",
- :reconnect => true,
- :pool => 1
- }
- end
-
- it "should provide the adapter, log_level, and host, port, username, password, database, connections, and socket arguments" do
- Puppet.settings.stubs(:value).with(:dbadapter).returns("postgresql")
- Puppet.settings.stubs(:value).with(:rails_loglevel).returns("testlevel")
- Puppet.settings.stubs(:value).with(:dbserver).returns("testserver")
- Puppet.settings.stubs(:value).with(:dbport).returns("9999")
- Puppet.settings.stubs(:value).with(:dbuser).returns("testuser")
- Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword")
- Puppet.settings.stubs(:value).with(:dbname).returns("testname")
- Puppet.settings.stubs(:value).with(:dbsocket).returns("testsocket")
- Puppet.settings.stubs(:value).with(:dbconnections).returns(1)
-
- Puppet::Rails.database_arguments.should == {
- :adapter => "postgresql",
- :log_level => "testlevel",
- :host => "testserver",
- :port => "9999",
- :username => "testuser",
- :password => "testpassword",
- :database => "testname",
- :socket => "testsocket",
- :pool => 1,
- :reconnect => true
- }
- end
+ confine "Cannot test without ActiveRecord" => Puppet.features.rails?
+
+ it "should provide the adapter, log_level, and host, port, username, password, connections, and database arguments" do
+ Puppet.settings.stubs(:value).with(:dbadapter).returns("postgresql")
+ Puppet.settings.stubs(:value).with(:rails_loglevel).returns("testlevel")
+ Puppet.settings.stubs(:value).with(:dbserver).returns("testserver")
+ Puppet.settings.stubs(:value).with(:dbport).returns("9999")
+ Puppet.settings.stubs(:value).with(:dbuser).returns("testuser")
+ Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword")
+ Puppet.settings.stubs(:value).with(:dbname).returns("testname")
+ Puppet.settings.stubs(:value).with(:dbsocket).returns("")
+ Puppet.settings.stubs(:value).with(:dbconnections).returns(1)
+
+ Puppet::Rails.database_arguments.should == {
+ :adapter => "postgresql",
+ :log_level => "testlevel",
+ :host => "testserver",
+ :port => "9999",
+ :username => "testuser",
+ :password => "testpassword",
+ :database => "testname",
+ :reconnect => true,
+ :pool => 1
+ }
+ end
+
+ it "should provide the adapter, log_level, and host, port, username, password, database, connections, and socket arguments" do
+ Puppet.settings.stubs(:value).with(:dbadapter).returns("postgresql")
+ Puppet.settings.stubs(:value).with(:rails_loglevel).returns("testlevel")
+ Puppet.settings.stubs(:value).with(:dbserver).returns("testserver")
+ Puppet.settings.stubs(:value).with(:dbport).returns("9999")
+ Puppet.settings.stubs(:value).with(:dbuser).returns("testuser")
+ Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword")
+ Puppet.settings.stubs(:value).with(:dbname).returns("testname")
+ Puppet.settings.stubs(:value).with(:dbsocket).returns("testsocket")
+ Puppet.settings.stubs(:value).with(:dbconnections).returns(1)
+
+ Puppet::Rails.database_arguments.should == {
+ :adapter => "postgresql",
+ :log_level => "testlevel",
+ :host => "testserver",
+ :port => "9999",
+ :username => "testuser",
+ :password => "testpassword",
+ :database => "testname",
+ :socket => "testsocket",
+ :pool => 1,
+ :reconnect => true
+ }
+ end
end
describe Puppet::Rails, "when initializing an Oracle connection" do
- confine "Cannot test without ActiveRecord" => Puppet.features.rails?
-
- it "should provide the adapter, log_level, and username, password, dbconnections, and database arguments" do
- Puppet.settings.stubs(:value).with(:dbadapter).returns("oracle_enhanced")
- Puppet.settings.stubs(:value).with(:rails_loglevel).returns("testlevel")
- Puppet.settings.stubs(:value).with(:dbuser).returns("testuser")
- Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword")
- Puppet.settings.stubs(:value).with(:dbname).returns("testname")
- Puppet.settings.stubs(:value).with(:dbconnections).returns(1)
-
- Puppet::Rails.database_arguments.should == {
- :adapter => "oracle_enhanced",
- :log_level => "testlevel",
- :username => "testuser",
- :password => "testpassword",
- :database => "testname",
- :pool => 1
- }
- end
-
- it "should provide the adapter, log_level, and host, username, password, database, pool, and socket arguments" do
- Puppet.settings.stubs(:value).with(:dbadapter).returns("oracle_enhanced")
- Puppet.settings.stubs(:value).with(:rails_loglevel).returns("testlevel")
- Puppet.settings.stubs(:value).with(:dbuser).returns("testuser")
- Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword")
- Puppet.settings.stubs(:value).with(:dbname).returns("testname")
- Puppet.settings.stubs(:value).with(:dbconnections).returns(1)
-
- Puppet::Rails.database_arguments.should == {
- :adapter => "oracle_enhanced",
- :log_level => "testlevel",
- :username => "testuser",
- :password => "testpassword",
- :database => "testname",
- :pool => 1
- }
- end
+ confine "Cannot test without ActiveRecord" => Puppet.features.rails?
+
+ it "should provide the adapter, log_level, and username, password, dbconnections, and database arguments" do
+ Puppet.settings.stubs(:value).with(:dbadapter).returns("oracle_enhanced")
+ Puppet.settings.stubs(:value).with(:rails_loglevel).returns("testlevel")
+ Puppet.settings.stubs(:value).with(:dbuser).returns("testuser")
+ Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword")
+ Puppet.settings.stubs(:value).with(:dbname).returns("testname")
+ Puppet.settings.stubs(:value).with(:dbconnections).returns(1)
+
+ Puppet::Rails.database_arguments.should == {
+ :adapter => "oracle_enhanced",
+ :log_level => "testlevel",
+ :username => "testuser",
+ :password => "testpassword",
+ :database => "testname",
+ :pool => 1
+ }
+ end
+
+ it "should provide the adapter, log_level, and host, username, password, database, pool, and socket arguments" do
+ Puppet.settings.stubs(:value).with(:dbadapter).returns("oracle_enhanced")
+ Puppet.settings.stubs(:value).with(:rails_loglevel).returns("testlevel")
+ Puppet.settings.stubs(:value).with(:dbuser).returns("testuser")
+ Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword")
+ Puppet.settings.stubs(:value).with(:dbname).returns("testname")
+ Puppet.settings.stubs(:value).with(:dbconnections).returns(1)
+
+ Puppet::Rails.database_arguments.should == {
+ :adapter => "oracle_enhanced",
+ :log_level => "testlevel",
+ :username => "testuser",
+ :password => "testpassword",
+ :database => "testname",
+ :pool => 1
+ }
+ end
end
diff --git a/spec/unit/relationship_spec.rb b/spec/unit/relationship_spec.rb
index b98e4e2..4586cd0 100755
--- a/spec/unit/relationship_spec.rb
+++ b/spec/unit/relationship_spec.rb
@@ -7,230 +7,230 @@ require File.dirname(__FILE__) + '/../spec_helper'
require 'puppet/relationship'
describe Puppet::Relationship do
- before do
- @edge = Puppet::Relationship.new(:a, :b)
- end
-
- it "should have a :source attribute" do
- @edge.should respond_to(:source)
- end
-
- it "should have a :target attribute" do
- @edge.should respond_to(:target)
- end
-
- it "should have a :callback attribute" do
- @edge.callback = :foo
- @edge.callback.should == :foo
- end
-
- it "should have an :event attribute" do
- @edge.event = :NONE
- @edge.event.should == :NONE
- end
-
- it "should require a callback if a non-NONE event is specified" do
- proc { @edge.event = :something }.should raise_error(ArgumentError)
- end
-
- it "should have a :label attribute" do
- @edge.should respond_to(:label)
- end
-
- it "should provide a :ref method that describes the edge" do
- @edge = Puppet::Relationship.new("a", "b")
- @edge.ref.should == "a => b"
- end
-
- it "should be able to produce a label as a hash with its event and callback" do
- @edge.callback = :foo
- @edge.event = :bar
-
- @edge.label.should == {:callback => :foo, :event => :bar}
- end
-
- it "should work if nil options are provided" do
- lambda { Puppet::Relationship.new("a", "b", nil) }.should_not raise_error
- end
+ before do
+ @edge = Puppet::Relationship.new(:a, :b)
+ end
+
+ it "should have a :source attribute" do
+ @edge.should respond_to(:source)
+ end
+
+ it "should have a :target attribute" do
+ @edge.should respond_to(:target)
+ end
+
+ it "should have a :callback attribute" do
+ @edge.callback = :foo
+ @edge.callback.should == :foo
+ end
+
+ it "should have an :event attribute" do
+ @edge.event = :NONE
+ @edge.event.should == :NONE
+ end
+
+ it "should require a callback if a non-NONE event is specified" do
+ proc { @edge.event = :something }.should raise_error(ArgumentError)
+ end
+
+ it "should have a :label attribute" do
+ @edge.should respond_to(:label)
+ end
+
+ it "should provide a :ref method that describes the edge" do
+ @edge = Puppet::Relationship.new("a", "b")
+ @edge.ref.should == "a => b"
+ end
+
+ it "should be able to produce a label as a hash with its event and callback" do
+ @edge.callback = :foo
+ @edge.event = :bar
+
+ @edge.label.should == {:callback => :foo, :event => :bar}
+ end
+
+ it "should work if nil options are provided" do
+ lambda { Puppet::Relationship.new("a", "b", nil) }.should_not raise_error
+ end
end
describe Puppet::Relationship, " when initializing" do
- before do
- @edge = Puppet::Relationship.new(:a, :b)
- end
-
- it "should use the first argument as the source" do
- @edge.source.should == :a
- end
-
- it "should use the second argument as the target" do
- @edge.target.should == :b
- end
-
- it "should set the rest of the arguments as the event and callback" do
- @edge = Puppet::Relationship.new(:a, :b, :callback => :foo, :event => :bar)
- @edge.callback.should == :foo
- @edge.event.should == :bar
- end
-
- it "should accept events specified as strings" do
- @edge = Puppet::Relationship.new(:a, :b, "event" => :NONE)
- @edge.event.should == :NONE
- end
-
- it "should accept callbacks specified as strings" do
- @edge = Puppet::Relationship.new(:a, :b, "callback" => :foo)
- @edge.callback.should == :foo
- end
+ before do
+ @edge = Puppet::Relationship.new(:a, :b)
+ end
+
+ it "should use the first argument as the source" do
+ @edge.source.should == :a
+ end
+
+ it "should use the second argument as the target" do
+ @edge.target.should == :b
+ end
+
+ it "should set the rest of the arguments as the event and callback" do
+ @edge = Puppet::Relationship.new(:a, :b, :callback => :foo, :event => :bar)
+ @edge.callback.should == :foo
+ @edge.event.should == :bar
+ end
+
+ it "should accept events specified as strings" do
+ @edge = Puppet::Relationship.new(:a, :b, "event" => :NONE)
+ @edge.event.should == :NONE
+ end
+
+ it "should accept callbacks specified as strings" do
+ @edge = Puppet::Relationship.new(:a, :b, "callback" => :foo)
+ @edge.callback.should == :foo
+ end
end
describe Puppet::Relationship, " when matching edges with no specified event" do
- before do
- @edge = Puppet::Relationship.new(:a, :b)
- end
+ before do
+ @edge = Puppet::Relationship.new(:a, :b)
+ end
- it "should not match :NONE" do
- @edge.should_not be_match(:NONE)
- end
+ it "should not match :NONE" do
+ @edge.should_not be_match(:NONE)
+ end
- it "should not match :ALL_EVENTS" do
- @edge.should_not be_match(:NONE)
- end
+ it "should not match :ALL_EVENTS" do
+ @edge.should_not be_match(:NONE)
+ end
- it "should not match any other events" do
- @edge.should_not be_match(:whatever)
- end
+ it "should not match any other events" do
+ @edge.should_not be_match(:whatever)
+ end
end
describe Puppet::Relationship, " when matching edges with :NONE as the event" do
- before do
- @edge = Puppet::Relationship.new(:a, :b, :event => :NONE)
- end
- it "should not match :NONE" do
- @edge.should_not be_match(:NONE)
- end
-
- it "should not match :ALL_EVENTS" do
- @edge.should_not be_match(:ALL_EVENTS)
- end
-
- it "should not match other events" do
- @edge.should_not be_match(:yayness)
- end
+ before do
+ @edge = Puppet::Relationship.new(:a, :b, :event => :NONE)
+ end
+ it "should not match :NONE" do
+ @edge.should_not be_match(:NONE)
+ end
+
+ it "should not match :ALL_EVENTS" do
+ @edge.should_not be_match(:ALL_EVENTS)
+ end
+
+ it "should not match other events" do
+ @edge.should_not be_match(:yayness)
+ end
end
describe Puppet::Relationship, " when matching edges with :ALL as the event" do
- before do
- @edge = Puppet::Relationship.new(:a, :b, :event => :ALL_EVENTS, :callback => :whatever)
- end
+ before do
+ @edge = Puppet::Relationship.new(:a, :b, :event => :ALL_EVENTS, :callback => :whatever)
+ end
- it "should not match :NONE" do
- @edge.should_not be_match(:NONE)
- end
+ it "should not match :NONE" do
+ @edge.should_not be_match(:NONE)
+ end
- it "should match :ALL_EVENTS" do
- @edge.should be_match(:ALLEVENTS)
- end
+ it "should match :ALL_EVENTS" do
+ @edge.should be_match(:ALLEVENTS)
+ end
- it "should match all other events" do
- @edge.should be_match(:foo)
- end
+ it "should match all other events" do
+ @edge.should be_match(:foo)
+ end
end
describe Puppet::Relationship, " when matching edges with a non-standard event" do
- before do
- @edge = Puppet::Relationship.new(:a, :b, :event => :random, :callback => :whatever)
- end
+ before do
+ @edge = Puppet::Relationship.new(:a, :b, :event => :random, :callback => :whatever)
+ end
- it "should not match :NONE" do
- @edge.should_not be_match(:NONE)
- end
+ it "should not match :NONE" do
+ @edge.should_not be_match(:NONE)
+ end
- it "should not match :ALL_EVENTS" do
- @edge.should_not be_match(:ALL_EVENTS)
- end
+ it "should not match :ALL_EVENTS" do
+ @edge.should_not be_match(:ALL_EVENTS)
+ end
- it "should match events with the same name" do
- @edge.should be_match(:random)
- end
+ it "should match events with the same name" do
+ @edge.should be_match(:random)
+ end
end
describe Puppet::Relationship, "when converting to pson" do
- confine "Missing 'pson' library" => Puppet.features.pson?
-
- before do
- @edge = Puppet::Relationship.new(:a, :b, :event => :random, :callback => :whatever)
- end
-
- it "should store the stringified source as the source in the data" do
- PSON.parse(@edge.to_pson)["source"].should == "a"
- end
-
- it "should store the stringified target as the target in the data" do
- PSON.parse(@edge.to_pson)['target'].should == "b"
- end
-
- it "should store the psonified event as the event in the data" do
- PSON.parse(@edge.to_pson)["event"].should == "random"
- end
-
- it "should not store an event when none is set" do
- @edge.event = nil
- PSON.parse(@edge.to_pson)["event"].should be_nil
- end
-
- it "should store the psonified callback as the callback in the data" do
- @edge.callback = "whatever"
- PSON.parse(@edge.to_pson)["callback"].should == "whatever"
- end
-
- it "should not store a callback when none is set in the edge" do
- @edge.callback = nil
- PSON.parse(@edge.to_pson)["callback"].should be_nil
- end
+ confine "Missing 'pson' library" => Puppet.features.pson?
+
+ before do
+ @edge = Puppet::Relationship.new(:a, :b, :event => :random, :callback => :whatever)
+ end
+
+ it "should store the stringified source as the source in the data" do
+ PSON.parse(@edge.to_pson)["source"].should == "a"
+ end
+
+ it "should store the stringified target as the target in the data" do
+ PSON.parse(@edge.to_pson)['target'].should == "b"
+ end
+
+ it "should store the psonified event as the event in the data" do
+ PSON.parse(@edge.to_pson)["event"].should == "random"
+ end
+
+ it "should not store an event when none is set" do
+ @edge.event = nil
+ PSON.parse(@edge.to_pson)["event"].should be_nil
+ end
+
+ it "should store the psonified callback as the callback in the data" do
+ @edge.callback = "whatever"
+ PSON.parse(@edge.to_pson)["callback"].should == "whatever"
+ end
+
+ it "should not store a callback when none is set in the edge" do
+ @edge.callback = nil
+ PSON.parse(@edge.to_pson)["callback"].should be_nil
+ end
end
describe Puppet::Relationship, "when converting from pson" do
- confine "Missing 'pson' library" => Puppet.features.pson?
-
- before do
- @event = "random"
- @callback = "whatever"
- @data = {
- "source" => "mysource",
- "target" => "mytarget",
- "event" => @event,
- "callback" => @callback
- }
- @pson = {
- "type" => "Puppet::Relationship",
- "data" => @data
- }
- end
-
- def pson_result_should
- Puppet::Relationship.expects(:new).with { |*args| yield args }
- end
-
- it "should be extended with the PSON utility module" do
- Puppet::Relationship.singleton_class.ancestors.should be_include(Puppet::Util::Pson)
- end
-
- # LAK:NOTE For all of these tests, we convert back to the edge so we can
- # trap the actual data structure then.
- it "should pass the source in as the first argument" do
- Puppet::Relationship.from_pson("source" => "mysource", "target" => "mytarget").source.should == "mysource"
- end
-
- it "should pass the target in as the second argument" do
- Puppet::Relationship.from_pson("source" => "mysource", "target" => "mytarget").target.should == "mytarget"
- end
-
- it "should pass the event as an argument if it's provided" do
- Puppet::Relationship.from_pson("source" => "mysource", "target" => "mytarget", "event" => "myevent", "callback" => "eh").event.should == "myevent"
- end
-
- it "should pass the callback as an argument if it's provided" do
- Puppet::Relationship.from_pson("source" => "mysource", "target" => "mytarget", "callback" => "mycallback").callback.should == "mycallback"
- end
+ confine "Missing 'pson' library" => Puppet.features.pson?
+
+ before do
+ @event = "random"
+ @callback = "whatever"
+ @data = {
+ "source" => "mysource",
+ "target" => "mytarget",
+ "event" => @event,
+ "callback" => @callback
+ }
+ @pson = {
+ "type" => "Puppet::Relationship",
+ "data" => @data
+ }
+ end
+
+ def pson_result_should
+ Puppet::Relationship.expects(:new).with { |*args| yield args }
+ end
+
+ it "should be extended with the PSON utility module" do
+ Puppet::Relationship.singleton_class.ancestors.should be_include(Puppet::Util::Pson)
+ end
+
+ # LAK:NOTE For all of these tests, we convert back to the edge so we can
+ # trap the actual data structure then.
+ it "should pass the source in as the first argument" do
+ Puppet::Relationship.from_pson("source" => "mysource", "target" => "mytarget").source.should == "mysource"
+ end
+
+ it "should pass the target in as the second argument" do
+ Puppet::Relationship.from_pson("source" => "mysource", "target" => "mytarget").target.should == "mytarget"
+ end
+
+ it "should pass the event as an argument if it's provided" do
+ Puppet::Relationship.from_pson("source" => "mysource", "target" => "mytarget", "event" => "myevent", "callback" => "eh").event.should == "myevent"
+ end
+
+ it "should pass the callback as an argument if it's provided" do
+ Puppet::Relationship.from_pson("source" => "mysource", "target" => "mytarget", "callback" => "mycallback").callback.should == "mycallback"
+ end
end
diff --git a/spec/unit/reports/http_spec.rb b/spec/unit/reports/http_spec.rb
index cc73464..c814975 100644
--- a/spec/unit/reports/http_spec.rb
+++ b/spec/unit/reports/http_spec.rb
@@ -8,49 +8,49 @@ require 'puppet/reports'
# otherwise difficult to trace method call.
#
class FakeHTTP
- REQUESTS = {}
- def self.request(req)
- REQUESTS[req.path] = req
- end
+ REQUESTS = {}
+ def self.request(req)
+ REQUESTS[req.path] = req
+ end
end
processor = Puppet::Reports.report(:http)
describe processor do
- before { Net::HTTP.any_instance.stubs(:start).yields(FakeHTTP) }
- subject { Puppet::Transaction::Report.new.extend(processor) }
+ before { Net::HTTP.any_instance.stubs(:start).yields(FakeHTTP) }
+ subject { Puppet::Transaction::Report.new.extend(processor) }
+
+ it { should respond_to(:process) }
+
+ it "should use the reporturl setting's host and port" do
+ uri = URI.parse(Puppet[:reporturl])
+ Net::HTTP.expects(:new).with(uri.host, uri.port).returns(stub_everything('http'))
+ subject.process
+ end
- it { should respond_to(:process) }
+ describe "request" do
+ before { subject.process }
+
+ describe "path" do
+ it "should use the path specified by the 'reporturl' setting" do
+ reports_request.path.should == URI.parse(Puppet[:reporturl]).path
+ end
+ end
- it "should use the reporturl setting's host and port" do
- uri = URI.parse(Puppet[:reporturl])
- Net::HTTP.expects(:new).with(uri.host, uri.port).returns(stub_everything('http'))
- subject.process
+ describe "body" do
+ it "should be the report as YAML" do
+ reports_request.body.should == subject.to_yaml
+ end
end
- describe "request" do
- before { subject.process }
-
- describe "path" do
- it "should use the path specified by the 'reporturl' setting" do
- reports_request.path.should == URI.parse(Puppet[:reporturl]).path
- end
- end
-
- describe "body" do
- it "should be the report as YAML" do
- reports_request.body.should == subject.to_yaml
- end
- end
-
- describe "content type" do
- it "should be 'application/x-yaml'" do
- reports_request.content_type.should == "application/x-yaml"
- end
- end
+ describe "content type" do
+ it "should be 'application/x-yaml'" do
+ reports_request.content_type.should == "application/x-yaml"
+ end
end
+ end
- private
+ private
- def reports_request; FakeHTTP::REQUESTS[URI.parse(Puppet[:reporturl]).path] end
+ def reports_request; FakeHTTP::REQUESTS[URI.parse(Puppet[:reporturl]).path] end
end
diff --git a/spec/unit/reports/tagmail_spec.rb b/spec/unit/reports/tagmail_spec.rb
index 87b070b..4349e99 100755
--- a/spec/unit/reports/tagmail_spec.rb
+++ b/spec/unit/reports/tagmail_spec.rb
@@ -8,87 +8,87 @@ require 'puppettest'
tagmail = Puppet::Reports.report(:tagmail)
describe tagmail do
- extend PuppetTest
+ extend PuppetTest
+ before do
+ @processor = Puppet::Transaction::Report.new
+ @processor.extend(Puppet::Reports.report(:tagmail))
+ end
+
+ passers = File.join(datadir, "reports", "tagmail_passers.conf")
+ File.readlines(passers).each do |line|
+ it "should be able to parse '#{line.inspect}'" do
+ @processor.parse(line)
+ end
+ end
+
+ failers = File.join(datadir, "reports", "tagmail_failers.conf")
+ File.readlines(failers).each do |line|
+ it "should not be able to parse '#{line.inspect}'" do
+ lambda { @processor.parse(line) }.should raise_error(ArgumentError)
+ end
+ end
+
+ {
+ "tag: abuse at domain.com" => [%w{abuse at domain.com}, %w{tag}, []],
+ "tag, other: abuse at domain.com" => [%w{abuse at domain.com}, %w{tag other}, []],
+ "tag-other: abuse at domain.com" => [%w{abuse at domain.com}, %w{tag-other}, []],
+ "tag, !other: abuse at domain.com" => [%w{abuse at domain.com}, %w{tag}, %w{other}],
+ "tag, !other, one, !two: abuse at domain.com" => [%w{abuse at domain.com}, %w{tag one}, %w{other two}],
+ "tag: abuse at domain.com, other at domain.com" => [%w{abuse at domain.com other at domain.com}, %w{tag}, []]
+
+ }.each do |line, results|
+ it "should parse '#{line}' as #{results.inspect}" do
+ @processor.parse(line).shift.should == results
+ end
+ end
+
+ describe "when matching logs" do
before do
- @processor = Puppet::Transaction::Report.new
- @processor.extend(Puppet::Reports.report(:tagmail))
+ @processor << Puppet::Util::Log.new(:level => :notice, :message => "first", :tags => %w{one})
+ @processor << Puppet::Util::Log.new(:level => :notice, :message => "second", :tags => %w{one two})
+ @processor << Puppet::Util::Log.new(:level => :notice, :message => "third", :tags => %w{one two three})
+ end
+
+ def match(pos = [], neg = [])
+ pos = Array(pos)
+ neg = Array(neg)
+ result = @processor.match([[%w{abuse at domain.com}, pos, neg]])
+ actual_result = result.shift
+ if actual_result
+ actual_result[1]
+ else
+ nil
+ end
+ end
+
+ it "should match all messages when provided the 'all' tag as a positive matcher" do
+ results = match("all")
+ %w{first second third}.each do |str|
+ results.should be_include(str)
+ end
end
- passers = File.join(datadir, "reports", "tagmail_passers.conf")
- File.readlines(passers).each do |line|
- it "should be able to parse '#{line.inspect}'" do
- @processor.parse(line)
- end
+ it "should remove messages that match a negated tag" do
+ match("all", "three").should_not be_include("third")
end
- failers = File.join(datadir, "reports", "tagmail_failers.conf")
- File.readlines(failers).each do |line|
- it "should not be able to parse '#{line.inspect}'" do
- lambda { @processor.parse(line) }.should raise_error(ArgumentError)
- end
+ it "should find any messages tagged with a provided tag" do
+ results = match("two")
+ results.should be_include("second")
+ results.should be_include("third")
+ results.should_not be_include("first")
end
- {
- "tag: abuse at domain.com" => [%w{abuse at domain.com}, %w{tag}, []],
- "tag, other: abuse at domain.com" => [%w{abuse at domain.com}, %w{tag other}, []],
- "tag-other: abuse at domain.com" => [%w{abuse at domain.com}, %w{tag-other}, []],
- "tag, !other: abuse at domain.com" => [%w{abuse at domain.com}, %w{tag}, %w{other}],
- "tag, !other, one, !two: abuse at domain.com" => [%w{abuse at domain.com}, %w{tag one}, %w{other two}],
- "tag: abuse at domain.com, other at domain.com" => [%w{abuse at domain.com other at domain.com}, %w{tag}, []]
-
- }.each do |line, results|
- it "should parse '#{line}' as #{results.inspect}" do
- @processor.parse(line).shift.should == results
- end
+ it "should allow negation of specific tags from a specific tag list" do
+ results = match("two", "three")
+ results.should be_include("second")
+ results.should_not be_include("third")
end
- describe "when matching logs" do
- before do
- @processor << Puppet::Util::Log.new(:level => :notice, :message => "first", :tags => %w{one})
- @processor << Puppet::Util::Log.new(:level => :notice, :message => "second", :tags => %w{one two})
- @processor << Puppet::Util::Log.new(:level => :notice, :message => "third", :tags => %w{one two three})
- end
-
- def match(pos = [], neg = [])
- pos = Array(pos)
- neg = Array(neg)
- result = @processor.match([[%w{abuse at domain.com}, pos, neg]])
- actual_result = result.shift
- if actual_result
- actual_result[1]
- else
- nil
- end
- end
-
- it "should match all messages when provided the 'all' tag as a positive matcher" do
- results = match("all")
- %w{first second third}.each do |str|
- results.should be_include(str)
- end
- end
-
- it "should remove messages that match a negated tag" do
- match("all", "three").should_not be_include("third")
- end
-
- it "should find any messages tagged with a provided tag" do
- results = match("two")
- results.should be_include("second")
- results.should be_include("third")
- results.should_not be_include("first")
- end
-
- it "should allow negation of specific tags from a specific tag list" do
- results = match("two", "three")
- results.should be_include("second")
- results.should_not be_include("third")
- end
-
- it "should allow a tag to negate all matches" do
- results = match([], "one")
- results.should be_nil
- end
+ it "should allow a tag to negate all matches" do
+ results = match([], "one")
+ results.should be_nil
end
+ end
end
diff --git a/spec/unit/reports_spec.rb b/spec/unit/reports_spec.rb
index f12f0d7..57e77a5 100755
--- a/spec/unit/reports_spec.rb
+++ b/spec/unit/reports_spec.rb
@@ -5,57 +5,57 @@ require File.dirname(__FILE__) + '/../spec_helper'
require 'puppet/reports'
describe Puppet::Reports do
- it "should instance-load report types" do
- Puppet::Reports.instance_loader(:report).should be_instance_of(Puppet::Util::Autoload)
- end
-
- it "should have a method for registering report types" do
- Puppet::Reports.should respond_to(:register_report)
- end
-
- it "should have a method for retrieving report types by name" do
- Puppet::Reports.should respond_to(:report)
- end
-
- it "should provide a method for returning documentation for all reports" do
- Puppet::Reports.expects(:loaded_instances).with(:report).returns([:one, :two])
- one = mock 'one', :doc => "onedoc"
- two = mock 'two', :doc => "twodoc"
- Puppet::Reports.expects(:report).with(:one).returns(one)
- Puppet::Reports.expects(:report).with(:two).returns(two)
-
- doc = Puppet::Reports.reportdocs
- doc.include?("onedoc").should be_true
- doc.include?("twodoc").should be_true
- end
+ it "should instance-load report types" do
+ Puppet::Reports.instance_loader(:report).should be_instance_of(Puppet::Util::Autoload)
+ end
+
+ it "should have a method for registering report types" do
+ Puppet::Reports.should respond_to(:register_report)
+ end
+
+ it "should have a method for retrieving report types by name" do
+ Puppet::Reports.should respond_to(:report)
+ end
+
+ it "should provide a method for returning documentation for all reports" do
+ Puppet::Reports.expects(:loaded_instances).with(:report).returns([:one, :two])
+ one = mock 'one', :doc => "onedoc"
+ two = mock 'two', :doc => "twodoc"
+ Puppet::Reports.expects(:report).with(:one).returns(one)
+ Puppet::Reports.expects(:report).with(:two).returns(two)
+
+ doc = Puppet::Reports.reportdocs
+ doc.include?("onedoc").should be_true
+ doc.include?("twodoc").should be_true
+ end
end
describe Puppet::Reports, " when loading report types" do
- it "should use the instance loader to retrieve report types" do
- Puppet::Reports.expects(:loaded_instance).with(:report, :myreporttype)
- Puppet::Reports.report(:myreporttype)
- end
+ it "should use the instance loader to retrieve report types" do
+ Puppet::Reports.expects(:loaded_instance).with(:report, :myreporttype)
+ Puppet::Reports.report(:myreporttype)
+ end
end
describe Puppet::Reports, " when registering report types" do
- it "should evaluate the supplied block as code for a module" do
- Puppet::Reports.expects(:genmodule).returns(Module.new)
- Puppet::Reports.register_report(:testing) { }
- end
+ it "should evaluate the supplied block as code for a module" do
+ Puppet::Reports.expects(:genmodule).returns(Module.new)
+ Puppet::Reports.register_report(:testing) { }
+ end
- it "should extend the report type with the Puppet::Util::Docs module" do
- mod = stub 'module', :define_method => true
+ it "should extend the report type with the Puppet::Util::Docs module" do
+ mod = stub 'module', :define_method => true
- Puppet::Reports.expects(:genmodule).with { |name, options, block| options[:extend] == Puppet::Util::Docs }.returns(mod)
- Puppet::Reports.register_report(:testing) { }
- end
+ Puppet::Reports.expects(:genmodule).with { |name, options, block| options[:extend] == Puppet::Util::Docs }.returns(mod)
+ Puppet::Reports.register_report(:testing) { }
+ end
- it "should define a :report_name method in the module that returns the name of the report" do
- mod = mock 'module'
- mod.expects(:define_method).with(:report_name)
+ it "should define a :report_name method in the module that returns the name of the report" do
+ mod = mock 'module'
+ mod.expects(:define_method).with(:report_name)
- Puppet::Reports.expects(:genmodule).returns(mod)
- Puppet::Reports.register_report(:testing) { }
- end
+ Puppet::Reports.expects(:genmodule).returns(mod)
+ Puppet::Reports.register_report(:testing) { }
+ end
end
diff --git a/spec/unit/resource/catalog_spec.rb b/spec/unit/resource/catalog_spec.rb
index 8105198..b6f96f0 100755
--- a/spec/unit/resource/catalog_spec.rb
+++ b/spec/unit/resource/catalog_spec.rb
@@ -4,1066 +4,1066 @@ require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::Resource::Catalog, "when compiling" do
+ before do
+ @basepath = Puppet.features.posix? ? "/somepath" : "C:/somepath"
+ # stub this to not try to create state.yaml
+ Puppet::Util::Storage.stubs(:store)
+ end
+
+ it "should be an Expirer" do
+ Puppet::Resource::Catalog.ancestors.should be_include(Puppet::Util::Cacher::Expirer)
+ end
+
+ it "should always be expired if it's not applying" do
+ @catalog = Puppet::Resource::Catalog.new("host")
+ @catalog.expects(:applying?).returns false
+ @catalog.should be_dependent_data_expired(Time.now)
+ end
+
+ it "should not be expired if it's applying and the timestamp is late enough" do
+ @catalog = Puppet::Resource::Catalog.new("host")
+ @catalog.expire
+ @catalog.expects(:applying?).returns true
+ @catalog.should_not be_dependent_data_expired(Time.now)
+ end
+
+ it "should be able to write its list of classes to the class file" do
+ @catalog = Puppet::Resource::Catalog.new("host")
+
+ @catalog.add_class "foo", "bar"
+
+ Puppet.settings.expects(:value).with(:classfile).returns "/class/file"
+
+ fh = mock 'filehandle'
+ File.expects(:open).with("/class/file", "w").yields fh
+
+ fh.expects(:puts).with "foo\nbar"
+
+ @catalog.write_class_file
+ end
+
+ it "should have a client_version attribute" do
+ @catalog = Puppet::Resource::Catalog.new("host")
+ @catalog.client_version = 5
+ @catalog.client_version.should == 5
+ end
+
+ it "should have a server_version attribute" do
+ @catalog = Puppet::Resource::Catalog.new("host")
+ @catalog.server_version = 5
+ @catalog.server_version.should == 5
+ end
+
+ describe "when compiling" do
+ it "should accept tags" do
+ config = Puppet::Resource::Catalog.new("mynode")
+ config.tag("one")
+ config.tags.should == %w{one}
+ end
+
+ it "should accept multiple tags at once" do
+ config = Puppet::Resource::Catalog.new("mynode")
+ config.tag("one", "two")
+ config.tags.should == %w{one two}
+ end
+
+ it "should convert all tags to strings" do
+ config = Puppet::Resource::Catalog.new("mynode")
+ config.tag("one", :two)
+ config.tags.should == %w{one two}
+ end
+
+ it "should tag with both the qualified name and the split name" do
+ config = Puppet::Resource::Catalog.new("mynode")
+ config.tag("one::two")
+ config.tags.include?("one").should be_true
+ config.tags.include?("one::two").should be_true
+ end
+
+ it "should accept classes" do
+ config = Puppet::Resource::Catalog.new("mynode")
+ config.add_class("one")
+ config.classes.should == %w{one}
+ config.add_class("two", "three")
+ config.classes.should == %w{one two three}
+ end
+
+ it "should tag itself with passed class names" do
+ config = Puppet::Resource::Catalog.new("mynode")
+ config.add_class("one")
+ config.tags.should == %w{one}
+ end
+ end
+
+ describe "when extracting transobjects" do
+
+ def mkscope
+ @node = Puppet::Node.new("mynode")
+ @compiler = Puppet::Parser::Compiler.new(@node)
+
+ # XXX This is ridiculous.
+ @compiler.send(:evaluate_main)
+ @scope = @compiler.topscope
+ end
+
+ def mkresource(type, name)
+ Puppet::Parser::Resource.new(type, name, :source => @source, :scope => @scope)
+ end
+
+ it "should fail if no 'main' stage can be found" do
+ lambda { Puppet::Resource::Catalog.new("mynode").extract }.should raise_error(Puppet::DevError)
+ end
+
+ it "should warn if any non-main stages are present" do
+ config = Puppet::Resource::Catalog.new("mynode")
+
+ @scope = mkscope
+ @source = mock 'source'
+
+ main = mkresource("stage", "main")
+ config.add_resource(main)
+
+ other = mkresource("stage", "other")
+ config.add_resource(other)
+
+ Puppet.expects(:warning)
+
+ config.extract
+ end
+
+ it "should always create a TransBucket for the 'main' stage" do
+ config = Puppet::Resource::Catalog.new("mynode")
+
+ @scope = mkscope
+ @source = mock 'source'
+
+ main = mkresource("stage", "main")
+ config.add_resource(main)
+
+ result = config.extract
+ result.type.should == "Stage"
+ result.name.should == "main"
+ end
+
+ # Now try it with a more complicated graph -- a three tier graph, each tier
+ it "should transform arbitrarily deep graphs into isomorphic trees" do
+ config = Puppet::Resource::Catalog.new("mynode")
+
+ @scope = mkscope
+ @scope.stubs(:tags).returns([])
+ @source = mock 'source'
+
+ # Create our scopes.
+ top = mkresource "stage", "main"
+
+ config.add_resource top
+ topbucket = []
+ topbucket.expects(:classes=).with([])
+ top.expects(:to_trans).returns(topbucket)
+ topres = mkresource "file", "/top"
+ topres.expects(:to_trans).returns(:topres)
+ config.add_edge top, topres
+
+ middle = mkresource "class", "middle"
+ middle.expects(:to_trans).returns([])
+ config.add_edge top, middle
+ midres = mkresource "file", "/mid"
+ midres.expects(:to_trans).returns(:midres)
+ config.add_edge middle, midres
+
+ bottom = mkresource "class", "bottom"
+ bottom.expects(:to_trans).returns([])
+ config.add_edge middle, bottom
+ botres = mkresource "file", "/bot"
+ botres.expects(:to_trans).returns(:botres)
+ config.add_edge bottom, botres
+
+ toparray = config.extract
+
+ # This is annoying; it should look like:
+ # [[[:botres], :midres], :topres]
+ # but we can't guarantee sort order.
+ toparray.include?(:topres).should be_true
+
+ midarray = toparray.find { |t| t.is_a?(Array) }
+ midarray.include?(:midres).should be_true
+ botarray = midarray.find { |t| t.is_a?(Array) }
+ botarray.include?(:botres).should be_true
+ end
+ end
+
+ describe " when converting to a Puppet::Resource catalog" do
before do
- @basepath = Puppet.features.posix? ? "/somepath" : "C:/somepath"
- # stub this to not try to create state.yaml
- Puppet::Util::Storage.stubs(:store)
+ @original = Puppet::Resource::Catalog.new("mynode")
+ @original.tag(*%w{one two three})
+ @original.add_class *%w{four five six}
+
+ @top = Puppet::TransObject.new 'top', "class"
+ @topobject = Puppet::TransObject.new '/topobject', "file"
+ @middle = Puppet::TransObject.new 'middle', "class"
+ @middleobject = Puppet::TransObject.new '/middleobject', "file"
+ @bottom = Puppet::TransObject.new 'bottom', "class"
+ @bottomobject = Puppet::TransObject.new '/bottomobject', "file"
+
+ @resources = [@top, @topobject, @middle, @middleobject, @bottom, @bottomobject]
+
+ @original.add_resource(*@resources)
+
+ @original.add_edge(@top, @topobject)
+ @original.add_edge(@top, @middle)
+ @original.add_edge(@middle, @middleobject)
+ @original.add_edge(@middle, @bottom)
+ @original.add_edge(@bottom, @bottomobject)
+
+ @catalog = @original.to_resource
end
- it "should be an Expirer" do
- Puppet::Resource::Catalog.ancestors.should be_include(Puppet::Util::Cacher::Expirer)
+ it "should copy over the version" do
+ @original.version = "foo"
+ @original.to_resource.version.should == "foo"
end
- it "should always be expired if it's not applying" do
- @catalog = Puppet::Resource::Catalog.new("host")
- @catalog.expects(:applying?).returns false
- @catalog.should be_dependent_data_expired(Time.now)
+ it "should convert parser resources to plain resources" do
+ resource = Puppet::Parser::Resource.new(:file, "foo", :scope => stub("scope"), :source => stub("source"))
+ catalog = Puppet::Resource::Catalog.new("whev")
+ catalog.add_resource(resource)
+ new = catalog.to_resource
+ new.resource(:file, "foo").class.should == Puppet::Resource
end
- it "should not be expired if it's applying and the timestamp is late enough" do
- @catalog = Puppet::Resource::Catalog.new("host")
- @catalog.expire
- @catalog.expects(:applying?).returns true
- @catalog.should_not be_dependent_data_expired(Time.now)
+ it "should add all resources as Puppet::Resource instances" do
+ @resources.each { |resource| @catalog.resource(resource.ref).should be_instance_of(Puppet::Resource) }
end
- it "should be able to write its list of classes to the class file" do
- @catalog = Puppet::Resource::Catalog.new("host")
+ it "should copy the tag list to the new catalog" do
+ @catalog.tags.sort.should == @original.tags.sort
+ end
+
+ it "should copy the class list to the new catalog" do
+ @catalog.classes.should == @original.classes
+ end
- @catalog.add_class "foo", "bar"
+ it "should duplicate the original edges" do
+ @original.edges.each do |edge|
+ @catalog.edge?(@catalog.resource(edge.source.ref), @catalog.resource(edge.target.ref)).should be_true
+ end
+ end
- Puppet.settings.expects(:value).with(:classfile).returns "/class/file"
+ it "should set itself as the catalog for each converted resource" do
+ @catalog.vertices.each { |v| v.catalog.object_id.should equal(@catalog.object_id) }
+ end
+ end
+
+ describe "when converting to a RAL catalog" do
+ before do
+ @original = Puppet::Resource::Catalog.new("mynode")
+ @original.tag(*%w{one two three})
+ @original.add_class *%w{four five six}
- fh = mock 'filehandle'
- File.expects(:open).with("/class/file", "w").yields fh
+ @top = Puppet::Resource.new :class, 'top'
+ @topobject = Puppet::Resource.new :file, @basepath+'/topobject'
+ @middle = Puppet::Resource.new :class, 'middle'
+ @middleobject = Puppet::Resource.new :file, @basepath+'/middleobject'
+ @bottom = Puppet::Resource.new :class, 'bottom'
+ @bottomobject = Puppet::Resource.new :file, @basepath+'/bottomobject'
- fh.expects(:puts).with "foo\nbar"
+ @resources = [@top, @topobject, @middle, @middleobject, @bottom, @bottomobject]
- @catalog.write_class_file
+ @original.add_resource(*@resources)
+
+ @original.add_edge(@top, @topobject)
+ @original.add_edge(@top, @middle)
+ @original.add_edge(@middle, @middleobject)
+ @original.add_edge(@middle, @bottom)
+ @original.add_edge(@bottom, @bottomobject)
+
+ @catalog = @original.to_ral
+ end
+
+ it "should add all resources as RAL instances" do
+ @resources.each { |resource| @catalog.resource(resource.ref).should be_instance_of(Puppet::Type) }
end
- it "should have a client_version attribute" do
- @catalog = Puppet::Resource::Catalog.new("host")
- @catalog.client_version = 5
- @catalog.client_version.should == 5
+ it "should copy the tag list to the new catalog" do
+ @catalog.tags.sort.should == @original.tags.sort
end
- it "should have a server_version attribute" do
- @catalog = Puppet::Resource::Catalog.new("host")
- @catalog.server_version = 5
- @catalog.server_version.should == 5
+ it "should copy the class list to the new catalog" do
+ @catalog.classes.should == @original.classes
end
- describe "when compiling" do
- it "should accept tags" do
- config = Puppet::Resource::Catalog.new("mynode")
- config.tag("one")
- config.tags.should == %w{one}
- end
+ it "should duplicate the original edges" do
+ @original.edges.each do |edge|
+ @catalog.edge?(@catalog.resource(edge.source.ref), @catalog.resource(edge.target.ref)).should be_true
+ end
+ end
- it "should accept multiple tags at once" do
- config = Puppet::Resource::Catalog.new("mynode")
- config.tag("one", "two")
- config.tags.should == %w{one two}
- end
+ it "should set itself as the catalog for each converted resource" do
+ @catalog.vertices.each { |v| v.catalog.object_id.should equal(@catalog.object_id) }
+ end
- it "should convert all tags to strings" do
- config = Puppet::Resource::Catalog.new("mynode")
- config.tag("one", :two)
- config.tags.should == %w{one two}
- end
+ # This tests #931.
+ it "should not lose track of resources whose names vary" do
+ changer = Puppet::TransObject.new 'changer', 'test'
- it "should tag with both the qualified name and the split name" do
- config = Puppet::Resource::Catalog.new("mynode")
- config.tag("one::two")
- config.tags.include?("one").should be_true
- config.tags.include?("one::two").should be_true
- end
+ config = Puppet::Resource::Catalog.new('test')
+ config.add_resource(changer)
+ config.add_resource(@top)
- it "should accept classes" do
- config = Puppet::Resource::Catalog.new("mynode")
- config.add_class("one")
- config.classes.should == %w{one}
- config.add_class("two", "three")
- config.classes.should == %w{one two three}
- end
+ config.add_edge(@top, changer)
- it "should tag itself with passed class names" do
- config = Puppet::Resource::Catalog.new("mynode")
- config.add_class("one")
- config.tags.should == %w{one}
- end
+ resource = stub 'resource', :name => "changer2", :title => "changer2", :ref => "Test[changer2]", :catalog= => nil, :remove => nil
+
+ #changer is going to get duplicated as part of a fix for aliases 1094
+ changer.expects(:dup).returns(changer)
+ changer.expects(:to_ral).returns(resource)
+
+ newconfig = nil
+
+ proc { @catalog = config.to_ral }.should_not raise_error
+ @catalog.resource("Test[changer2]").should equal(resource)
end
- describe "when extracting transobjects" do
+ after do
+ # Remove all resource instances.
+ @catalog.clear(true)
+ end
+ end
- def mkscope
- @node = Puppet::Node.new("mynode")
- @compiler = Puppet::Parser::Compiler.new(@node)
+ describe "when filtering" do
+ before :each do
+ @original = Puppet::Resource::Catalog.new("mynode")
+ @original.tag(*%w{one two three})
+ @original.add_class *%w{four five six}
- # XXX This is ridiculous.
- @compiler.send(:evaluate_main)
- @scope = @compiler.topscope
- end
+ @r1 = stub_everything 'r1', :ref => "File[/a]"
+ @r1.stubs(:respond_to?).with(:ref).returns(true)
+ @r1.stubs(:dup).returns(@r1)
+ @r1.stubs(:is_a?).returns(Puppet::Resource).returns(true)
- def mkresource(type, name)
- Puppet::Parser::Resource.new(type, name, :source => @source, :scope => @scope)
- end
+ @r2 = stub_everything 'r2', :ref => "File[/b]"
+ @r2.stubs(:respond_to?).with(:ref).returns(true)
+ @r2.stubs(:dup).returns(@r2)
+ @r2.stubs(:is_a?).returns(Puppet::Resource).returns(true)
- it "should fail if no 'main' stage can be found" do
- lambda { Puppet::Resource::Catalog.new("mynode").extract }.should raise_error(Puppet::DevError)
- end
+ @resources = [@r1, at r2]
- it "should warn if any non-main stages are present" do
- config = Puppet::Resource::Catalog.new("mynode")
+ @original.add_resource(@r1, at r2)
+ end
- @scope = mkscope
- @source = mock 'source'
+ it "should transform the catalog to a resource catalog" do
+ @original.expects(:to_catalog).with { |h,b| h == :to_resource }
- main = mkresource("stage", "main")
- config.add_resource(main)
+ @original.filter
+ end
- other = mkresource("stage", "other")
- config.add_resource(other)
+ it "should scan each catalog resource in turn and apply filtering block" do
+ @resources.each { |r| r.expects(:test?) }
+ @original.filter do |r|
+ r.test?
+ end
+ end
- Puppet.expects(:warning)
+ it "should filter out resources which produce true when the filter block is evaluated" do
+ @original.filter do |r|
+ r == @r1
+ end.resource("File[/a]").should be_nil
+ end
+
+ it "should not consider edges against resources that were filtered out" do
+ @original.add_edge(@r1, at r2)
+ @original.filter do |r|
+ r == @r1
+ end.edge(@r1, at r2).should be_empty
+ end
+ end
- config.extract
- end
+ describe "when functioning as a resource container" do
+ before do
+ @catalog = Puppet::Resource::Catalog.new("host")
+ @one = Puppet::Type.type(:notify).new :name => "one"
+ @two = Puppet::Type.type(:notify).new :name => "two"
+ @dupe = Puppet::Type.type(:notify).new :name => "one"
+ end
- it "should always create a TransBucket for the 'main' stage" do
- config = Puppet::Resource::Catalog.new("mynode")
-
- @scope = mkscope
- @source = mock 'source'
-
- main = mkresource("stage", "main")
- config.add_resource(main)
-
- result = config.extract
- result.type.should == "Stage"
- result.name.should == "main"
- end
-
- # Now try it with a more complicated graph -- a three tier graph, each tier
- it "should transform arbitrarily deep graphs into isomorphic trees" do
- config = Puppet::Resource::Catalog.new("mynode")
-
- @scope = mkscope
- @scope.stubs(:tags).returns([])
- @source = mock 'source'
-
- # Create our scopes.
- top = mkresource "stage", "main"
-
- config.add_resource top
- topbucket = []
- topbucket.expects(:classes=).with([])
- top.expects(:to_trans).returns(topbucket)
- topres = mkresource "file", "/top"
- topres.expects(:to_trans).returns(:topres)
- config.add_edge top, topres
-
- middle = mkresource "class", "middle"
- middle.expects(:to_trans).returns([])
- config.add_edge top, middle
- midres = mkresource "file", "/mid"
- midres.expects(:to_trans).returns(:midres)
- config.add_edge middle, midres
-
- bottom = mkresource "class", "bottom"
- bottom.expects(:to_trans).returns([])
- config.add_edge middle, bottom
- botres = mkresource "file", "/bot"
- botres.expects(:to_trans).returns(:botres)
- config.add_edge bottom, botres
-
- toparray = config.extract
-
- # This is annoying; it should look like:
- # [[[:botres], :midres], :topres]
- # but we can't guarantee sort order.
- toparray.include?(:topres).should be_true
-
- midarray = toparray.find { |t| t.is_a?(Array) }
- midarray.include?(:midres).should be_true
- botarray = midarray.find { |t| t.is_a?(Array) }
- botarray.include?(:botres).should be_true
- end
- end
+ it "should provide a method to add one or more resources" do
+ @catalog.add_resource @one, @two
+ @catalog.resource(@one.ref).should equal(@one)
+ @catalog.resource(@two.ref).should equal(@two)
+ end
- describe " when converting to a Puppet::Resource catalog" do
- before do
- @original = Puppet::Resource::Catalog.new("mynode")
- @original.tag(*%w{one two three})
- @original.add_class *%w{four five six}
-
- @top = Puppet::TransObject.new 'top', "class"
- @topobject = Puppet::TransObject.new '/topobject', "file"
- @middle = Puppet::TransObject.new 'middle', "class"
- @middleobject = Puppet::TransObject.new '/middleobject', "file"
- @bottom = Puppet::TransObject.new 'bottom', "class"
- @bottomobject = Puppet::TransObject.new '/bottomobject', "file"
-
- @resources = [@top, @topobject, @middle, @middleobject, @bottom, @bottomobject]
-
- @original.add_resource(*@resources)
-
- @original.add_edge(@top, @topobject)
- @original.add_edge(@top, @middle)
- @original.add_edge(@middle, @middleobject)
- @original.add_edge(@middle, @bottom)
- @original.add_edge(@bottom, @bottomobject)
-
- @catalog = @original.to_resource
- end
-
- it "should copy over the version" do
- @original.version = "foo"
- @original.to_resource.version.should == "foo"
- end
-
- it "should convert parser resources to plain resources" do
- resource = Puppet::Parser::Resource.new(:file, "foo", :scope => stub("scope"), :source => stub("source"))
- catalog = Puppet::Resource::Catalog.new("whev")
- catalog.add_resource(resource)
- new = catalog.to_resource
- new.resource(:file, "foo").class.should == Puppet::Resource
- end
-
- it "should add all resources as Puppet::Resource instances" do
- @resources.each { |resource| @catalog.resource(resource.ref).should be_instance_of(Puppet::Resource) }
- end
-
- it "should copy the tag list to the new catalog" do
- @catalog.tags.sort.should == @original.tags.sort
- end
-
- it "should copy the class list to the new catalog" do
- @catalog.classes.should == @original.classes
- end
-
- it "should duplicate the original edges" do
- @original.edges.each do |edge|
- @catalog.edge?(@catalog.resource(edge.source.ref), @catalog.resource(edge.target.ref)).should be_true
- end
- end
-
- it "should set itself as the catalog for each converted resource" do
- @catalog.vertices.each { |v| v.catalog.object_id.should equal(@catalog.object_id) }
- end
- end
-
- describe "when converting to a RAL catalog" do
- before do
- @original = Puppet::Resource::Catalog.new("mynode")
- @original.tag(*%w{one two three})
- @original.add_class *%w{four five six}
-
- @top = Puppet::Resource.new :class, 'top'
- @topobject = Puppet::Resource.new :file, @basepath+'/topobject'
- @middle = Puppet::Resource.new :class, 'middle'
- @middleobject = Puppet::Resource.new :file, @basepath+'/middleobject'
- @bottom = Puppet::Resource.new :class, 'bottom'
- @bottomobject = Puppet::Resource.new :file, @basepath+'/bottomobject'
-
- @resources = [@top, @topobject, @middle, @middleobject, @bottom, @bottomobject]
-
- @original.add_resource(*@resources)
-
- @original.add_edge(@top, @topobject)
- @original.add_edge(@top, @middle)
- @original.add_edge(@middle, @middleobject)
- @original.add_edge(@middle, @bottom)
- @original.add_edge(@bottom, @bottomobject)
-
- @catalog = @original.to_ral
- end
-
- it "should add all resources as RAL instances" do
- @resources.each { |resource| @catalog.resource(resource.ref).should be_instance_of(Puppet::Type) }
- end
-
- it "should copy the tag list to the new catalog" do
- @catalog.tags.sort.should == @original.tags.sort
- end
-
- it "should copy the class list to the new catalog" do
- @catalog.classes.should == @original.classes
- end
-
- it "should duplicate the original edges" do
- @original.edges.each do |edge|
- @catalog.edge?(@catalog.resource(edge.source.ref), @catalog.resource(edge.target.ref)).should be_true
- end
- end
-
- it "should set itself as the catalog for each converted resource" do
- @catalog.vertices.each { |v| v.catalog.object_id.should equal(@catalog.object_id) }
- end
-
- # This tests #931.
- it "should not lose track of resources whose names vary" do
- changer = Puppet::TransObject.new 'changer', 'test'
-
- config = Puppet::Resource::Catalog.new('test')
- config.add_resource(changer)
- config.add_resource(@top)
-
- config.add_edge(@top, changer)
-
- resource = stub 'resource', :name => "changer2", :title => "changer2", :ref => "Test[changer2]", :catalog= => nil, :remove => nil
-
- #changer is going to get duplicated as part of a fix for aliases 1094
- changer.expects(:dup).returns(changer)
- changer.expects(:to_ral).returns(resource)
-
- newconfig = nil
-
- proc { @catalog = config.to_ral }.should_not raise_error
- @catalog.resource("Test[changer2]").should equal(resource)
- end
-
- after do
- # Remove all resource instances.
- @catalog.clear(true)
- end
- end
-
- describe "when filtering" do
- before :each do
- @original = Puppet::Resource::Catalog.new("mynode")
- @original.tag(*%w{one two three})
- @original.add_class *%w{four five six}
-
- @r1 = stub_everything 'r1', :ref => "File[/a]"
- @r1.stubs(:respond_to?).with(:ref).returns(true)
- @r1.stubs(:dup).returns(@r1)
- @r1.stubs(:is_a?).returns(Puppet::Resource).returns(true)
-
- @r2 = stub_everything 'r2', :ref => "File[/b]"
- @r2.stubs(:respond_to?).with(:ref).returns(true)
- @r2.stubs(:dup).returns(@r2)
- @r2.stubs(:is_a?).returns(Puppet::Resource).returns(true)
-
- @resources = [@r1, at r2]
-
- @original.add_resource(@r1, at r2)
- end
-
- it "should transform the catalog to a resource catalog" do
- @original.expects(:to_catalog).with { |h,b| h == :to_resource }
-
- @original.filter
- end
-
- it "should scan each catalog resource in turn and apply filtering block" do
- @resources.each { |r| r.expects(:test?) }
- @original.filter do |r|
- r.test?
- end
- end
-
- it "should filter out resources which produce true when the filter block is evaluated" do
- @original.filter do |r|
- r == @r1
- end.resource("File[/a]").should be_nil
- end
-
- it "should not consider edges against resources that were filtered out" do
- @original.add_edge(@r1, at r2)
- @original.filter do |r|
- r == @r1
- end.edge(@r1, at r2).should be_empty
- end
- end
-
- describe "when functioning as a resource container" do
- before do
- @catalog = Puppet::Resource::Catalog.new("host")
- @one = Puppet::Type.type(:notify).new :name => "one"
- @two = Puppet::Type.type(:notify).new :name => "two"
- @dupe = Puppet::Type.type(:notify).new :name => "one"
- end
-
- it "should provide a method to add one or more resources" do
- @catalog.add_resource @one, @two
- @catalog.resource(@one.ref).should equal(@one)
- @catalog.resource(@two.ref).should equal(@two)
- end
-
- it "should add resources to the relationship graph if it exists" do
- relgraph = @catalog.relationship_graph
- @catalog.add_resource @one
- relgraph.should be_vertex(@one)
- end
-
- it "should yield added resources if a block is provided" do
- yielded = []
- @catalog.add_resource(@one, @two) { |r| yielded << r }
- yielded.length.should == 2
- end
-
- it "should set itself as the resource's catalog if it is not a relationship graph" do
- @one.expects(:catalog=).with(@catalog)
- @catalog.add_resource @one
- end
-
- it "should make all vertices available by resource reference" do
- @catalog.add_resource(@one)
- @catalog.resource(@one.ref).should equal(@one)
- @catalog.vertices.find { |r| r.ref == @one.ref }.should equal(@one)
- end
-
- it "should canonize how resources are referred to during retrieval when both type and title are provided" do
- @catalog.add_resource(@one)
-
- @catalog.resource("notify", "one").should equal(@one)
- end
-
- it "should canonize how resources are referred to during retrieval when just the title is provided" do
- @catalog.add_resource(@one)
-
- @catalog.resource("notify[one]", nil).should equal(@one)
- end
-
- it "should not allow two resources with the same resource reference" do
- @catalog.add_resource(@one)
-
- proc { @catalog.add_resource(@dupe) }.should raise_error(Puppet::Resource::Catalog::DuplicateResourceError)
- end
-
- it "should not store objects that do not respond to :ref" do
- proc { @catalog.add_resource("thing") }.should raise_error(ArgumentError)
- end
-
- it "should remove all resources when asked" do
- @catalog.add_resource @one
- @catalog.add_resource @two
- @one.expects :remove
- @two.expects :remove
- @catalog.clear(true)
- end
-
- it "should support a mechanism for finishing resources" do
- @one.expects :finish
- @two.expects :finish
- @catalog.add_resource @one
- @catalog.add_resource @two
-
- @catalog.finalize
- end
-
- it "should make default resources when finalizing" do
- @catalog.expects(:make_default_resources)
- @catalog.finalize
- end
-
- it "should add default resources to the catalog upon creation" do
- @catalog.make_default_resources
- @catalog.resource(:schedule, "daily").should_not be_nil
- end
-
- it "should optionally support an initialization block and should finalize after such blocks" do
- @one.expects :finish
- @two.expects :finish
- config = Puppet::Resource::Catalog.new("host") do |conf|
- conf.add_resource @one
- conf.add_resource @two
- end
- end
-
- it "should inform the resource that it is the resource's catalog" do
- @one.expects(:catalog=).with(@catalog)
- @catalog.add_resource @one
- end
-
- it "should be able to find resources by reference" do
- @catalog.add_resource @one
- @catalog.resource(@one.ref).should equal(@one)
- end
-
- it "should be able to find resources by reference or by type/title tuple" do
- @catalog.add_resource @one
- @catalog.resource("notify", "one").should equal(@one)
- end
-
- it "should have a mechanism for removing resources" do
- @catalog.add_resource @one
- @one.expects :remove
- @catalog.remove_resource(@one)
- @catalog.resource(@one.ref).should be_nil
- @catalog.vertex?(@one).should be_false
- end
-
- it "should have a method for creating aliases for resources" do
- @catalog.add_resource @one
- @catalog.alias(@one, "other")
- @catalog.resource("notify", "other").should equal(@one)
- end
-
- it "should ignore conflicting aliases that point to the aliased resource" do
- @catalog.alias(@one, "other")
- lambda { @catalog.alias(@one, "other") }.should_not raise_error
- end
-
- it "should create aliases for resources isomorphic resources whose names do not match their titles" do
- resource = Puppet::Type::File.new(:title => "testing", :path => @basepath+"/something")
-
- @catalog.add_resource(resource)
-
- @catalog.resource(:file, @basepath+"/something").should equal(resource)
- end
-
- it "should not create aliases for resources non-isomorphic resources whose names do not match their titles" do
- resource = Puppet::Type.type(:exec).new(:title => "testing", :command => "echo", :path => %w{/bin /usr/bin /usr/local/bin})
-
- @catalog.add_resource(resource)
-
- # Yay, I've already got a 'should' method
- @catalog.resource(:exec, "echo").object_id.should == nil.object_id
- end
-
- # This test is the same as the previous, but the behaviour should be explicit.
- it "should alias using the class name from the resource reference, not the resource class name" do
- @catalog.add_resource @one
- @catalog.alias(@one, "other")
- @catalog.resource("notify", "other").should equal(@one)
- end
-
- it "should ignore conflicting aliases that point to the aliased resource" do
- @catalog.alias(@one, "other")
- lambda { @catalog.alias(@one, "other") }.should_not raise_error
- end
-
- it "should fail to add an alias if the aliased name already exists" do
- @catalog.add_resource @one
- proc { @catalog.alias @two, "one" }.should raise_error(ArgumentError)
- end
-
- it "should not fail when a resource has duplicate aliases created" do
- @catalog.add_resource @one
- proc { @catalog.alias @one, "one" }.should_not raise_error
- end
-
- it "should not create aliases that point back to the resource" do
- @catalog.alias(@one, "one")
- @catalog.resource(:notify, "one").should be_nil
- end
-
- it "should be able to look resources up by their aliases" do
- @catalog.add_resource @one
- @catalog.alias @one, "two"
- @catalog.resource(:notify, "two").should equal(@one)
- end
-
- it "should remove resource aliases when the target resource is removed" do
- @catalog.add_resource @one
- @catalog.alias(@one, "other")
- @one.expects :remove
- @catalog.remove_resource(@one)
- @catalog.resource("notify", "other").should be_nil
- end
-
- it "should add an alias for the namevar when the title and name differ on isomorphic resource types" do
- resource = Puppet::Type.type(:file).new :path => @basepath+"/something", :title => "other", :content => "blah"
- resource.expects(:isomorphic?).returns(true)
- @catalog.add_resource(resource)
- @catalog.resource(:file, "other").should equal(resource)
- @catalog.resource(:file, @basepath+"/something").ref.should == resource.ref
- end
-
- it "should not add an alias for the namevar when the title and name differ on non-isomorphic resource types" do
- resource = Puppet::Type.type(:file).new :path => @basepath+"/something", :title => "other", :content => "blah"
- resource.expects(:isomorphic?).returns(false)
- @catalog.add_resource(resource)
- @catalog.resource(:file, resource.title).should equal(resource)
- # We can't use .should here, because the resources respond to that method.
- raise "Aliased non-isomorphic resource" if @catalog.resource(:file, resource.name)
- end
-
- it "should provide a method to create additional resources that also registers the resource" do
- args = {:name => "/yay", :ensure => :file}
- resource = stub 'file', :ref => "File[/yay]", :catalog= => @catalog, :title => "/yay", :[] => "/yay"
- Puppet::Type.type(:file).expects(:new).with(args).returns(resource)
- @catalog.create_resource :file, args
- @catalog.resource("File[/yay]").should equal(resource)
- end
- end
-
- describe "when applying" do
- before :each do
- @catalog = Puppet::Resource::Catalog.new("host")
-
- @transaction = mock 'transaction'
- Puppet::Transaction.stubs(:new).returns(@transaction)
- @transaction.stubs(:evaluate)
- @transaction.stubs(:add_times)
-
- Puppet.settings.stubs(:use)
- end
-
- it "should create and evaluate a transaction" do
- @transaction.expects(:evaluate)
- @catalog.apply
- end
-
- it "should provide the catalog retrieval time to the transaction" do
- @catalog.retrieval_duration = 5
- @transaction.expects(:add_times).with(:config_retrieval => 5)
- @catalog.apply
- end
-
- it "should use a retrieval time of 0 if none is set in the catalog" do
- @catalog.retrieval_duration = nil
- @transaction.expects(:add_times).with(:config_retrieval => 0)
- @catalog.apply
- end
-
- it "should return the transaction" do
- @catalog.apply.should equal(@transaction)
- end
-
- it "should yield the transaction if a block is provided" do
- @catalog.apply do |trans|
- trans.should equal(@transaction)
- end
- end
-
- it "should default to being a host catalog" do
- @catalog.host_config.should be_true
- end
-
- it "should be able to be set to a non-host_config" do
- @catalog.host_config = false
- @catalog.host_config.should be_false
- end
-
- it "should pass supplied tags on to the transaction" do
- @transaction.expects(:tags=).with(%w{one two})
- @catalog.apply(:tags => %w{one two})
- end
-
- it "should set ignoreschedules on the transaction if specified in apply()" do
- @transaction.expects(:ignoreschedules=).with(true)
- @catalog.apply(:ignoreschedules => true)
- end
-
- it "should expire cached data in the resources both before and after the transaction" do
- @catalog.expects(:expire).times(2)
- @catalog.apply
- end
-
- describe "host catalogs" do
-
- # super() doesn't work in the setup method for some reason
- before do
- @catalog.host_config = true
- Puppet::Util::Storage.stubs(:store)
- end
-
- it "should initialize the state database before applying a catalog" do
- Puppet::Util::Storage.expects(:load)
-
- # Short-circuit the apply, so we know we're loading before the transaction
- Puppet::Transaction.expects(:new).raises ArgumentError
- proc { @catalog.apply }.should raise_error(ArgumentError)
- end
-
- it "should sync the state database after applying" do
- Puppet::Util::Storage.expects(:store)
- @transaction.stubs :any_failed? => false
- @catalog.apply
- end
-
- after { Puppet.settings.clear }
- end
-
- describe "non-host catalogs" do
-
- before do
- @catalog.host_config = false
- end
-
- it "should never send reports" do
- Puppet[:report] = true
- Puppet[:summarize] = true
- @catalog.apply
- end
-
- it "should never modify the state database" do
- Puppet::Util::Storage.expects(:load).never
- Puppet::Util::Storage.expects(:store).never
- @catalog.apply
- end
-
- after { Puppet.settings.clear }
- end
- end
-
- describe "when creating a relationship graph" do
- before do
- Puppet::Type.type(:component)
- @catalog = Puppet::Resource::Catalog.new("host")
- @compone = Puppet::Type::Component.new :name => "one"
- @comptwo = Puppet::Type::Component.new :name => "two", :require => "Class[one]"
- @file = Puppet::Type.type(:file)
- @one = @file.new :path => @basepath+"/one"
- @two = @file.new :path => @basepath+"/two"
- @sub = @file.new :path => @basepath+"/two/subdir"
- @catalog.add_edge @compone, @one
- @catalog.add_edge @comptwo, @two
-
- @three = @file.new :path => @basepath+"/three"
- @four = @file.new :path => @basepath+"/four", :require => "File[#{@basepath}/three]"
- @five = @file.new :path => @basepath+"/five"
- @catalog.add_resource @compone, @comptwo, @one, @two, @three, @four, @five, @sub
-
- @relationships = @catalog.relationship_graph
- end
-
- it "should be able to create a relationship graph" do
- @relationships.should be_instance_of(Puppet::SimpleGraph)
- end
-
- it "should not have any components" do
- @relationships.vertices.find { |r| r.instance_of?(Puppet::Type::Component) }.should be_nil
- end
-
- it "should have all non-component resources from the catalog" do
- # The failures print out too much info, so i just do a class comparison
- @relationships.vertex?(@five).should be_true
- end
-
- it "should have all resource relationships set as edges" do
- @relationships.edge?(@three, @four).should be_true
- end
-
- it "should copy component relationships to all contained resources" do
- @relationships.edge?(@one, @two).should be_true
- end
-
- it "should add automatic relationships to the relationship graph" do
- @relationships.edge?(@two, @sub).should be_true
- end
-
- it "should get removed when the catalog is cleaned up" do
- @relationships.expects(:clear)
- @catalog.clear
- @catalog.instance_variable_get("@relationship_graph").should be_nil
- end
-
- it "should write :relationships and :expanded_relationships graph files if the catalog is a host catalog" do
- @catalog.clear
- graph = Puppet::SimpleGraph.new
- Puppet::SimpleGraph.expects(:new).returns graph
-
- graph.expects(:write_graph).with(:relationships)
- graph.expects(:write_graph).with(:expanded_relationships)
-
- @catalog.host_config = true
-
- @catalog.relationship_graph
- end
-
- it "should not write graph files if the catalog is not a host catalog" do
- @catalog.clear
- graph = Puppet::SimpleGraph.new
- Puppet::SimpleGraph.expects(:new).returns graph
-
- graph.expects(:write_graph).never
-
- @catalog.host_config = false
-
- @catalog.relationship_graph
- end
-
- it "should create a new relationship graph after clearing the old one" do
- @relationships.expects(:clear)
- @catalog.clear
- @catalog.relationship_graph.should be_instance_of(Puppet::SimpleGraph)
- end
-
- it "should remove removed resources from the relationship graph if it exists" do
- @catalog.remove_resource(@one)
- @catalog.relationship_graph.vertex?(@one).should be_false
- end
- end
-
- describe "when writing dot files" do
- before do
- @catalog = Puppet::Resource::Catalog.new("host")
- @name = :test
- @file = File.join(Puppet[:graphdir], @name.to_s + ".dot")
- end
+ it "should add resources to the relationship graph if it exists" do
+ relgraph = @catalog.relationship_graph
+ @catalog.add_resource @one
+ relgraph.should be_vertex(@one)
+ end
- it "should only write when it is a host catalog" do
- File.expects(:open).with(@file).never
- @catalog.host_config = false
- Puppet[:graph] = true
- @catalog.write_graph(@name)
- end
-
- after do
- Puppet.settings.clear
- end
+ it "should yield added resources if a block is provided" do
+ yielded = []
+ @catalog.add_resource(@one, @two) { |r| yielded << r }
+ yielded.length.should == 2
end
- describe "when indirecting" do
- before do
- @real_indirection = Puppet::Resource::Catalog.indirection
+ it "should set itself as the resource's catalog if it is not a relationship graph" do
+ @one.expects(:catalog=).with(@catalog)
+ @catalog.add_resource @one
+ end
- @indirection = stub 'indirection', :name => :catalog
+ it "should make all vertices available by resource reference" do
+ @catalog.add_resource(@one)
+ @catalog.resource(@one.ref).should equal(@one)
+ @catalog.vertices.find { |r| r.ref == @one.ref }.should equal(@one)
+ end
- Puppet::Util::Cacher.expire
- end
+ it "should canonize how resources are referred to during retrieval when both type and title are provided" do
+ @catalog.add_resource(@one)
- it "should redirect to the indirection for retrieval" do
- Puppet::Resource::Catalog.stubs(:indirection).returns(@indirection)
- @indirection.expects(:find)
- Puppet::Resource::Catalog.find(:myconfig)
- end
+ @catalog.resource("notify", "one").should equal(@one)
+ end
- it "should use the value of the 'catalog_terminus' setting to determine its terminus class" do
- # Puppet only checks the terminus setting the first time you ask
- # so this returns the object to the clean state
- # at the expense of making this test less pure
- Puppet::Resource::Catalog.indirection.reset_terminus_class
+ it "should canonize how resources are referred to during retrieval when just the title is provided" do
+ @catalog.add_resource(@one)
- Puppet.settings[:catalog_terminus] = "rest"
- Puppet::Resource::Catalog.indirection.terminus_class.should == :rest
- end
+ @catalog.resource("notify[one]", nil).should equal(@one)
+ end
- it "should allow the terminus class to be set manually" do
- Puppet::Resource::Catalog.indirection.terminus_class = :rest
- Puppet::Resource::Catalog.indirection.terminus_class.should == :rest
- end
+ it "should not allow two resources with the same resource reference" do
+ @catalog.add_resource(@one)
- after do
- Puppet::Util::Cacher.expire
- @real_indirection.reset_terminus_class
- end
+ proc { @catalog.add_resource(@dupe) }.should raise_error(Puppet::Resource::Catalog::DuplicateResourceError)
end
- describe "when converting to yaml" do
- before do
- @catalog = Puppet::Resource::Catalog.new("me")
- @catalog.add_edge("one", "two")
- end
+ it "should not store objects that do not respond to :ref" do
+ proc { @catalog.add_resource("thing") }.should raise_error(ArgumentError)
+ end
- it "should be able to be dumped to yaml" do
- YAML.dump(@catalog).should be_instance_of(String)
- end
+ it "should remove all resources when asked" do
+ @catalog.add_resource @one
+ @catalog.add_resource @two
+ @one.expects :remove
+ @two.expects :remove
+ @catalog.clear(true)
end
- describe "when converting from yaml" do
- before do
- @catalog = Puppet::Resource::Catalog.new("me")
- @catalog.add_edge("one", "two")
+ it "should support a mechanism for finishing resources" do
+ @one.expects :finish
+ @two.expects :finish
+ @catalog.add_resource @one
+ @catalog.add_resource @two
- text = YAML.dump(@catalog)
- @newcatalog = YAML.load(text)
- end
+ @catalog.finalize
+ end
- it "should get converted back to a catalog" do
- @newcatalog.should be_instance_of(Puppet::Resource::Catalog)
- end
+ it "should make default resources when finalizing" do
+ @catalog.expects(:make_default_resources)
+ @catalog.finalize
+ end
- it "should have all vertices" do
- @newcatalog.vertex?("one").should be_true
- @newcatalog.vertex?("two").should be_true
- end
+ it "should add default resources to the catalog upon creation" do
+ @catalog.make_default_resources
+ @catalog.resource(:schedule, "daily").should_not be_nil
+ end
- it "should have all edges" do
- @newcatalog.edge?("one", "two").should be_true
- end
+ it "should optionally support an initialization block and should finalize after such blocks" do
+ @one.expects :finish
+ @two.expects :finish
+ config = Puppet::Resource::Catalog.new("host") do |conf|
+ conf.add_resource @one
+ conf.add_resource @two
+ end
end
-end
-describe Puppet::Resource::Catalog, "when converting to pson" do
- confine "Missing 'pson' library" => Puppet.features.pson?
+ it "should inform the resource that it is the resource's catalog" do
+ @one.expects(:catalog=).with(@catalog)
+ @catalog.add_resource @one
+ end
- before do
- @catalog = Puppet::Resource::Catalog.new("myhost")
+ it "should be able to find resources by reference" do
+ @catalog.add_resource @one
+ @catalog.resource(@one.ref).should equal(@one)
end
- def pson_output_should
- @catalog.class.expects(:pson_create).with { |hash| yield hash }.returns(:something)
+ it "should be able to find resources by reference or by type/title tuple" do
+ @catalog.add_resource @one
+ @catalog.resource("notify", "one").should equal(@one)
end
- # LAK:NOTE For all of these tests, we convert back to the resource so we can
- # trap the actual data structure then.
- it "should set its document_type to 'Catalog'" do
- pson_output_should { |hash| hash['document_type'] == "Catalog" }
+ it "should have a mechanism for removing resources" do
+ @catalog.add_resource @one
+ @one.expects :remove
+ @catalog.remove_resource(@one)
+ @catalog.resource(@one.ref).should be_nil
+ @catalog.vertex?(@one).should be_false
+ end
- PSON.parse @catalog.to_pson
+ it "should have a method for creating aliases for resources" do
+ @catalog.add_resource @one
+ @catalog.alias(@one, "other")
+ @catalog.resource("notify", "other").should equal(@one)
end
- it "should set its data as a hash" do
- pson_output_should { |hash| hash['data'].is_a?(Hash) }
- PSON.parse @catalog.to_pson
+ it "should ignore conflicting aliases that point to the aliased resource" do
+ @catalog.alias(@one, "other")
+ lambda { @catalog.alias(@one, "other") }.should_not raise_error
end
- [:name, :version, :tags, :classes].each do |param|
- it "should set its #{param} to the #{param} of the resource" do
- @catalog.send(param.to_s + "=", "testing") unless @catalog.send(param)
+ it "should create aliases for resources isomorphic resources whose names do not match their titles" do
+ resource = Puppet::Type::File.new(:title => "testing", :path => @basepath+"/something")
+
+ @catalog.add_resource(resource)
- pson_output_should { |hash| hash['data'][param.to_s] == @catalog.send(param) }
- PSON.parse @catalog.to_pson
- end
+ @catalog.resource(:file, @basepath+"/something").should equal(resource)
end
- it "should convert its resources to a PSON-encoded array and store it as the 'resources' data" do
- one = stub 'one', :to_pson_data_hash => "one_resource", :ref => "Foo[one]"
- two = stub 'two', :to_pson_data_hash => "two_resource", :ref => "Foo[two]"
+ it "should not create aliases for resources non-isomorphic resources whose names do not match their titles" do
+ resource = Puppet::Type.type(:exec).new(:title => "testing", :command => "echo", :path => %w{/bin /usr/bin /usr/local/bin})
- @catalog.add_resource(one)
- @catalog.add_resource(two)
+ @catalog.add_resource(resource)
- # TODO this should really guarantee sort order
- PSON.parse(@catalog.to_pson,:create_additions => false)['data']['resources'].sort.should == ["one_resource", "two_resource"].sort
+ # Yay, I've already got a 'should' method
+ @catalog.resource(:exec, "echo").object_id.should == nil.object_id
+ end
+ # This test is the same as the previous, but the behaviour should be explicit.
+ it "should alias using the class name from the resource reference, not the resource class name" do
+ @catalog.add_resource @one
+ @catalog.alias(@one, "other")
+ @catalog.resource("notify", "other").should equal(@one)
end
- it "should convert its edges to a PSON-encoded array and store it as the 'edges' data" do
- one = stub 'one', :to_pson_data_hash => "one_resource", :ref => 'Foo[one]'
- two = stub 'two', :to_pson_data_hash => "two_resource", :ref => 'Foo[two]'
- three = stub 'three', :to_pson_data_hash => "three_resource", :ref => 'Foo[three]'
+ it "should ignore conflicting aliases that point to the aliased resource" do
+ @catalog.alias(@one, "other")
+ lambda { @catalog.alias(@one, "other") }.should_not raise_error
+ end
- @catalog.add_edge(one, two)
- @catalog.add_edge(two, three)
+ it "should fail to add an alias if the aliased name already exists" do
+ @catalog.add_resource @one
+ proc { @catalog.alias @two, "one" }.should raise_error(ArgumentError)
+ end
- @catalog.edge(one, two ).expects(:to_pson_data_hash).returns "one_two_pson"
- @catalog.edge(two, three).expects(:to_pson_data_hash).returns "two_three_pson"
+ it "should not fail when a resource has duplicate aliases created" do
+ @catalog.add_resource @one
+ proc { @catalog.alias @one, "one" }.should_not raise_error
+ end
- PSON.parse(@catalog.to_pson,:create_additions => false)['data']['edges'].sort.should == %w{one_two_pson two_three_pson}.sort
+ it "should not create aliases that point back to the resource" do
+ @catalog.alias(@one, "one")
+ @catalog.resource(:notify, "one").should be_nil
end
-end
-describe Puppet::Resource::Catalog, "when converting from pson" do
- confine "Missing 'pson' library" => Puppet.features.pson?
+ it "should be able to look resources up by their aliases" do
+ @catalog.add_resource @one
+ @catalog.alias @one, "two"
+ @catalog.resource(:notify, "two").should equal(@one)
+ end
- def pson_result_should
- Puppet::Resource::Catalog.expects(:new).with { |hash| yield hash }
+ it "should remove resource aliases when the target resource is removed" do
+ @catalog.add_resource @one
+ @catalog.alias(@one, "other")
+ @one.expects :remove
+ @catalog.remove_resource(@one)
+ @catalog.resource("notify", "other").should be_nil
end
- before do
- @data = {
- 'name' => "myhost"
- }
- @pson = {
- 'document_type' => 'Puppet::Resource::Catalog',
- 'data' => @data,
- 'metadata' => {}
- }
+ it "should add an alias for the namevar when the title and name differ on isomorphic resource types" do
+ resource = Puppet::Type.type(:file).new :path => @basepath+"/something", :title => "other", :content => "blah"
+ resource.expects(:isomorphic?).returns(true)
+ @catalog.add_resource(resource)
+ @catalog.resource(:file, "other").should equal(resource)
+ @catalog.resource(:file, @basepath+"/something").ref.should == resource.ref
+ end
+
+ it "should not add an alias for the namevar when the title and name differ on non-isomorphic resource types" do
+ resource = Puppet::Type.type(:file).new :path => @basepath+"/something", :title => "other", :content => "blah"
+ resource.expects(:isomorphic?).returns(false)
+ @catalog.add_resource(resource)
+ @catalog.resource(:file, resource.title).should equal(resource)
+ # We can't use .should here, because the resources respond to that method.
+ raise "Aliased non-isomorphic resource" if @catalog.resource(:file, resource.name)
+ end
+
+ it "should provide a method to create additional resources that also registers the resource" do
+ args = {:name => "/yay", :ensure => :file}
+ resource = stub 'file', :ref => "File[/yay]", :catalog= => @catalog, :title => "/yay", :[] => "/yay"
+ Puppet::Type.type(:file).expects(:new).with(args).returns(resource)
+ @catalog.create_resource :file, args
+ @catalog.resource("File[/yay]").should equal(resource)
+ end
+ end
+
+ describe "when applying" do
+ before :each do
+ @catalog = Puppet::Resource::Catalog.new("host")
+
+ @transaction = mock 'transaction'
+ Puppet::Transaction.stubs(:new).returns(@transaction)
+ @transaction.stubs(:evaluate)
+ @transaction.stubs(:add_times)
+
+ Puppet.settings.stubs(:use)
+ end
+
+ it "should create and evaluate a transaction" do
+ @transaction.expects(:evaluate)
+ @catalog.apply
+ end
+
+ it "should provide the catalog retrieval time to the transaction" do
+ @catalog.retrieval_duration = 5
+ @transaction.expects(:add_times).with(:config_retrieval => 5)
+ @catalog.apply
+ end
+
+ it "should use a retrieval time of 0 if none is set in the catalog" do
+ @catalog.retrieval_duration = nil
+ @transaction.expects(:add_times).with(:config_retrieval => 0)
+ @catalog.apply
+ end
+
+ it "should return the transaction" do
+ @catalog.apply.should equal(@transaction)
+ end
- @catalog = Puppet::Resource::Catalog.new("myhost")
- Puppet::Resource::Catalog.stubs(:new).returns @catalog
+ it "should yield the transaction if a block is provided" do
+ @catalog.apply do |trans|
+ trans.should equal(@transaction)
+ end
end
- it "should be extended with the PSON utility module" do
- Puppet::Resource::Catalog.singleton_class.ancestors.should be_include(Puppet::Util::Pson)
+ it "should default to being a host catalog" do
+ @catalog.host_config.should be_true
end
- it "should create it with the provided name" do
- Puppet::Resource::Catalog.expects(:new).with('myhost').returns @catalog
- PSON.parse @pson.to_pson
+ it "should be able to be set to a non-host_config" do
+ @catalog.host_config = false
+ @catalog.host_config.should be_false
end
- it "should set the provided version on the catalog if one is set" do
- @data['version'] = 50
- PSON.parse @pson.to_pson
- @catalog.version.should == @data['version']
+ it "should pass supplied tags on to the transaction" do
+ @transaction.expects(:tags=).with(%w{one two})
+ @catalog.apply(:tags => %w{one two})
end
- it "should set any provided tags on the catalog" do
- @data['tags'] = %w{one two}
- PSON.parse @pson.to_pson
- @catalog.tags.should == @data['tags']
+ it "should set ignoreschedules on the transaction if specified in apply()" do
+ @transaction.expects(:ignoreschedules=).with(true)
+ @catalog.apply(:ignoreschedules => true)
end
- it "should set any provided classes on the catalog" do
- @data['classes'] = %w{one two}
- PSON.parse @pson.to_pson
- @catalog.classes.should == @data['classes']
+ it "should expire cached data in the resources both before and after the transaction" do
+ @catalog.expects(:expire).times(2)
+ @catalog.apply
end
- it 'should convert the resources list into resources and add each of them' do
- @data['resources'] = [Puppet::Resource.new(:file, "/foo"), Puppet::Resource.new(:file, "/bar")]
+ describe "host catalogs" do
+
+ # super() doesn't work in the setup method for some reason
+ before do
+ @catalog.host_config = true
+ Puppet::Util::Storage.stubs(:store)
+ end
+
+ it "should initialize the state database before applying a catalog" do
+ Puppet::Util::Storage.expects(:load)
- @catalog.expects(:add_resource).times(2).with { |res| res.type == "File" }
- PSON.parse @pson.to_pson
+ # Short-circuit the apply, so we know we're loading before the transaction
+ Puppet::Transaction.expects(:new).raises ArgumentError
+ proc { @catalog.apply }.should raise_error(ArgumentError)
+ end
+
+ it "should sync the state database after applying" do
+ Puppet::Util::Storage.expects(:store)
+ @transaction.stubs :any_failed? => false
+ @catalog.apply
+ end
+
+ after { Puppet.settings.clear }
end
- it 'should convert resources even if they do not include "type" information' do
- @data['resources'] = [Puppet::Resource.new(:file, "/foo")]
+ describe "non-host catalogs" do
+
+ before do
+ @catalog.host_config = false
+ end
- @data['resources'][0].expects(:to_pson).returns '{"title":"/foo","tags":["file"],"type":"File"}'
+ it "should never send reports" do
+ Puppet[:report] = true
+ Puppet[:summarize] = true
+ @catalog.apply
+ end
- @catalog.expects(:add_resource).with { |res| res.type == "File" }
+ it "should never modify the state database" do
+ Puppet::Util::Storage.expects(:load).never
+ Puppet::Util::Storage.expects(:store).never
+ @catalog.apply
+ end
- PSON.parse @pson.to_pson
+ after { Puppet.settings.clear }
end
+ end
- it 'should convert the edges list into edges and add each of them' do
- one = Puppet::Relationship.new("osource", "otarget", :event => "one", :callback => "refresh")
- two = Puppet::Relationship.new("tsource", "ttarget", :event => "two", :callback => "refresh")
+ describe "when creating a relationship graph" do
+ before do
+ Puppet::Type.type(:component)
+ @catalog = Puppet::Resource::Catalog.new("host")
+ @compone = Puppet::Type::Component.new :name => "one"
+ @comptwo = Puppet::Type::Component.new :name => "two", :require => "Class[one]"
+ @file = Puppet::Type.type(:file)
+ @one = @file.new :path => @basepath+"/one"
+ @two = @file.new :path => @basepath+"/two"
+ @sub = @file.new :path => @basepath+"/two/subdir"
+ @catalog.add_edge @compone, @one
+ @catalog.add_edge @comptwo, @two
+
+ @three = @file.new :path => @basepath+"/three"
+ @four = @file.new :path => @basepath+"/four", :require => "File[#{@basepath}/three]"
+ @five = @file.new :path => @basepath+"/five"
+ @catalog.add_resource @compone, @comptwo, @one, @two, @three, @four, @five, @sub
+
+ @relationships = @catalog.relationship_graph
+ end
- @data['edges'] = [one, two]
+ it "should be able to create a relationship graph" do
+ @relationships.should be_instance_of(Puppet::SimpleGraph)
+ end
- @catalog.stubs(:resource).returns("eh")
+ it "should not have any components" do
+ @relationships.vertices.find { |r| r.instance_of?(Puppet::Type::Component) }.should be_nil
+ end
- @catalog.expects(:add_edge).with { |edge| edge.event == "one" }
- @catalog.expects(:add_edge).with { |edge| edge.event == "two" }
+ it "should have all non-component resources from the catalog" do
+ # The failures print out too much info, so i just do a class comparison
+ @relationships.vertex?(@five).should be_true
+ end
- PSON.parse @pson.to_pson
+ it "should have all resource relationships set as edges" do
+ @relationships.edge?(@three, @four).should be_true
end
- it "should be able to convert relationships that do not include 'type' information" do
- one = Puppet::Relationship.new("osource", "otarget", :event => "one", :callback => "refresh")
- one.expects(:to_pson).returns "{\"event\":\"one\",\"callback\":\"refresh\",\"source\":\"osource\",\"target\":\"otarget\"}"
+ it "should copy component relationships to all contained resources" do
+ @relationships.edge?(@one, @two).should be_true
+ end
- @data['edges'] = [one]
+ it "should add automatic relationships to the relationship graph" do
+ @relationships.edge?(@two, @sub).should be_true
+ end
- @catalog.stubs(:resource).returns("eh")
+ it "should get removed when the catalog is cleaned up" do
+ @relationships.expects(:clear)
+ @catalog.clear
+ @catalog.instance_variable_get("@relationship_graph").should be_nil
+ end
+
+ it "should write :relationships and :expanded_relationships graph files if the catalog is a host catalog" do
+ @catalog.clear
+ graph = Puppet::SimpleGraph.new
+ Puppet::SimpleGraph.expects(:new).returns graph
- @catalog.expects(:add_edge).with { |edge| edge.event == "one" }
+ graph.expects(:write_graph).with(:relationships)
+ graph.expects(:write_graph).with(:expanded_relationships)
- PSON.parse @pson.to_pson
+ @catalog.host_config = true
+
+ @catalog.relationship_graph
end
- it "should set the source and target for each edge to the actual resource" do
- edge = Puppet::Relationship.new("source", "target")
+ it "should not write graph files if the catalog is not a host catalog" do
+ @catalog.clear
+ graph = Puppet::SimpleGraph.new
+ Puppet::SimpleGraph.expects(:new).returns graph
- @data['edges'] = [edge]
+ graph.expects(:write_graph).never
- @catalog.expects(:resource).with("source").returns("source_resource")
- @catalog.expects(:resource).with("target").returns("target_resource")
+ @catalog.host_config = false
- @catalog.expects(:add_edge).with { |edge| edge.source == "source_resource" and edge.target == "target_resource" }
+ @catalog.relationship_graph
+ end
- PSON.parse @pson.to_pson
+ it "should create a new relationship graph after clearing the old one" do
+ @relationships.expects(:clear)
+ @catalog.clear
+ @catalog.relationship_graph.should be_instance_of(Puppet::SimpleGraph)
end
- it "should fail if the source resource cannot be found" do
- edge = Puppet::Relationship.new("source", "target")
+ it "should remove removed resources from the relationship graph if it exists" do
+ @catalog.remove_resource(@one)
+ @catalog.relationship_graph.vertex?(@one).should be_false
+ end
+ end
- @data['edges'] = [edge]
+ describe "when writing dot files" do
+ before do
+ @catalog = Puppet::Resource::Catalog.new("host")
+ @name = :test
+ @file = File.join(Puppet[:graphdir], @name.to_s + ".dot")
+ end
- @catalog.expects(:resource).with("source").returns(nil)
- @catalog.stubs(:resource).with("target").returns("target_resource")
+ it "should only write when it is a host catalog" do
+ File.expects(:open).with(@file).never
+ @catalog.host_config = false
+ Puppet[:graph] = true
+ @catalog.write_graph(@name)
+ end
- lambda { PSON.parse @pson.to_pson }.should raise_error(ArgumentError)
+ after do
+ Puppet.settings.clear
end
+ end
+
+ describe "when indirecting" do
+ before do
+ @real_indirection = Puppet::Resource::Catalog.indirection
- it "should fail if the target resource cannot be found" do
- edge = Puppet::Relationship.new("source", "target")
+ @indirection = stub 'indirection', :name => :catalog
- @data['edges'] = [edge]
+ Puppet::Util::Cacher.expire
+ end
+
+ it "should redirect to the indirection for retrieval" do
+ Puppet::Resource::Catalog.stubs(:indirection).returns(@indirection)
+ @indirection.expects(:find)
+ Puppet::Resource::Catalog.find(:myconfig)
+ end
- @catalog.stubs(:resource).with("source").returns("source_resource")
- @catalog.expects(:resource).with("target").returns(nil)
+ it "should use the value of the 'catalog_terminus' setting to determine its terminus class" do
+ # Puppet only checks the terminus setting the first time you ask
+ # so this returns the object to the clean state
+ # at the expense of making this test less pure
+ Puppet::Resource::Catalog.indirection.reset_terminus_class
- lambda { PSON.parse @pson.to_pson }.should raise_error(ArgumentError)
+ Puppet.settings[:catalog_terminus] = "rest"
+ Puppet::Resource::Catalog.indirection.terminus_class.should == :rest
end
+
+ it "should allow the terminus class to be set manually" do
+ Puppet::Resource::Catalog.indirection.terminus_class = :rest
+ Puppet::Resource::Catalog.indirection.terminus_class.should == :rest
+ end
+
+ after do
+ Puppet::Util::Cacher.expire
+ @real_indirection.reset_terminus_class
+ end
+ end
+
+ describe "when converting to yaml" do
+ before do
+ @catalog = Puppet::Resource::Catalog.new("me")
+ @catalog.add_edge("one", "two")
+ end
+
+ it "should be able to be dumped to yaml" do
+ YAML.dump(@catalog).should be_instance_of(String)
+ end
+ end
+
+ describe "when converting from yaml" do
+ before do
+ @catalog = Puppet::Resource::Catalog.new("me")
+ @catalog.add_edge("one", "two")
+
+ text = YAML.dump(@catalog)
+ @newcatalog = YAML.load(text)
+ end
+
+ it "should get converted back to a catalog" do
+ @newcatalog.should be_instance_of(Puppet::Resource::Catalog)
+ end
+
+ it "should have all vertices" do
+ @newcatalog.vertex?("one").should be_true
+ @newcatalog.vertex?("two").should be_true
+ end
+
+ it "should have all edges" do
+ @newcatalog.edge?("one", "two").should be_true
+ end
+ end
+end
+
+describe Puppet::Resource::Catalog, "when converting to pson" do
+ confine "Missing 'pson' library" => Puppet.features.pson?
+
+ before do
+ @catalog = Puppet::Resource::Catalog.new("myhost")
+ end
+
+ def pson_output_should
+ @catalog.class.expects(:pson_create).with { |hash| yield hash }.returns(:something)
+ end
+
+ # LAK:NOTE For all of these tests, we convert back to the resource so we can
+ # trap the actual data structure then.
+ it "should set its document_type to 'Catalog'" do
+ pson_output_should { |hash| hash['document_type'] == "Catalog" }
+
+ PSON.parse @catalog.to_pson
+ end
+
+ it "should set its data as a hash" do
+ pson_output_should { |hash| hash['data'].is_a?(Hash) }
+ PSON.parse @catalog.to_pson
+ end
+
+ [:name, :version, :tags, :classes].each do |param|
+ it "should set its #{param} to the #{param} of the resource" do
+ @catalog.send(param.to_s + "=", "testing") unless @catalog.send(param)
+
+ pson_output_should { |hash| hash['data'][param.to_s] == @catalog.send(param) }
+ PSON.parse @catalog.to_pson
+ end
+ end
+
+ it "should convert its resources to a PSON-encoded array and store it as the 'resources' data" do
+ one = stub 'one', :to_pson_data_hash => "one_resource", :ref => "Foo[one]"
+ two = stub 'two', :to_pson_data_hash => "two_resource", :ref => "Foo[two]"
+
+ @catalog.add_resource(one)
+ @catalog.add_resource(two)
+
+ # TODO this should really guarantee sort order
+ PSON.parse(@catalog.to_pson,:create_additions => false)['data']['resources'].sort.should == ["one_resource", "two_resource"].sort
+
+ end
+
+ it "should convert its edges to a PSON-encoded array and store it as the 'edges' data" do
+ one = stub 'one', :to_pson_data_hash => "one_resource", :ref => 'Foo[one]'
+ two = stub 'two', :to_pson_data_hash => "two_resource", :ref => 'Foo[two]'
+ three = stub 'three', :to_pson_data_hash => "three_resource", :ref => 'Foo[three]'
+
+ @catalog.add_edge(one, two)
+ @catalog.add_edge(two, three)
+
+ @catalog.edge(one, two ).expects(:to_pson_data_hash).returns "one_two_pson"
+ @catalog.edge(two, three).expects(:to_pson_data_hash).returns "two_three_pson"
+
+ PSON.parse(@catalog.to_pson,:create_additions => false)['data']['edges'].sort.should == %w{one_two_pson two_three_pson}.sort
+ end
+end
+
+describe Puppet::Resource::Catalog, "when converting from pson" do
+ confine "Missing 'pson' library" => Puppet.features.pson?
+
+ def pson_result_should
+ Puppet::Resource::Catalog.expects(:new).with { |hash| yield hash }
+ end
+
+ before do
+ @data = {
+ 'name' => "myhost"
+ }
+ @pson = {
+ 'document_type' => 'Puppet::Resource::Catalog',
+ 'data' => @data,
+ 'metadata' => {}
+ }
+
+ @catalog = Puppet::Resource::Catalog.new("myhost")
+ Puppet::Resource::Catalog.stubs(:new).returns @catalog
+ end
+
+ it "should be extended with the PSON utility module" do
+ Puppet::Resource::Catalog.singleton_class.ancestors.should be_include(Puppet::Util::Pson)
+ end
+
+ it "should create it with the provided name" do
+ Puppet::Resource::Catalog.expects(:new).with('myhost').returns @catalog
+ PSON.parse @pson.to_pson
+ end
+
+ it "should set the provided version on the catalog if one is set" do
+ @data['version'] = 50
+ PSON.parse @pson.to_pson
+ @catalog.version.should == @data['version']
+ end
+
+ it "should set any provided tags on the catalog" do
+ @data['tags'] = %w{one two}
+ PSON.parse @pson.to_pson
+ @catalog.tags.should == @data['tags']
+ end
+
+ it "should set any provided classes on the catalog" do
+ @data['classes'] = %w{one two}
+ PSON.parse @pson.to_pson
+ @catalog.classes.should == @data['classes']
+ end
+
+ it 'should convert the resources list into resources and add each of them' do
+ @data['resources'] = [Puppet::Resource.new(:file, "/foo"), Puppet::Resource.new(:file, "/bar")]
+
+ @catalog.expects(:add_resource).times(2).with { |res| res.type == "File" }
+ PSON.parse @pson.to_pson
+ end
+
+ it 'should convert resources even if they do not include "type" information' do
+ @data['resources'] = [Puppet::Resource.new(:file, "/foo")]
+
+ @data['resources'][0].expects(:to_pson).returns '{"title":"/foo","tags":["file"],"type":"File"}'
+
+ @catalog.expects(:add_resource).with { |res| res.type == "File" }
+
+ PSON.parse @pson.to_pson
+ end
+
+ it 'should convert the edges list into edges and add each of them' do
+ one = Puppet::Relationship.new("osource", "otarget", :event => "one", :callback => "refresh")
+ two = Puppet::Relationship.new("tsource", "ttarget", :event => "two", :callback => "refresh")
+
+ @data['edges'] = [one, two]
+
+ @catalog.stubs(:resource).returns("eh")
+
+ @catalog.expects(:add_edge).with { |edge| edge.event == "one" }
+ @catalog.expects(:add_edge).with { |edge| edge.event == "two" }
+
+ PSON.parse @pson.to_pson
+ end
+
+ it "should be able to convert relationships that do not include 'type' information" do
+ one = Puppet::Relationship.new("osource", "otarget", :event => "one", :callback => "refresh")
+ one.expects(:to_pson).returns "{\"event\":\"one\",\"callback\":\"refresh\",\"source\":\"osource\",\"target\":\"otarget\"}"
+
+ @data['edges'] = [one]
+
+ @catalog.stubs(:resource).returns("eh")
+
+ @catalog.expects(:add_edge).with { |edge| edge.event == "one" }
+
+ PSON.parse @pson.to_pson
+ end
+
+ it "should set the source and target for each edge to the actual resource" do
+ edge = Puppet::Relationship.new("source", "target")
+
+ @data['edges'] = [edge]
+
+ @catalog.expects(:resource).with("source").returns("source_resource")
+ @catalog.expects(:resource).with("target").returns("target_resource")
+
+ @catalog.expects(:add_edge).with { |edge| edge.source == "source_resource" and edge.target == "target_resource" }
+
+ PSON.parse @pson.to_pson
+ end
+
+ it "should fail if the source resource cannot be found" do
+ edge = Puppet::Relationship.new("source", "target")
+
+ @data['edges'] = [edge]
+
+ @catalog.expects(:resource).with("source").returns(nil)
+ @catalog.stubs(:resource).with("target").returns("target_resource")
+
+ lambda { PSON.parse @pson.to_pson }.should raise_error(ArgumentError)
+ end
+
+ it "should fail if the target resource cannot be found" do
+ edge = Puppet::Relationship.new("source", "target")
+
+ @data['edges'] = [edge]
+
+ @catalog.stubs(:resource).with("source").returns("source_resource")
+ @catalog.expects(:resource).with("target").returns(nil)
+
+ lambda { PSON.parse @pson.to_pson }.should raise_error(ArgumentError)
+ end
end
diff --git a/spec/unit/resource/status_spec.rb b/spec/unit/resource/status_spec.rb
index b03f9d4..425015a 100755
--- a/spec/unit/resource/status_spec.rb
+++ b/spec/unit/resource/status_spec.rb
@@ -5,99 +5,99 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/resource/status'
describe Puppet::Resource::Status do
- before do
- @resource = Puppet::Type.type(:file).new :path => "/my/file"
- @status = Puppet::Resource::Status.new(@resource)
+ before do
+ @resource = Puppet::Type.type(:file).new :path => "/my/file"
+ @status = Puppet::Resource::Status.new(@resource)
+ end
+
+ [:node, :version, :file, :line, :current_values, :skipped_reason, :status, :evaluation_time, :change_count].each do |attr|
+ it "should support #{attr}" do
+ @status.send(attr.to_s + "=", "foo")
+ @status.send(attr).should == "foo"
end
+ end
- [:node, :version, :file, :line, :current_values, :skipped_reason, :status, :evaluation_time, :change_count].each do |attr|
- it "should support #{attr}" do
- @status.send(attr.to_s + "=", "foo")
- @status.send(attr).should == "foo"
- end
+ [:skipped, :failed, :restarted, :failed_to_restart, :changed, :out_of_sync, :scheduled].each do |attr|
+ it "should support #{attr}" do
+ @status.send(attr.to_s + "=", "foo")
+ @status.send(attr).should == "foo"
end
- [:skipped, :failed, :restarted, :failed_to_restart, :changed, :out_of_sync, :scheduled].each do |attr|
- it "should support #{attr}" do
- @status.send(attr.to_s + "=", "foo")
- @status.send(attr).should == "foo"
- end
-
- it "should have a boolean method for determining whehter it was #{attr}" do
- @status.send(attr.to_s + "=", "foo")
- @status.should send("be_#{attr}")
- end
+ it "should have a boolean method for determining whehter it was #{attr}" do
+ @status.send(attr.to_s + "=", "foo")
+ @status.should send("be_#{attr}")
end
+ end
- it "should accept a resource at initialization" do
- Puppet::Resource::Status.new(@resource).resource.should_not be_nil
- end
+ it "should accept a resource at initialization" do
+ Puppet::Resource::Status.new(@resource).resource.should_not be_nil
+ end
- it "should set its source description to the resource's path" do
- @resource.expects(:path).returns "/my/path"
- Puppet::Resource::Status.new(@resource).source_description.should == "/my/path"
- end
+ it "should set its source description to the resource's path" do
+ @resource.expects(:path).returns "/my/path"
+ Puppet::Resource::Status.new(@resource).source_description.should == "/my/path"
+ end
- [:file, :line, :version].each do |attr|
- it "should copy the resource's #{attr}" do
- @resource.expects(attr).returns "foo"
- Puppet::Resource::Status.new(@resource).send(attr).should == "foo"
- end
+ [:file, :line, :version].each do |attr|
+ it "should copy the resource's #{attr}" do
+ @resource.expects(attr).returns "foo"
+ Puppet::Resource::Status.new(@resource).send(attr).should == "foo"
end
+ end
- it "should copy the resource's tags" do
- @resource.expects(:tags).returns %w{foo bar}
- Puppet::Resource::Status.new(@resource).tags.should == %w{foo bar}
- end
+ it "should copy the resource's tags" do
+ @resource.expects(:tags).returns %w{foo bar}
+ Puppet::Resource::Status.new(@resource).tags.should == %w{foo bar}
+ end
- it "should always convert the resource to a string" do
- @resource.expects(:to_s).returns "foo"
- Puppet::Resource::Status.new(@resource).resource.should == "foo"
- end
+ it "should always convert the resource to a string" do
+ @resource.expects(:to_s).returns "foo"
+ Puppet::Resource::Status.new(@resource).resource.should == "foo"
+ end
- it "should support tags" do
- Puppet::Resource::Status.ancestors.should include(Puppet::Util::Tagging)
- end
+ it "should support tags" do
+ Puppet::Resource::Status.ancestors.should include(Puppet::Util::Tagging)
+ end
+
+ it "should create a timestamp at its creation time" do
+ @status.time.should be_instance_of(Time)
+ end
- it "should create a timestamp at its creation time" do
- @status.time.should be_instance_of(Time)
+ describe "when sending logs" do
+ before do
+ Puppet::Util::Log.stubs(:new)
end
- describe "when sending logs" do
- before do
- Puppet::Util::Log.stubs(:new)
- end
-
- it "should set the tags to the event tags" do
- Puppet::Util::Log.expects(:new).with { |args| args[:tags] == %w{one two} }
- @status.stubs(:tags).returns %w{one two}
- @status.send_log :notice, "my message"
- end
-
- [:file, :line, :version].each do |attr|
- it "should pass the #{attr}" do
- Puppet::Util::Log.expects(:new).with { |args| args[attr] == "my val" }
- @status.send(attr.to_s + "=", "my val")
- @status.send_log :notice, "my message"
- end
- end
-
- it "should use the source description as the source" do
- Puppet::Util::Log.expects(:new).with { |args| args[:source] == "my source" }
- @status.stubs(:source_description).returns "my source"
- @status.send_log :notice, "my message"
- end
+ it "should set the tags to the event tags" do
+ Puppet::Util::Log.expects(:new).with { |args| args[:tags] == %w{one two} }
+ @status.stubs(:tags).returns %w{one two}
+ @status.send_log :notice, "my message"
end
- it "should support adding events" do
- event = Puppet::Transaction::Event.new(:name => :foobar)
- @status.add_event(event)
- @status.events.should == [event]
+ [:file, :line, :version].each do |attr|
+ it "should pass the #{attr}" do
+ Puppet::Util::Log.expects(:new).with { |args| args[attr] == "my val" }
+ @status.send(attr.to_s + "=", "my val")
+ @status.send_log :notice, "my message"
+ end
end
- it "should use '<<' to add events" do
- event = Puppet::Transaction::Event.new(:name => :foobar)
- (@status << event).should equal(@status)
- @status.events.should == [event]
+ it "should use the source description as the source" do
+ Puppet::Util::Log.expects(:new).with { |args| args[:source] == "my source" }
+ @status.stubs(:source_description).returns "my source"
+ @status.send_log :notice, "my message"
end
+ end
+
+ it "should support adding events" do
+ event = Puppet::Transaction::Event.new(:name => :foobar)
+ @status.add_event(event)
+ @status.events.should == [event]
+ end
+
+ it "should use '<<' to add events" do
+ event = Puppet::Transaction::Event.new(:name => :foobar)
+ (@status << event).should equal(@status)
+ @status.events.should == [event]
+ end
end
diff --git a/spec/unit/resource/type_collection_helper_spec.rb b/spec/unit/resource/type_collection_helper_spec.rb
index e390ff9..608b6e6 100644
--- a/spec/unit/resource/type_collection_helper_spec.rb
+++ b/spec/unit/resource/type_collection_helper_spec.rb
@@ -5,21 +5,21 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/resource/type_collection_helper'
class RTCHelperTester
- include Puppet::Resource::TypeCollectionHelper
+ include Puppet::Resource::TypeCollectionHelper
end
describe Puppet::Resource::TypeCollectionHelper do
- before do
- @helper = RTCHelperTester.new
- end
+ before do
+ @helper = RTCHelperTester.new
+ end
- it "should use its current environment to retrieve the known resource type collection" do
- env = stub 'environment'
- @helper.expects(:environment).returns env
+ it "should use its current environment to retrieve the known resource type collection" do
+ env = stub 'environment'
+ @helper.expects(:environment).returns env
- rtc = stub 'known_resource_types'
- env.expects(:known_resource_types).returns rtc
+ rtc = stub 'known_resource_types'
+ env.expects(:known_resource_types).returns rtc
- @helper.known_resource_types.should equal(rtc)
- end
+ @helper.known_resource_types.should equal(rtc)
+ end
end
diff --git a/spec/unit/resource/type_collection_spec.rb b/spec/unit/resource/type_collection_spec.rb
index 9a7c80e..788ea41 100644
--- a/spec/unit/resource/type_collection_spec.rb
+++ b/spec/unit/resource/type_collection_spec.rb
@@ -6,427 +6,427 @@ require 'puppet/resource/type_collection'
require 'puppet/resource/type'
describe Puppet::Resource::TypeCollection do
+ before do
+ @instance = Puppet::Resource::Type.new(:hostclass, "foo")
+ @code = Puppet::Resource::TypeCollection.new("env")
+ end
+
+ it "should require an environment at initialization" do
+ env = Puppet::Node::Environment.new("testing")
+ Puppet::Resource::TypeCollection.new(env).environment.should equal(env)
+ end
+
+ it "should convert the environment into an environment instance if a string is provided" do
+ env = Puppet::Node::Environment.new("testing")
+ Puppet::Resource::TypeCollection.new("testing").environment.should equal(env)
+ end
+
+ it "should create a 'loader' at initialization" do
+ Puppet::Resource::TypeCollection.new("testing").loader.should be_instance_of(Puppet::Parser::TypeLoader)
+ end
+
+ it "should be able to add a resource type" do
+ Puppet::Resource::TypeCollection.new("env").should respond_to(:add)
+ end
+
+ it "should consider '<<' to be an alias to 'add' but should return self" do
+ loader = Puppet::Resource::TypeCollection.new("env")
+ loader.expects(:add).with "foo"
+ loader.expects(:add).with "bar"
+ loader << "foo" << "bar"
+ end
+
+ it "should set itself as the code collection for added resource types" do
+ loader = Puppet::Resource::TypeCollection.new("env")
+
+ node = Puppet::Resource::Type.new(:node, "foo")
+
+ @code.add(node)
+ @code.node("foo").should equal(node)
+
+ node.resource_type_collection.should equal(@code)
+ end
+
+ it "should store node resource types as nodes" do
+ node = Puppet::Resource::Type.new(:node, "foo")
+
+ @code.add(node)
+ @code.node("foo").should equal(node)
+ end
+
+ it "should store hostclasses as hostclasses" do
+ klass = Puppet::Resource::Type.new(:hostclass, "foo")
+
+ @code.add(klass)
+ @code.hostclass("foo").should equal(klass)
+ end
+
+ it "should store definitions as definitions" do
+ define = Puppet::Resource::Type.new(:definition, "foo")
+
+ @code.add(define)
+ @code.definition("foo").should equal(define)
+ end
+
+ it "should merge new classes with existing classes of the same name" do
+ loader = Puppet::Resource::TypeCollection.new("env")
+ first = Puppet::Resource::Type.new(:hostclass, "foo")
+ second = Puppet::Resource::Type.new(:hostclass, "foo")
+ loader.add first
+ first.expects(:merge).with(second)
+ loader.add(second)
+ end
+
+ it "should remove all nodes, classes, and definitions when cleared" do
+ loader = Puppet::Resource::TypeCollection.new("env")
+ loader.add Puppet::Resource::Type.new(:hostclass, "class")
+ loader.add Puppet::Resource::Type.new(:definition, "define")
+ loader.add Puppet::Resource::Type.new(:node, "node")
+
+ loader.clear
+ loader.hostclass("class").should be_nil
+ loader.definition("define").should be_nil
+ loader.node("node").should be_nil
+ end
+
+ describe "when looking up names" do
before do
- @instance = Puppet::Resource::Type.new(:hostclass, "foo")
- @code = Puppet::Resource::TypeCollection.new("env")
+ @type = Puppet::Resource::Type.new(:hostclass, "ns::klass")
end
- it "should require an environment at initialization" do
- env = Puppet::Node::Environment.new("testing")
- Puppet::Resource::TypeCollection.new(env).environment.should equal(env)
+ it "should support looking up with multiple namespaces" do
+ @code.add @type
+ @code.find_hostclass(%w{boo baz ns}, "klass").should equal(@type)
end
- it "should convert the environment into an environment instance if a string is provided" do
- env = Puppet::Node::Environment.new("testing")
- Puppet::Resource::TypeCollection.new("testing").environment.should equal(env)
+ it "should not attempt to import anything when the type is already defined" do
+ @code.add @type
+ @code.loader.expects(:import).never
+ @code.find_hostclass(%w{ns}, "klass").should equal(@type)
end
- it "should create a 'loader' at initialization" do
- Puppet::Resource::TypeCollection.new("testing").loader.should be_instance_of(Puppet::Parser::TypeLoader)
+ describe "that need to be loaded" do
+ it "should use the loader to load the files" do
+ @code.loader.expects(:load_until).with(["ns"], "klass")
+ @code.find_or_load(["ns"], "klass", :hostclass)
+ end
+
+ it "should downcase the name and downcase and array-fy the namespaces before passing to the loader" do
+ @code.loader.expects(:load_until).with(["ns"], "klass")
+ @code.find_or_load("Ns", "Klass", :hostclass)
+ end
+
+ it "should attempt to find the type when the loader yields" do
+ @code.loader.expects(:load_until).yields
+ @code.expects(:find).with(["ns"], "klass", :hostclass).times(2).returns(false).then.returns(true)
+ @code.find_or_load("ns", "klass", :hostclass)
+ end
+
+ it "should return the result of 'load_until'" do
+ @code.loader.expects(:load_until).returns "foo"
+ @code.find_or_load("Ns", "Klass", :hostclass).should == "foo"
+ end
+
+ it "should return nil if the name isn't found" do
+ @code.stubs(:load_until).returns(nil)
+ @code.find_or_load("Ns", "Klass", :hostclass).should be_nil
+ end
end
+ end
- it "should be able to add a resource type" do
- Puppet::Resource::TypeCollection.new("env").should respond_to(:add)
+ %w{hostclass node definition}.each do |data|
+ before do
+ @instance = Puppet::Resource::Type.new(data, "foo")
end
- it "should consider '<<' to be an alias to 'add' but should return self" do
- loader = Puppet::Resource::TypeCollection.new("env")
- loader.expects(:add).with "foo"
- loader.expects(:add).with "bar"
- loader << "foo" << "bar"
+ it "should have a method for adding a #{data}" do
+ Puppet::Resource::TypeCollection.new("env").should respond_to("add_#{data}")
end
- it "should set itself as the code collection for added resource types" do
+ it "should use the name of the instance to add it" do
+ loader = Puppet::Resource::TypeCollection.new("env")
+ loader.send("add_#{data}", @instance)
+ loader.send(data, @instance.name).should equal(@instance)
+ end
+
+ unless data == "hostclass"
+ it "should fail to add a #{data} when one already exists" do
loader = Puppet::Resource::TypeCollection.new("env")
+ loader.add @instance
+ lambda { loader.add(@instance) }.should raise_error(Puppet::ParseError)
+ end
+ end
- node = Puppet::Resource::Type.new(:node, "foo")
+ it "should return the added #{data}" do
+ loader = Puppet::Resource::TypeCollection.new("env")
- @code.add(node)
- @code.node("foo").should equal(node)
+ loader.add(@instance).should equal(@instance)
+ end
- node.resource_type_collection.should equal(@code)
+ it "should be able to retrieve #{data} by name" do
+ loader = Puppet::Resource::TypeCollection.new("env")
+ instance = Puppet::Resource::Type.new(data, "bar")
+ loader.add instance
+ loader.send(data, "bar").should equal(instance)
end
- it "should store node resource types as nodes" do
- node = Puppet::Resource::Type.new(:node, "foo")
+ it "should retrieve #{data} insensitive to case" do
+ loader = Puppet::Resource::TypeCollection.new("env")
+ instance = Puppet::Resource::Type.new(data, "Bar")
+ loader.add instance
+ loader.send(data, "bAr").should equal(instance)
+ end
- @code.add(node)
- @code.node("foo").should equal(node)
+ it "should return nil when asked for a #{data} that has not been added" do
+ Puppet::Resource::TypeCollection.new("env").send(data, "foo").should be_nil
end
- it "should store hostclasses as hostclasses" do
- klass = Puppet::Resource::Type.new(:hostclass, "foo")
+ it "should be able to retrieve all #{data}s" do
+ plurals = { "hostclass" => "hostclasses", "node" => "nodes", "definition" => "definitions" }
+ loader = Puppet::Resource::TypeCollection.new("env")
+ instance = Puppet::Resource::Type.new(data, "foo")
+ loader.add instance
+ loader.send(plurals[data]).should == { "foo" => instance }
+ end
+ end
+
+ describe "when finding a qualified instance" do
+ it "should return any found instance if the instance name is fully qualified" do
+ loader = Puppet::Resource::TypeCollection.new("env")
+ instance = Puppet::Resource::Type.new(:hostclass, "foo::bar")
+ loader.add instance
+ loader.find("namespace", "::foo::bar", :hostclass).should equal(instance)
+ end
- @code.add(klass)
- @code.hostclass("foo").should equal(klass)
+ it "should return nil if the instance name is fully qualified and no such instance exists" do
+ loader = Puppet::Resource::TypeCollection.new("env")
+ loader.find("namespace", "::foo::bar", :hostclass).should be_nil
end
- it "should store definitions as definitions" do
- define = Puppet::Resource::Type.new(:definition, "foo")
+ it "should be able to find classes in the base namespace" do
+ loader = Puppet::Resource::TypeCollection.new("env")
+ instance = Puppet::Resource::Type.new(:hostclass, "foo")
+ loader.add instance
+ loader.find("", "foo", :hostclass).should equal(instance)
+ end
- @code.add(define)
- @code.definition("foo").should equal(define)
+ it "should return the partially qualified object if it exists in a provided namespace" do
+ loader = Puppet::Resource::TypeCollection.new("env")
+ instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz")
+ loader.add instance
+ loader.find("foo", "bar::baz", :hostclass).should equal(instance)
end
- it "should merge new classes with existing classes of the same name" do
- loader = Puppet::Resource::TypeCollection.new("env")
- first = Puppet::Resource::Type.new(:hostclass, "foo")
- second = Puppet::Resource::Type.new(:hostclass, "foo")
- loader.add first
- first.expects(:merge).with(second)
- loader.add(second)
+ it "should be able to find partially qualified objects in any of the provided namespaces" do
+ loader = Puppet::Resource::TypeCollection.new("env")
+ instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz")
+ loader.add instance
+ loader.find(["nons", "foo", "otherns"], "bar::baz", :hostclass).should equal(instance)
end
- it "should remove all nodes, classes, and definitions when cleared" do
- loader = Puppet::Resource::TypeCollection.new("env")
- loader.add Puppet::Resource::Type.new(:hostclass, "class")
- loader.add Puppet::Resource::Type.new(:definition, "define")
- loader.add Puppet::Resource::Type.new(:node, "node")
-
- loader.clear
- loader.hostclass("class").should be_nil
- loader.definition("define").should be_nil
- loader.node("node").should be_nil
- end
-
- describe "when looking up names" do
- before do
- @type = Puppet::Resource::Type.new(:hostclass, "ns::klass")
- end
-
- it "should support looking up with multiple namespaces" do
- @code.add @type
- @code.find_hostclass(%w{boo baz ns}, "klass").should equal(@type)
- end
-
- it "should not attempt to import anything when the type is already defined" do
- @code.add @type
- @code.loader.expects(:import).never
- @code.find_hostclass(%w{ns}, "klass").should equal(@type)
- end
-
- describe "that need to be loaded" do
- it "should use the loader to load the files" do
- @code.loader.expects(:load_until).with(["ns"], "klass")
- @code.find_or_load(["ns"], "klass", :hostclass)
- end
-
- it "should downcase the name and downcase and array-fy the namespaces before passing to the loader" do
- @code.loader.expects(:load_until).with(["ns"], "klass")
- @code.find_or_load("Ns", "Klass", :hostclass)
- end
-
- it "should attempt to find the type when the loader yields" do
- @code.loader.expects(:load_until).yields
- @code.expects(:find).with(["ns"], "klass", :hostclass).times(2).returns(false).then.returns(true)
- @code.find_or_load("ns", "klass", :hostclass)
- end
-
- it "should return the result of 'load_until'" do
- @code.loader.expects(:load_until).returns "foo"
- @code.find_or_load("Ns", "Klass", :hostclass).should == "foo"
- end
-
- it "should return nil if the name isn't found" do
- @code.stubs(:load_until).returns(nil)
- @code.find_or_load("Ns", "Klass", :hostclass).should be_nil
- end
- end
- end
-
- %w{hostclass node definition}.each do |data|
- before do
- @instance = Puppet::Resource::Type.new(data, "foo")
- end
-
- it "should have a method for adding a #{data}" do
- Puppet::Resource::TypeCollection.new("env").should respond_to("add_#{data}")
- end
-
- it "should use the name of the instance to add it" do
- loader = Puppet::Resource::TypeCollection.new("env")
- loader.send("add_#{data}", @instance)
- loader.send(data, @instance.name).should equal(@instance)
- end
-
- unless data == "hostclass"
- it "should fail to add a #{data} when one already exists" do
- loader = Puppet::Resource::TypeCollection.new("env")
- loader.add @instance
- lambda { loader.add(@instance) }.should raise_error(Puppet::ParseError)
- end
- end
-
- it "should return the added #{data}" do
- loader = Puppet::Resource::TypeCollection.new("env")
-
- loader.add(@instance).should equal(@instance)
- end
-
- it "should be able to retrieve #{data} by name" do
- loader = Puppet::Resource::TypeCollection.new("env")
- instance = Puppet::Resource::Type.new(data, "bar")
- loader.add instance
- loader.send(data, "bar").should equal(instance)
- end
-
- it "should retrieve #{data} insensitive to case" do
- loader = Puppet::Resource::TypeCollection.new("env")
- instance = Puppet::Resource::Type.new(data, "Bar")
- loader.add instance
- loader.send(data, "bAr").should equal(instance)
- end
-
- it "should return nil when asked for a #{data} that has not been added" do
- Puppet::Resource::TypeCollection.new("env").send(data, "foo").should be_nil
- end
-
- it "should be able to retrieve all #{data}s" do
- plurals = { "hostclass" => "hostclasses", "node" => "nodes", "definition" => "definitions" }
- loader = Puppet::Resource::TypeCollection.new("env")
- instance = Puppet::Resource::Type.new(data, "foo")
- loader.add instance
- loader.send(plurals[data]).should == { "foo" => instance }
- end
- end
-
- describe "when finding a qualified instance" do
- it "should return any found instance if the instance name is fully qualified" do
- loader = Puppet::Resource::TypeCollection.new("env")
- instance = Puppet::Resource::Type.new(:hostclass, "foo::bar")
- loader.add instance
- loader.find("namespace", "::foo::bar", :hostclass).should equal(instance)
- end
-
- it "should return nil if the instance name is fully qualified and no such instance exists" do
- loader = Puppet::Resource::TypeCollection.new("env")
- loader.find("namespace", "::foo::bar", :hostclass).should be_nil
- end
-
- it "should be able to find classes in the base namespace" do
- loader = Puppet::Resource::TypeCollection.new("env")
- instance = Puppet::Resource::Type.new(:hostclass, "foo")
- loader.add instance
- loader.find("", "foo", :hostclass).should equal(instance)
- end
-
- it "should return the partially qualified object if it exists in a provided namespace" do
- loader = Puppet::Resource::TypeCollection.new("env")
- instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz")
- loader.add instance
- loader.find("foo", "bar::baz", :hostclass).should equal(instance)
- end
-
- it "should be able to find partially qualified objects in any of the provided namespaces" do
- loader = Puppet::Resource::TypeCollection.new("env")
- instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz")
- loader.add instance
- loader.find(["nons", "foo", "otherns"], "bar::baz", :hostclass).should equal(instance)
- end
-
- it "should return the unqualified object if it exists in a provided namespace" do
- loader = Puppet::Resource::TypeCollection.new("env")
- instance = Puppet::Resource::Type.new(:hostclass, "foo::bar")
- loader.add instance
- loader.find("foo", "bar", :hostclass).should equal(instance)
- end
-
- it "should return the unqualified object if it exists in the parent namespace" do
- loader = Puppet::Resource::TypeCollection.new("env")
- instance = Puppet::Resource::Type.new(:hostclass, "foo::bar")
- loader.add instance
- loader.find("foo::bar::baz", "bar", :hostclass).should equal(instance)
- end
-
- it "should should return the partially qualified object if it exists in the parent namespace" do
- loader = Puppet::Resource::TypeCollection.new("env")
- instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz")
- loader.add instance
- loader.find("foo::bar", "bar::baz", :hostclass).should equal(instance)
- end
-
- it "should return the qualified object if it exists in the root namespace" do
- loader = Puppet::Resource::TypeCollection.new("env")
- instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz")
- loader.add instance
- loader.find("foo::bar", "foo::bar::baz", :hostclass).should equal(instance)
- end
-
- it "should return nil if the object cannot be found" do
- loader = Puppet::Resource::TypeCollection.new("env")
- instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz")
- loader.add instance
- loader.find("foo::bar", "eh", :hostclass).should be_nil
- end
- end
-
- it "should use the generic 'find' method with an empty namespace to find nodes" do
- loader = Puppet::Resource::TypeCollection.new("env")
- loader.expects(:find).with("", "bar", :node)
- loader.find_node("bar")
+ it "should return the unqualified object if it exists in a provided namespace" do
+ loader = Puppet::Resource::TypeCollection.new("env")
+ instance = Puppet::Resource::Type.new(:hostclass, "foo::bar")
+ loader.add instance
+ loader.find("foo", "bar", :hostclass).should equal(instance)
end
- it "should use the 'find_or_load' method to find hostclasses" do
- loader = Puppet::Resource::TypeCollection.new("env")
- loader.expects(:find_or_load).with("foo", "bar", :hostclass)
- loader.find_hostclass("foo", "bar")
+ it "should return the unqualified object if it exists in the parent namespace" do
+ loader = Puppet::Resource::TypeCollection.new("env")
+ instance = Puppet::Resource::Type.new(:hostclass, "foo::bar")
+ loader.add instance
+ loader.find("foo::bar::baz", "bar", :hostclass).should equal(instance)
end
- it "should use the 'find_or_load' method to find definitions" do
- loader = Puppet::Resource::TypeCollection.new("env")
- loader.expects(:find_or_load).with("foo", "bar", :definition)
- loader.find_definition("foo", "bar")
+ it "should should return the partially qualified object if it exists in the parent namespace" do
+ loader = Puppet::Resource::TypeCollection.new("env")
+ instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz")
+ loader.add instance
+ loader.find("foo::bar", "bar::baz", :hostclass).should equal(instance)
end
- it "should indicate whether any nodes are defined" do
- loader = Puppet::Resource::TypeCollection.new("env")
- loader.add_node(Puppet::Resource::Type.new(:node, "foo"))
- loader.should be_nodes
- end
-
- it "should indicate whether no nodes are defined" do
- Puppet::Resource::TypeCollection.new("env").should_not be_nodes
- end
-
- describe "when finding nodes" do
- before :each do
- @loader = Puppet::Resource::TypeCollection.new("env")
- end
-
- it "should return any node whose name exactly matches the provided node name" do
- node = Puppet::Resource::Type.new(:node, "foo")
- @loader << node
-
- @loader.node("foo").should equal(node)
- end
-
- it "should return the first regex node whose regex matches the provided node name" do
- node1 = Puppet::Resource::Type.new(:node, /\w/)
- node2 = Puppet::Resource::Type.new(:node, /\d/)
- @loader << node1 << node2
-
- @loader.node("foo10").should equal(node1)
- end
-
- it "should preferentially return a node whose name is string-equal over returning a node whose regex matches a provided name" do
- node1 = Puppet::Resource::Type.new(:node, /\w/)
- node2 = Puppet::Resource::Type.new(:node, "foo")
- @loader << node1 << node2
-
- @loader.node("foo").should equal(node2)
- end
- end
-
- describe "when managing files" do
- before do
- @loader = Puppet::Resource::TypeCollection.new("env")
- Puppet::Util::LoadedFile.stubs(:new).returns stub("watched_file")
- end
-
- it "should have a method for specifying a file should be watched" do
- @loader.should respond_to(:watch_file)
- end
-
- it "should have a method for determining if a file is being watched" do
- @loader.watch_file("/foo/bar")
- @loader.should be_watching_file("/foo/bar")
- end
-
- it "should use LoadedFile to watch files" do
- Puppet::Util::LoadedFile.expects(:new).with("/foo/bar").returns stub("watched_file")
- @loader.watch_file("/foo/bar")
- end
-
- it "should be considered stale if any files have changed" do
- file1 = stub 'file1', :changed? => false
- file2 = stub 'file2', :changed? => true
- Puppet::Util::LoadedFile.expects(:new).times(2).returns(file1).then.returns(file2)
- @loader.watch_file("/foo/bar")
- @loader.watch_file("/other/bar")
-
- @loader.should be_stale
- end
-
- it "should not be considered stable if no files have changed" do
- file1 = stub 'file1', :changed? => false
- file2 = stub 'file2', :changed? => false
- Puppet::Util::LoadedFile.expects(:new).times(2).returns(file1).then.returns(file2)
- @loader.watch_file("/foo/bar")
- @loader.watch_file("/other/bar")
-
- @loader.should_not be_stale
- end
- end
-
- describe "when performing initial import" do
- before do
- @parser = stub 'parser', :file= => nil, :string => nil, :parse => nil
- Puppet::Parser::Parser.stubs(:new).returns @parser
- @code = Puppet::Resource::TypeCollection.new("env")
- end
-
- it "should create a new parser instance" do
- Puppet::Parser::Parser.expects(:new).returns @parser
- @code.perform_initial_import
- end
-
- it "should set the parser's string to the 'code' setting and parse if code is available" do
- Puppet.settings[:code] = "my code"
- @parser.expects(:string=).with "my code"
- @parser.expects(:parse)
- @code.perform_initial_import
- end
-
- it "should set the parser's file to the 'manifest' setting and parse if no code is available and the manifest is available" do
- File.stubs(:expand_path).with("/my/file").returns "/my/file"
- File.expects(:exist?).with("/my/file").returns true
- Puppet.settings[:manifest] = "/my/file"
- @parser.expects(:file=).with "/my/file"
- @parser.expects(:parse)
- @code.perform_initial_import
- end
-
- it "should not attempt to load a manifest if none is present" do
- File.stubs(:expand_path).with("/my/file").returns "/my/file"
- File.expects(:exist?).with("/my/file").returns false
- Puppet.settings[:manifest] = "/my/file"
- @parser.expects(:file=).never
- @parser.expects(:parse).never
- @code.perform_initial_import
- end
-
- it "should fail helpfully if there is an error importing" do
- File.stubs(:exist?).returns true
- @parser.expects(:parse).raises ArgumentError
- lambda { @code.perform_initial_import }.should raise_error(Puppet::Error)
- end
- end
-
- describe "when determining the configuration version" do
- before do
- @code = Puppet::Resource::TypeCollection.new("env")
- end
-
- it "should default to the current time" do
- time = Time.now
-
- Time.stubs(:now).returns time
- @code.version.should == time.to_i
- end
-
- it "should use the output of the environment's config_version setting if one is provided" do
- @code.environment.stubs(:[]).with(:config_version).returns("/my/foo")
-
- Puppet::Util.expects(:execute).with(["/my/foo"]).returns "output\n"
- @code.version.should == "output"
- end
-
- it "should raise a puppet parser error if executing config_version fails" do
- @code.environment.stubs(:[]).with(:config_version).returns("test")
- Puppet::Util.expects(:execute).raises(Puppet::ExecutionFailure.new("msg"))
-
- lambda { @code.version }.should raise_error(Puppet::ParseError)
- end
+ it "should return the qualified object if it exists in the root namespace" do
+ loader = Puppet::Resource::TypeCollection.new("env")
+ instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz")
+ loader.add instance
+ loader.find("foo::bar", "foo::bar::baz", :hostclass).should equal(instance)
+ end
+
+ it "should return nil if the object cannot be found" do
+ loader = Puppet::Resource::TypeCollection.new("env")
+ instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz")
+ loader.add instance
+ loader.find("foo::bar", "eh", :hostclass).should be_nil
+ end
+ end
+
+ it "should use the generic 'find' method with an empty namespace to find nodes" do
+ loader = Puppet::Resource::TypeCollection.new("env")
+ loader.expects(:find).with("", "bar", :node)
+ loader.find_node("bar")
+ end
+
+ it "should use the 'find_or_load' method to find hostclasses" do
+ loader = Puppet::Resource::TypeCollection.new("env")
+ loader.expects(:find_or_load).with("foo", "bar", :hostclass)
+ loader.find_hostclass("foo", "bar")
+ end
+
+ it "should use the 'find_or_load' method to find definitions" do
+ loader = Puppet::Resource::TypeCollection.new("env")
+ loader.expects(:find_or_load).with("foo", "bar", :definition)
+ loader.find_definition("foo", "bar")
+ end
+
+ it "should indicate whether any nodes are defined" do
+ loader = Puppet::Resource::TypeCollection.new("env")
+ loader.add_node(Puppet::Resource::Type.new(:node, "foo"))
+ loader.should be_nodes
+ end
+
+ it "should indicate whether no nodes are defined" do
+ Puppet::Resource::TypeCollection.new("env").should_not be_nodes
+ end
+
+ describe "when finding nodes" do
+ before :each do
+ @loader = Puppet::Resource::TypeCollection.new("env")
+ end
+
+ it "should return any node whose name exactly matches the provided node name" do
+ node = Puppet::Resource::Type.new(:node, "foo")
+ @loader << node
+
+ @loader.node("foo").should equal(node)
+ end
+
+ it "should return the first regex node whose regex matches the provided node name" do
+ node1 = Puppet::Resource::Type.new(:node, /\w/)
+ node2 = Puppet::Resource::Type.new(:node, /\d/)
+ @loader << node1 << node2
+
+ @loader.node("foo10").should equal(node1)
+ end
+
+ it "should preferentially return a node whose name is string-equal over returning a node whose regex matches a provided name" do
+ node1 = Puppet::Resource::Type.new(:node, /\w/)
+ node2 = Puppet::Resource::Type.new(:node, "foo")
+ @loader << node1 << node2
+
+ @loader.node("foo").should equal(node2)
+ end
+ end
+
+ describe "when managing files" do
+ before do
+ @loader = Puppet::Resource::TypeCollection.new("env")
+ Puppet::Util::LoadedFile.stubs(:new).returns stub("watched_file")
+ end
+
+ it "should have a method for specifying a file should be watched" do
+ @loader.should respond_to(:watch_file)
+ end
+ it "should have a method for determining if a file is being watched" do
+ @loader.watch_file("/foo/bar")
+ @loader.should be_watching_file("/foo/bar")
end
+
+ it "should use LoadedFile to watch files" do
+ Puppet::Util::LoadedFile.expects(:new).with("/foo/bar").returns stub("watched_file")
+ @loader.watch_file("/foo/bar")
+ end
+
+ it "should be considered stale if any files have changed" do
+ file1 = stub 'file1', :changed? => false
+ file2 = stub 'file2', :changed? => true
+ Puppet::Util::LoadedFile.expects(:new).times(2).returns(file1).then.returns(file2)
+ @loader.watch_file("/foo/bar")
+ @loader.watch_file("/other/bar")
+
+ @loader.should be_stale
+ end
+
+ it "should not be considered stable if no files have changed" do
+ file1 = stub 'file1', :changed? => false
+ file2 = stub 'file2', :changed? => false
+ Puppet::Util::LoadedFile.expects(:new).times(2).returns(file1).then.returns(file2)
+ @loader.watch_file("/foo/bar")
+ @loader.watch_file("/other/bar")
+
+ @loader.should_not be_stale
+ end
+ end
+
+ describe "when performing initial import" do
+ before do
+ @parser = stub 'parser', :file= => nil, :string => nil, :parse => nil
+ Puppet::Parser::Parser.stubs(:new).returns @parser
+ @code = Puppet::Resource::TypeCollection.new("env")
+ end
+
+ it "should create a new parser instance" do
+ Puppet::Parser::Parser.expects(:new).returns @parser
+ @code.perform_initial_import
+ end
+
+ it "should set the parser's string to the 'code' setting and parse if code is available" do
+ Puppet.settings[:code] = "my code"
+ @parser.expects(:string=).with "my code"
+ @parser.expects(:parse)
+ @code.perform_initial_import
+ end
+
+ it "should set the parser's file to the 'manifest' setting and parse if no code is available and the manifest is available" do
+ File.stubs(:expand_path).with("/my/file").returns "/my/file"
+ File.expects(:exist?).with("/my/file").returns true
+ Puppet.settings[:manifest] = "/my/file"
+ @parser.expects(:file=).with "/my/file"
+ @parser.expects(:parse)
+ @code.perform_initial_import
+ end
+
+ it "should not attempt to load a manifest if none is present" do
+ File.stubs(:expand_path).with("/my/file").returns "/my/file"
+ File.expects(:exist?).with("/my/file").returns false
+ Puppet.settings[:manifest] = "/my/file"
+ @parser.expects(:file=).never
+ @parser.expects(:parse).never
+ @code.perform_initial_import
+ end
+
+ it "should fail helpfully if there is an error importing" do
+ File.stubs(:exist?).returns true
+ @parser.expects(:parse).raises ArgumentError
+ lambda { @code.perform_initial_import }.should raise_error(Puppet::Error)
+ end
+ end
+
+ describe "when determining the configuration version" do
+ before do
+ @code = Puppet::Resource::TypeCollection.new("env")
+ end
+
+ it "should default to the current time" do
+ time = Time.now
+
+ Time.stubs(:now).returns time
+ @code.version.should == time.to_i
+ end
+
+ it "should use the output of the environment's config_version setting if one is provided" do
+ @code.environment.stubs(:[]).with(:config_version).returns("/my/foo")
+
+ Puppet::Util.expects(:execute).with(["/my/foo"]).returns "output\n"
+ @code.version.should == "output"
+ end
+
+ it "should raise a puppet parser error if executing config_version fails" do
+ @code.environment.stubs(:[]).with(:config_version).returns("test")
+ Puppet::Util.expects(:execute).raises(Puppet::ExecutionFailure.new("msg"))
+
+ lambda { @code.version }.should raise_error(Puppet::ParseError)
+ end
+
+ end
end
diff --git a/spec/unit/resource/type_spec.rb b/spec/unit/resource/type_spec.rb
index ca9daf8..be2e6b1 100755
--- a/spec/unit/resource/type_spec.rb
+++ b/spec/unit/resource/type_spec.rb
@@ -5,697 +5,697 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/resource/type'
describe Puppet::Resource::Type do
- it "should have a 'name' attribute" do
- Puppet::Resource::Type.new(:hostclass, "foo").name.should == "foo"
+ it "should have a 'name' attribute" do
+ Puppet::Resource::Type.new(:hostclass, "foo").name.should == "foo"
+ end
+
+ [:code, :doc, :line, :file, :resource_type_collection, :ruby_code].each do |attr|
+ it "should have a '#{attr}' attribute" do
+ type = Puppet::Resource::Type.new(:hostclass, "foo")
+ type.send(attr.to_s + "=", "yay")
+ type.send(attr).should == "yay"
end
+ end
- [:code, :doc, :line, :file, :resource_type_collection, :ruby_code].each do |attr|
- it "should have a '#{attr}' attribute" do
- type = Puppet::Resource::Type.new(:hostclass, "foo")
- type.send(attr.to_s + "=", "yay")
- type.send(attr).should == "yay"
- end
+ [:hostclass, :node, :definition].each do |type|
+ it "should know when it is a #{type}" do
+ Puppet::Resource::Type.new(type, "foo").send("#{type}?").should be_true
end
+ end
- [:hostclass, :node, :definition].each do |type|
- it "should know when it is a #{type}" do
- Puppet::Resource::Type.new(type, "foo").send("#{type}?").should be_true
- end
+ it "should indirect 'resource_type'" do
+ Puppet::Resource::Type.indirection.name.should == :resource_type
+ end
+
+ it "should default to 'parser' for its terminus class" do
+ Puppet::Resource::Type.indirection.terminus_class.should == :parser
+ end
+
+ describe "when converting to json" do
+ before do
+ @type = Puppet::Resource::Type.new(:hostclass, "foo")
end
- it "should indirect 'resource_type'" do
- Puppet::Resource::Type.indirection.name.should == :resource_type
+ def from_json(json)
+ Puppet::Resource::Type.from_pson(json)
end
- it "should default to 'parser' for its terminus class" do
- Puppet::Resource::Type.indirection.terminus_class.should == :parser
+ def double_convert
+ Puppet::Resource::Type.from_pson(PSON.parse(@type.to_pson))
end
- describe "when converting to json" do
- before do
- @type = Puppet::Resource::Type.new(:hostclass, "foo")
- end
+ it "should include the name and type" do
+ double_convert.name.should == @type.name
+ double_convert.type.should == @type.type
+ end
- def from_json(json)
- Puppet::Resource::Type.from_pson(json)
- end
+ it "should include any arguments" do
+ @type.set_arguments("one" => nil, "two" => "foo")
- def double_convert
- Puppet::Resource::Type.from_pson(PSON.parse(@type.to_pson))
- end
+ double_convert.arguments.should == {"one" => nil, "two" => "foo"}
+ end
- it "should include the name and type" do
- double_convert.name.should == @type.name
- double_convert.type.should == @type.type
- end
+ it "should include any extra attributes" do
+ @type.file = "/my/file"
+ @type.line = 50
- it "should include any arguments" do
- @type.set_arguments("one" => nil, "two" => "foo")
+ double_convert.file.should == "/my/file"
+ double_convert.line.should == 50
+ end
+ end
- double_convert.arguments.should == {"one" => nil, "two" => "foo"}
- end
+ describe "when a node" do
+ it "should allow a regex as its name" do
+ lambda { Puppet::Resource::Type.new(:node, /foo/) }.should_not raise_error
+ end
- it "should include any extra attributes" do
- @type.file = "/my/file"
- @type.line = 50
+ it "should allow a AST::HostName instance as its name" do
+ regex = Puppet::Parser::AST::Regex.new(:value => /foo/)
+ name = Puppet::Parser::AST::HostName.new(:value => regex)
+ lambda { Puppet::Resource::Type.new(:node, name) }.should_not raise_error
+ end
- double_convert.file.should == "/my/file"
- double_convert.line.should == 50
- end
+ it "should match against the regexp in the AST::HostName when a HostName instance is provided" do
+ regex = Puppet::Parser::AST::Regex.new(:value => /\w/)
+ name = Puppet::Parser::AST::HostName.new(:value => regex)
+ node = Puppet::Resource::Type.new(:node, name)
+
+ node.match("foo").should be_true
end
- describe "when a node" do
- it "should allow a regex as its name" do
- lambda { Puppet::Resource::Type.new(:node, /foo/) }.should_not raise_error
- end
+ it "should return the value of the hostname if provided a string-form AST::HostName instance as the name" do
+ name = Puppet::Parser::AST::HostName.new(:value => "foo")
+ node = Puppet::Resource::Type.new(:node, name)
- it "should allow a AST::HostName instance as its name" do
- regex = Puppet::Parser::AST::Regex.new(:value => /foo/)
- name = Puppet::Parser::AST::HostName.new(:value => regex)
- lambda { Puppet::Resource::Type.new(:node, name) }.should_not raise_error
- end
+ node.name.should == "foo"
+ end
- it "should match against the regexp in the AST::HostName when a HostName instance is provided" do
- regex = Puppet::Parser::AST::Regex.new(:value => /\w/)
- name = Puppet::Parser::AST::HostName.new(:value => regex)
- node = Puppet::Resource::Type.new(:node, name)
+ describe "and the name is a regex" do
+ it "should have a method that indicates that this is the case" do
+ Puppet::Resource::Type.new(:node, /w/).should be_name_is_regex
+ end
- node.match("foo").should be_true
- end
+ it "should set its namespace to ''" do
+ Puppet::Resource::Type.new(:node, /w/).namespace.should == ""
+ end
- it "should return the value of the hostname if provided a string-form AST::HostName instance as the name" do
- name = Puppet::Parser::AST::HostName.new(:value => "foo")
- node = Puppet::Resource::Type.new(:node, name)
+ it "should return the regex converted to a string when asked for its name" do
+ Puppet::Resource::Type.new(:node, /ww/).name.should == "ww"
+ end
- node.name.should == "foo"
- end
+ it "should downcase the regex when returning the name as a string" do
+ Puppet::Resource::Type.new(:node, /W/).name.should == "w"
+ end
- describe "and the name is a regex" do
- it "should have a method that indicates that this is the case" do
- Puppet::Resource::Type.new(:node, /w/).should be_name_is_regex
- end
+ it "should remove non-alpha characters when returning the name as a string" do
+ Puppet::Resource::Type.new(:node, /w*w/).name.should_not include("*")
+ end
- it "should set its namespace to ''" do
- Puppet::Resource::Type.new(:node, /w/).namespace.should == ""
- end
+ it "should remove leading dots when returning the name as a string" do
+ Puppet::Resource::Type.new(:node, /.ww/).name.should_not =~ /^\./
+ end
- it "should return the regex converted to a string when asked for its name" do
- Puppet::Resource::Type.new(:node, /ww/).name.should == "ww"
- end
+ it "should have a method for matching its regex name against a provided name" do
+ Puppet::Resource::Type.new(:node, /.ww/).should respond_to(:match)
+ end
- it "should downcase the regex when returning the name as a string" do
- Puppet::Resource::Type.new(:node, /W/).name.should == "w"
- end
+ it "should return true when its regex matches the provided name" do
+ Puppet::Resource::Type.new(:node, /\w/).match("foo").should be_true
+ end
- it "should remove non-alpha characters when returning the name as a string" do
- Puppet::Resource::Type.new(:node, /w*w/).name.should_not include("*")
- end
-
- it "should remove leading dots when returning the name as a string" do
- Puppet::Resource::Type.new(:node, /.ww/).name.should_not =~ /^\./
- end
+ it "should return false when its regex does not match the provided name" do
+ (!!Puppet::Resource::Type.new(:node, /\d/).match("foo")).should be_false
+ end
- it "should have a method for matching its regex name against a provided name" do
- Puppet::Resource::Type.new(:node, /.ww/).should respond_to(:match)
- end
-
- it "should return true when its regex matches the provided name" do
- Puppet::Resource::Type.new(:node, /\w/).match("foo").should be_true
- end
-
- it "should return false when its regex does not match the provided name" do
- (!!Puppet::Resource::Type.new(:node, /\d/).match("foo")).should be_false
- end
-
- it "should return true when its name, as a string, is matched against an equal string" do
- Puppet::Resource::Type.new(:node, "foo").match("foo").should be_true
- end
-
- it "should return false when its name is matched against an unequal string" do
- Puppet::Resource::Type.new(:node, "foo").match("bar").should be_false
- end
-
- it "should match names insensitive to case" do
- Puppet::Resource::Type.new(:node, "fOo").match("foO").should be_true
- end
- end
-
- it "should return the name converted to a string when the name is not a regex" do
- pending "Need to define LoadedCode behaviour first"
- name = Puppet::Parser::AST::HostName.new(:value => "foo")
- Puppet::Resource::Type.new(:node, name).name.should == "foo"
- end
-
- it "should return the name converted to a string when the name is a regex" do
- pending "Need to define LoadedCode behaviour first"
- name = Puppet::Parser::AST::HostName.new(:value => /regex/)
- Puppet::Resource::Type.new(:node, name).name.should == /regex/.to_s
- end
-
- it "should mark any created scopes as a node scope" do
- pending "Need to define LoadedCode behaviour first"
- name = Puppet::Parser::AST::HostName.new(:value => /regex/)
- Puppet::Resource::Type.new(:node, name).name.should == /regex/.to_s
- end
- end
-
- describe "when initializing" do
- it "should require a resource super type" do
- Puppet::Resource::Type.new(:hostclass, "foo").type.should == :hostclass
- end
-
- it "should fail if provided an invalid resource super type" do
- lambda { Puppet::Resource::Type.new(:nope, "foo") }.should raise_error(ArgumentError)
- end
-
- it "should set its name to the downcased, stringified provided name" do
- Puppet::Resource::Type.new(:hostclass, "Foo::Bar".intern).name.should == "foo::bar"
- end
-
- it "should set its namespace to the downcased, stringified qualified name for classes" do
- Puppet::Resource::Type.new(:hostclass, "Foo::Bar::Baz".intern).namespace.should == "foo::bar::baz"
- end
-
- [:definition, :node].each do |type|
- it "should set its namespace to the downcased, stringified qualified portion of the name for #{type}s" do
- Puppet::Resource::Type.new(type, "Foo::Bar::Baz".intern).namespace.should == "foo::bar"
- end
- end
-
- %w{code line file doc}.each do |arg|
- it "should set #{arg} if provided" do
- type = Puppet::Resource::Type.new(:hostclass, "foo", arg.to_sym => "something")
- type.send(arg).should == "something"
- end
- end
-
- it "should set any provided arguments with the keys as symbols" do
- type = Puppet::Resource::Type.new(:hostclass, "foo", :arguments => {:foo => "bar", :baz => "biz"})
- type.should be_valid_parameter("foo")
- type.should be_valid_parameter("baz")
- end
-
- it "should set any provided arguments with they keys as strings" do
- type = Puppet::Resource::Type.new(:hostclass, "foo", :arguments => {"foo" => "bar", "baz" => "biz"})
- type.should be_valid_parameter(:foo)
- type.should be_valid_parameter(:baz)
- end
-
- it "should function if provided no arguments" do
- type = Puppet::Resource::Type.new(:hostclass, "foo")
- type.should_not be_valid_parameter(:foo)
- end
- end
-
- describe "when testing the validity of an attribute" do
- it "should return true if the parameter was typed at initialization" do
- Puppet::Resource::Type.new(:hostclass, "foo", :arguments => {"foo" => "bar"}).should be_valid_parameter("foo")
- end
-
- it "should return true if it is a metaparam" do
- Puppet::Resource::Type.new(:hostclass, "foo").should be_valid_parameter("require")
- end
-
- it "should return true if the parameter is named 'name'" do
- Puppet::Resource::Type.new(:hostclass, "foo").should be_valid_parameter("name")
- end
-
- it "should return false if it is not a metaparam and was not provided at initialization" do
- Puppet::Resource::Type.new(:hostclass, "foo").should_not be_valid_parameter("yayness")
- end
- end
-
- describe "when creating a subscope" do
- before do
- @scope = stub 'scope', :newscope => nil
- @resource = stub 'resource'
- @type = Puppet::Resource::Type.new(:hostclass, "foo")
- end
+ it "should return true when its name, as a string, is matched against an equal string" do
+ Puppet::Resource::Type.new(:node, "foo").match("foo").should be_true
+ end
- it "should return a new scope created with the provided scope as the parent" do
- @scope.expects(:newscope).returns "foo"
- @type.subscope(@scope, @resource).should == "foo"
- end
+ it "should return false when its name is matched against an unequal string" do
+ Puppet::Resource::Type.new(:node, "foo").match("bar").should be_false
+ end
- it "should set the source as itself" do
- @scope.expects(:newscope).with { |args| args[:source] == @type }
- @type.subscope(@scope, @resource)
- end
+ it "should match names insensitive to case" do
+ Puppet::Resource::Type.new(:node, "fOo").match("foO").should be_true
+ end
+ end
- it "should set the scope's namespace to its namespace" do
- @type.expects(:namespace).returns "yayness"
- @scope.expects(:newscope).with { |args| args[:namespace] == "yayness" }
- @type.subscope(@scope, @resource)
- end
+ it "should return the name converted to a string when the name is not a regex" do
+ pending "Need to define LoadedCode behaviour first"
+ name = Puppet::Parser::AST::HostName.new(:value => "foo")
+ Puppet::Resource::Type.new(:node, name).name.should == "foo"
+ end
- it "should set the scope's resource to the provided resource" do
- @scope.expects(:newscope).with { |args| args[:resource] == @resource }
- @type.subscope(@scope, @resource)
- end
+ it "should return the name converted to a string when the name is a regex" do
+ pending "Need to define LoadedCode behaviour first"
+ name = Puppet::Parser::AST::HostName.new(:value => /regex/)
+ Puppet::Resource::Type.new(:node, name).name.should == /regex/.to_s
end
- describe "when setting its parameters in the scope" do
- before do
- @scope = Puppet::Parser::Scope.new(:compiler => stub("compiler", :environment => Puppet::Node::Environment.new), :source => stub("source"))
- @resource = Puppet::Parser::Resource.new(:foo, "bar", :scope => @scope)
- @type = Puppet::Resource::Type.new(:hostclass, "foo")
- end
+ it "should mark any created scopes as a node scope" do
+ pending "Need to define LoadedCode behaviour first"
+ name = Puppet::Parser::AST::HostName.new(:value => /regex/)
+ Puppet::Resource::Type.new(:node, name).name.should == /regex/.to_s
+ end
+ end
- it "should set each of the resource's parameters as variables in the scope" do
- @type.set_arguments :foo => nil, :boo => nil
- @resource[:foo] = "bar"
- @resource[:boo] = "baz"
+ describe "when initializing" do
+ it "should require a resource super type" do
+ Puppet::Resource::Type.new(:hostclass, "foo").type.should == :hostclass
+ end
- @type.set_resource_parameters(@resource, @scope)
+ it "should fail if provided an invalid resource super type" do
+ lambda { Puppet::Resource::Type.new(:nope, "foo") }.should raise_error(ArgumentError)
+ end
- @scope.lookupvar("foo").should == "bar"
- @scope.lookupvar("boo").should == "baz"
- end
+ it "should set its name to the downcased, stringified provided name" do
+ Puppet::Resource::Type.new(:hostclass, "Foo::Bar".intern).name.should == "foo::bar"
+ end
- it "should set the variables as strings" do
- @type.set_arguments :foo => nil
- @resource[:foo] = "bar"
+ it "should set its namespace to the downcased, stringified qualified name for classes" do
+ Puppet::Resource::Type.new(:hostclass, "Foo::Bar::Baz".intern).namespace.should == "foo::bar::baz"
+ end
- @type.set_resource_parameters(@resource, @scope)
+ [:definition, :node].each do |type|
+ it "should set its namespace to the downcased, stringified qualified portion of the name for #{type}s" do
+ Puppet::Resource::Type.new(type, "Foo::Bar::Baz".intern).namespace.should == "foo::bar"
+ end
+ end
- @scope.lookupvar("foo").should == "bar"
- end
+ %w{code line file doc}.each do |arg|
+ it "should set #{arg} if provided" do
+ type = Puppet::Resource::Type.new(:hostclass, "foo", arg.to_sym => "something")
+ type.send(arg).should == "something"
+ end
+ end
- it "should fail if any of the resource's parameters are not valid attributes" do
- @type.set_arguments :foo => nil
- @resource[:boo] = "baz"
+ it "should set any provided arguments with the keys as symbols" do
+ type = Puppet::Resource::Type.new(:hostclass, "foo", :arguments => {:foo => "bar", :baz => "biz"})
+ type.should be_valid_parameter("foo")
+ type.should be_valid_parameter("baz")
+ end
- lambda { @type.set_resource_parameters(@resource, @scope) }.should raise_error(Puppet::ParseError)
- end
+ it "should set any provided arguments with they keys as strings" do
+ type = Puppet::Resource::Type.new(:hostclass, "foo", :arguments => {"foo" => "bar", "baz" => "biz"})
+ type.should be_valid_parameter(:foo)
+ type.should be_valid_parameter(:baz)
+ end
- it "should evaluate and set its default values as variables for parameters not provided by the resource" do
- @type.set_arguments :foo => stub("value", :safeevaluate => "something")
- @type.set_resource_parameters(@resource, @scope)
- @scope.lookupvar("foo").should == "something"
- end
+ it "should function if provided no arguments" do
+ type = Puppet::Resource::Type.new(:hostclass, "foo")
+ type.should_not be_valid_parameter(:foo)
+ end
+ end
- it "should set all default values as parameters in the resource" do
- @type.set_arguments :foo => stub("value", :safeevaluate => "something")
+ describe "when testing the validity of an attribute" do
+ it "should return true if the parameter was typed at initialization" do
+ Puppet::Resource::Type.new(:hostclass, "foo", :arguments => {"foo" => "bar"}).should be_valid_parameter("foo")
+ end
- @type.set_resource_parameters(@resource, @scope)
+ it "should return true if it is a metaparam" do
+ Puppet::Resource::Type.new(:hostclass, "foo").should be_valid_parameter("require")
+ end
- @resource[:foo].should == "something"
- end
+ it "should return true if the parameter is named 'name'" do
+ Puppet::Resource::Type.new(:hostclass, "foo").should be_valid_parameter("name")
+ end
- it "should fail if the resource does not provide a value for a required argument" do
- @type.set_arguments :foo => nil
- @resource.expects(:to_hash).returns({})
+ it "should return false if it is not a metaparam and was not provided at initialization" do
+ Puppet::Resource::Type.new(:hostclass, "foo").should_not be_valid_parameter("yayness")
+ end
+ end
- lambda { @type.set_resource_parameters(@resource, @scope) }.should raise_error(Puppet::ParseError)
- end
+ describe "when creating a subscope" do
+ before do
+ @scope = stub 'scope', :newscope => nil
+ @resource = stub 'resource'
+ @type = Puppet::Resource::Type.new(:hostclass, "foo")
+ end
+
+ it "should return a new scope created with the provided scope as the parent" do
+ @scope.expects(:newscope).returns "foo"
+ @type.subscope(@scope, @resource).should == "foo"
+ end
- it "should set the resource's title as a variable if not otherwise provided" do
- @type.set_resource_parameters(@resource, @scope)
+ it "should set the source as itself" do
+ @scope.expects(:newscope).with { |args| args[:source] == @type }
+ @type.subscope(@scope, @resource)
+ end
- @scope.lookupvar("title").should == "bar"
- end
+ it "should set the scope's namespace to its namespace" do
+ @type.expects(:namespace).returns "yayness"
+ @scope.expects(:newscope).with { |args| args[:namespace] == "yayness" }
+ @type.subscope(@scope, @resource)
+ end
- it "should set the resource's name as a variable if not otherwise provided" do
- @type.set_resource_parameters(@resource, @scope)
+ it "should set the scope's resource to the provided resource" do
+ @scope.expects(:newscope).with { |args| args[:resource] == @resource }
+ @type.subscope(@scope, @resource)
+ end
+ end
- @scope.lookupvar("name").should == "bar"
- end
+ describe "when setting its parameters in the scope" do
+ before do
+ @scope = Puppet::Parser::Scope.new(:compiler => stub("compiler", :environment => Puppet::Node::Environment.new), :source => stub("source"))
+ @resource = Puppet::Parser::Resource.new(:foo, "bar", :scope => @scope)
+ @type = Puppet::Resource::Type.new(:hostclass, "foo")
+ end
- it "should set its module name in the scope if available" do
- @type.module_name = "mymod"
+ it "should set each of the resource's parameters as variables in the scope" do
+ @type.set_arguments :foo => nil, :boo => nil
+ @resource[:foo] = "bar"
+ @resource[:boo] = "baz"
- @type.set_resource_parameters(@resource, @scope)
+ @type.set_resource_parameters(@resource, @scope)
- @scope.lookupvar("module_name").should == "mymod"
- end
+ @scope.lookupvar("foo").should == "bar"
+ @scope.lookupvar("boo").should == "baz"
+ end
- it "should set its caller module name in the scope if available" do
- @scope.expects(:parent_module_name).returns "mycaller"
+ it "should set the variables as strings" do
+ @type.set_arguments :foo => nil
+ @resource[:foo] = "bar"
- @type.set_resource_parameters(@resource, @scope)
+ @type.set_resource_parameters(@resource, @scope)
- @scope.lookupvar("caller_module_name").should == "mycaller"
- end
+ @scope.lookupvar("foo").should == "bar"
end
- describe "when describing and managing parent classes" do
- before do
- @code = Puppet::Resource::TypeCollection.new("env")
- @parent = Puppet::Resource::Type.new(:hostclass, "bar")
- @code.add @parent
+ it "should fail if any of the resource's parameters are not valid attributes" do
+ @type.set_arguments :foo => nil
+ @resource[:boo] = "baz"
- @child = Puppet::Resource::Type.new(:hostclass, "foo", :parent => "bar")
- @code.add @child
- end
+ lambda { @type.set_resource_parameters(@resource, @scope) }.should raise_error(Puppet::ParseError)
+ end
- it "should be able to define a parent" do
- Puppet::Resource::Type.new(:hostclass, "foo", :parent => "bar")
- end
+ it "should evaluate and set its default values as variables for parameters not provided by the resource" do
+ @type.set_arguments :foo => stub("value", :safeevaluate => "something")
+ @type.set_resource_parameters(@resource, @scope)
+ @scope.lookupvar("foo").should == "something"
+ end
- it "should use the code collection to find the parent resource type" do
- @child.parent_type.should equal(@parent)
- end
+ it "should set all default values as parameters in the resource" do
+ @type.set_arguments :foo => stub("value", :safeevaluate => "something")
- it "should be able to find parent nodes" do
- parent = Puppet::Resource::Type.new(:node, "bar")
- @code.add parent
- child = Puppet::Resource::Type.new(:node, "foo", :parent => "bar")
- @code.add child
+ @type.set_resource_parameters(@resource, @scope)
- child.parent_type.should equal(parent)
- end
+ @resource[:foo].should == "something"
+ end
- it "should cache a reference to the parent type" do
- @code.expects(:hostclass).once.with("bar").returns @parent
- @child.parent_type
- @child.parent_type
- end
+ it "should fail if the resource does not provide a value for a required argument" do
+ @type.set_arguments :foo => nil
+ @resource.expects(:to_hash).returns({})
- it "should correctly state when it is another type's child" do
- @child.should be_child_of(@parent)
- end
+ lambda { @type.set_resource_parameters(@resource, @scope) }.should raise_error(Puppet::ParseError)
+ end
- it "should be considered the child of a parent's parent" do
- @grandchild = Puppet::Resource::Type.new(:hostclass, "baz", :parent => "foo")
- @code.add @grandchild
+ it "should set the resource's title as a variable if not otherwise provided" do
+ @type.set_resource_parameters(@resource, @scope)
- @grandchild.should be_child_of(@parent)
- end
+ @scope.lookupvar("title").should == "bar"
+ end
- it "should correctly state when it is not another type's child" do
- @notchild = Puppet::Resource::Type.new(:hostclass, "baz")
- @code.add @notchild
+ it "should set the resource's name as a variable if not otherwise provided" do
+ @type.set_resource_parameters(@resource, @scope)
- @notchild.should_not be_child_of(@parent)
- end
+ @scope.lookupvar("name").should == "bar"
end
- describe "when evaluating its code" do
- before do
- @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode"))
- @scope = Puppet::Parser::Scope.new :compiler => @compiler
- @resource = Puppet::Parser::Resource.new(:foo, "yay", :scope => @scope)
+ it "should set its module name in the scope if available" do
+ @type.module_name = "mymod"
- # This is so the internal resource lookup works, yo.
- @compiler.catalog.add_resource @resource
+ @type.set_resource_parameters(@resource, @scope)
- @known_resource_types = stub 'known_resource_types'
- @resource.stubs(:known_resource_types).returns @known_resource_types
- @type = Puppet::Resource::Type.new(:hostclass, "foo")
- end
+ @scope.lookupvar("module_name").should == "mymod"
+ end
- it "should set all of its parameters in a subscope" do
- subscope = stub 'subscope', :compiler => @compiler
- @type.expects(:subscope).with(@scope, @resource).returns subscope
- @type.expects(:set_resource_parameters).with(@resource, subscope)
+ it "should set its caller module name in the scope if available" do
+ @scope.expects(:parent_module_name).returns "mycaller"
- @type.evaluate_code(@resource)
- end
+ @type.set_resource_parameters(@resource, @scope)
- it "should not create a subscope for the :main class" do
- @resource.stubs(:title).returns(:main)
- @type.expects(:subscope).never
- @type.expects(:set_resource_parameters).with(@resource, @scope)
+ @scope.lookupvar("caller_module_name").should == "mycaller"
+ end
+ end
- @type.evaluate_code(@resource)
- end
+ describe "when describing and managing parent classes" do
+ before do
+ @code = Puppet::Resource::TypeCollection.new("env")
+ @parent = Puppet::Resource::Type.new(:hostclass, "bar")
+ @code.add @parent
- it "should store the class scope" do
- @type.evaluate_code(@resource)
- @scope.class_scope(@type).should be_instance_of(@scope.class)
- end
+ @child = Puppet::Resource::Type.new(:hostclass, "foo", :parent => "bar")
+ @code.add @child
+ end
- it "should still create a scope but not store it if the type is a definition" do
- @type = Puppet::Resource::Type.new(:definition, "foo")
- @type.evaluate_code(@resource)
- @scope.class_scope(@type).should be_nil
- end
+ it "should be able to define a parent" do
+ Puppet::Resource::Type.new(:hostclass, "foo", :parent => "bar")
+ end
- it "should evaluate the AST code if any is provided" do
- code = stub 'code'
- @type.stubs(:code).returns code
- @type.stubs(:subscope).returns stub_everything("subscope", :compiler => @compiler)
- code.expects(:safeevaluate).with @type.subscope
+ it "should use the code collection to find the parent resource type" do
+ @child.parent_type.should equal(@parent)
+ end
- @type.evaluate_code(@resource)
- end
+ it "should be able to find parent nodes" do
+ parent = Puppet::Resource::Type.new(:node, "bar")
+ @code.add parent
+ child = Puppet::Resource::Type.new(:node, "foo", :parent => "bar")
+ @code.add child
- describe "and ruby code is provided" do
- it "should create a DSL Resource API and evaluate it" do
- @type.stubs(:ruby_code).returns(proc { "foo" })
- @api = stub 'api'
- Puppet::DSL::ResourceAPI.expects(:new).with { |res, scope, code| code == @type.ruby_code }.returns @api
- @api.expects(:evaluate)
+ child.parent_type.should equal(parent)
+ end
- @type.evaluate_code(@resource)
- end
- end
+ it "should cache a reference to the parent type" do
+ @code.expects(:hostclass).once.with("bar").returns @parent
+ @child.parent_type
+ @child.parent_type
+ end
- it "should noop if there is no code" do
- @type.expects(:code).returns nil
+ it "should correctly state when it is another type's child" do
+ @child.should be_child_of(@parent)
+ end
- @type.evaluate_code(@resource)
- end
+ it "should be considered the child of a parent's parent" do
+ @grandchild = Puppet::Resource::Type.new(:hostclass, "baz", :parent => "foo")
+ @code.add @grandchild
- describe "and it has a parent class" do
- before do
- @parent_type = Puppet::Resource::Type.new(:hostclass, "parent")
- @type.parent = "parent"
- @parent_resource = Puppet::Parser::Resource.new(:class, "parent", :scope => @scope)
+ @grandchild.should be_child_of(@parent)
+ end
- @compiler.add_resource @scope, @parent_resource
+ it "should correctly state when it is not another type's child" do
+ @notchild = Puppet::Resource::Type.new(:hostclass, "baz")
+ @code.add @notchild
- @type.resource_type_collection = @scope.known_resource_types
- @type.resource_type_collection.add @parent_type
- end
+ @notchild.should_not be_child_of(@parent)
+ end
+ end
- it "should evaluate the parent's resource" do
- @type.evaluate_code(@resource)
+ describe "when evaluating its code" do
+ before do
+ @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode"))
+ @scope = Puppet::Parser::Scope.new :compiler => @compiler
+ @resource = Puppet::Parser::Resource.new(:foo, "yay", :scope => @scope)
- @scope.class_scope(@parent_type).should_not be_nil
- end
+ # This is so the internal resource lookup works, yo.
+ @compiler.catalog.add_resource @resource
- it "should not evaluate the parent's resource if it has already been evaluated" do
- @parent_resource.evaluate
+ @known_resource_types = stub 'known_resource_types'
+ @resource.stubs(:known_resource_types).returns @known_resource_types
+ @type = Puppet::Resource::Type.new(:hostclass, "foo")
+ end
- @parent_resource.expects(:evaluate).never
+ it "should set all of its parameters in a subscope" do
+ subscope = stub 'subscope', :compiler => @compiler
+ @type.expects(:subscope).with(@scope, @resource).returns subscope
+ @type.expects(:set_resource_parameters).with(@resource, subscope)
- @type.evaluate_code(@resource)
- end
+ @type.evaluate_code(@resource)
+ end
+
+ it "should not create a subscope for the :main class" do
+ @resource.stubs(:title).returns(:main)
+ @type.expects(:subscope).never
+ @type.expects(:set_resource_parameters).with(@resource, @scope)
+
+ @type.evaluate_code(@resource)
+ end
+
+ it "should store the class scope" do
+ @type.evaluate_code(@resource)
+ @scope.class_scope(@type).should be_instance_of(@scope.class)
+ end
+
+ it "should still create a scope but not store it if the type is a definition" do
+ @type = Puppet::Resource::Type.new(:definition, "foo")
+ @type.evaluate_code(@resource)
+ @scope.class_scope(@type).should be_nil
+ end
+
+ it "should evaluate the AST code if any is provided" do
+ code = stub 'code'
+ @type.stubs(:code).returns code
+ @type.stubs(:subscope).returns stub_everything("subscope", :compiler => @compiler)
+ code.expects(:safeevaluate).with @type.subscope
+
+ @type.evaluate_code(@resource)
+ end
+
+ describe "and ruby code is provided" do
+ it "should create a DSL Resource API and evaluate it" do
+ @type.stubs(:ruby_code).returns(proc { "foo" })
+ @api = stub 'api'
+ Puppet::DSL::ResourceAPI.expects(:new).with { |res, scope, code| code == @type.ruby_code }.returns @api
+ @api.expects(:evaluate)
+
+ @type.evaluate_code(@resource)
+ end
+ end
+
+ it "should noop if there is no code" do
+ @type.expects(:code).returns nil
+
+ @type.evaluate_code(@resource)
+ end
+
+ describe "and it has a parent class" do
+ before do
+ @parent_type = Puppet::Resource::Type.new(:hostclass, "parent")
+ @type.parent = "parent"
+ @parent_resource = Puppet::Parser::Resource.new(:class, "parent", :scope => @scope)
+
+ @compiler.add_resource @scope, @parent_resource
+
+ @type.resource_type_collection = @scope.known_resource_types
+ @type.resource_type_collection.add @parent_type
+ end
+
+ it "should evaluate the parent's resource" do
+ @type.evaluate_code(@resource)
+
+ @scope.class_scope(@parent_type).should_not be_nil
+ end
+
+ it "should not evaluate the parent's resource if it has already been evaluated" do
+ @parent_resource.evaluate
+
+ @parent_resource.expects(:evaluate).never
- it "should use the parent's scope as its base scope" do
- @type.evaluate_code(@resource)
+ @type.evaluate_code(@resource)
+ end
- @scope.class_scope(@type).parent.object_id.should == @scope.class_scope(@parent_type).object_id
- end
- end
+ it "should use the parent's scope as its base scope" do
+ @type.evaluate_code(@resource)
- describe "and it has a parent node" do
- before do
- @type = Puppet::Resource::Type.new(:node, "foo")
- @parent_type = Puppet::Resource::Type.new(:node, "parent")
- @type.parent = "parent"
- @parent_resource = Puppet::Parser::Resource.new(:node, "parent", :scope => @scope)
+ @scope.class_scope(@type).parent.object_id.should == @scope.class_scope(@parent_type).object_id
+ end
+ end
+
+ describe "and it has a parent node" do
+ before do
+ @type = Puppet::Resource::Type.new(:node, "foo")
+ @parent_type = Puppet::Resource::Type.new(:node, "parent")
+ @type.parent = "parent"
+ @parent_resource = Puppet::Parser::Resource.new(:node, "parent", :scope => @scope)
- @compiler.add_resource @scope, @parent_resource
+ @compiler.add_resource @scope, @parent_resource
- @type.resource_type_collection = @scope.known_resource_types
- @type.resource_type_collection.stubs(:node).with("parent").returns(@parent_type)
- @type.resource_type_collection.stubs(:node).with("Parent").returns(@parent_type)
- end
+ @type.resource_type_collection = @scope.known_resource_types
+ @type.resource_type_collection.stubs(:node).with("parent").returns(@parent_type)
+ @type.resource_type_collection.stubs(:node).with("Parent").returns(@parent_type)
+ end
- it "should evaluate the parent's resource" do
- @type.evaluate_code(@resource)
+ it "should evaluate the parent's resource" do
+ @type.evaluate_code(@resource)
- @scope.class_scope(@parent_type).should_not be_nil
- end
+ @scope.class_scope(@parent_type).should_not be_nil
+ end
- it "should not evaluate the parent's resource if it has already been evaluated" do
- @parent_resource.evaluate
+ it "should not evaluate the parent's resource if it has already been evaluated" do
+ @parent_resource.evaluate
- @parent_resource.expects(:evaluate).never
+ @parent_resource.expects(:evaluate).never
- @type.evaluate_code(@resource)
- end
+ @type.evaluate_code(@resource)
+ end
- it "should use the parent's scope as its base scope" do
- @type.evaluate_code(@resource)
+ it "should use the parent's scope as its base scope" do
+ @type.evaluate_code(@resource)
- @scope.class_scope(@type).parent.object_id.should == @scope.class_scope(@parent_type).object_id
- end
- end
+ @scope.class_scope(@type).parent.object_id.should == @scope.class_scope(@parent_type).object_id
+ end
end
+ end
- describe "when creating a resource" do
- before do
- @node = Puppet::Node.new("foo")
- @compiler = Puppet::Parser::Compiler.new(@node)
- @scope = Puppet::Parser::Scope.new(:compiler => @compiler)
+ describe "when creating a resource" do
+ before do
+ @node = Puppet::Node.new("foo")
+ @compiler = Puppet::Parser::Compiler.new(@node)
+ @scope = Puppet::Parser::Scope.new(:compiler => @compiler)
- @top = Puppet::Resource::Type.new :hostclass, "top"
- @middle = Puppet::Resource::Type.new :hostclass, "middle", :parent => "top"
+ @top = Puppet::Resource::Type.new :hostclass, "top"
+ @middle = Puppet::Resource::Type.new :hostclass, "middle", :parent => "top"
- @code = Puppet::Resource::TypeCollection.new("env")
- @code.add @top
- @code.add @middle
- end
+ @code = Puppet::Resource::TypeCollection.new("env")
+ @code.add @top
+ @code.add @middle
+ end
- it "should create a resource instance" do
- @top.mk_plain_resource(@scope).should be_instance_of(Puppet::Parser::Resource)
- end
+ it "should create a resource instance" do
+ @top.mk_plain_resource(@scope).should be_instance_of(Puppet::Parser::Resource)
+ end
- it "should set its resource type to 'class' when it is a hostclass" do
- Puppet::Resource::Type.new(:hostclass, "top").mk_plain_resource(@scope).type.should == "Class"
- end
+ it "should set its resource type to 'class' when it is a hostclass" do
+ Puppet::Resource::Type.new(:hostclass, "top").mk_plain_resource(@scope).type.should == "Class"
+ end
- it "should set its resource type to 'node' when it is a node" do
- Puppet::Resource::Type.new(:node, "top").mk_plain_resource(@scope).type.should == "Node"
- end
+ it "should set its resource type to 'node' when it is a node" do
+ Puppet::Resource::Type.new(:node, "top").mk_plain_resource(@scope).type.should == "Node"
+ end
- it "should fail when it is a definition" do
- lambda { Puppet::Resource::Type.new(:definition, "top").mk_plain_resource(@scope) }.should raise_error(ArgumentError)
- end
+ it "should fail when it is a definition" do
+ lambda { Puppet::Resource::Type.new(:definition, "top").mk_plain_resource(@scope) }.should raise_error(ArgumentError)
+ end
- it "should add the created resource to the scope's catalog" do
- @top.mk_plain_resource(@scope)
+ it "should add the created resource to the scope's catalog" do
+ @top.mk_plain_resource(@scope)
- @compiler.catalog.resource(:class, "top").should be_instance_of(Puppet::Parser::Resource)
- end
+ @compiler.catalog.resource(:class, "top").should be_instance_of(Puppet::Parser::Resource)
+ end
- it "should evaluate the parent class if one exists" do
- @middle.mk_plain_resource(@scope)
+ it "should evaluate the parent class if one exists" do
+ @middle.mk_plain_resource(@scope)
- @compiler.catalog.resource(:class, "top").should be_instance_of(Puppet::Parser::Resource)
- end
+ @compiler.catalog.resource(:class, "top").should be_instance_of(Puppet::Parser::Resource)
+ end
- it "should fail to evaluate if a parent class is defined but cannot be found" do
- othertop = Puppet::Resource::Type.new :hostclass, "something", :parent => "yay"
- @code.add othertop
- lambda { othertop.mk_plain_resource(@scope) }.should raise_error(Puppet::ParseError)
- end
+ it "should fail to evaluate if a parent class is defined but cannot be found" do
+ othertop = Puppet::Resource::Type.new :hostclass, "something", :parent => "yay"
+ @code.add othertop
+ lambda { othertop.mk_plain_resource(@scope) }.should raise_error(Puppet::ParseError)
+ end
- it "should not create a new resource if one already exists" do
- @compiler.catalog.expects(:resource).with(:class, "top").returns("something")
- @compiler.catalog.expects(:add_resource).never
- @top.mk_plain_resource(@scope)
- end
+ it "should not create a new resource if one already exists" do
+ @compiler.catalog.expects(:resource).with(:class, "top").returns("something")
+ @compiler.catalog.expects(:add_resource).never
+ @top.mk_plain_resource(@scope)
+ end
- it "should return the existing resource when not creating a new one" do
- @compiler.catalog.expects(:resource).with(:class, "top").returns("something")
- @compiler.catalog.expects(:add_resource).never
- @top.mk_plain_resource(@scope).should == "something"
- end
+ it "should return the existing resource when not creating a new one" do
+ @compiler.catalog.expects(:resource).with(:class, "top").returns("something")
+ @compiler.catalog.expects(:add_resource).never
+ @top.mk_plain_resource(@scope).should == "something"
+ end
- it "should not create a new parent resource if one already exists and it has a parent class" do
- @top.mk_plain_resource(@scope)
+ it "should not create a new parent resource if one already exists and it has a parent class" do
+ @top.mk_plain_resource(@scope)
- top_resource = @compiler.catalog.resource(:class, "top")
+ top_resource = @compiler.catalog.resource(:class, "top")
- @middle.mk_plain_resource(@scope)
+ @middle.mk_plain_resource(@scope)
- @compiler.catalog.resource(:class, "top").should equal(top_resource)
- end
+ @compiler.catalog.resource(:class, "top").should equal(top_resource)
+ end
- # #795 - tag before evaluation.
- it "should tag the catalog with the resource tags when it is evaluated" do
- @middle.mk_plain_resource(@scope)
+ # #795 - tag before evaluation.
+ it "should tag the catalog with the resource tags when it is evaluated" do
+ @middle.mk_plain_resource(@scope)
- @compiler.catalog.should be_tagged("middle")
- end
+ @compiler.catalog.should be_tagged("middle")
+ end
- it "should tag the catalog with the parent class tags when it is evaluated" do
- @middle.mk_plain_resource(@scope)
+ it "should tag the catalog with the parent class tags when it is evaluated" do
+ @middle.mk_plain_resource(@scope)
- @compiler.catalog.should be_tagged("top")
- end
+ @compiler.catalog.should be_tagged("top")
end
+ end
- describe "when merging code from another instance" do
- def code(str)
- Puppet::Parser::AST::Leaf.new :value => str
- end
+ describe "when merging code from another instance" do
+ def code(str)
+ Puppet::Parser::AST::Leaf.new :value => str
+ end
- it "should fail unless it is a class" do
- lambda { Puppet::Resource::Type.new(:node, "bar").merge("foo") }.should raise_error(Puppet::Error)
- end
+ it "should fail unless it is a class" do
+ lambda { Puppet::Resource::Type.new(:node, "bar").merge("foo") }.should raise_error(Puppet::Error)
+ end
- it "should fail unless the source instance is a class" do
- dest = Puppet::Resource::Type.new(:hostclass, "bar")
- source = Puppet::Resource::Type.new(:node, "foo")
- lambda { dest.merge(source) }.should raise_error(Puppet::Error)
- end
+ it "should fail unless the source instance is a class" do
+ dest = Puppet::Resource::Type.new(:hostclass, "bar")
+ source = Puppet::Resource::Type.new(:node, "foo")
+ lambda { dest.merge(source) }.should raise_error(Puppet::Error)
+ end
- it "should fail if both classes have different parent classes" do
- code = Puppet::Resource::TypeCollection.new("env")
- {"a" => "b", "c" => "d"}.each do |parent, child|
- code.add Puppet::Resource::Type.new(:hostclass, parent)
- code.add Puppet::Resource::Type.new(:hostclass, child, :parent => parent)
- end
- lambda { code.hostclass("b").merge(code.hostclass("d")) }.should raise_error(Puppet::Error)
- end
+ it "should fail if both classes have different parent classes" do
+ code = Puppet::Resource::TypeCollection.new("env")
+ {"a" => "b", "c" => "d"}.each do |parent, child|
+ code.add Puppet::Resource::Type.new(:hostclass, parent)
+ code.add Puppet::Resource::Type.new(:hostclass, child, :parent => parent)
+ end
+ lambda { code.hostclass("b").merge(code.hostclass("d")) }.should raise_error(Puppet::Error)
+ end
- it "should fail if it's named 'main' and 'freeze_main' is enabled" do
- Puppet.settings[:freeze_main] = true
- code = Puppet::Resource::TypeCollection.new("env")
- code.add Puppet::Resource::Type.new(:hostclass, "")
- other = Puppet::Resource::Type.new(:hostclass, "")
- lambda { code.hostclass("").merge(other) }.should raise_error(Puppet::Error)
- end
+ it "should fail if it's named 'main' and 'freeze_main' is enabled" do
+ Puppet.settings[:freeze_main] = true
+ code = Puppet::Resource::TypeCollection.new("env")
+ code.add Puppet::Resource::Type.new(:hostclass, "")
+ other = Puppet::Resource::Type.new(:hostclass, "")
+ lambda { code.hostclass("").merge(other) }.should raise_error(Puppet::Error)
+ end
- it "should copy the other class's parent if it has not parent" do
- dest = Puppet::Resource::Type.new(:hostclass, "bar")
+ it "should copy the other class's parent if it has not parent" do
+ dest = Puppet::Resource::Type.new(:hostclass, "bar")
- parent = Puppet::Resource::Type.new(:hostclass, "parent")
- source = Puppet::Resource::Type.new(:hostclass, "foo", :parent => "parent")
- dest.merge(source)
+ parent = Puppet::Resource::Type.new(:hostclass, "parent")
+ source = Puppet::Resource::Type.new(:hostclass, "foo", :parent => "parent")
+ dest.merge(source)
- dest.parent.should == "parent"
- end
+ dest.parent.should == "parent"
+ end
- it "should copy the other class's documentation as its docs if it has no docs" do
- dest = Puppet::Resource::Type.new(:hostclass, "bar")
- source = Puppet::Resource::Type.new(:hostclass, "foo", :doc => "yayness")
- dest.merge(source)
+ it "should copy the other class's documentation as its docs if it has no docs" do
+ dest = Puppet::Resource::Type.new(:hostclass, "bar")
+ source = Puppet::Resource::Type.new(:hostclass, "foo", :doc => "yayness")
+ dest.merge(source)
- dest.doc.should == "yayness"
- end
+ dest.doc.should == "yayness"
+ end
- it "should append the other class's docs to its docs if it has any" do
- dest = Puppet::Resource::Type.new(:hostclass, "bar", :doc => "fooness")
- source = Puppet::Resource::Type.new(:hostclass, "foo", :doc => "yayness")
- dest.merge(source)
+ it "should append the other class's docs to its docs if it has any" do
+ dest = Puppet::Resource::Type.new(:hostclass, "bar", :doc => "fooness")
+ source = Puppet::Resource::Type.new(:hostclass, "foo", :doc => "yayness")
+ dest.merge(source)
- dest.doc.should == "foonessyayness"
- end
+ dest.doc.should == "foonessyayness"
+ end
- it "should turn its code into an ASTArray if necessary" do
- dest = Puppet::Resource::Type.new(:hostclass, "bar", :code => code("foo"))
- source = Puppet::Resource::Type.new(:hostclass, "foo", :code => code("bar"))
+ it "should turn its code into an ASTArray if necessary" do
+ dest = Puppet::Resource::Type.new(:hostclass, "bar", :code => code("foo"))
+ source = Puppet::Resource::Type.new(:hostclass, "foo", :code => code("bar"))
- dest.merge(source)
+ dest.merge(source)
- dest.code.should be_instance_of(Puppet::Parser::AST::ASTArray)
- end
+ dest.code.should be_instance_of(Puppet::Parser::AST::ASTArray)
+ end
- it "should set the other class's code as its code if it has none" do
- dest = Puppet::Resource::Type.new(:hostclass, "bar")
- source = Puppet::Resource::Type.new(:hostclass, "foo", :code => code("bar"))
+ it "should set the other class's code as its code if it has none" do
+ dest = Puppet::Resource::Type.new(:hostclass, "bar")
+ source = Puppet::Resource::Type.new(:hostclass, "foo", :code => code("bar"))
- dest.merge(source)
+ dest.merge(source)
- dest.code.value.should == "bar"
- end
+ dest.code.value.should == "bar"
+ end
- it "should append the other class's code to its code if it has any" do
- dcode = Puppet::Parser::AST::ASTArray.new :children => [code("dest")]
- dest = Puppet::Resource::Type.new(:hostclass, "bar", :code => dcode)
+ it "should append the other class's code to its code if it has any" do
+ dcode = Puppet::Parser::AST::ASTArray.new :children => [code("dest")]
+ dest = Puppet::Resource::Type.new(:hostclass, "bar", :code => dcode)
- scode = Puppet::Parser::AST::ASTArray.new :children => [code("source")]
- source = Puppet::Resource::Type.new(:hostclass, "foo", :code => scode)
+ scode = Puppet::Parser::AST::ASTArray.new :children => [code("source")]
+ source = Puppet::Resource::Type.new(:hostclass, "foo", :code => scode)
- dest.merge(source)
+ dest.merge(source)
- dest.code.children.collect { |l| l.value }.should == %w{dest source}
- end
+ dest.code.children.collect { |l| l.value }.should == %w{dest source}
end
+ end
end
diff --git a/spec/unit/resource_spec.rb b/spec/unit/resource_spec.rb
index 712bc2c..aff3816 100755
--- a/spec/unit/resource_spec.rb
+++ b/spec/unit/resource_spec.rb
@@ -5,801 +5,801 @@ require 'puppet/resource'
describe Puppet::Resource do
- before do
- @basepath = Puppet.features.posix? ? "/somepath" : "C:/somepath"
- end
+ before do
+ @basepath = Puppet.features.posix? ? "/somepath" : "C:/somepath"
+ end
+
+ [:catalog, :file, :line].each do |attr|
+ it "should have an #{attr} attribute" do
+ resource = Puppet::Resource.new("file", "/my/file")
+ resource.should respond_to(attr)
+ resource.should respond_to(attr.to_s + "=")
+ end
+ end
+
+ it "should have a :title attribute" do
+ Puppet::Resource.new(:user, "foo").title.should == "foo"
+ end
+
+ it "should require the type and title" do
+ lambda { Puppet::Resource.new }.should raise_error(ArgumentError)
+ end
+
+ it "should canonize types to capitalized strings" do
+ Puppet::Resource.new(:user, "foo").type.should == "User"
+ end
+
+ it "should canonize qualified types so all strings are capitalized" do
+ Puppet::Resource.new("foo::bar", "foo").type.should == "Foo::Bar"
+ end
+
+ it "should tag itself with its type" do
+ Puppet::Resource.new("file", "/f").should be_tagged("file")
+ end
+
+ it "should tag itself with its title if the title is a valid tag" do
+ Puppet::Resource.new("user", "bar").should be_tagged("bar")
+ end
+
+ it "should not tag itself with its title if the title is a not valid tag" do
+ Puppet::Resource.new("file", "/bar").should_not be_tagged("/bar")
+ end
+
+ it "should allow setting of attributes" do
+ Puppet::Resource.new("file", "/bar", :file => "/foo").file.should == "/foo"
+ Puppet::Resource.new("file", "/bar", :exported => true).should be_exported
+ end
+
+ it "should set its type to 'Class' and its title to the passed title if the passed type is :component and the title has no square brackets in it" do
+ ref = Puppet::Resource.new(:component, "foo")
+ ref.type.should == "Class"
+ ref.title.should == "Foo"
+ end
+
+ it "should interpret the title as a reference and assign appropriately if the type is :component and the title contains square brackets" do
+ ref = Puppet::Resource.new(:component, "foo::bar[yay]")
+ ref.type.should == "Foo::Bar"
+ ref.title.should == "yay"
+ end
+
+ it "should set the type to 'Class' if it is nil and the title contains no square brackets" do
+ ref = Puppet::Resource.new(nil, "yay")
+ ref.type.should == "Class"
+ ref.title.should == "Yay"
+ end
+
+ it "should interpret the title as a reference and assign appropriately if the type is nil and the title contains square brackets" do
+ ref = Puppet::Resource.new(nil, "foo::bar[yay]")
+ ref.type.should == "Foo::Bar"
+ ref.title.should == "yay"
+ end
+
+ it "should interpret the title as a reference and assign appropriately if the type is nil and the title contains nested square brackets" do
+ ref = Puppet::Resource.new(nil, "foo::bar[baz[yay]]")
+ ref.type.should == "Foo::Bar"
+ ref.title.should =="baz[yay]"
+ end
+
+ it "should interpret the type as a reference and assign appropriately if the title is nil and the type contains square brackets" do
+ ref = Puppet::Resource.new("foo::bar[baz]")
+ ref.type.should == "Foo::Bar"
+ ref.title.should =="baz"
+ end
+
+ it "should be able to extract its information from a Puppet::Type instance" do
+ ral = Puppet::Type.type(:file).new :path => @basepath+"/foo"
+ ref = Puppet::Resource.new(ral)
+ ref.type.should == "File"
+ ref.title.should == @basepath+"/foo"
+ end
+
+
+ it "should fail if the title is nil and the type is not a valid resource reference string" do
+ lambda { Puppet::Resource.new("foo") }.should raise_error(ArgumentError)
+ end
+
+ it "should be able to produce a backward-compatible reference array" do
+ Puppet::Resource.new("foobar", "/f").to_trans_ref.should == %w{Foobar /f}
+ end
+
+ it "should be taggable" do
+ Puppet::Resource.ancestors.should be_include(Puppet::Util::Tagging)
+ end
+
+ it "should have an 'exported' attribute" do
+ resource = Puppet::Resource.new("file", "/f")
+ resource.exported = true
+ resource.exported.should == true
+ resource.should be_exported
+ end
+
+ it "should support an environment attribute" do
+ Puppet::Resource.new("file", "/my/file", :environment => :foo).environment.name.should == :foo
+ end
+
+ it "should support specifying namespaces" do
+ Puppet::Resource.new("file", "/my/file", :namespaces => ["foo"]).namespaces.should == ["foo"]
+ end
+
+ it "should convert namespaces to an array if not specified as one" do
+ Puppet::Resource.new("file", "/my/file", :namespaces => "foo").namespaces.should == ["foo"]
+ end
+
+ it "should default to a single amespace of an empty string" do
+ Puppet::Resource.new("file", "/my/file").namespaces.should == [""]
+ end
+
+ describe "and munging its type and title" do
+ describe "when modeling a builtin resource" do
+ it "should be able to find the resource type" do
+ Puppet::Resource.new("file", "/my/file").resource_type.should equal(Puppet::Type.type(:file))
+ end
+
+ it "should set its type to the capitalized type name" do
+ Puppet::Resource.new("file", "/my/file").type.should == "File"
+ end
+ end
+
+ describe "when modeling a defined resource" do
+ describe "that exists" do
+ before do
+ @type = Puppet::Resource::Type.new(:definition, "foo::bar")
+ Puppet::Node::Environment.new.known_resource_types.add @type
+ end
- [:catalog, :file, :line].each do |attr|
- it "should have an #{attr} attribute" do
- resource = Puppet::Resource.new("file", "/my/file")
- resource.should respond_to(attr)
- resource.should respond_to(attr.to_s + "=")
+ it "should set its type to the capitalized type name" do
+ Puppet::Resource.new("foo::bar", "/my/file").type.should == "Foo::Bar"
end
- end
- it "should have a :title attribute" do
- Puppet::Resource.new(:user, "foo").title.should == "foo"
- end
+ it "should be able to find the resource type" do
+ Puppet::Resource.new("foo::bar", "/my/file").resource_type.should equal(@type)
+ end
- it "should require the type and title" do
- lambda { Puppet::Resource.new }.should raise_error(ArgumentError)
- end
+ it "should set its title to the provided title" do
+ Puppet::Resource.new("foo::bar", "/my/file").title.should == "/my/file"
+ end
- it "should canonize types to capitalized strings" do
- Puppet::Resource.new(:user, "foo").type.should == "User"
- end
+ describe "and the resource is unqualified and models a qualified resource type" do
+ it "should set its type to the fully qualified resource type" do
+ Puppet::Resource.new("bar", "/my/file", :namespaces => %w{foo}).type.should == "Foo::Bar"
+ end
- it "should canonize qualified types so all strings are capitalized" do
- Puppet::Resource.new("foo::bar", "foo").type.should == "Foo::Bar"
- end
+ it "should be able to find the resource type" do
+ Puppet::Resource.new("bar", "/my/file", :namespaces => %w{foo}).resource_type.should equal(@type)
+ end
+ end
+ end
- it "should tag itself with its type" do
- Puppet::Resource.new("file", "/f").should be_tagged("file")
+ describe "that does not exist" do
+ it "should set its resource type to the capitalized resource type name" do
+ Puppet::Resource.new("foo::bar", "/my/file").type.should == "Foo::Bar"
+ end
+ end
end
- it "should tag itself with its title if the title is a valid tag" do
- Puppet::Resource.new("user", "bar").should be_tagged("bar")
+ describe "when modeling a node" do
+ # Life's easier with nodes, because they can't be qualified.
+ it "should set its type to 'Node' and its title to the provided title" do
+ node = Puppet::Resource.new("node", "foo")
+ node.type.should == "Node"
+ node.title.should == "foo"
+ end
end
- it "should not tag itself with its title if the title is a not valid tag" do
- Puppet::Resource.new("file", "/bar").should_not be_tagged("/bar")
- end
+ describe "when modeling a class" do
+ it "should set its type to 'Class'" do
+ Puppet::Resource.new("class", "foo").type.should == "Class"
+ end
- it "should allow setting of attributes" do
- Puppet::Resource.new("file", "/bar", :file => "/foo").file.should == "/foo"
- Puppet::Resource.new("file", "/bar", :exported => true).should be_exported
- end
+ describe "that exists" do
+ before do
+ @type = Puppet::Resource::Type.new(:hostclass, "foo::bar")
+ Puppet::Node::Environment.new.known_resource_types.add @type
+ end
- it "should set its type to 'Class' and its title to the passed title if the passed type is :component and the title has no square brackets in it" do
- ref = Puppet::Resource.new(:component, "foo")
- ref.type.should == "Class"
- ref.title.should == "Foo"
- end
+ it "should set its title to the capitalized, fully qualified resource type" do
+ Puppet::Resource.new("class", "foo::bar").title.should == "Foo::Bar"
+ end
- it "should interpret the title as a reference and assign appropriately if the type is :component and the title contains square brackets" do
- ref = Puppet::Resource.new(:component, "foo::bar[yay]")
- ref.type.should == "Foo::Bar"
- ref.title.should == "yay"
- end
+ it "should be able to find the resource type" do
+ Puppet::Resource.new("class", "foo::bar").resource_type.should equal(@type)
+ end
- it "should set the type to 'Class' if it is nil and the title contains no square brackets" do
- ref = Puppet::Resource.new(nil, "yay")
- ref.type.should == "Class"
- ref.title.should == "Yay"
- end
+ describe "and the resource is unqualified and models a qualified class" do
+ it "should set its title to the fully qualified resource type" do
+ Puppet::Resource.new("class", "bar", :namespaces => %w{foo}).title.should == "Foo::Bar"
+ end
- it "should interpret the title as a reference and assign appropriately if the type is nil and the title contains square brackets" do
- ref = Puppet::Resource.new(nil, "foo::bar[yay]")
- ref.type.should == "Foo::Bar"
- ref.title.should == "yay"
- end
+ it "should be able to find the resource type" do
+ Puppet::Resource.new("class", "bar", :namespaces => %w{foo}).resource_type.should equal(@type)
+ end
- it "should interpret the title as a reference and assign appropriately if the type is nil and the title contains nested square brackets" do
- ref = Puppet::Resource.new(nil, "foo::bar[baz[yay]]")
- ref.type.should == "Foo::Bar"
- ref.title.should =="baz[yay]"
- end
+ it "should set its type to 'Class'" do
+ Puppet::Resource.new("class", "bar", :namespaces => %w{foo}).type.should == "Class"
+ end
+ end
+ end
+
+ describe "that does not exist" do
+ it "should set its type to 'Class' and its title to the capitalized provided name" do
+ klass = Puppet::Resource.new("class", "foo::bar")
+ klass.type.should == "Class"
+ klass.title.should == "Foo::Bar"
+ end
+ end
+
+ describe "and its name is set to the empty string" do
+ it "should set its title to :main" do
+ Puppet::Resource.new("class", "").title.should == :main
+ end
+
+ describe "and a class exists whose name is the empty string" do # this was a bit tough to track down
+ it "should set its title to :main" do
+ @type = Puppet::Resource::Type.new(:hostclass, "")
+ Puppet::Node::Environment.new.known_resource_types.add @type
+
+ Puppet::Resource.new("class", "").title.should == :main
+ end
+ end
+ end
- it "should interpret the type as a reference and assign appropriately if the title is nil and the type contains square brackets" do
- ref = Puppet::Resource.new("foo::bar[baz]")
- ref.type.should == "Foo::Bar"
- ref.title.should =="baz"
+ describe "and its name is set to :main" do
+ it "should set its title to :main" do
+ Puppet::Resource.new("class", :main).title.should == :main
+ end
+
+ describe "and a class exists whose name is the empty string" do # this was a bit tough to track down
+ it "should set its title to :main" do
+ @type = Puppet::Resource::Type.new(:hostclass, "")
+ Puppet::Node::Environment.new.known_resource_types.add @type
+
+ Puppet::Resource.new("class", :main).title.should == :main
+ end
+ end
+ end
end
+ end
+
+ it "should return nil when looking up resource types that don't exist" do
+ Puppet::Resource.new("foobar", "bar").resource_type.should be_nil
+ end
+
+ it "should not fail when an invalid parameter is used and strict mode is disabled" do
+ type = Puppet::Resource::Type.new(:definition, "foobar")
+ Puppet::Node::Environment.new.known_resource_types.add type
+ resource = Puppet::Resource.new("foobar", "/my/file")
+ resource[:yay] = true
+ end
+
+ it "should be considered equivalent to another resource if their type and title match and no parameters are set" do
+ Puppet::Resource.new("file", "/f").should == Puppet::Resource.new("file", "/f")
+ end
+
+ it "should be considered equivalent to another resource if their type, title, and parameters are equal" do
+ Puppet::Resource.new("file", "/f", :parameters => {:foo => "bar"}).should == Puppet::Resource.new("file", "/f", :parameters => {:foo => "bar"})
+ end
+
+ it "should not be considered equivalent to another resource if their type and title match but parameters are different" do
+ Puppet::Resource.new("file", "/f", :parameters => {:fee => "baz"}).should_not == Puppet::Resource.new("file", "/f", :parameters => {:foo => "bar"})
+ end
+
+ it "should not be considered equivalent to a non-resource" do
+ Puppet::Resource.new("file", "/f").should_not == "foo"
+ end
+
+ it "should not be considered equivalent to another resource if their types do not match" do
+ Puppet::Resource.new("file", "/f").should_not == Puppet::Resource.new("exec", "/f")
+ end
- it "should be able to extract its information from a Puppet::Type instance" do
- ral = Puppet::Type.type(:file).new :path => @basepath+"/foo"
- ref = Puppet::Resource.new(ral)
- ref.type.should == "File"
- ref.title.should == @basepath+"/foo"
+ it "should not be considered equivalent to another resource if their titles do not match" do
+ Puppet::Resource.new("file", "/foo").should_not == Puppet::Resource.new("file", "/f")
+ end
+
+ describe "when referring to a resource with name canonicalization" do
+ it "should canonicalize its own name" do
+ res = Puppet::Resource.new("file", "/path/")
+ res.uniqueness_key.should == ["/path"]
+ res.ref.should == "File[/path/]"
end
+ end
+ describe "when running in strict mode" do
+ it "should be strict" do
+ Puppet::Resource.new("file", "/path", :strict => true).should be_strict
+ end
- it "should fail if the title is nil and the type is not a valid resource reference string" do
- lambda { Puppet::Resource.new("foo") }.should raise_error(ArgumentError)
+ it "should fail if invalid parameters are used" do
+ lambda { Puppet::Resource.new("file", "/path", :strict => true, :parameters => {:nosuchparam => "bar"}) }.should raise_error
end
- it "should be able to produce a backward-compatible reference array" do
- Puppet::Resource.new("foobar", "/f").to_trans_ref.should == %w{Foobar /f}
+ it "should fail if the resource type cannot be resolved" do
+ lambda { Puppet::Resource.new("nosuchtype", "/path", :strict => true) }.should raise_error
end
+ end
- it "should be taggable" do
- Puppet::Resource.ancestors.should be_include(Puppet::Util::Tagging)
+ describe "when managing parameters" do
+ before do
+ @resource = Puppet::Resource.new("file", "/my/file")
end
- it "should have an 'exported' attribute" do
- resource = Puppet::Resource.new("file", "/f")
- resource.exported = true
- resource.exported.should == true
- resource.should be_exported
+ it "should correctly detect when provided parameters are not valid for builtin types" do
+ Puppet::Resource.new("file", "/my/file").should_not be_valid_parameter("foobar")
end
- it "should support an environment attribute" do
- Puppet::Resource.new("file", "/my/file", :environment => :foo).environment.name.should == :foo
+ it "should correctly detect when provided parameters are valid for builtin types" do
+ Puppet::Resource.new("file", "/my/file").should be_valid_parameter("mode")
end
- it "should support specifying namespaces" do
- Puppet::Resource.new("file", "/my/file", :namespaces => ["foo"]).namespaces.should == ["foo"]
+ it "should correctly detect when provided parameters are not valid for defined resource types" do
+ type = Puppet::Resource::Type.new(:definition, "foobar")
+ Puppet::Node::Environment.new.known_resource_types.add type
+ Puppet::Resource.new("foobar", "/my/file").should_not be_valid_parameter("myparam")
end
- it "should convert namespaces to an array if not specified as one" do
- Puppet::Resource.new("file", "/my/file", :namespaces => "foo").namespaces.should == ["foo"]
+ it "should correctly detect when provided parameters are valid for defined resource types" do
+ type = Puppet::Resource::Type.new(:definition, "foobar", :arguments => {"myparam" => nil})
+ Puppet::Node::Environment.new.known_resource_types.add type
+ Puppet::Resource.new("foobar", "/my/file").should be_valid_parameter("myparam")
end
- it "should default to a single amespace of an empty string" do
- Puppet::Resource.new("file", "/my/file").namespaces.should == [""]
+ it "should allow setting and retrieving of parameters" do
+ @resource[:foo] = "bar"
+ @resource[:foo].should == "bar"
end
- describe "and munging its type and title" do
- describe "when modeling a builtin resource" do
- it "should be able to find the resource type" do
- Puppet::Resource.new("file", "/my/file").resource_type.should equal(Puppet::Type.type(:file))
- end
+ it "should allow setting of parameters at initialization" do
+ Puppet::Resource.new("file", "/my/file", :parameters => {:foo => "bar"})[:foo].should == "bar"
+ end
- it "should set its type to the capitalized type name" do
- Puppet::Resource.new("file", "/my/file").type.should == "File"
- end
- end
+ it "should canonicalize retrieved parameter names to treat symbols and strings equivalently" do
+ @resource[:foo] = "bar"
+ @resource["foo"].should == "bar"
+ end
- describe "when modeling a defined resource" do
- describe "that exists" do
- before do
- @type = Puppet::Resource::Type.new(:definition, "foo::bar")
- Puppet::Node::Environment.new.known_resource_types.add @type
- end
-
- it "should set its type to the capitalized type name" do
- Puppet::Resource.new("foo::bar", "/my/file").type.should == "Foo::Bar"
- end
-
- it "should be able to find the resource type" do
- Puppet::Resource.new("foo::bar", "/my/file").resource_type.should equal(@type)
- end
-
- it "should set its title to the provided title" do
- Puppet::Resource.new("foo::bar", "/my/file").title.should == "/my/file"
- end
-
- describe "and the resource is unqualified and models a qualified resource type" do
- it "should set its type to the fully qualified resource type" do
- Puppet::Resource.new("bar", "/my/file", :namespaces => %w{foo}).type.should == "Foo::Bar"
- end
-
- it "should be able to find the resource type" do
- Puppet::Resource.new("bar", "/my/file", :namespaces => %w{foo}).resource_type.should equal(@type)
- end
- end
- end
-
- describe "that does not exist" do
- it "should set its resource type to the capitalized resource type name" do
- Puppet::Resource.new("foo::bar", "/my/file").type.should == "Foo::Bar"
- end
- end
- end
+ it "should canonicalize set parameter names to treat symbols and strings equivalently" do
+ @resource["foo"] = "bar"
+ @resource[:foo].should == "bar"
+ end
- describe "when modeling a node" do
- # Life's easier with nodes, because they can't be qualified.
- it "should set its type to 'Node' and its title to the provided title" do
- node = Puppet::Resource.new("node", "foo")
- node.type.should == "Node"
- node.title.should == "foo"
- end
- end
+ it "should set the namevar when asked to set the name" do
+ resource = Puppet::Resource.new("user", "bob")
+ Puppet::Type.type(:user).stubs(:key_attributes).returns [:myvar]
+ resource[:name] = "bob"
+ resource[:myvar].should == "bob"
+ end
- describe "when modeling a class" do
- it "should set its type to 'Class'" do
- Puppet::Resource.new("class", "foo").type.should == "Class"
- end
-
- describe "that exists" do
- before do
- @type = Puppet::Resource::Type.new(:hostclass, "foo::bar")
- Puppet::Node::Environment.new.known_resource_types.add @type
- end
-
- it "should set its title to the capitalized, fully qualified resource type" do
- Puppet::Resource.new("class", "foo::bar").title.should == "Foo::Bar"
- end
-
- it "should be able to find the resource type" do
- Puppet::Resource.new("class", "foo::bar").resource_type.should equal(@type)
- end
-
- describe "and the resource is unqualified and models a qualified class" do
- it "should set its title to the fully qualified resource type" do
- Puppet::Resource.new("class", "bar", :namespaces => %w{foo}).title.should == "Foo::Bar"
- end
-
- it "should be able to find the resource type" do
- Puppet::Resource.new("class", "bar", :namespaces => %w{foo}).resource_type.should equal(@type)
- end
-
- it "should set its type to 'Class'" do
- Puppet::Resource.new("class", "bar", :namespaces => %w{foo}).type.should == "Class"
- end
- end
- end
-
- describe "that does not exist" do
- it "should set its type to 'Class' and its title to the capitalized provided name" do
- klass = Puppet::Resource.new("class", "foo::bar")
- klass.type.should == "Class"
- klass.title.should == "Foo::Bar"
- end
- end
-
- describe "and its name is set to the empty string" do
- it "should set its title to :main" do
- Puppet::Resource.new("class", "").title.should == :main
- end
-
- describe "and a class exists whose name is the empty string" do # this was a bit tough to track down
- it "should set its title to :main" do
- @type = Puppet::Resource::Type.new(:hostclass, "")
- Puppet::Node::Environment.new.known_resource_types.add @type
-
- Puppet::Resource.new("class", "").title.should == :main
- end
- end
- end
-
- describe "and its name is set to :main" do
- it "should set its title to :main" do
- Puppet::Resource.new("class", :main).title.should == :main
- end
-
- describe "and a class exists whose name is the empty string" do # this was a bit tough to track down
- it "should set its title to :main" do
- @type = Puppet::Resource::Type.new(:hostclass, "")
- Puppet::Node::Environment.new.known_resource_types.add @type
-
- Puppet::Resource.new("class", :main).title.should == :main
- end
- end
- end
- end
+ it "should return the namevar when asked to return the name" do
+ resource = Puppet::Resource.new("user", "bob")
+ Puppet::Type.type(:user).stubs(:key_attributes).returns [:myvar]
+ resource[:myvar] = "test"
+ resource[:name].should == "test"
end
- it "should return nil when looking up resource types that don't exist" do
- Puppet::Resource.new("foobar", "bar").resource_type.should be_nil
+ it "should be able to set the name for non-builtin types" do
+ resource = Puppet::Resource.new(:foo, "bar")
+ resource[:name] = "eh"
+ lambda { resource[:name] = "eh" }.should_not raise_error
end
- it "should not fail when an invalid parameter is used and strict mode is disabled" do
- type = Puppet::Resource::Type.new(:definition, "foobar")
- Puppet::Node::Environment.new.known_resource_types.add type
- resource = Puppet::Resource.new("foobar", "/my/file")
- resource[:yay] = true
+ it "should be able to return the name for non-builtin types" do
+ resource = Puppet::Resource.new(:foo, "bar")
+ resource[:name] = "eh"
+ resource[:name].should == "eh"
end
- it "should be considered equivalent to another resource if their type and title match and no parameters are set" do
- Puppet::Resource.new("file", "/f").should == Puppet::Resource.new("file", "/f")
+ it "should be able to iterate over parameters" do
+ @resource[:foo] = "bar"
+ @resource[:fee] = "bare"
+ params = {}
+ @resource.each do |key, value|
+ params[key] = value
+ end
+ params.should == {:foo => "bar", :fee => "bare"}
end
- it "should be considered equivalent to another resource if their type, title, and parameters are equal" do
- Puppet::Resource.new("file", "/f", :parameters => {:foo => "bar"}).should == Puppet::Resource.new("file", "/f", :parameters => {:foo => "bar"})
+ it "should include Enumerable" do
+ @resource.class.ancestors.should be_include(Enumerable)
end
- it "should not be considered equivalent to another resource if their type and title match but parameters are different" do
- Puppet::Resource.new("file", "/f", :parameters => {:fee => "baz"}).should_not == Puppet::Resource.new("file", "/f", :parameters => {:foo => "bar"})
+ it "should have a method for testing whether a parameter is included" do
+ @resource[:foo] = "bar"
+ @resource.should be_has_key(:foo)
+ @resource.should_not be_has_key(:eh)
end
- it "should not be considered equivalent to a non-resource" do
- Puppet::Resource.new("file", "/f").should_not == "foo"
+ it "should have a method for providing the list of parameters" do
+ @resource[:foo] = "bar"
+ @resource[:bar] = "foo"
+ keys = @resource.keys
+ keys.should be_include(:foo)
+ keys.should be_include(:bar)
end
- it "should not be considered equivalent to another resource if their types do not match" do
- Puppet::Resource.new("file", "/f").should_not == Puppet::Resource.new("exec", "/f")
+ it "should have a method for providing the number of parameters" do
+ @resource[:foo] = "bar"
+ @resource.length.should == 1
end
- it "should not be considered equivalent to another resource if their titles do not match" do
- Puppet::Resource.new("file", "/foo").should_not == Puppet::Resource.new("file", "/f")
+ it "should have a method for deleting parameters" do
+ @resource[:foo] = "bar"
+ @resource.delete(:foo)
+ @resource[:foo].should be_nil
end
- describe "when referring to a resource with name canonicalization" do
- it "should canonicalize its own name" do
- res = Puppet::Resource.new("file", "/path/")
- res.uniqueness_key.should == ["/path"]
- res.ref.should == "File[/path/]"
- end
+ it "should have a method for testing whether the parameter list is empty" do
+ @resource.should be_empty
+ @resource[:foo] = "bar"
+ @resource.should_not be_empty
end
- describe "when running in strict mode" do
- it "should be strict" do
- Puppet::Resource.new("file", "/path", :strict => true).should be_strict
- end
+ it "should be able to produce a hash of all existing parameters" do
+ @resource[:foo] = "bar"
+ @resource[:fee] = "yay"
- it "should fail if invalid parameters are used" do
- lambda { Puppet::Resource.new("file", "/path", :strict => true, :parameters => {:nosuchparam => "bar"}) }.should raise_error
- end
+ hash = @resource.to_hash
+ hash[:foo].should == "bar"
+ hash[:fee].should == "yay"
+ end
- it "should fail if the resource type cannot be resolved" do
- lambda { Puppet::Resource.new("nosuchtype", "/path", :strict => true) }.should raise_error
- end
+ it "should not provide direct access to the internal parameters hash when producing a hash" do
+ hash = @resource.to_hash
+ hash[:foo] = "bar"
+ @resource[:foo].should be_nil
end
- describe "when managing parameters" do
- before do
- @resource = Puppet::Resource.new("file", "/my/file")
- end
+ it "should use the title as the namevar to the hash if no namevar is present" do
+ resource = Puppet::Resource.new("user", "bob")
+ Puppet::Type.type(:user).stubs(:key_attributes).returns [:myvar]
+ resource.to_hash[:myvar].should == "bob"
+ end
- it "should correctly detect when provided parameters are not valid for builtin types" do
- Puppet::Resource.new("file", "/my/file").should_not be_valid_parameter("foobar")
- end
+ it "should set :name to the title if :name is not present for non-builtin types" do
+ krt = Puppet::Resource::TypeCollection.new("myenv")
+ krt.add Puppet::Resource::Type.new(:definition, :foo)
+ resource = Puppet::Resource.new :foo, "bar"
+ resource.stubs(:known_resource_types).returns krt
+ resource.to_hash[:name].should == "bar"
+ end
+ end
- it "should correctly detect when provided parameters are valid for builtin types" do
- Puppet::Resource.new("file", "/my/file").should be_valid_parameter("mode")
- end
+ describe "when serializing" do
+ before do
+ @resource = Puppet::Resource.new("file", "/my/file")
+ @resource["one"] = "test"
+ @resource["two"] = "other"
+ end
- it "should correctly detect when provided parameters are not valid for defined resource types" do
- type = Puppet::Resource::Type.new(:definition, "foobar")
- Puppet::Node::Environment.new.known_resource_types.add type
- Puppet::Resource.new("foobar", "/my/file").should_not be_valid_parameter("myparam")
- end
+ it "should be able to be dumped to yaml" do
+ proc { YAML.dump(@resource) }.should_not raise_error
+ end
- it "should correctly detect when provided parameters are valid for defined resource types" do
- type = Puppet::Resource::Type.new(:definition, "foobar", :arguments => {"myparam" => nil})
- Puppet::Node::Environment.new.known_resource_types.add type
- Puppet::Resource.new("foobar", "/my/file").should be_valid_parameter("myparam")
- end
+ it "should produce an equivalent yaml object" do
+ text = YAML.dump(@resource)
- it "should allow setting and retrieving of parameters" do
- @resource[:foo] = "bar"
- @resource[:foo].should == "bar"
- end
+ newresource = YAML.load(text)
+ newresource.title.should == @resource.title
+ newresource.type.should == @resource.type
+ %w{one two}.each do |param|
+ newresource[param].should == @resource[param]
+ end
+ end
+ end
- it "should allow setting of parameters at initialization" do
- Puppet::Resource.new("file", "/my/file", :parameters => {:foo => "bar"})[:foo].should == "bar"
- end
+ describe "when converting to a RAL resource" do
+ it "should use the resource type's :new method to create the resource if the resource is of a builtin type" do
+ resource = Puppet::Resource.new("file", @basepath+"/my/file")
+ result = resource.to_ral
+ result.should be_instance_of(Puppet::Type.type(:file))
+ result[:path].should == @basepath+"/my/file"
+ end
- it "should canonicalize retrieved parameter names to treat symbols and strings equivalently" do
- @resource[:foo] = "bar"
- @resource["foo"].should == "bar"
- end
+ it "should convert to a component instance if the resource type is not of a builtin type" do
+ resource = Puppet::Resource.new("foobar", "somename")
+ result = resource.to_ral
- it "should canonicalize set parameter names to treat symbols and strings equivalently" do
- @resource["foo"] = "bar"
- @resource[:foo].should == "bar"
- end
+ result.should be_instance_of(Puppet::Type.type(:component))
+ result.title.should == "Foobar[somename]"
+ end
+ end
- it "should set the namevar when asked to set the name" do
- resource = Puppet::Resource.new("user", "bob")
- Puppet::Type.type(:user).stubs(:key_attributes).returns [:myvar]
- resource[:name] = "bob"
- resource[:myvar].should == "bob"
- end
+ it "should be able to convert itself to Puppet code" do
+ Puppet::Resource.new("one::two", "/my/file").should respond_to(:to_manifest)
+ end
- it "should return the namevar when asked to return the name" do
- resource = Puppet::Resource.new("user", "bob")
- Puppet::Type.type(:user).stubs(:key_attributes).returns [:myvar]
- resource[:myvar] = "test"
- resource[:name].should == "test"
- end
+ describe "when converting to puppet code" do
+ before do
+ @resource = Puppet::Resource.new("one::two", "/my/file", :parameters => {:noop => true, :foo => %w{one two}})
+ end
+
+ it "should print the type and title" do
+ @resource.to_manifest.should be_include("one::two { '/my/file':\n")
+ end
- it "should be able to set the name for non-builtin types" do
- resource = Puppet::Resource.new(:foo, "bar")
- resource[:name] = "eh"
- lambda { resource[:name] = "eh" }.should_not raise_error
- end
+ it "should print each parameter, with the value single-quoted" do
+ @resource.to_manifest.should be_include(" noop => 'true'")
+ end
- it "should be able to return the name for non-builtin types" do
- resource = Puppet::Resource.new(:foo, "bar")
- resource[:name] = "eh"
- resource[:name].should == "eh"
- end
+ it "should print array values appropriately" do
+ @resource.to_manifest.should be_include(" foo => ['one','two']")
+ end
+ end
- it "should be able to iterate over parameters" do
- @resource[:foo] = "bar"
- @resource[:fee] = "bare"
- params = {}
- @resource.each do |key, value|
- params[key] = value
- end
- params.should == {:foo => "bar", :fee => "bare"}
- end
+ it "should be able to convert itself to a TransObject instance" do
+ Puppet::Resource.new("one::two", "/my/file").should respond_to(:to_trans)
+ end
- it "should include Enumerable" do
- @resource.class.ancestors.should be_include(Enumerable)
- end
+ describe "when converting to a TransObject" do
+ describe "and the resource is not an instance of a builtin type" do
+ before do
+ @resource = Puppet::Resource.new("foo", "bar")
+ end
- it "should have a method for testing whether a parameter is included" do
- @resource[:foo] = "bar"
- @resource.should be_has_key(:foo)
- @resource.should_not be_has_key(:eh)
- end
+ it "should return a simple TransBucket if it is not an instance of a builtin type" do
+ bucket = @resource.to_trans
+ bucket.should be_instance_of(Puppet::TransBucket)
+ bucket.type.should == @resource.type
+ bucket.name.should == @resource.title
+ end
- it "should have a method for providing the list of parameters" do
- @resource[:foo] = "bar"
- @resource[:bar] = "foo"
- keys = @resource.keys
- keys.should be_include(:foo)
- keys.should be_include(:bar)
- end
+ it "should return a simple TransBucket if it is a stage" do
+ @resource = Puppet::Resource.new("stage", "bar")
+ bucket = @resource.to_trans
+ bucket.should be_instance_of(Puppet::TransBucket)
+ bucket.type.should == @resource.type
+ bucket.name.should == @resource.title
+ end
- it "should have a method for providing the number of parameters" do
- @resource[:foo] = "bar"
- @resource.length.should == 1
- end
+ it "should copy over the resource's file" do
+ @resource.file = "/foo/bar"
+ @resource.to_trans.file.should == "/foo/bar"
+ end
- it "should have a method for deleting parameters" do
- @resource[:foo] = "bar"
- @resource.delete(:foo)
- @resource[:foo].should be_nil
- end
+ it "should copy over the resource's line" do
+ @resource.line = 50
+ @resource.to_trans.line.should == 50
+ end
+ end
- it "should have a method for testing whether the parameter list is empty" do
- @resource.should be_empty
- @resource[:foo] = "bar"
- @resource.should_not be_empty
- end
+ describe "and the resource is an instance of a builtin type" do
+ before do
+ @resource = Puppet::Resource.new("file", "bar")
+ end
- it "should be able to produce a hash of all existing parameters" do
- @resource[:foo] = "bar"
- @resource[:fee] = "yay"
+ it "should return a TransObject if it is an instance of a builtin resource type" do
+ trans = @resource.to_trans
+ trans.should be_instance_of(Puppet::TransObject)
+ trans.type.should == "file"
+ trans.name.should == @resource.title
+ end
- hash = @resource.to_hash
- hash[:foo].should == "bar"
- hash[:fee].should == "yay"
- end
+ it "should copy over the resource's file" do
+ @resource.file = "/foo/bar"
+ @resource.to_trans.file.should == "/foo/bar"
+ end
- it "should not provide direct access to the internal parameters hash when producing a hash" do
- hash = @resource.to_hash
- hash[:foo] = "bar"
- @resource[:foo].should be_nil
- end
+ it "should copy over the resource's line" do
+ @resource.line = 50
+ @resource.to_trans.line.should == 50
+ end
- it "should use the title as the namevar to the hash if no namevar is present" do
- resource = Puppet::Resource.new("user", "bob")
- Puppet::Type.type(:user).stubs(:key_attributes).returns [:myvar]
- resource.to_hash[:myvar].should == "bob"
- end
+ # Only TransObjects support tags, annoyingly
+ it "should copy over the resource's tags" do
+ @resource.tag "foo"
+ @resource.to_trans.tags.should == @resource.tags
+ end
- it "should set :name to the title if :name is not present for non-builtin types" do
- krt = Puppet::Resource::TypeCollection.new("myenv")
- krt.add Puppet::Resource::Type.new(:definition, :foo)
- resource = Puppet::Resource.new :foo, "bar"
- resource.stubs(:known_resource_types).returns krt
- resource.to_hash[:name].should == "bar"
- end
- end
+ it "should copy the resource's parameters into the transobject and convert the parameter name to a string" do
+ @resource[:foo] = "bar"
+ @resource.to_trans["foo"].should == "bar"
+ end
- describe "when serializing" do
- before do
- @resource = Puppet::Resource.new("file", "/my/file")
- @resource["one"] = "test"
- @resource["two"] = "other"
- end
+ it "should be able to copy arrays of values" do
+ @resource[:foo] = %w{yay fee}
+ @resource.to_trans["foo"].should == %w{yay fee}
+ end
- it "should be able to be dumped to yaml" do
- proc { YAML.dump(@resource) }.should_not raise_error
- end
+ it "should reduce single-value arrays to just a value" do
+ @resource[:foo] = %w{yay}
+ @resource.to_trans["foo"].should == "yay"
+ end
- it "should produce an equivalent yaml object" do
- text = YAML.dump(@resource)
+ it "should convert resource references into the backward-compatible form" do
+ @resource[:foo] = Puppet::Resource.new(:file, "/f")
+ @resource.to_trans["foo"].should == %w{File /f}
+ end
- newresource = YAML.load(text)
- newresource.title.should == @resource.title
- newresource.type.should == @resource.type
- %w{one two}.each do |param|
- newresource[param].should == @resource[param]
- end
- end
+ it "should convert resource references into the backward-compatible form even when within arrays" do
+ @resource[:foo] = ["a", Puppet::Resource.new(:file, "/f")]
+ @resource.to_trans["foo"].should == ["a", %w{File /f}]
+ end
end
+ end
- describe "when converting to a RAL resource" do
- it "should use the resource type's :new method to create the resource if the resource is of a builtin type" do
- resource = Puppet::Resource.new("file", @basepath+"/my/file")
- result = resource.to_ral
- result.should be_instance_of(Puppet::Type.type(:file))
- result[:path].should == @basepath+"/my/file"
- end
-
- it "should convert to a component instance if the resource type is not of a builtin type" do
- resource = Puppet::Resource.new("foobar", "somename")
- result = resource.to_ral
+ describe "when converting to pson" do
+ confine "Missing 'pson' library" => Puppet.features.pson?
- result.should be_instance_of(Puppet::Type.type(:component))
- result.title.should == "Foobar[somename]"
- end
+ def pson_output_should
+ @resource.class.expects(:pson_create).with { |hash| yield hash }
end
- it "should be able to convert itself to Puppet code" do
- Puppet::Resource.new("one::two", "/my/file").should respond_to(:to_manifest)
+ it "should include the pson util module" do
+ Puppet::Resource.singleton_class.ancestors.should be_include(Puppet::Util::Pson)
end
- describe "when converting to puppet code" do
- before do
- @resource = Puppet::Resource.new("one::two", "/my/file", :parameters => {:noop => true, :foo => %w{one two}})
- end
-
- it "should print the type and title" do
- @resource.to_manifest.should be_include("one::two { '/my/file':\n")
- end
+ # LAK:NOTE For all of these tests, we convert back to the resource so we can
+ # trap the actual data structure then.
- it "should print each parameter, with the value single-quoted" do
- @resource.to_manifest.should be_include(" noop => 'true'")
- end
-
- it "should print array values appropriately" do
- @resource.to_manifest.should be_include(" foo => ['one','two']")
- end
+ it "should set its type to the provided type" do
+ Puppet::Resource.from_pson(PSON.parse(Puppet::Resource.new("File", "/foo").to_pson)).type.should == "File"
end
- it "should be able to convert itself to a TransObject instance" do
- Puppet::Resource.new("one::two", "/my/file").should respond_to(:to_trans)
- end
-
- describe "when converting to a TransObject" do
- describe "and the resource is not an instance of a builtin type" do
- before do
- @resource = Puppet::Resource.new("foo", "bar")
- end
-
- it "should return a simple TransBucket if it is not an instance of a builtin type" do
- bucket = @resource.to_trans
- bucket.should be_instance_of(Puppet::TransBucket)
- bucket.type.should == @resource.type
- bucket.name.should == @resource.title
- end
-
- it "should return a simple TransBucket if it is a stage" do
- @resource = Puppet::Resource.new("stage", "bar")
- bucket = @resource.to_trans
- bucket.should be_instance_of(Puppet::TransBucket)
- bucket.type.should == @resource.type
- bucket.name.should == @resource.title
- end
-
- it "should copy over the resource's file" do
- @resource.file = "/foo/bar"
- @resource.to_trans.file.should == "/foo/bar"
- end
-
- it "should copy over the resource's line" do
- @resource.line = 50
- @resource.to_trans.line.should == 50
- end
- end
-
- describe "and the resource is an instance of a builtin type" do
- before do
- @resource = Puppet::Resource.new("file", "bar")
- end
-
- it "should return a TransObject if it is an instance of a builtin resource type" do
- trans = @resource.to_trans
- trans.should be_instance_of(Puppet::TransObject)
- trans.type.should == "file"
- trans.name.should == @resource.title
- end
-
- it "should copy over the resource's file" do
- @resource.file = "/foo/bar"
- @resource.to_trans.file.should == "/foo/bar"
- end
-
- it "should copy over the resource's line" do
- @resource.line = 50
- @resource.to_trans.line.should == 50
- end
-
- # Only TransObjects support tags, annoyingly
- it "should copy over the resource's tags" do
- @resource.tag "foo"
- @resource.to_trans.tags.should == @resource.tags
- end
-
- it "should copy the resource's parameters into the transobject and convert the parameter name to a string" do
- @resource[:foo] = "bar"
- @resource.to_trans["foo"].should == "bar"
- end
-
- it "should be able to copy arrays of values" do
- @resource[:foo] = %w{yay fee}
- @resource.to_trans["foo"].should == %w{yay fee}
- end
-
- it "should reduce single-value arrays to just a value" do
- @resource[:foo] = %w{yay}
- @resource.to_trans["foo"].should == "yay"
- end
-
- it "should convert resource references into the backward-compatible form" do
- @resource[:foo] = Puppet::Resource.new(:file, "/f")
- @resource.to_trans["foo"].should == %w{File /f}
- end
-
- it "should convert resource references into the backward-compatible form even when within arrays" do
- @resource[:foo] = ["a", Puppet::Resource.new(:file, "/f")]
- @resource.to_trans["foo"].should == ["a", %w{File /f}]
- end
- end
+ it "should set its title to the provided title" do
+ Puppet::Resource.from_pson(PSON.parse(Puppet::Resource.new("File", "/foo").to_pson)).title.should == "/foo"
end
- describe "when converting to pson" do
- confine "Missing 'pson' library" => Puppet.features.pson?
-
- def pson_output_should
- @resource.class.expects(:pson_create).with { |hash| yield hash }
- end
-
- it "should include the pson util module" do
- Puppet::Resource.singleton_class.ancestors.should be_include(Puppet::Util::Pson)
- end
-
- # LAK:NOTE For all of these tests, we convert back to the resource so we can
- # trap the actual data structure then.
+ it "should include all tags from the resource" do
+ resource = Puppet::Resource.new("File", "/foo")
+ resource.tag("yay")
- it "should set its type to the provided type" do
- Puppet::Resource.from_pson(PSON.parse(Puppet::Resource.new("File", "/foo").to_pson)).type.should == "File"
- end
-
- it "should set its title to the provided title" do
- Puppet::Resource.from_pson(PSON.parse(Puppet::Resource.new("File", "/foo").to_pson)).title.should == "/foo"
- end
+ Puppet::Resource.from_pson(PSON.parse(resource.to_pson)).tags.should == resource.tags
+ end
- it "should include all tags from the resource" do
- resource = Puppet::Resource.new("File", "/foo")
- resource.tag("yay")
+ it "should include the file if one is set" do
+ resource = Puppet::Resource.new("File", "/foo")
+ resource.file = "/my/file"
- Puppet::Resource.from_pson(PSON.parse(resource.to_pson)).tags.should == resource.tags
- end
+ Puppet::Resource.from_pson(PSON.parse(resource.to_pson)).file.should == "/my/file"
+ end
- it "should include the file if one is set" do
- resource = Puppet::Resource.new("File", "/foo")
- resource.file = "/my/file"
+ it "should include the line if one is set" do
+ resource = Puppet::Resource.new("File", "/foo")
+ resource.line = 50
- Puppet::Resource.from_pson(PSON.parse(resource.to_pson)).file.should == "/my/file"
- end
+ Puppet::Resource.from_pson(PSON.parse(resource.to_pson)).line.should == 50
+ end
- it "should include the line if one is set" do
- resource = Puppet::Resource.new("File", "/foo")
- resource.line = 50
+ it "should include the 'exported' value if one is set" do
+ resource = Puppet::Resource.new("File", "/foo")
+ resource.exported = true
- Puppet::Resource.from_pson(PSON.parse(resource.to_pson)).line.should == 50
- end
+ Puppet::Resource.from_pson(PSON.parse(resource.to_pson)).exported.should be_true
+ end
- it "should include the 'exported' value if one is set" do
- resource = Puppet::Resource.new("File", "/foo")
- resource.exported = true
+ it "should set 'exported' to false if no value is set" do
+ resource = Puppet::Resource.new("File", "/foo")
- Puppet::Resource.from_pson(PSON.parse(resource.to_pson)).exported.should be_true
- end
+ Puppet::Resource.from_pson(PSON.parse(resource.to_pson)).exported.should be_false
+ end
- it "should set 'exported' to false if no value is set" do
- resource = Puppet::Resource.new("File", "/foo")
+ it "should set all of its parameters as the 'parameters' entry" do
+ resource = Puppet::Resource.new("File", "/foo")
+ resource[:foo] = %w{bar eh}
+ resource[:fee] = %w{baz}
- Puppet::Resource.from_pson(PSON.parse(resource.to_pson)).exported.should be_false
- end
+ result = Puppet::Resource.from_pson(PSON.parse(resource.to_pson))
+ result["foo"].should == %w{bar eh}
+ result["fee"].should == %w{baz}
+ end
- it "should set all of its parameters as the 'parameters' entry" do
- resource = Puppet::Resource.new("File", "/foo")
- resource[:foo] = %w{bar eh}
- resource[:fee] = %w{baz}
+ it "should serialize relationships as reference strings" do
+ resource = Puppet::Resource.new("File", "/foo")
+ resource[:requires] = Puppet::Resource.new("File", "/bar")
+ result = Puppet::Resource.from_pson(PSON.parse(resource.to_pson))
+ result[:requires].should == "File[/bar]"
+ end
+ end
- result = Puppet::Resource.from_pson(PSON.parse(resource.to_pson))
- result["foo"].should == %w{bar eh}
- result["fee"].should == %w{baz}
- end
+ describe "when converting from pson" do
+ confine "Missing 'pson' library" => Puppet.features.pson?
- it "should serialize relationships as reference strings" do
- resource = Puppet::Resource.new("File", "/foo")
- resource[:requires] = Puppet::Resource.new("File", "/bar")
- result = Puppet::Resource.from_pson(PSON.parse(resource.to_pson))
- result[:requires].should == "File[/bar]"
- end
+ def pson_result_should
+ Puppet::Resource.expects(:new).with { |hash| yield hash }
end
- describe "when converting from pson" do
- confine "Missing 'pson' library" => Puppet.features.pson?
+ before do
+ @data = {
+ 'type' => "file",
+ 'title' => @basepath+"/yay",
+ }
+ end
- def pson_result_should
- Puppet::Resource.expects(:new).with { |hash| yield hash }
- end
+ it "should set its type to the provided type" do
+ Puppet::Resource.from_pson(@data).type.should == "File"
+ end
- before do
- @data = {
- 'type' => "file",
- 'title' => @basepath+"/yay",
- }
- end
+ it "should set its title to the provided title" do
+ Puppet::Resource.from_pson(@data).title.should == @basepath+"/yay"
+ end
- it "should set its type to the provided type" do
- Puppet::Resource.from_pson(@data).type.should == "File"
- end
+ it "should tag the resource with any provided tags" do
+ @data['tags'] = %w{foo bar}
+ resource = Puppet::Resource.from_pson(@data)
+ resource.tags.should be_include("foo")
+ resource.tags.should be_include("bar")
+ end
- it "should set its title to the provided title" do
- Puppet::Resource.from_pson(@data).title.should == @basepath+"/yay"
- end
+ it "should set its file to the provided file" do
+ @data['file'] = "/foo/bar"
+ Puppet::Resource.from_pson(@data).file.should == "/foo/bar"
+ end
- it "should tag the resource with any provided tags" do
- @data['tags'] = %w{foo bar}
- resource = Puppet::Resource.from_pson(@data)
- resource.tags.should be_include("foo")
- resource.tags.should be_include("bar")
- end
+ it "should set its line to the provided line" do
+ @data['line'] = 50
+ Puppet::Resource.from_pson(@data).line.should == 50
+ end
- it "should set its file to the provided file" do
- @data['file'] = "/foo/bar"
- Puppet::Resource.from_pson(@data).file.should == "/foo/bar"
- end
+ it "should 'exported' to true if set in the pson data" do
+ @data['exported'] = true
+ Puppet::Resource.from_pson(@data).exported.should be_true
+ end
- it "should set its line to the provided line" do
- @data['line'] = 50
- Puppet::Resource.from_pson(@data).line.should == 50
- end
+ it "should 'exported' to false if not set in the pson data" do
+ Puppet::Resource.from_pson(@data).exported.should be_false
+ end
- it "should 'exported' to true if set in the pson data" do
- @data['exported'] = true
- Puppet::Resource.from_pson(@data).exported.should be_true
- end
+ it "should fail if no title is provided" do
+ @data.delete('title')
+ lambda { Puppet::Resource.from_pson(@data) }.should raise_error(ArgumentError)
+ end
- it "should 'exported' to false if not set in the pson data" do
- Puppet::Resource.from_pson(@data).exported.should be_false
- end
+ it "should fail if no type is provided" do
+ @data.delete('type')
+ lambda { Puppet::Resource.from_pson(@data) }.should raise_error(ArgumentError)
+ end
- it "should fail if no title is provided" do
- @data.delete('title')
- lambda { Puppet::Resource.from_pson(@data) }.should raise_error(ArgumentError)
- end
+ it "should set each of the provided parameters" do
+ @data['parameters'] = {'foo' => %w{one two}, 'fee' => %w{three four}}
+ resource = Puppet::Resource.from_pson(@data)
+ resource['foo'].should == %w{one two}
+ resource['fee'].should == %w{three four}
+ end
- it "should fail if no type is provided" do
- @data.delete('type')
- lambda { Puppet::Resource.from_pson(@data) }.should raise_error(ArgumentError)
- end
+ it "should convert single-value array parameters to normal values" do
+ @data['parameters'] = {'foo' => %w{one}}
+ resource = Puppet::Resource.from_pson(@data)
+ resource['foo'].should == %w{one}
+ end
+ end
- it "should set each of the provided parameters" do
- @data['parameters'] = {'foo' => %w{one two}, 'fee' => %w{three four}}
- resource = Puppet::Resource.from_pson(@data)
- resource['foo'].should == %w{one two}
- resource['fee'].should == %w{three four}
- end
+ describe "it should implement to_resource" do
+ resource = Puppet::Resource.new("file", "/my/file")
+ resource.to_resource.should == resource
+ end
- it "should convert single-value array parameters to normal values" do
- @data['parameters'] = {'foo' => %w{one}}
- resource = Puppet::Resource.from_pson(@data)
- resource['foo'].should == %w{one}
- end
+ describe "because it is an indirector model" do
+ it "should include Puppet::Indirector" do
+ Puppet::Resource.should be_is_a(Puppet::Indirector)
end
- describe "it should implement to_resource" do
- resource = Puppet::Resource.new("file", "/my/file")
- resource.to_resource.should == resource
+ it "should have a default terminus" do
+ Puppet::Resource.indirection.terminus_class.should == :ral
end
- describe "because it is an indirector model" do
- it "should include Puppet::Indirector" do
- Puppet::Resource.should be_is_a(Puppet::Indirector)
- end
-
- it "should have a default terminus" do
- Puppet::Resource.indirection.terminus_class.should == :ral
- end
-
- it "should have a name" do
- Puppet::Resource.new("file", "/my/file").name.should == "File//my/file"
- end
+ it "should have a name" do
+ Puppet::Resource.new("file", "/my/file").name.should == "File//my/file"
end
+ end
- describe "when resolving resources with a catalog" do
- it "should resolve all resources using the catalog" do
- catalog = mock 'catalog'
- resource = Puppet::Resource.new("foo::bar", "yay")
- resource.catalog = catalog
+ describe "when resolving resources with a catalog" do
+ it "should resolve all resources using the catalog" do
+ catalog = mock 'catalog'
+ resource = Puppet::Resource.new("foo::bar", "yay")
+ resource.catalog = catalog
- catalog.expects(:resource).with("Foo::Bar[yay]").returns(:myresource)
+ catalog.expects(:resource).with("Foo::Bar[yay]").returns(:myresource)
- resource.resolve.should == :myresource
- end
+ resource.resolve.should == :myresource
end
+ end
- describe "when generating the uniqueness key" do
- it "should include all of the key_attributes in alphabetical order by attribute name" do
- Puppet::Type.type(:file).stubs(:key_attributes).returns [:myvar, :owner, :path]
- Puppet::Type.type(:file).stubs(:title_patterns).returns(
- [ [ /(.*)/, [ [:path, lambda{|x| x} ] ] ] ]
- )
- res = Puppet::Resource.new("file", "/my/file", :parameters => {:owner => 'root', :content => 'hello'})
- res.uniqueness_key.should == [ nil, 'root', '/my/file']
- end
+ describe "when generating the uniqueness key" do
+ it "should include all of the key_attributes in alphabetical order by attribute name" do
+ Puppet::Type.type(:file).stubs(:key_attributes).returns [:myvar, :owner, :path]
+ Puppet::Type.type(:file).stubs(:title_patterns).returns(
+ [ [ /(.*)/, [ [:path, lambda{|x| x} ] ] ] ]
+ )
+ res = Puppet::Resource.new("file", "/my/file", :parameters => {:owner => 'root', :content => 'hello'})
+ res.uniqueness_key.should == [ nil, 'root', '/my/file']
end
+ end
end
diff --git a/spec/unit/run_spec.rb b/spec/unit/run_spec.rb
index 4b654ea..58a16d2 100755
--- a/spec/unit/run_spec.rb
+++ b/spec/unit/run_spec.rb
@@ -5,133 +5,133 @@ require 'puppet/agent'
require 'puppet/run'
describe Puppet::Run do
- before do
- @runner = Puppet::Run.new
- end
+ before do
+ @runner = Puppet::Run.new
+ end
- it "should indirect :run" do
- Puppet::Run.indirection.name.should == :run
- end
+ it "should indirect :run" do
+ Puppet::Run.indirection.name.should == :run
+ end
- it "should use a configurer agent as its agent" do
- agent = mock 'agent'
- Puppet::Agent.expects(:new).with(Puppet::Configurer).returns agent
+ it "should use a configurer agent as its agent" do
+ agent = mock 'agent'
+ Puppet::Agent.expects(:new).with(Puppet::Configurer).returns agent
- @runner.agent.should equal(agent)
- end
+ @runner.agent.should equal(agent)
+ end
- it "should accept options at initialization" do
- lambda { Puppet::Run.new :background => true }.should_not raise_error
- end
+ it "should accept options at initialization" do
+ lambda { Puppet::Run.new :background => true }.should_not raise_error
+ end
- it "should default to running in the foreground" do
- Puppet::Run.new.should_not be_background
- end
+ it "should default to running in the foreground" do
+ Puppet::Run.new.should_not be_background
+ end
- it "should default to its options being an empty hash" do
- Puppet::Run.new.options.should == {}
- end
+ it "should default to its options being an empty hash" do
+ Puppet::Run.new.options.should == {}
+ end
- it "should accept :tags for the agent" do
- Puppet::Run.new(:tags => "foo").options[:tags].should == "foo"
- end
+ it "should accept :tags for the agent" do
+ Puppet::Run.new(:tags => "foo").options[:tags].should == "foo"
+ end
- it "should accept :ignoreschedules for the agent" do
- Puppet::Run.new(:ignoreschedules => true).options[:ignoreschedules].should be_true
- end
+ it "should accept :ignoreschedules for the agent" do
+ Puppet::Run.new(:ignoreschedules => true).options[:ignoreschedules].should be_true
+ end
- it "should accept an option to configure it to run in the background" do
- Puppet::Run.new(:background => true).should be_background
- end
+ it "should accept an option to configure it to run in the background" do
+ Puppet::Run.new(:background => true).should be_background
+ end
- it "should retain the background option" do
- Puppet::Run.new(:background => true).options[:background].should be_nil
- end
+ it "should retain the background option" do
+ Puppet::Run.new(:background => true).options[:background].should be_nil
+ end
- it "should not accept arbitrary options" do
- lambda { Puppet::Run.new(:foo => true) }.should raise_error(ArgumentError)
- end
+ it "should not accept arbitrary options" do
+ lambda { Puppet::Run.new(:foo => true) }.should raise_error(ArgumentError)
+ end
- describe "when asked to run" do
- before do
- @agent = stub 'agent', :run => nil, :running? => false
- @runner.stubs(:agent).returns @agent
- end
+ describe "when asked to run" do
+ before do
+ @agent = stub 'agent', :run => nil, :running? => false
+ @runner.stubs(:agent).returns @agent
+ end
- it "should run its agent" do
- agent = stub 'agent2', :running? => false
- @runner.stubs(:agent).returns agent
+ it "should run its agent" do
+ agent = stub 'agent2', :running? => false
+ @runner.stubs(:agent).returns agent
- agent.expects(:run)
+ agent.expects(:run)
- @runner.run
- end
+ @runner.run
+ end
- it "should pass any of its options on to the agent" do
- @runner.stubs(:options).returns(:foo => :bar)
- @agent.expects(:run).with(:foo => :bar)
+ it "should pass any of its options on to the agent" do
+ @runner.stubs(:options).returns(:foo => :bar)
+ @agent.expects(:run).with(:foo => :bar)
- @runner.run
- end
+ @runner.run
+ end
- it "should log its run using the provided options" do
- @runner.expects(:log_run)
+ it "should log its run using the provided options" do
+ @runner.expects(:log_run)
- @runner.run
- end
+ @runner.run
+ end
- it "should set its status to 'already_running' if the agent is already running" do
- @agent.expects(:running?).returns true
+ it "should set its status to 'already_running' if the agent is already running" do
+ @agent.expects(:running?).returns true
- @runner.run
+ @runner.run
- @runner.status.should == "running"
- end
+ @runner.status.should == "running"
+ end
- it "should set its status to 'success' if the agent is run" do
- @agent.expects(:running?).returns false
+ it "should set its status to 'success' if the agent is run" do
+ @agent.expects(:running?).returns false
- @runner.run
+ @runner.run
- @runner.status.should == "success"
- end
+ @runner.status.should == "success"
+ end
- it "should run the agent in a thread if asked to run it in the background" do
- Thread.expects(:new)
+ it "should run the agent in a thread if asked to run it in the background" do
+ Thread.expects(:new)
- @runner.expects(:background?).returns true
+ @runner.expects(:background?).returns true
- @agent.expects(:run).never # because our thread didn't yield
+ @agent.expects(:run).never # because our thread didn't yield
- @runner.run
- end
+ @runner.run
+ end
- it "should run the agent directly if asked to run it in the foreground" do
- Thread.expects(:new).never
+ it "should run the agent directly if asked to run it in the foreground" do
+ Thread.expects(:new).never
- @runner.expects(:background?).returns false
- @agent.expects(:run)
+ @runner.expects(:background?).returns false
+ @agent.expects(:run)
- @runner.run
- end
+ @runner.run
end
+ end
- describe ".from_pson" do
- it "should accept a hash of options, and pass them with symbolified keys to new" do
- options = {
- "tags" => "whatever",
- "background" => true,
- }
+ describe ".from_pson" do
+ it "should accept a hash of options, and pass them with symbolified keys to new" do
+ options = {
+ "tags" => "whatever",
+ "background" => true,
+ }
- Puppet::Run.expects(:new).with(
- {
- :tags => "whatever",
- :background => true,
+ Puppet::Run.expects(:new).with(
+ {
+ :tags => "whatever",
+ :background => true,
- })
+ })
- Puppet::Run.from_pson(options)
- end
+ Puppet::Run.from_pson(options)
end
+ end
end
diff --git a/spec/unit/simple_graph_spec.rb b/spec/unit/simple_graph_spec.rb
index 234a2fc..83e6741 100755
--- a/spec/unit/simple_graph_spec.rb
+++ b/spec/unit/simple_graph_spec.rb
@@ -7,538 +7,538 @@ require File.dirname(__FILE__) + '/../spec_helper'
require 'puppet/simple_graph'
describe Puppet::SimpleGraph do
- it "should return the number of its vertices as its length" do
- @graph = Puppet::SimpleGraph.new
- @graph.add_vertex("one")
- @graph.add_vertex("two")
- @graph.size.should == 2
+ it "should return the number of its vertices as its length" do
+ @graph = Puppet::SimpleGraph.new
+ @graph.add_vertex("one")
+ @graph.add_vertex("two")
+ @graph.size.should == 2
+ end
+
+ it "should consider itself a directed graph" do
+ Puppet::SimpleGraph.new.directed?.should be_true
+ end
+
+ it "should provide a method for reversing the graph" do
+ @graph = Puppet::SimpleGraph.new
+ @graph.add_edge(:one, :two)
+ @graph.reversal.edge?(:two, :one).should be_true
+ end
+
+ it "should be able to produce a dot graph" do
+ @graph = Puppet::SimpleGraph.new
+ @graph.add_edge(:one, :two)
+
+ proc { @graph.to_dot_graph }.should_not raise_error
+ end
+
+ it "should always put its edges first when printing yaml" do
+ @graph = Puppet::SimpleGraph.new
+ @graph.add_edge(:one, :two)
+ @graph.to_yaml_properties[0].should == "@edges"
+ end
+
+ describe "when managing vertices" do
+ before do
+ @graph = Puppet::SimpleGraph.new
end
- it "should consider itself a directed graph" do
- Puppet::SimpleGraph.new.directed?.should be_true
+ it "should provide a method to add a vertex" do
+ @graph.add_vertex(:test)
+ @graph.vertex?(:test).should be_true
end
- it "should provide a method for reversing the graph" do
- @graph = Puppet::SimpleGraph.new
- @graph.add_edge(:one, :two)
- @graph.reversal.edge?(:two, :one).should be_true
+ it "should reset its reversed graph when vertices are added" do
+ rev = @graph.reversal
+ @graph.add_vertex(:test)
+ @graph.reversal.should_not equal(rev)
end
- it "should be able to produce a dot graph" do
- @graph = Puppet::SimpleGraph.new
- @graph.add_edge(:one, :two)
-
- proc { @graph.to_dot_graph }.should_not raise_error
+ it "should ignore already-present vertices when asked to add a vertex" do
+ @graph.add_vertex(:test)
+ proc { @graph.add_vertex(:test) }.should_not raise_error
end
- it "should always put its edges first when printing yaml" do
- @graph = Puppet::SimpleGraph.new
- @graph.add_edge(:one, :two)
- @graph.to_yaml_properties[0].should == "@edges"
+ it "should return true when asked if a vertex is present" do
+ @graph.add_vertex(:test)
+ @graph.vertex?(:test).should be_true
end
- describe "when managing vertices" do
- before do
- @graph = Puppet::SimpleGraph.new
- end
-
- it "should provide a method to add a vertex" do
- @graph.add_vertex(:test)
- @graph.vertex?(:test).should be_true
- end
-
- it "should reset its reversed graph when vertices are added" do
- rev = @graph.reversal
- @graph.add_vertex(:test)
- @graph.reversal.should_not equal(rev)
- end
-
- it "should ignore already-present vertices when asked to add a vertex" do
- @graph.add_vertex(:test)
- proc { @graph.add_vertex(:test) }.should_not raise_error
- end
-
- it "should return true when asked if a vertex is present" do
- @graph.add_vertex(:test)
- @graph.vertex?(:test).should be_true
- end
-
- it "should return false when asked if a non-vertex is present" do
- @graph.vertex?(:test).should be_false
- end
-
- it "should return all set vertices when asked" do
- @graph.add_vertex(:one)
- @graph.add_vertex(:two)
- @graph.vertices.length.should == 2
- @graph.vertices.should include(:one)
- @graph.vertices.should include(:two)
- end
-
- it "should remove a given vertex when asked" do
- @graph.add_vertex(:one)
- @graph.remove_vertex!(:one)
- @graph.vertex?(:one).should be_false
- end
-
- it "should do nothing when a non-vertex is asked to be removed" do
- proc { @graph.remove_vertex!(:one) }.should_not raise_error
- end
+ it "should return false when asked if a non-vertex is present" do
+ @graph.vertex?(:test).should be_false
end
- describe "when managing edges" do
- before do
- @graph = Puppet::SimpleGraph.new
- end
+ it "should return all set vertices when asked" do
+ @graph.add_vertex(:one)
+ @graph.add_vertex(:two)
+ @graph.vertices.length.should == 2
+ @graph.vertices.should include(:one)
+ @graph.vertices.should include(:two)
+ end
- it "should provide a method to test whether a given vertex pair is an edge" do
- @graph.should respond_to(:edge?)
- end
+ it "should remove a given vertex when asked" do
+ @graph.add_vertex(:one)
+ @graph.remove_vertex!(:one)
+ @graph.vertex?(:one).should be_false
+ end
- it "should reset its reversed graph when edges are added" do
- rev = @graph.reversal
- @graph.add_edge(:one, :two)
- @graph.reversal.should_not equal(rev)
- end
+ it "should do nothing when a non-vertex is asked to be removed" do
+ proc { @graph.remove_vertex!(:one) }.should_not raise_error
+ end
+ end
- it "should provide a method to add an edge as an instance of the edge class" do
- edge = Puppet::Relationship.new(:one, :two)
- @graph.add_edge(edge)
- @graph.edge?(:one, :two).should be_true
- end
+ describe "when managing edges" do
+ before do
+ @graph = Puppet::SimpleGraph.new
+ end
- it "should provide a method to add an edge by specifying the two vertices" do
- @graph.add_edge(:one, :two)
- @graph.edge?(:one, :two).should be_true
- end
+ it "should provide a method to test whether a given vertex pair is an edge" do
+ @graph.should respond_to(:edge?)
+ end
- it "should provide a method to add an edge by specifying the two vertices and a label" do
- @graph.add_edge(:one, :two, :callback => :awesome)
- @graph.edge?(:one, :two).should be_true
- end
+ it "should reset its reversed graph when edges are added" do
+ rev = @graph.reversal
+ @graph.add_edge(:one, :two)
+ @graph.reversal.should_not equal(rev)
+ end
- it "should provide a method for retrieving an edge label" do
- edge = Puppet::Relationship.new(:one, :two, :callback => :awesome)
- @graph.add_edge(edge)
- @graph.edge_label(:one, :two).should == {:callback => :awesome}
- end
+ it "should provide a method to add an edge as an instance of the edge class" do
+ edge = Puppet::Relationship.new(:one, :two)
+ @graph.add_edge(edge)
+ @graph.edge?(:one, :two).should be_true
+ end
- it "should provide a method for retrieving an edge" do
- edge = Puppet::Relationship.new(:one, :two)
- @graph.add_edge(edge)
- @graph.edge(:one, :two).should equal(edge)
- end
+ it "should provide a method to add an edge by specifying the two vertices" do
+ @graph.add_edge(:one, :two)
+ @graph.edge?(:one, :two).should be_true
+ end
- it "should add the edge source as a vertex if it is not already" do
- edge = Puppet::Relationship.new(:one, :two)
- @graph.add_edge(edge)
- @graph.vertex?(:one).should be_true
- end
+ it "should provide a method to add an edge by specifying the two vertices and a label" do
+ @graph.add_edge(:one, :two, :callback => :awesome)
+ @graph.edge?(:one, :two).should be_true
+ end
- it "should add the edge target as a vertex if it is not already" do
- edge = Puppet::Relationship.new(:one, :two)
- @graph.add_edge(edge)
- @graph.vertex?(:two).should be_true
- end
+ it "should provide a method for retrieving an edge label" do
+ edge = Puppet::Relationship.new(:one, :two, :callback => :awesome)
+ @graph.add_edge(edge)
+ @graph.edge_label(:one, :two).should == {:callback => :awesome}
+ end
- it "should return all edges as edge instances when asked" do
- one = Puppet::Relationship.new(:one, :two)
- two = Puppet::Relationship.new(:two, :three)
- @graph.add_edge(one)
- @graph.add_edge(two)
- edges = @graph.edges
- edges.should be_instance_of(Array)
- edges.length.should == 2
- edges.should include(one)
- edges.should include(two)
- end
+ it "should provide a method for retrieving an edge" do
+ edge = Puppet::Relationship.new(:one, :two)
+ @graph.add_edge(edge)
+ @graph.edge(:one, :two).should equal(edge)
+ end
- it "should remove an edge when asked" do
- edge = Puppet::Relationship.new(:one, :two)
- @graph.add_edge(edge)
- @graph.remove_edge!(edge)
- @graph.edge?(edge.source, edge.target).should be_false
- end
+ it "should add the edge source as a vertex if it is not already" do
+ edge = Puppet::Relationship.new(:one, :two)
+ @graph.add_edge(edge)
+ @graph.vertex?(:one).should be_true
+ end
- it "should remove all related edges when a vertex is removed" do
- one = Puppet::Relationship.new(:one, :two)
- two = Puppet::Relationship.new(:two, :three)
- @graph.add_edge(one)
- @graph.add_edge(two)
- @graph.remove_vertex!(:two)
- @graph.edge?(:one, :two).should be_false
- @graph.edge?(:two, :three).should be_false
- @graph.edges.length.should == 0
- end
+ it "should add the edge target as a vertex if it is not already" do
+ edge = Puppet::Relationship.new(:one, :two)
+ @graph.add_edge(edge)
+ @graph.vertex?(:two).should be_true
end
- describe "when finding adjacent vertices" do
- before do
- @graph = Puppet::SimpleGraph.new
- @one_two = Puppet::Relationship.new(:one, :two)
- @two_three = Puppet::Relationship.new(:two, :three)
- @one_three = Puppet::Relationship.new(:one, :three)
- @graph.add_edge(@one_two)
- @graph.add_edge(@one_three)
- @graph.add_edge(@two_three)
- end
+ it "should return all edges as edge instances when asked" do
+ one = Puppet::Relationship.new(:one, :two)
+ two = Puppet::Relationship.new(:two, :three)
+ @graph.add_edge(one)
+ @graph.add_edge(two)
+ edges = @graph.edges
+ edges.should be_instance_of(Array)
+ edges.length.should == 2
+ edges.should include(one)
+ edges.should include(two)
+ end
- it "should return adjacent vertices" do
- adj = @graph.adjacent(:one)
- adj.should be_include(:three)
- adj.should be_include(:two)
- end
+ it "should remove an edge when asked" do
+ edge = Puppet::Relationship.new(:one, :two)
+ @graph.add_edge(edge)
+ @graph.remove_edge!(edge)
+ @graph.edge?(edge.source, edge.target).should be_false
+ end
- it "should default to finding :out vertices" do
- @graph.adjacent(:two).should == [:three]
- end
+ it "should remove all related edges when a vertex is removed" do
+ one = Puppet::Relationship.new(:one, :two)
+ two = Puppet::Relationship.new(:two, :three)
+ @graph.add_edge(one)
+ @graph.add_edge(two)
+ @graph.remove_vertex!(:two)
+ @graph.edge?(:one, :two).should be_false
+ @graph.edge?(:two, :three).should be_false
+ @graph.edges.length.should == 0
+ end
+ end
+
+ describe "when finding adjacent vertices" do
+ before do
+ @graph = Puppet::SimpleGraph.new
+ @one_two = Puppet::Relationship.new(:one, :two)
+ @two_three = Puppet::Relationship.new(:two, :three)
+ @one_three = Puppet::Relationship.new(:one, :three)
+ @graph.add_edge(@one_two)
+ @graph.add_edge(@one_three)
+ @graph.add_edge(@two_three)
+ end
- it "should support selecting :in vertices" do
- @graph.adjacent(:two, :direction => :in).should == [:one]
- end
+ it "should return adjacent vertices" do
+ adj = @graph.adjacent(:one)
+ adj.should be_include(:three)
+ adj.should be_include(:two)
+ end
- it "should default to returning the matching vertices as an array of vertices" do
- @graph.adjacent(:two).should == [:three]
- end
+ it "should default to finding :out vertices" do
+ @graph.adjacent(:two).should == [:three]
+ end
- it "should support returning an array of matching edges" do
- @graph.adjacent(:two, :type => :edges).should == [@two_three]
- end
+ it "should support selecting :in vertices" do
+ @graph.adjacent(:two, :direction => :in).should == [:one]
+ end
- # Bug #2111
- it "should not consider a vertex adjacent just because it was asked about previously" do
- @graph = Puppet::SimpleGraph.new
- @graph.add_vertex("a")
- @graph.add_vertex("b")
- @graph.edge?("a", "b")
- @graph.adjacent("a").should == []
- end
+ it "should default to returning the matching vertices as an array of vertices" do
+ @graph.adjacent(:two).should == [:three]
end
- describe "when clearing" do
- before do
- @graph = Puppet::SimpleGraph.new
- one = Puppet::Relationship.new(:one, :two)
- two = Puppet::Relationship.new(:two, :three)
- @graph.add_edge(one)
- @graph.add_edge(two)
+ it "should support returning an array of matching edges" do
+ @graph.adjacent(:two, :type => :edges).should == [@two_three]
+ end
- @graph.clear
- end
+ # Bug #2111
+ it "should not consider a vertex adjacent just because it was asked about previously" do
+ @graph = Puppet::SimpleGraph.new
+ @graph.add_vertex("a")
+ @graph.add_vertex("b")
+ @graph.edge?("a", "b")
+ @graph.adjacent("a").should == []
+ end
+ end
- it "should remove all vertices" do
- @graph.vertices.should be_empty
- end
+ describe "when clearing" do
+ before do
+ @graph = Puppet::SimpleGraph.new
+ one = Puppet::Relationship.new(:one, :two)
+ two = Puppet::Relationship.new(:two, :three)
+ @graph.add_edge(one)
+ @graph.add_edge(two)
- it "should remove all edges" do
- @graph.edges.should be_empty
- end
+ @graph.clear
end
- describe "when reversing graphs" do
- before do
- @graph = Puppet::SimpleGraph.new
- end
+ it "should remove all vertices" do
+ @graph.vertices.should be_empty
+ end
- it "should provide a method for reversing the graph" do
- @graph.add_edge(:one, :two)
- @graph.reversal.edge?(:two, :one).should be_true
- end
+ it "should remove all edges" do
+ @graph.edges.should be_empty
+ end
+ end
- it "should add all vertices to the reversed graph" do
- @graph.add_edge(:one, :two)
- @graph.vertex?(:one).should be_true
- @graph.vertex?(:two).should be_true
- end
+ describe "when reversing graphs" do
+ before do
+ @graph = Puppet::SimpleGraph.new
+ end
- it "should retain labels on edges" do
- @graph.add_edge(:one, :two, :callback => :awesome)
- edge = @graph.reversal.edge(:two, :one)
- edge.label.should == {:callback => :awesome}
- end
+ it "should provide a method for reversing the graph" do
+ @graph.add_edge(:one, :two)
+ @graph.reversal.edge?(:two, :one).should be_true
end
- describe "when sorting the graph" do
- before do
- @graph = Puppet::SimpleGraph.new
- end
+ it "should add all vertices to the reversed graph" do
+ @graph.add_edge(:one, :two)
+ @graph.vertex?(:one).should be_true
+ @graph.vertex?(:two).should be_true
+ end
- def add_edges(hash)
- hash.each do |a,b|
- @graph.add_edge(a, b)
- end
- end
+ it "should retain labels on edges" do
+ @graph.add_edge(:one, :two, :callback => :awesome)
+ edge = @graph.reversal.edge(:two, :one)
+ edge.label.should == {:callback => :awesome}
+ end
+ end
- it "should sort the graph topologically" do
- add_edges :a => :b, :b => :c
- @graph.topsort.should == [:a, :b, :c]
- end
+ describe "when sorting the graph" do
+ before do
+ @graph = Puppet::SimpleGraph.new
+ end
- it "should fail on two-vertex loops" do
- add_edges :a => :b, :b => :a
- proc { @graph.topsort }.should raise_error(Puppet::Error)
- end
+ def add_edges(hash)
+ hash.each do |a,b|
+ @graph.add_edge(a, b)
+ end
+ end
- it "should fail on multi-vertex loops" do
- add_edges :a => :b, :b => :c, :c => :a
- proc { @graph.topsort }.should raise_error(Puppet::Error)
- end
+ it "should sort the graph topologically" do
+ add_edges :a => :b, :b => :c
+ @graph.topsort.should == [:a, :b, :c]
+ end
- it "should fail when a larger tree contains a small cycle" do
- add_edges :a => :b, :b => :a, :c => :a, :d => :c
- proc { @graph.topsort }.should raise_error(Puppet::Error)
- end
+ it "should fail on two-vertex loops" do
+ add_edges :a => :b, :b => :a
+ proc { @graph.topsort }.should raise_error(Puppet::Error)
+ end
- it "should succeed on trees with no cycles" do
- add_edges :a => :b, :b => :e, :c => :a, :d => :c
- proc { @graph.topsort }.should_not raise_error
- end
+ it "should fail on multi-vertex loops" do
+ add_edges :a => :b, :b => :c, :c => :a
+ proc { @graph.topsort }.should raise_error(Puppet::Error)
+ end
- # Our graph's add_edge method is smart enough not to add
- # duplicate edges, so we use the objects, which it doesn't
- # check.
- it "should be able to sort graphs with duplicate edges" do
- one = Puppet::Relationship.new(:a, :b)
- @graph.add_edge(one)
- two = Puppet::Relationship.new(:a, :b)
- @graph.add_edge(two)
- proc { @graph.topsort }.should_not raise_error
- end
+ it "should fail when a larger tree contains a small cycle" do
+ add_edges :a => :b, :b => :a, :c => :a, :d => :c
+ proc { @graph.topsort }.should raise_error(Puppet::Error)
end
- describe "when writing dot files" do
- before do
- @graph = Puppet::SimpleGraph.new
- @name = :test
- @file = File.join(Puppet[:graphdir], @name.to_s + ".dot")
- end
+ it "should succeed on trees with no cycles" do
+ add_edges :a => :b, :b => :e, :c => :a, :d => :c
+ proc { @graph.topsort }.should_not raise_error
+ end
- it "should only write when graphing is enabled" do
- File.expects(:open).with(@file).never
- Puppet[:graph] = false
- @graph.write_graph(@name)
- end
+ # Our graph's add_edge method is smart enough not to add
+ # duplicate edges, so we use the objects, which it doesn't
+ # check.
+ it "should be able to sort graphs with duplicate edges" do
+ one = Puppet::Relationship.new(:a, :b)
+ @graph.add_edge(one)
+ two = Puppet::Relationship.new(:a, :b)
+ @graph.add_edge(two)
+ proc { @graph.topsort }.should_not raise_error
+ end
+ end
- it "should write a dot file based on the passed name" do
- File.expects(:open).with(@file, "w").yields(stub("file", :puts => nil))
- @graph.expects(:to_dot).with("name" => @name.to_s.capitalize)
- Puppet[:graph] = true
- @graph.write_graph(@name)
- end
+ describe "when writing dot files" do
+ before do
+ @graph = Puppet::SimpleGraph.new
+ @name = :test
+ @file = File.join(Puppet[:graphdir], @name.to_s + ".dot")
+ end
- after do
- Puppet.settings.clear
- end
+ it "should only write when graphing is enabled" do
+ File.expects(:open).with(@file).never
+ Puppet[:graph] = false
+ @graph.write_graph(@name)
end
- describe Puppet::SimpleGraph do
- before do
- @graph = Puppet::SimpleGraph.new
- end
+ it "should write a dot file based on the passed name" do
+ File.expects(:open).with(@file, "w").yields(stub("file", :puts => nil))
+ @graph.expects(:to_dot).with("name" => @name.to_s.capitalize)
+ Puppet[:graph] = true
+ @graph.write_graph(@name)
+ end
- it "should correctly clear vertices and edges when asked" do
- @graph.add_edge("a", "b")
- @graph.add_vertex "c"
- @graph.clear
- @graph.vertices.should be_empty
- @graph.edges.should be_empty
- end
+ after do
+ Puppet.settings.clear
end
+ end
- describe "when matching edges" do
- before do
- @graph = Puppet::SimpleGraph.new
- @event = Puppet::Transaction::Event.new(:name => :yay, :resource => "a")
- @none = Puppet::Transaction::Event.new(:name => :NONE, :resource => "a")
+ describe Puppet::SimpleGraph do
+ before do
+ @graph = Puppet::SimpleGraph.new
+ end
- @edges = {}
- @edges["a/b"] = Puppet::Relationship.new("a", "b", {:event => :yay, :callback => :refresh})
- @edges["a/c"] = Puppet::Relationship.new("a", "c", {:event => :yay, :callback => :refresh})
- @graph.add_edge(@edges["a/b"])
- end
+ it "should correctly clear vertices and edges when asked" do
+ @graph.add_edge("a", "b")
+ @graph.add_vertex "c"
+ @graph.clear
+ @graph.vertices.should be_empty
+ @graph.edges.should be_empty
+ end
+ end
+
+ describe "when matching edges" do
+ before do
+ @graph = Puppet::SimpleGraph.new
+ @event = Puppet::Transaction::Event.new(:name => :yay, :resource => "a")
+ @none = Puppet::Transaction::Event.new(:name => :NONE, :resource => "a")
+
+ @edges = {}
+ @edges["a/b"] = Puppet::Relationship.new("a", "b", {:event => :yay, :callback => :refresh})
+ @edges["a/c"] = Puppet::Relationship.new("a", "c", {:event => :yay, :callback => :refresh})
+ @graph.add_edge(@edges["a/b"])
+ end
- it "should match edges whose source matches the source of the event" do
- @graph.matching_edges(@event).should == [@edges["a/b"]]
- end
+ it "should match edges whose source matches the source of the event" do
+ @graph.matching_edges(@event).should == [@edges["a/b"]]
+ end
- it "should match always match nothing when the event is :NONE" do
- @graph.matching_edges(@none).should be_empty
- end
+ it "should match always match nothing when the event is :NONE" do
+ @graph.matching_edges(@none).should be_empty
+ end
- it "should match multiple edges" do
- @graph.add_edge(@edges["a/c"])
- edges = @graph.matching_edges(@event)
- edges.should be_include(@edges["a/b"])
- edges.should be_include(@edges["a/c"])
- end
+ it "should match multiple edges" do
+ @graph.add_edge(@edges["a/c"])
+ edges = @graph.matching_edges(@event)
+ edges.should be_include(@edges["a/b"])
+ edges.should be_include(@edges["a/c"])
end
+ end
- describe "when determining dependencies" do
- before do
- @graph = Puppet::SimpleGraph.new
+ describe "when determining dependencies" do
+ before do
+ @graph = Puppet::SimpleGraph.new
- @graph.add_edge("a", "b")
- @graph.add_edge("a", "c")
- @graph.add_edge("b", "d")
- end
+ @graph.add_edge("a", "b")
+ @graph.add_edge("a", "c")
+ @graph.add_edge("b", "d")
+ end
- it "should find all dependents when they are on multiple levels" do
- @graph.dependents("a").sort.should == %w{b c d}.sort
- end
+ it "should find all dependents when they are on multiple levels" do
+ @graph.dependents("a").sort.should == %w{b c d}.sort
+ end
- it "should find single dependents" do
- @graph.dependents("b").sort.should == %w{d}.sort
- end
+ it "should find single dependents" do
+ @graph.dependents("b").sort.should == %w{d}.sort
+ end
- it "should return an empty array when there are no dependents" do
- @graph.dependents("c").sort.should == [].sort
- end
+ it "should return an empty array when there are no dependents" do
+ @graph.dependents("c").sort.should == [].sort
+ end
- it "should find all dependencies when they are on multiple levels" do
- @graph.dependencies("d").sort.should == %w{a b}
- end
+ it "should find all dependencies when they are on multiple levels" do
+ @graph.dependencies("d").sort.should == %w{a b}
+ end
- it "should find single dependencies" do
- @graph.dependencies("c").sort.should == %w{a}
- end
+ it "should find single dependencies" do
+ @graph.dependencies("c").sort.should == %w{a}
+ end
- it "should return an empty array when there are no dependencies" do
- @graph.dependencies("a").sort.should == []
- end
+ it "should return an empty array when there are no dependencies" do
+ @graph.dependencies("a").sort.should == []
end
+ end
- require 'puppet/util/graph'
+ require 'puppet/util/graph'
- class Container
- include Puppet::Util::Graph
- include Enumerable
- attr_accessor :name
- def each
- @children.each do |c| yield c end
- end
+ class Container
+ include Puppet::Util::Graph
+ include Enumerable
+ attr_accessor :name
+ def each
+ @children.each do |c| yield c end
+ end
- def initialize(name, ary)
- @name = name
- @children = ary
- end
+ def initialize(name, ary)
+ @name = name
+ @children = ary
+ end
- def push(*ary)
- ary.each { |c| @children.push(c)}
- end
+ def push(*ary)
+ ary.each { |c| @children.push(c)}
+ end
- def to_s
- @name
- end
+ def to_s
+ @name
end
+ end
- describe "when splicing the graph" do
- def container_graph
- @one = Container.new("one", %w{a b})
- @two = Container.new("two", ["c", "d"])
- @three = Container.new("three", ["i", "j"])
- @middle = Container.new("middle", ["e", "f", @two])
- @top = Container.new("top", ["g", "h", @middle, @one, @three])
- @empty = Container.new("empty", [])
+ describe "when splicing the graph" do
+ def container_graph
+ @one = Container.new("one", %w{a b})
+ @two = Container.new("two", ["c", "d"])
+ @three = Container.new("three", ["i", "j"])
+ @middle = Container.new("middle", ["e", "f", @two])
+ @top = Container.new("top", ["g", "h", @middle, @one, @three])
+ @empty = Container.new("empty", [])
- @stage = Puppet::Type.type(:stage).new(:name => "foo")
+ @stage = Puppet::Type.type(:stage).new(:name => "foo")
- @contgraph = @top.to_graph
+ @contgraph = @top.to_graph
- # We have to add the container to the main graph, else it won't
- # be spliced in the dependency graph.
- @contgraph.add_vertex(@empty)
- end
+ # We have to add the container to the main graph, else it won't
+ # be spliced in the dependency graph.
+ @contgraph.add_vertex(@empty)
+ end
- def dependency_graph
- @depgraph = Puppet::SimpleGraph.new
- @contgraph.vertices.each do |v|
- @depgraph.add_vertex(v)
- end
-
- # We have to specify a relationship to our empty container, else it
- # never makes it into the dep graph in the first place.
- {@one => @two, "f" => "c", "h" => @middle, "c" => @empty}.each do |source, target|
- @depgraph.add_edge(source, target, :callback => :refresh)
- end
- end
+ def dependency_graph
+ @depgraph = Puppet::SimpleGraph.new
+ @contgraph.vertices.each do |v|
+ @depgraph.add_vertex(v)
+ end
+
+ # We have to specify a relationship to our empty container, else it
+ # never makes it into the dep graph in the first place.
+ {@one => @two, "f" => "c", "h" => @middle, "c" => @empty}.each do |source, target|
+ @depgraph.add_edge(source, target, :callback => :refresh)
+ end
+ end
- def splice
- @depgraph.splice!(@contgraph, Container)
- end
+ def splice
+ @depgraph.splice!(@contgraph, Container)
+ end
- before do
- container_graph
- dependency_graph
- splice
- end
+ before do
+ container_graph
+ dependency_graph
+ splice
+ end
- # This is the real heart of splicing -- replacing all containers in
- # our relationship and exploding their relationships so that each
- # relationship to a container gets copied to all of its children.
- it "should remove all Container objects from the dependency graph" do
- @depgraph.vertices.find_all { |v| v.is_a?(Container) }.should be_empty
- end
+ # This is the real heart of splicing -- replacing all containers in
+ # our relationship and exploding their relationships so that each
+ # relationship to a container gets copied to all of its children.
+ it "should remove all Container objects from the dependency graph" do
+ @depgraph.vertices.find_all { |v| v.is_a?(Container) }.should be_empty
+ end
- # This is a bit hideous, but required to make stages work with relationships - they're
- # the top of the graph.
- it "should remove all Stage resources from the dependency graph" do
- @depgraph.vertices.find_all { |v| v.is_a?(Puppet::Type.type(:stage)) }.should be_empty
- end
+ # This is a bit hideous, but required to make stages work with relationships - they're
+ # the top of the graph.
+ it "should remove all Stage resources from the dependency graph" do
+ @depgraph.vertices.find_all { |v| v.is_a?(Puppet::Type.type(:stage)) }.should be_empty
+ end
- it "should add container relationships to contained objects" do
- @contgraph.leaves(@middle).each do |leaf|
- @depgraph.should be_edge("h", leaf)
- end
- end
+ it "should add container relationships to contained objects" do
+ @contgraph.leaves(@middle).each do |leaf|
+ @depgraph.should be_edge("h", leaf)
+ end
+ end
- it "should explode container-to-container relationships, making edges between all respective contained objects" do
- @one.each do |oobj|
- @two.each do |tobj|
- @depgraph.should be_edge(oobj, tobj)
- end
- end
+ it "should explode container-to-container relationships, making edges between all respective contained objects" do
+ @one.each do |oobj|
+ @two.each do |tobj|
+ @depgraph.should be_edge(oobj, tobj)
end
+ end
+ end
- it "should no longer contain anything but the non-container objects" do
- @depgraph.vertices.find_all { |v| ! v.is_a?(String) }.should be_empty
- end
+ it "should no longer contain anything but the non-container objects" do
+ @depgraph.vertices.find_all { |v| ! v.is_a?(String) }.should be_empty
+ end
- it "should copy labels" do
- @depgraph.edges.each do |edge|
- edge.label.should == {:callback => :refresh}
- end
- end
+ it "should copy labels" do
+ @depgraph.edges.each do |edge|
+ edge.label.should == {:callback => :refresh}
+ end
+ end
- it "should not add labels to edges that have none" do
- @depgraph.add_edge(@two, @three)
- splice
- @depgraph.edge_label("c", "i").should == {}
- end
+ it "should not add labels to edges that have none" do
+ @depgraph.add_edge(@two, @three)
+ splice
+ @depgraph.edge_label("c", "i").should == {}
+ end
- it "should copy labels over edges that have none" do
- @depgraph.add_edge("c", @three, {:callback => :refresh})
- splice
- # And make sure the label got copied.
- @depgraph.edge_label("c", "i").should == {:callback => :refresh}
- end
+ it "should copy labels over edges that have none" do
+ @depgraph.add_edge("c", @three, {:callback => :refresh})
+ splice
+ # And make sure the label got copied.
+ @depgraph.edge_label("c", "i").should == {:callback => :refresh}
+ end
- it "should not replace a label with a nil label" do
- # Lastly, add some new label-less edges and make sure the label stays.
- @depgraph.add_edge(@middle, @three)
- @depgraph.add_edge("c", @three, {:callback => :refresh})
- splice
- @depgraph.edge_label("c", "i").should == {:callback => :refresh}
- end
+ it "should not replace a label with a nil label" do
+ # Lastly, add some new label-less edges and make sure the label stays.
+ @depgraph.add_edge(@middle, @three)
+ @depgraph.add_edge("c", @three, {:callback => :refresh})
+ splice
+ @depgraph.edge_label("c", "i").should == {:callback => :refresh}
+ end
- it "should copy labels to all created edges" do
- @depgraph.add_edge(@middle, @three)
- @depgraph.add_edge("c", @three, {:callback => :refresh})
- splice
- @three.each do |child|
- edge = Puppet::Relationship.new("c", child)
- @depgraph.should be_edge(edge.source, edge.target)
- @depgraph.edge_label(edge.source, edge.target).should == {:callback => :refresh}
- end
- end
+ it "should copy labels to all created edges" do
+ @depgraph.add_edge(@middle, @three)
+ @depgraph.add_edge("c", @three, {:callback => :refresh})
+ splice
+ @three.each do |child|
+ edge = Puppet::Relationship.new("c", child)
+ @depgraph.should be_edge(edge.source, edge.target)
+ @depgraph.edge_label(edge.source, edge.target).should == {:callback => :refresh}
+ end
end
+ end
end
diff --git a/spec/unit/ssl/base_spec.rb b/spec/unit/ssl/base_spec.rb
index 062ea33..47575fe 100755
--- a/spec/unit/ssl/base_spec.rb
+++ b/spec/unit/ssl/base_spec.rb
@@ -7,37 +7,37 @@ require 'puppet/ssl/certificate'
class TestCertificate < Puppet::SSL::Base; end
describe Puppet::SSL::Certificate do
+ before :each do
+ @base = TestCertificate.new("name")
+ end
+
+ describe "when fingerprinting content" do
before :each do
- @base = TestCertificate.new("name")
+ @cert = stub 'cert', :to_der => "DER"
+ @base.stubs(:content).returns(@cert)
+ OpenSSL::Digest.stubs(:constants).returns ["MD5", "DIGEST"]
+ @digest = stub_everything
+ OpenSSL::Digest.stubs(:const_get).returns @digest
end
- describe "when fingerprinting content" do
- before :each do
- @cert = stub 'cert', :to_der => "DER"
- @base.stubs(:content).returns(@cert)
- OpenSSL::Digest.stubs(:constants).returns ["MD5", "DIGEST"]
- @digest = stub_everything
- OpenSSL::Digest.stubs(:const_get).returns @digest
- end
-
- it "should digest the certificate DER value and return a ':' seperated nibblet string" do
- @cert.expects(:to_der).returns("DER")
- @digest.expects(:hexdigest).with("DER").returns "digest"
+ it "should digest the certificate DER value and return a ':' seperated nibblet string" do
+ @cert.expects(:to_der).returns("DER")
+ @digest.expects(:hexdigest).with("DER").returns "digest"
- @base.fingerprint.should == "DI:GE:ST"
- end
+ @base.fingerprint.should == "DI:GE:ST"
+ end
- it "should raise an error if the digest algorithm is not defined" do
- OpenSSL::Digest.expects(:constants).returns []
+ it "should raise an error if the digest algorithm is not defined" do
+ OpenSSL::Digest.expects(:constants).returns []
- lambda { @base.fingerprint }.should raise_error
- end
+ lambda { @base.fingerprint }.should raise_error
+ end
- it "should use the given digest algorithm" do
- OpenSSL::Digest.stubs(:const_get).with("DIGEST").returns @digest
- @digest.expects(:hexdigest).with("DER").returns "digest"
+ it "should use the given digest algorithm" do
+ OpenSSL::Digest.stubs(:const_get).with("DIGEST").returns @digest
+ @digest.expects(:hexdigest).with("DER").returns "digest"
- @base.fingerprint(:digest).should == "DI:GE:ST"
- end
+ @base.fingerprint(:digest).should == "DI:GE:ST"
end
+ end
end
\ No newline at end of file
diff --git a/spec/unit/ssl/certificate_authority/interface_spec.rb b/spec/unit/ssl/certificate_authority/interface_spec.rb
index 4d76b7e..d8c351a 100755
--- a/spec/unit/ssl/certificate_authority/interface_spec.rb
+++ b/spec/unit/ssl/certificate_authority/interface_spec.rb
@@ -5,329 +5,329 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/ssl/certificate_authority'
describe "a normal interface method", :shared => true do
- it "should call the method on the CA for each host specified if an array was provided" do
- @ca.expects(@method).with("host1")
- @ca.expects(@method).with("host2")
+ it "should call the method on the CA for each host specified if an array was provided" do
+ @ca.expects(@method).with("host1")
+ @ca.expects(@method).with("host2")
- @applier = Puppet::SSL::CertificateAuthority::Interface.new(@method, :to => %w{host1 host2})
+ @applier = Puppet::SSL::CertificateAuthority::Interface.new(@method, :to => %w{host1 host2})
- @applier.apply(@ca)
- end
+ @applier.apply(@ca)
+ end
- it "should call the method on the CA for all existing certificates if :all was provided" do
- @ca.expects(:list).returns %w{host1 host2}
+ it "should call the method on the CA for all existing certificates if :all was provided" do
+ @ca.expects(:list).returns %w{host1 host2}
- @ca.expects(@method).with("host1")
- @ca.expects(@method).with("host2")
+ @ca.expects(@method).with("host1")
+ @ca.expects(@method).with("host2")
- @applier = Puppet::SSL::CertificateAuthority::Interface.new(@method, :to => :all)
+ @applier = Puppet::SSL::CertificateAuthority::Interface.new(@method, :to => :all)
- @applier.apply(@ca)
- end
+ @applier.apply(@ca)
+ end
end
describe Puppet::SSL::CertificateAuthority::Interface do
- before do
- @class = Puppet::SSL::CertificateAuthority::Interface
+ before do
+ @class = Puppet::SSL::CertificateAuthority::Interface
+ end
+ describe "when initializing" do
+ it "should set its method using its settor" do
+ @class.any_instance.expects(:method=).with(:generate)
+ @class.new(:generate, :to => :all)
end
- describe "when initializing" do
- it "should set its method using its settor" do
- @class.any_instance.expects(:method=).with(:generate)
- @class.new(:generate, :to => :all)
- end
- it "should set its subjects using the settor" do
- @class.any_instance.expects(:subjects=).with(:all)
- @class.new(:generate, :to => :all)
- end
+ it "should set its subjects using the settor" do
+ @class.any_instance.expects(:subjects=).with(:all)
+ @class.new(:generate, :to => :all)
+ end
- it "should set the digest if given" do
- interface = @class.new(:generate, :to => :all, :digest => :digest)
- interface.digest.should == :digest
- end
+ it "should set the digest if given" do
+ interface = @class.new(:generate, :to => :all, :digest => :digest)
+ interface.digest.should == :digest
+ end
- it "should set the digest to md5 if none given" do
- interface = @class.new(:generate, :to => :all)
- interface.digest.should == :MD5
- end
+ it "should set the digest to md5 if none given" do
+ interface = @class.new(:generate, :to => :all)
+ interface.digest.should == :MD5
end
+ end
- describe "when setting the method" do
- it "should set the method" do
- @class.new(:generate, :to => :all).method.should == :generate
- end
+ describe "when setting the method" do
+ it "should set the method" do
+ @class.new(:generate, :to => :all).method.should == :generate
+ end
- it "should fail if the method isn't a member of the INTERFACE_METHODS array" do
- Puppet::SSL::CertificateAuthority::Interface::INTERFACE_METHODS.expects(:include?).with(:thing).returns false
+ it "should fail if the method isn't a member of the INTERFACE_METHODS array" do
+ Puppet::SSL::CertificateAuthority::Interface::INTERFACE_METHODS.expects(:include?).with(:thing).returns false
- lambda { @class.new(:thing, :to => :all) }.should raise_error(ArgumentError)
- end
+ lambda { @class.new(:thing, :to => :all) }.should raise_error(ArgumentError)
end
+ end
- describe "when setting the subjects" do
- it "should set the subjects" do
- @class.new(:generate, :to => :all).subjects.should == :all
- end
+ describe "when setting the subjects" do
+ it "should set the subjects" do
+ @class.new(:generate, :to => :all).subjects.should == :all
+ end
- it "should fail if the subjects setting isn't :all or an array" do
- lambda { @class.new(:generate, "other") }.should raise_error(ArgumentError)
- end
+ it "should fail if the subjects setting isn't :all or an array" do
+ lambda { @class.new(:generate, "other") }.should raise_error(ArgumentError)
end
+ end
+
+ it "should have a method for triggering the application" do
+ @class.new(:generate, :to => :all).should respond_to(:apply)
+ end
- it "should have a method for triggering the application" do
- @class.new(:generate, :to => :all).should respond_to(:apply)
+ describe "when applying" do
+ before do
+ # We use a real object here, because :verify can't be stubbed, apparently.
+ @ca = Object.new
end
- describe "when applying" do
- before do
- # We use a real object here, because :verify can't be stubbed, apparently.
- @ca = Object.new
- end
+ it "should raise InterfaceErrors" do
+ @applier = @class.new(:revoke, :to => :all)
- it "should raise InterfaceErrors" do
- @applier = @class.new(:revoke, :to => :all)
+ @ca.expects(:list).raises Puppet::SSL::CertificateAuthority::Interface::InterfaceError
- @ca.expects(:list).raises Puppet::SSL::CertificateAuthority::Interface::InterfaceError
+ lambda { @applier.apply(@ca) }.should raise_error(Puppet::SSL::CertificateAuthority::Interface::InterfaceError)
+ end
- lambda { @applier.apply(@ca) }.should raise_error(Puppet::SSL::CertificateAuthority::Interface::InterfaceError)
- end
+ it "should log non-Interface failures rather than failing" do
+ @applier = @class.new(:revoke, :to => :all)
- it "should log non-Interface failures rather than failing" do
- @applier = @class.new(:revoke, :to => :all)
+ @ca.expects(:list).raises ArgumentError
- @ca.expects(:list).raises ArgumentError
+ Puppet.expects(:err)
- Puppet.expects(:err)
+ lambda { @applier.apply(@ca) }.should_not raise_error
+ end
- lambda { @applier.apply(@ca) }.should_not raise_error
- end
+ describe "with an empty array specified and the method is not list" do
+ it "should fail" do
+ @applier = @class.new(:sign, :to => [])
+ lambda { @applier.apply(@ca) }.should raise_error(ArgumentError)
+ end
+ end
- describe "with an empty array specified and the method is not list" do
- it "should fail" do
- @applier = @class.new(:sign, :to => [])
- lambda { @applier.apply(@ca) }.should raise_error(ArgumentError)
- end
- end
+ describe ":generate" do
+ it "should fail if :all was specified" do
+ @applier = @class.new(:generate, :to => :all)
+ lambda { @applier.apply(@ca) }.should raise_error(ArgumentError)
+ end
- describe ":generate" do
- it "should fail if :all was specified" do
- @applier = @class.new(:generate, :to => :all)
- lambda { @applier.apply(@ca) }.should raise_error(ArgumentError)
- end
+ it "should call :generate on the CA for each host specified" do
+ @applier = @class.new(:generate, :to => %w{host1 host2})
- it "should call :generate on the CA for each host specified" do
- @applier = @class.new(:generate, :to => %w{host1 host2})
+ @ca.expects(:generate).with("host1")
+ @ca.expects(:generate).with("host2")
- @ca.expects(:generate).with("host1")
- @ca.expects(:generate).with("host2")
+ @applier.apply(@ca)
+ end
+ end
- @applier.apply(@ca)
- end
- end
+ describe ":verify" do
+ before { @method = :verify }
+ #it_should_behave_like "a normal interface method"
- describe ":verify" do
- before { @method = :verify }
- #it_should_behave_like "a normal interface method"
+ it "should call the method on the CA for each host specified if an array was provided" do
+ # LAK:NOTE Mocha apparently doesn't allow you to mock :verify, but I'm confident this works in real life.
+ end
- it "should call the method on the CA for each host specified if an array was provided" do
- # LAK:NOTE Mocha apparently doesn't allow you to mock :verify, but I'm confident this works in real life.
- end
+ it "should call the method on the CA for all existing certificates if :all was provided" do
+ # LAK:NOTE Mocha apparently doesn't allow you to mock :verify, but I'm confident this works in real life.
+ end
+ end
- it "should call the method on the CA for all existing certificates if :all was provided" do
- # LAK:NOTE Mocha apparently doesn't allow you to mock :verify, but I'm confident this works in real life.
- end
- end
+ describe ":destroy" do
+ before { @method = :destroy }
+ it_should_behave_like "a normal interface method"
+ end
- describe ":destroy" do
- before { @method = :destroy }
- it_should_behave_like "a normal interface method"
- end
+ describe ":revoke" do
+ before { @method = :revoke }
+ it_should_behave_like "a normal interface method"
+ end
- describe ":revoke" do
- before { @method = :revoke }
- it_should_behave_like "a normal interface method"
+ describe ":sign" do
+ describe "and an array of names was provided" do
+ before do
+ @applier = @class.new(:sign, :to => %w{host1 host2})
end
- describe ":sign" do
- describe "and an array of names was provided" do
- before do
- @applier = @class.new(:sign, :to => %w{host1 host2})
- end
-
- it "should sign the specified waiting certificate requests" do
- @ca.expects(:sign).with("host1")
- @ca.expects(:sign).with("host2")
+ it "should sign the specified waiting certificate requests" do
+ @ca.expects(:sign).with("host1")
+ @ca.expects(:sign).with("host2")
- @applier.apply(@ca)
- end
- end
+ @applier.apply(@ca)
+ end
+ end
- describe "and :all was provided" do
- it "should sign all waiting certificate requests" do
- @ca.stubs(:waiting?).returns(%w{cert1 cert2})
+ describe "and :all was provided" do
+ it "should sign all waiting certificate requests" do
+ @ca.stubs(:waiting?).returns(%w{cert1 cert2})
- @ca.expects(:sign).with("cert1")
- @ca.expects(:sign).with("cert2")
+ @ca.expects(:sign).with("cert1")
+ @ca.expects(:sign).with("cert2")
- @applier = @class.new(:sign, :to => :all)
- @applier.apply(@ca)
- end
+ @applier = @class.new(:sign, :to => :all)
+ @applier.apply(@ca)
+ end
- it "should fail if there are no waiting certificate requests" do
- @ca.stubs(:waiting?).returns([])
+ it "should fail if there are no waiting certificate requests" do
+ @ca.stubs(:waiting?).returns([])
- @applier = @class.new(:sign, :to => :all)
- lambda { @applier.apply(@ca) }.should raise_error(Puppet::SSL::CertificateAuthority::Interface::InterfaceError)
- end
- end
+ @applier = @class.new(:sign, :to => :all)
+ lambda { @applier.apply(@ca) }.should raise_error(Puppet::SSL::CertificateAuthority::Interface::InterfaceError)
end
+ end
+ end
- describe ":list" do
- describe "and an empty array was provided" do
- it "should print a string containing all certificate requests" do
- @ca.expects(:waiting?).returns %w{host1 host2}
- @ca.stubs(:verify)
+ describe ":list" do
+ describe "and an empty array was provided" do
+ it "should print a string containing all certificate requests" do
+ @ca.expects(:waiting?).returns %w{host1 host2}
+ @ca.stubs(:verify)
- @applier = @class.new(:list, :to => [])
+ @applier = @class.new(:list, :to => [])
- @applier.expects(:puts).with "host1\nhost2"
+ @applier.expects(:puts).with "host1\nhost2"
- @applier.apply(@ca)
- end
- end
+ @applier.apply(@ca)
+ end
+ end
- describe "and :all was provided" do
- it "should print a string containing all certificate requests and certificates" do
- @ca.expects(:waiting?).returns %w{host1 host2}
- @ca.expects(:list).returns %w{host3 host4}
- @ca.stubs(:verify)
- @ca.stubs(:fingerprint).returns "fingerprint"
- @ca.expects(:verify).with("host3").raises(Puppet::SSL::CertificateAuthority::CertificateVerificationError.new(23), "certificate revoked")
+ describe "and :all was provided" do
+ it "should print a string containing all certificate requests and certificates" do
+ @ca.expects(:waiting?).returns %w{host1 host2}
+ @ca.expects(:list).returns %w{host3 host4}
+ @ca.stubs(:verify)
+ @ca.stubs(:fingerprint).returns "fingerprint"
+ @ca.expects(:verify).with("host3").raises(Puppet::SSL::CertificateAuthority::CertificateVerificationError.new(23), "certificate revoked")
- @applier = @class.new(:list, :to => :all)
+ @applier = @class.new(:list, :to => :all)
- @applier.expects(:puts).with "host1 (fingerprint)"
- @applier.expects(:puts).with "host2 (fingerprint)"
- @applier.expects(:puts).with "- host3 (fingerprint) (certificate revoked)"
- @applier.expects(:puts).with "+ host4 (fingerprint)"
+ @applier.expects(:puts).with "host1 (fingerprint)"
+ @applier.expects(:puts).with "host2 (fingerprint)"
+ @applier.expects(:puts).with "- host3 (fingerprint) (certificate revoked)"
+ @applier.expects(:puts).with "+ host4 (fingerprint)"
- @applier.apply(@ca)
- end
- end
+ @applier.apply(@ca)
+ end
+ end
- describe "and :signed was provided" do
- it "should print a string containing all signed certificate requests and certificates" do
- @ca.expects(:list).returns %w{host1 host2}
+ describe "and :signed was provided" do
+ it "should print a string containing all signed certificate requests and certificates" do
+ @ca.expects(:list).returns %w{host1 host2}
- @applier = @class.new(:list, :to => :signed)
+ @applier = @class.new(:list, :to => :signed)
- @applier.apply(@ca)
- end
- end
+ @applier.apply(@ca)
+ end
+ end
- describe "and an array of names was provided" do
- it "should print a string of all named hosts that have a waiting request" do
- @ca.expects(:waiting?).returns %w{host1 host2}
- @ca.expects(:list).returns %w{host3 host4}
- @ca.stubs(:fingerprint).returns "fingerprint"
- @ca.stubs(:verify)
+ describe "and an array of names was provided" do
+ it "should print a string of all named hosts that have a waiting request" do
+ @ca.expects(:waiting?).returns %w{host1 host2}
+ @ca.expects(:list).returns %w{host3 host4}
+ @ca.stubs(:fingerprint).returns "fingerprint"
+ @ca.stubs(:verify)
- @applier = @class.new(:list, :to => %w{host1 host2 host3 host4})
+ @applier = @class.new(:list, :to => %w{host1 host2 host3 host4})
- @applier.expects(:puts).with "host1 (fingerprint)"
- @applier.expects(:puts).with "host2 (fingerprint)"
- @applier.expects(:puts).with "+ host3 (fingerprint)"
- @applier.expects(:puts).with "+ host4 (fingerprint)"
+ @applier.expects(:puts).with "host1 (fingerprint)"
+ @applier.expects(:puts).with "host2 (fingerprint)"
+ @applier.expects(:puts).with "+ host3 (fingerprint)"
+ @applier.expects(:puts).with "+ host4 (fingerprint)"
- @applier.apply(@ca)
- end
- end
+ @applier.apply(@ca)
end
+ end
+ end
- describe ":print" do
- describe "and :all was provided" do
- it "should print all certificates" do
- @ca.expects(:list).returns %w{host1 host2}
+ describe ":print" do
+ describe "and :all was provided" do
+ it "should print all certificates" do
+ @ca.expects(:list).returns %w{host1 host2}
- @applier = @class.new(:print, :to => :all)
+ @applier = @class.new(:print, :to => :all)
- @ca.expects(:print).with("host1").returns "h1"
- @applier.expects(:puts).with "h1"
+ @ca.expects(:print).with("host1").returns "h1"
+ @applier.expects(:puts).with "h1"
- @ca.expects(:print).with("host2").returns "h2"
- @applier.expects(:puts).with "h2"
+ @ca.expects(:print).with("host2").returns "h2"
+ @applier.expects(:puts).with "h2"
- @applier.apply(@ca)
- end
- end
+ @applier.apply(@ca)
+ end
+ end
- describe "and an array of names was provided" do
- it "should print each named certificate if found" do
- @applier = @class.new(:print, :to => %w{host1 host2})
+ describe "and an array of names was provided" do
+ it "should print each named certificate if found" do
+ @applier = @class.new(:print, :to => %w{host1 host2})
- @ca.expects(:print).with("host1").returns "h1"
- @applier.expects(:puts).with "h1"
+ @ca.expects(:print).with("host1").returns "h1"
+ @applier.expects(:puts).with "h1"
- @ca.expects(:print).with("host2").returns "h2"
- @applier.expects(:puts).with "h2"
+ @ca.expects(:print).with("host2").returns "h2"
+ @applier.expects(:puts).with "h2"
- @applier.apply(@ca)
- end
+ @applier.apply(@ca)
+ end
- it "should log any named but not found certificates" do
- @applier = @class.new(:print, :to => %w{host1 host2})
+ it "should log any named but not found certificates" do
+ @applier = @class.new(:print, :to => %w{host1 host2})
- @ca.expects(:print).with("host1").returns "h1"
- @applier.expects(:puts).with "h1"
+ @ca.expects(:print).with("host1").returns "h1"
+ @applier.expects(:puts).with "h1"
- @ca.expects(:print).with("host2").returns nil
- Puppet.expects(:err).with { |msg| msg.include?("host2") }
+ @ca.expects(:print).with("host2").returns nil
+ Puppet.expects(:err).with { |msg| msg.include?("host2") }
- @applier.apply(@ca)
- end
- end
+ @applier.apply(@ca)
end
+ end
+ end
- describe ":fingerprint" do
- it "should fingerprint with the set digest algorithm" do
- @applier = @class.new(:fingerprint, :to => %w{host1}, :digest => :digest)
+ describe ":fingerprint" do
+ it "should fingerprint with the set digest algorithm" do
+ @applier = @class.new(:fingerprint, :to => %w{host1}, :digest => :digest)
- @ca.expects(:fingerprint).with("host1", :digest).returns "fingerprint1"
- @applier.expects(:puts).with "host1 fingerprint1"
+ @ca.expects(:fingerprint).with("host1", :digest).returns "fingerprint1"
+ @applier.expects(:puts).with "host1 fingerprint1"
- @applier.apply(@ca)
- end
+ @applier.apply(@ca)
+ end
- describe "and :all was provided" do
- it "should fingerprint all certificates (including waiting ones)" do
- @ca.expects(:list).returns %w{host1}
- @ca.expects(:waiting?).returns %w{host2}
+ describe "and :all was provided" do
+ it "should fingerprint all certificates (including waiting ones)" do
+ @ca.expects(:list).returns %w{host1}
+ @ca.expects(:waiting?).returns %w{host2}
- @applier = @class.new(:fingerprint, :to => :all)
+ @applier = @class.new(:fingerprint, :to => :all)
- @ca.expects(:fingerprint).with("host1", :MD5).returns "fingerprint1"
- @applier.expects(:puts).with "host1 fingerprint1"
+ @ca.expects(:fingerprint).with("host1", :MD5).returns "fingerprint1"
+ @applier.expects(:puts).with "host1 fingerprint1"
- @ca.expects(:fingerprint).with("host2", :MD5).returns "fingerprint2"
- @applier.expects(:puts).with "host2 fingerprint2"
+ @ca.expects(:fingerprint).with("host2", :MD5).returns "fingerprint2"
+ @applier.expects(:puts).with "host2 fingerprint2"
- @applier.apply(@ca)
- end
- end
+ @applier.apply(@ca)
+ end
+ end
- describe "and an array of names was provided" do
- it "should print each named certificate if found" do
- @applier = @class.new(:fingerprint, :to => %w{host1 host2})
+ describe "and an array of names was provided" do
+ it "should print each named certificate if found" do
+ @applier = @class.new(:fingerprint, :to => %w{host1 host2})
- @ca.expects(:fingerprint).with("host1", :MD5).returns "fingerprint1"
- @applier.expects(:puts).with "host1 fingerprint1"
+ @ca.expects(:fingerprint).with("host1", :MD5).returns "fingerprint1"
+ @applier.expects(:puts).with "host1 fingerprint1"
- @ca.expects(:fingerprint).with("host2", :MD5).returns "fingerprint2"
- @applier.expects(:puts).with "host2 fingerprint2"
+ @ca.expects(:fingerprint).with("host2", :MD5).returns "fingerprint2"
+ @applier.expects(:puts).with "host2 fingerprint2"
- @applier.apply(@ca)
- end
- end
+ @applier.apply(@ca)
end
+ end
end
+ end
end
diff --git a/spec/unit/ssl/certificate_authority_spec.rb b/spec/unit/ssl/certificate_authority_spec.rb
index a39113d..39fee3f 100755
--- a/spec/unit/ssl/certificate_authority_spec.rb
+++ b/spec/unit/ssl/certificate_authority_spec.rb
@@ -5,768 +5,768 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/ssl/certificate_authority'
describe Puppet::SSL::CertificateAuthority do
- after do
- Puppet::Util::Cacher.expire
- Puppet.settings.clearused
+ after do
+ Puppet::Util::Cacher.expire
+ Puppet.settings.clearused
+ end
+
+ def stub_ca_host
+ @key = mock 'key'
+ @key.stubs(:content).returns "cakey"
+ @cacert = mock 'certificate'
+ @cacert.stubs(:content).returns "cacertificate"
+
+ @host = stub 'ssl_host', :key => @key, :certificate => @cacert, :name => Puppet::SSL::Host.ca_name
+ end
+
+ it "should have a class method for returning a singleton instance" do
+ Puppet::SSL::CertificateAuthority.should respond_to(:instance)
+ end
+
+ describe "when finding an existing instance" do
+ describe "and the host is a CA host and the run_mode is master" do
+ before do
+ Puppet.settings.stubs(:value).with(:ca).returns true
+ Puppet.run_mode.stubs(:master?).returns true
+
+ @ca = mock('ca')
+ Puppet::SSL::CertificateAuthority.stubs(:new).returns @ca
+ end
+
+ it "should return an instance" do
+ Puppet::SSL::CertificateAuthority.instance.should equal(@ca)
+ end
+
+ it "should always return the same instance" do
+ Puppet::SSL::CertificateAuthority.instance.should equal(Puppet::SSL::CertificateAuthority.instance)
+ end
end
- def stub_ca_host
- @key = mock 'key'
- @key.stubs(:content).returns "cakey"
- @cacert = mock 'certificate'
- @cacert.stubs(:content).returns "cacertificate"
+ describe "and the host is not a CA host" do
+ it "should return nil" do
+ Puppet.settings.stubs(:value).with(:ca).returns false
+ Puppet.run_mode.stubs(:master?).returns true
- @host = stub 'ssl_host', :key => @key, :certificate => @cacert, :name => Puppet::SSL::Host.ca_name
+ ca = mock('ca')
+ Puppet::SSL::CertificateAuthority.expects(:new).never
+ Puppet::SSL::CertificateAuthority.instance.should be_nil
+ end
end
- it "should have a class method for returning a singleton instance" do
- Puppet::SSL::CertificateAuthority.should respond_to(:instance)
- end
-
- describe "when finding an existing instance" do
- describe "and the host is a CA host and the run_mode is master" do
- before do
- Puppet.settings.stubs(:value).with(:ca).returns true
- Puppet.run_mode.stubs(:master?).returns true
-
- @ca = mock('ca')
- Puppet::SSL::CertificateAuthority.stubs(:new).returns @ca
- end
-
- it "should return an instance" do
- Puppet::SSL::CertificateAuthority.instance.should equal(@ca)
- end
-
- it "should always return the same instance" do
- Puppet::SSL::CertificateAuthority.instance.should equal(Puppet::SSL::CertificateAuthority.instance)
- end
- end
+ describe "and the run_mode is not master" do
+ it "should return nil" do
+ Puppet.settings.stubs(:value).with(:ca).returns true
+ Puppet.run_mode.stubs(:master?).returns false
- describe "and the host is not a CA host" do
- it "should return nil" do
- Puppet.settings.stubs(:value).with(:ca).returns false
- Puppet.run_mode.stubs(:master?).returns true
-
- ca = mock('ca')
- Puppet::SSL::CertificateAuthority.expects(:new).never
- Puppet::SSL::CertificateAuthority.instance.should be_nil
- end
- end
-
- describe "and the run_mode is not master" do
- it "should return nil" do
- Puppet.settings.stubs(:value).with(:ca).returns true
- Puppet.run_mode.stubs(:master?).returns false
-
- ca = mock('ca')
- Puppet::SSL::CertificateAuthority.expects(:new).never
- Puppet::SSL::CertificateAuthority.instance.should be_nil
- end
- end
+ ca = mock('ca')
+ Puppet::SSL::CertificateAuthority.expects(:new).never
+ Puppet::SSL::CertificateAuthority.instance.should be_nil
+ end
end
+ end
- describe "when initializing" do
- before do
- Puppet.settings.stubs(:use)
- Puppet.settings.stubs(:value).returns "ca_testing"
+ describe "when initializing" do
+ before do
+ Puppet.settings.stubs(:use)
+ Puppet.settings.stubs(:value).returns "ca_testing"
- Puppet::SSL::CertificateAuthority.any_instance.stubs(:setup)
- end
+ Puppet::SSL::CertificateAuthority.any_instance.stubs(:setup)
+ end
- it "should always set its name to the value of :certname" do
- Puppet.settings.expects(:value).with(:certname).returns "ca_testing"
+ it "should always set its name to the value of :certname" do
+ Puppet.settings.expects(:value).with(:certname).returns "ca_testing"
- Puppet::SSL::CertificateAuthority.new.name.should == "ca_testing"
- end
+ Puppet::SSL::CertificateAuthority.new.name.should == "ca_testing"
+ end
- it "should create an SSL::Host instance whose name is the 'ca_name'" do
- Puppet::SSL::Host.expects(:ca_name).returns "caname"
+ it "should create an SSL::Host instance whose name is the 'ca_name'" do
+ Puppet::SSL::Host.expects(:ca_name).returns "caname"
- host = stub 'host'
- Puppet::SSL::Host.expects(:new).with("caname").returns host
+ host = stub 'host'
+ Puppet::SSL::Host.expects(:new).with("caname").returns host
- Puppet::SSL::CertificateAuthority.new
- end
+ Puppet::SSL::CertificateAuthority.new
+ end
- it "should use the :main, :ca, and :ssl settings sections" do
- Puppet.settings.expects(:use).with(:main, :ssl, :ca)
- Puppet::SSL::CertificateAuthority.new
- end
+ it "should use the :main, :ca, and :ssl settings sections" do
+ Puppet.settings.expects(:use).with(:main, :ssl, :ca)
+ Puppet::SSL::CertificateAuthority.new
+ end
- it "should create an inventory instance" do
- Puppet::SSL::Inventory.expects(:new).returns "inventory"
+ it "should create an inventory instance" do
+ Puppet::SSL::Inventory.expects(:new).returns "inventory"
- Puppet::SSL::CertificateAuthority.new.inventory.should == "inventory"
- end
+ Puppet::SSL::CertificateAuthority.new.inventory.should == "inventory"
+ end
- it "should make sure the CA is set up" do
- Puppet::SSL::CertificateAuthority.any_instance.expects(:setup)
+ it "should make sure the CA is set up" do
+ Puppet::SSL::CertificateAuthority.any_instance.expects(:setup)
- Puppet::SSL::CertificateAuthority.new
- end
+ Puppet::SSL::CertificateAuthority.new
end
+ end
- describe "when setting itself up" do
- it "should generate the CA certificate if it does not have one" do
- Puppet.settings.stubs :use
+ describe "when setting itself up" do
+ it "should generate the CA certificate if it does not have one" do
+ Puppet.settings.stubs :use
- host = stub 'host'
- Puppet::SSL::Host.stubs(:new).returns host
+ host = stub 'host'
+ Puppet::SSL::Host.stubs(:new).returns host
- host.expects(:certificate).returns nil
+ host.expects(:certificate).returns nil
- Puppet::SSL::CertificateAuthority.any_instance.expects(:generate_ca_certificate)
- Puppet::SSL::CertificateAuthority.new
- end
+ Puppet::SSL::CertificateAuthority.any_instance.expects(:generate_ca_certificate)
+ Puppet::SSL::CertificateAuthority.new
end
+ end
- describe "when retrieving the certificate revocation list" do
- before do
- Puppet.settings.stubs(:use)
- Puppet.settings.stubs(:value).returns "ca_testing"
- Puppet.settings.stubs(:value).with(:cacrl).returns "/my/crl"
+ describe "when retrieving the certificate revocation list" do
+ before do
+ Puppet.settings.stubs(:use)
+ Puppet.settings.stubs(:value).returns "ca_testing"
+ Puppet.settings.stubs(:value).with(:cacrl).returns "/my/crl"
- cert = stub("certificate", :content => "real_cert")
- key = stub("key", :content => "real_key")
- @host = stub 'host', :certificate => cert, :name => "hostname", :key => key
+ cert = stub("certificate", :content => "real_cert")
+ key = stub("key", :content => "real_key")
+ @host = stub 'host', :certificate => cert, :name => "hostname", :key => key
- Puppet::SSL::CertificateAuthority.any_instance.stubs(:setup)
- @ca = Puppet::SSL::CertificateAuthority.new
+ Puppet::SSL::CertificateAuthority.any_instance.stubs(:setup)
+ @ca = Puppet::SSL::CertificateAuthority.new
- @ca.stubs(:host).returns @host
- end
+ @ca.stubs(:host).returns @host
+ end
- it "should return any found CRL instance" do
- crl = mock 'crl'
- Puppet::SSL::CertificateRevocationList.expects(:find).returns crl
- @ca.crl.should equal(crl)
- end
+ it "should return any found CRL instance" do
+ crl = mock 'crl'
+ Puppet::SSL::CertificateRevocationList.expects(:find).returns crl
+ @ca.crl.should equal(crl)
+ end
- it "should create, generate, and save a new CRL instance of no CRL can be found" do
- crl = mock 'crl'
- Puppet::SSL::CertificateRevocationList.expects(:find).returns nil
+ it "should create, generate, and save a new CRL instance of no CRL can be found" do
+ crl = mock 'crl'
+ Puppet::SSL::CertificateRevocationList.expects(:find).returns nil
- Puppet::SSL::CertificateRevocationList.expects(:new).returns crl
+ Puppet::SSL::CertificateRevocationList.expects(:new).returns crl
- crl.expects(:generate).with(@ca.host.certificate.content, @ca.host.key.content)
- crl.expects(:save)
+ crl.expects(:generate).with(@ca.host.certificate.content, @ca.host.key.content)
+ crl.expects(:save)
- @ca.crl.should equal(crl)
- end
+ @ca.crl.should equal(crl)
end
+ end
- describe "when generating a self-signed CA certificate" do
- before do
- Puppet.settings.stubs(:use)
- Puppet.settings.stubs(:value).returns "ca_testing"
+ describe "when generating a self-signed CA certificate" do
+ before do
+ Puppet.settings.stubs(:use)
+ Puppet.settings.stubs(:value).returns "ca_testing"
- Puppet::SSL::CertificateAuthority.any_instance.stubs(:setup)
- Puppet::SSL::CertificateAuthority.any_instance.stubs(:crl)
- @ca = Puppet::SSL::CertificateAuthority.new
+ Puppet::SSL::CertificateAuthority.any_instance.stubs(:setup)
+ Puppet::SSL::CertificateAuthority.any_instance.stubs(:crl)
+ @ca = Puppet::SSL::CertificateAuthority.new
- @host = stub 'host', :key => mock("key"), :name => "hostname", :certificate => mock('certificate')
+ @host = stub 'host', :key => mock("key"), :name => "hostname", :certificate => mock('certificate')
- Puppet::SSL::CertificateRequest.any_instance.stubs(:generate)
+ Puppet::SSL::CertificateRequest.any_instance.stubs(:generate)
- @ca.stubs(:host).returns @host
- end
+ @ca.stubs(:host).returns @host
+ end
- it "should create and store a password at :capass" do
- Puppet.settings.expects(:value).with(:capass).returns "/path/to/pass"
+ it "should create and store a password at :capass" do
+ Puppet.settings.expects(:value).with(:capass).returns "/path/to/pass"
- FileTest.expects(:exist?).with("/path/to/pass").returns false
+ FileTest.expects(:exist?).with("/path/to/pass").returns false
- fh = mock 'filehandle'
- Puppet.settings.expects(:write).with(:capass).yields fh
+ fh = mock 'filehandle'
+ Puppet.settings.expects(:write).with(:capass).yields fh
- fh.expects(:print).with { |s| s.length > 18 }
+ fh.expects(:print).with { |s| s.length > 18 }
- @ca.stubs(:sign)
+ @ca.stubs(:sign)
- @ca.generate_ca_certificate
- end
+ @ca.generate_ca_certificate
+ end
- it "should generate a key if one does not exist" do
- @ca.stubs :generate_password
- @ca.stubs :sign
+ it "should generate a key if one does not exist" do
+ @ca.stubs :generate_password
+ @ca.stubs :sign
- @ca.host.expects(:key).returns nil
- @ca.host.expects(:generate_key)
+ @ca.host.expects(:key).returns nil
+ @ca.host.expects(:generate_key)
- @ca.generate_ca_certificate
- end
+ @ca.generate_ca_certificate
+ end
- it "should create and sign a self-signed cert using the CA name" do
- request = mock 'request'
- Puppet::SSL::CertificateRequest.expects(:new).with(@ca.host.name).returns request
- request.expects(:generate).with(@ca.host.key)
+ it "should create and sign a self-signed cert using the CA name" do
+ request = mock 'request'
+ Puppet::SSL::CertificateRequest.expects(:new).with(@ca.host.name).returns request
+ request.expects(:generate).with(@ca.host.key)
- @ca.expects(:sign).with(@host.name, :ca, request)
+ @ca.expects(:sign).with(@host.name, :ca, request)
- @ca.stubs :generate_password
+ @ca.stubs :generate_password
- @ca.generate_ca_certificate
- end
+ @ca.generate_ca_certificate
+ end
- it "should generate its CRL" do
- @ca.stubs :generate_password
- @ca.stubs :sign
+ it "should generate its CRL" do
+ @ca.stubs :generate_password
+ @ca.stubs :sign
- @ca.host.expects(:key).returns nil
- @ca.host.expects(:generate_key)
+ @ca.host.expects(:key).returns nil
+ @ca.host.expects(:generate_key)
- @ca.expects(:crl)
+ @ca.expects(:crl)
- @ca.generate_ca_certificate
- end
+ @ca.generate_ca_certificate
end
+ end
- describe "when signing" do
- before do
- Puppet.settings.stubs(:use)
+ describe "when signing" do
+ before do
+ Puppet.settings.stubs(:use)
- Puppet::SSL::CertificateAuthority.any_instance.stubs(:password?).returns true
+ Puppet::SSL::CertificateAuthority.any_instance.stubs(:password?).returns true
- stub_ca_host
+ stub_ca_host
- Puppet::SSL::Host.expects(:new).with(Puppet::SSL::Host.ca_name).returns @host
+ Puppet::SSL::Host.expects(:new).with(Puppet::SSL::Host.ca_name).returns @host
- @ca = Puppet::SSL::CertificateAuthority.new
+ @ca = Puppet::SSL::CertificateAuthority.new
- @name = "myhost"
- @real_cert = stub 'realcert', :sign => nil
- @cert = stub 'certificate', :content => @real_cert
+ @name = "myhost"
+ @real_cert = stub 'realcert', :sign => nil
+ @cert = stub 'certificate', :content => @real_cert
- Puppet::SSL::Certificate.stubs(:new).returns @cert
+ Puppet::SSL::Certificate.stubs(:new).returns @cert
- @cert.stubs(:content=)
- @cert.stubs(:save)
+ @cert.stubs(:content=)
+ @cert.stubs(:save)
- # Stub out the factory
- @factory = stub 'factory', :result => "my real cert"
- Puppet::SSL::CertificateFactory.stubs(:new).returns @factory
+ # Stub out the factory
+ @factory = stub 'factory', :result => "my real cert"
+ Puppet::SSL::CertificateFactory.stubs(:new).returns @factory
- @request = stub 'request', :content => "myrequest", :name => @name
+ @request = stub 'request', :content => "myrequest", :name => @name
- # And the inventory
- @inventory = stub 'inventory', :add => nil
- @ca.stubs(:inventory).returns @inventory
+ # And the inventory
+ @inventory = stub 'inventory', :add => nil
+ @ca.stubs(:inventory).returns @inventory
- Puppet::SSL::CertificateRequest.stubs(:destroy)
- end
+ Puppet::SSL::CertificateRequest.stubs(:destroy)
+ end
- describe "and calculating the next certificate serial number" do
- before do
- @path = "/path/to/serial"
- Puppet.settings.stubs(:value).with(:serial).returns @path
+ describe "and calculating the next certificate serial number" do
+ before do
+ @path = "/path/to/serial"
+ Puppet.settings.stubs(:value).with(:serial).returns @path
- @filehandle = stub 'filehandle', :<< => @filehandle
- Puppet.settings.stubs(:readwritelock).with(:serial).yields @filehandle
- end
+ @filehandle = stub 'filehandle', :<< => @filehandle
+ Puppet.settings.stubs(:readwritelock).with(:serial).yields @filehandle
+ end
- it "should default to 0x1 for the first serial number" do
- @ca.next_serial.should == 0x1
- end
+ it "should default to 0x1 for the first serial number" do
+ @ca.next_serial.should == 0x1
+ end
- it "should return the current content of the serial file" do
- FileTest.stubs(:exist?).with(@path).returns true
- File.expects(:read).with(@path).returns "0002"
+ it "should return the current content of the serial file" do
+ FileTest.stubs(:exist?).with(@path).returns true
+ File.expects(:read).with(@path).returns "0002"
- @ca.next_serial.should == 2
- end
+ @ca.next_serial.should == 2
+ end
- it "should write the next serial number to the serial file as hex" do
- @filehandle.expects(:<<).with("0002")
+ it "should write the next serial number to the serial file as hex" do
+ @filehandle.expects(:<<).with("0002")
- @ca.next_serial
- end
+ @ca.next_serial
+ end
- it "should lock the serial file while writing" do
- Puppet.settings.expects(:readwritelock).with(:serial)
+ it "should lock the serial file while writing" do
+ Puppet.settings.expects(:readwritelock).with(:serial)
- @ca.next_serial
- end
- end
+ @ca.next_serial
+ end
+ end
- describe "its own certificate" do
- before do
- @serial = 10
- @ca.stubs(:next_serial).returns @serial
- end
-
- it "should not look up a certificate request for the host" do
- Puppet::SSL::CertificateRequest.expects(:find).never
-
- @ca.sign(@name, :ca, @request)
- end
-
- it "should use a certificate type of :ca" do
- Puppet::SSL::CertificateFactory.expects(:new).with do |*args|
- args[0] == :ca
- end.returns @factory
- @ca.sign(@name, :ca, @request)
- end
-
- it "should pass the provided CSR as the CSR" do
- Puppet::SSL::CertificateFactory.expects(:new).with do |*args|
- args[1] == "myrequest"
- end.returns @factory
- @ca.sign(@name, :ca, @request)
- end
-
- it "should use the provided CSR's content as the issuer" do
- Puppet::SSL::CertificateFactory.expects(:new).with do |*args|
- args[2] == "myrequest"
- end.returns @factory
- @ca.sign(@name, :ca, @request)
- end
-
- it "should pass the next serial as the serial number" do
- Puppet::SSL::CertificateFactory.expects(:new).with do |*args|
- args[3] == @serial
- end.returns @factory
- @ca.sign(@name, :ca, @request)
- end
-
- it "should save the resulting certificate" do
- @cert.expects(:save)
-
- @ca.sign(@name, :ca, @request)
- end
- end
+ describe "its own certificate" do
+ before do
+ @serial = 10
+ @ca.stubs(:next_serial).returns @serial
+ end
+
+ it "should not look up a certificate request for the host" do
+ Puppet::SSL::CertificateRequest.expects(:find).never
+
+ @ca.sign(@name, :ca, @request)
+ end
+
+ it "should use a certificate type of :ca" do
+ Puppet::SSL::CertificateFactory.expects(:new).with do |*args|
+ args[0] == :ca
+ end.returns @factory
+ @ca.sign(@name, :ca, @request)
+ end
+
+ it "should pass the provided CSR as the CSR" do
+ Puppet::SSL::CertificateFactory.expects(:new).with do |*args|
+ args[1] == "myrequest"
+ end.returns @factory
+ @ca.sign(@name, :ca, @request)
+ end
+
+ it "should use the provided CSR's content as the issuer" do
+ Puppet::SSL::CertificateFactory.expects(:new).with do |*args|
+ args[2] == "myrequest"
+ end.returns @factory
+ @ca.sign(@name, :ca, @request)
+ end
+
+ it "should pass the next serial as the serial number" do
+ Puppet::SSL::CertificateFactory.expects(:new).with do |*args|
+ args[3] == @serial
+ end.returns @factory
+ @ca.sign(@name, :ca, @request)
+ end
+
+ it "should save the resulting certificate" do
+ @cert.expects(:save)
+
+ @ca.sign(@name, :ca, @request)
+ end
+ end
- describe "another host's certificate" do
- before do
- @serial = 10
- @ca.stubs(:next_serial).returns @serial
+ describe "another host's certificate" do
+ before do
+ @serial = 10
+ @ca.stubs(:next_serial).returns @serial
- Puppet::SSL::CertificateRequest.stubs(:find).with(@name).returns @request
- @cert.stubs :save
- end
+ Puppet::SSL::CertificateRequest.stubs(:find).with(@name).returns @request
+ @cert.stubs :save
+ end
- it "should use a certificate type of :server" do
- Puppet::SSL::CertificateFactory.expects(:new).with do |*args|
- args[0] == :server
- end.returns @factory
+ it "should use a certificate type of :server" do
+ Puppet::SSL::CertificateFactory.expects(:new).with do |*args|
+ args[0] == :server
+ end.returns @factory
- @ca.sign(@name)
- end
+ @ca.sign(@name)
+ end
- it "should use look up a CSR for the host in the :ca_file terminus" do
- Puppet::SSL::CertificateRequest.expects(:find).with(@name).returns @request
+ it "should use look up a CSR for the host in the :ca_file terminus" do
+ Puppet::SSL::CertificateRequest.expects(:find).with(@name).returns @request
- @ca.sign(@name)
- end
+ @ca.sign(@name)
+ end
- it "should fail if no CSR can be found for the host" do
- Puppet::SSL::CertificateRequest.expects(:find).with(@name).returns nil
+ it "should fail if no CSR can be found for the host" do
+ Puppet::SSL::CertificateRequest.expects(:find).with(@name).returns nil
- lambda { @ca.sign(@name) }.should raise_error(ArgumentError)
- end
+ lambda { @ca.sign(@name) }.should raise_error(ArgumentError)
+ end
- it "should use the CA certificate as the issuer" do
- Puppet::SSL::CertificateFactory.expects(:new).with do |*args|
- args[2] == @cacert.content
- end.returns @factory
- @ca.sign(@name)
- end
+ it "should use the CA certificate as the issuer" do
+ Puppet::SSL::CertificateFactory.expects(:new).with do |*args|
+ args[2] == @cacert.content
+ end.returns @factory
+ @ca.sign(@name)
+ end
- it "should pass the next serial as the serial number" do
- Puppet::SSL::CertificateFactory.expects(:new).with do |*args|
- args[3] == @serial
- end.returns @factory
- @ca.sign(@name)
- end
+ it "should pass the next serial as the serial number" do
+ Puppet::SSL::CertificateFactory.expects(:new).with do |*args|
+ args[3] == @serial
+ end.returns @factory
+ @ca.sign(@name)
+ end
- it "should sign the resulting certificate using its real key and a digest" do
- digest = mock 'digest'
- OpenSSL::Digest::SHA1.expects(:new).returns digest
+ it "should sign the resulting certificate using its real key and a digest" do
+ digest = mock 'digest'
+ OpenSSL::Digest::SHA1.expects(:new).returns digest
- key = stub 'key', :content => "real_key"
- @ca.host.stubs(:key).returns key
+ key = stub 'key', :content => "real_key"
+ @ca.host.stubs(:key).returns key
- @cert.content.expects(:sign).with("real_key", digest)
- @ca.sign(@name)
- end
+ @cert.content.expects(:sign).with("real_key", digest)
+ @ca.sign(@name)
+ end
- it "should save the resulting certificate" do
- @cert.expects(:save)
- @ca.sign(@name)
- end
+ it "should save the resulting certificate" do
+ @cert.expects(:save)
+ @ca.sign(@name)
+ end
- it "should remove the host's certificate request" do
- Puppet::SSL::CertificateRequest.expects(:destroy).with(@name)
+ it "should remove the host's certificate request" do
+ Puppet::SSL::CertificateRequest.expects(:destroy).with(@name)
- @ca.sign(@name)
- end
- end
+ @ca.sign(@name)
+ end
+ end
- it "should create a certificate instance with the content set to the newly signed x509 certificate" do
- @serial = 10
- @ca.stubs(:next_serial).returns @serial
+ it "should create a certificate instance with the content set to the newly signed x509 certificate" do
+ @serial = 10
+ @ca.stubs(:next_serial).returns @serial
- Puppet::SSL::CertificateRequest.stubs(:find).with(@name).returns @request
- @cert.stubs :save
- Puppet::SSL::Certificate.expects(:new).with(@name).returns @cert
+ Puppet::SSL::CertificateRequest.stubs(:find).with(@name).returns @request
+ @cert.stubs :save
+ Puppet::SSL::Certificate.expects(:new).with(@name).returns @cert
- @ca.sign(@name)
- end
+ @ca.sign(@name)
+ end
- it "should return the certificate instance" do
- @ca.stubs(:next_serial).returns @serial
- Puppet::SSL::CertificateRequest.stubs(:find).with(@name).returns @request
- @cert.stubs :save
- @ca.sign(@name).should equal(@cert)
- end
+ it "should return the certificate instance" do
+ @ca.stubs(:next_serial).returns @serial
+ Puppet::SSL::CertificateRequest.stubs(:find).with(@name).returns @request
+ @cert.stubs :save
+ @ca.sign(@name).should equal(@cert)
+ end
- it "should add the certificate to its inventory" do
- @ca.stubs(:next_serial).returns @serial
- @inventory.expects(:add).with(@cert)
+ it "should add the certificate to its inventory" do
+ @ca.stubs(:next_serial).returns @serial
+ @inventory.expects(:add).with(@cert)
- Puppet::SSL::CertificateRequest.stubs(:find).with(@name).returns @request
- @cert.stubs :save
- @ca.sign(@name)
- end
+ Puppet::SSL::CertificateRequest.stubs(:find).with(@name).returns @request
+ @cert.stubs :save
+ @ca.sign(@name)
+ end
- it "should have a method for triggering autosigning of available CSRs" do
- @ca.should respond_to(:autosign)
- end
+ it "should have a method for triggering autosigning of available CSRs" do
+ @ca.should respond_to(:autosign)
+ end
- describe "when autosigning certificates" do
- it "should do nothing if autosign is disabled" do
- Puppet.settings.expects(:value).with(:autosign).returns 'false'
+ describe "when autosigning certificates" do
+ it "should do nothing if autosign is disabled" do
+ Puppet.settings.expects(:value).with(:autosign).returns 'false'
- Puppet::SSL::CertificateRequest.expects(:search).never
- @ca.autosign
- end
+ Puppet::SSL::CertificateRequest.expects(:search).never
+ @ca.autosign
+ end
- it "should do nothing if no autosign.conf exists" do
- Puppet.settings.expects(:value).with(:autosign).returns '/auto/sign'
- FileTest.expects(:exist?).with("/auto/sign").returns false
+ it "should do nothing if no autosign.conf exists" do
+ Puppet.settings.expects(:value).with(:autosign).returns '/auto/sign'
+ FileTest.expects(:exist?).with("/auto/sign").returns false
- Puppet::SSL::CertificateRequest.expects(:search).never
- @ca.autosign
- end
+ Puppet::SSL::CertificateRequest.expects(:search).never
+ @ca.autosign
+ end
- describe "and autosign is enabled and the autosign.conf file exists" do
- before do
- Puppet.settings.stubs(:value).with(:autosign).returns '/auto/sign'
- FileTest.stubs(:exist?).with("/auto/sign").returns true
- File.stubs(:readlines).with("/auto/sign").returns ["one\n", "two\n"]
+ describe "and autosign is enabled and the autosign.conf file exists" do
+ before do
+ Puppet.settings.stubs(:value).with(:autosign).returns '/auto/sign'
+ FileTest.stubs(:exist?).with("/auto/sign").returns true
+ File.stubs(:readlines).with("/auto/sign").returns ["one\n", "two\n"]
- Puppet::SSL::CertificateRequest.stubs(:search).returns []
+ Puppet::SSL::CertificateRequest.stubs(:search).returns []
- @store = stub 'store', :allow => nil
- Puppet::Network::AuthStore.stubs(:new).returns @store
- end
+ @store = stub 'store', :allow => nil
+ Puppet::Network::AuthStore.stubs(:new).returns @store
+ end
- describe "when creating the AuthStore instance to verify autosigning" do
- it "should create an AuthStore with each line in the configuration file allowed to be autosigned" do
- Puppet::Network::AuthStore.expects(:new).returns @store
+ describe "when creating the AuthStore instance to verify autosigning" do
+ it "should create an AuthStore with each line in the configuration file allowed to be autosigned" do
+ Puppet::Network::AuthStore.expects(:new).returns @store
- @store.expects(:allow).with("one")
- @store.expects(:allow).with("two")
+ @store.expects(:allow).with("one")
+ @store.expects(:allow).with("two")
- @ca.autosign
- end
+ @ca.autosign
+ end
- it "should reparse the autosign configuration on each call" do
- Puppet::Network::AuthStore.expects(:new).times(2).returns @store
+ it "should reparse the autosign configuration on each call" do
+ Puppet::Network::AuthStore.expects(:new).times(2).returns @store
- @ca.autosign
- @ca.autosign
- end
+ @ca.autosign
+ @ca.autosign
+ end
- it "should ignore comments" do
- File.stubs(:readlines).with("/auto/sign").returns ["one\n", "#two\n"]
+ it "should ignore comments" do
+ File.stubs(:readlines).with("/auto/sign").returns ["one\n", "#two\n"]
- @store.expects(:allow).with("one")
- @ca.autosign
- end
+ @store.expects(:allow).with("one")
+ @ca.autosign
+ end
- it "should ignore blank lines" do
- File.stubs(:readlines).with("/auto/sign").returns ["one\n", "\n"]
+ it "should ignore blank lines" do
+ File.stubs(:readlines).with("/auto/sign").returns ["one\n", "\n"]
- @store.expects(:allow).with("one")
- @ca.autosign
- end
- end
+ @store.expects(:allow).with("one")
+ @ca.autosign
+ end
+ end
- it "should sign all CSRs whose hostname matches the autosign configuration" do
- csr1 = mock 'csr1'
- csr2 = mock 'csr2'
- Puppet::SSL::CertificateRequest.stubs(:search).returns [csr1, csr2]
- end
+ it "should sign all CSRs whose hostname matches the autosign configuration" do
+ csr1 = mock 'csr1'
+ csr2 = mock 'csr2'
+ Puppet::SSL::CertificateRequest.stubs(:search).returns [csr1, csr2]
+ end
- it "should not sign CSRs whose hostname does not match the autosign configuration" do
- csr1 = mock 'csr1'
- csr2 = mock 'csr2'
- Puppet::SSL::CertificateRequest.stubs(:search).returns [csr1, csr2]
- end
- end
+ it "should not sign CSRs whose hostname does not match the autosign configuration" do
+ csr1 = mock 'csr1'
+ csr2 = mock 'csr2'
+ Puppet::SSL::CertificateRequest.stubs(:search).returns [csr1, csr2]
end
+ end
end
+ end
- describe "when managing certificate clients" do
- before do
- Puppet.settings.stubs(:use)
+ describe "when managing certificate clients" do
+ before do
+ Puppet.settings.stubs(:use)
- Puppet::SSL::CertificateAuthority.any_instance.stubs(:password?).returns true
+ Puppet::SSL::CertificateAuthority.any_instance.stubs(:password?).returns true
- stub_ca_host
+ stub_ca_host
- Puppet::SSL::Host.expects(:new).returns @host
- Puppet::SSL::CertificateAuthority.any_instance.stubs(:host).returns @host
+ Puppet::SSL::Host.expects(:new).returns @host
+ Puppet::SSL::CertificateAuthority.any_instance.stubs(:host).returns @host
- @cacert = mock 'certificate'
- @cacert.stubs(:content).returns "cacertificate"
- @ca = Puppet::SSL::CertificateAuthority.new
- end
+ @cacert = mock 'certificate'
+ @cacert.stubs(:content).returns "cacertificate"
+ @ca = Puppet::SSL::CertificateAuthority.new
+ end
- it "should have a method for acting on the SSL files" do
- @ca.should respond_to(:apply)
- end
+ it "should have a method for acting on the SSL files" do
+ @ca.should respond_to(:apply)
+ end
- describe "when applying a method to a set of hosts" do
- it "should fail if no subjects have been specified" do
- lambda { @ca.apply(:generate) }.should raise_error(ArgumentError)
- end
-
- it "should create an Interface instance with the specified method and the options" do
- Puppet::SSL::CertificateAuthority::Interface.expects(:new).with(:generate, :to => :host).returns(stub('applier', :apply => nil))
- @ca.apply(:generate, :to => :host)
- end
-
- it "should apply the Interface with itself as the argument" do
- applier = stub('applier')
- applier.expects(:apply).with(@ca)
- Puppet::SSL::CertificateAuthority::Interface.expects(:new).returns applier
- @ca.apply(:generate, :to => :ca_testing)
- end
- end
+ describe "when applying a method to a set of hosts" do
+ it "should fail if no subjects have been specified" do
+ lambda { @ca.apply(:generate) }.should raise_error(ArgumentError)
+ end
+
+ it "should create an Interface instance with the specified method and the options" do
+ Puppet::SSL::CertificateAuthority::Interface.expects(:new).with(:generate, :to => :host).returns(stub('applier', :apply => nil))
+ @ca.apply(:generate, :to => :host)
+ end
+
+ it "should apply the Interface with itself as the argument" do
+ applier = stub('applier')
+ applier.expects(:apply).with(@ca)
+ Puppet::SSL::CertificateAuthority::Interface.expects(:new).returns applier
+ @ca.apply(:generate, :to => :ca_testing)
+ end
+ end
- it "should be able to list waiting certificate requests" do
- req1 = stub 'req1', :name => "one"
- req2 = stub 'req2', :name => "two"
- Puppet::SSL::CertificateRequest.expects(:search).with("*").returns [req1, req2]
+ it "should be able to list waiting certificate requests" do
+ req1 = stub 'req1', :name => "one"
+ req2 = stub 'req2', :name => "two"
+ Puppet::SSL::CertificateRequest.expects(:search).with("*").returns [req1, req2]
- @ca.waiting?.should == %w{one two}
- end
+ @ca.waiting?.should == %w{one two}
+ end
- it "should delegate removing hosts to the Host class" do
- Puppet::SSL::Host.expects(:destroy).with("myhost")
+ it "should delegate removing hosts to the Host class" do
+ Puppet::SSL::Host.expects(:destroy).with("myhost")
- @ca.destroy("myhost")
- end
+ @ca.destroy("myhost")
+ end
- it "should be able to verify certificates" do
- @ca.should respond_to(:verify)
- end
+ it "should be able to verify certificates" do
+ @ca.should respond_to(:verify)
+ end
- it "should list certificates as the sorted list of all existing signed certificates" do
- cert1 = stub 'cert1', :name => "cert1"
- cert2 = stub 'cert2', :name => "cert2"
- Puppet::SSL::Certificate.expects(:search).with("*").returns [cert1, cert2]
- @ca.list.should == %w{cert1 cert2}
- end
+ it "should list certificates as the sorted list of all existing signed certificates" do
+ cert1 = stub 'cert1', :name => "cert1"
+ cert2 = stub 'cert2', :name => "cert2"
+ Puppet::SSL::Certificate.expects(:search).with("*").returns [cert1, cert2]
+ @ca.list.should == %w{cert1 cert2}
+ end
- describe "and printing certificates" do
- it "should return nil if the certificate cannot be found" do
- Puppet::SSL::Certificate.expects(:find).with("myhost").returns nil
- @ca.print("myhost").should be_nil
- end
-
- it "should print certificates by calling :to_text on the host's certificate" do
- cert1 = stub 'cert1', :name => "cert1", :to_text => "mytext"
- Puppet::SSL::Certificate.expects(:find).with("myhost").returns cert1
- @ca.print("myhost").should == "mytext"
- end
- end
+ describe "and printing certificates" do
+ it "should return nil if the certificate cannot be found" do
+ Puppet::SSL::Certificate.expects(:find).with("myhost").returns nil
+ @ca.print("myhost").should be_nil
+ end
+
+ it "should print certificates by calling :to_text on the host's certificate" do
+ cert1 = stub 'cert1', :name => "cert1", :to_text => "mytext"
+ Puppet::SSL::Certificate.expects(:find).with("myhost").returns cert1
+ @ca.print("myhost").should == "mytext"
+ end
+ end
- describe "and fingerprinting certificates" do
- before :each do
- @cert = stub 'cert', :name => "cert", :fingerprint => "DIGEST"
- Puppet::SSL::Certificate.stubs(:find).with("myhost").returns @cert
- Puppet::SSL::CertificateRequest.stubs(:find).with("myhost")
- end
-
- it "should raise an error if the certificate or CSR cannot be found" do
- Puppet::SSL::Certificate.expects(:find).with("myhost").returns nil
- Puppet::SSL::CertificateRequest.expects(:find).with("myhost").returns nil
- lambda { @ca.fingerprint("myhost") }.should raise_error
- end
-
- it "should try to find a CSR if no certificate can be found" do
- Puppet::SSL::Certificate.expects(:find).with("myhost").returns nil
- Puppet::SSL::CertificateRequest.expects(:find).with("myhost").returns @cert
- @cert.expects(:fingerprint)
- @ca.fingerprint("myhost")
- end
-
- it "should delegate to the certificate fingerprinting" do
- @cert.expects(:fingerprint)
- @ca.fingerprint("myhost")
- end
-
- it "should propagate the digest algorithm to the certificate fingerprinting system" do
- @cert.expects(:fingerprint).with(:digest)
- @ca.fingerprint("myhost", :digest)
- end
- end
+ describe "and fingerprinting certificates" do
+ before :each do
+ @cert = stub 'cert', :name => "cert", :fingerprint => "DIGEST"
+ Puppet::SSL::Certificate.stubs(:find).with("myhost").returns @cert
+ Puppet::SSL::CertificateRequest.stubs(:find).with("myhost")
+ end
+
+ it "should raise an error if the certificate or CSR cannot be found" do
+ Puppet::SSL::Certificate.expects(:find).with("myhost").returns nil
+ Puppet::SSL::CertificateRequest.expects(:find).with("myhost").returns nil
+ lambda { @ca.fingerprint("myhost") }.should raise_error
+ end
+
+ it "should try to find a CSR if no certificate can be found" do
+ Puppet::SSL::Certificate.expects(:find).with("myhost").returns nil
+ Puppet::SSL::CertificateRequest.expects(:find).with("myhost").returns @cert
+ @cert.expects(:fingerprint)
+ @ca.fingerprint("myhost")
+ end
+
+ it "should delegate to the certificate fingerprinting" do
+ @cert.expects(:fingerprint)
+ @ca.fingerprint("myhost")
+ end
+
+ it "should propagate the digest algorithm to the certificate fingerprinting system" do
+ @cert.expects(:fingerprint).with(:digest)
+ @ca.fingerprint("myhost", :digest)
+ end
+ end
- describe "and verifying certificates" do
- before do
- @store = stub 'store', :verify => true, :add_file => nil, :purpose= => nil, :add_crl => true, :flags= => nil
+ describe "and verifying certificates" do
+ before do
+ @store = stub 'store', :verify => true, :add_file => nil, :purpose= => nil, :add_crl => true, :flags= => nil
- OpenSSL::X509::Store.stubs(:new).returns @store
+ OpenSSL::X509::Store.stubs(:new).returns @store
- Puppet.settings.stubs(:value).returns "crtstuff"
+ Puppet.settings.stubs(:value).returns "crtstuff"
- @cert = stub 'cert', :content => "mycert"
- Puppet::SSL::Certificate.stubs(:find).returns @cert
+ @cert = stub 'cert', :content => "mycert"
+ Puppet::SSL::Certificate.stubs(:find).returns @cert
- @crl = stub('crl', :content => "mycrl")
+ @crl = stub('crl', :content => "mycrl")
- @ca.stubs(:crl).returns @crl
- end
+ @ca.stubs(:crl).returns @crl
+ end
- it "should fail if the host's certificate cannot be found" do
- Puppet::SSL::Certificate.expects(:find).with("me").returns(nil)
+ it "should fail if the host's certificate cannot be found" do
+ Puppet::SSL::Certificate.expects(:find).with("me").returns(nil)
- lambda { @ca.verify("me") }.should raise_error(ArgumentError)
- end
+ lambda { @ca.verify("me") }.should raise_error(ArgumentError)
+ end
- it "should create an SSL Store to verify" do
- OpenSSL::X509::Store.expects(:new).returns @store
+ it "should create an SSL Store to verify" do
+ OpenSSL::X509::Store.expects(:new).returns @store
- @ca.verify("me")
- end
+ @ca.verify("me")
+ end
- it "should add the CA Certificate to the store" do
- Puppet.settings.stubs(:value).with(:cacert).returns "/ca/cert"
- @store.expects(:add_file).with "/ca/cert"
+ it "should add the CA Certificate to the store" do
+ Puppet.settings.stubs(:value).with(:cacert).returns "/ca/cert"
+ @store.expects(:add_file).with "/ca/cert"
- @ca.verify("me")
- end
+ @ca.verify("me")
+ end
- it "should add the CRL to the store if the crl is enabled" do
- @store.expects(:add_crl).with "mycrl"
+ it "should add the CRL to the store if the crl is enabled" do
+ @store.expects(:add_crl).with "mycrl"
- @ca.verify("me")
- end
+ @ca.verify("me")
+ end
- it "should set the store purpose to OpenSSL::X509::PURPOSE_SSL_CLIENT" do
- Puppet.settings.stubs(:value).with(:cacert).returns "/ca/cert"
- @store.expects(:add_file).with "/ca/cert"
+ it "should set the store purpose to OpenSSL::X509::PURPOSE_SSL_CLIENT" do
+ Puppet.settings.stubs(:value).with(:cacert).returns "/ca/cert"
+ @store.expects(:add_file).with "/ca/cert"
- @ca.verify("me")
- end
+ @ca.verify("me")
+ end
- it "should set the store flags to check the crl" do
- @store.expects(:flags=).with OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK
+ it "should set the store flags to check the crl" do
+ @store.expects(:flags=).with OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK
- @ca.verify("me")
- end
+ @ca.verify("me")
+ end
- it "should use the store to verify the certificate" do
- @cert.expects(:content).returns "mycert"
+ it "should use the store to verify the certificate" do
+ @cert.expects(:content).returns "mycert"
- @store.expects(:verify).with("mycert").returns true
+ @store.expects(:verify).with("mycert").returns true
- @ca.verify("me")
- end
+ @ca.verify("me")
+ end
- it "should fail if the verification returns false" do
- @cert.expects(:content).returns "mycert"
+ it "should fail if the verification returns false" do
+ @cert.expects(:content).returns "mycert"
- @store.expects(:verify).with("mycert").returns false
+ @store.expects(:verify).with("mycert").returns false
- lambda { @ca.verify("me") }.should raise_error
- end
- end
+ lambda { @ca.verify("me") }.should raise_error
+ end
+ end
- describe "and revoking certificates" do
- before do
- @crl = mock 'crl'
- @ca.stubs(:crl).returns @crl
+ describe "and revoking certificates" do
+ before do
+ @crl = mock 'crl'
+ @ca.stubs(:crl).returns @crl
- @ca.stubs(:next_serial).returns 10
+ @ca.stubs(:next_serial).returns 10
- @real_cert = stub 'real_cert', :serial => 15
- @cert = stub 'cert', :content => @real_cert
- Puppet::SSL::Certificate.stubs(:find).returns @cert
+ @real_cert = stub 'real_cert', :serial => 15
+ @cert = stub 'cert', :content => @real_cert
+ Puppet::SSL::Certificate.stubs(:find).returns @cert
- end
+ end
- it "should fail if the certificate revocation list is disabled" do
- @ca.stubs(:crl).returns false
+ it "should fail if the certificate revocation list is disabled" do
+ @ca.stubs(:crl).returns false
- lambda { @ca.revoke('ca_testing') }.should raise_error(ArgumentError)
+ lambda { @ca.revoke('ca_testing') }.should raise_error(ArgumentError)
- end
+ end
- it "should delegate the revocation to its CRL" do
- @ca.crl.expects(:revoke)
+ it "should delegate the revocation to its CRL" do
+ @ca.crl.expects(:revoke)
- @ca.revoke('host')
- end
+ @ca.revoke('host')
+ end
- it "should get the serial number from the local certificate if it exists" do
- @ca.crl.expects(:revoke).with { |serial, key| serial == 15 }
+ it "should get the serial number from the local certificate if it exists" do
+ @ca.crl.expects(:revoke).with { |serial, key| serial == 15 }
- Puppet::SSL::Certificate.expects(:find).with("host").returns @cert
+ Puppet::SSL::Certificate.expects(:find).with("host").returns @cert
- @ca.revoke('host')
- end
+ @ca.revoke('host')
+ end
- it "should get the serial number from inventory if no local certificate exists" do
- real_cert = stub 'real_cert', :serial => 15
- cert = stub 'cert', :content => real_cert
- Puppet::SSL::Certificate.expects(:find).with("host").returns nil
+ it "should get the serial number from inventory if no local certificate exists" do
+ real_cert = stub 'real_cert', :serial => 15
+ cert = stub 'cert', :content => real_cert
+ Puppet::SSL::Certificate.expects(:find).with("host").returns nil
- @ca.inventory.expects(:serial).with("host").returns 16
+ @ca.inventory.expects(:serial).with("host").returns 16
- @ca.crl.expects(:revoke).with { |serial, key| serial == 16 }
- @ca.revoke('host')
- end
- end
+ @ca.crl.expects(:revoke).with { |serial, key| serial == 16 }
+ @ca.revoke('host')
+ end
+ end
- it "should be able to generate a complete new SSL host" do
- @ca.should respond_to(:generate)
- end
+ it "should be able to generate a complete new SSL host" do
+ @ca.should respond_to(:generate)
+ end
- describe "and generating certificates" do
- before do
- @host = stub 'host', :generate_certificate_request => nil
- Puppet::SSL::Host.stubs(:new).returns @host
- Puppet::SSL::Certificate.stubs(:find).returns nil
+ describe "and generating certificates" do
+ before do
+ @host = stub 'host', :generate_certificate_request => nil
+ Puppet::SSL::Host.stubs(:new).returns @host
+ Puppet::SSL::Certificate.stubs(:find).returns nil
- @ca.stubs(:sign)
- end
+ @ca.stubs(:sign)
+ end
- it "should fail if a certificate already exists for the host" do
- Puppet::SSL::Certificate.expects(:find).with("him").returns "something"
+ it "should fail if a certificate already exists for the host" do
+ Puppet::SSL::Certificate.expects(:find).with("him").returns "something"
- lambda { @ca.generate("him") }.should raise_error(ArgumentError)
- end
+ lambda { @ca.generate("him") }.should raise_error(ArgumentError)
+ end
- it "should create a new Host instance with the correct name" do
- Puppet::SSL::Host.expects(:new).with("him").returns @host
+ it "should create a new Host instance with the correct name" do
+ Puppet::SSL::Host.expects(:new).with("him").returns @host
- @ca.generate("him")
- end
+ @ca.generate("him")
+ end
- it "should use the Host to generate the certificate request" do
- @host.expects :generate_certificate_request
+ it "should use the Host to generate the certificate request" do
+ @host.expects :generate_certificate_request
- @ca.generate("him")
- end
+ @ca.generate("him")
+ end
- it "should sign the generated request" do
- @ca.expects(:sign).with("him")
+ it "should sign the generated request" do
+ @ca.expects(:sign).with("him")
- @ca.generate("him")
- end
- end
+ @ca.generate("him")
+ end
end
+ end
end
diff --git a/spec/unit/ssl/certificate_factory_spec.rb b/spec/unit/ssl/certificate_factory_spec.rb
index 089ce3f..de20938 100755
--- a/spec/unit/ssl/certificate_factory_spec.rb
+++ b/spec/unit/ssl/certificate_factory_spec.rb
@@ -5,103 +5,103 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/ssl/certificate_factory'
describe Puppet::SSL::CertificateFactory do
- before do
- @cert_type = mock 'cert_type'
- @name = mock 'name'
- @csr = stub 'csr', :subject => @name
- @issuer = mock 'issuer'
- @serial = mock 'serial'
-
- @factory = Puppet::SSL::CertificateFactory.new(@cert_type, @csr, @issuer, @serial)
+ before do
+ @cert_type = mock 'cert_type'
+ @name = mock 'name'
+ @csr = stub 'csr', :subject => @name
+ @issuer = mock 'issuer'
+ @serial = mock 'serial'
+
+ @factory = Puppet::SSL::CertificateFactory.new(@cert_type, @csr, @issuer, @serial)
+ end
+
+ describe "when initializing" do
+ it "should set its :cert_type to its first argument" do
+ @factory.cert_type.should equal(@cert_type)
end
- describe "when initializing" do
- it "should set its :cert_type to its first argument" do
- @factory.cert_type.should equal(@cert_type)
- end
-
- it "should set its :csr to its second argument" do
- @factory.csr.should equal(@csr)
- end
-
- it "should set its :issuer to its third argument" do
- @factory.issuer.should equal(@issuer)
- end
-
- it "should set its :serial to its fourth argument" do
- @factory.serial.should equal(@serial)
- end
+ it "should set its :csr to its second argument" do
+ @factory.csr.should equal(@csr)
+ end
- it "should set its name to the subject of the csr" do
- @factory.name.should equal(@name)
- end
+ it "should set its :issuer to its third argument" do
+ @factory.issuer.should equal(@issuer)
end
- describe "when generating the certificate" do
- before do
- @cert = mock 'cert'
+ it "should set its :serial to its fourth argument" do
+ @factory.serial.should equal(@serial)
+ end
- @cert.stub_everything
+ it "should set its name to the subject of the csr" do
+ @factory.name.should equal(@name)
+ end
+ end
- @factory.stubs :build_extensions
+ describe "when generating the certificate" do
+ before do
+ @cert = mock 'cert'
- @factory.stubs :set_ttl
+ @cert.stub_everything
- @issuer_name = mock 'issuer_name'
- @issuer.stubs(:subject).returns @issuer_name
+ @factory.stubs :build_extensions
- @public_key = mock 'public_key'
- @csr.stubs(:public_key).returns @public_key
+ @factory.stubs :set_ttl
- OpenSSL::X509::Certificate.stubs(:new).returns @cert
- end
+ @issuer_name = mock 'issuer_name'
+ @issuer.stubs(:subject).returns @issuer_name
- it "should return a new X509 certificate" do
- OpenSSL::X509::Certificate.expects(:new).returns @cert
- @factory.result.should equal(@cert)
- end
+ @public_key = mock 'public_key'
+ @csr.stubs(:public_key).returns @public_key
- it "should set the certificate's version to 2" do
- @cert.expects(:version=).with 2
- @factory.result
- end
+ OpenSSL::X509::Certificate.stubs(:new).returns @cert
+ end
- it "should set the certificate's subject to the CSR's subject" do
- @cert.expects(:subject=).with @name
- @factory.result
- end
+ it "should return a new X509 certificate" do
+ OpenSSL::X509::Certificate.expects(:new).returns @cert
+ @factory.result.should equal(@cert)
+ end
- it "should set the certificate's issuer to the Issuer's subject" do
- @cert.expects(:issuer=).with @issuer_name
- @factory.result
- end
+ it "should set the certificate's version to 2" do
+ @cert.expects(:version=).with 2
+ @factory.result
+ end
- it "should set the certificate's public key to the CSR's public key" do
- @cert.expects(:public_key=).with @public_key
- @factory.result
- end
+ it "should set the certificate's subject to the CSR's subject" do
+ @cert.expects(:subject=).with @name
+ @factory.result
+ end
- it "should set the certificate's serial number to the provided serial number" do
- @cert.expects(:serial=).with @serial
- @factory.result
- end
+ it "should set the certificate's issuer to the Issuer's subject" do
+ @cert.expects(:issuer=).with @issuer_name
+ @factory.result
+ end
- it "should build extensions for the certificate" do
- @factory.expects(:build_extensions)
- @factory.result
- end
+ it "should set the certificate's public key to the CSR's public key" do
+ @cert.expects(:public_key=).with @public_key
+ @factory.result
+ end
- it "should set the ttl of the certificate" do
- @factory.expects(:set_ttl)
- @factory.result
- end
+ it "should set the certificate's serial number to the provided serial number" do
+ @cert.expects(:serial=).with @serial
+ @factory.result
end
- describe "when building extensions" do
- it "should have tests"
+ it "should build extensions for the certificate" do
+ @factory.expects(:build_extensions)
+ @factory.result
end
- describe "when setting the ttl" do
- it "should have tests"
+ it "should set the ttl of the certificate" do
+ @factory.expects(:set_ttl)
+ @factory.result
end
+ end
+
+ describe "when building extensions" do
+ it "should have tests"
+ end
+
+ describe "when setting the ttl" do
+ it "should have tests"
+ end
end
diff --git a/spec/unit/ssl/certificate_request_spec.rb b/spec/unit/ssl/certificate_request_spec.rb
index 253009b..437fc05 100755
--- a/spec/unit/ssl/certificate_request_spec.rb
+++ b/spec/unit/ssl/certificate_request_spec.rb
@@ -6,215 +6,215 @@ require 'puppet/ssl/certificate_request'
require 'puppet/ssl/key'
describe Puppet::SSL::CertificateRequest do
+ before do
+ @class = Puppet::SSL::CertificateRequest
+ end
+
+ it "should be extended with the Indirector module" do
+ @class.singleton_class.should be_include(Puppet::Indirector)
+ end
+
+ it "should indirect certificate_request" do
+ @class.indirection.name.should == :certificate_request
+ end
+
+ it "should use any provided name as its name" do
+ @class.new("myname").name.should == "myname"
+ end
+
+ it "should only support the text format" do
+ @class.supported_formats.should == [:s]
+ end
+
+ describe "when converting from a string" do
+ it "should create a CSR instance with its name set to the CSR subject and its content set to the extracted CSR" do
+ csr = stub 'csr', :subject => "/CN=Foo.madstop.com"
+ OpenSSL::X509::Request.expects(:new).with("my csr").returns(csr)
+
+ mycsr = stub 'sslcsr'
+ mycsr.expects(:content=).with(csr)
+
+ @class.expects(:new).with("foo.madstop.com").returns mycsr
+
+ @class.from_s("my csr")
+ end
+ end
+
+ describe "when managing instances" do
+ before do
+ @request = @class.new("myname")
+ end
+
+ it "should have a name attribute" do
+ @request.name.should == "myname"
+ end
+
+ it "should downcase its name" do
+ @class.new("MyName").name.should == "myname"
+ end
+
+ it "should have a content attribute" do
+ @request.should respond_to(:content)
+ end
+
+ it "should be able to read requests from disk" do
+ path = "/my/path"
+ File.expects(:read).with(path).returns("my request")
+ request = mock 'request'
+ OpenSSL::X509::Request.expects(:new).with("my request").returns(request)
+ @request.read(path).should equal(request)
+ @request.content.should equal(request)
+ end
+
+ it "should return an empty string when converted to a string with no request" do
+ @request.to_s.should == ""
+ end
+
+ it "should convert the request to pem format when converted to a string" do
+ request = mock 'request', :to_pem => "pem"
+ @request.content = request
+ @request.to_s.should == "pem"
+ end
+
+ it "should have a :to_text method that it delegates to the actual key" do
+ real_request = mock 'request'
+ real_request.expects(:to_text).returns "requesttext"
+ @request.content = real_request
+ @request.to_text.should == "requesttext"
+ end
+ end
+
+ describe "when generating" do
before do
- @class = Puppet::SSL::CertificateRequest
+ @instance = @class.new("myname")
+
+ key = Puppet::SSL::Key.new("myname")
+ @key = key.generate
+
+ @request = OpenSSL::X509::Request.new
+ OpenSSL::X509::Request.expects(:new).returns(@request)
+
+ @request.stubs(:verify).returns(true)
end
- it "should be extended with the Indirector module" do
- @class.singleton_class.should be_include(Puppet::Indirector)
+ it "should use the content of the provided key if the key is a Puppet::SSL::Key instance" do
+ key = Puppet::SSL::Key.new("test")
+ key.expects(:content).returns @key
+
+ @request.expects(:sign).with{ |key, digest| key == @key }
+ @instance.generate(key)
end
- it "should indirect certificate_request" do
- @class.indirection.name.should == :certificate_request
+ it "should log that it is creating a new certificate request" do
+ Puppet.expects(:info).twice
+ @instance.generate(@key)
end
- it "should use any provided name as its name" do
- @class.new("myname").name.should == "myname"
+ it "should set the subject to [CN, name]" do
+ subject = mock 'subject'
+ OpenSSL::X509::Name.expects(:new).with([["CN", @instance.name]]).returns(subject)
+ @request.expects(:subject=).with(subject)
+ @instance.generate(@key)
end
- it "should only support the text format" do
- @class.supported_formats.should == [:s]
+ it "should set the CN to the CSR name when the CSR is not for a CA" do
+ subject = mock 'subject'
+ OpenSSL::X509::Name.expects(:new).with { |subject| subject[0][1] == @instance.name }.returns(subject)
+ @request.expects(:subject=).with(subject)
+ @instance.generate(@key)
end
- describe "when converting from a string" do
- it "should create a CSR instance with its name set to the CSR subject and its content set to the extracted CSR" do
- csr = stub 'csr', :subject => "/CN=Foo.madstop.com"
- OpenSSL::X509::Request.expects(:new).with("my csr").returns(csr)
+ it "should set the CN to the :ca_name setting when the CSR is for a CA" do
+ subject = mock 'subject'
+ Puppet.settings.expects(:value).with(:ca_name).returns "mycertname"
+ OpenSSL::X509::Name.expects(:new).with { |subject| subject[0][1] == "mycertname" }.returns(subject)
+ @request.expects(:subject=).with(subject)
+ Puppet::SSL::CertificateRequest.new(Puppet::SSL::CA_NAME).generate(@key)
+ end
- mycsr = stub 'sslcsr'
- mycsr.expects(:content=).with(csr)
+ it "should set the version to 0" do
+ @request.expects(:version=).with(0)
+ @instance.generate(@key)
+ end
- @class.expects(:new).with("foo.madstop.com").returns mycsr
+ it "should set the public key to the provided key's public key" do
+ # Yay, the private key extracts a new key each time.
+ pubkey = @key.public_key
+ @key.stubs(:public_key).returns pubkey
+ @request.expects(:public_key=).with(@key.public_key)
+ @instance.generate(@key)
+ end
- @class.from_s("my csr")
- end
+ it "should sign the csr with the provided key and a digest" do
+ digest = mock 'digest'
+ OpenSSL::Digest::MD5.expects(:new).returns(digest)
+ @request.expects(:sign).with(@key, digest)
+ @instance.generate(@key)
end
- describe "when managing instances" do
- before do
- @request = @class.new("myname")
- end
+ it "should verify the generated request using the public key" do
+ # Stupid keys don't have a competent == method.
+ @request.expects(:verify).with { |public_key| public_key.to_s == @key.public_key.to_s }.returns true
+ @instance.generate(@key)
+ end
- it "should have a name attribute" do
- @request.name.should == "myname"
- end
+ it "should fail if verification fails" do
+ @request.expects(:verify).returns false
- it "should downcase its name" do
- @class.new("MyName").name.should == "myname"
- end
+ lambda { @instance.generate(@key) }.should raise_error(Puppet::Error)
+ end
- it "should have a content attribute" do
- @request.should respond_to(:content)
- end
+ it "should fingerprint the request" do
+ @instance.expects(:fingerprint)
+ @instance.generate(@key)
+ end
- it "should be able to read requests from disk" do
- path = "/my/path"
- File.expects(:read).with(path).returns("my request")
- request = mock 'request'
- OpenSSL::X509::Request.expects(:new).with("my request").returns(request)
- @request.read(path).should equal(request)
- @request.content.should equal(request)
- end
+ it "should display the fingerprint" do
+ Puppet.stubs(:info)
+ @instance.stubs(:fingerprint).returns("FINGERPRINT")
+ Puppet.expects(:info).with { |s| s =~ /FINGERPRINT/ }
+ @instance.generate(@key)
+ end
- it "should return an empty string when converted to a string with no request" do
- @request.to_s.should == ""
- end
+ it "should return the generated request" do
+ @instance.generate(@key).should equal(@request)
+ end
- it "should convert the request to pem format when converted to a string" do
- request = mock 'request', :to_pem => "pem"
- @request.content = request
- @request.to_s.should == "pem"
- end
+ it "should set its content to the generated request" do
+ @instance.generate(@key)
+ @instance.content.should equal(@request)
+ end
+ end
- it "should have a :to_text method that it delegates to the actual key" do
- real_request = mock 'request'
- real_request.expects(:to_text).returns "requesttext"
- @request.content = real_request
- @request.to_text.should == "requesttext"
- end
- end
-
- describe "when generating" do
- before do
- @instance = @class.new("myname")
+ describe "when a CSR is saved" do
+ it "should allow arguments" do
+ csr = Puppet::SSL::CertificateRequest.new("me")
+ csr.class.indirection.stubs(:save)
- key = Puppet::SSL::Key.new("myname")
- @key = key.generate
+ lambda { csr.save :ipaddress => "foo" }.should_not raise_error
+ end
- @request = OpenSSL::X509::Request.new
- OpenSSL::X509::Request.expects(:new).returns(@request)
+ describe "and a CA is available" do
+ it "should save the CSR and trigger autosigning" do
+ ca = mock 'ca', :autosign
+ Puppet::SSL::CertificateAuthority.expects(:instance).returns ca
- @request.stubs(:verify).returns(true)
- end
+ csr = Puppet::SSL::CertificateRequest.new("me")
+ Puppet::SSL::CertificateRequest.indirection.expects(:save).with(nil, csr)
- it "should use the content of the provided key if the key is a Puppet::SSL::Key instance" do
- key = Puppet::SSL::Key.new("test")
- key.expects(:content).returns @key
+ csr.save
+ end
+ end
- @request.expects(:sign).with{ |key, digest| key == @key }
- @instance.generate(key)
- end
+ describe "and a CA is not available" do
+ it "should save the CSR" do
+ Puppet::SSL::CertificateAuthority.expects(:instance).returns nil
- it "should log that it is creating a new certificate request" do
- Puppet.expects(:info).twice
- @instance.generate(@key)
- end
+ csr = Puppet::SSL::CertificateRequest.new("me")
+ Puppet::SSL::CertificateRequest.indirection.expects(:save).with(nil, csr)
- it "should set the subject to [CN, name]" do
- subject = mock 'subject'
- OpenSSL::X509::Name.expects(:new).with([["CN", @instance.name]]).returns(subject)
- @request.expects(:subject=).with(subject)
- @instance.generate(@key)
- end
-
- it "should set the CN to the CSR name when the CSR is not for a CA" do
- subject = mock 'subject'
- OpenSSL::X509::Name.expects(:new).with { |subject| subject[0][1] == @instance.name }.returns(subject)
- @request.expects(:subject=).with(subject)
- @instance.generate(@key)
- end
-
- it "should set the CN to the :ca_name setting when the CSR is for a CA" do
- subject = mock 'subject'
- Puppet.settings.expects(:value).with(:ca_name).returns "mycertname"
- OpenSSL::X509::Name.expects(:new).with { |subject| subject[0][1] == "mycertname" }.returns(subject)
- @request.expects(:subject=).with(subject)
- Puppet::SSL::CertificateRequest.new(Puppet::SSL::CA_NAME).generate(@key)
- end
-
- it "should set the version to 0" do
- @request.expects(:version=).with(0)
- @instance.generate(@key)
- end
-
- it "should set the public key to the provided key's public key" do
- # Yay, the private key extracts a new key each time.
- pubkey = @key.public_key
- @key.stubs(:public_key).returns pubkey
- @request.expects(:public_key=).with(@key.public_key)
- @instance.generate(@key)
- end
-
- it "should sign the csr with the provided key and a digest" do
- digest = mock 'digest'
- OpenSSL::Digest::MD5.expects(:new).returns(digest)
- @request.expects(:sign).with(@key, digest)
- @instance.generate(@key)
- end
-
- it "should verify the generated request using the public key" do
- # Stupid keys don't have a competent == method.
- @request.expects(:verify).with { |public_key| public_key.to_s == @key.public_key.to_s }.returns true
- @instance.generate(@key)
- end
-
- it "should fail if verification fails" do
- @request.expects(:verify).returns false
-
- lambda { @instance.generate(@key) }.should raise_error(Puppet::Error)
- end
-
- it "should fingerprint the request" do
- @instance.expects(:fingerprint)
- @instance.generate(@key)
- end
-
- it "should display the fingerprint" do
- Puppet.stubs(:info)
- @instance.stubs(:fingerprint).returns("FINGERPRINT")
- Puppet.expects(:info).with { |s| s =~ /FINGERPRINT/ }
- @instance.generate(@key)
- end
-
- it "should return the generated request" do
- @instance.generate(@key).should equal(@request)
- end
-
- it "should set its content to the generated request" do
- @instance.generate(@key)
- @instance.content.should equal(@request)
- end
- end
-
- describe "when a CSR is saved" do
- it "should allow arguments" do
- csr = Puppet::SSL::CertificateRequest.new("me")
- csr.class.indirection.stubs(:save)
-
- lambda { csr.save :ipaddress => "foo" }.should_not raise_error
- end
-
- describe "and a CA is available" do
- it "should save the CSR and trigger autosigning" do
- ca = mock 'ca', :autosign
- Puppet::SSL::CertificateAuthority.expects(:instance).returns ca
-
- csr = Puppet::SSL::CertificateRequest.new("me")
- Puppet::SSL::CertificateRequest.indirection.expects(:save).with(nil, csr)
-
- csr.save
- end
- end
-
- describe "and a CA is not available" do
- it "should save the CSR" do
- Puppet::SSL::CertificateAuthority.expects(:instance).returns nil
-
- csr = Puppet::SSL::CertificateRequest.new("me")
- Puppet::SSL::CertificateRequest.indirection.expects(:save).with(nil, csr)
-
- csr.save
- end
- end
+ csr.save
+ end
end
+ end
end
diff --git a/spec/unit/ssl/certificate_revocation_list_spec.rb b/spec/unit/ssl/certificate_revocation_list_spec.rb
index 3d15db7..f9993d5 100755
--- a/spec/unit/ssl/certificate_revocation_list_spec.rb
+++ b/spec/unit/ssl/certificate_revocation_list_spec.rb
@@ -5,164 +5,164 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/ssl/certificate_revocation_list'
describe Puppet::SSL::CertificateRevocationList do
- before do
- @cert = stub 'cert', :subject => "mysubject"
- @key = stub 'key', :private? => true
+ before do
+ @cert = stub 'cert', :subject => "mysubject"
+ @key = stub 'key', :private? => true
- @class = Puppet::SSL::CertificateRevocationList
- end
+ @class = Puppet::SSL::CertificateRevocationList
+ end
- it "should only support the text format" do
- @class.supported_formats.should == [:s]
- end
+ it "should only support the text format" do
+ @class.supported_formats.should == [:s]
+ end
- describe "when converting from a string" do
- it "should create a CRL instance with its name set to 'foo' and its content set to the extracted CRL" do
- crl = stub 'crl'
- OpenSSL::X509::CRL.expects(:new).returns(crl)
+ describe "when converting from a string" do
+ it "should create a CRL instance with its name set to 'foo' and its content set to the extracted CRL" do
+ crl = stub 'crl'
+ OpenSSL::X509::CRL.expects(:new).returns(crl)
- mycrl = stub 'sslcrl'
- mycrl.expects(:content=).with(crl)
+ mycrl = stub 'sslcrl'
+ mycrl.expects(:content=).with(crl)
- @class.expects(:new).with("foo").returns mycrl
+ @class.expects(:new).with("foo").returns mycrl
- @class.from_s("my crl").should == mycrl
- end
+ @class.from_s("my crl").should == mycrl
end
+ end
- describe "when an instance" do
- before do
- @class.any_instance.stubs(:read_or_generate)
+ describe "when an instance" do
+ before do
+ @class.any_instance.stubs(:read_or_generate)
- @crl = @class.new("whatever")
- end
+ @crl = @class.new("whatever")
+ end
- it "should always use 'crl' for its name" do
- @crl.name.should == "crl"
- end
+ it "should always use 'crl' for its name" do
+ @crl.name.should == "crl"
+ end
- it "should have a content attribute" do
- @crl.should respond_to(:content)
- end
+ it "should have a content attribute" do
+ @crl.should respond_to(:content)
end
+ end
- describe "when generating the crl" do
- before do
- @real_crl = mock 'crl'
- @real_crl.stub_everything
+ describe "when generating the crl" do
+ before do
+ @real_crl = mock 'crl'
+ @real_crl.stub_everything
- OpenSSL::X509::CRL.stubs(:new).returns(@real_crl)
+ OpenSSL::X509::CRL.stubs(:new).returns(@real_crl)
- @class.any_instance.stubs(:read_or_generate)
+ @class.any_instance.stubs(:read_or_generate)
- @crl = @class.new("crl")
- end
+ @crl = @class.new("crl")
+ end
- it "should set its issuer to the subject of the passed certificate" do
- @real_crl.expects(:issuer=).with(@cert.subject)
+ it "should set its issuer to the subject of the passed certificate" do
+ @real_crl.expects(:issuer=).with(@cert.subject)
- @crl.generate(@cert, @key)
- end
+ @crl.generate(@cert, @key)
+ end
- it "should set its version to 1" do
- @real_crl.expects(:version=).with(1)
+ it "should set its version to 1" do
+ @real_crl.expects(:version=).with(1)
- @crl.generate(@cert, @key)
- end
+ @crl.generate(@cert, @key)
+ end
- it "should create an instance of OpenSSL::X509::CRL" do
- OpenSSL::X509::CRL.expects(:new).returns(@real_crl)
+ it "should create an instance of OpenSSL::X509::CRL" do
+ OpenSSL::X509::CRL.expects(:new).returns(@real_crl)
- @crl.generate(@cert, @key)
- end
+ @crl.generate(@cert, @key)
+ end
- # The next three tests aren't good, but at least they
- # specify the behaviour.
- it "should add an extension for the CRL number" do
- @real_crl.expects(:extensions=)
- @crl.generate(@cert, @key)
- end
+ # The next three tests aren't good, but at least they
+ # specify the behaviour.
+ it "should add an extension for the CRL number" do
+ @real_crl.expects(:extensions=)
+ @crl.generate(@cert, @key)
+ end
- it "should set the last update time" do
- @real_crl.expects(:last_update=)
- @crl.generate(@cert, @key)
- end
+ it "should set the last update time" do
+ @real_crl.expects(:last_update=)
+ @crl.generate(@cert, @key)
+ end
- it "should set the next update time" do
- @real_crl.expects(:next_update=)
- @crl.generate(@cert, @key)
- end
+ it "should set the next update time" do
+ @real_crl.expects(:next_update=)
+ @crl.generate(@cert, @key)
+ end
- it "should sign the CRL" do
- @real_crl.expects(:sign).with { |key, digest| key == @key }
- @crl.generate(@cert, @key)
- end
+ it "should sign the CRL" do
+ @real_crl.expects(:sign).with { |key, digest| key == @key }
+ @crl.generate(@cert, @key)
+ end
- it "should set the content to the generated crl" do
- @crl.generate(@cert, @key)
- @crl.content.should equal(@real_crl)
- end
+ it "should set the content to the generated crl" do
+ @crl.generate(@cert, @key)
+ @crl.content.should equal(@real_crl)
+ end
- it "should return the generated crl" do
- @crl.generate(@cert, @key).should equal(@real_crl)
- end
+ it "should return the generated crl" do
+ @crl.generate(@cert, @key).should equal(@real_crl)
end
+ end
- # This test suite isn't exactly complete, because the
- # SSL stuff is very complicated. It just hits the high points.
- describe "when revoking a certificate" do
- before do
- @class.wrapped_class.any_instance.stubs(:issuer=)
- @class.wrapped_class.any_instance.stubs(:sign)
+ # This test suite isn't exactly complete, because the
+ # SSL stuff is very complicated. It just hits the high points.
+ describe "when revoking a certificate" do
+ before do
+ @class.wrapped_class.any_instance.stubs(:issuer=)
+ @class.wrapped_class.any_instance.stubs(:sign)
- @crl = @class.new("crl")
- @crl.generate(@cert, @key)
- @crl.content.stubs(:sign)
+ @crl = @class.new("crl")
+ @crl.generate(@cert, @key)
+ @crl.content.stubs(:sign)
- @crl.stubs :save
+ @crl.stubs :save
- @key = mock 'key'
- end
+ @key = mock 'key'
+ end
- it "should require a serial number and the CA's private key" do
- lambda { @crl.revoke }.should raise_error(ArgumentError)
- end
+ it "should require a serial number and the CA's private key" do
+ lambda { @crl.revoke }.should raise_error(ArgumentError)
+ end
- it "should default to OpenSSL::OCSP::REVOKED_STATUS_KEYCOMPROMISE as the revocation reason" do
- # This makes it a bit more of an integration test than we'd normally like, but that's life
- # with openssl.
- reason = OpenSSL::ASN1::Enumerated(OpenSSL::OCSP::REVOKED_STATUS_KEYCOMPROMISE)
- OpenSSL::ASN1.expects(:Enumerated).with(OpenSSL::OCSP::REVOKED_STATUS_KEYCOMPROMISE).returns reason
+ it "should default to OpenSSL::OCSP::REVOKED_STATUS_KEYCOMPROMISE as the revocation reason" do
+ # This makes it a bit more of an integration test than we'd normally like, but that's life
+ # with openssl.
+ reason = OpenSSL::ASN1::Enumerated(OpenSSL::OCSP::REVOKED_STATUS_KEYCOMPROMISE)
+ OpenSSL::ASN1.expects(:Enumerated).with(OpenSSL::OCSP::REVOKED_STATUS_KEYCOMPROMISE).returns reason
- @crl.revoke(1, @key)
- end
+ @crl.revoke(1, @key)
+ end
- it "should mark the CRL as updated" do
- time = Time.now
- Time.stubs(:now).returns time
+ it "should mark the CRL as updated" do
+ time = Time.now
+ Time.stubs(:now).returns time
- @crl.content.expects(:last_update=).with(time)
+ @crl.content.expects(:last_update=).with(time)
- @crl.revoke(1, @key)
- end
+ @crl.revoke(1, @key)
+ end
- it "should mark the CRL valid for five years" do
- time = Time.now
- Time.stubs(:now).returns time
+ it "should mark the CRL valid for five years" do
+ time = Time.now
+ Time.stubs(:now).returns time
- @crl.content.expects(:next_update=).with(time + (5 * 365*24*60*60))
+ @crl.content.expects(:next_update=).with(time + (5 * 365*24*60*60))
- @crl.revoke(1, @key)
- end
+ @crl.revoke(1, @key)
+ end
- it "should sign the CRL with the CA's private key and a digest instance" do
- @crl.content.expects(:sign).with { |key, digest| key == @key and digest.is_a?(OpenSSL::Digest::SHA1) }
- @crl.revoke(1, @key)
- end
+ it "should sign the CRL with the CA's private key and a digest instance" do
+ @crl.content.expects(:sign).with { |key, digest| key == @key and digest.is_a?(OpenSSL::Digest::SHA1) }
+ @crl.revoke(1, @key)
+ end
- it "should save the CRL" do
- @crl.expects :save
- @crl.revoke(1, @key)
- end
+ it "should save the CRL" do
+ @crl.expects :save
+ @crl.revoke(1, @key)
end
+ end
end
diff --git a/spec/unit/ssl/certificate_spec.rb b/spec/unit/ssl/certificate_spec.rb
index 6bd7e77..842aa35 100755
--- a/spec/unit/ssl/certificate_spec.rb
+++ b/spec/unit/ssl/certificate_spec.rb
@@ -5,120 +5,120 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/ssl/certificate'
describe Puppet::SSL::Certificate do
- before do
- @class = Puppet::SSL::Certificate
+ before do
+ @class = Puppet::SSL::Certificate
+ end
+
+ after do
+ @class.instance_variable_set("@ca_location", nil)
+ end
+
+ it "should be extended with the Indirector module" do
+ @class.singleton_class.should be_include(Puppet::Indirector)
+ end
+
+ it "should indirect certificate" do
+ @class.indirection.name.should == :certificate
+ end
+
+ it "should only support the text format" do
+ @class.supported_formats.should == [:s]
+ end
+
+ describe "when converting from a string" do
+ it "should create a certificate instance with its name set to the certificate subject and its content set to the extracted certificate" do
+ cert = stub 'certificate', :subject => "/CN=Foo.madstop.com"
+ OpenSSL::X509::Certificate.expects(:new).with("my certificate").returns(cert)
+
+ mycert = stub 'sslcert'
+ mycert.expects(:content=).with(cert)
+
+ @class.expects(:new).with("foo.madstop.com").returns mycert
+
+ @class.from_s("my certificate")
end
- after do
- @class.instance_variable_set("@ca_location", nil)
+ it "should create multiple certificate instances when asked" do
+ cert1 = stub 'cert1'
+ @class.expects(:from_s).with("cert1").returns cert1
+ cert2 = stub 'cert2'
+ @class.expects(:from_s).with("cert2").returns cert2
+
+ @class.from_multiple_s("cert1\n---\ncert2").should == [cert1, cert2]
end
+ end
- it "should be extended with the Indirector module" do
- @class.singleton_class.should be_include(Puppet::Indirector)
+ describe "when converting to a string" do
+ before do
+ @certificate = @class.new("myname")
end
- it "should indirect certificate" do
- @class.indirection.name.should == :certificate
+ it "should return an empty string when it has no certificate" do
+ @certificate.to_s.should == ""
end
- it "should only support the text format" do
- @class.supported_formats.should == [:s]
+ it "should convert the certificate to pem format" do
+ certificate = mock 'certificate', :to_pem => "pem"
+ @certificate.content = certificate
+ @certificate.to_s.should == "pem"
end
- describe "when converting from a string" do
- it "should create a certificate instance with its name set to the certificate subject and its content set to the extracted certificate" do
- cert = stub 'certificate', :subject => "/CN=Foo.madstop.com"
- OpenSSL::X509::Certificate.expects(:new).with("my certificate").returns(cert)
+ it "should be able to convert multiple instances to a string" do
+ cert2 = @class.new("foo")
+ @certificate.expects(:to_s).returns "cert1"
+ cert2.expects(:to_s).returns "cert2"
- mycert = stub 'sslcert'
- mycert.expects(:content=).with(cert)
+ @class.to_multiple_s([@certificate, cert2]).should == "cert1\n---\ncert2"
- @class.expects(:new).with("foo.madstop.com").returns mycert
+ end
+ end
- @class.from_s("my certificate")
- end
+ describe "when managing instances" do
+ before do
+ @certificate = @class.new("myname")
+ end
- it "should create multiple certificate instances when asked" do
- cert1 = stub 'cert1'
- @class.expects(:from_s).with("cert1").returns cert1
- cert2 = stub 'cert2'
- @class.expects(:from_s).with("cert2").returns cert2
+ it "should have a name attribute" do
+ @certificate.name.should == "myname"
+ end
- @class.from_multiple_s("cert1\n---\ncert2").should == [cert1, cert2]
- end
+ it "should convert its name to a string and downcase it" do
+ @class.new(:MyName).name.should == "myname"
end
- describe "when converting to a string" do
- before do
- @certificate = @class.new("myname")
- end
+ it "should have a content attribute" do
+ @certificate.should respond_to(:content)
+ end
+
+ it "should return a nil expiration if there is no actual certificate" do
+ @certificate.stubs(:content).returns nil
- it "should return an empty string when it has no certificate" do
- @certificate.to_s.should == ""
- end
+ @certificate.expiration.should be_nil
+ end
- it "should convert the certificate to pem format" do
- certificate = mock 'certificate', :to_pem => "pem"
- @certificate.content = certificate
- @certificate.to_s.should == "pem"
- end
+ it "should use the expiration of the certificate as its expiration date" do
+ cert = stub 'cert'
+ @certificate.stubs(:content).returns cert
- it "should be able to convert multiple instances to a string" do
- cert2 = @class.new("foo")
- @certificate.expects(:to_s).returns "cert1"
- cert2.expects(:to_s).returns "cert2"
+ cert.expects(:not_after).returns "sometime"
- @class.to_multiple_s([@certificate, cert2]).should == "cert1\n---\ncert2"
+ @certificate.expiration.should == "sometime"
+ end
- end
+ it "should be able to read certificates from disk" do
+ path = "/my/path"
+ File.expects(:read).with(path).returns("my certificate")
+ certificate = mock 'certificate'
+ OpenSSL::X509::Certificate.expects(:new).with("my certificate").returns(certificate)
+ @certificate.read(path).should equal(certificate)
+ @certificate.content.should equal(certificate)
end
- describe "when managing instances" do
- before do
- @certificate = @class.new("myname")
- end
-
- it "should have a name attribute" do
- @certificate.name.should == "myname"
- end
-
- it "should convert its name to a string and downcase it" do
- @class.new(:MyName).name.should == "myname"
- end
-
- it "should have a content attribute" do
- @certificate.should respond_to(:content)
- end
-
- it "should return a nil expiration if there is no actual certificate" do
- @certificate.stubs(:content).returns nil
-
- @certificate.expiration.should be_nil
- end
-
- it "should use the expiration of the certificate as its expiration date" do
- cert = stub 'cert'
- @certificate.stubs(:content).returns cert
-
- cert.expects(:not_after).returns "sometime"
-
- @certificate.expiration.should == "sometime"
- end
-
- it "should be able to read certificates from disk" do
- path = "/my/path"
- File.expects(:read).with(path).returns("my certificate")
- certificate = mock 'certificate'
- OpenSSL::X509::Certificate.expects(:new).with("my certificate").returns(certificate)
- @certificate.read(path).should equal(certificate)
- @certificate.content.should equal(certificate)
- end
-
- it "should have a :to_text method that it delegates to the actual key" do
- real_certificate = mock 'certificate'
- real_certificate.expects(:to_text).returns "certificatetext"
- @certificate.content = real_certificate
- @certificate.to_text.should == "certificatetext"
- end
+ it "should have a :to_text method that it delegates to the actual key" do
+ real_certificate = mock 'certificate'
+ real_certificate.expects(:to_text).returns "certificatetext"
+ @certificate.content = real_certificate
+ @certificate.to_text.should == "certificatetext"
end
+ end
end
diff --git a/spec/unit/ssl/host_spec.rb b/spec/unit/ssl/host_spec.rb
index 0b6591d..b2e4339 100755
--- a/spec/unit/ssl/host_spec.rb
+++ b/spec/unit/ssl/host_spec.rb
@@ -5,703 +5,703 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/ssl/host'
describe Puppet::SSL::Host do
- before do
- @class = Puppet::SSL::Host
- @host = @class.new("myname")
- end
+ before do
+ @class = Puppet::SSL::Host
+ @host = @class.new("myname")
+ end
- after do
- # Cleaned out any cached localhost instance.
- Puppet::Util::Cacher.expire
- end
+ after do
+ # Cleaned out any cached localhost instance.
+ Puppet::Util::Cacher.expire
+ end
- it "should use any provided name as its name" do
- @host.name.should == "myname"
- end
+ it "should use any provided name as its name" do
+ @host.name.should == "myname"
+ end
- it "should retrieve its public key from its private key" do
- realkey = mock 'realkey'
- key = stub 'key', :content => realkey
- Puppet::SSL::Key.stubs(:find).returns(key)
- pubkey = mock 'public_key'
- realkey.expects(:public_key).returns pubkey
+ it "should retrieve its public key from its private key" do
+ realkey = mock 'realkey'
+ key = stub 'key', :content => realkey
+ Puppet::SSL::Key.stubs(:find).returns(key)
+ pubkey = mock 'public_key'
+ realkey.expects(:public_key).returns pubkey
- @host.public_key.should equal(pubkey)
- end
+ @host.public_key.should equal(pubkey)
+ end
- it "should default to being a non-ca host" do
- @host.ca?.should be_false
- end
+ it "should default to being a non-ca host" do
+ @host.ca?.should be_false
+ end
- it "should be a ca host if its name matches the CA_NAME" do
- Puppet::SSL::Host.stubs(:ca_name).returns "yayca"
- Puppet::SSL::Host.new("yayca").should be_ca
- end
+ it "should be a ca host if its name matches the CA_NAME" do
+ Puppet::SSL::Host.stubs(:ca_name).returns "yayca"
+ Puppet::SSL::Host.new("yayca").should be_ca
+ end
- it "should have a method for determining the CA location" do
- Puppet::SSL::Host.should respond_to(:ca_location)
- end
+ it "should have a method for determining the CA location" do
+ Puppet::SSL::Host.should respond_to(:ca_location)
+ end
- it "should have a method for specifying the CA location" do
- Puppet::SSL::Host.should respond_to(:ca_location=)
- end
+ it "should have a method for specifying the CA location" do
+ Puppet::SSL::Host.should respond_to(:ca_location=)
+ end
- it "should have a method for retrieving the default ssl host" do
- Puppet::SSL::Host.should respond_to(:ca_location=)
- end
+ it "should have a method for retrieving the default ssl host" do
+ Puppet::SSL::Host.should respond_to(:ca_location=)
+ end
- it "should have a method for producing an instance to manage the local host's keys" do
- Puppet::SSL::Host.should respond_to(:localhost)
- end
+ it "should have a method for producing an instance to manage the local host's keys" do
+ Puppet::SSL::Host.should respond_to(:localhost)
+ end
- it "should generate the certificate for the localhost instance if no certificate is available" do
- host = stub 'host', :key => nil
- Puppet::SSL::Host.expects(:new).returns host
+ it "should generate the certificate for the localhost instance if no certificate is available" do
+ host = stub 'host', :key => nil
+ Puppet::SSL::Host.expects(:new).returns host
- host.expects(:certificate).returns nil
- host.expects(:generate)
+ host.expects(:certificate).returns nil
+ host.expects(:generate)
- Puppet::SSL::Host.localhost.should equal(host)
- end
+ Puppet::SSL::Host.localhost.should equal(host)
+ end
- it "should always read the key for the localhost instance in from disk" do
- host = stub 'host', :certificate => "eh"
- Puppet::SSL::Host.expects(:new).returns host
+ it "should always read the key for the localhost instance in from disk" do
+ host = stub 'host', :certificate => "eh"
+ Puppet::SSL::Host.expects(:new).returns host
- host.expects(:key)
+ host.expects(:key)
- Puppet::SSL::Host.localhost
- end
+ Puppet::SSL::Host.localhost
+ end
+
+ it "should cache the localhost instance" do
+ host = stub 'host', :certificate => "eh", :key => 'foo'
+ Puppet::SSL::Host.expects(:new).once.returns host
+
+ Puppet::SSL::Host.localhost.should == Puppet::SSL::Host.localhost
+ end
+
+ it "should be able to expire the cached instance" do
+ one = stub 'host1', :certificate => "eh", :key => 'foo'
+ two = stub 'host2', :certificate => "eh", :key => 'foo'
+ Puppet::SSL::Host.expects(:new).times(2).returns(one).then.returns(two)
+
+ Puppet::SSL::Host.localhost.should equal(one)
+ Puppet::Util::Cacher.expire
+ Puppet::SSL::Host.localhost.should equal(two)
+ end
+
+ it "should be able to verify its certificate matches its key" do
+ Puppet::SSL::Host.new("foo").should respond_to(:certificate_matches_key?)
+ end
+
+ it "should consider the certificate invalid if it cannot find a key" do
+ host = Puppet::SSL::Host.new("foo")
+ host.expects(:key).returns nil
+
+ host.should_not be_certificate_matches_key
+ end
+
+ it "should consider the certificate invalid if it cannot find a certificate" do
+ host = Puppet::SSL::Host.new("foo")
+ host.expects(:key).returns mock("key")
+ host.expects(:certificate).returns nil
+
+ host.should_not be_certificate_matches_key
+ end
+
+ it "should consider the certificate invalid if the SSL certificate's key verification fails" do
+ host = Puppet::SSL::Host.new("foo")
+
+ key = mock 'key', :content => "private_key"
+ sslcert = mock 'sslcert'
+ certificate = mock 'cert', :content => sslcert
+
+ host.stubs(:key).returns key
+ host.stubs(:certificate).returns certificate
- it "should cache the localhost instance" do
- host = stub 'host', :certificate => "eh", :key => 'foo'
- Puppet::SSL::Host.expects(:new).once.returns host
+ sslcert.expects(:check_private_key).with("private_key").returns false
- Puppet::SSL::Host.localhost.should == Puppet::SSL::Host.localhost
+ host.should_not be_certificate_matches_key
+ end
+
+ it "should consider the certificate valid if the SSL certificate's key verification succeeds" do
+ host = Puppet::SSL::Host.new("foo")
+
+ key = mock 'key', :content => "private_key"
+ sslcert = mock 'sslcert'
+ certificate = mock 'cert', :content => sslcert
+
+ host.stubs(:key).returns key
+ host.stubs(:certificate).returns certificate
+
+ sslcert.expects(:check_private_key).with("private_key").returns true
+
+ host.should be_certificate_matches_key
+ end
+
+ describe "when specifying the CA location" do
+ before do
+ [Puppet::SSL::Key, Puppet::SSL::Certificate, Puppet::SSL::CertificateRequest, Puppet::SSL::CertificateRevocationList].each do |klass|
+ klass.stubs(:terminus_class=)
+ klass.stubs(:cache_class=)
+ end
end
- it "should be able to expire the cached instance" do
- one = stub 'host1', :certificate => "eh", :key => 'foo'
- two = stub 'host2', :certificate => "eh", :key => 'foo'
- Puppet::SSL::Host.expects(:new).times(2).returns(one).then.returns(two)
+ it "should support the location ':local'" do
+ lambda { Puppet::SSL::Host.ca_location = :local }.should_not raise_error
+ end
- Puppet::SSL::Host.localhost.should equal(one)
- Puppet::Util::Cacher.expire
- Puppet::SSL::Host.localhost.should equal(two)
+ it "should support the location ':remote'" do
+ lambda { Puppet::SSL::Host.ca_location = :remote }.should_not raise_error
end
- it "should be able to verify its certificate matches its key" do
- Puppet::SSL::Host.new("foo").should respond_to(:certificate_matches_key?)
+ it "should support the location ':none'" do
+ lambda { Puppet::SSL::Host.ca_location = :none }.should_not raise_error
end
- it "should consider the certificate invalid if it cannot find a key" do
- host = Puppet::SSL::Host.new("foo")
- host.expects(:key).returns nil
+ it "should support the location ':only'" do
+ lambda { Puppet::SSL::Host.ca_location = :only }.should_not raise_error
+ end
- host.should_not be_certificate_matches_key
+ it "should not support other modes" do
+ lambda { Puppet::SSL::Host.ca_location = :whatever }.should raise_error(ArgumentError)
end
- it "should consider the certificate invalid if it cannot find a certificate" do
- host = Puppet::SSL::Host.new("foo")
- host.expects(:key).returns mock("key")
- host.expects(:certificate).returns nil
+ describe "as 'local'" do
+ it "should set the cache class for Certificate, CertificateRevocationList, and CertificateRequest as :file" do
+ Puppet::SSL::Certificate.expects(:cache_class=).with :file
+ Puppet::SSL::CertificateRequest.expects(:cache_class=).with :file
+ Puppet::SSL::CertificateRevocationList.expects(:cache_class=).with :file
+
+ Puppet::SSL::Host.ca_location = :local
+ end
+
+ it "should set the terminus class for Key as :file" do
+ Puppet::SSL::Key.expects(:terminus_class=).with :file
+
+ Puppet::SSL::Host.ca_location = :local
+ end
- host.should_not be_certificate_matches_key
+ it "should set the terminus class for Certificate, CertificateRevocationList, and CertificateRequest as :ca" do
+ Puppet::SSL::Certificate.expects(:terminus_class=).with :ca
+ Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :ca
+ Puppet::SSL::CertificateRevocationList.expects(:terminus_class=).with :ca
+
+ Puppet::SSL::Host.ca_location = :local
+ end
end
- it "should consider the certificate invalid if the SSL certificate's key verification fails" do
- host = Puppet::SSL::Host.new("foo")
+ describe "as 'remote'" do
+ it "should set the cache class for Certificate, CertificateRevocationList, and CertificateRequest as :file" do
+ Puppet::SSL::Certificate.expects(:cache_class=).with :file
+ Puppet::SSL::CertificateRequest.expects(:cache_class=).with :file
+ Puppet::SSL::CertificateRevocationList.expects(:cache_class=).with :file
+
+ Puppet::SSL::Host.ca_location = :remote
+ end
- key = mock 'key', :content => "private_key"
- sslcert = mock 'sslcert'
- certificate = mock 'cert', :content => sslcert
+ it "should set the terminus class for Key as :file" do
+ Puppet::SSL::Key.expects(:terminus_class=).with :file
- host.stubs(:key).returns key
- host.stubs(:certificate).returns certificate
+ Puppet::SSL::Host.ca_location = :remote
+ end
- sslcert.expects(:check_private_key).with("private_key").returns false
+ it "should set the terminus class for Certificate, CertificateRevocationList, and CertificateRequest as :rest" do
+ Puppet::SSL::Certificate.expects(:terminus_class=).with :rest
+ Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :rest
+ Puppet::SSL::CertificateRevocationList.expects(:terminus_class=).with :rest
- host.should_not be_certificate_matches_key
+ Puppet::SSL::Host.ca_location = :remote
+ end
end
- it "should consider the certificate valid if the SSL certificate's key verification succeeds" do
- host = Puppet::SSL::Host.new("foo")
+ describe "as 'only'" do
+ it "should set the terminus class for Key, Certificate, CertificateRevocationList, and CertificateRequest as :ca" do
+ Puppet::SSL::Key.expects(:terminus_class=).with :ca
+ Puppet::SSL::Certificate.expects(:terminus_class=).with :ca
+ Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :ca
+ Puppet::SSL::CertificateRevocationList.expects(:terminus_class=).with :ca
+
+ Puppet::SSL::Host.ca_location = :only
+ end
- key = mock 'key', :content => "private_key"
- sslcert = mock 'sslcert'
- certificate = mock 'cert', :content => sslcert
+ it "should reset the cache class for Certificate, CertificateRevocationList, and CertificateRequest to nil" do
+ Puppet::SSL::Certificate.expects(:cache_class=).with nil
+ Puppet::SSL::CertificateRequest.expects(:cache_class=).with nil
+ Puppet::SSL::CertificateRevocationList.expects(:cache_class=).with nil
- host.stubs(:key).returns key
- host.stubs(:certificate).returns certificate
+ Puppet::SSL::Host.ca_location = :only
+ end
+ end
- sslcert.expects(:check_private_key).with("private_key").returns true
+ describe "as 'none'" do
+ it "should set the terminus class for Key, Certificate, CertificateRevocationList, and CertificateRequest as :file" do
+ Puppet::SSL::Key.expects(:terminus_class=).with :file
+ Puppet::SSL::Certificate.expects(:terminus_class=).with :file
+ Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :file
+ Puppet::SSL::CertificateRevocationList.expects(:terminus_class=).with :file
- host.should be_certificate_matches_key
+ Puppet::SSL::Host.ca_location = :none
+ end
end
+ end
- describe "when specifying the CA location" do
- before do
- [Puppet::SSL::Key, Puppet::SSL::Certificate, Puppet::SSL::CertificateRequest, Puppet::SSL::CertificateRevocationList].each do |klass|
- klass.stubs(:terminus_class=)
- klass.stubs(:cache_class=)
- end
- end
+ it "should have a class method for destroying all files related to a given host" do
+ Puppet::SSL::Host.should respond_to(:destroy)
+ end
- it "should support the location ':local'" do
- lambda { Puppet::SSL::Host.ca_location = :local }.should_not raise_error
- end
+ describe "when destroying a host's SSL files" do
+ before do
+ Puppet::SSL::Key.stubs(:destroy).returns false
+ Puppet::SSL::Certificate.stubs(:destroy).returns false
+ Puppet::SSL::CertificateRequest.stubs(:destroy).returns false
+ end
- it "should support the location ':remote'" do
- lambda { Puppet::SSL::Host.ca_location = :remote }.should_not raise_error
- end
+ it "should destroy its certificate, certificate request, and key" do
+ Puppet::SSL::Key.expects(:destroy).with("myhost")
+ Puppet::SSL::Certificate.expects(:destroy).with("myhost")
+ Puppet::SSL::CertificateRequest.expects(:destroy).with("myhost")
- it "should support the location ':none'" do
- lambda { Puppet::SSL::Host.ca_location = :none }.should_not raise_error
- end
+ Puppet::SSL::Host.destroy("myhost")
+ end
- it "should support the location ':only'" do
- lambda { Puppet::SSL::Host.ca_location = :only }.should_not raise_error
- end
+ it "should return true if any of the classes returned true" do
+ Puppet::SSL::Certificate.expects(:destroy).with("myhost").returns true
- it "should not support other modes" do
- lambda { Puppet::SSL::Host.ca_location = :whatever }.should raise_error(ArgumentError)
- end
+ Puppet::SSL::Host.destroy("myhost").should be_true
+ end
- describe "as 'local'" do
- it "should set the cache class for Certificate, CertificateRevocationList, and CertificateRequest as :file" do
- Puppet::SSL::Certificate.expects(:cache_class=).with :file
- Puppet::SSL::CertificateRequest.expects(:cache_class=).with :file
- Puppet::SSL::CertificateRevocationList.expects(:cache_class=).with :file
+ it "should return false if none of the classes returned true" do
+ Puppet::SSL::Host.destroy("myhost").should be_false
+ end
+ end
- Puppet::SSL::Host.ca_location = :local
- end
+ describe "when initializing" do
+ it "should default its name to the :certname setting" do
+ Puppet.settings.expects(:value).with(:certname).returns "myname"
- it "should set the terminus class for Key as :file" do
- Puppet::SSL::Key.expects(:terminus_class=).with :file
+ Puppet::SSL::Host.new.name.should == "myname"
+ end
- Puppet::SSL::Host.ca_location = :local
- end
+ it "should downcase a passed in name" do
+ Puppet::SSL::Host.new("Host.Domain.Com").name.should == "host.domain.com"
+ end
- it "should set the terminus class for Certificate, CertificateRevocationList, and CertificateRequest as :ca" do
- Puppet::SSL::Certificate.expects(:terminus_class=).with :ca
- Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :ca
- Puppet::SSL::CertificateRevocationList.expects(:terminus_class=).with :ca
+ it "should downcase the certname if it's used" do
+ Puppet.settings.expects(:value).with(:certname).returns "Host.Domain.Com"
+ Puppet::SSL::Host.new.name.should == "host.domain.com"
+ end
- Puppet::SSL::Host.ca_location = :local
- end
- end
+ it "should indicate that it is a CA host if its name matches the ca_name constant" do
+ Puppet::SSL::Host.stubs(:ca_name).returns "myca"
+ Puppet::SSL::Host.new("myca").should be_ca
+ end
+ end
- describe "as 'remote'" do
- it "should set the cache class for Certificate, CertificateRevocationList, and CertificateRequest as :file" do
- Puppet::SSL::Certificate.expects(:cache_class=).with :file
- Puppet::SSL::CertificateRequest.expects(:cache_class=).with :file
- Puppet::SSL::CertificateRevocationList.expects(:cache_class=).with :file
+ describe "when managing its private key" do
+ before do
+ @realkey = "mykey"
+ @key = stub 'key', :content => @realkey
+ end
- Puppet::SSL::Host.ca_location = :remote
- end
+ it "should return nil if the key is not set and cannot be found" do
+ Puppet::SSL::Key.expects(:find).with("myname").returns(nil)
+ @host.key.should be_nil
+ end
- it "should set the terminus class for Key as :file" do
- Puppet::SSL::Key.expects(:terminus_class=).with :file
+ it "should find the key in the Key class and return the Puppet instance" do
+ Puppet::SSL::Key.expects(:find).with("myname").returns(@key)
+ @host.key.should equal(@key)
+ end
- Puppet::SSL::Host.ca_location = :remote
- end
+ it "should be able to generate and save a new key" do
+ Puppet::SSL::Key.expects(:new).with("myname").returns(@key)
- it "should set the terminus class for Certificate, CertificateRevocationList, and CertificateRequest as :rest" do
- Puppet::SSL::Certificate.expects(:terminus_class=).with :rest
- Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :rest
- Puppet::SSL::CertificateRevocationList.expects(:terminus_class=).with :rest
+ @key.expects(:generate)
+ @key.expects(:save)
- Puppet::SSL::Host.ca_location = :remote
- end
- end
+ @host.generate_key.should be_true
+ @host.key.should equal(@key)
+ end
- describe "as 'only'" do
- it "should set the terminus class for Key, Certificate, CertificateRevocationList, and CertificateRequest as :ca" do
- Puppet::SSL::Key.expects(:terminus_class=).with :ca
- Puppet::SSL::Certificate.expects(:terminus_class=).with :ca
- Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :ca
- Puppet::SSL::CertificateRevocationList.expects(:terminus_class=).with :ca
+ it "should not retain keys that could not be saved" do
+ Puppet::SSL::Key.expects(:new).with("myname").returns(@key)
- Puppet::SSL::Host.ca_location = :only
- end
+ @key.stubs(:generate)
+ @key.expects(:save).raises "eh"
- it "should reset the cache class for Certificate, CertificateRevocationList, and CertificateRequest to nil" do
- Puppet::SSL::Certificate.expects(:cache_class=).with nil
- Puppet::SSL::CertificateRequest.expects(:cache_class=).with nil
- Puppet::SSL::CertificateRevocationList.expects(:cache_class=).with nil
+ lambda { @host.generate_key }.should raise_error
+ @host.key.should be_nil
+ end
- Puppet::SSL::Host.ca_location = :only
- end
- end
+ it "should return any previously found key without requerying" do
+ Puppet::SSL::Key.expects(:find).with("myname").returns(@key).once
+ @host.key.should equal(@key)
+ @host.key.should equal(@key)
+ end
+ end
- describe "as 'none'" do
- it "should set the terminus class for Key, Certificate, CertificateRevocationList, and CertificateRequest as :file" do
- Puppet::SSL::Key.expects(:terminus_class=).with :file
- Puppet::SSL::Certificate.expects(:terminus_class=).with :file
- Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :file
- Puppet::SSL::CertificateRevocationList.expects(:terminus_class=).with :file
+ describe "when managing its certificate request" do
+ before do
+ @realrequest = "real request"
+ @request = stub 'request', :content => @realrequest
+ end
- Puppet::SSL::Host.ca_location = :none
- end
- end
+ it "should return nil if the key is not set and cannot be found" do
+ Puppet::SSL::CertificateRequest.expects(:find).with("myname").returns(nil)
+ @host.certificate_request.should be_nil
end
- it "should have a class method for destroying all files related to a given host" do
- Puppet::SSL::Host.should respond_to(:destroy)
+ it "should find the request in the Key class and return it and return the Puppet SSL request" do
+ Puppet::SSL::CertificateRequest.expects(:find).with("myname").returns @request
+
+ @host.certificate_request.should equal(@request)
end
- describe "when destroying a host's SSL files" do
- before do
- Puppet::SSL::Key.stubs(:destroy).returns false
- Puppet::SSL::Certificate.stubs(:destroy).returns false
- Puppet::SSL::CertificateRequest.stubs(:destroy).returns false
- end
+ it "should generate a new key when generating the cert request if no key exists" do
+ Puppet::SSL::CertificateRequest.expects(:new).with("myname").returns @request
+
+ key = stub 'key', :public_key => mock("public_key"), :content => "mycontent"
- it "should destroy its certificate, certificate request, and key" do
- Puppet::SSL::Key.expects(:destroy).with("myhost")
- Puppet::SSL::Certificate.expects(:destroy).with("myhost")
- Puppet::SSL::CertificateRequest.expects(:destroy).with("myhost")
+ @host.expects(:key).times(2).returns(nil).then.returns(key)
+ @host.expects(:generate_key).returns(key)
- Puppet::SSL::Host.destroy("myhost")
- end
+ @request.stubs(:generate)
+ @request.stubs(:save)
- it "should return true if any of the classes returned true" do
- Puppet::SSL::Certificate.expects(:destroy).with("myhost").returns true
+ @host.generate_certificate_request
+ end
+
+ it "should be able to generate and save a new request using the private key" do
+ Puppet::SSL::CertificateRequest.expects(:new).with("myname").returns @request
- Puppet::SSL::Host.destroy("myhost").should be_true
- end
+ key = stub 'key', :public_key => mock("public_key"), :content => "mycontent"
+ @host.stubs(:key).returns(key)
+ @request.expects(:generate).with("mycontent")
+ @request.expects(:save)
- it "should return false if none of the classes returned true" do
- Puppet::SSL::Host.destroy("myhost").should be_false
- end
+ @host.generate_certificate_request.should be_true
+ @host.certificate_request.should equal(@request)
end
- describe "when initializing" do
- it "should default its name to the :certname setting" do
- Puppet.settings.expects(:value).with(:certname).returns "myname"
+ it "should return any previously found request without requerying" do
+ Puppet::SSL::CertificateRequest.expects(:find).with("myname").returns(@request).once
+
+ @host.certificate_request.should equal(@request)
+ @host.certificate_request.should equal(@request)
+ end
- Puppet::SSL::Host.new.name.should == "myname"
- end
+ it "should not keep its certificate request in memory if the request cannot be saved" do
+ Puppet::SSL::CertificateRequest.expects(:new).with("myname").returns @request
- it "should downcase a passed in name" do
- Puppet::SSL::Host.new("Host.Domain.Com").name.should == "host.domain.com"
- end
+ key = stub 'key', :public_key => mock("public_key"), :content => "mycontent"
+ @host.stubs(:key).returns(key)
+ @request.stubs(:generate)
+ @request.expects(:save).raises "eh"
- it "should downcase the certname if it's used" do
- Puppet.settings.expects(:value).with(:certname).returns "Host.Domain.Com"
- Puppet::SSL::Host.new.name.should == "host.domain.com"
- end
+ lambda { @host.generate_certificate_request }.should raise_error
- it "should indicate that it is a CA host if its name matches the ca_name constant" do
- Puppet::SSL::Host.stubs(:ca_name).returns "myca"
- Puppet::SSL::Host.new("myca").should be_ca
- end
+ @host.certificate_request.should be_nil
end
+ end
- describe "when managing its private key" do
- before do
- @realkey = "mykey"
- @key = stub 'key', :content => @realkey
- end
+ describe "when managing its certificate" do
+ before do
+ @realcert = mock 'certificate'
+ @cert = stub 'cert', :content => @realcert
- it "should return nil if the key is not set and cannot be found" do
- Puppet::SSL::Key.expects(:find).with("myname").returns(nil)
- @host.key.should be_nil
- end
+ @host.stubs(:key).returns mock("key")
+ @host.stubs(:certificate_matches_key?).returns true
+ end
- it "should find the key in the Key class and return the Puppet instance" do
- Puppet::SSL::Key.expects(:find).with("myname").returns(@key)
- @host.key.should equal(@key)
- end
+ it "should find the CA certificate if it does not have a certificate" do
+ Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).returns mock("cacert")
+ Puppet::SSL::Certificate.stubs(:find).with("myname").returns @cert
- it "should be able to generate and save a new key" do
- Puppet::SSL::Key.expects(:new).with("myname").returns(@key)
+ @host.certificate
+ end
- @key.expects(:generate)
- @key.expects(:save)
+ it "should not find the CA certificate if it is the CA host" do
+ @host.expects(:ca?).returns true
+ Puppet::SSL::Certificate.stubs(:find)
+ Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).never
- @host.generate_key.should be_true
- @host.key.should equal(@key)
- end
+ @host.certificate
+ end
- it "should not retain keys that could not be saved" do
- Puppet::SSL::Key.expects(:new).with("myname").returns(@key)
+ it "should return nil if it cannot find a CA certificate" do
+ Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).returns nil
+ Puppet::SSL::Certificate.expects(:find).with("myname").never
- @key.stubs(:generate)
- @key.expects(:save).raises "eh"
+ @host.certificate.should be_nil
+ end
- lambda { @host.generate_key }.should raise_error
- @host.key.should be_nil
- end
+ it "should find the key if it does not have one" do
+ Puppet::SSL::Certificate.stubs(:find)
+ @host.expects(:key).returns mock("key")
- it "should return any previously found key without requerying" do
- Puppet::SSL::Key.expects(:find).with("myname").returns(@key).once
- @host.key.should equal(@key)
- @host.key.should equal(@key)
- end
+ @host.certificate
end
- describe "when managing its certificate request" do
- before do
- @realrequest = "real request"
- @request = stub 'request', :content => @realrequest
- end
+ it "should generate the key if one cannot be found" do
+ Puppet::SSL::Certificate.stubs(:find)
- it "should return nil if the key is not set and cannot be found" do
- Puppet::SSL::CertificateRequest.expects(:find).with("myname").returns(nil)
- @host.certificate_request.should be_nil
- end
+ @host.expects(:key).returns nil
+ @host.expects(:generate_key)
- it "should find the request in the Key class and return it and return the Puppet SSL request" do
- Puppet::SSL::CertificateRequest.expects(:find).with("myname").returns @request
+ @host.certificate
+ end
+
+ it "should find the certificate in the Certificate class and return the Puppet certificate instance" do
+ Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).returns mock("cacert")
+ Puppet::SSL::Certificate.expects(:find).with("myname").returns @cert
- @host.certificate_request.should equal(@request)
- end
+ @host.certificate.should equal(@cert)
+ end
- it "should generate a new key when generating the cert request if no key exists" do
- Puppet::SSL::CertificateRequest.expects(:new).with("myname").returns @request
+ it "should fail if the found certificate does not match the private key" do
+ @host.expects(:certificate_matches_key?).returns false
- key = stub 'key', :public_key => mock("public_key"), :content => "mycontent"
+ Puppet::SSL::Certificate.stubs(:find).returns @cert
- @host.expects(:key).times(2).returns(nil).then.returns(key)
- @host.expects(:generate_key).returns(key)
+ lambda { @host.certificate }.should raise_error(Puppet::Error)
+ end
- @request.stubs(:generate)
- @request.stubs(:save)
+ it "should return any previously found certificate" do
+ Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).returns mock("cacert")
+ Puppet::SSL::Certificate.expects(:find).with("myname").returns(@cert).once
- @host.generate_certificate_request
- end
+ @host.certificate.should equal(@cert)
+ @host.certificate.should equal(@cert)
+ end
+ end
- it "should be able to generate and save a new request using the private key" do
- Puppet::SSL::CertificateRequest.expects(:new).with("myname").returns @request
+ it "should have a method for listing certificate hosts" do
+ Puppet::SSL::Host.should respond_to(:search)
+ end
- key = stub 'key', :public_key => mock("public_key"), :content => "mycontent"
- @host.stubs(:key).returns(key)
- @request.expects(:generate).with("mycontent")
- @request.expects(:save)
+ describe "when listing certificate hosts" do
+ it "should default to listing all clients with any file types" do
+ Puppet::SSL::Key.expects(:search).returns []
+ Puppet::SSL::Certificate.expects(:search).returns []
+ Puppet::SSL::CertificateRequest.expects(:search).returns []
+ Puppet::SSL::Host.search
+ end
- @host.generate_certificate_request.should be_true
- @host.certificate_request.should equal(@request)
- end
+ it "should be able to list only clients with a key" do
+ Puppet::SSL::Key.expects(:search).returns []
+ Puppet::SSL::Certificate.expects(:search).never
+ Puppet::SSL::CertificateRequest.expects(:search).never
+ Puppet::SSL::Host.search :for => Puppet::SSL::Key
+ end
- it "should return any previously found request without requerying" do
- Puppet::SSL::CertificateRequest.expects(:find).with("myname").returns(@request).once
+ it "should be able to list only clients with a certificate" do
+ Puppet::SSL::Key.expects(:search).never
+ Puppet::SSL::Certificate.expects(:search).returns []
+ Puppet::SSL::CertificateRequest.expects(:search).never
+ Puppet::SSL::Host.search :for => Puppet::SSL::Certificate
+ end
- @host.certificate_request.should equal(@request)
- @host.certificate_request.should equal(@request)
- end
+ it "should be able to list only clients with a certificate request" do
+ Puppet::SSL::Key.expects(:search).never
+ Puppet::SSL::Certificate.expects(:search).never
+ Puppet::SSL::CertificateRequest.expects(:search).returns []
+ Puppet::SSL::Host.search :for => Puppet::SSL::CertificateRequest
+ end
- it "should not keep its certificate request in memory if the request cannot be saved" do
- Puppet::SSL::CertificateRequest.expects(:new).with("myname").returns @request
+ it "should return a Host instance created with the name of each found instance" do
+ key = stub 'key', :name => "key"
+ cert = stub 'cert', :name => "cert"
+ csr = stub 'csr', :name => "csr"
- key = stub 'key', :public_key => mock("public_key"), :content => "mycontent"
- @host.stubs(:key).returns(key)
- @request.stubs(:generate)
- @request.expects(:save).raises "eh"
+ Puppet::SSL::Key.expects(:search).returns [key]
+ Puppet::SSL::Certificate.expects(:search).returns [cert]
+ Puppet::SSL::CertificateRequest.expects(:search).returns [csr]
- lambda { @host.generate_certificate_request }.should raise_error
+ returned = []
+ %w{key cert csr}.each do |name|
+ result = mock(name)
+ returned << result
+ Puppet::SSL::Host.expects(:new).with(name).returns result
+ end
- @host.certificate_request.should be_nil
- end
+ result = Puppet::SSL::Host.search
+ returned.each do |r|
+ result.should be_include(r)
+ end
end
+ end
- describe "when managing its certificate" do
- before do
- @realcert = mock 'certificate'
- @cert = stub 'cert', :content => @realcert
+ it "should have a method for generating all necessary files" do
+ Puppet::SSL::Host.new("me").should respond_to(:generate)
+ end
- @host.stubs(:key).returns mock("key")
- @host.stubs(:certificate_matches_key?).returns true
- end
+ describe "when generating files" do
+ before do
+ @host = Puppet::SSL::Host.new("me")
+ @host.stubs(:generate_key)
+ @host.stubs(:generate_certificate_request)
+ end
- it "should find the CA certificate if it does not have a certificate" do
- Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).returns mock("cacert")
- Puppet::SSL::Certificate.stubs(:find).with("myname").returns @cert
+ it "should generate a key if one is not present" do
+ @host.stubs(:key).returns nil
+ @host.expects(:generate_key)
- @host.certificate
- end
+ @host.generate
+ end
- it "should not find the CA certificate if it is the CA host" do
- @host.expects(:ca?).returns true
- Puppet::SSL::Certificate.stubs(:find)
- Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).never
+ it "should generate a certificate request if one is not present" do
+ @host.expects(:certificate_request).returns nil
+ @host.expects(:generate_certificate_request)
- @host.certificate
- end
+ @host.generate
+ end
- it "should return nil if it cannot find a CA certificate" do
- Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).returns nil
- Puppet::SSL::Certificate.expects(:find).with("myname").never
+ describe "and it can create a certificate authority" do
+ before do
+ @ca = mock 'ca'
+ Puppet::SSL::CertificateAuthority.stubs(:instance).returns @ca
+ end
- @host.certificate.should be_nil
- end
+ it "should use the CA to sign its certificate request if it does not have a certificate" do
+ @host.expects(:certificate).returns nil
- it "should find the key if it does not have one" do
- Puppet::SSL::Certificate.stubs(:find)
- @host.expects(:key).returns mock("key")
+ @ca.expects(:sign).with(@host.name)
- @host.certificate
- end
+ @host.generate
+ end
+ end
- it "should generate the key if one cannot be found" do
- Puppet::SSL::Certificate.stubs(:find)
+ describe "and it cannot create a certificate authority" do
+ before do
+ Puppet::SSL::CertificateAuthority.stubs(:instance).returns nil
+ end
- @host.expects(:key).returns nil
- @host.expects(:generate_key)
+ it "should seek its certificate" do
+ @host.expects(:certificate)
- @host.certificate
- end
+ @host.generate
+ end
+ end
+ end
- it "should find the certificate in the Certificate class and return the Puppet certificate instance" do
- Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).returns mock("cacert")
- Puppet::SSL::Certificate.expects(:find).with("myname").returns @cert
+ it "should have a method for creating an SSL store" do
+ Puppet::SSL::Host.new("me").should respond_to(:ssl_store)
+ end
- @host.certificate.should equal(@cert)
- end
+ it "should always return the same store" do
+ host = Puppet::SSL::Host.new("foo")
+ store = mock 'store'
+ store.stub_everything
+ OpenSSL::X509::Store.expects(:new).returns store
+ host.ssl_store.should equal(host.ssl_store)
+ end
- it "should fail if the found certificate does not match the private key" do
- @host.expects(:certificate_matches_key?).returns false
+ describe "when creating an SSL store" do
+ before do
+ @host = Puppet::SSL::Host.new("me")
+ @store = mock 'store'
+ @store.stub_everything
+ OpenSSL::X509::Store.stubs(:new).returns @store
- Puppet::SSL::Certificate.stubs(:find).returns @cert
+ Puppet.settings.stubs(:value).with(:localcacert).returns "ssl_host_testing"
- lambda { @host.certificate }.should raise_error(Puppet::Error)
- end
+ Puppet::SSL::CertificateRevocationList.stubs(:find).returns(nil)
+ end
- it "should return any previously found certificate" do
- Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).returns mock("cacert")
- Puppet::SSL::Certificate.expects(:find).with("myname").returns(@cert).once
+ it "should accept a purpose" do
+ @store.expects(:purpose=).with "my special purpose"
+ @host.ssl_store("my special purpose")
+ end
- @host.certificate.should equal(@cert)
- @host.certificate.should equal(@cert)
- end
+ it "should default to OpenSSL::X509::PURPOSE_ANY as the purpose" do
+ @store.expects(:purpose=).with OpenSSL::X509::PURPOSE_ANY
+ @host.ssl_store
end
- it "should have a method for listing certificate hosts" do
- Puppet::SSL::Host.should respond_to(:search)
+ it "should add the local CA cert file" do
+ Puppet.settings.stubs(:value).with(:localcacert).returns "/ca/cert/file"
+ @store.expects(:add_file).with "/ca/cert/file"
+ @host.ssl_store
end
- describe "when listing certificate hosts" do
- it "should default to listing all clients with any file types" do
- Puppet::SSL::Key.expects(:search).returns []
- Puppet::SSL::Certificate.expects(:search).returns []
- Puppet::SSL::CertificateRequest.expects(:search).returns []
- Puppet::SSL::Host.search
- end
+ describe "and a CRL is available" do
+ before do
+ @crl = stub 'crl', :content => "real_crl"
+ Puppet::SSL::CertificateRevocationList.stubs(:find).returns @crl
+ Puppet.settings.stubs(:value).with(:certificate_revocation).returns true
+ end
- it "should be able to list only clients with a key" do
- Puppet::SSL::Key.expects(:search).returns []
- Puppet::SSL::Certificate.expects(:search).never
- Puppet::SSL::CertificateRequest.expects(:search).never
- Puppet::SSL::Host.search :for => Puppet::SSL::Key
- end
+ it "should add the CRL" do
+ @store.expects(:add_crl).with "real_crl"
+ @host.ssl_store
+ end
- it "should be able to list only clients with a certificate" do
- Puppet::SSL::Key.expects(:search).never
- Puppet::SSL::Certificate.expects(:search).returns []
- Puppet::SSL::CertificateRequest.expects(:search).never
- Puppet::SSL::Host.search :for => Puppet::SSL::Certificate
- end
+ it "should set the flags to OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK" do
+ @store.expects(:flags=).with OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK
+ @host.ssl_store
+ end
+ end
+ end
- it "should be able to list only clients with a certificate request" do
- Puppet::SSL::Key.expects(:search).never
- Puppet::SSL::Certificate.expects(:search).never
- Puppet::SSL::CertificateRequest.expects(:search).returns []
- Puppet::SSL::Host.search :for => Puppet::SSL::CertificateRequest
- end
+ describe "when waiting for a cert" do
+ before do
+ @host = Puppet::SSL::Host.new("me")
+ end
- it "should return a Host instance created with the name of each found instance" do
- key = stub 'key', :name => "key"
- cert = stub 'cert', :name => "cert"
- csr = stub 'csr', :name => "csr"
+ it "should generate its certificate request and attempt to read the certificate again if no certificate is found" do
+ @host.expects(:certificate).times(2).returns(nil).then.returns "foo"
+ @host.expects(:generate)
+ @host.wait_for_cert(1)
+ end
- Puppet::SSL::Key.expects(:search).returns [key]
- Puppet::SSL::Certificate.expects(:search).returns [cert]
- Puppet::SSL::CertificateRequest.expects(:search).returns [csr]
+ it "should catch and log errors during CSR saving" do
+ @host.expects(:certificate).times(2).returns(nil).then.returns "foo"
+ @host.expects(:generate).raises(RuntimeError).then.returns nil
+ @host.stubs(:sleep)
+ @host.wait_for_cert(1)
+ end
- returned = []
- %w{key cert csr}.each do |name|
- result = mock(name)
- returned << result
- Puppet::SSL::Host.expects(:new).with(name).returns result
- end
+ it "should sleep and retry after failures saving the CSR if waitforcert is enabled" do
+ @host.expects(:certificate).times(2).returns(nil).then.returns "foo"
+ @host.expects(:generate).raises(RuntimeError).then.returns nil
+ @host.expects(:sleep).with(1)
+ @host.wait_for_cert(1)
+ end
- result = Puppet::SSL::Host.search
- returned.each do |r|
- result.should be_include(r)
- end
- end
+ it "should exit after failures saving the CSR of waitforcert is disabled" do
+ @host.expects(:certificate).returns(nil)
+ @host.expects(:generate).raises(RuntimeError)
+ @host.expects(:puts)
+ @host.expects(:exit).with(1).raises(SystemExit)
+ lambda { @host.wait_for_cert(0) }.should raise_error(SystemExit)
end
- it "should have a method for generating all necessary files" do
- Puppet::SSL::Host.new("me").should respond_to(:generate)
+ it "should exit if the wait time is 0 and it can neither find nor retrieve a certificate" do
+ @host.stubs(:certificate).returns nil
+ @host.expects(:generate)
+ @host.expects(:puts)
+ @host.expects(:exit).with(1).raises(SystemExit)
+ lambda { @host.wait_for_cert(0) }.should raise_error(SystemExit)
end
- describe "when generating files" do
- before do
- @host = Puppet::SSL::Host.new("me")
- @host.stubs(:generate_key)
- @host.stubs(:generate_certificate_request)
- end
+ it "should sleep for the specified amount of time if no certificate is found after generating its certificate request" do
+ @host.expects(:certificate).times(3).returns(nil).then.returns(nil).then.returns "foo"
+ @host.expects(:generate)
+
+ @host.expects(:sleep).with(1)
+
+ @host.wait_for_cert(1)
+ end
- it "should generate a key if one is not present" do
- @host.stubs(:key).returns nil
- @host.expects(:generate_key)
+ it "should catch and log exceptions during certificate retrieval" do
+ @host.expects(:certificate).times(3).returns(nil).then.raises(RuntimeError).then.returns("foo")
+ @host.stubs(:generate)
+ @host.stubs(:sleep)
- @host.generate
- end
+ Puppet.expects(:err)
- it "should generate a certificate request if one is not present" do
- @host.expects(:certificate_request).returns nil
- @host.expects(:generate_certificate_request)
-
- @host.generate
- end
-
- describe "and it can create a certificate authority" do
- before do
- @ca = mock 'ca'
- Puppet::SSL::CertificateAuthority.stubs(:instance).returns @ca
- end
-
- it "should use the CA to sign its certificate request if it does not have a certificate" do
- @host.expects(:certificate).returns nil
-
- @ca.expects(:sign).with(@host.name)
-
- @host.generate
- end
- end
-
- describe "and it cannot create a certificate authority" do
- before do
- Puppet::SSL::CertificateAuthority.stubs(:instance).returns nil
- end
-
- it "should seek its certificate" do
- @host.expects(:certificate)
-
- @host.generate
- end
- end
- end
-
- it "should have a method for creating an SSL store" do
- Puppet::SSL::Host.new("me").should respond_to(:ssl_store)
- end
-
- it "should always return the same store" do
- host = Puppet::SSL::Host.new("foo")
- store = mock 'store'
- store.stub_everything
- OpenSSL::X509::Store.expects(:new).returns store
- host.ssl_store.should equal(host.ssl_store)
- end
-
- describe "when creating an SSL store" do
- before do
- @host = Puppet::SSL::Host.new("me")
- @store = mock 'store'
- @store.stub_everything
- OpenSSL::X509::Store.stubs(:new).returns @store
-
- Puppet.settings.stubs(:value).with(:localcacert).returns "ssl_host_testing"
-
- Puppet::SSL::CertificateRevocationList.stubs(:find).returns(nil)
- end
-
- it "should accept a purpose" do
- @store.expects(:purpose=).with "my special purpose"
- @host.ssl_store("my special purpose")
- end
-
- it "should default to OpenSSL::X509::PURPOSE_ANY as the purpose" do
- @store.expects(:purpose=).with OpenSSL::X509::PURPOSE_ANY
- @host.ssl_store
- end
-
- it "should add the local CA cert file" do
- Puppet.settings.stubs(:value).with(:localcacert).returns "/ca/cert/file"
- @store.expects(:add_file).with "/ca/cert/file"
- @host.ssl_store
- end
-
- describe "and a CRL is available" do
- before do
- @crl = stub 'crl', :content => "real_crl"
- Puppet::SSL::CertificateRevocationList.stubs(:find).returns @crl
- Puppet.settings.stubs(:value).with(:certificate_revocation).returns true
- end
-
- it "should add the CRL" do
- @store.expects(:add_crl).with "real_crl"
- @host.ssl_store
- end
-
- it "should set the flags to OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK" do
- @store.expects(:flags=).with OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK
- @host.ssl_store
- end
- end
- end
-
- describe "when waiting for a cert" do
- before do
- @host = Puppet::SSL::Host.new("me")
- end
-
- it "should generate its certificate request and attempt to read the certificate again if no certificate is found" do
- @host.expects(:certificate).times(2).returns(nil).then.returns "foo"
- @host.expects(:generate)
- @host.wait_for_cert(1)
- end
-
- it "should catch and log errors during CSR saving" do
- @host.expects(:certificate).times(2).returns(nil).then.returns "foo"
- @host.expects(:generate).raises(RuntimeError).then.returns nil
- @host.stubs(:sleep)
- @host.wait_for_cert(1)
- end
-
- it "should sleep and retry after failures saving the CSR if waitforcert is enabled" do
- @host.expects(:certificate).times(2).returns(nil).then.returns "foo"
- @host.expects(:generate).raises(RuntimeError).then.returns nil
- @host.expects(:sleep).with(1)
- @host.wait_for_cert(1)
- end
-
- it "should exit after failures saving the CSR of waitforcert is disabled" do
- @host.expects(:certificate).returns(nil)
- @host.expects(:generate).raises(RuntimeError)
- @host.expects(:puts)
- @host.expects(:exit).with(1).raises(SystemExit)
- lambda { @host.wait_for_cert(0) }.should raise_error(SystemExit)
- end
-
- it "should exit if the wait time is 0 and it can neither find nor retrieve a certificate" do
- @host.stubs(:certificate).returns nil
- @host.expects(:generate)
- @host.expects(:puts)
- @host.expects(:exit).with(1).raises(SystemExit)
- lambda { @host.wait_for_cert(0) }.should raise_error(SystemExit)
- end
-
- it "should sleep for the specified amount of time if no certificate is found after generating its certificate request" do
- @host.expects(:certificate).times(3).returns(nil).then.returns(nil).then.returns "foo"
- @host.expects(:generate)
-
- @host.expects(:sleep).with(1)
-
- @host.wait_for_cert(1)
- end
-
- it "should catch and log exceptions during certificate retrieval" do
- @host.expects(:certificate).times(3).returns(nil).then.raises(RuntimeError).then.returns("foo")
- @host.stubs(:generate)
- @host.stubs(:sleep)
-
- Puppet.expects(:err)
-
- @host.wait_for_cert(1)
- end
+ @host.wait_for_cert(1)
end
+ end
end
diff --git a/spec/unit/ssl/inventory_spec.rb b/spec/unit/ssl/inventory_spec.rb
index bf1dbfb..a57d6fa 100755
--- a/spec/unit/ssl/inventory_spec.rb
+++ b/spec/unit/ssl/inventory_spec.rb
@@ -5,176 +5,176 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/ssl/inventory'
describe Puppet::SSL::Inventory do
- before do
- @class = Puppet::SSL::Inventory
- end
+ before do
+ @class = Puppet::SSL::Inventory
+ end
- it "should use the :certinventory setting for the path to the inventory file" do
- Puppet.settings.expects(:value).with(:cert_inventory).returns "/inven/tory"
+ it "should use the :certinventory setting for the path to the inventory file" do
+ Puppet.settings.expects(:value).with(:cert_inventory).returns "/inven/tory"
- @class.any_instance.stubs(:rebuild)
+ @class.any_instance.stubs(:rebuild)
- @class.new.path.should == "/inven/tory"
- end
+ @class.new.path.should == "/inven/tory"
+ end
- describe "when initializing" do
- it "should set its path to the inventory file" do
- Puppet.settings.stubs(:value).with(:cert_inventory).returns "/inven/tory"
- @class.new.path.should == "/inven/tory"
- end
+ describe "when initializing" do
+ it "should set its path to the inventory file" do
+ Puppet.settings.stubs(:value).with(:cert_inventory).returns "/inven/tory"
+ @class.new.path.should == "/inven/tory"
end
+ end
- describe "when managing an inventory" do
- before do
- Puppet.settings.stubs(:value).with(:cert_inventory).returns "/inven/tory"
+ describe "when managing an inventory" do
+ before do
+ Puppet.settings.stubs(:value).with(:cert_inventory).returns "/inven/tory"
- FileTest.stubs(:exist?).with("/inven/tory").returns true
+ FileTest.stubs(:exist?).with("/inven/tory").returns true
- @inventory = @class.new
+ @inventory = @class.new
- @cert = mock 'cert'
- end
+ @cert = mock 'cert'
+ end
- describe "and creating the inventory file" do
- before do
- Puppet.settings.stubs(:write)
- FileTest.stubs(:exist?).with("/inven/tory").returns false
+ describe "and creating the inventory file" do
+ before do
+ Puppet.settings.stubs(:write)
+ FileTest.stubs(:exist?).with("/inven/tory").returns false
- Puppet::SSL::Certificate.stubs(:search).returns []
- end
+ Puppet::SSL::Certificate.stubs(:search).returns []
+ end
- it "should log that it is building a new inventory file" do
- Puppet.expects(:notice)
+ it "should log that it is building a new inventory file" do
+ Puppet.expects(:notice)
- @inventory.rebuild
- end
+ @inventory.rebuild
+ end
- it "should use the Settings to write to the file" do
- Puppet.settings.expects(:write).with(:cert_inventory)
+ it "should use the Settings to write to the file" do
+ Puppet.settings.expects(:write).with(:cert_inventory)
- @inventory.rebuild
- end
+ @inventory.rebuild
+ end
- it "should add a header to the file" do
- fh = mock 'filehandle'
- Puppet.settings.stubs(:write).yields fh
- fh.expects(:print).with { |str| str =~ /^#/ }
+ it "should add a header to the file" do
+ fh = mock 'filehandle'
+ Puppet.settings.stubs(:write).yields fh
+ fh.expects(:print).with { |str| str =~ /^#/ }
- @inventory.rebuild
- end
+ @inventory.rebuild
+ end
- it "should add formatted information on all existing certificates" do
- cert1 = mock 'cert1'
- cert2 = mock 'cert2'
+ it "should add formatted information on all existing certificates" do
+ cert1 = mock 'cert1'
+ cert2 = mock 'cert2'
- Puppet::SSL::Certificate.expects(:search).with("*").returns [cert1, cert2]
+ Puppet::SSL::Certificate.expects(:search).with("*").returns [cert1, cert2]
- @class.any_instance.expects(:add).with(cert1)
- @class.any_instance.expects(:add).with(cert2)
+ @class.any_instance.expects(:add).with(cert1)
+ @class.any_instance.expects(:add).with(cert2)
- @inventory.rebuild
- end
- end
+ @inventory.rebuild
+ end
+ end
- describe "and adding a certificate" do
- it "should build the inventory file if one does not exist" do
- Puppet.settings.stubs(:value).with(:cert_inventory).returns "/inven/tory"
- Puppet.settings.stubs(:write)
+ describe "and adding a certificate" do
+ it "should build the inventory file if one does not exist" do
+ Puppet.settings.stubs(:value).with(:cert_inventory).returns "/inven/tory"
+ Puppet.settings.stubs(:write)
- FileTest.expects(:exist?).with("/inven/tory").returns false
+ FileTest.expects(:exist?).with("/inven/tory").returns false
- @inventory.expects(:rebuild)
+ @inventory.expects(:rebuild)
- @inventory.add(@cert)
- end
+ @inventory.add(@cert)
+ end
- it "should use the Settings to write to the file" do
- Puppet.settings.expects(:write).with(:cert_inventory, "a")
+ it "should use the Settings to write to the file" do
+ Puppet.settings.expects(:write).with(:cert_inventory, "a")
- @inventory.add(@cert)
- end
+ @inventory.add(@cert)
+ end
- it "should use the actual certificate if it was passed a Puppet certificate" do
- cert = Puppet::SSL::Certificate.new("mycert")
- cert.content = @cert
+ it "should use the actual certificate if it was passed a Puppet certificate" do
+ cert = Puppet::SSL::Certificate.new("mycert")
+ cert.content = @cert
- fh = stub 'filehandle', :print => nil
- Puppet.settings.stubs(:write).yields fh
+ fh = stub 'filehandle', :print => nil
+ Puppet.settings.stubs(:write).yields fh
- @inventory.expects(:format).with(@cert)
+ @inventory.expects(:format).with(@cert)
- @inventory.add(@cert)
- end
+ @inventory.add(@cert)
+ end
- it "should add formatted certificate information to the end of the file" do
- fh = mock 'filehandle'
+ it "should add formatted certificate information to the end of the file" do
+ fh = mock 'filehandle'
- Puppet.settings.stubs(:write).yields fh
+ Puppet.settings.stubs(:write).yields fh
- @inventory.expects(:format).with(@cert).returns "myformat"
+ @inventory.expects(:format).with(@cert).returns "myformat"
- fh.expects(:print).with("myformat")
+ fh.expects(:print).with("myformat")
- @inventory.add(@cert)
- end
- end
+ @inventory.add(@cert)
+ end
+ end
- describe "and formatting a certificate" do
- before do
- @cert = stub 'cert', :not_before => Time.now, :not_after => Time.now, :subject => "mycert", :serial => 15
- end
+ describe "and formatting a certificate" do
+ before do
+ @cert = stub 'cert', :not_before => Time.now, :not_after => Time.now, :subject => "mycert", :serial => 15
+ end
- it "should print the serial number as a 4 digit hex number in the first field" do
- @inventory.format(@cert).split[0].should == "0x000f" # 15 in hex
- end
+ it "should print the serial number as a 4 digit hex number in the first field" do
+ @inventory.format(@cert).split[0].should == "0x000f" # 15 in hex
+ end
- it "should print the not_before date in '%Y-%m-%dT%H:%M:%S%Z' format in the second field" do
- @cert.not_before.expects(:strftime).with('%Y-%m-%dT%H:%M:%S%Z').returns "before_time"
+ it "should print the not_before date in '%Y-%m-%dT%H:%M:%S%Z' format in the second field" do
+ @cert.not_before.expects(:strftime).with('%Y-%m-%dT%H:%M:%S%Z').returns "before_time"
- @inventory.format(@cert).split[1].should == "before_time"
- end
+ @inventory.format(@cert).split[1].should == "before_time"
+ end
- it "should print the not_after date in '%Y-%m-%dT%H:%M:%S%Z' format in the third field" do
- @cert.not_after.expects(:strftime).with('%Y-%m-%dT%H:%M:%S%Z').returns "after_time"
+ it "should print the not_after date in '%Y-%m-%dT%H:%M:%S%Z' format in the third field" do
+ @cert.not_after.expects(:strftime).with('%Y-%m-%dT%H:%M:%S%Z').returns "after_time"
- @inventory.format(@cert).split[2].should == "after_time"
- end
+ @inventory.format(@cert).split[2].should == "after_time"
+ end
- it "should print the subject in the fourth field" do
- @inventory.format(@cert).split[3].should == "mycert"
- end
+ it "should print the subject in the fourth field" do
+ @inventory.format(@cert).split[3].should == "mycert"
+ end
- it "should add a carriage return" do
- @inventory.format(@cert).should =~ /\n$/
- end
+ it "should add a carriage return" do
+ @inventory.format(@cert).should =~ /\n$/
+ end
- it "should produce a line consisting of the serial number, start date, expiration date, and subject" do
- # Just make sure our serial and subject bracket the lines.
- @inventory.format(@cert).should =~ /^0x.+mycert$/
- end
- end
+ it "should produce a line consisting of the serial number, start date, expiration date, and subject" do
+ # Just make sure our serial and subject bracket the lines.
+ @inventory.format(@cert).should =~ /^0x.+mycert$/
+ end
+ end
- it "should be able to find a given host's serial number" do
- @inventory.should respond_to(:serial)
- end
+ it "should be able to find a given host's serial number" do
+ @inventory.should respond_to(:serial)
+ end
- describe "and finding a serial number" do
- it "should return nil if the inventory file is missing" do
- FileTest.expects(:exist?).with("/inven/tory").returns false
- @inventory.serial(:whatever).should be_nil
- end
+ describe "and finding a serial number" do
+ it "should return nil if the inventory file is missing" do
+ FileTest.expects(:exist?).with("/inven/tory").returns false
+ @inventory.serial(:whatever).should be_nil
+ end
- it "should return the serial number from the line matching the provided name" do
- File.expects(:readlines).with("/inven/tory").returns ["0x00f blah blah /CN=me\n", "0x001 blah blah /CN=you\n"]
+ it "should return the serial number from the line matching the provided name" do
+ File.expects(:readlines).with("/inven/tory").returns ["0x00f blah blah /CN=me\n", "0x001 blah blah /CN=you\n"]
- @inventory.serial("me").should == 15
- end
+ @inventory.serial("me").should == 15
+ end
- it "should return the number as an integer" do
- File.expects(:readlines).with("/inven/tory").returns ["0x00f blah blah /CN=me\n", "0x001 blah blah /CN=you\n"]
+ it "should return the number as an integer" do
+ File.expects(:readlines).with("/inven/tory").returns ["0x00f blah blah /CN=me\n", "0x001 blah blah /CN=you\n"]
- @inventory.serial("me").should == 15
- end
- end
+ @inventory.serial("me").should == 15
+ end
end
+ end
end
diff --git a/spec/unit/ssl/key_spec.rb b/spec/unit/ssl/key_spec.rb
index cfeaf79..58193db 100755
--- a/spec/unit/ssl/key_spec.rb
+++ b/spec/unit/ssl/key_spec.rb
@@ -5,194 +5,194 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/ssl/key'
describe Puppet::SSL::Key do
- before do
- @class = Puppet::SSL::Key
- end
+ before do
+ @class = Puppet::SSL::Key
+ end
- it "should be extended with the Indirector module" do
- @class.singleton_class.should be_include(Puppet::Indirector)
- end
+ it "should be extended with the Indirector module" do
+ @class.singleton_class.should be_include(Puppet::Indirector)
+ end
- it "should indirect key" do
- @class.indirection.name.should == :key
- end
+ it "should indirect key" do
+ @class.indirection.name.should == :key
+ end
- it "should default to the :file terminus" do
- @class.indirection.terminus_class.should == :file
- end
+ it "should default to the :file terminus" do
+ @class.indirection.terminus_class.should == :file
+ end
- it "should only support the text format" do
- @class.supported_formats.should == [:s]
- end
+ it "should only support the text format" do
+ @class.supported_formats.should == [:s]
+ end
- it "should have a method for determining whether it's a CA key" do
- @class.new("test").should respond_to(:ca?)
- end
+ it "should have a method for determining whether it's a CA key" do
+ @class.new("test").should respond_to(:ca?)
+ end
- it "should consider itself a ca key if its name matches the CA_NAME" do
- @class.new(Puppet::SSL::Host.ca_name).should be_ca
- end
+ it "should consider itself a ca key if its name matches the CA_NAME" do
+ @class.new(Puppet::SSL::Host.ca_name).should be_ca
+ end
- describe "when initializing" do
- it "should set its password file to the :capass if it's a CA key" do
- Puppet.settings.stubs(:value).returns "whatever"
- Puppet.settings.stubs(:value).with(:capass).returns "/ca/pass"
+ describe "when initializing" do
+ it "should set its password file to the :capass if it's a CA key" do
+ Puppet.settings.stubs(:value).returns "whatever"
+ Puppet.settings.stubs(:value).with(:capass).returns "/ca/pass"
- key = Puppet::SSL::Key.new(Puppet::SSL::Host.ca_name)
- key.password_file.should == "/ca/pass"
- end
+ key = Puppet::SSL::Key.new(Puppet::SSL::Host.ca_name)
+ key.password_file.should == "/ca/pass"
+ end
- it "should downcase its name" do
- @class.new("MyName").name.should == "myname"
- end
+ it "should downcase its name" do
+ @class.new("MyName").name.should == "myname"
+ end
- it "should set its password file to the default password file if it is not the CA key" do
- Puppet.settings.stubs(:value).returns "whatever"
- Puppet.settings.stubs(:value).with(:passfile).returns "/normal/pass"
+ it "should set its password file to the default password file if it is not the CA key" do
+ Puppet.settings.stubs(:value).returns "whatever"
+ Puppet.settings.stubs(:value).with(:passfile).returns "/normal/pass"
- key = Puppet::SSL::Key.new("notca")
- key.password_file.should == "/normal/pass"
- end
+ key = Puppet::SSL::Key.new("notca")
+ key.password_file.should == "/normal/pass"
end
+ end
- describe "when managing instances" do
- before do
- @key = @class.new("myname")
- end
+ describe "when managing instances" do
+ before do
+ @key = @class.new("myname")
+ end
- it "should have a name attribute" do
- @key.name.should == "myname"
- end
+ it "should have a name attribute" do
+ @key.name.should == "myname"
+ end
- it "should have a content attribute" do
- @key.should respond_to(:content)
- end
+ it "should have a content attribute" do
+ @key.should respond_to(:content)
+ end
- it "should be able to read keys from disk" do
- path = "/my/path"
- File.expects(:read).with(path).returns("my key")
- key = mock 'key'
- OpenSSL::PKey::RSA.expects(:new).returns(key)
- @key.read(path).should equal(key)
- @key.content.should equal(key)
- end
+ it "should be able to read keys from disk" do
+ path = "/my/path"
+ File.expects(:read).with(path).returns("my key")
+ key = mock 'key'
+ OpenSSL::PKey::RSA.expects(:new).returns(key)
+ @key.read(path).should equal(key)
+ @key.content.should equal(key)
+ end
- it "should not try to use the provided password file if the file does not exist" do
- FileTest.stubs(:exist?).returns false
- @key.password_file = "/path/to/password"
+ it "should not try to use the provided password file if the file does not exist" do
+ FileTest.stubs(:exist?).returns false
+ @key.password_file = "/path/to/password"
- path = "/my/path"
+ path = "/my/path"
- File.stubs(:read).with(path).returns("my key")
- OpenSSL::PKey::RSA.expects(:new).with("my key", nil).returns(mock('key'))
- File.expects(:read).with("/path/to/password").never
+ File.stubs(:read).with(path).returns("my key")
+ OpenSSL::PKey::RSA.expects(:new).with("my key", nil).returns(mock('key'))
+ File.expects(:read).with("/path/to/password").never
- @key.read(path)
- end
+ @key.read(path)
+ end
- it "should read the key with the password retrieved from the password file if one is provided" do
- FileTest.stubs(:exist?).returns true
- @key.password_file = "/path/to/password"
+ it "should read the key with the password retrieved from the password file if one is provided" do
+ FileTest.stubs(:exist?).returns true
+ @key.password_file = "/path/to/password"
- path = "/my/path"
- File.expects(:read).with(path).returns("my key")
- File.expects(:read).with("/path/to/password").returns("my password")
+ path = "/my/path"
+ File.expects(:read).with(path).returns("my key")
+ File.expects(:read).with("/path/to/password").returns("my password")
- key = mock 'key'
- OpenSSL::PKey::RSA.expects(:new).with("my key", "my password").returns(key)
- @key.read(path).should equal(key)
- @key.content.should equal(key)
- end
+ key = mock 'key'
+ OpenSSL::PKey::RSA.expects(:new).with("my key", "my password").returns(key)
+ @key.read(path).should equal(key)
+ @key.content.should equal(key)
+ end
- it "should return an empty string when converted to a string with no key" do
- @key.to_s.should == ""
- end
+ it "should return an empty string when converted to a string with no key" do
+ @key.to_s.should == ""
+ end
- it "should convert the key to pem format when converted to a string" do
- key = mock 'key', :to_pem => "pem"
- @key.content = key
- @key.to_s.should == "pem"
- end
+ it "should convert the key to pem format when converted to a string" do
+ key = mock 'key', :to_pem => "pem"
+ @key.content = key
+ @key.to_s.should == "pem"
+ end
- it "should have a :to_text method that it delegates to the actual key" do
- real_key = mock 'key'
- real_key.expects(:to_text).returns "keytext"
- @key.content = real_key
- @key.to_text.should == "keytext"
- end
+ it "should have a :to_text method that it delegates to the actual key" do
+ real_key = mock 'key'
+ real_key.expects(:to_text).returns "keytext"
+ @key.content = real_key
+ @key.to_text.should == "keytext"
end
+ end
- describe "when generating the private key" do
- before do
- @instance = @class.new("test")
+ describe "when generating the private key" do
+ before do
+ @instance = @class.new("test")
- @key = mock 'key'
- end
+ @key = mock 'key'
+ end
- it "should create an instance of OpenSSL::PKey::RSA" do
- OpenSSL::PKey::RSA.expects(:new).returns(@key)
+ it "should create an instance of OpenSSL::PKey::RSA" do
+ OpenSSL::PKey::RSA.expects(:new).returns(@key)
- @instance.generate
- end
+ @instance.generate
+ end
- it "should create the private key with the keylength specified in the settings" do
- Puppet.settings.expects(:value).with(:keylength).returns("50")
- OpenSSL::PKey::RSA.expects(:new).with(50).returns(@key)
+ it "should create the private key with the keylength specified in the settings" do
+ Puppet.settings.expects(:value).with(:keylength).returns("50")
+ OpenSSL::PKey::RSA.expects(:new).with(50).returns(@key)
- @instance.generate
- end
+ @instance.generate
+ end
- it "should set the content to the generated key" do
- OpenSSL::PKey::RSA.stubs(:new).returns(@key)
- @instance.generate
- @instance.content.should equal(@key)
- end
+ it "should set the content to the generated key" do
+ OpenSSL::PKey::RSA.stubs(:new).returns(@key)
+ @instance.generate
+ @instance.content.should equal(@key)
+ end
- it "should return the generated key" do
- OpenSSL::PKey::RSA.stubs(:new).returns(@key)
- @instance.generate.should equal(@key)
- end
+ it "should return the generated key" do
+ OpenSSL::PKey::RSA.stubs(:new).returns(@key)
+ @instance.generate.should equal(@key)
+ end
- it "should return the key in pem format" do
- @instance.generate
- @instance.content.expects(:to_pem).returns "my normal key"
- @instance.to_s.should == "my normal key"
- end
+ it "should return the key in pem format" do
+ @instance.generate
+ @instance.content.expects(:to_pem).returns "my normal key"
+ @instance.to_s.should == "my normal key"
+ end
- describe "with a password file set" do
- it "should return a nil password if the password file does not exist" do
- FileTest.expects(:exist?).with("/path/to/pass").returns false
- File.expects(:read).with("/path/to/pass").never
+ describe "with a password file set" do
+ it "should return a nil password if the password file does not exist" do
+ FileTest.expects(:exist?).with("/path/to/pass").returns false
+ File.expects(:read).with("/path/to/pass").never
- @instance.password_file = "/path/to/pass"
+ @instance.password_file = "/path/to/pass"
- @instance.password.should be_nil
- end
+ @instance.password.should be_nil
+ end
- it "should return the contents of the password file as its password" do
- FileTest.expects(:exist?).with("/path/to/pass").returns true
- File.expects(:read).with("/path/to/pass").returns "my password"
+ it "should return the contents of the password file as its password" do
+ FileTest.expects(:exist?).with("/path/to/pass").returns true
+ File.expects(:read).with("/path/to/pass").returns "my password"
- @instance.password_file = "/path/to/pass"
+ @instance.password_file = "/path/to/pass"
- @instance.password.should == "my password"
- end
+ @instance.password.should == "my password"
+ end
- it "should export the private key to text using the password" do
- Puppet.settings.stubs(:value).with(:keylength).returns("50")
+ it "should export the private key to text using the password" do
+ Puppet.settings.stubs(:value).with(:keylength).returns("50")
- @instance.password_file = "/path/to/pass"
- @instance.stubs(:password).returns "my password"
+ @instance.password_file = "/path/to/pass"
+ @instance.stubs(:password).returns "my password"
- OpenSSL::PKey::RSA.expects(:new).returns(@key)
- @instance.generate
+ OpenSSL::PKey::RSA.expects(:new).returns(@key)
+ @instance.generate
- cipher = mock 'cipher'
- OpenSSL::Cipher::DES.expects(:new).with(:EDE3, :CBC).returns cipher
- @key.expects(:export).with(cipher, "my password").returns "my encrypted key"
+ cipher = mock 'cipher'
+ OpenSSL::Cipher::DES.expects(:new).with(:EDE3, :CBC).returns cipher
+ @key.expects(:export).with(cipher, "my password").returns "my encrypted key"
- @instance.to_s.should == "my encrypted key"
- end
- end
+ @instance.to_s.should == "my encrypted key"
+ end
end
+ end
end
diff --git a/spec/unit/status_spec.rb b/spec/unit/status_spec.rb
index 334b9b5..71bfa4a 100644
--- a/spec/unit/status_spec.rb
+++ b/spec/unit/status_spec.rb
@@ -3,29 +3,29 @@
require File.dirname(__FILE__) + '/../spec_helper'
describe Puppet::Status do
- it "should implement find" do
- Puppet::Status.find( :default ).should be_is_a(Puppet::Status)
- Puppet::Status.find( :default ).status["is_alive"].should == true
- end
+ it "should implement find" do
+ Puppet::Status.find( :default ).should be_is_a(Puppet::Status)
+ Puppet::Status.find( :default ).status["is_alive"].should == true
+ end
- it "should default to is_alive is true" do
- Puppet::Status.new.status["is_alive"].should == true
- end
+ it "should default to is_alive is true" do
+ Puppet::Status.new.status["is_alive"].should == true
+ end
- it "should return a pson hash" do
- Puppet::Status.new.status.to_pson.should == '{"is_alive":true}'
- end
+ it "should return a pson hash" do
+ Puppet::Status.new.status.to_pson.should == '{"is_alive":true}'
+ end
- it "should accept a hash from pson" do
- status = Puppet::Status.new( { "is_alive" => false } )
- status.status.should == { "is_alive" => false }
- end
+ it "should accept a hash from pson" do
+ status = Puppet::Status.new( { "is_alive" => false } )
+ status.status.should == { "is_alive" => false }
+ end
- it "should have a name" do
- Puppet::Status.new.name
- end
+ it "should have a name" do
+ Puppet::Status.new.name
+ end
- it "should allow a name to be set" do
- Puppet::Status.new.name = "status"
- end
+ it "should allow a name to be set" do
+ Puppet::Status.new.name = "status"
+ end
end
diff --git a/spec/unit/transaction/change_spec.rb b/spec/unit/transaction/change_spec.rb
index 10a7aae..e443e3b 100755
--- a/spec/unit/transaction/change_spec.rb
+++ b/spec/unit/transaction/change_spec.rb
@@ -5,189 +5,189 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/transaction/change'
describe Puppet::Transaction::Change do
- Change = Puppet::Transaction::Change
+ Change = Puppet::Transaction::Change
- describe "when initializing" do
- before do
- @property = stub 'property', :path => "/property/path", :should => "shouldval"
- end
+ describe "when initializing" do
+ before do
+ @property = stub 'property', :path => "/property/path", :should => "shouldval"
+ end
- it "should require the property and current value" do
- lambda { Change.new }.should raise_error
- end
+ it "should require the property and current value" do
+ lambda { Change.new }.should raise_error
+ end
- it "should set its property to the provided property" do
- Change.new(@property, "value").property.should == :property
- end
+ it "should set its property to the provided property" do
+ Change.new(@property, "value").property.should == :property
+ end
- it "should set its 'is' value to the provided value" do
- Change.new(@property, "value").is.should == "value"
- end
+ it "should set its 'is' value to the provided value" do
+ Change.new(@property, "value").is.should == "value"
+ end
- it "should retrieve the 'should' value from the property" do
- # Yay rspec :)
- Change.new(@property, "value").should.should == @property.should
- end
+ it "should retrieve the 'should' value from the property" do
+ # Yay rspec :)
+ Change.new(@property, "value").should.should == @property.should
end
+ end
- describe "when an instance" do
- before do
- @property = stub 'property', :path => "/property/path", :should => "shouldval"
- @change = Change.new(@property, "value")
- end
+ describe "when an instance" do
+ before do
+ @property = stub 'property', :path => "/property/path", :should => "shouldval"
+ @change = Change.new(@property, "value")
+ end
- it "should be noop if the property is noop" do
- @property.expects(:noop).returns true
- @change.noop?.should be_true
- end
+ it "should be noop if the property is noop" do
+ @property.expects(:noop).returns true
+ @change.noop?.should be_true
+ end
- it "should be auditing if set so" do
- @change.auditing = true
- @change.must be_auditing
- end
+ it "should be auditing if set so" do
+ @change.auditing = true
+ @change.must be_auditing
+ end
- it "should set its resource to the proxy if it has one" do
- @change.proxy = :myresource
- @change.resource.should == :myresource
- end
+ it "should set its resource to the proxy if it has one" do
+ @change.proxy = :myresource
+ @change.resource.should == :myresource
+ end
- it "should set its resource to the property's resource if no proxy is set" do
- @property.expects(:resource).returns :myresource
- @change.resource.should == :myresource
- end
+ it "should set its resource to the property's resource if no proxy is set" do
+ @property.expects(:resource).returns :myresource
+ @change.resource.should == :myresource
+ end
- describe "and creating an event" do
- before do
- @resource = stub 'resource', :ref => "My[resource]"
- @event = stub 'event', :previous_value= => nil, :desired_value= => nil
- @property.stubs(:event).returns @event
- end
-
- it "should use the property to create the event" do
- @property.expects(:event).returns @event
- @change.event.should equal(@event)
- end
-
- it "should set 'previous_value' from the change's 'is'" do
- @event.expects(:previous_value=).with(@change.is)
- @change.event
- end
-
- it "should set 'desired_value' from the change's 'should'" do
- @event.expects(:desired_value=).with(@change.should)
- @change.event
- end
- end
+ describe "and creating an event" do
+ before do
+ @resource = stub 'resource', :ref => "My[resource]"
+ @event = stub 'event', :previous_value= => nil, :desired_value= => nil
+ @property.stubs(:event).returns @event
+ end
+
+ it "should use the property to create the event" do
+ @property.expects(:event).returns @event
+ @change.event.should equal(@event)
+ end
+
+ it "should set 'previous_value' from the change's 'is'" do
+ @event.expects(:previous_value=).with(@change.is)
+ @change.event
+ end
+
+ it "should set 'desired_value' from the change's 'should'" do
+ @event.expects(:desired_value=).with(@change.should)
+ @change.event
+ end
+ end
- describe "and executing" do
- before do
- @event = Puppet::Transaction::Event.new(:myevent)
- @event.stubs(:send_log)
- @change.stubs(:noop?).returns false
- @property.stubs(:event).returns @event
+ describe "and executing" do
+ before do
+ @event = Puppet::Transaction::Event.new(:myevent)
+ @event.stubs(:send_log)
+ @change.stubs(:noop?).returns false
+ @property.stubs(:event).returns @event
- @property.stub_everything
- @property.stubs(:resource).returns "myresource"
- @property.stubs(:name).returns :myprop
- end
+ @property.stub_everything
+ @property.stubs(:resource).returns "myresource"
+ @property.stubs(:name).returns :myprop
+ end
- describe "in noop mode" do
- before { @change.stubs(:noop?).returns true }
+ describe "in noop mode" do
+ before { @change.stubs(:noop?).returns true }
- it "should log that it is in noop" do
- @property.expects(:is_to_s)
- @property.expects(:should_to_s)
+ it "should log that it is in noop" do
+ @property.expects(:is_to_s)
+ @property.expects(:should_to_s)
- @event.expects(:message=).with { |msg| msg.include?("should be") }
+ @event.expects(:message=).with { |msg| msg.include?("should be") }
- @change.apply
- end
+ @change.apply
+ end
- it "should produce a :noop event and return" do
- @property.stub_everything
+ it "should produce a :noop event and return" do
+ @property.stub_everything
- @event.expects(:status=).with("noop")
+ @event.expects(:status=).with("noop")
- @change.apply.should == @event
- end
- end
+ @change.apply.should == @event
+ end
+ end
- describe "in audit mode" do
- before { @change.auditing = true }
+ describe "in audit mode" do
+ before { @change.auditing = true }
- it "should log that it is in audit mode" do
- @property.expects(:is_to_s)
- @property.expects(:should_to_s)
+ it "should log that it is in audit mode" do
+ @property.expects(:is_to_s)
+ @property.expects(:should_to_s)
- @event.expects(:message=).with { |msg| msg.include?("audit") }
+ @event.expects(:message=).with { |msg| msg.include?("audit") }
- @change.apply
- end
+ @change.apply
+ end
- it "should produce a :audit event and return" do
- @property.stub_everything
+ it "should produce a :audit event and return" do
+ @property.stub_everything
- @event.expects(:status=).with("audit")
+ @event.expects(:status=).with("audit")
- @change.apply.should == @event
- end
- end
+ @change.apply.should == @event
+ end
+ end
- it "should sync the property" do
- @property.expects(:sync)
+ it "should sync the property" do
+ @property.expects(:sync)
- @change.apply
- end
+ @change.apply
+ end
- it "should return the default event if syncing the property returns nil" do
- @property.stubs(:sync).returns nil
+ it "should return the default event if syncing the property returns nil" do
+ @property.stubs(:sync).returns nil
- @change.expects(:event).with(nil).returns @event
+ @change.expects(:event).with(nil).returns @event
- @change.apply.should == @event
- end
+ @change.apply.should == @event
+ end
- it "should return the default event if syncing the property returns an empty array" do
- @property.stubs(:sync).returns []
+ it "should return the default event if syncing the property returns an empty array" do
+ @property.stubs(:sync).returns []
- @change.expects(:event).with(nil).returns @event
+ @change.expects(:event).with(nil).returns @event
- @change.apply.should == @event
- end
+ @change.apply.should == @event
+ end
- it "should log the change" do
- @property.expects(:sync).returns [:one]
+ it "should log the change" do
+ @property.expects(:sync).returns [:one]
- @event.expects(:send_log)
+ @event.expects(:send_log)
- @change.apply
- end
+ @change.apply
+ end
- it "should set the event's message to the change log" do
- @property.expects(:change_to_s).returns "my change"
- @change.apply.message.should == "my change"
- end
+ it "should set the event's message to the change log" do
+ @property.expects(:change_to_s).returns "my change"
+ @change.apply.message.should == "my change"
+ end
- it "should set the event's status to 'success'" do
- @change.apply.status.should == "success"
- end
+ it "should set the event's status to 'success'" do
+ @change.apply.status.should == "success"
+ end
- describe "and the change fails" do
- before { @property.expects(:sync).raises "an exception" }
+ describe "and the change fails" do
+ before { @property.expects(:sync).raises "an exception" }
- it "should catch the exception and log the err" do
- @event.expects(:send_log)
- lambda { @change.apply }.should_not raise_error
- end
+ it "should catch the exception and log the err" do
+ @event.expects(:send_log)
+ lambda { @change.apply }.should_not raise_error
+ end
- it "should mark the event status as 'failure'" do
- @change.apply.status.should == "failure"
- end
+ it "should mark the event status as 'failure'" do
+ @change.apply.status.should == "failure"
+ end
- it "should set the event log to a failure log" do
- @change.apply.message.should be_include("failed")
- end
- end
+ it "should set the event log to a failure log" do
+ @change.apply.message.should be_include("failed")
end
+ end
end
+ end
end
diff --git a/spec/unit/transaction/event_manager_spec.rb b/spec/unit/transaction/event_manager_spec.rb
index 6b9fe03..eeb3d33 100755
--- a/spec/unit/transaction/event_manager_spec.rb
+++ b/spec/unit/transaction/event_manager_spec.rb
@@ -5,256 +5,256 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/transaction/event_manager'
describe Puppet::Transaction::EventManager do
- describe "at initialization" do
- it "should require a transaction" do
- Puppet::Transaction::EventManager.new("trans").transaction.should == "trans"
- end
+ describe "at initialization" do
+ it "should require a transaction" do
+ Puppet::Transaction::EventManager.new("trans").transaction.should == "trans"
end
+ end
- it "should delegate its relationship graph to the transaction" do
- transaction = stub 'transaction'
- manager = Puppet::Transaction::EventManager.new(transaction)
+ it "should delegate its relationship graph to the transaction" do
+ transaction = stub 'transaction'
+ manager = Puppet::Transaction::EventManager.new(transaction)
- transaction.expects(:relationship_graph).returns "mygraph"
+ transaction.expects(:relationship_graph).returns "mygraph"
- manager.relationship_graph.should == "mygraph"
- end
+ manager.relationship_graph.should == "mygraph"
+ end
- describe "when queueing events" do
- before do
- @manager = Puppet::Transaction::EventManager.new(@transaction)
+ describe "when queueing events" do
+ before do
+ @manager = Puppet::Transaction::EventManager.new(@transaction)
- @resource = Puppet::Type.type(:file).new :path => "/my/file"
+ @resource = Puppet::Type.type(:file).new :path => "/my/file"
- @graph = stub 'graph', :matching_edges => [], :resource => @resource
- @manager.stubs(:relationship_graph).returns @graph
+ @graph = stub 'graph', :matching_edges => [], :resource => @resource
+ @manager.stubs(:relationship_graph).returns @graph
- @event = Puppet::Transaction::Event.new(:name => :foo, :resource => @resource)
- end
+ @event = Puppet::Transaction::Event.new(:name => :foo, :resource => @resource)
+ end
- it "should store all of the events in its event list" do
- @event2 = Puppet::Transaction::Event.new(:name => :bar, :resource => @resource)
- @manager.queue_events(@resource, [@event, @event2])
+ it "should store all of the events in its event list" do
+ @event2 = Puppet::Transaction::Event.new(:name => :bar, :resource => @resource)
+ @manager.queue_events(@resource, [@event, @event2])
- @manager.events.should include(@event)
- @manager.events.should include(@event2)
- end
+ @manager.events.should include(@event)
+ @manager.events.should include(@event2)
+ end
- it "should queue events for the target and callback of any matching edges" do
- edge1 = stub("edge1", :callback => :c1, :source => stub("s1"), :target => stub("t1", :c1 => nil))
- edge2 = stub("edge2", :callback => :c2, :source => stub("s2"), :target => stub("t2", :c2 => nil))
+ it "should queue events for the target and callback of any matching edges" do
+ edge1 = stub("edge1", :callback => :c1, :source => stub("s1"), :target => stub("t1", :c1 => nil))
+ edge2 = stub("edge2", :callback => :c2, :source => stub("s2"), :target => stub("t2", :c2 => nil))
- @graph.expects(:matching_edges).with { |event, resource| event == @event }.returns [edge1, edge2]
+ @graph.expects(:matching_edges).with { |event, resource| event == @event }.returns [edge1, edge2]
- @manager.expects(:queue_events_for_resource).with(@resource, edge1.target, edge1.callback, [@event])
- @manager.expects(:queue_events_for_resource).with(@resource, edge2.target, edge2.callback, [@event])
+ @manager.expects(:queue_events_for_resource).with(@resource, edge1.target, edge1.callback, [@event])
+ @manager.expects(:queue_events_for_resource).with(@resource, edge2.target, edge2.callback, [@event])
- @manager.queue_events(@resource, [@event])
- end
+ @manager.queue_events(@resource, [@event])
+ end
- it "should queue events for the changed resource if the resource is self-refreshing and not being deleted" do
- @graph.stubs(:matching_edges).returns []
+ it "should queue events for the changed resource if the resource is self-refreshing and not being deleted" do
+ @graph.stubs(:matching_edges).returns []
- @resource.expects(:self_refresh?).returns true
- @resource.expects(:deleting?).returns false
- @manager.expects(:queue_events_for_resource).with(@resource, @resource, :refresh, [@event])
+ @resource.expects(:self_refresh?).returns true
+ @resource.expects(:deleting?).returns false
+ @manager.expects(:queue_events_for_resource).with(@resource, @resource, :refresh, [@event])
- @manager.queue_events(@resource, [@event])
- end
+ @manager.queue_events(@resource, [@event])
+ end
- it "should not queue events for the changed resource if the resource is not self-refreshing" do
- @graph.stubs(:matching_edges).returns []
+ it "should not queue events for the changed resource if the resource is not self-refreshing" do
+ @graph.stubs(:matching_edges).returns []
- @resource.expects(:self_refresh?).returns false
- @resource.stubs(:deleting?).returns false
- @manager.expects(:queue_events_for_resource).never
+ @resource.expects(:self_refresh?).returns false
+ @resource.stubs(:deleting?).returns false
+ @manager.expects(:queue_events_for_resource).never
- @manager.queue_events(@resource, [@event])
- end
+ @manager.queue_events(@resource, [@event])
+ end
- it "should not queue events for the changed resource if the resource is being deleted" do
- @graph.stubs(:matching_edges).returns []
+ it "should not queue events for the changed resource if the resource is being deleted" do
+ @graph.stubs(:matching_edges).returns []
- @resource.expects(:self_refresh?).returns true
- @resource.expects(:deleting?).returns true
- @manager.expects(:queue_events_for_resource).never
+ @resource.expects(:self_refresh?).returns true
+ @resource.expects(:deleting?).returns true
+ @manager.expects(:queue_events_for_resource).never
- @manager.queue_events(@resource, [@event])
- end
+ @manager.queue_events(@resource, [@event])
+ end
- it "should ignore edges that don't have a callback" do
- edge1 = stub("edge1", :callback => :nil, :source => stub("s1"), :target => stub("t1", :c1 => nil))
+ it "should ignore edges that don't have a callback" do
+ edge1 = stub("edge1", :callback => :nil, :source => stub("s1"), :target => stub("t1", :c1 => nil))
- @graph.expects(:matching_edges).returns [edge1]
+ @graph.expects(:matching_edges).returns [edge1]
- @manager.expects(:queue_events_for_resource).never
+ @manager.expects(:queue_events_for_resource).never
- @manager.queue_events(@resource, [@event])
- end
+ @manager.queue_events(@resource, [@event])
+ end
- it "should ignore targets that don't respond to the callback" do
- edge1 = stub("edge1", :callback => :c1, :source => stub("s1"), :target => stub("t1"))
+ it "should ignore targets that don't respond to the callback" do
+ edge1 = stub("edge1", :callback => :c1, :source => stub("s1"), :target => stub("t1"))
- @graph.expects(:matching_edges).returns [edge1]
+ @graph.expects(:matching_edges).returns [edge1]
- @manager.expects(:queue_events_for_resource).never
+ @manager.expects(:queue_events_for_resource).never
- @manager.queue_events(@resource, [@event])
- end
+ @manager.queue_events(@resource, [@event])
end
+ end
- describe "when queueing events for a resource" do
- before do
- @transaction = stub 'transaction'
- @manager = Puppet::Transaction::EventManager.new(@transaction)
- end
+ describe "when queueing events for a resource" do
+ before do
+ @transaction = stub 'transaction'
+ @manager = Puppet::Transaction::EventManager.new(@transaction)
+ end
- it "should do nothing if no events are queued" do
- @manager.queued_events(stub("target")) { |callback, events| raise "should never reach this" }
- end
+ it "should do nothing if no events are queued" do
+ @manager.queued_events(stub("target")) { |callback, events| raise "should never reach this" }
+ end
- it "should yield the callback and events for each callback" do
- target = stub("target")
+ it "should yield the callback and events for each callback" do
+ target = stub("target")
- 2.times do |i|
- @manager.queue_events_for_resource(stub("source", :info => nil), target, "callback#{i}", ["event#{i}"])
- end
+ 2.times do |i|
+ @manager.queue_events_for_resource(stub("source", :info => nil), target, "callback#{i}", ["event#{i}"])
+ end
- @manager.queued_events(target) { |callback, events| }
- end
+ @manager.queued_events(target) { |callback, events| }
+ end
- it "should use the source to log that it's scheduling a refresh of the target" do
- target = stub("target")
- source = stub 'source'
- source.expects(:info)
+ it "should use the source to log that it's scheduling a refresh of the target" do
+ target = stub("target")
+ source = stub 'source'
+ source.expects(:info)
- @manager.queue_events_for_resource(source, target, "callback", ["event"])
+ @manager.queue_events_for_resource(source, target, "callback", ["event"])
- @manager.queued_events(target) { |callback, events| }
- end
+ @manager.queued_events(target) { |callback, events| }
end
+ end
- describe "when processing events for a given resource" do
- before do
- @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new)
- @manager = Puppet::Transaction::EventManager.new(@transaction)
- @manager.stubs(:queue_events)
+ describe "when processing events for a given resource" do
+ before do
+ @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new)
+ @manager = Puppet::Transaction::EventManager.new(@transaction)
+ @manager.stubs(:queue_events)
- @resource = Puppet::Type.type(:file).new :path => "/my/file"
- @event = Puppet::Transaction::Event.new(:name => :event, :resource => @resource)
- end
+ @resource = Puppet::Type.type(:file).new :path => "/my/file"
+ @event = Puppet::Transaction::Event.new(:name => :event, :resource => @resource)
+ end
- it "should call the required callback once for each set of associated events" do
- @manager.expects(:queued_events).with(@resource).multiple_yields([:callback1, [@event]], [:callback2, [@event]])
+ it "should call the required callback once for each set of associated events" do
+ @manager.expects(:queued_events).with(@resource).multiple_yields([:callback1, [@event]], [:callback2, [@event]])
- @resource.expects(:callback1)
- @resource.expects(:callback2)
+ @resource.expects(:callback1)
+ @resource.expects(:callback2)
- @manager.process_events(@resource)
- end
+ @manager.process_events(@resource)
+ end
- it "should set the 'restarted' state on the resource status" do
- @manager.expects(:queued_events).with(@resource).yields(:callback1, [@event])
+ it "should set the 'restarted' state on the resource status" do
+ @manager.expects(:queued_events).with(@resource).yields(:callback1, [@event])
- @resource.stubs(:callback1)
+ @resource.stubs(:callback1)
- @manager.process_events(@resource)
+ @manager.process_events(@resource)
- @transaction.resource_status(@resource).should be_restarted
- end
+ @transaction.resource_status(@resource).should be_restarted
+ end
- it "should queue a 'restarted' event generated by the resource" do
- @manager.expects(:queued_events).with(@resource).yields(:callback1, [@event])
+ it "should queue a 'restarted' event generated by the resource" do
+ @manager.expects(:queued_events).with(@resource).yields(:callback1, [@event])
- @resource.stubs(:callback1)
+ @resource.stubs(:callback1)
- @resource.expects(:event).with(:name => :restarted, :status => "success").returns "myevent"
- @manager.expects(:queue_events).with(@resource, ["myevent"])
+ @resource.expects(:event).with(:name => :restarted, :status => "success").returns "myevent"
+ @manager.expects(:queue_events).with(@resource, ["myevent"])
- @manager.process_events(@resource)
- end
+ @manager.process_events(@resource)
+ end
- it "should log that it restarted" do
- @manager.expects(:queued_events).with(@resource).yields(:callback1, [@event])
+ it "should log that it restarted" do
+ @manager.expects(:queued_events).with(@resource).yields(:callback1, [@event])
- @resource.stubs(:callback1)
+ @resource.stubs(:callback1)
- @resource.expects(:notice).with { |msg| msg.include?("Triggered 'callback1'") }
+ @resource.expects(:notice).with { |msg| msg.include?("Triggered 'callback1'") }
- @manager.process_events(@resource)
- end
+ @manager.process_events(@resource)
+ end
- describe "and the events include a noop event and at least one non-noop event" do
- before do
- @event.stubs(:status).returns "noop"
- @event2 = Puppet::Transaction::Event.new(:name => :event, :resource => @resource)
- @event2.status = "success"
- @manager.expects(:queued_events).with(@resource).yields(:callback1, [@event, @event2])
- end
+ describe "and the events include a noop event and at least one non-noop event" do
+ before do
+ @event.stubs(:status).returns "noop"
+ @event2 = Puppet::Transaction::Event.new(:name => :event, :resource => @resource)
+ @event2.status = "success"
+ @manager.expects(:queued_events).with(@resource).yields(:callback1, [@event, @event2])
+ end
- it "should call the callback" do
- @resource.expects(:callback1)
+ it "should call the callback" do
+ @resource.expects(:callback1)
- @manager.process_events(@resource)
- end
- end
+ @manager.process_events(@resource)
+ end
+ end
- describe "and the events are all noop events" do
- before do
- @event.stubs(:status).returns "noop"
- @resource.stubs(:event).returns(Puppet::Transaction::Event.new)
- @manager.expects(:queued_events).with(@resource).yields(:callback1, [@event])
- end
+ describe "and the events are all noop events" do
+ before do
+ @event.stubs(:status).returns "noop"
+ @resource.stubs(:event).returns(Puppet::Transaction::Event.new)
+ @manager.expects(:queued_events).with(@resource).yields(:callback1, [@event])
+ end
- it "should log" do
- @resource.expects(:notice).with { |msg| msg.include?("Would have triggered 'callback1'") }
+ it "should log" do
+ @resource.expects(:notice).with { |msg| msg.include?("Would have triggered 'callback1'") }
- @manager.process_events(@resource)
- end
+ @manager.process_events(@resource)
+ end
- it "should not call the callback" do
- @resource.expects(:callback1).never
+ it "should not call the callback" do
+ @resource.expects(:callback1).never
- @manager.process_events(@resource)
- end
+ @manager.process_events(@resource)
+ end
- it "should queue a new noop event generated from the resource" do
- event = Puppet::Transaction::Event.new
- @resource.expects(:event).with(:status => "noop", :name => :noop_restart).returns event
- @manager.expects(:queue_events).with(@resource, [event])
+ it "should queue a new noop event generated from the resource" do
+ event = Puppet::Transaction::Event.new
+ @resource.expects(:event).with(:status => "noop", :name => :noop_restart).returns event
+ @manager.expects(:queue_events).with(@resource, [event])
- @manager.process_events(@resource)
- end
- end
+ @manager.process_events(@resource)
+ end
+ end
- describe "and the callback fails" do
- before do
- @resource.expects(:callback1).raises "a failure"
- @resource.stubs(:err)
+ describe "and the callback fails" do
+ before do
+ @resource.expects(:callback1).raises "a failure"
+ @resource.stubs(:err)
- @manager.expects(:queued_events).yields(:callback1, [@event])
- end
+ @manager.expects(:queued_events).yields(:callback1, [@event])
+ end
- it "should log but not fail" do
- @resource.expects(:err)
+ it "should log but not fail" do
+ @resource.expects(:err)
- lambda { @manager.process_events(@resource) }.should_not raise_error
- end
+ lambda { @manager.process_events(@resource) }.should_not raise_error
+ end
- it "should set the 'failed_restarts' state on the resource status" do
- @manager.process_events(@resource)
- @transaction.resource_status(@resource).should be_failed_to_restart
- end
+ it "should set the 'failed_restarts' state on the resource status" do
+ @manager.process_events(@resource)
+ @transaction.resource_status(@resource).should be_failed_to_restart
+ end
- it "should not queue a 'restarted' event" do
- @manager.expects(:queue_events).never
- @manager.process_events(@resource)
- end
+ it "should not queue a 'restarted' event" do
+ @manager.expects(:queue_events).never
+ @manager.process_events(@resource)
+ end
- it "should set the 'restarted' state on the resource status" do
- @manager.process_events(@resource)
- @transaction.resource_status(@resource).should_not be_restarted
- end
- end
+ it "should set the 'restarted' state on the resource status" do
+ @manager.process_events(@resource)
+ @transaction.resource_status(@resource).should_not be_restarted
+ end
end
+ end
end
diff --git a/spec/unit/transaction/event_spec.rb b/spec/unit/transaction/event_spec.rb
index 85811c1..9cf6bc1 100755
--- a/spec/unit/transaction/event_spec.rb
+++ b/spec/unit/transaction/event_spec.rb
@@ -5,104 +5,104 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/transaction/event'
describe Puppet::Transaction::Event do
- [:previous_value, :desired_value, :property, :resource, :name, :message, :node, :version, :file, :line, :tags].each do |attr|
- it "should support #{attr}" do
- event = Puppet::Transaction::Event.new
- event.send(attr.to_s + "=", "foo")
- event.send(attr).should == "foo"
- end
+ [:previous_value, :desired_value, :property, :resource, :name, :message, :node, :version, :file, :line, :tags].each do |attr|
+ it "should support #{attr}" do
+ event = Puppet::Transaction::Event.new
+ event.send(attr.to_s + "=", "foo")
+ event.send(attr).should == "foo"
+ end
+ end
+
+ it "should always convert the property to a string" do
+ Puppet::Transaction::Event.new(:property => :foo).property.should == "foo"
+ end
+
+ it "should always convert the resource to a string" do
+ Puppet::Transaction::Event.new(:resource => :foo).resource.should == "foo"
+ end
+
+ it "should produce the message when converted to a string" do
+ event = Puppet::Transaction::Event.new
+ event.expects(:message).returns "my message"
+ event.to_s.should == "my message"
+ end
+
+ it "should support 'status'" do
+ event = Puppet::Transaction::Event.new
+ event.status = "success"
+ event.status.should == "success"
+ end
+
+ it "should fail if the status is not to 'audit', 'noop', 'success', or 'failure" do
+ event = Puppet::Transaction::Event.new
+ lambda { event.status = "foo" }.should raise_error(ArgumentError)
+ end
+
+ it "should support tags" do
+ Puppet::Transaction::Event.ancestors.should include(Puppet::Util::Tagging)
+ end
+
+ it "should create a timestamp at its creation time" do
+ Puppet::Transaction::Event.new.time.should be_instance_of(Time)
+ end
+
+ describe "when sending logs" do
+ before do
+ Puppet::Util::Log.stubs(:new)
+ end
+
+ it "should set the level to the resources's log level if the event status is 'success' and a resource is available" do
+ resource = stub 'resource'
+ resource.expects(:[]).with(:loglevel).returns :myloglevel
+ Puppet::Util::Log.expects(:create).with { |args| args[:level] == :myloglevel }
+ Puppet::Transaction::Event.new(:status => "success", :resource => resource).send_log
+ end
+
+ it "should set the level to 'notice' if the event status is 'success' and no resource is available" do
+ Puppet::Util::Log.expects(:new).with { |args| args[:level] == :notice }
+ Puppet::Transaction::Event.new(:status => "success").send_log
end
- it "should always convert the property to a string" do
- Puppet::Transaction::Event.new(:property => :foo).property.should == "foo"
+ it "should set the level to 'notice' if the event status is 'noop'" do
+ Puppet::Util::Log.expects(:new).with { |args| args[:level] == :notice }
+ Puppet::Transaction::Event.new(:status => "noop").send_log
end
- it "should always convert the resource to a string" do
- Puppet::Transaction::Event.new(:resource => :foo).resource.should == "foo"
+ it "should set the level to 'err' if the event status is 'failure'" do
+ Puppet::Util::Log.expects(:new).with { |args| args[:level] == :err }
+ Puppet::Transaction::Event.new(:status => "failure").send_log
end
- it "should produce the message when converted to a string" do
- event = Puppet::Transaction::Event.new
- event.expects(:message).returns "my message"
- event.to_s.should == "my message"
+ it "should set the 'message' to the event log" do
+ Puppet::Util::Log.expects(:new).with { |args| args[:message] == "my message" }
+ Puppet::Transaction::Event.new(:message => "my message").send_log
end
- it "should support 'status'" do
- event = Puppet::Transaction::Event.new
- event.status = "success"
- event.status.should == "success"
+ it "should set the tags to the event tags" do
+ Puppet::Util::Log.expects(:new).with { |args| args[:tags] == %w{one two} }
+ Puppet::Transaction::Event.new(:tags => %w{one two}).send_log
end
- it "should fail if the status is not to 'audit', 'noop', 'success', or 'failure" do
- event = Puppet::Transaction::Event.new
- lambda { event.status = "foo" }.should raise_error(ArgumentError)
+ [:file, :line, :version].each do |attr|
+ it "should pass the #{attr}" do
+ Puppet::Util::Log.expects(:new).with { |args| args[attr] == "my val" }
+ Puppet::Transaction::Event.new(attr => "my val").send_log
+ end
end
- it "should support tags" do
- Puppet::Transaction::Event.ancestors.should include(Puppet::Util::Tagging)
+ it "should use the source description as the source if one is set" do
+ Puppet::Util::Log.expects(:new).with { |args| args[:source] == "/my/param" }
+ Puppet::Transaction::Event.new(:source_description => "/my/param", :resource => "Foo[bar]", :property => "foo").send_log
end
- it "should create a timestamp at its creation time" do
- Puppet::Transaction::Event.new.time.should be_instance_of(Time)
+ it "should use the property as the source if one is available and no source description is set" do
+ Puppet::Util::Log.expects(:new).with { |args| args[:source] == "foo" }
+ Puppet::Transaction::Event.new(:resource => "Foo[bar]", :property => "foo").send_log
end
- describe "when sending logs" do
- before do
- Puppet::Util::Log.stubs(:new)
- end
-
- it "should set the level to the resources's log level if the event status is 'success' and a resource is available" do
- resource = stub 'resource'
- resource.expects(:[]).with(:loglevel).returns :myloglevel
- Puppet::Util::Log.expects(:create).with { |args| args[:level] == :myloglevel }
- Puppet::Transaction::Event.new(:status => "success", :resource => resource).send_log
- end
-
- it "should set the level to 'notice' if the event status is 'success' and no resource is available" do
- Puppet::Util::Log.expects(:new).with { |args| args[:level] == :notice }
- Puppet::Transaction::Event.new(:status => "success").send_log
- end
-
- it "should set the level to 'notice' if the event status is 'noop'" do
- Puppet::Util::Log.expects(:new).with { |args| args[:level] == :notice }
- Puppet::Transaction::Event.new(:status => "noop").send_log
- end
-
- it "should set the level to 'err' if the event status is 'failure'" do
- Puppet::Util::Log.expects(:new).with { |args| args[:level] == :err }
- Puppet::Transaction::Event.new(:status => "failure").send_log
- end
-
- it "should set the 'message' to the event log" do
- Puppet::Util::Log.expects(:new).with { |args| args[:message] == "my message" }
- Puppet::Transaction::Event.new(:message => "my message").send_log
- end
-
- it "should set the tags to the event tags" do
- Puppet::Util::Log.expects(:new).with { |args| args[:tags] == %w{one two} }
- Puppet::Transaction::Event.new(:tags => %w{one two}).send_log
- end
-
- [:file, :line, :version].each do |attr|
- it "should pass the #{attr}" do
- Puppet::Util::Log.expects(:new).with { |args| args[attr] == "my val" }
- Puppet::Transaction::Event.new(attr => "my val").send_log
- end
- end
-
- it "should use the source description as the source if one is set" do
- Puppet::Util::Log.expects(:new).with { |args| args[:source] == "/my/param" }
- Puppet::Transaction::Event.new(:source_description => "/my/param", :resource => "Foo[bar]", :property => "foo").send_log
- end
-
- it "should use the property as the source if one is available and no source description is set" do
- Puppet::Util::Log.expects(:new).with { |args| args[:source] == "foo" }
- Puppet::Transaction::Event.new(:resource => "Foo[bar]", :property => "foo").send_log
- end
-
- it "should use the property as the source if one is available and no property or source description is set" do
- Puppet::Util::Log.expects(:new).with { |args| args[:source] == "Foo[bar]" }
- Puppet::Transaction::Event.new(:resource => "Foo[bar]").send_log
- end
+ it "should use the property as the source if one is available and no property or source description is set" do
+ Puppet::Util::Log.expects(:new).with { |args| args[:source] == "Foo[bar]" }
+ Puppet::Transaction::Event.new(:resource => "Foo[bar]").send_log
end
+ end
end
diff --git a/spec/unit/transaction/report_spec.rb b/spec/unit/transaction/report_spec.rb
index 1ce68b3..7e0b055 100755
--- a/spec/unit/transaction/report_spec.rb
+++ b/spec/unit/transaction/report_spec.rb
@@ -5,230 +5,230 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/transaction/report'
describe Puppet::Transaction::Report do
+ before do
+ Puppet::Util::Storage.stubs(:store)
+ end
+
+ it "should set its host name to the certname" do
+ Puppet.settings.expects(:value).with(:certname).returns "myhost"
+ Puppet::Transaction::Report.new.host.should == "myhost"
+ end
+
+ it "should return its host name as its name" do
+ r = Puppet::Transaction::Report.new
+ r.name.should == r.host
+ end
+
+ it "should create an initialization timestamp" do
+ Time.expects(:now).returns "mytime"
+ Puppet::Transaction::Report.new.time.should == "mytime"
+ end
+
+ describe "when accepting logs" do
before do
- Puppet::Util::Storage.stubs(:store)
+ @report = Puppet::Transaction::Report.new
end
- it "should set its host name to the certname" do
- Puppet.settings.expects(:value).with(:certname).returns "myhost"
- Puppet::Transaction::Report.new.host.should == "myhost"
+ it "should add new logs to the log list" do
+ @report << "log"
+ @report.logs[-1].should == "log"
end
- it "should return its host name as its name" do
- r = Puppet::Transaction::Report.new
- r.name.should == r.host
+ it "should return self" do
+ r = @report << "log"
+ r.should equal(@report)
end
+ end
- it "should create an initialization timestamp" do
- Time.expects(:now).returns "mytime"
- Puppet::Transaction::Report.new.time.should == "mytime"
+ describe "when accepting resource statuses" do
+ before do
+ @report = Puppet::Transaction::Report.new
end
- describe "when accepting logs" do
- before do
- @report = Puppet::Transaction::Report.new
- end
-
- it "should add new logs to the log list" do
- @report << "log"
- @report.logs[-1].should == "log"
- end
+ it "should add each status to its status list" do
+ status = stub 'status', :resource => "foo"
+ @report.add_resource_status status
+ @report.resource_statuses["foo"].should equal(status)
+ end
+ end
+
+ describe "when using the indirector" do
+ it "should redirect :find to the indirection" do
+ @indirection = stub 'indirection', :name => :report
+ Puppet::Transaction::Report.stubs(:indirection).returns(@indirection)
+ @indirection.expects(:find)
+ Puppet::Transaction::Report.find(:report)
+ end
- it "should return self" do
- r = @report << "log"
- r.should equal(@report)
- end
+ it "should redirect :save to the indirection" do
+ Facter.stubs(:value).returns("eh")
+ @indirection = stub 'indirection', :name => :report
+ Puppet::Transaction::Report.stubs(:indirection).returns(@indirection)
+ report = Puppet::Transaction::Report.new
+ @indirection.expects(:save)
+ report.save
end
- describe "when accepting resource statuses" do
- before do
- @report = Puppet::Transaction::Report.new
- end
+ it "should default to the 'processor' terminus" do
+ Puppet::Transaction::Report.indirection.terminus_class.should == :processor
+ end
- it "should add each status to its status list" do
- status = stub 'status', :resource => "foo"
- @report.add_resource_status status
- @report.resource_statuses["foo"].should equal(status)
- end
+ it "should delegate its name attribute to its host method" do
+ report = Puppet::Transaction::Report.new
+ report.expects(:host).returns "me"
+ report.name.should == "me"
end
- describe "when using the indirector" do
- it "should redirect :find to the indirection" do
- @indirection = stub 'indirection', :name => :report
- Puppet::Transaction::Report.stubs(:indirection).returns(@indirection)
- @indirection.expects(:find)
- Puppet::Transaction::Report.find(:report)
- end
+ after do
+ Puppet::Util::Cacher.expire
+ end
+ end
+
+ describe "when computing exit status" do
+ it "should produce 2 if changes are present" do
+ report = Puppet::Transaction::Report.new
+ report.add_metric("changes", {:total => 1})
+ report.add_metric("resources", {:failed => 0})
+ report.exit_status.should == 2
+ end
- it "should redirect :save to the indirection" do
- Facter.stubs(:value).returns("eh")
- @indirection = stub 'indirection', :name => :report
- Puppet::Transaction::Report.stubs(:indirection).returns(@indirection)
- report = Puppet::Transaction::Report.new
- @indirection.expects(:save)
- report.save
- end
+ it "should produce 4 if failures are present" do
+ report = Puppet::Transaction::Report.new
+ report.add_metric("changes", {:total => 0})
+ report.add_metric("resources", {:failed => 1})
+ report.exit_status.should == 4
+ end
- it "should default to the 'processor' terminus" do
- Puppet::Transaction::Report.indirection.terminus_class.should == :processor
- end
+ it "should produce 6 if both changes and failures are present" do
+ report = Puppet::Transaction::Report.new
+ report.add_metric("changes", {:total => 1})
+ report.add_metric("resources", {:failed => 1})
+ report.exit_status.should == 6
+ end
+ end
- it "should delegate its name attribute to its host method" do
- report = Puppet::Transaction::Report.new
- report.expects(:host).returns "me"
- report.name.should == "me"
- end
+ describe "when calculating metrics" do
+ before do
+ @report = Puppet::Transaction::Report.new
+ end
- after do
- Puppet::Util::Cacher.expire
- end
+ def metric(name, value)
+ if metric = @report.metrics[name.to_s]
+ metric[value]
+ else
+ nil
+ end
end
- describe "when computing exit status" do
- it "should produce 2 if changes are present" do
- report = Puppet::Transaction::Report.new
- report.add_metric("changes", {:total => 1})
- report.add_metric("resources", {:failed => 0})
- report.exit_status.should == 2
- end
+ def add_statuses(count, type = :file)
+ 3.times do |i|
+ status = Puppet::Resource::Status.new(Puppet::Type.type(type).new(:title => "/my/path#{i}"))
+ yield status if block_given?
+ @report.add_resource_status status
+ end
+ end
- it "should produce 4 if failures are present" do
- report = Puppet::Transaction::Report.new
- report.add_metric("changes", {:total => 0})
- report.add_metric("resources", {:failed => 1})
- report.exit_status.should == 4
- end
- it "should produce 6 if both changes and failures are present" do
- report = Puppet::Transaction::Report.new
- report.add_metric("changes", {:total => 1})
- report.add_metric("resources", {:failed => 1})
- report.exit_status.should == 6
- end
+ [:time, :resources, :changes, :events].each do |type|
+ it "should add #{type} metrics" do
+ @report.calculate_metrics
+ @report.metrics[type.to_s].should be_instance_of(Puppet::Transaction::Metric)
+ end
end
- describe "when calculating metrics" do
- before do
- @report = Puppet::Transaction::Report.new
- end
-
- def metric(name, value)
- if metric = @report.metrics[name.to_s]
- metric[value]
- else
- nil
- end
- end
+ describe "for resources" do
+ it "should provide the total number of resources" do
+ add_statuses(3)
- def add_statuses(count, type = :file)
- 3.times do |i|
- status = Puppet::Resource::Status.new(Puppet::Type.type(type).new(:title => "/my/path#{i}"))
- yield status if block_given?
- @report.add_resource_status status
- end
- end
+ @report.calculate_metrics
+ metric(:resources, :total).should == 3
+ end
+ Puppet::Resource::Status::STATES.each do |state|
+ it "should provide the number of #{state} resources as determined by the status objects" do
+ add_statuses(3) { |status| status.send(state.to_s + "=", true) }
- [:time, :resources, :changes, :events].each do |type|
- it "should add #{type} metrics" do
- @report.calculate_metrics
- @report.metrics[type.to_s].should be_instance_of(Puppet::Transaction::Metric)
- end
+ @report.calculate_metrics
+ metric(:resources, state).should == 3
end
+ end
+ end
- describe "for resources" do
- it "should provide the total number of resources" do
- add_statuses(3)
-
- @report.calculate_metrics
- metric(:resources, :total).should == 3
- end
-
- Puppet::Resource::Status::STATES.each do |state|
- it "should provide the number of #{state} resources as determined by the status objects" do
- add_statuses(3) { |status| status.send(state.to_s + "=", true) }
+ describe "for changes" do
+ it "should provide the number of changes from the resource statuses" do
+ add_statuses(3) { |status| status.change_count = 3 }
+ @report.calculate_metrics
+ metric(:changes, :total).should == 9
+ end
+ end
- @report.calculate_metrics
- metric(:resources, state).should == 3
- end
- end
+ describe "for times" do
+ it "should provide the total amount of time for each resource type" do
+ add_statuses(3, :file) do |status|
+ status.evaluation_time = 1
end
-
- describe "for changes" do
- it "should provide the number of changes from the resource statuses" do
- add_statuses(3) { |status| status.change_count = 3 }
- @report.calculate_metrics
- metric(:changes, :total).should == 9
- end
+ add_statuses(3, :exec) do |status|
+ status.evaluation_time = 2
+ end
+ add_statuses(3, :mount) do |status|
+ status.evaluation_time = 3
end
- describe "for times" do
- it "should provide the total amount of time for each resource type" do
- add_statuses(3, :file) do |status|
- status.evaluation_time = 1
- end
- add_statuses(3, :exec) do |status|
- status.evaluation_time = 2
- end
- add_statuses(3, :mount) do |status|
- status.evaluation_time = 3
- end
-
- @report.calculate_metrics
-
- metric(:time, "file").should == 3
- metric(:time, "exec").should == 6
- metric(:time, "mount").should == 9
- end
+ @report.calculate_metrics
- it "should add any provided times from external sources" do
- @report.add_times :foobar, 50
- @report.calculate_metrics
- metric(:time, "foobar").should == 50
- end
+ metric(:time, "file").should == 3
+ metric(:time, "exec").should == 6
+ metric(:time, "mount").should == 9
+ end
+
+ it "should add any provided times from external sources" do
+ @report.add_times :foobar, 50
+ @report.calculate_metrics
+ metric(:time, "foobar").should == 50
+ end
+ end
+
+ describe "for events" do
+ it "should provide the total number of events" do
+ add_statuses(3) do |status|
+ 3.times { |i| status.add_event(Puppet::Transaction::Event.new) }
end
+ @report.calculate_metrics
+ metric(:events, :total).should == 9
+ end
- describe "for events" do
- it "should provide the total number of events" do
- add_statuses(3) do |status|
- 3.times { |i| status.add_event(Puppet::Transaction::Event.new) }
- end
- @report.calculate_metrics
- metric(:events, :total).should == 9
+ Puppet::Transaction::Event::EVENT_STATUSES.each do |status_name|
+ it "should provide the number of #{status_name} events" do
+ add_statuses(3) do |status|
+ 3.times do |i|
+ event = Puppet::Transaction::Event.new
+ event.status = status_name
+ status.add_event(event)
end
+ end
- Puppet::Transaction::Event::EVENT_STATUSES.each do |status_name|
- it "should provide the number of #{status_name} events" do
- add_statuses(3) do |status|
- 3.times do |i|
- event = Puppet::Transaction::Event.new
- event.status = status_name
- status.add_event(event)
- end
- end
-
- @report.calculate_metrics
- metric(:events, status_name).should == 9
- end
- end
+ @report.calculate_metrics
+ metric(:events, status_name).should == 9
end
+ end
end
+ end
- describe "when producing a summary" do
- before do
- resource = Puppet::Type.type(:notify).new(:name => "testing")
- catalog = Puppet::Resource::Catalog.new
- catalog.add_resource resource
- trans = catalog.apply
+ describe "when producing a summary" do
+ before do
+ resource = Puppet::Type.type(:notify).new(:name => "testing")
+ catalog = Puppet::Resource::Catalog.new
+ catalog.add_resource resource
+ trans = catalog.apply
- @report = trans.report
- @report.calculate_metrics
- end
+ @report = trans.report
+ @report.calculate_metrics
+ end
- %w{Changes Total Resources}.each do |main|
- it "should include information on #{main} in the summary" do
- @report.summary.should be_include(main)
- end
- end
+ %w{Changes Total Resources}.each do |main|
+ it "should include information on #{main} in the summary" do
+ @report.summary.should be_include(main)
+ end
end
+ end
end
diff --git a/spec/unit/transaction/resource_harness_spec.rb b/spec/unit/transaction/resource_harness_spec.rb
index 953b509..31965c9 100755
--- a/spec/unit/transaction/resource_harness_spec.rb
+++ b/spec/unit/transaction/resource_harness_spec.rb
@@ -5,397 +5,397 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/transaction/resource_harness'
describe Puppet::Transaction::ResourceHarness do
+ before do
+ @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new)
+ @resource = Puppet::Type.type(:file).new :path => "/my/file"
+ @harness = Puppet::Transaction::ResourceHarness.new(@transaction)
+ @current_state = Puppet::Resource.new(:file, "/my/file")
+ @resource.stubs(:retrieve).returns @current_state
+ @status = Puppet::Resource::Status.new(@resource)
+ Puppet::Resource::Status.stubs(:new).returns @status
+ end
+
+ it "should accept a transaction at initialization" do
+ harness = Puppet::Transaction::ResourceHarness.new(@transaction)
+ harness.transaction.should equal(@transaction)
+ end
+
+ it "should delegate to the transaction for its relationship graph" do
+ @transaction.expects(:relationship_graph).returns "relgraph"
+ Puppet::Transaction::ResourceHarness.new(@transaction).relationship_graph.should == "relgraph"
+ end
+
+ describe "when copying audited parameters" do
before do
- @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new)
- @resource = Puppet::Type.type(:file).new :path => "/my/file"
- @harness = Puppet::Transaction::ResourceHarness.new(@transaction)
- @current_state = Puppet::Resource.new(:file, "/my/file")
+ @resource = Puppet::Type.type(:file).new :path => "/foo/bar", :audit => :mode
+ end
+
+ it "should do nothing if no parameters are being audited" do
+ @resource[:audit] = []
+ @harness.expects(:cached).never
+ @harness.copy_audited_parameters(@resource, {}).should == []
+ end
+
+ it "should do nothing if an audited parameter already has a desired value set" do
+ @resource[:mode] = "755"
+ @harness.expects(:cached).never
+ @harness.copy_audited_parameters(@resource, {}).should == []
+ end
+
+ it "should copy any cached values to the 'should' values" do
+ @harness.cache(@resource, :mode, "755")
+ @harness.copy_audited_parameters(@resource, {}).should == [:mode]
+
+ @resource[:mode].should == 0755
+ end
+
+ it "should cache and log the current value if no cached values are present" do
+ @resource.expects(:info)
+ @harness.copy_audited_parameters(@resource, {:mode => "755"}).should == []
+
+ @harness.cached(@resource, :mode).should == "755"
+ end
+ end
+
+ describe "when evaluating a resource" do
+ it "should create and return a resource status instance for the resource" do
+ @harness.evaluate(@resource).should be_instance_of(Puppet::Resource::Status)
+ end
+
+ it "should fail if no status can be created" do
+ Puppet::Resource::Status.expects(:new).raises ArgumentError
+
+ lambda { @harness.evaluate(@resource) }.should raise_error
+ end
+
+ it "should retrieve the current state of the resource" do
+ @resource.expects(:retrieve).returns @current_state
+ @harness.evaluate(@resource)
+ end
+
+ it "should mark the resource as failed and return if the current state cannot be retrieved" do
+ @resource.expects(:retrieve).raises ArgumentError
+ @harness.evaluate(@resource).should be_failed
+ end
+
+ it "should use the status and retrieved state to determine which changes need to be made" do
+ @harness.expects(:changes_to_perform).with(@status, @resource).returns []
+ @harness.evaluate(@resource)
+ end
+
+ it "should mark the status as out of sync and apply the created changes if there are any" do
+ changes = %w{mychanges}
+ @harness.expects(:changes_to_perform).returns changes
+ @harness.expects(:apply_changes).with(@status, changes)
+ @harness.evaluate(@resource).should be_out_of_sync
+ end
+
+ it "should cache the last-synced time" do
+ changes = %w{mychanges}
+ @harness.stubs(:changes_to_perform).returns changes
+ @harness.stubs(:apply_changes)
+ @harness.expects(:cache).with { |resource, name, time| name == :synced and time.is_a?(Time) }
+ @harness.evaluate(@resource)
+ end
+
+ it "should flush the resource when applying changes if appropriate" do
+ changes = %w{mychanges}
+ @harness.stubs(:changes_to_perform).returns changes
+ @harness.stubs(:apply_changes)
+ @resource.expects(:flush)
+ @harness.evaluate(@resource)
+ end
+
+ it "should use the status and retrieved state to determine which changes need to be made" do
+ @harness.expects(:changes_to_perform).with(@status, @resource).returns []
+ @harness.evaluate(@resource)
+ end
+
+ it "should not attempt to apply changes if none need to be made" do
+ @harness.expects(:changes_to_perform).returns []
+ @harness.expects(:apply_changes).never
+ @harness.evaluate(@resource).should_not be_out_of_sync
+ end
+
+ it "should store the resource's evaluation time in the resource status" do
+ @harness.evaluate(@resource).evaluation_time.should be_instance_of(Float)
+ end
+
+ it "should set the change count to the total number of changes" do
+ changes = %w{a b c d}
+ @harness.expects(:changes_to_perform).returns changes
+ @harness.expects(:apply_changes).with(@status, changes)
+ @harness.evaluate(@resource).change_count.should == 4
+ end
+ end
+
+ describe "when creating changes" do
+ before do
+ @current_state = Puppet::Resource.new(:file, "/my/file")
+ @resource.stubs(:retrieve).returns @current_state
+ Puppet.features.stubs(:root?).returns true
+ end
+
+ it "should retrieve the current values from the resource" do
+ @resource.expects(:retrieve).returns @current_state
+ @harness.changes_to_perform(@status, @resource)
+ end
+
+ it "should cache that the resource was checked" do
+ @harness.expects(:cache).with { |resource, name, time| name == :checked and time.is_a?(Time) }
+ @harness.changes_to_perform(@status, @resource)
+ end
+
+ it "should create changes with the appropriate property and current value" do
+ @resource[:ensure] = :present
+ @current_state[:ensure] = :absent
+
+ change = stub 'change'
+ Puppet::Transaction::Change.expects(:new).with(@resource.parameter(:ensure), :absent).returns change
+
+ @harness.changes_to_perform(@status, @resource)[0].should equal(change)
+ end
+
+ it "should not attempt to manage properties that do not have desired values set" do
+ mode = @resource.newattr(:mode)
+ @current_state[:mode] = :absent
+
+ mode.expects(:insync?).never
+
+ @harness.changes_to_perform(@status, @resource)
+ end
+
+ it "should copy audited parameters" do
+ @resource[:audit] = :mode
+ @harness.cache(@resource, :mode, "755")
+ @harness.changes_to_perform(@status, @resource)
+ @resource[:mode].should == 0755
+ end
+
+ it "should mark changes created as a result of auditing as auditing changes" do
+ @current_state[:mode] = 0644
+ @resource[:audit] = :mode
+ @harness.cache(@resource, :mode, "755")
+ @harness.changes_to_perform(@status, @resource)[0].must be_auditing
+ end
+
+ describe "and the 'ensure' parameter is present but not in sync" do
+ it "should return a single change for the 'ensure' parameter" do
+ @resource[:ensure] = :present
+ @resource[:mode] = "755"
+ @current_state[:ensure] = :absent
+ @current_state[:mode] = :absent
+
@resource.stubs(:retrieve).returns @current_state
- @status = Puppet::Resource::Status.new(@resource)
- Puppet::Resource::Status.stubs(:new).returns @status
- end
-
- it "should accept a transaction at initialization" do
- harness = Puppet::Transaction::ResourceHarness.new(@transaction)
- harness.transaction.should equal(@transaction)
- end
-
- it "should delegate to the transaction for its relationship graph" do
- @transaction.expects(:relationship_graph).returns "relgraph"
- Puppet::Transaction::ResourceHarness.new(@transaction).relationship_graph.should == "relgraph"
- end
-
- describe "when copying audited parameters" do
- before do
- @resource = Puppet::Type.type(:file).new :path => "/foo/bar", :audit => :mode
- end
-
- it "should do nothing if no parameters are being audited" do
- @resource[:audit] = []
- @harness.expects(:cached).never
- @harness.copy_audited_parameters(@resource, {}).should == []
- end
-
- it "should do nothing if an audited parameter already has a desired value set" do
- @resource[:mode] = "755"
- @harness.expects(:cached).never
- @harness.copy_audited_parameters(@resource, {}).should == []
- end
-
- it "should copy any cached values to the 'should' values" do
- @harness.cache(@resource, :mode, "755")
- @harness.copy_audited_parameters(@resource, {}).should == [:mode]
-
- @resource[:mode].should == 0755
- end
-
- it "should cache and log the current value if no cached values are present" do
- @resource.expects(:info)
- @harness.copy_audited_parameters(@resource, {:mode => "755"}).should == []
-
- @harness.cached(@resource, :mode).should == "755"
- end
- end
-
- describe "when evaluating a resource" do
- it "should create and return a resource status instance for the resource" do
- @harness.evaluate(@resource).should be_instance_of(Puppet::Resource::Status)
- end
-
- it "should fail if no status can be created" do
- Puppet::Resource::Status.expects(:new).raises ArgumentError
-
- lambda { @harness.evaluate(@resource) }.should raise_error
- end
-
- it "should retrieve the current state of the resource" do
- @resource.expects(:retrieve).returns @current_state
- @harness.evaluate(@resource)
- end
-
- it "should mark the resource as failed and return if the current state cannot be retrieved" do
- @resource.expects(:retrieve).raises ArgumentError
- @harness.evaluate(@resource).should be_failed
- end
-
- it "should use the status and retrieved state to determine which changes need to be made" do
- @harness.expects(:changes_to_perform).with(@status, @resource).returns []
- @harness.evaluate(@resource)
- end
-
- it "should mark the status as out of sync and apply the created changes if there are any" do
- changes = %w{mychanges}
- @harness.expects(:changes_to_perform).returns changes
- @harness.expects(:apply_changes).with(@status, changes)
- @harness.evaluate(@resource).should be_out_of_sync
- end
-
- it "should cache the last-synced time" do
- changes = %w{mychanges}
- @harness.stubs(:changes_to_perform).returns changes
- @harness.stubs(:apply_changes)
- @harness.expects(:cache).with { |resource, name, time| name == :synced and time.is_a?(Time) }
- @harness.evaluate(@resource)
- end
-
- it "should flush the resource when applying changes if appropriate" do
- changes = %w{mychanges}
- @harness.stubs(:changes_to_perform).returns changes
- @harness.stubs(:apply_changes)
- @resource.expects(:flush)
- @harness.evaluate(@resource)
- end
-
- it "should use the status and retrieved state to determine which changes need to be made" do
- @harness.expects(:changes_to_perform).with(@status, @resource).returns []
- @harness.evaluate(@resource)
- end
-
- it "should not attempt to apply changes if none need to be made" do
- @harness.expects(:changes_to_perform).returns []
- @harness.expects(:apply_changes).never
- @harness.evaluate(@resource).should_not be_out_of_sync
- end
-
- it "should store the resource's evaluation time in the resource status" do
- @harness.evaluate(@resource).evaluation_time.should be_instance_of(Float)
- end
-
- it "should set the change count to the total number of changes" do
- changes = %w{a b c d}
- @harness.expects(:changes_to_perform).returns changes
- @harness.expects(:apply_changes).with(@status, changes)
- @harness.evaluate(@resource).change_count.should == 4
- end
- end
-
- describe "when creating changes" do
- before do
- @current_state = Puppet::Resource.new(:file, "/my/file")
- @resource.stubs(:retrieve).returns @current_state
- Puppet.features.stubs(:root?).returns true
- end
-
- it "should retrieve the current values from the resource" do
- @resource.expects(:retrieve).returns @current_state
- @harness.changes_to_perform(@status, @resource)
- end
-
- it "should cache that the resource was checked" do
- @harness.expects(:cache).with { |resource, name, time| name == :checked and time.is_a?(Time) }
- @harness.changes_to_perform(@status, @resource)
- end
-
- it "should create changes with the appropriate property and current value" do
- @resource[:ensure] = :present
- @current_state[:ensure] = :absent
-
- change = stub 'change'
- Puppet::Transaction::Change.expects(:new).with(@resource.parameter(:ensure), :absent).returns change
-
- @harness.changes_to_perform(@status, @resource)[0].should equal(change)
- end
-
- it "should not attempt to manage properties that do not have desired values set" do
- mode = @resource.newattr(:mode)
- @current_state[:mode] = :absent
-
- mode.expects(:insync?).never
-
- @harness.changes_to_perform(@status, @resource)
- end
-
- it "should copy audited parameters" do
- @resource[:audit] = :mode
- @harness.cache(@resource, :mode, "755")
- @harness.changes_to_perform(@status, @resource)
- @resource[:mode].should == 0755
- end
-
- it "should mark changes created as a result of auditing as auditing changes" do
- @current_state[:mode] = 0644
- @resource[:audit] = :mode
- @harness.cache(@resource, :mode, "755")
- @harness.changes_to_perform(@status, @resource)[0].must be_auditing
- end
-
- describe "and the 'ensure' parameter is present but not in sync" do
- it "should return a single change for the 'ensure' parameter" do
- @resource[:ensure] = :present
- @resource[:mode] = "755"
- @current_state[:ensure] = :absent
- @current_state[:mode] = :absent
-
- @resource.stubs(:retrieve).returns @current_state
-
- changes = @harness.changes_to_perform(@status, @resource)
- changes.length.should == 1
- changes[0].property.name.should == :ensure
- end
- end
-
- describe "and the 'ensure' parameter should be set to 'absent', and is correctly set to 'absent'" do
- it "should return no changes" do
- @resource[:ensure] = :absent
- @resource[:mode] = "755"
- @current_state[:ensure] = :absent
- @current_state[:mode] = :absent
-
- @harness.changes_to_perform(@status, @resource).should == []
- end
- end
-
- describe "and the 'ensure' parameter is 'absent' and there is no 'desired value'" do
- it "should return no changes" do
- @resource.newattr(:ensure)
- @resource[:mode] = "755"
- @current_state[:ensure] = :absent
- @current_state[:mode] = :absent
-
- @harness.changes_to_perform(@status, @resource).should == []
- end
- end
-
- describe "and non-'ensure' parameters are not in sync" do
- it "should return a change for each parameter that is not in sync" do
- @resource[:ensure] = :present
- @resource[:mode] = "755"
- @resource[:owner] = 0
- @current_state[:ensure] = :present
- @current_state[:mode] = 0444
- @current_state[:owner] = 50
-
- mode = stub 'mode_change'
- owner = stub 'owner_change'
- Puppet::Transaction::Change.expects(:new).with(@resource.parameter(:mode), 0444).returns mode
- Puppet::Transaction::Change.expects(:new).with(@resource.parameter(:owner), 50).returns owner
-
- changes = @harness.changes_to_perform(@status, @resource)
- changes.length.should == 2
- changes.should be_include(mode)
- changes.should be_include(owner)
- end
- end
-
- describe "and all parameters are in sync" do
- it "should return an empty array" do
- @resource[:ensure] = :present
- @resource[:mode] = "755"
- @current_state[:ensure] = :present
- @current_state[:mode] = 0755
- @harness.changes_to_perform(@status, @resource).should == []
- end
- end
- end
-
- describe "when applying changes" do
- before do
- @change1 = stub 'change1', :apply => stub("event", :status => "success"), :auditing? => false
- @change2 = stub 'change2', :apply => stub("event", :status => "success"), :auditing? => false
- @changes = [@change1, @change2]
- end
-
- it "should apply the change" do
- @change1.expects(:apply).returns( stub("event", :status => "success") )
- @change2.expects(:apply).returns( stub("event", :status => "success") )
-
- @harness.apply_changes(@status, @changes)
- end
-
- it "should mark the resource as changed" do
- @harness.apply_changes(@status, @changes)
-
- @status.should be_changed
- end
-
- it "should queue the resulting event" do
- @harness.apply_changes(@status, @changes)
-
- @status.events.should be_include(@change1.apply)
- @status.events.should be_include(@change2.apply)
- end
-
- it "should cache the new value if it is an auditing change" do
- @change1.expects(:auditing?).returns true
- property = stub 'property', :name => "foo", :resource => "myres"
- @change1.stubs(:property).returns property
- @change1.stubs(:is).returns "myval"
-
- @harness.apply_changes(@status, @changes)
-
- @harness.cached("myres", "foo").should == "myval"
- end
- end
-
- describe "when determining whether the resource can be changed" do
- before do
- @resource.stubs(:purging?).returns true
- @resource.stubs(:deleting?).returns true
- end
-
- it "should be true if the resource is not being purged" do
- @resource.expects(:purging?).returns false
- @harness.should be_allow_changes(@resource)
- end
-
- it "should be true if the resource is not being deleted" do
- @resource.expects(:deleting?).returns false
- @harness.should be_allow_changes(@resource)
- end
-
- it "should be true if the resource has no dependents" do
- @harness.relationship_graph.expects(:dependents).with(@resource).returns []
- @harness.should be_allow_changes(@resource)
- end
-
- it "should be true if all dependents are being deleted" do
- dep = stub 'dependent', :deleting? => true
- @harness.relationship_graph.expects(:dependents).with(@resource).returns [dep]
- @resource.expects(:purging?).returns true
- @harness.should be_allow_changes(@resource)
- end
-
- it "should be false if the resource's dependents are not being deleted" do
- dep = stub 'dependent', :deleting? => false, :ref => "myres"
- @resource.expects(:warning)
- @harness.relationship_graph.expects(:dependents).with(@resource).returns [dep]
- @harness.should_not be_allow_changes(@resource)
- end
- end
-
- describe "when finding the schedule" do
- before do
- @catalog = Puppet::Resource::Catalog.new
- @resource.catalog = @catalog
- end
-
- it "should warn and return nil if the resource has no catalog" do
- @resource.catalog = nil
- @resource.expects(:warning)
-
- @harness.schedule(@resource).should be_nil
- end
- it "should return nil if the resource specifies no schedule" do
- @harness.schedule(@resource).should be_nil
- end
+ changes = @harness.changes_to_perform(@status, @resource)
+ changes.length.should == 1
+ changes[0].property.name.should == :ensure
+ end
+ end
+
+ describe "and the 'ensure' parameter should be set to 'absent', and is correctly set to 'absent'" do
+ it "should return no changes" do
+ @resource[:ensure] = :absent
+ @resource[:mode] = "755"
+ @current_state[:ensure] = :absent
+ @current_state[:mode] = :absent
+
+ @harness.changes_to_perform(@status, @resource).should == []
+ end
+ end
+
+ describe "and the 'ensure' parameter is 'absent' and there is no 'desired value'" do
+ it "should return no changes" do
+ @resource.newattr(:ensure)
+ @resource[:mode] = "755"
+ @current_state[:ensure] = :absent
+ @current_state[:mode] = :absent
+
+ @harness.changes_to_perform(@status, @resource).should == []
+ end
+ end
+
+ describe "and non-'ensure' parameters are not in sync" do
+ it "should return a change for each parameter that is not in sync" do
+ @resource[:ensure] = :present
+ @resource[:mode] = "755"
+ @resource[:owner] = 0
+ @current_state[:ensure] = :present
+ @current_state[:mode] = 0444
+ @current_state[:owner] = 50
+
+ mode = stub 'mode_change'
+ owner = stub 'owner_change'
+ Puppet::Transaction::Change.expects(:new).with(@resource.parameter(:mode), 0444).returns mode
+ Puppet::Transaction::Change.expects(:new).with(@resource.parameter(:owner), 50).returns owner
+
+ changes = @harness.changes_to_perform(@status, @resource)
+ changes.length.should == 2
+ changes.should be_include(mode)
+ changes.should be_include(owner)
+ end
+ end
+
+ describe "and all parameters are in sync" do
+ it "should return an empty array" do
+ @resource[:ensure] = :present
+ @resource[:mode] = "755"
+ @current_state[:ensure] = :present
+ @current_state[:mode] = 0755
+ @harness.changes_to_perform(@status, @resource).should == []
+ end
+ end
+ end
+
+ describe "when applying changes" do
+ before do
+ @change1 = stub 'change1', :apply => stub("event", :status => "success"), :auditing? => false
+ @change2 = stub 'change2', :apply => stub("event", :status => "success"), :auditing? => false
+ @changes = [@change1, @change2]
+ end
+
+ it "should apply the change" do
+ @change1.expects(:apply).returns( stub("event", :status => "success") )
+ @change2.expects(:apply).returns( stub("event", :status => "success") )
+
+ @harness.apply_changes(@status, @changes)
+ end
+
+ it "should mark the resource as changed" do
+ @harness.apply_changes(@status, @changes)
+
+ @status.should be_changed
+ end
+
+ it "should queue the resulting event" do
+ @harness.apply_changes(@status, @changes)
+
+ @status.events.should be_include(@change1.apply)
+ @status.events.should be_include(@change2.apply)
+ end
+
+ it "should cache the new value if it is an auditing change" do
+ @change1.expects(:auditing?).returns true
+ property = stub 'property', :name => "foo", :resource => "myres"
+ @change1.stubs(:property).returns property
+ @change1.stubs(:is).returns "myval"
+
+ @harness.apply_changes(@status, @changes)
- it "should fail if the named schedule cannot be found" do
- @resource[:schedule] = "whatever"
- @resource.expects(:fail)
- @harness.schedule(@resource)
- end
+ @harness.cached("myres", "foo").should == "myval"
+ end
+ end
+
+ describe "when determining whether the resource can be changed" do
+ before do
+ @resource.stubs(:purging?).returns true
+ @resource.stubs(:deleting?).returns true
+ end
- it "should return the named schedule if it exists" do
- sched = Puppet::Type.type(:schedule).new(:name => "sched")
- @catalog.add_resource(sched)
- @resource[:schedule] = "sched"
- @harness.schedule(@resource).to_s.should == sched.to_s
- end
+ it "should be true if the resource is not being purged" do
+ @resource.expects(:purging?).returns false
+ @harness.should be_allow_changes(@resource)
end
- describe "when determining if a resource is scheduled" do
- before do
- @catalog = Puppet::Resource::Catalog.new
- @resource.catalog = @catalog
- @status = Puppet::Resource::Status.new(@resource)
- end
+ it "should be true if the resource is not being deleted" do
+ @resource.expects(:deleting?).returns false
+ @harness.should be_allow_changes(@resource)
+ end
+
+ it "should be true if the resource has no dependents" do
+ @harness.relationship_graph.expects(:dependents).with(@resource).returns []
+ @harness.should be_allow_changes(@resource)
+ end
- it "should return true if 'ignoreschedules' is set" do
- Puppet[:ignoreschedules] = true
- @resource[:schedule] = "meh"
- @harness.should be_scheduled(@status, @resource)
- end
+ it "should be true if all dependents are being deleted" do
+ dep = stub 'dependent', :deleting? => true
+ @harness.relationship_graph.expects(:dependents).with(@resource).returns [dep]
+ @resource.expects(:purging?).returns true
+ @harness.should be_allow_changes(@resource)
+ end
- it "should return true if the resource has no schedule set" do
- @harness.should be_scheduled(@status, @resource)
- end
+ it "should be false if the resource's dependents are not being deleted" do
+ dep = stub 'dependent', :deleting? => false, :ref => "myres"
+ @resource.expects(:warning)
+ @harness.relationship_graph.expects(:dependents).with(@resource).returns [dep]
+ @harness.should_not be_allow_changes(@resource)
+ end
+ end
- it "should return the result of matching the schedule with the cached 'checked' time if a schedule is set" do
- t = Time.now
- @harness.expects(:cached).with(@resource, :checked).returns(t)
+ describe "when finding the schedule" do
+ before do
+ @catalog = Puppet::Resource::Catalog.new
+ @resource.catalog = @catalog
+ end
- sched = Puppet::Type.type(:schedule).new(:name => "sched")
- @catalog.add_resource(sched)
- @resource[:schedule] = "sched"
+ it "should warn and return nil if the resource has no catalog" do
+ @resource.catalog = nil
+ @resource.expects(:warning)
- sched.expects(:match?).with(t.to_i).returns "feh"
+ @harness.schedule(@resource).should be_nil
+ end
- @harness.scheduled?(@status, @resource).should == "feh"
- end
+ it "should return nil if the resource specifies no schedule" do
+ @harness.schedule(@resource).should be_nil
end
- it "should be able to cache data in the Storage module" do
- data = {}
- Puppet::Util::Storage.expects(:cache).with(@resource).returns data
- @harness.cache(@resource, :foo, "something")
-
- data[:foo].should == "something"
+ it "should fail if the named schedule cannot be found" do
+ @resource[:schedule] = "whatever"
+ @resource.expects(:fail)
+ @harness.schedule(@resource)
end
- it "should be able to retrieve data from the cache" do
- data = {:foo => "other"}
- Puppet::Util::Storage.expects(:cache).with(@resource).returns data
- @harness.cached(@resource, :foo).should == "other"
+ it "should return the named schedule if it exists" do
+ sched = Puppet::Type.type(:schedule).new(:name => "sched")
+ @catalog.add_resource(sched)
+ @resource[:schedule] = "sched"
+ @harness.schedule(@resource).to_s.should == sched.to_s
end
+ end
+
+ describe "when determining if a resource is scheduled" do
+ before do
+ @catalog = Puppet::Resource::Catalog.new
+ @resource.catalog = @catalog
+ @status = Puppet::Resource::Status.new(@resource)
+ end
+
+ it "should return true if 'ignoreschedules' is set" do
+ Puppet[:ignoreschedules] = true
+ @resource[:schedule] = "meh"
+ @harness.should be_scheduled(@status, @resource)
+ end
+
+ it "should return true if the resource has no schedule set" do
+ @harness.should be_scheduled(@status, @resource)
+ end
+
+ it "should return the result of matching the schedule with the cached 'checked' time if a schedule is set" do
+ t = Time.now
+ @harness.expects(:cached).with(@resource, :checked).returns(t)
+
+ sched = Puppet::Type.type(:schedule).new(:name => "sched")
+ @catalog.add_resource(sched)
+ @resource[:schedule] = "sched"
+
+ sched.expects(:match?).with(t.to_i).returns "feh"
+
+ @harness.scheduled?(@status, @resource).should == "feh"
+ end
+ end
+
+ it "should be able to cache data in the Storage module" do
+ data = {}
+ Puppet::Util::Storage.expects(:cache).with(@resource).returns data
+ @harness.cache(@resource, :foo, "something")
+
+ data[:foo].should == "something"
+ end
+
+ it "should be able to retrieve data from the cache" do
+ data = {:foo => "other"}
+ Puppet::Util::Storage.expects(:cache).with(@resource).returns data
+ @harness.cached(@resource, :foo).should == "other"
+ end
end
diff --git a/spec/unit/transaction_spec.rb b/spec/unit/transaction_spec.rb
index f0e3113..2df4404 100755
--- a/spec/unit/transaction_spec.rb
+++ b/spec/unit/transaction_spec.rb
@@ -5,448 +5,448 @@ require File.dirname(__FILE__) + '/../spec_helper'
require 'puppet/transaction'
def without_warnings
- flag = $VERBOSE
- $VERBOSE = nil
- yield
- $VERBOSE = flag
+ flag = $VERBOSE
+ $VERBOSE = nil
+ yield
+ $VERBOSE = flag
end
describe Puppet::Transaction do
- before do
- @basepath = Puppet.features.posix? ? "/what/ever" : "C:/tmp"
- @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new)
+ before do
+ @basepath = Puppet.features.posix? ? "/what/ever" : "C:/tmp"
+ @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new)
+ end
+
+ it "should delegate its event list to the event manager" do
+ @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new)
+ @transaction.event_manager.expects(:events).returns %w{my events}
+ @transaction.events.should == %w{my events}
+ end
+
+ it "should delegate adding times to its report" do
+ @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new)
+ @transaction.report.expects(:add_times).with(:foo, 10)
+ @transaction.report.expects(:add_times).with(:bar, 20)
+
+ @transaction.add_times :foo => 10, :bar => 20
+ end
+
+ it "should be able to accept resource status instances" do
+ resource = Puppet::Type.type(:notify).new :title => "foobar"
+ status = Puppet::Resource::Status.new(resource)
+ @transaction.add_resource_status(status)
+ @transaction.resource_status(resource).should equal(status)
+ end
+
+ it "should be able to look resource status up by resource reference" do
+ resource = Puppet::Type.type(:notify).new :title => "foobar"
+ status = Puppet::Resource::Status.new(resource)
+ @transaction.add_resource_status(status)
+ @transaction.resource_status(resource.to_s).should equal(status)
+ end
+
+ # This will basically only ever be used during testing.
+ it "should automatically create resource statuses if asked for a non-existent status" do
+ resource = Puppet::Type.type(:notify).new :title => "foobar"
+ @transaction.resource_status(resource).should be_instance_of(Puppet::Resource::Status)
+ end
+
+ it "should add provided resource statuses to its report" do
+ resource = Puppet::Type.type(:notify).new :title => "foobar"
+ status = Puppet::Resource::Status.new(resource)
+ @transaction.add_resource_status(status)
+ @transaction.report.resource_statuses[resource.to_s].should equal(status)
+ end
+
+ it "should calculate metrics on and report the report when asked to generate a report" do
+ @transaction.report.expects(:calculate_metrics)
+ @transaction.generate_report.should equal(@transaction.report)
+ end
+
+ it "should consider a resource to be failed if a status instance exists for that resource and indicates it is failed" do
+ resource = Puppet::Type.type(:notify).new :name => "yayness"
+ status = Puppet::Resource::Status.new(resource)
+ status.failed = "some message"
+ @transaction.add_resource_status(status)
+ @transaction.should be_failed(resource)
+ end
+
+ it "should not consider a resource to be failed if a status instance exists for that resource but indicates it is not failed" do
+ resource = Puppet::Type.type(:notify).new :name => "yayness"
+ status = Puppet::Resource::Status.new(resource)
+ @transaction.add_resource_status(status)
+ @transaction.should_not be_failed(resource)
+ end
+
+ it "should consider there to be failed resources if any statuses are marked failed" do
+ resource = Puppet::Type.type(:notify).new :name => "yayness"
+ status = Puppet::Resource::Status.new(resource)
+ status.failed = "some message"
+ @transaction.add_resource_status(status)
+ @transaction.should be_any_failed
+ end
+
+ it "should not consider there to be failed resources if no statuses are marked failed" do
+ resource = Puppet::Type.type(:notify).new :name => "yayness"
+ status = Puppet::Resource::Status.new(resource)
+ @transaction.add_resource_status(status)
+ @transaction.should_not be_any_failed
+ end
+
+ it "should be possible to replace the report object" do
+ report = Puppet::Transaction::Report.new
+ @transaction.report = report
+
+ @transaction.report.should == report
+ end
+
+ it "should consider a resource to have failed dependencies if any of its dependencies are failed"
+
+ describe "when initializing" do
+ it "should create an event manager" do
+ @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new)
+ @transaction.event_manager.should be_instance_of(Puppet::Transaction::EventManager)
+ @transaction.event_manager.transaction.should equal(@transaction)
end
- it "should delegate its event list to the event manager" do
- @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new)
- @transaction.event_manager.expects(:events).returns %w{my events}
- @transaction.events.should == %w{my events}
+ it "should create a resource harness" do
+ @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new)
+ @transaction.resource_harness.should be_instance_of(Puppet::Transaction::ResourceHarness)
+ @transaction.resource_harness.transaction.should equal(@transaction)
end
+ end
- it "should delegate adding times to its report" do
- @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new)
- @transaction.report.expects(:add_times).with(:foo, 10)
- @transaction.report.expects(:add_times).with(:bar, 20)
-
- @transaction.add_times :foo => 10, :bar => 20
- end
+ describe "when evaluating a resource" do
+ before do
+ @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new)
+ @transaction.stubs(:eval_children_and_apply_resource)
+ @transaction.stubs(:skip?).returns false
- it "should be able to accept resource status instances" do
- resource = Puppet::Type.type(:notify).new :title => "foobar"
- status = Puppet::Resource::Status.new(resource)
- @transaction.add_resource_status(status)
- @transaction.resource_status(resource).should equal(status)
+ @resource = Puppet::Type.type(:file).new :path => @basepath
end
- it "should be able to look resource status up by resource reference" do
- resource = Puppet::Type.type(:notify).new :title => "foobar"
- status = Puppet::Resource::Status.new(resource)
- @transaction.add_resource_status(status)
- @transaction.resource_status(resource.to_s).should equal(status)
- end
+ it "should check whether the resource should be skipped" do
+ @transaction.expects(:skip?).with(@resource).returns false
- # This will basically only ever be used during testing.
- it "should automatically create resource statuses if asked for a non-existent status" do
- resource = Puppet::Type.type(:notify).new :title => "foobar"
- @transaction.resource_status(resource).should be_instance_of(Puppet::Resource::Status)
+ @transaction.eval_resource(@resource)
end
- it "should add provided resource statuses to its report" do
- resource = Puppet::Type.type(:notify).new :title => "foobar"
- status = Puppet::Resource::Status.new(resource)
- @transaction.add_resource_status(status)
- @transaction.report.resource_statuses[resource.to_s].should equal(status)
- end
+ it "should eval and apply children" do
+ @transaction.expects(:eval_children_and_apply_resource).with(@resource, nil)
- it "should calculate metrics on and report the report when asked to generate a report" do
- @transaction.report.expects(:calculate_metrics)
- @transaction.generate_report.should equal(@transaction.report)
+ @transaction.eval_resource(@resource)
end
- it "should consider a resource to be failed if a status instance exists for that resource and indicates it is failed" do
- resource = Puppet::Type.type(:notify).new :name => "yayness"
- status = Puppet::Resource::Status.new(resource)
- status.failed = "some message"
- @transaction.add_resource_status(status)
- @transaction.should be_failed(resource)
- end
+ it "should process events" do
+ @transaction.event_manager.expects(:process_events).with(@resource)
- it "should not consider a resource to be failed if a status instance exists for that resource but indicates it is not failed" do
- resource = Puppet::Type.type(:notify).new :name => "yayness"
- status = Puppet::Resource::Status.new(resource)
- @transaction.add_resource_status(status)
- @transaction.should_not be_failed(resource)
+ @transaction.eval_resource(@resource)
end
- it "should consider there to be failed resources if any statuses are marked failed" do
- resource = Puppet::Type.type(:notify).new :name => "yayness"
- status = Puppet::Resource::Status.new(resource)
- status.failed = "some message"
- @transaction.add_resource_status(status)
- @transaction.should be_any_failed
- end
+ describe "and the resource should be skipped" do
+ before do
+ @transaction.expects(:skip?).with(@resource).returns true
+ end
- it "should not consider there to be failed resources if no statuses are marked failed" do
- resource = Puppet::Type.type(:notify).new :name => "yayness"
- status = Puppet::Resource::Status.new(resource)
- @transaction.add_resource_status(status)
- @transaction.should_not be_any_failed
+ it "should mark the resource's status as skipped" do
+ @transaction.eval_resource(@resource)
+ @transaction.resource_status(@resource).should be_skipped
+ end
end
+ end
- it "should be possible to replace the report object" do
- report = Puppet::Transaction::Report.new
- @transaction.report = report
+ describe "when applying a resource" do
+ before do
+ @resource = Puppet::Type.type(:file).new :path => @basepath
+ @status = Puppet::Resource::Status.new(@resource)
- @transaction.report.should == report
+ @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new)
+ @transaction.event_manager.stubs(:queue_events)
+ @transaction.resource_harness.stubs(:evaluate).returns(@status)
end
- it "should consider a resource to have failed dependencies if any of its dependencies are failed"
-
- describe "when initializing" do
- it "should create an event manager" do
- @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new)
- @transaction.event_manager.should be_instance_of(Puppet::Transaction::EventManager)
- @transaction.event_manager.transaction.should equal(@transaction)
- end
-
- it "should create a resource harness" do
- @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new)
- @transaction.resource_harness.should be_instance_of(Puppet::Transaction::ResourceHarness)
- @transaction.resource_harness.transaction.should equal(@transaction)
- end
+ it "should use its resource harness to apply the resource" do
+ @transaction.resource_harness.expects(:evaluate).with(@resource)
+ @transaction.apply(@resource)
end
- describe "when evaluating a resource" do
- before do
- @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new)
- @transaction.stubs(:eval_children_and_apply_resource)
- @transaction.stubs(:skip?).returns false
-
- @resource = Puppet::Type.type(:file).new :path => @basepath
- end
-
- it "should check whether the resource should be skipped" do
- @transaction.expects(:skip?).with(@resource).returns false
-
- @transaction.eval_resource(@resource)
- end
-
- it "should eval and apply children" do
- @transaction.expects(:eval_children_and_apply_resource).with(@resource, nil)
-
- @transaction.eval_resource(@resource)
- end
-
- it "should process events" do
- @transaction.event_manager.expects(:process_events).with(@resource)
-
- @transaction.eval_resource(@resource)
- end
-
- describe "and the resource should be skipped" do
- before do
- @transaction.expects(:skip?).with(@resource).returns true
- end
-
- it "should mark the resource's status as skipped" do
- @transaction.eval_resource(@resource)
- @transaction.resource_status(@resource).should be_skipped
- end
- end
+ it "should add the resulting resource status to its status list" do
+ @transaction.apply(@resource)
+ @transaction.resource_status(@resource).should be_instance_of(Puppet::Resource::Status)
end
- describe "when applying a resource" do
- before do
- @resource = Puppet::Type.type(:file).new :path => @basepath
- @status = Puppet::Resource::Status.new(@resource)
+ it "should queue any events added to the resource status" do
+ @status.expects(:events).returns %w{a b}
+ @transaction.event_manager.expects(:queue_events).with(@resource, ["a", "b"])
+ @transaction.apply(@resource)
+ end
- @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new)
- @transaction.event_manager.stubs(:queue_events)
- @transaction.resource_harness.stubs(:evaluate).returns(@status)
- end
+ it "should log and skip any resources that cannot be applied" do
+ @transaction.resource_harness.expects(:evaluate).raises ArgumentError
+ @resource.expects(:err)
+ @transaction.apply(@resource)
+ @transaction.report.resource_statuses[@resource.to_s].should be_nil
+ end
+ end
- it "should use its resource harness to apply the resource" do
- @transaction.resource_harness.expects(:evaluate).with(@resource)
- @transaction.apply(@resource)
- end
+ describe "when generating resources" do
+ it "should call 'generate' on all created resources" do
+ first = Puppet::Type.type(:notify).new(:name => "first")
+ second = Puppet::Type.type(:notify).new(:name => "second")
+ third = Puppet::Type.type(:notify).new(:name => "third")
- it "should add the resulting resource status to its status list" do
- @transaction.apply(@resource)
- @transaction.resource_status(@resource).should be_instance_of(Puppet::Resource::Status)
- end
+ @catalog = Puppet::Resource::Catalog.new
+ @transaction = Puppet::Transaction.new(@catalog)
- it "should queue any events added to the resource status" do
- @status.expects(:events).returns %w{a b}
- @transaction.event_manager.expects(:queue_events).with(@resource, ["a", "b"])
- @transaction.apply(@resource)
- end
+ first.expects(:generate).returns [second]
+ second.expects(:generate).returns [third]
+ third.expects(:generate)
- it "should log and skip any resources that cannot be applied" do
- @transaction.resource_harness.expects(:evaluate).raises ArgumentError
- @resource.expects(:err)
- @transaction.apply(@resource)
- @transaction.report.resource_statuses[@resource.to_s].should be_nil
- end
+ @transaction.generate_additional_resources(first, :generate)
end
- describe "when generating resources" do
- it "should call 'generate' on all created resources" do
- first = Puppet::Type.type(:notify).new(:name => "first")
- second = Puppet::Type.type(:notify).new(:name => "second")
- third = Puppet::Type.type(:notify).new(:name => "third")
-
- @catalog = Puppet::Resource::Catalog.new
- @transaction = Puppet::Transaction.new(@catalog)
-
- first.expects(:generate).returns [second]
- second.expects(:generate).returns [third]
- third.expects(:generate)
+ it "should finish all resources" do
+ generator = stub 'generator', :depthfirst? => true, :tags => []
+ resource = stub 'resource', :tag => nil
- @transaction.generate_additional_resources(first, :generate)
- end
+ @catalog = Puppet::Resource::Catalog.new
+ @transaction = Puppet::Transaction.new(@catalog)
- it "should finish all resources" do
- generator = stub 'generator', :depthfirst? => true, :tags => []
- resource = stub 'resource', :tag => nil
+ generator.expects(:generate).returns [resource]
- @catalog = Puppet::Resource::Catalog.new
- @transaction = Puppet::Transaction.new(@catalog)
+ @catalog.expects(:add_resource).yields(resource)
- generator.expects(:generate).returns [resource]
+ resource.expects(:finish)
- @catalog.expects(:add_resource).yields(resource)
-
- resource.expects(:finish)
+ @transaction.generate_additional_resources(generator, :generate)
+ end
- @transaction.generate_additional_resources(generator, :generate)
- end
+ it "should skip generated resources that conflict with existing resources" do
+ generator = mock 'generator', :tags => []
+ resource = stub 'resource', :tag => nil
- it "should skip generated resources that conflict with existing resources" do
- generator = mock 'generator', :tags => []
- resource = stub 'resource', :tag => nil
+ @catalog = Puppet::Resource::Catalog.new
+ @transaction = Puppet::Transaction.new(@catalog)
- @catalog = Puppet::Resource::Catalog.new
- @transaction = Puppet::Transaction.new(@catalog)
+ generator.expects(:generate).returns [resource]
- generator.expects(:generate).returns [resource]
+ @catalog.expects(:add_resource).raises(Puppet::Resource::Catalog::DuplicateResourceError.new("foo"))
- @catalog.expects(:add_resource).raises(Puppet::Resource::Catalog::DuplicateResourceError.new("foo"))
+ resource.expects(:finish).never
+ resource.expects(:info) # log that it's skipped
- resource.expects(:finish).never
- resource.expects(:info) # log that it's skipped
+ @transaction.generate_additional_resources(generator, :generate).should be_empty
+ end
- @transaction.generate_additional_resources(generator, :generate).should be_empty
- end
+ it "should copy all tags to the newly generated resources" do
+ child = stub 'child'
+ generator = stub 'resource', :tags => ["one", "two"]
- it "should copy all tags to the newly generated resources" do
- child = stub 'child'
- generator = stub 'resource', :tags => ["one", "two"]
+ @catalog = Puppet::Resource::Catalog.new
+ @transaction = Puppet::Transaction.new(@catalog)
- @catalog = Puppet::Resource::Catalog.new
- @transaction = Puppet::Transaction.new(@catalog)
+ generator.stubs(:generate).returns [child]
+ @catalog.stubs(:add_resource)
- generator.stubs(:generate).returns [child]
- @catalog.stubs(:add_resource)
+ child.expects(:tag).with("one", "two")
- child.expects(:tag).with("one", "two")
+ @transaction.generate_additional_resources(generator, :generate)
+ end
+ end
+
+ describe "when skipping a resource" do
+ before :each do
+ @resource = Puppet::Type.type(:notify).new :name => "foo"
+ @catalog = Puppet::Resource::Catalog.new
+ @resource.catalog = @catalog
+ @transaction = Puppet::Transaction.new(@catalog)
+ end
- @transaction.generate_additional_resources(generator, :generate)
- end
+ it "should skip resource with missing tags" do
+ @transaction.stubs(:missing_tags?).returns(true)
+ @transaction.should be_skip(@resource)
end
- describe "when skipping a resource" do
- before :each do
- @resource = Puppet::Type.type(:notify).new :name => "foo"
- @catalog = Puppet::Resource::Catalog.new
- @resource.catalog = @catalog
- @transaction = Puppet::Transaction.new(@catalog)
- end
+ it "should skip unscheduled resources" do
+ @transaction.stubs(:scheduled?).returns(false)
+ @transaction.should be_skip(@resource)
+ end
- it "should skip resource with missing tags" do
- @transaction.stubs(:missing_tags?).returns(true)
- @transaction.should be_skip(@resource)
- end
+ it "should skip resources with failed dependencies" do
+ @transaction.stubs(:failed_dependencies?).returns(true)
+ @transaction.should be_skip(@resource)
+ end
- it "should skip unscheduled resources" do
- @transaction.stubs(:scheduled?).returns(false)
- @transaction.should be_skip(@resource)
- end
+ it "should skip virtual resource" do
+ @resource.stubs(:virtual?).returns true
+ @transaction.should be_skip(@resource)
+ end
+ end
- it "should skip resources with failed dependencies" do
- @transaction.stubs(:failed_dependencies?).returns(true)
- @transaction.should be_skip(@resource)
- end
+ describe "when determining if tags are missing" do
+ before :each do
+ @resource = Puppet::Type.type(:notify).new :name => "foo"
+ @catalog = Puppet::Resource::Catalog.new
+ @resource.catalog = @catalog
+ @transaction = Puppet::Transaction.new(@catalog)
- it "should skip virtual resource" do
- @resource.stubs(:virtual?).returns true
- @transaction.should be_skip(@resource)
- end
+ @transaction.stubs(:ignore_tags?).returns false
end
- describe "when determining if tags are missing" do
- before :each do
- @resource = Puppet::Type.type(:notify).new :name => "foo"
- @catalog = Puppet::Resource::Catalog.new
- @resource.catalog = @catalog
- @transaction = Puppet::Transaction.new(@catalog)
+ it "should not be missing tags if tags are being ignored" do
+ @transaction.expects(:ignore_tags?).returns true
- @transaction.stubs(:ignore_tags?).returns false
- end
+ @resource.expects(:tagged?).never
- it "should not be missing tags if tags are being ignored" do
- @transaction.expects(:ignore_tags?).returns true
+ @transaction.should_not be_missing_tags(@resource)
+ end
- @resource.expects(:tagged?).never
+ it "should not be missing tags if the transaction tags are empty" do
+ @transaction.tags = []
+ @resource.expects(:tagged?).never
+ @transaction.should_not be_missing_tags(@resource)
+ end
- @transaction.should_not be_missing_tags(@resource)
- end
+ it "should otherwise let the resource determine if it is missing tags" do
+ tags = ['one', 'two']
+ @transaction.tags = tags
+ @resource.expects(:tagged?).with(*tags).returns(false)
+ @transaction.should be_missing_tags(@resource)
+ end
+ end
+
+ describe "when determining if a resource should be scheduled" do
+ before :each do
+ @resource = Puppet::Type.type(:notify).new :name => "foo"
+ @catalog = Puppet::Resource::Catalog.new
+ @resource.catalog = @catalog
+ @transaction = Puppet::Transaction.new(@catalog)
+ end
- it "should not be missing tags if the transaction tags are empty" do
- @transaction.tags = []
- @resource.expects(:tagged?).never
- @transaction.should_not be_missing_tags(@resource)
- end
+ it "should always schedule resources if 'ignoreschedules' is set" do
+ @transaction.ignoreschedules = true
+ @transaction.resource_harness.expects(:scheduled?).never
- it "should otherwise let the resource determine if it is missing tags" do
- tags = ['one', 'two']
- @transaction.tags = tags
- @resource.expects(:tagged?).with(*tags).returns(false)
- @transaction.should be_missing_tags(@resource)
- end
+ @transaction.should be_scheduled(@resource)
end
- describe "when determining if a resource should be scheduled" do
- before :each do
- @resource = Puppet::Type.type(:notify).new :name => "foo"
- @catalog = Puppet::Resource::Catalog.new
- @resource.catalog = @catalog
- @transaction = Puppet::Transaction.new(@catalog)
- end
+ it "should let the resource harness determine whether the resource should be scheduled" do
+ @transaction.resource_harness.expects(:scheduled?).with(@transaction.resource_status(@resource), @resource).returns "feh"
- it "should always schedule resources if 'ignoreschedules' is set" do
- @transaction.ignoreschedules = true
- @transaction.resource_harness.expects(:scheduled?).never
+ @transaction.scheduled?(@resource).should == "feh"
+ end
+ end
- @transaction.should be_scheduled(@resource)
- end
+ describe "when prefetching" do
+ it "should match resources by name, not title" do
+ @catalog = Puppet::Resource::Catalog.new
+ @transaction = Puppet::Transaction.new(@catalog)
- it "should let the resource harness determine whether the resource should be scheduled" do
- @transaction.resource_harness.expects(:scheduled?).with(@transaction.resource_status(@resource), @resource).returns "feh"
+ # Have both a title and name
+ resource = Puppet::Type.type(:sshkey).create :title => "foo", :name => "bar", :type => :dsa, :key => "eh"
+ @catalog.add_resource resource
- @transaction.scheduled?(@resource).should == "feh"
- end
- end
+ resource.provider.class.expects(:prefetch).with("bar" => resource)
- describe "when prefetching" do
- it "should match resources by name, not title" do
- @catalog = Puppet::Resource::Catalog.new
- @transaction = Puppet::Transaction.new(@catalog)
+ @transaction.prefetch
+ end
+ end
+
+ it "should return all resources for which the resource status indicates the resource has changed when determinig changed resources" do
+ @catalog = Puppet::Resource::Catalog.new
+ @transaction = Puppet::Transaction.new(@catalog)
+ names = []
+ 2.times do |i|
+ name = File.join(@basepath, "file#{i}")
+ resource = Puppet::Type.type(:file).new :path => name
+ names << resource.to_s
+ @catalog.add_resource resource
+ @transaction.add_resource_status Puppet::Resource::Status.new(resource)
+ end
- # Have both a title and name
- resource = Puppet::Type.type(:sshkey).create :title => "foo", :name => "bar", :type => :dsa, :key => "eh"
- @catalog.add_resource resource
-
- resource.provider.class.expects(:prefetch).with("bar" => resource)
-
- @transaction.prefetch
- end
- end
-
- it "should return all resources for which the resource status indicates the resource has changed when determinig changed resources" do
- @catalog = Puppet::Resource::Catalog.new
- @transaction = Puppet::Transaction.new(@catalog)
- names = []
- 2.times do |i|
- name = File.join(@basepath, "file#{i}")
- resource = Puppet::Type.type(:file).new :path => name
- names << resource.to_s
- @catalog.add_resource resource
- @transaction.add_resource_status Puppet::Resource::Status.new(resource)
- end
-
- @transaction.resource_status(names[0]).changed = true
-
- @transaction.changed?.should == [@catalog.resource(names[0])]
- end
-
- describe 'when checking application run state' do
- before do
- without_warnings { Puppet::Application = Class.new(Puppet::Application) }
- @catalog = Puppet::Resource::Catalog.new
- @transaction = Puppet::Transaction.new(@catalog)
- end
-
- after do
- without_warnings { Puppet::Application = Puppet::Application.superclass }
- end
-
- it 'should return true for :stop_processing? if Puppet::Application.stop_requested? is true' do
- Puppet::Application.stubs(:stop_requested?).returns(true)
- @transaction.stop_processing?.should be_true
- end
-
- it 'should return false for :stop_processing? if Puppet::Application.stop_requested? is false' do
- Puppet::Application.stubs(:stop_requested?).returns(false)
- @transaction.stop_processing?.should be_false
- end
+ @transaction.resource_status(names[0]).changed = true
- describe 'within an evaluate call' do
- before do
- @resource = stub 'resource', :ref => 'some_ref'
- @catalog.add_resource @resource
- @transaction.stubs(:prepare)
- @transaction.sorted_resources = [@resource]
- end
-
- it 'should stop processing if :stop_processing? is true' do
- @transaction.expects(:stop_processing?).returns(true)
- @transaction.expects(:eval_resource).never
- @transaction.evaluate
- end
-
- it 'should continue processing if :stop_processing? is false' do
- @transaction.expects(:stop_processing?).returns(false)
- @transaction.expects(:eval_resource).returns(nil)
- @transaction.evaluate
- end
- end
- end
-end
+ @transaction.changed?.should == [@catalog.resource(names[0])]
+ end
-describe Puppet::Transaction, " when determining tags" do
+ describe 'when checking application run state' do
before do
- @config = Puppet::Resource::Catalog.new
- @transaction = Puppet::Transaction.new(@config)
+ without_warnings { Puppet::Application = Class.new(Puppet::Application) }
+ @catalog = Puppet::Resource::Catalog.new
+ @transaction = Puppet::Transaction.new(@catalog)
end
- it "should default to the tags specified in the :tags setting" do
- Puppet.expects(:[]).with(:tags).returns("one")
- @transaction.tags.should == %w{one}
+ after do
+ without_warnings { Puppet::Application = Puppet::Application.superclass }
end
- it "should split tags based on ','" do
- Puppet.expects(:[]).with(:tags).returns("one,two")
- @transaction.tags.should == %w{one two}
+ it 'should return true for :stop_processing? if Puppet::Application.stop_requested? is true' do
+ Puppet::Application.stubs(:stop_requested?).returns(true)
+ @transaction.stop_processing?.should be_true
end
- it "should use any tags set after creation" do
- Puppet.expects(:[]).with(:tags).never
- @transaction.tags = %w{one two}
- @transaction.tags.should == %w{one two}
+ it 'should return false for :stop_processing? if Puppet::Application.stop_requested? is false' do
+ Puppet::Application.stubs(:stop_requested?).returns(false)
+ @transaction.stop_processing?.should be_false
end
- it "should always convert assigned tags to an array" do
- @transaction.tags = "one::two"
- @transaction.tags.should == %w{one::two}
- end
-
- it "should accept a comma-delimited string" do
- @transaction.tags = "one, two"
- @transaction.tags.should == %w{one two}
+ describe 'within an evaluate call' do
+ before do
+ @resource = stub 'resource', :ref => 'some_ref'
+ @catalog.add_resource @resource
+ @transaction.stubs(:prepare)
+ @transaction.sorted_resources = [@resource]
+ end
+
+ it 'should stop processing if :stop_processing? is true' do
+ @transaction.expects(:stop_processing?).returns(true)
+ @transaction.expects(:eval_resource).never
+ @transaction.evaluate
+ end
+
+ it 'should continue processing if :stop_processing? is false' do
+ @transaction.expects(:stop_processing?).returns(false)
+ @transaction.expects(:eval_resource).returns(nil)
+ @transaction.evaluate
+ end
end
+ end
+end
- it "should accept an empty string" do
- @transaction.tags = ""
- @transaction.tags.should == []
- end
+describe Puppet::Transaction, " when determining tags" do
+ before do
+ @config = Puppet::Resource::Catalog.new
+ @transaction = Puppet::Transaction.new(@config)
+ end
+
+ it "should default to the tags specified in the :tags setting" do
+ Puppet.expects(:[]).with(:tags).returns("one")
+ @transaction.tags.should == %w{one}
+ end
+
+ it "should split tags based on ','" do
+ Puppet.expects(:[]).with(:tags).returns("one,two")
+ @transaction.tags.should == %w{one two}
+ end
+
+ it "should use any tags set after creation" do
+ Puppet.expects(:[]).with(:tags).never
+ @transaction.tags = %w{one two}
+ @transaction.tags.should == %w{one two}
+ end
+
+ it "should always convert assigned tags to an array" do
+ @transaction.tags = "one::two"
+ @transaction.tags.should == %w{one::two}
+ end
+
+ it "should accept a comma-delimited string" do
+ @transaction.tags = "one, two"
+ @transaction.tags.should == %w{one two}
+ end
+
+ it "should accept an empty string" do
+ @transaction.tags = ""
+ @transaction.tags.should == []
+ end
end
diff --git a/spec/unit/type/augeas_spec.rb b/spec/unit/type/augeas_spec.rb
index ace9410..e426fbe 100644
--- a/spec/unit/type/augeas_spec.rb
+++ b/spec/unit/type/augeas_spec.rb
@@ -5,118 +5,118 @@ require File.dirname(__FILE__) + '/../../spec_helper'
augeas = Puppet::Type.type(:augeas)
describe augeas do
- describe "when augeas is present" do
- confine "Augeas is unavailable" => Puppet.features.augeas?
+ describe "when augeas is present" do
+ confine "Augeas is unavailable" => Puppet.features.augeas?
- it "should have a default provider inheriting from Puppet::Provider" do
- augeas.defaultprovider.ancestors.should be_include(Puppet::Provider)
- end
+ it "should have a default provider inheriting from Puppet::Provider" do
+ augeas.defaultprovider.ancestors.should be_include(Puppet::Provider)
+ end
+
+ it "should have a valid provider" do
+ augeas.new(:name => "foo").provider.class.ancestors.should be_include(Puppet::Provider)
+ end
+ end
- it "should have a valid provider" do
- augeas.new(:name => "foo").provider.class.ancestors.should be_include(Puppet::Provider)
- end
+ describe "basic structure" do
+ it "should be able to create a instance" do
+ provider_class = Puppet::Type::Augeas.provider(Puppet::Type::Augeas.providers[0])
+ Puppet::Type::Augeas.expects(:defaultprovider).returns provider_class
+ augeas.new(:name => "bar").should_not be_nil
end
- describe "basic structure" do
- it "should be able to create a instance" do
- provider_class = Puppet::Type::Augeas.provider(Puppet::Type::Augeas.providers[0])
- Puppet::Type::Augeas.expects(:defaultprovider).returns provider_class
- augeas.new(:name => "bar").should_not be_nil
- end
-
- it "should have an parse_commands feature" do
- augeas.provider_feature(:parse_commands).should_not be_nil
- end
+ it "should have an parse_commands feature" do
+ augeas.provider_feature(:parse_commands).should_not be_nil
+ end
- it "should have an need_to_run? feature" do
- augeas.provider_feature(:need_to_run?).should_not be_nil
- end
+ it "should have an need_to_run? feature" do
+ augeas.provider_feature(:need_to_run?).should_not be_nil
+ end
- it "should have an execute_changes feature" do
- augeas.provider_feature(:execute_changes).should_not be_nil
- end
+ it "should have an execute_changes feature" do
+ augeas.provider_feature(:execute_changes).should_not be_nil
+ end
- properties = [:returns]
- params = [:name, :context, :onlyif, :changes, :root, :load_path, :type_check]
+ properties = [:returns]
+ params = [:name, :context, :onlyif, :changes, :root, :load_path, :type_check]
- properties.each do |property|
- it "should have a #{property} property" do
- augeas.attrclass(property).ancestors.should be_include(Puppet::Property)
- end
+ properties.each do |property|
+ it "should have a #{property} property" do
+ augeas.attrclass(property).ancestors.should be_include(Puppet::Property)
+ end
- it "should have documentation for its #{property} property" do
- augeas.attrclass(property).doc.should be_instance_of(String)
- end
- end
+ it "should have documentation for its #{property} property" do
+ augeas.attrclass(property).doc.should be_instance_of(String)
+ end
+ end
- params.each do |param|
- it "should have a #{param} parameter" do
- augeas.attrclass(param).ancestors.should be_include(Puppet::Parameter)
- end
+ params.each do |param|
+ it "should have a #{param} parameter" do
+ augeas.attrclass(param).ancestors.should be_include(Puppet::Parameter)
+ end
- it "should have documentation for its #{param} parameter" do
- augeas.attrclass(param).doc.should be_instance_of(String)
- end
- end
+ it "should have documentation for its #{param} parameter" do
+ augeas.attrclass(param).doc.should be_instance_of(String)
+ end
end
+ end
- describe "default values" do
- before do
- provider_class = augeas.provider(augeas.providers[0])
- augeas.expects(:defaultprovider).returns provider_class
- end
+ describe "default values" do
+ before do
+ provider_class = augeas.provider(augeas.providers[0])
+ augeas.expects(:defaultprovider).returns provider_class
+ end
- it "should be blank for context" do
- augeas.new(:name => :context)[:context].should == ""
- end
+ it "should be blank for context" do
+ augeas.new(:name => :context)[:context].should == ""
+ end
- it "should be blank for onlyif" do
- augeas.new(:name => :onlyif)[:onlyif].should == ""
- end
+ it "should be blank for onlyif" do
+ augeas.new(:name => :onlyif)[:onlyif].should == ""
+ end
- it "should be blank for load_path" do
- augeas.new(:name => :load_path)[:load_path].should == ""
- end
+ it "should be blank for load_path" do
+ augeas.new(:name => :load_path)[:load_path].should == ""
+ end
- it "should be / for root" do
- augeas.new(:name => :root)[:root].should == "/"
- end
+ it "should be / for root" do
+ augeas.new(:name => :root)[:root].should == "/"
+ end
- it "should be false for type_check" do
- augeas.new(:name => :type_check)[:type_check].should == :false
- end
+ it "should be false for type_check" do
+ augeas.new(:name => :type_check)[:type_check].should == :false
end
+ end
- describe "provider interaction" do
+ describe "provider interaction" do
- it "should return 0 if it does not need to run" do
- provider = stub("provider", :need_to_run? => false)
- resource = stub('resource', :resource => nil, :provider => provider, :line => nil, :file => nil)
- changes = augeas.attrclass(:returns).new(:resource => resource)
- changes.retrieve.should == 0
- end
+ it "should return 0 if it does not need to run" do
+ provider = stub("provider", :need_to_run? => false)
+ resource = stub('resource', :resource => nil, :provider => provider, :line => nil, :file => nil)
+ changes = augeas.attrclass(:returns).new(:resource => resource)
+ changes.retrieve.should == 0
+ end
- it "should return :need_to_run if it needs to run" do
- provider = stub("provider", :need_to_run? => true)
- resource = stub('resource', :resource => nil, :provider => provider, :line => nil, :file => nil)
- changes = augeas.attrclass(:returns).new(:resource => resource)
- changes.retrieve.should == :need_to_run
- end
+ it "should return :need_to_run if it needs to run" do
+ provider = stub("provider", :need_to_run? => true)
+ resource = stub('resource', :resource => nil, :provider => provider, :line => nil, :file => nil)
+ changes = augeas.attrclass(:returns).new(:resource => resource)
+ changes.retrieve.should == :need_to_run
end
+ end
- describe "loading specific files" do
- it "should require lens when incl is used" do
- lambda { augeas.new(:name => :no_lens, :incl => "/etc/hosts")}.should raise_error(Puppet::Error)
- end
+ describe "loading specific files" do
+ it "should require lens when incl is used" do
+ lambda { augeas.new(:name => :no_lens, :incl => "/etc/hosts")}.should raise_error(Puppet::Error)
+ end
- it "should require incl when lens is used" do
- lambda { augeas.new(:name => :no_incl, :lens => "Hosts.lns") }.should raise_error(Puppet::Error)
- end
+ it "should require incl when lens is used" do
+ lambda { augeas.new(:name => :no_incl, :lens => "Hosts.lns") }.should raise_error(Puppet::Error)
+ end
- it "should set the context when a specific file is used" do
- fake_provider = stub_everything "fake_provider"
- augeas.stubs(:defaultprovider).returns fake_provider
- augeas.new(:name => :no_incl, :lens => "Hosts.lns", :incl => "/etc/hosts")[:context].should == "/files/etc/hosts"
- end
+ it "should set the context when a specific file is used" do
+ fake_provider = stub_everything "fake_provider"
+ augeas.stubs(:defaultprovider).returns fake_provider
+ augeas.new(:name => :no_incl, :lens => "Hosts.lns", :incl => "/etc/hosts")[:context].should == "/files/etc/hosts"
end
+ end
end
diff --git a/spec/unit/type/component_spec.rb b/spec/unit/type/component_spec.rb
index ab60e02..f7403e5 100755
--- a/spec/unit/type/component_spec.rb
+++ b/spec/unit/type/component_spec.rb
@@ -5,59 +5,59 @@ require File.dirname(__FILE__) + '/../../spec_helper'
component = Puppet::Type.type(:component)
describe component do
- it "should have a :name attribute" do
- component.attrclass(:name).should_not be_nil
- end
+ it "should have a :name attribute" do
+ component.attrclass(:name).should_not be_nil
+ end
- it "should use Class as its type when a normal string is provided as the title" do
- component.new(:name => "bar").ref.should == "Class[Bar]"
- end
+ it "should use Class as its type when a normal string is provided as the title" do
+ component.new(:name => "bar").ref.should == "Class[Bar]"
+ end
- it "should always produce a resource reference string as its title" do
- component.new(:name => "bar").title.should == "Class[Bar]"
- end
+ it "should always produce a resource reference string as its title" do
+ component.new(:name => "bar").title.should == "Class[Bar]"
+ end
- it "should have a reference string equivalent to its title" do
- comp = component.new(:name => "Foo[bar]")
- comp.title.should == comp.ref
- end
+ it "should have a reference string equivalent to its title" do
+ comp = component.new(:name => "Foo[bar]")
+ comp.title.should == comp.ref
+ end
- it "should alias itself to its reference if it has a catalog and the catalog does not already have a resource with the same reference" do
- catalog = mock 'catalog'
- catalog.expects(:resource).with("Foo[bar]").returns nil
+ it "should alias itself to its reference if it has a catalog and the catalog does not already have a resource with the same reference" do
+ catalog = mock 'catalog'
+ catalog.expects(:resource).with("Foo[bar]").returns nil
- catalog.expects(:alias).with { |resource, name| resource.is_a?(component) and name == "Foo[bar]" }
+ catalog.expects(:alias).with { |resource, name| resource.is_a?(component) and name == "Foo[bar]" }
- component.new(:name => "Foo[bar]", :catalog => catalog)
- end
+ component.new(:name => "Foo[bar]", :catalog => catalog)
+ end
- it "should not fail when provided an invalid value" do
- comp = component.new(:name => "Foo[bar]")
- lambda { comp[:yayness] = "ey" }.should_not raise_error
- end
+ it "should not fail when provided an invalid value" do
+ comp = component.new(:name => "Foo[bar]")
+ lambda { comp[:yayness] = "ey" }.should_not raise_error
+ end
- it "should return previously provided invalid values" do
- comp = component.new(:name => "Foo[bar]")
- comp[:yayness] = "eh"
- comp[:yayness].should == "eh"
- end
+ it "should return previously provided invalid values" do
+ comp = component.new(:name => "Foo[bar]")
+ comp[:yayness] = "eh"
+ comp[:yayness].should == "eh"
+ end
- it "should correctly support metaparameters" do
- comp = component.new(:name => "Foo[bar]", :require => "Foo[bar]")
- comp.parameter(:require).should be_instance_of(component.attrclass(:require))
- end
+ it "should correctly support metaparameters" do
+ comp = component.new(:name => "Foo[bar]", :require => "Foo[bar]")
+ comp.parameter(:require).should be_instance_of(component.attrclass(:require))
+ end
- describe "when building up the path" do
- it "should produce the class name if the component models a class" do
- component.new(:name => "Class[foo]").pathbuilder.must == ["Foo"]
- end
+ describe "when building up the path" do
+ it "should produce the class name if the component models a class" do
+ component.new(:name => "Class[foo]").pathbuilder.must == ["Foo"]
+ end
- it "should produce an empty string if the component models the 'main' class" do
- component.new(:name => "Class[main]").pathbuilder.must == [""]
- end
+ it "should produce an empty string if the component models the 'main' class" do
+ component.new(:name => "Class[main]").pathbuilder.must == [""]
+ end
- it "should produce a resource reference if the component does not model a class" do
- component.new(:name => "Foo[bar]").pathbuilder.must == ["Foo[bar]"]
- end
+ it "should produce a resource reference if the component does not model a class" do
+ component.new(:name => "Foo[bar]").pathbuilder.must == ["Foo[bar]"]
end
+ end
end
diff --git a/spec/unit/type/computer_spec.rb b/spec/unit/type/computer_spec.rb
index b1a6bfe..1f1c55b 100755
--- a/spec/unit/type/computer_spec.rb
+++ b/spec/unit/type/computer_spec.rb
@@ -5,77 +5,77 @@ require File.dirname(__FILE__) + '/../../spec_helper'
computer = Puppet::Type.type(:computer)
describe Puppet::Type.type(:computer), " when checking computer objects" do
- before do
- provider_class = Puppet::Type::Computer.provider(Puppet::Type::Computer.providers[0])
- Puppet::Type::Computer.expects(:defaultprovider).returns provider_class
+ before do
+ provider_class = Puppet::Type::Computer.provider(Puppet::Type::Computer.providers[0])
+ Puppet::Type::Computer.expects(:defaultprovider).returns provider_class
- @resource = Puppet::Type::Computer.new(
+ @resource = Puppet::Type::Computer.new(
- :name => "puppetcomputertest",
- :en_address => "aa:bb:cc:dd:ee:ff",
+ :name => "puppetcomputertest",
+ :en_address => "aa:bb:cc:dd:ee:ff",
- :ip_address => "1.2.3.4")
- @properties = {}
- @ensure = Puppet::Type::Computer.attrclass(:ensure).new(:resource => @resource)
+ :ip_address => "1.2.3.4")
+ @properties = {}
+ @ensure = Puppet::Type::Computer.attrclass(:ensure).new(:resource => @resource)
+ end
+
+ it "should be able to create a instance" do
+ provider_class = Puppet::Type::Computer.provider(Puppet::Type::Computer.providers[0])
+ Puppet::Type::Computer.expects(:defaultprovider).returns provider_class
+ computer.new(:name => "bar").should_not be_nil
+ end
+
+ properties = [:en_address, :ip_address]
+ params = [:name]
+
+ properties.each do |property|
+ it "should have a #{property} property" do
+ computer.attrclass(property).ancestors.should be_include(Puppet::Property)
end
- it "should be able to create a instance" do
- provider_class = Puppet::Type::Computer.provider(Puppet::Type::Computer.providers[0])
- Puppet::Type::Computer.expects(:defaultprovider).returns provider_class
- computer.new(:name => "bar").should_not be_nil
+ it "should have documentation for its #{property} property" do
+ computer.attrclass(property).doc.should be_instance_of(String)
end
- properties = [:en_address, :ip_address]
- params = [:name]
-
- properties.each do |property|
- it "should have a #{property} property" do
- computer.attrclass(property).ancestors.should be_include(Puppet::Property)
- end
-
- it "should have documentation for its #{property} property" do
- computer.attrclass(property).doc.should be_instance_of(String)
- end
-
- it "should accept :absent as a value" do
- prop = computer.attrclass(property).new(:resource => @resource)
- prop.should = :absent
- prop.should.must == :absent
- end
+ it "should accept :absent as a value" do
+ prop = computer.attrclass(property).new(:resource => @resource)
+ prop.should = :absent
+ prop.should.must == :absent
end
+ end
- params.each do |param|
- it "should have a #{param} parameter" do
- computer.attrclass(param).ancestors.should be_include(Puppet::Parameter)
- end
+ params.each do |param|
+ it "should have a #{param} parameter" do
+ computer.attrclass(param).ancestors.should be_include(Puppet::Parameter)
+ end
- it "should have documentation for its #{param} parameter" do
- computer.attrclass(param).doc.should be_instance_of(String)
- end
+ it "should have documentation for its #{param} parameter" do
+ computer.attrclass(param).doc.should be_instance_of(String)
end
+ end
- describe "default values" do
- before do
- provider_class = computer.provider(computer.providers[0])
- computer.expects(:defaultprovider).returns provider_class
- end
+ describe "default values" do
+ before do
+ provider_class = computer.provider(computer.providers[0])
+ computer.expects(:defaultprovider).returns provider_class
+ end
- it "should be nil for en_address" do
- computer.new(:name => :en_address)[:en_address].should == nil
- end
+ it "should be nil for en_address" do
+ computer.new(:name => :en_address)[:en_address].should == nil
+ end
- it "should be nil for ip_address" do
- computer.new(:name => :ip_address)[:ip_address].should == nil
- end
+ it "should be nil for ip_address" do
+ computer.new(:name => :ip_address)[:ip_address].should == nil
end
+ end
- describe "when managing the ensure property" do
- it "should support a :present value" do
- lambda { @ensure.should = :present }.should_not raise_error
- end
+ describe "when managing the ensure property" do
+ it "should support a :present value" do
+ lambda { @ensure.should = :present }.should_not raise_error
+ end
- it "should support an :absent value" do
- lambda { @ensure.should = :absent }.should_not raise_error
- end
+ it "should support an :absent value" do
+ lambda { @ensure.should = :absent }.should_not raise_error
end
+ end
end
diff --git a/spec/unit/type/cron_spec.rb b/spec/unit/type/cron_spec.rb
index 6951077..03817d2 100755
--- a/spec/unit/type/cron_spec.rb
+++ b/spec/unit/type/cron_spec.rb
@@ -3,31 +3,31 @@
Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") }
describe Puppet::Type.type(:cron) do
- before do
- @cron = Puppet::Type.type(:cron).new( :name => "foo" )
- end
+ before do
+ @cron = Puppet::Type.type(:cron).new( :name => "foo" )
+ end
- it "it should accept an :environment that looks like a path" do
- lambda do
- @cron[:environment] = 'PATH=/bin:/usr/bin:/usr/sbin'
- end.should_not raise_error
- end
+ it "it should accept an :environment that looks like a path" do
+ lambda do
+ @cron[:environment] = 'PATH=/bin:/usr/bin:/usr/sbin'
+ end.should_not raise_error
+ end
- it "should not accept environment variables that do not contain '='" do
- lambda do
- @cron[:environment] = "INVALID"
- end.should raise_error(Puppet::Error)
- end
+ it "should not accept environment variables that do not contain '='" do
+ lambda do
+ @cron[:environment] = "INVALID"
+ end.should raise_error(Puppet::Error)
+ end
- it "should accept empty environment variables that do not contain '='" do
- lambda do
- @cron[:environment] = "MAILTO="
- end.should_not raise_error(Puppet::Error)
- end
+ it "should accept empty environment variables that do not contain '='" do
+ lambda do
+ @cron[:environment] = "MAILTO="
+ end.should_not raise_error(Puppet::Error)
+ end
- it "should accept 'absent'" do
- lambda do
- @cron[:environment] = 'absent'
- end.should_not raise_error(Puppet::Error)
- end
+ it "should accept 'absent'" do
+ lambda do
+ @cron[:environment] = 'absent'
+ end.should_not raise_error(Puppet::Error)
+ end
end
diff --git a/spec/unit/type/exec_spec.rb b/spec/unit/type/exec_spec.rb
index 2a3408f..e04cfc0 100755
--- a/spec/unit/type/exec_spec.rb
+++ b/spec/unit/type/exec_spec.rb
@@ -4,159 +4,159 @@ require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::Type.type(:exec) do
- def create_resource(command, output, exitstatus, returns = 0)
- @user_name = 'some_user_name'
- @group_name = 'some_group_name'
- Puppet.features.stubs(:root?).returns(true)
- @execer = Puppet::Type.type(:exec).new(:name => command, :path => @example_path, :user => @user_name, :group => @group_name, :returns => returns)
+ def create_resource(command, output, exitstatus, returns = 0)
+ @user_name = 'some_user_name'
+ @group_name = 'some_group_name'
+ Puppet.features.stubs(:root?).returns(true)
+ @execer = Puppet::Type.type(:exec).new(:name => command, :path => @example_path, :user => @user_name, :group => @group_name, :returns => returns)
+
+ status = stub "process"
+ status.stubs(:exitstatus).returns(exitstatus)
+
+ Puppet::Util::SUIDManager.expects(:run_and_capture).with([command], @user_name, @group_name).returns([output, status])
+ end
+
+ def create_logging_resource(command, output, exitstatus, logoutput, loglevel, returns = 0)
+ create_resource(command, output, exitstatus, returns)
+ @execer[:logoutput] = logoutput
+ @execer[:loglevel] = loglevel
+ end
+
+ def expect_output(output, loglevel)
+ output.split(/\n/).each do |line|
+ @execer.property(:returns).expects(loglevel).with(line)
+ end
+ end
+
+ before do
+ @executable = Puppet.features.posix? ? '/bin/true' : 'C:/Program Files/something.exe'
+ @command = Puppet.features.posix? ? '/bin/true whatever' : '"C:/Program Files/something.exe" whatever'
+ File.stubs(:exists?).returns false
+ File.stubs(:exists?).with(@executable).returns true
+ @example_path = Puppet.features.posix? ? %w{/usr/bin /bin} : [ "C:/Program Files/something/bin", "C:/Ruby/bin" ]
+ File.stubs(:exists?).with(File.join(@example_path[0],"true")).returns true
+ File.stubs(:exists?).with(File.join(@example_path[0],"false")).returns true
+ end
+
+ it "should return :executed_command as its event" do
+ resource = Puppet::Type.type(:exec).new :command => @command
+ resource.parameter(:returns).event.name.should == :executed_command
+ end
+
+ describe "when execing" do
+
+ it "should use the 'run_and_capture' method to exec" do
+ command = "true"
+ create_resource(command, "", 0)
+
+ @execer.refresh.should == :executed_command
+ end
- status = stub "process"
- status.stubs(:exitstatus).returns(exitstatus)
+ it "should report a failure" do
+ command = "false"
+ create_resource(command, "", 1)
- Puppet::Util::SUIDManager.expects(:run_and_capture).with([command], @user_name, @group_name).returns([output, status])
+ proc { @execer.refresh }.should raise_error(Puppet::Error)
end
- def create_logging_resource(command, output, exitstatus, logoutput, loglevel, returns = 0)
- create_resource(command, output, exitstatus, returns)
- @execer[:logoutput] = logoutput
- @execer[:loglevel] = loglevel
+ it "should not report a failure if the exit status is specified in a returns array" do
+ command = "false"
+ create_resource(command, "", 1, [0,1])
+ proc { @execer.refresh }.should_not raise_error(Puppet::Error)
end
- def expect_output(output, loglevel)
- output.split(/\n/).each do |line|
- @execer.property(:returns).expects(loglevel).with(line)
- end
+ it "should report a failure if the exit status is not specified in a returns array" do
+ command = "false"
+ create_resource(command, "", 1, [0,100])
+ proc { @execer.refresh }.should raise_error(Puppet::Error)
end
- before do
- @executable = Puppet.features.posix? ? '/bin/true' : 'C:/Program Files/something.exe'
- @command = Puppet.features.posix? ? '/bin/true whatever' : '"C:/Program Files/something.exe" whatever'
- File.stubs(:exists?).returns false
- File.stubs(:exists?).with(@executable).returns true
- @example_path = Puppet.features.posix? ? %w{/usr/bin /bin} : [ "C:/Program Files/something/bin", "C:/Ruby/bin" ]
- File.stubs(:exists?).with(File.join(@example_path[0],"true")).returns true
- File.stubs(:exists?).with(File.join(@example_path[0],"false")).returns true
+ it "should log the output on success" do
+ #Puppet::Util::Log.newdestination :console
+ command = "false"
+ output = "output1\noutput2\n"
+ create_logging_resource(command, output, 0, true, :err)
+ expect_output(output, :err)
+ @execer.refresh
end
- it "should return :executed_command as its event" do
- resource = Puppet::Type.type(:exec).new :command => @command
- resource.parameter(:returns).event.name.should == :executed_command
+ it "should log the output on failure" do
+ #Puppet::Util::Log.newdestination :console
+ command = "false"
+ output = "output1\noutput2\n"
+ create_logging_resource(command, output, 1, true, :err)
+ expect_output(output, :err)
+
+ proc { @execer.refresh }.should raise_error(Puppet::Error)
end
- describe "when execing" do
-
- it "should use the 'run_and_capture' method to exec" do
- command = "true"
- create_resource(command, "", 0)
-
- @execer.refresh.should == :executed_command
- end
-
- it "should report a failure" do
- command = "false"
- create_resource(command, "", 1)
-
- proc { @execer.refresh }.should raise_error(Puppet::Error)
- end
-
- it "should not report a failure if the exit status is specified in a returns array" do
- command = "false"
- create_resource(command, "", 1, [0,1])
- proc { @execer.refresh }.should_not raise_error(Puppet::Error)
- end
-
- it "should report a failure if the exit status is not specified in a returns array" do
- command = "false"
- create_resource(command, "", 1, [0,100])
- proc { @execer.refresh }.should raise_error(Puppet::Error)
- end
-
- it "should log the output on success" do
- #Puppet::Util::Log.newdestination :console
- command = "false"
- output = "output1\noutput2\n"
- create_logging_resource(command, output, 0, true, :err)
- expect_output(output, :err)
- @execer.refresh
- end
-
- it "should log the output on failure" do
- #Puppet::Util::Log.newdestination :console
- command = "false"
- output = "output1\noutput2\n"
- create_logging_resource(command, output, 1, true, :err)
- expect_output(output, :err)
-
- proc { @execer.refresh }.should raise_error(Puppet::Error)
- end
+ end
- end
+ describe "when logoutput=>on_failure is set" do
- describe "when logoutput=>on_failure is set" do
-
- it "should log the output on failure" do
- #Puppet::Util::Log.newdestination :console
- command = "false"
- output = "output1\noutput2\n"
- create_logging_resource(command, output, 1, :on_failure, :err)
- expect_output(output, :err)
-
- proc { @execer.refresh }.should raise_error(Puppet::Error)
- end
-
- it "should log the output on failure when returns is specified as an array" do
- #Puppet::Util::Log.newdestination :console
- command = "false"
- output = "output1\noutput2\n"
- create_logging_resource(command, output, 1, :on_failure, :err, [0, 100])
- expect_output(output, :err)
-
- proc { @execer.refresh }.should raise_error(Puppet::Error)
- end
-
- it "shouldn't log the output on success" do
- #Puppet::Util::Log.newdestination :console
- command = "true"
- output = "output1\noutput2\n"
- create_logging_resource(command, output, 0, :on_failure, :err)
- @execer.property(:returns).expects(:err).never
- @execer.refresh
- end
- end
+ it "should log the output on failure" do
+ #Puppet::Util::Log.newdestination :console
+ command = "false"
+ output = "output1\noutput2\n"
+ create_logging_resource(command, output, 1, :on_failure, :err)
+ expect_output(output, :err)
- it "shouldn't log the output on success when non-zero exit status is in a returns array" do
- #Puppet::Util::Log.newdestination :console
- command = "true"
- output = "output1\noutput2\n"
- create_logging_resource(command, output, 100, :on_failure, :err, [1,100])
- @execer.property(:returns).expects(:err).never
- @execer.refresh
+ proc { @execer.refresh }.should raise_error(Puppet::Error)
end
- describe " when multiple tries are set," do
-
- it "should repeat the command attempt 'tries' times on failure and produce an error" do
- Puppet.features.stubs(:root?).returns(true)
- command = "false"
- user = "user"
- group = "group"
- tries = 5
- retry_exec = Puppet::Type.type(:exec).new(:name => command, :path => %w{/usr/bin /bin}, :user => user, :group => group, :returns => 0, :tries => tries, :try_sleep => 0)
- status = stub "process"
- status.stubs(:exitstatus).returns(1)
- Puppet::Util::SUIDManager.expects(:run_and_capture).with([command], user, group).times(tries).returns(["", status])
- proc { retry_exec.refresh }.should raise_error(Puppet::Error)
- end
- end
+ it "should log the output on failure when returns is specified as an array" do
+ #Puppet::Util::Log.newdestination :console
+ command = "false"
+ output = "output1\noutput2\n"
+ create_logging_resource(command, output, 1, :on_failure, :err, [0, 100])
+ expect_output(output, :err)
- it "should be able to autorequire files mentioned in the command" do
- catalog = Puppet::Resource::Catalog.new
- catalog.add_resource Puppet::Type.type(:file).new(:name => @executable)
- @execer = Puppet::Type.type(:exec).new(:name => @command)
- catalog.add_resource @execer
+ proc { @execer.refresh }.should raise_error(Puppet::Error)
+ end
- rels = @execer.autorequire
- rels[0].should be_instance_of(Puppet::Relationship)
- rels[0].target.should equal(@execer)
+ it "shouldn't log the output on success" do
+ #Puppet::Util::Log.newdestination :console
+ command = "true"
+ output = "output1\noutput2\n"
+ create_logging_resource(command, output, 0, :on_failure, :err)
+ @execer.property(:returns).expects(:err).never
+ @execer.refresh
+ end
+ end
+
+ it "shouldn't log the output on success when non-zero exit status is in a returns array" do
+ #Puppet::Util::Log.newdestination :console
+ command = "true"
+ output = "output1\noutput2\n"
+ create_logging_resource(command, output, 100, :on_failure, :err, [1,100])
+ @execer.property(:returns).expects(:err).never
+ @execer.refresh
+ end
+
+ describe " when multiple tries are set," do
+
+ it "should repeat the command attempt 'tries' times on failure and produce an error" do
+ Puppet.features.stubs(:root?).returns(true)
+ command = "false"
+ user = "user"
+ group = "group"
+ tries = 5
+ retry_exec = Puppet::Type.type(:exec).new(:name => command, :path => %w{/usr/bin /bin}, :user => user, :group => group, :returns => 0, :tries => tries, :try_sleep => 0)
+ status = stub "process"
+ status.stubs(:exitstatus).returns(1)
+ Puppet::Util::SUIDManager.expects(:run_and_capture).with([command], user, group).times(tries).returns(["", status])
+ proc { retry_exec.refresh }.should raise_error(Puppet::Error)
end
+ end
+
+ it "should be able to autorequire files mentioned in the command" do
+ catalog = Puppet::Resource::Catalog.new
+ catalog.add_resource Puppet::Type.type(:file).new(:name => @executable)
+ @execer = Puppet::Type.type(:exec).new(:name => @command)
+ catalog.add_resource @execer
+
+ rels = @execer.autorequire
+ rels[0].should be_instance_of(Puppet::Relationship)
+ rels[0].target.should equal(@execer)
+ end
end
diff --git a/spec/unit/type/file/checksum_spec.rb b/spec/unit/type/file/checksum_spec.rb
index e6a8530..8b9138b 100644
--- a/spec/unit/type/file/checksum_spec.rb
+++ b/spec/unit/type/file/checksum_spec.rb
@@ -4,70 +4,70 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
checksum = Puppet::Type.type(:file).attrclass(:checksum)
describe checksum do
- before do
- @resource = Puppet::Type.type(:file).new :path => "/foo/bar"
- @checksum = @resource.parameter(:checksum)
- end
+ before do
+ @resource = Puppet::Type.type(:file).new :path => "/foo/bar"
+ @checksum = @resource.parameter(:checksum)
+ end
- it "should be a parameter" do
- checksum.superclass.must == Puppet::Parameter
- end
+ it "should be a parameter" do
+ checksum.superclass.must == Puppet::Parameter
+ end
- it "should use its current value when asked to sum content" do
- @checksum.value = :md5lite
- @checksum.expects(:md5lite).with("foobar").returns "yay"
- @checksum.sum("foobar")
- end
+ it "should use its current value when asked to sum content" do
+ @checksum.value = :md5lite
+ @checksum.expects(:md5lite).with("foobar").returns "yay"
+ @checksum.sum("foobar")
+ end
- it "should use :md5 to sum when no value is set" do
- @checksum.expects(:md5).with("foobar").returns "yay"
- @checksum.sum("foobar")
- end
+ it "should use :md5 to sum when no value is set" do
+ @checksum.expects(:md5).with("foobar").returns "yay"
+ @checksum.sum("foobar")
+ end
- it "should return the summed contents with a checksum label" do
- sum = Digest::MD5.hexdigest("foobar")
- @resource[:checksum] = :md5
- @checksum.sum("foobar").should == "{md5}#{sum}"
- end
+ it "should return the summed contents with a checksum label" do
+ sum = Digest::MD5.hexdigest("foobar")
+ @resource[:checksum] = :md5
+ @checksum.sum("foobar").should == "{md5}#{sum}"
+ end
- it "should use :md5 as its default type" do
- @checksum.default.should == :md5
- end
+ it "should use :md5 as its default type" do
+ @checksum.default.should == :md5
+ end
- it "should use its current value when asked to sum a file's content" do
- @checksum.value = :md5lite
- @checksum.expects(:md5lite_file).with("/foo/bar").returns "yay"
- @checksum.sum_file("/foo/bar")
- end
+ it "should use its current value when asked to sum a file's content" do
+ @checksum.value = :md5lite
+ @checksum.expects(:md5lite_file).with("/foo/bar").returns "yay"
+ @checksum.sum_file("/foo/bar")
+ end
- it "should use :md5 to sum a file when no value is set" do
- @checksum.expects(:md5_file).with("/foo/bar").returns "yay"
- @checksum.sum_file("/foo/bar")
- end
+ it "should use :md5 to sum a file when no value is set" do
+ @checksum.expects(:md5_file).with("/foo/bar").returns "yay"
+ @checksum.sum_file("/foo/bar")
+ end
- it "should convert all sums to strings when summing files" do
- @checksum.value = :mtime
- @checksum.expects(:mtime_file).with("/foo/bar").returns Time.now
- lambda { @checksum.sum_file("/foo/bar") }.should_not raise_error
- end
+ it "should convert all sums to strings when summing files" do
+ @checksum.value = :mtime
+ @checksum.expects(:mtime_file).with("/foo/bar").returns Time.now
+ lambda { @checksum.sum_file("/foo/bar") }.should_not raise_error
+ end
- it "should return the summed contents of a file with a checksum label" do
- @resource[:checksum] = :md5
- @checksum.expects(:md5_file).returns "mysum"
- @checksum.sum_file("/foo/bar").should == "{md5}mysum"
- end
+ it "should return the summed contents of a file with a checksum label" do
+ @resource[:checksum] = :md5
+ @checksum.expects(:md5_file).returns "mysum"
+ @checksum.sum_file("/foo/bar").should == "{md5}mysum"
+ end
- it "should return the summed contents of a stream with a checksum label" do
- @resource[:checksum] = :md5
- @checksum.expects(:md5_stream).returns "mysum"
- @checksum.sum_stream.should == "{md5}mysum"
- end
+ it "should return the summed contents of a stream with a checksum label" do
+ @resource[:checksum] = :md5
+ @checksum.expects(:md5_stream).returns "mysum"
+ @checksum.sum_stream.should == "{md5}mysum"
+ end
- it "should yield the sum_stream block to the underlying checksum" do
- @resource[:checksum] = :md5
- @checksum.expects(:md5_stream).yields("something").returns("mysum")
- @checksum.sum_stream do |sum|
- sum.should == "something"
- end
+ it "should yield the sum_stream block to the underlying checksum" do
+ @resource[:checksum] = :md5
+ @checksum.expects(:md5_stream).yields("something").returns("mysum")
+ @checksum.sum_stream do |sum|
+ sum.should == "something"
end
+ end
end
diff --git a/spec/unit/type/file/content_spec.rb b/spec/unit/type/file/content_spec.rb
index 295f212..e4b9f9b 100755
--- a/spec/unit/type/file/content_spec.rb
+++ b/spec/unit/type/file/content_spec.rb
@@ -4,457 +4,457 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
content = Puppet::Type.type(:file).attrclass(:content)
describe content do
- before do
- @resource = Puppet::Type.type(:file).new :path => "/foo/bar"
+ before do
+ @resource = Puppet::Type.type(:file).new :path => "/foo/bar"
+ end
+
+ it "should be a subclass of Property" do
+ content.superclass.must == Puppet::Property
+ end
+
+ describe "when determining the checksum type" do
+ it "should use the type specified in the source checksum if a source is set" do
+ @resource[:source] = "/foo"
+ @resource.parameter(:source).expects(:checksum).returns "{md5lite}eh"
+
+ @content = content.new(:resource => @resource)
+ @content.checksum_type.should == :md5lite
end
- it "should be a subclass of Property" do
- content.superclass.must == Puppet::Property
+ it "should use the type specified by the checksum parameter if no source is set" do
+ @resource[:checksum] = :md5lite
+
+ @content = content.new(:resource => @resource)
+ @content.checksum_type.should == :md5lite
end
+ end
- describe "when determining the checksum type" do
- it "should use the type specified in the source checksum if a source is set" do
- @resource[:source] = "/foo"
- @resource.parameter(:source).expects(:checksum).returns "{md5lite}eh"
+ describe "when determining the actual content to write" do
+ it "should use the set content if available" do
+ @content = content.new(:resource => @resource)
+ @content.should = "ehness"
+ @content.actual_content.should == "ehness"
+ end
- @content = content.new(:resource => @resource)
- @content.checksum_type.should == :md5lite
- end
+ it "should not use the content from the source if the source is set" do
+ source = mock 'source'
- it "should use the type specified by the checksum parameter if no source is set" do
- @resource[:checksum] = :md5lite
+ @resource.expects(:parameter).never.with(:source).returns source
- @content = content.new(:resource => @resource)
- @content.checksum_type.should == :md5lite
- end
+ @content = content.new(:resource => @resource)
+ @content.actual_content.should be_nil
end
+ end
- describe "when determining the actual content to write" do
- it "should use the set content if available" do
- @content = content.new(:resource => @resource)
- @content.should = "ehness"
- @content.actual_content.should == "ehness"
- end
+ describe "when setting the desired content" do
+ it "should make the actual content available via an attribute" do
+ @content = content.new(:resource => @resource)
+ @content.stubs(:checksum_type).returns "md5"
+ @content.should = "this is some content"
+
+ @content.actual_content.should == "this is some content"
+ end
- it "should not use the content from the source if the source is set" do
- source = mock 'source'
+ it "should store the checksum as the desired content" do
+ @content = content.new(:resource => @resource)
+ digest = Digest::MD5.hexdigest("this is some content")
- @resource.expects(:parameter).never.with(:source).returns source
+ @content.stubs(:checksum_type).returns "md5"
+ @content.should = "this is some content"
- @content = content.new(:resource => @resource)
- @content.actual_content.should be_nil
- end
+ @content.should.must == "{md5}#{digest}"
end
- describe "when setting the desired content" do
- it "should make the actual content available via an attribute" do
- @content = content.new(:resource => @resource)
- @content.stubs(:checksum_type).returns "md5"
- @content.should = "this is some content"
+ it "should not checksum 'absent'" do
+ @content = content.new(:resource => @resource)
+ @content.should = :absent
- @content.actual_content.should == "this is some content"
- end
+ @content.should.must == :absent
+ end
- it "should store the checksum as the desired content" do
- @content = content.new(:resource => @resource)
- digest = Digest::MD5.hexdigest("this is some content")
+ it "should accept a checksum as the desired content" do
+ @content = content.new(:resource => @resource)
+ digest = Digest::MD5.hexdigest("this is some content")
- @content.stubs(:checksum_type).returns "md5"
- @content.should = "this is some content"
+ string = "{md5}#{digest}"
+ @content.should = string
- @content.should.must == "{md5}#{digest}"
- end
+ @content.should.must == string
+ end
+ end
- it "should not checksum 'absent'" do
- @content = content.new(:resource => @resource)
- @content.should = :absent
+ describe "when retrieving the current content" do
+ it "should return :absent if the file does not exist" do
+ @content = content.new(:resource => @resource)
+ @resource.expects(:stat).returns nil
- @content.should.must == :absent
- end
+ @content.retrieve.should == :absent
+ end
- it "should accept a checksum as the desired content" do
- @content = content.new(:resource => @resource)
- digest = Digest::MD5.hexdigest("this is some content")
+ it "should not manage content on directories" do
+ @content = content.new(:resource => @resource)
- string = "{md5}#{digest}"
- @content.should = string
+ stat = mock 'stat', :ftype => "directory"
+ @resource.expects(:stat).returns stat
- @content.should.must == string
- end
+ @content.retrieve.should be_nil
end
- describe "when retrieving the current content" do
- it "should return :absent if the file does not exist" do
- @content = content.new(:resource => @resource)
- @resource.expects(:stat).returns nil
+ it "should not manage content on links" do
+ @content = content.new(:resource => @resource)
- @content.retrieve.should == :absent
- end
+ stat = mock 'stat', :ftype => "link"
+ @resource.expects(:stat).returns stat
- it "should not manage content on directories" do
- @content = content.new(:resource => @resource)
+ @content.retrieve.should be_nil
+ end
- stat = mock 'stat', :ftype => "directory"
- @resource.expects(:stat).returns stat
+ it "should always return the checksum as a string" do
+ @content = content.new(:resource => @resource)
+ @resource[:checksum] = :mtime
- @content.retrieve.should be_nil
- end
+ stat = mock 'stat', :ftype => "file"
+ @resource.expects(:stat).returns stat
- it "should not manage content on links" do
- @content = content.new(:resource => @resource)
+ time = Time.now
+ @resource.parameter(:checksum).expects(:mtime_file).with(@resource[:path]).returns time
- stat = mock 'stat', :ftype => "link"
- @resource.expects(:stat).returns stat
+ @content.retrieve.should == "{mtime}#{time}"
+ end
- @content.retrieve.should be_nil
- end
+ it "should return the checksum of the file if it exists and is a normal file" do
+ @content = content.new(:resource => @resource)
+ stat = mock 'stat', :ftype => "file"
+ @resource.expects(:stat).returns stat
+ @resource.parameter(:checksum).expects(:md5_file).with(@resource[:path]).returns "mysum"
- it "should always return the checksum as a string" do
- @content = content.new(:resource => @resource)
- @resource[:checksum] = :mtime
+ @content.retrieve.should == "{md5}mysum"
+ end
+ end
- stat = mock 'stat', :ftype => "file"
- @resource.expects(:stat).returns stat
+ describe "when testing whether the content is in sync" do
+ before do
+ @resource[:ensure] = :file
+ @content = content.new(:resource => @resource)
+ end
- time = Time.now
- @resource.parameter(:checksum).expects(:mtime_file).with(@resource[:path]).returns time
+ it "should return true if the resource shouldn't be a regular file" do
+ @resource.expects(:should_be_file?).returns false
+ @content.must be_insync("whatever")
+ end
- @content.retrieve.should == "{mtime}#{time}"
- end
+ it "should return false if the current content is :absent" do
+ @content.should_not be_insync(:absent)
+ end
- it "should return the checksum of the file if it exists and is a normal file" do
- @content = content.new(:resource => @resource)
- stat = mock 'stat', :ftype => "file"
- @resource.expects(:stat).returns stat
- @resource.parameter(:checksum).expects(:md5_file).with(@resource[:path]).returns "mysum"
+ it "should return false if the file should be a file but is not present" do
+ @resource.expects(:should_be_file?).returns true
- @content.retrieve.should == "{md5}mysum"
- end
+ @content.should_not be_insync(:absent)
end
- describe "when testing whether the content is in sync" do
- before do
- @resource[:ensure] = :file
- @content = content.new(:resource => @resource)
- end
+ describe "and the file exists" do
+ before do
+ @resource.stubs(:stat).returns mock("stat")
+ end
- it "should return true if the resource shouldn't be a regular file" do
- @resource.expects(:should_be_file?).returns false
- @content.must be_insync("whatever")
- end
+ it "should return false if the current contents are different from the desired content" do
+ @content.should = "some content"
+ @content.should_not be_insync("other content")
+ end
- it "should return false if the current content is :absent" do
- @content.should_not be_insync(:absent)
+ it "should return true if the sum for the current contents is the same as the sum for the desired content" do
+ @content.should = "some content"
+ @content.must be_insync("{md5}" + Digest::MD5.hexdigest("some content"))
+ end
+
+ describe "and Puppet[:show_diff] is set" do
+ before do
+ Puppet[:show_diff] = true
end
- it "should return false if the file should be a file but is not present" do
- @resource.expects(:should_be_file?).returns true
+ it "should display a diff if the current contents are different from the desired content" do
+ @content.should = "some content"
+ @content.expects(:diff).returns("my diff").once
+ @content.expects(:print).with("my diff").once
- @content.should_not be_insync(:absent)
+ @content.insync?("other content")
end
- describe "and the file exists" do
- before do
- @resource.stubs(:stat).returns mock("stat")
- end
-
- it "should return false if the current contents are different from the desired content" do
- @content.should = "some content"
- @content.should_not be_insync("other content")
- end
-
- it "should return true if the sum for the current contents is the same as the sum for the desired content" do
- @content.should = "some content"
- @content.must be_insync("{md5}" + Digest::MD5.hexdigest("some content"))
- end
-
- describe "and Puppet[:show_diff] is set" do
- before do
- Puppet[:show_diff] = true
- end
-
- it "should display a diff if the current contents are different from the desired content" do
- @content.should = "some content"
- @content.expects(:diff).returns("my diff").once
- @content.expects(:print).with("my diff").once
-
- @content.insync?("other content")
- end
-
- it "should not display a diff if the sum for the current contents is the same as the sum for the desired content" do
- @content.should = "some content"
- @content.expects(:diff).never
-
- @content.insync?("{md5}" + Digest::MD5.hexdigest("some content"))
- end
- end
+ it "should not display a diff if the sum for the current contents is the same as the sum for the desired content" do
+ @content.should = "some content"
+ @content.expects(:diff).never
+
+ @content.insync?("{md5}" + Digest::MD5.hexdigest("some content"))
end
+ end
+ end
- describe "and :replace is false" do
- before do
- @resource.stubs(:replace?).returns false
- end
+ describe "and :replace is false" do
+ before do
+ @resource.stubs(:replace?).returns false
+ end
- it "should be insync if the file exists and the content is different" do
- @resource.stubs(:stat).returns mock('stat')
+ it "should be insync if the file exists and the content is different" do
+ @resource.stubs(:stat).returns mock('stat')
- @content.must be_insync("whatever")
- end
+ @content.must be_insync("whatever")
+ end
- it "should be insync if the file exists and the content is right" do
- @resource.stubs(:stat).returns mock('stat')
+ it "should be insync if the file exists and the content is right" do
+ @resource.stubs(:stat).returns mock('stat')
- @content.must be_insync("something")
- end
+ @content.must be_insync("something")
+ end
- it "should not be insync if the file does not exist" do
- @content.should_not be_insync(:absent)
- end
- end
+ it "should not be insync if the file does not exist" do
+ @content.should_not be_insync(:absent)
+ end
end
+ end
- describe "when changing the content" do
- before do
- @content = content.new(:resource => @resource)
- @content.should = "some content"
+ describe "when changing the content" do
+ before do
+ @content = content.new(:resource => @resource)
+ @content.should = "some content"
- @resource.stubs(:[]).with(:path).returns "/boo"
- @resource.stubs(:stat).returns "eh"
- end
+ @resource.stubs(:[]).with(:path).returns "/boo"
+ @resource.stubs(:stat).returns "eh"
+ end
- it "should use the file's :write method to write the content" do
- @resource.expects(:write).with(:content)
+ it "should use the file's :write method to write the content" do
+ @resource.expects(:write).with(:content)
- @content.sync
- end
+ @content.sync
+ end
- it "should return :file_changed if the file already existed" do
- @resource.expects(:stat).returns "something"
- @resource.stubs(:write)
- @content.sync.should == :file_changed
- end
+ it "should return :file_changed if the file already existed" do
+ @resource.expects(:stat).returns "something"
+ @resource.stubs(:write)
+ @content.sync.should == :file_changed
+ end
- it "should return :file_created if the file did not exist" do
- @resource.expects(:stat).returns nil
- @resource.stubs(:write)
- @content.sync.should == :file_created
- end
+ it "should return :file_created if the file did not exist" do
+ @resource.expects(:stat).returns nil
+ @resource.stubs(:write)
+ @content.sync.should == :file_created
end
+ end
- describe "when writing" do
- before do
- @content = content.new(:resource => @resource)
- @fh = stub_everything
- end
+ describe "when writing" do
+ before do
+ @content = content.new(:resource => @resource)
+ @fh = stub_everything
+ end
- it "should attempt to read from the filebucket if no actual content nor source exists" do
- @content.should = "{md5}foo"
- @content.resource.bucket.class.any_instance.stubs(:getfile).returns "foo"
- @content.write(@fh)
- end
+ it "should attempt to read from the filebucket if no actual content nor source exists" do
+ @content.should = "{md5}foo"
+ @content.resource.bucket.class.any_instance.stubs(:getfile).returns "foo"
+ @content.write(@fh)
+ end
- describe "from actual content" do
- before(:each) do
- @content.stubs(:actual_content).returns("this is content")
- end
+ describe "from actual content" do
+ before(:each) do
+ @content.stubs(:actual_content).returns("this is content")
+ end
- it "should write to the given file handle" do
- @fh.expects(:print).with("this is content")
- @content.write(@fh)
- end
+ it "should write to the given file handle" do
+ @fh.expects(:print).with("this is content")
+ @content.write(@fh)
+ end
- it "should return the current checksum value" do
- @resource.parameter(:checksum).expects(:sum_stream).returns "checksum"
- @content.write(@fh).should == "checksum"
- end
- end
+ it "should return the current checksum value" do
+ @resource.parameter(:checksum).expects(:sum_stream).returns "checksum"
+ @content.write(@fh).should == "checksum"
+ end
+ end
- describe "from a file bucket" do
- it "should fail if a file bucket cannot be retrieved" do
- @content.should = "{md5}foo"
- @content.resource.expects(:bucket).returns nil
- lambda { @content.write(@fh) }.should raise_error(Puppet::Error)
- end
-
- it "should fail if the file bucket cannot find any content" do
- @content.should = "{md5}foo"
- bucket = stub 'bucket'
- @content.resource.expects(:bucket).returns bucket
- bucket.expects(:getfile).with("foo").raises "foobar"
- lambda { @content.write(@fh) }.should raise_error(Puppet::Error)
- end
-
- it "should write the returned content to the file" do
- @content.should = "{md5}foo"
- bucket = stub 'bucket'
- @content.resource.expects(:bucket).returns bucket
- bucket.expects(:getfile).with("foo").returns "mycontent"
-
- @fh.expects(:print).with("mycontent")
- @content.write(@fh)
- end
- end
+ describe "from a file bucket" do
+ it "should fail if a file bucket cannot be retrieved" do
+ @content.should = "{md5}foo"
+ @content.resource.expects(:bucket).returns nil
+ lambda { @content.write(@fh) }.should raise_error(Puppet::Error)
+ end
+
+ it "should fail if the file bucket cannot find any content" do
+ @content.should = "{md5}foo"
+ bucket = stub 'bucket'
+ @content.resource.expects(:bucket).returns bucket
+ bucket.expects(:getfile).with("foo").raises "foobar"
+ lambda { @content.write(@fh) }.should raise_error(Puppet::Error)
+ end
+
+ it "should write the returned content to the file" do
+ @content.should = "{md5}foo"
+ bucket = stub 'bucket'
+ @content.resource.expects(:bucket).returns bucket
+ bucket.expects(:getfile).with("foo").returns "mycontent"
+
+ @fh.expects(:print).with("mycontent")
+ @content.write(@fh)
+ end
+ end
- describe "from local source" do
- before(:each) do
- @content.stubs(:actual_content).returns(nil)
- @source = stub_everything 'source', :local? => true, :full_path => "/path/to/source"
- @resource.stubs(:parameter).with(:source).returns @source
-
- @sum = stub_everything 'sum'
- @resource.stubs(:parameter).with(:checksum).returns(@sum)
-
- @digest = stub_everything 'digest'
- @sum.stubs(:sum_stream).yields(@digest)
-
- @file = stub_everything 'file'
- File.stubs(:open).yields(@file)
- @file.stubs(:read).with(8192).returns("chunk1").then.returns("chunk2").then.returns(nil)
- end
-
- it "should open the local file" do
- File.expects(:open).with("/path/to/source", "r")
- @content.write(@fh)
- end
-
- it "should read the local file by chunks" do
- @file.expects(:read).with(8192).returns("chunk1").then.returns(nil)
- @content.write(@fh)
- end
-
- it "should write each chunk to the file" do
- @fh.expects(:print).with("chunk1").then.with("chunk2")
- @content.write(@fh)
- end
-
- it "should pass each chunk to the current sum stream" do
- @digest.expects(:<<).with("chunk1").then.with("chunk2")
- @content.write(@fh)
- end
-
- it "should return the checksum computed" do
- @sum.stubs(:sum_stream).yields(@digest).returns("checksum")
- @content.write(@fh).should == "checksum"
- end
- end
+ describe "from local source" do
+ before(:each) do
+ @content.stubs(:actual_content).returns(nil)
+ @source = stub_everything 'source', :local? => true, :full_path => "/path/to/source"
+ @resource.stubs(:parameter).with(:source).returns @source
+
+ @sum = stub_everything 'sum'
+ @resource.stubs(:parameter).with(:checksum).returns(@sum)
+
+ @digest = stub_everything 'digest'
+ @sum.stubs(:sum_stream).yields(@digest)
+
+ @file = stub_everything 'file'
+ File.stubs(:open).yields(@file)
+ @file.stubs(:read).with(8192).returns("chunk1").then.returns("chunk2").then.returns(nil)
+ end
+
+ it "should open the local file" do
+ File.expects(:open).with("/path/to/source", "r")
+ @content.write(@fh)
+ end
+
+ it "should read the local file by chunks" do
+ @file.expects(:read).with(8192).returns("chunk1").then.returns(nil)
+ @content.write(@fh)
+ end
+
+ it "should write each chunk to the file" do
+ @fh.expects(:print).with("chunk1").then.with("chunk2")
+ @content.write(@fh)
+ end
+
+ it "should pass each chunk to the current sum stream" do
+ @digest.expects(:<<).with("chunk1").then.with("chunk2")
+ @content.write(@fh)
+ end
+
+ it "should return the checksum computed" do
+ @sum.stubs(:sum_stream).yields(@digest).returns("checksum")
+ @content.write(@fh).should == "checksum"
+ end
+ end
- describe "from remote source" do
- before(:each) do
- @response = stub_everything 'mock response', :code => "404"
- @conn = stub_everything 'connection'
- @conn.stubs(:request_get).yields(@response)
- Puppet::Network::HttpPool.stubs(:http_instance).returns @conn
-
- @content.stubs(:actual_content).returns(nil)
- @source = stub_everything 'source', :local? => false, :full_path => "/path/to/source", :server => "server", :port => 1234
- @resource.stubs(:parameter).with(:source).returns @source
-
- @sum = stub_everything 'sum'
- @resource.stubs(:parameter).with(:checksum).returns(@sum)
-
- @digest = stub_everything 'digest'
- @sum.stubs(:sum_stream).yields(@digest)
- end
-
- it "should open a network connection to source server and port" do
- Puppet::Network::HttpPool.expects(:http_instance).with("server", 1234).returns @conn
- @content.write(@fh)
- end
-
- it "should send the correct indirection uri" do
- @conn.expects(:request_get).with { |uri,headers| uri == "/production/file_content//path/to/source" }.yields(@response)
- @content.write(@fh)
- end
-
- it "should return nil if source is not found" do
- @response.expects(:code).returns("404")
- @content.write(@fh).should == nil
- end
-
- it "should not write anything if source is not found" do
- @response.expects(:code).returns("404")
- @fh.expects(:print).never
- @content.write(@fh).should == nil
- end
-
- it "should raise an HTTP error in case of server error" do
- @response.expects(:code).returns("500")
- lambda { @content.write(@fh) }.should raise_error
- end
-
- it "should write content by chunks" do
- @response.expects(:code).returns("200")
- @response.expects(:read_body).multiple_yields("chunk1","chunk2")
- @fh.expects(:print).with("chunk1").then.with("chunk2")
- @content.write(@fh)
- end
-
- it "should pass each chunk to the current sum stream" do
- @response.expects(:code).returns("200")
- @response.expects(:read_body).multiple_yields("chunk1","chunk2")
- @digest.expects(:<<).with("chunk1").then.with("chunk2")
- @content.write(@fh)
- end
-
- it "should return the checksum computed" do
- @response.expects(:code).returns("200")
- @response.expects(:read_body).multiple_yields("chunk1","chunk2")
- @sum.expects(:sum_stream).yields(@digest).returns("checksum")
- @content.write(@fh).should == "checksum"
- end
-
- it "should get the current accept encoding header value" do
- @content.expects(:add_accept_encoding)
- @content.write(@fh)
- end
-
- it "should uncompress body on error" do
- @response.expects(:code).returns("500")
- @response.expects(:body).returns("compressed body")
- @content.expects(:uncompress_body).with(@response).returns("uncompressed")
- lambda { @content.write(@fh) }.should raise_error { |e| e.message =~ /uncompressed/ }
- end
-
- it "should uncompress chunk by chunk" do
- uncompressor = stub_everything 'uncompressor'
- @content.expects(:uncompress).with(@response).yields(uncompressor)
- @response.expects(:code).returns("200")
- @response.expects(:read_body).multiple_yields("chunk1","chunk2")
-
- uncompressor.expects(:uncompress).with("chunk1").then.with("chunk2")
- @content.write(@fh)
- end
-
- it "should write uncompressed chunks to the file" do
- uncompressor = stub_everything 'uncompressor'
- @content.expects(:uncompress).with(@response).yields(uncompressor)
- @response.expects(:code).returns("200")
- @response.expects(:read_body).multiple_yields("chunk1","chunk2")
-
- uncompressor.expects(:uncompress).with("chunk1").returns("uncompressed1")
- uncompressor.expects(:uncompress).with("chunk2").returns("uncompressed2")
-
- @fh.expects(:print).with("uncompressed1")
- @fh.expects(:print).with("uncompressed2")
-
- @content.write(@fh)
- end
-
- it "should pass each uncompressed chunk to the current sum stream" do
- uncompressor = stub_everything 'uncompressor'
- @content.expects(:uncompress).with(@response).yields(uncompressor)
- @response.expects(:code).returns("200")
- @response.expects(:read_body).multiple_yields("chunk1","chunk2")
-
- uncompressor.expects(:uncompress).with("chunk1").returns("uncompressed1")
- uncompressor.expects(:uncompress).with("chunk2").returns("uncompressed2")
-
- @digest.expects(:<<).with("uncompressed1").then.with("uncompressed2")
- @content.write(@fh)
- end
- end
+ describe "from remote source" do
+ before(:each) do
+ @response = stub_everything 'mock response', :code => "404"
+ @conn = stub_everything 'connection'
+ @conn.stubs(:request_get).yields(@response)
+ Puppet::Network::HttpPool.stubs(:http_instance).returns @conn
+
+ @content.stubs(:actual_content).returns(nil)
+ @source = stub_everything 'source', :local? => false, :full_path => "/path/to/source", :server => "server", :port => 1234
+ @resource.stubs(:parameter).with(:source).returns @source
+
+ @sum = stub_everything 'sum'
+ @resource.stubs(:parameter).with(:checksum).returns(@sum)
+
+ @digest = stub_everything 'digest'
+ @sum.stubs(:sum_stream).yields(@digest)
+ end
+
+ it "should open a network connection to source server and port" do
+ Puppet::Network::HttpPool.expects(:http_instance).with("server", 1234).returns @conn
+ @content.write(@fh)
+ end
+
+ it "should send the correct indirection uri" do
+ @conn.expects(:request_get).with { |uri,headers| uri == "/production/file_content//path/to/source" }.yields(@response)
+ @content.write(@fh)
+ end
+
+ it "should return nil if source is not found" do
+ @response.expects(:code).returns("404")
+ @content.write(@fh).should == nil
+ end
+
+ it "should not write anything if source is not found" do
+ @response.expects(:code).returns("404")
+ @fh.expects(:print).never
+ @content.write(@fh).should == nil
+ end
+
+ it "should raise an HTTP error in case of server error" do
+ @response.expects(:code).returns("500")
+ lambda { @content.write(@fh) }.should raise_error
+ end
+
+ it "should write content by chunks" do
+ @response.expects(:code).returns("200")
+ @response.expects(:read_body).multiple_yields("chunk1","chunk2")
+ @fh.expects(:print).with("chunk1").then.with("chunk2")
+ @content.write(@fh)
+ end
+
+ it "should pass each chunk to the current sum stream" do
+ @response.expects(:code).returns("200")
+ @response.expects(:read_body).multiple_yields("chunk1","chunk2")
+ @digest.expects(:<<).with("chunk1").then.with("chunk2")
+ @content.write(@fh)
+ end
+
+ it "should return the checksum computed" do
+ @response.expects(:code).returns("200")
+ @response.expects(:read_body).multiple_yields("chunk1","chunk2")
+ @sum.expects(:sum_stream).yields(@digest).returns("checksum")
+ @content.write(@fh).should == "checksum"
+ end
+
+ it "should get the current accept encoding header value" do
+ @content.expects(:add_accept_encoding)
+ @content.write(@fh)
+ end
+
+ it "should uncompress body on error" do
+ @response.expects(:code).returns("500")
+ @response.expects(:body).returns("compressed body")
+ @content.expects(:uncompress_body).with(@response).returns("uncompressed")
+ lambda { @content.write(@fh) }.should raise_error { |e| e.message =~ /uncompressed/ }
+ end
+
+ it "should uncompress chunk by chunk" do
+ uncompressor = stub_everything 'uncompressor'
+ @content.expects(:uncompress).with(@response).yields(uncompressor)
+ @response.expects(:code).returns("200")
+ @response.expects(:read_body).multiple_yields("chunk1","chunk2")
+
+ uncompressor.expects(:uncompress).with("chunk1").then.with("chunk2")
+ @content.write(@fh)
+ end
+
+ it "should write uncompressed chunks to the file" do
+ uncompressor = stub_everything 'uncompressor'
+ @content.expects(:uncompress).with(@response).yields(uncompressor)
+ @response.expects(:code).returns("200")
+ @response.expects(:read_body).multiple_yields("chunk1","chunk2")
+
+ uncompressor.expects(:uncompress).with("chunk1").returns("uncompressed1")
+ uncompressor.expects(:uncompress).with("chunk2").returns("uncompressed2")
+
+ @fh.expects(:print).with("uncompressed1")
+ @fh.expects(:print).with("uncompressed2")
+
+ @content.write(@fh)
+ end
+
+ it "should pass each uncompressed chunk to the current sum stream" do
+ uncompressor = stub_everything 'uncompressor'
+ @content.expects(:uncompress).with(@response).yields(uncompressor)
+ @response.expects(:code).returns("200")
+ @response.expects(:read_body).multiple_yields("chunk1","chunk2")
+
+ uncompressor.expects(:uncompress).with("chunk1").returns("uncompressed1")
+ uncompressor.expects(:uncompress).with("chunk2").returns("uncompressed2")
+
+ @digest.expects(:<<).with("uncompressed1").then.with("uncompressed2")
+ @content.write(@fh)
+ end
+ end
- describe "from a filebucket" do
- end
+ describe "from a filebucket" do
end
+ end
end
diff --git a/spec/unit/type/file/ensure_spec.rb b/spec/unit/type/file/ensure_spec.rb
index d766eeb..ec53ed8 100755
--- a/spec/unit/type/file/ensure_spec.rb
+++ b/spec/unit/type/file/ensure_spec.rb
@@ -5,80 +5,80 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
property = Puppet::Type.type(:file).attrclass(:ensure)
describe property do
- before do
- # Wow that's a messy interface to the resource.
- @resource = stub 'resource', :[] => nil, :[]= => nil, :property => nil, :newattr => nil, :parameter => nil, :replace? => true
- @resource.stubs(:[]).returns "foo"
- @resource.stubs(:[]).with(:path).returns "/my/file"
- @ensure = property.new :resource => @resource
- end
-
- it "should be a subclass of Ensure" do
- property.superclass.must == Puppet::Property::Ensure
+ before do
+ # Wow that's a messy interface to the resource.
+ @resource = stub 'resource', :[] => nil, :[]= => nil, :property => nil, :newattr => nil, :parameter => nil, :replace? => true
+ @resource.stubs(:[]).returns "foo"
+ @resource.stubs(:[]).with(:path).returns "/my/file"
+ @ensure = property.new :resource => @resource
+ end
+
+ it "should be a subclass of Ensure" do
+ property.superclass.must == Puppet::Property::Ensure
+ end
+
+ describe "when retrieving the current state" do
+ it "should return :absent if the file does not exist" do
+ @ensure = property.new(:resource => @resource)
+ @resource.expects(:stat).returns nil
+
+ @ensure.retrieve.should == :absent
end
- describe "when retrieving the current state" do
- it "should return :absent if the file does not exist" do
- @ensure = property.new(:resource => @resource)
- @resource.expects(:stat).returns nil
-
- @ensure.retrieve.should == :absent
- end
+ it "should return the current file type if the file exists" do
+ @ensure = property.new(:resource => @resource)
+ stat = mock 'stat', :ftype => "directory"
+ @resource.expects(:stat).returns stat
- it "should return the current file type if the file exists" do
- @ensure = property.new(:resource => @resource)
- stat = mock 'stat', :ftype => "directory"
- @resource.expects(:stat).returns stat
-
- @ensure.retrieve.should == :directory
- end
+ @ensure.retrieve.should == :directory
end
+ end
- describe "when testing whether :ensure is in sync" do
- before do
- @ensure = property.new(:resource => @resource)
- @stat = stub 'stat', :ftype => "file"
- end
+ describe "when testing whether :ensure is in sync" do
+ before do
+ @ensure = property.new(:resource => @resource)
+ @stat = stub 'stat', :ftype => "file"
+ end
- it "should always be in sync if replace is 'false' unless the file is missing" do
- @resource.expects(:replace?).returns false
- @ensure.insync?(:link).should be_true
- end
+ it "should always be in sync if replace is 'false' unless the file is missing" do
+ @resource.expects(:replace?).returns false
+ @ensure.insync?(:link).should be_true
+ end
- it "should be in sync if :ensure is set to :absent and the file does not exist" do
- @ensure.should = :absent
+ it "should be in sync if :ensure is set to :absent and the file does not exist" do
+ @ensure.should = :absent
- @ensure.must be_insync(:absent)
- end
+ @ensure.must be_insync(:absent)
+ end
- it "should not be in sync if :ensure is set to :absent and the file exists" do
- @ensure.should = :absent
+ it "should not be in sync if :ensure is set to :absent and the file exists" do
+ @ensure.should = :absent
- @ensure.should_not be_insync(:file)
- end
+ @ensure.should_not be_insync(:file)
+ end
- it "should be in sync if a normal file exists and :ensure is set to :present" do
- @ensure.should = :present
+ it "should be in sync if a normal file exists and :ensure is set to :present" do
+ @ensure.should = :present
- @ensure.must be_insync(:file)
- end
+ @ensure.must be_insync(:file)
+ end
- it "should be in sync if a directory exists and :ensure is set to :present" do
- @ensure.should = :present
+ it "should be in sync if a directory exists and :ensure is set to :present" do
+ @ensure.should = :present
- @ensure.must be_insync(:directory)
- end
+ @ensure.must be_insync(:directory)
+ end
- it "should be in sync if a symlink exists and :ensure is set to :present" do
- @ensure.should = :present
+ it "should be in sync if a symlink exists and :ensure is set to :present" do
+ @ensure.should = :present
- @ensure.must be_insync(:link)
- end
+ @ensure.must be_insync(:link)
+ end
- it "should not be in sync if :ensure is set to :file and a directory exists" do
- @ensure.should = :file
+ it "should not be in sync if :ensure is set to :file and a directory exists" do
+ @ensure.should = :file
- @ensure.should_not be_insync(:directory)
- end
+ @ensure.should_not be_insync(:directory)
end
+ end
end
diff --git a/spec/unit/type/file/group_spec.rb b/spec/unit/type/file/group_spec.rb
index 0062f03..2283b57 100755
--- a/spec/unit/type/file/group_spec.rb
+++ b/spec/unit/type/file/group_spec.rb
@@ -5,119 +5,119 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
property = Puppet::Type.type(:file).attrclass(:group)
describe property do
- before do
- @resource = stub 'resource', :line => "foo", :file => "bar"
- @resource.stubs(:[]).returns "foo"
- @resource.stubs(:[]).with(:path).returns "/my/file"
- @group = property.new :resource => @resource
+ before do
+ @resource = stub 'resource', :line => "foo", :file => "bar"
+ @resource.stubs(:[]).returns "foo"
+ @resource.stubs(:[]).with(:path).returns "/my/file"
+ @group = property.new :resource => @resource
+ end
+
+ it "should have a method for testing whether a group is valid" do
+ @group.must respond_to(:validgroup?)
+ end
+
+ it "should return the found gid if a group is valid" do
+ @group.expects(:gid).with("foo").returns 500
+ @group.validgroup?("foo").should == 500
+ end
+
+ it "should return false if a group is not valid" do
+ @group.expects(:gid).with("foo").returns nil
+ @group.validgroup?("foo").should be_false
+ end
+
+ describe "when retrieving the current value" do
+ it "should return :absent if the file cannot stat" do
+ @resource.expects(:stat).returns nil
+
+ @group.retrieve.should == :absent
end
- it "should have a method for testing whether a group is valid" do
- @group.must respond_to(:validgroup?)
- end
+ it "should get the gid from the stat instance from the file" do
+ stat = stub 'stat', :ftype => "foo"
+ @resource.expects(:stat).returns stat
+ stat.expects(:gid).returns 500
- it "should return the found gid if a group is valid" do
- @group.expects(:gid).with("foo").returns 500
- @group.validgroup?("foo").should == 500
+ @group.retrieve.should == 500
end
- it "should return false if a group is not valid" do
- @group.expects(:gid).with("foo").returns nil
- @group.validgroup?("foo").should be_false
- end
-
- describe "when retrieving the current value" do
- it "should return :absent if the file cannot stat" do
- @resource.expects(:stat).returns nil
-
- @group.retrieve.should == :absent
- end
+ it "should warn and return :silly if the found value is higher than the maximum uid value" do
+ Puppet.settings.expects(:value).with(:maximum_uid).returns 500
- it "should get the gid from the stat instance from the file" do
- stat = stub 'stat', :ftype => "foo"
- @resource.expects(:stat).returns stat
- stat.expects(:gid).returns 500
+ stat = stub 'stat', :ftype => "foo"
+ @resource.expects(:stat).returns stat
+ stat.expects(:gid).returns 1000
- @group.retrieve.should == 500
- end
-
- it "should warn and return :silly if the found value is higher than the maximum uid value" do
- Puppet.settings.expects(:value).with(:maximum_uid).returns 500
-
- stat = stub 'stat', :ftype => "foo"
- @resource.expects(:stat).returns stat
- stat.expects(:gid).returns 1000
-
- @group.expects(:warning)
- @group.retrieve.should == :silly
- end
+ @group.expects(:warning)
+ @group.retrieve.should == :silly
end
+ end
- describe "when determining if the file is in sync" do
- it "should directly compare the group values if the desired group is an integer" do
- @group.should = [10]
- @group.must be_insync(10)
- end
+ describe "when determining if the file is in sync" do
+ it "should directly compare the group values if the desired group is an integer" do
+ @group.should = [10]
+ @group.must be_insync(10)
+ end
- it "should treat numeric strings as integers" do
- @group.should = ["10"]
- @group.must be_insync(10)
- end
+ it "should treat numeric strings as integers" do
+ @group.should = ["10"]
+ @group.must be_insync(10)
+ end
- it "should convert the group name to an integer if the desired group is a string" do
- @group.expects(:gid).with("foo").returns 10
- @group.should = %w{foo}
+ it "should convert the group name to an integer if the desired group is a string" do
+ @group.expects(:gid).with("foo").returns 10
+ @group.should = %w{foo}
- @group.must be_insync(10)
- end
+ @group.must be_insync(10)
+ end
- it "should not validate that groups exist when a group is specified as an integer" do
- @group.expects(:gid).never
- @group.validgroup?(10)
- end
+ it "should not validate that groups exist when a group is specified as an integer" do
+ @group.expects(:gid).never
+ @group.validgroup?(10)
+ end
- it "should fail if it cannot convert a group name to an integer" do
- @group.expects(:gid).with("foo").returns nil
- @group.should = %w{foo}
+ it "should fail if it cannot convert a group name to an integer" do
+ @group.expects(:gid).with("foo").returns nil
+ @group.should = %w{foo}
- lambda { @group.insync?(10) }.should raise_error(Puppet::Error)
- end
+ lambda { @group.insync?(10) }.should raise_error(Puppet::Error)
+ end
- it "should return false if the groups are not equal" do
- @group.should = [10]
- @group.should_not be_insync(20)
- end
+ it "should return false if the groups are not equal" do
+ @group.should = [10]
+ @group.should_not be_insync(20)
end
+ end
- describe "when changing the group" do
- before do
- @group.should = %w{one}
- @group.stubs(:gid).returns 500
- end
+ describe "when changing the group" do
+ before do
+ @group.should = %w{one}
+ @group.stubs(:gid).returns 500
+ end
- it "should chown the file if :links is set to :follow" do
- @resource.expects(:[]).with(:links).returns :follow
- File.expects(:chown)
+ it "should chown the file if :links is set to :follow" do
+ @resource.expects(:[]).with(:links).returns :follow
+ File.expects(:chown)
- @group.sync
- end
+ @group.sync
+ end
- it "should lchown the file if :links is set to :manage" do
- @resource.expects(:[]).with(:links).returns :manage
- File.expects(:lchown)
+ it "should lchown the file if :links is set to :manage" do
+ @resource.expects(:[]).with(:links).returns :manage
+ File.expects(:lchown)
- @group.sync
- end
+ @group.sync
+ end
- it "should use the first valid group in its 'should' list" do
- @group.should = %w{one two three}
- @group.expects(:validgroup?).with("one").returns nil
- @group.expects(:validgroup?).with("two").returns 500
- @group.expects(:validgroup?).with("three").never
+ it "should use the first valid group in its 'should' list" do
+ @group.should = %w{one two three}
+ @group.expects(:validgroup?).with("one").returns nil
+ @group.expects(:validgroup?).with("two").returns 500
+ @group.expects(:validgroup?).with("three").never
- File.expects(:chown).with(nil, 500, "/my/file")
+ File.expects(:chown).with(nil, 500, "/my/file")
- @group.sync
- end
+ @group.sync
end
+ end
end
diff --git a/spec/unit/type/file/owner_spec.rb b/spec/unit/type/file/owner_spec.rb
index 8b58505..8e136a1 100755
--- a/spec/unit/type/file/owner_spec.rb
+++ b/spec/unit/type/file/owner_spec.rb
@@ -5,146 +5,146 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
property = Puppet::Type.type(:file).attrclass(:owner)
describe property do
- before do
- # FIXME: many of these tests exercise the provider rather than `owner`
- # and should be moved into provider tests. ~JW
- @provider = Puppet::Type.type(:file).provider(:posix).new
- @provider.stubs(:uid).with("one").returns(1)
-
- @resource = stub 'resource', :line => "foo", :file => "bar"
- @resource.stubs(:[]).returns "foo"
- @resource.stubs(:[]).with(:path).returns "/my/file"
- @resource.stubs(:provider).returns @provider
-
- @owner = property.new :resource => @resource
+ before do
+ # FIXME: many of these tests exercise the provider rather than `owner`
+ # and should be moved into provider tests. ~JW
+ @provider = Puppet::Type.type(:file).provider(:posix).new
+ @provider.stubs(:uid).with("one").returns(1)
+
+ @resource = stub 'resource', :line => "foo", :file => "bar"
+ @resource.stubs(:[]).returns "foo"
+ @resource.stubs(:[]).with(:path).returns "/my/file"
+ @resource.stubs(:provider).returns @provider
+
+ @owner = property.new :resource => @resource
+ end
+
+ it "should have a method for testing whether an owner is valid" do
+ @provider.must respond_to(:validuser?)
+ end
+
+ it "should return the found uid if an owner is valid" do
+ @provider.expects(:uid).with("foo").returns 500
+ @provider.validuser?("foo").should == 500
+ end
+
+ it "should return false if an owner is not valid" do
+ @provider.expects(:uid).with("foo").returns nil
+ @provider.validuser?("foo").should be_false
+ end
+
+ describe "when retrieving the current value" do
+ it "should return :absent if the file cannot stat" do
+ @resource.expects(:stat).returns nil
+
+ @owner.retrieve.should == :absent
end
- it "should have a method for testing whether an owner is valid" do
- @provider.must respond_to(:validuser?)
- end
-
- it "should return the found uid if an owner is valid" do
- @provider.expects(:uid).with("foo").returns 500
- @provider.validuser?("foo").should == 500
- end
+ it "should get the uid from the stat instance from the file" do
+ stat = stub 'stat', :ftype => "foo"
+ @resource.expects(:stat).returns stat
+ stat.expects(:uid).returns 500
- it "should return false if an owner is not valid" do
- @provider.expects(:uid).with("foo").returns nil
- @provider.validuser?("foo").should be_false
+ @owner.retrieve.should == 500
end
- describe "when retrieving the current value" do
- it "should return :absent if the file cannot stat" do
- @resource.expects(:stat).returns nil
+ it "should warn and return :silly if the found value is higher than the maximum uid value" do
+ Puppet.settings.expects(:value).with(:maximum_uid).returns 500
- @owner.retrieve.should == :absent
- end
+ stat = stub 'stat', :ftype => "foo"
+ @resource.expects(:stat).returns stat
+ stat.expects(:uid).returns 1000
- it "should get the uid from the stat instance from the file" do
- stat = stub 'stat', :ftype => "foo"
- @resource.expects(:stat).returns stat
- stat.expects(:uid).returns 500
-
- @owner.retrieve.should == 500
- end
-
- it "should warn and return :silly if the found value is higher than the maximum uid value" do
- Puppet.settings.expects(:value).with(:maximum_uid).returns 500
-
- stat = stub 'stat', :ftype => "foo"
- @resource.expects(:stat).returns stat
- stat.expects(:uid).returns 1000
-
- @provider.expects(:warning)
- @owner.retrieve.should == :silly
- end
+ @provider.expects(:warning)
+ @owner.retrieve.should == :silly
end
+ end
- describe "when determining if the file is in sync" do
- describe "and not running as root" do
- it "should warn once and return true" do
- Puppet.features.expects(:root?).returns false
+ describe "when determining if the file is in sync" do
+ describe "and not running as root" do
+ it "should warn once and return true" do
+ Puppet.features.expects(:root?).returns false
- @provider.expects(:warnonce)
+ @provider.expects(:warnonce)
- @owner.should = [10]
- @owner.must be_insync(20)
- end
- end
+ @owner.should = [10]
+ @owner.must be_insync(20)
+ end
+ end
- before do
- Puppet.features.stubs(:root?).returns true
- end
+ before do
+ Puppet.features.stubs(:root?).returns true
+ end
- it "should be in sync if 'should' is not provided" do
- @owner.must be_insync(10)
- end
+ it "should be in sync if 'should' is not provided" do
+ @owner.must be_insync(10)
+ end
- it "should directly compare the owner values if the desired owner is an integer" do
- @owner.should = [10]
- @owner.must be_insync(10)
- end
+ it "should directly compare the owner values if the desired owner is an integer" do
+ @owner.should = [10]
+ @owner.must be_insync(10)
+ end
- it "should treat numeric strings as integers" do
- @owner.should = ["10"]
- @owner.must be_insync(10)
- end
+ it "should treat numeric strings as integers" do
+ @owner.should = ["10"]
+ @owner.must be_insync(10)
+ end
- it "should convert the owner name to an integer if the desired owner is a string" do
- @provider.expects(:uid).with("foo").returns 10
- @owner.should = %w{foo}
+ it "should convert the owner name to an integer if the desired owner is a string" do
+ @provider.expects(:uid).with("foo").returns 10
+ @owner.should = %w{foo}
- @owner.must be_insync(10)
- end
+ @owner.must be_insync(10)
+ end
- it "should not validate that users exist when a user is specified as an integer" do
- @provider.expects(:uid).never
- @provider.validuser?(10)
- end
+ it "should not validate that users exist when a user is specified as an integer" do
+ @provider.expects(:uid).never
+ @provider.validuser?(10)
+ end
- it "should fail if it cannot convert an owner name to an integer" do
- @provider.expects(:uid).with("foo").returns nil
- @owner.should = %w{foo}
+ it "should fail if it cannot convert an owner name to an integer" do
+ @provider.expects(:uid).with("foo").returns nil
+ @owner.should = %w{foo}
- lambda { @owner.insync?(10) }.should raise_error(Puppet::Error)
- end
+ lambda { @owner.insync?(10) }.should raise_error(Puppet::Error)
+ end
- it "should return false if the owners are not equal" do
- @owner.should = [10]
- @owner.should_not be_insync(20)
- end
+ it "should return false if the owners are not equal" do
+ @owner.should = [10]
+ @owner.should_not be_insync(20)
end
+ end
- describe "when changing the owner" do
- before do
- @owner.should = %w{one}
- @owner.stubs(:path).returns "path"
- @owner.stubs(:uid).returns 500
- end
+ describe "when changing the owner" do
+ before do
+ @owner.should = %w{one}
+ @owner.stubs(:path).returns "path"
+ @owner.stubs(:uid).returns 500
+ end
- it "should chown the file if :links is set to :follow" do
- @resource.expects(:[]).with(:links).returns :follow
- File.expects(:chown)
+ it "should chown the file if :links is set to :follow" do
+ @resource.expects(:[]).with(:links).returns :follow
+ File.expects(:chown)
- @owner.sync
- end
+ @owner.sync
+ end
- it "should lchown the file if :links is set to :manage" do
- @resource.expects(:[]).with(:links).returns :manage
- File.expects(:lchown)
+ it "should lchown the file if :links is set to :manage" do
+ @resource.expects(:[]).with(:links).returns :manage
+ File.expects(:lchown)
- @owner.sync
- end
+ @owner.sync
+ end
- it "should use the first valid owner in its 'should' list" do
- @owner.should = %w{one two three}
- @provider.expects(:validuser?).with("one").returns nil
- @provider.expects(:validuser?).with("two").returns 500
- @provider.expects(:validuser?).with("three").never
+ it "should use the first valid owner in its 'should' list" do
+ @owner.should = %w{one two three}
+ @provider.expects(:validuser?).with("one").returns nil
+ @provider.expects(:validuser?).with("two").returns 500
+ @provider.expects(:validuser?).with("three").never
- File.expects(:chown).with(500, nil, "/my/file")
+ File.expects(:chown).with(500, nil, "/my/file")
- @owner.sync
- end
+ @owner.sync
end
+ end
end
diff --git a/spec/unit/type/file/selinux_spec.rb b/spec/unit/type/file/selinux_spec.rb
index af92a76..1ca59e9 100644
--- a/spec/unit/type/file/selinux_spec.rb
+++ b/spec/unit/type/file/selinux_spec.rb
@@ -4,80 +4,80 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
[:seluser, :selrole, :seltype, :selrange].each do |param|
- property = Puppet::Type.type(:file).attrclass(param)
- describe property do
- before do
- @resource = Puppet::Type.type(:file).new :path => "/my/file"
- @sel = property.new :resource => @resource
- end
+ property = Puppet::Type.type(:file).attrclass(param)
+ describe property do
+ before do
+ @resource = Puppet::Type.type(:file).new :path => "/my/file"
+ @sel = property.new :resource => @resource
+ end
- it "retrieve on #{param} should return :absent if the file isn't statable" do
- @resource.expects(:stat).returns nil
- @sel.retrieve.should == :absent
- end
+ it "retrieve on #{param} should return :absent if the file isn't statable" do
+ @resource.expects(:stat).returns nil
+ @sel.retrieve.should == :absent
+ end
- it "should retrieve nil for #{param} if there is no SELinux support" do
- stat = stub 'stat', :ftype => "foo"
- @resource.expects(:stat).returns stat
- @sel.expects(:get_selinux_current_context).with("/my/file").returns nil
- @sel.retrieve.should be_nil
- end
+ it "should retrieve nil for #{param} if there is no SELinux support" do
+ stat = stub 'stat', :ftype => "foo"
+ @resource.expects(:stat).returns stat
+ @sel.expects(:get_selinux_current_context).with("/my/file").returns nil
+ @sel.retrieve.should be_nil
+ end
- it "should retrieve #{param} if a SELinux context is found with a range" do
- stat = stub 'stat', :ftype => "foo"
- @resource.expects(:stat).returns stat
- @sel.expects(:get_selinux_current_context).with("/my/file").returns "user_u:role_r:type_t:s0"
- expectedresult = case param
- when :seluser; "user_u"
- when :selrole; "role_r"
- when :seltype; "type_t"
- when :selrange; "s0"
- end
- @sel.retrieve.should == expectedresult
- end
+ it "should retrieve #{param} if a SELinux context is found with a range" do
+ stat = stub 'stat', :ftype => "foo"
+ @resource.expects(:stat).returns stat
+ @sel.expects(:get_selinux_current_context).with("/my/file").returns "user_u:role_r:type_t:s0"
+ expectedresult = case param
+ when :seluser; "user_u"
+ when :selrole; "role_r"
+ when :seltype; "type_t"
+ when :selrange; "s0"
+ end
+ @sel.retrieve.should == expectedresult
+ end
- it "should retrieve #{param} if a SELinux context is found without a range" do
- stat = stub 'stat', :ftype => "foo"
- @resource.expects(:stat).returns stat
- @sel.expects(:get_selinux_current_context).with("/my/file").returns "user_u:role_r:type_t"
- expectedresult = case param
- when :seluser; "user_u"
- when :selrole; "role_r"
- when :seltype; "type_t"
- when :selrange; nil
- end
- @sel.retrieve.should == expectedresult
- end
+ it "should retrieve #{param} if a SELinux context is found without a range" do
+ stat = stub 'stat', :ftype => "foo"
+ @resource.expects(:stat).returns stat
+ @sel.expects(:get_selinux_current_context).with("/my/file").returns "user_u:role_r:type_t"
+ expectedresult = case param
+ when :seluser; "user_u"
+ when :selrole; "role_r"
+ when :seltype; "type_t"
+ when :selrange; nil
+ end
+ @sel.retrieve.should == expectedresult
+ end
- it "should handle no default gracefully" do
- @sel.expects(:get_selinux_default_context).with("/my/file").returns nil
- @sel.default.must be_nil
- end
+ it "should handle no default gracefully" do
+ @sel.expects(:get_selinux_default_context).with("/my/file").returns nil
+ @sel.default.must be_nil
+ end
- it "should be able to detect matchpathcon defaults" do
- @sel.stubs(:debug)
- @sel.expects(:get_selinux_default_context).with("/my/file").returns "user_u:role_r:type_t:s0"
- expectedresult = case param
- when :seluser; "user_u"
- when :selrole; "role_r"
- when :seltype; "type_t"
- when :selrange; "s0"
- end
- @sel.default.must == expectedresult
- end
+ it "should be able to detect matchpathcon defaults" do
+ @sel.stubs(:debug)
+ @sel.expects(:get_selinux_default_context).with("/my/file").returns "user_u:role_r:type_t:s0"
+ expectedresult = case param
+ when :seluser; "user_u"
+ when :selrole; "role_r"
+ when :seltype; "type_t"
+ when :selrange; "s0"
+ end
+ @sel.default.must == expectedresult
+ end
- it "should be able to set a new context" do
- stat = stub 'stat', :ftype => "foo"
- @sel.should = %w{newone}
- @sel.expects(:set_selinux_context).with("/my/file", ["newone"], param)
- @sel.sync
- end
+ it "should be able to set a new context" do
+ stat = stub 'stat', :ftype => "foo"
+ @sel.should = %w{newone}
+ @sel.expects(:set_selinux_context).with("/my/file", ["newone"], param)
+ @sel.sync
+ end
- it "should do nothing for insync? if no SELinux support" do
- @sel.should = %{newcontext}
- @sel.expects(:selinux_support?).returns false
- @sel.insync?("oldcontext").should == true
- end
+ it "should do nothing for insync? if no SELinux support" do
+ @sel.should = %{newcontext}
+ @sel.expects(:selinux_support?).returns false
+ @sel.insync?("oldcontext").should == true
end
+ end
end
diff --git a/spec/unit/type/file/source_spec.rb b/spec/unit/type/file/source_spec.rb
index 536cb63..a45a1f7 100755
--- a/spec/unit/type/file/source_spec.rb
+++ b/spec/unit/type/file/source_spec.rb
@@ -4,269 +4,269 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
source = Puppet::Type.type(:file).attrclass(:source)
describe Puppet::Type.type(:file).attrclass(:source) do
- before do
- # Wow that's a messy interface to the resource.
- @resource = stub 'resource', :[]= => nil, :property => nil, :catalog => stub("catalog", :dependent_data_expired? => false)
+ before do
+ # Wow that's a messy interface to the resource.
+ @resource = stub 'resource', :[]= => nil, :property => nil, :catalog => stub("catalog", :dependent_data_expired? => false)
+ end
+
+ it "should be a subclass of Parameter" do
+ source.superclass.must == Puppet::Parameter
+ end
+
+ describe "when initializing" do
+ it "should fail if the set values are not URLs" do
+ s = source.new(:resource => @resource)
+ URI.expects(:parse).with('foo').raises RuntimeError
+
+ lambda { s.value = %w{foo} }.must raise_error(Puppet::Error)
end
- it "should be a subclass of Parameter" do
- source.superclass.must == Puppet::Parameter
+ it "should fail if the URI is not a local file, file URI, or puppet URI" do
+ s = source.new(:resource => @resource)
+
+ lambda { s.value = %w{http://foo/bar} }.must raise_error(Puppet::Error)
end
+ end
- describe "when initializing" do
- it "should fail if the set values are not URLs" do
- s = source.new(:resource => @resource)
- URI.expects(:parse).with('foo').raises RuntimeError
+ it "should have a method for retrieving its metadata" do
+ source.new(:resource => @resource).must respond_to(:metadata)
+ end
- lambda { s.value = %w{foo} }.must raise_error(Puppet::Error)
- end
+ it "should have a method for setting its metadata" do
+ source.new(:resource => @resource).must respond_to(:metadata=)
+ end
- it "should fail if the URI is not a local file, file URI, or puppet URI" do
- s = source.new(:resource => @resource)
+ describe "when returning the metadata" do
+ before do
+ @metadata = stub 'metadata', :source= => nil
+ end
- lambda { s.value = %w{http://foo/bar} }.must raise_error(Puppet::Error)
- end
+ it "should return already-available metadata" do
+ @source = source.new(:resource => @resource)
+ @source.metadata = "foo"
+ @source.metadata.should == "foo"
end
- it "should have a method for retrieving its metadata" do
- source.new(:resource => @resource).must respond_to(:metadata)
+ it "should return nil if no @should value is set and no metadata is available" do
+ @source = source.new(:resource => @resource)
+ @source.metadata.should be_nil
end
- it "should have a method for setting its metadata" do
- source.new(:resource => @resource).must respond_to(:metadata=)
+ it "should collect its metadata using the Metadata class if it is not already set" do
+ @source = source.new(:resource => @resource, :value => "/foo/bar")
+ Puppet::FileServing::Metadata.expects(:find).with("/foo/bar").returns @metadata
+ @source.metadata
end
- describe "when returning the metadata" do
- before do
- @metadata = stub 'metadata', :source= => nil
- end
+ it "should use the metadata from the first found source" do
+ metadata = stub 'metadata', :source= => nil
+ @source = source.new(:resource => @resource, :value => ["/foo/bar", "/fee/booz"])
+ Puppet::FileServing::Metadata.expects(:find).with("/foo/bar").returns nil
+ Puppet::FileServing::Metadata.expects(:find).with("/fee/booz").returns metadata
+ @source.metadata.should equal(metadata)
+ end
- it "should return already-available metadata" do
- @source = source.new(:resource => @resource)
- @source.metadata = "foo"
- @source.metadata.should == "foo"
- end
+ it "should store the found source as the metadata's source" do
+ metadata = mock 'metadata'
+ @source = source.new(:resource => @resource, :value => "/foo/bar")
+ Puppet::FileServing::Metadata.expects(:find).with("/foo/bar").returns metadata
- it "should return nil if no @should value is set and no metadata is available" do
- @source = source.new(:resource => @resource)
- @source.metadata.should be_nil
- end
+ metadata.expects(:source=).with("/foo/bar")
+ @source.metadata
+ end
- it "should collect its metadata using the Metadata class if it is not already set" do
- @source = source.new(:resource => @resource, :value => "/foo/bar")
- Puppet::FileServing::Metadata.expects(:find).with("/foo/bar").returns @metadata
- @source.metadata
- end
+ it "should fail intelligently if an exception is encountered while querying for metadata" do
+ @source = source.new(:resource => @resource, :value => "/foo/bar")
+ Puppet::FileServing::Metadata.expects(:find).with("/foo/bar").raises RuntimeError
- it "should use the metadata from the first found source" do
- metadata = stub 'metadata', :source= => nil
- @source = source.new(:resource => @resource, :value => ["/foo/bar", "/fee/booz"])
- Puppet::FileServing::Metadata.expects(:find).with("/foo/bar").returns nil
- Puppet::FileServing::Metadata.expects(:find).with("/fee/booz").returns metadata
- @source.metadata.should equal(metadata)
- end
+ @source.expects(:fail).raises ArgumentError
+ lambda { @source.metadata }.should raise_error(ArgumentError)
+ end
- it "should store the found source as the metadata's source" do
- metadata = mock 'metadata'
- @source = source.new(:resource => @resource, :value => "/foo/bar")
- Puppet::FileServing::Metadata.expects(:find).with("/foo/bar").returns metadata
+ it "should fail if no specified sources can be found" do
+ @source = source.new(:resource => @resource, :value => "/foo/bar")
+ Puppet::FileServing::Metadata.expects(:find).with("/foo/bar").returns nil
- metadata.expects(:source=).with("/foo/bar")
- @source.metadata
- end
+ @source.expects(:fail).raises RuntimeError
- it "should fail intelligently if an exception is encountered while querying for metadata" do
- @source = source.new(:resource => @resource, :value => "/foo/bar")
- Puppet::FileServing::Metadata.expects(:find).with("/foo/bar").raises RuntimeError
+ lambda { @source.metadata }.should raise_error(RuntimeError)
+ end
- @source.expects(:fail).raises ArgumentError
- lambda { @source.metadata }.should raise_error(ArgumentError)
- end
+ it "should expire the metadata appropriately" do
+ expirer = stub 'expired', :dependent_data_expired? => true
- it "should fail if no specified sources can be found" do
- @source = source.new(:resource => @resource, :value => "/foo/bar")
- Puppet::FileServing::Metadata.expects(:find).with("/foo/bar").returns nil
+ metadata = stub 'metadata', :source= => nil
+ Puppet::FileServing::Metadata.expects(:find).with("/fee/booz").returns metadata
- @source.expects(:fail).raises RuntimeError
+ @source = source.new(:resource => @resource, :value => ["/fee/booz"])
+ @source.metadata = "foo"
- lambda { @source.metadata }.should raise_error(RuntimeError)
- end
+ @source.stubs(:expirer).returns expirer
+
+ @source.metadata.should_not == "foo"
+ end
+ end
- it "should expire the metadata appropriately" do
- expirer = stub 'expired', :dependent_data_expired? => true
+ it "should have a method for setting the desired values on the resource" do
+ source.new(:resource => @resource).must respond_to(:copy_source_values)
+ end
- metadata = stub 'metadata', :source= => nil
- Puppet::FileServing::Metadata.expects(:find).with("/fee/booz").returns metadata
+ describe "when copying the source values" do
+ before do
- @source = source.new(:resource => @resource, :value => ["/fee/booz"])
- @source.metadata = "foo"
+ @resource = Puppet::Type.type(:file).new :path => "/foo/bar"
- @source.stubs(:expirer).returns expirer
+ @source = source.new(:resource => @resource)
+ @metadata = stub 'metadata', :owner => 100, :group => 200, :mode => 123, :checksum => "{md5}asdfasdf", :ftype => "file"
+ @source.stubs(:metadata).returns @metadata
+ end
- @source.metadata.should_not == "foo"
- end
+ it "should fail if there is no metadata" do
+ @source.stubs(:metadata).returns nil
+ @source.expects(:devfail).raises ArgumentError
+ lambda { @source.copy_source_values }.should raise_error(ArgumentError)
end
- it "should have a method for setting the desired values on the resource" do
- source.new(:resource => @resource).must respond_to(:copy_source_values)
+ it "should set :ensure to the file type" do
+ @metadata.stubs(:ftype).returns "file"
+
+ @source.copy_source_values
+ @resource[:ensure].must == :file
end
- describe "when copying the source values" do
- before do
+ it "should not set 'ensure' if it is already set to 'absent'" do
+ @metadata.stubs(:ftype).returns "file"
- @resource = Puppet::Type.type(:file).new :path => "/foo/bar"
+ @resource[:ensure] = :absent
+ @source.copy_source_values
+ @resource[:ensure].must == :absent
+ end
- @source = source.new(:resource => @resource)
- @metadata = stub 'metadata', :owner => 100, :group => 200, :mode => 123, :checksum => "{md5}asdfasdf", :ftype => "file"
- @source.stubs(:metadata).returns @metadata
- end
+ describe "and the source is a file" do
+ before do
+ @metadata.stubs(:ftype).returns "file"
+ end
- it "should fail if there is no metadata" do
- @source.stubs(:metadata).returns nil
- @source.expects(:devfail).raises ArgumentError
- lambda { @source.copy_source_values }.should raise_error(ArgumentError)
- end
+ it "should copy the metadata's owner, group, checksum, and mode to the resource if they are not set on the resource" do
+ Puppet.features.expects(:root?).returns true
- it "should set :ensure to the file type" do
- @metadata.stubs(:ftype).returns "file"
+ @source.copy_source_values
- @source.copy_source_values
- @resource[:ensure].must == :file
- end
+ @resource[:owner].must == 100
+ @resource[:group].must == 200
+ @resource[:mode].must == 123
- it "should not set 'ensure' if it is already set to 'absent'" do
- @metadata.stubs(:ftype).returns "file"
+ # Metadata calls it checksum, we call it content.
+ @resource[:content].must == @metadata.checksum
+ end
- @resource[:ensure] = :absent
- @source.copy_source_values
- @resource[:ensure].must == :absent
- end
+ it "should not copy the metadata's owner to the resource if it is already set" do
+ @resource[:owner] = 1
+ @resource[:group] = 2
+ @resource[:mode] = 3
+ @resource[:content] = "foobar"
- describe "and the source is a file" do
- before do
- @metadata.stubs(:ftype).returns "file"
- end
+ @source.copy_source_values
- it "should copy the metadata's owner, group, checksum, and mode to the resource if they are not set on the resource" do
- Puppet.features.expects(:root?).returns true
+ @resource[:owner].must == 1
+ @resource[:group].must == 2
+ @resource[:mode].must == 3
+ @resource[:content].should_not == @metadata.checksum
+ end
- @source.copy_source_values
+ describe "and puppet is not running as root" do
+ it "should not try to set the owner" do
+ Puppet.features.expects(:root?).returns false
- @resource[:owner].must == 100
- @resource[:group].must == 200
- @resource[:mode].must == 123
+ @source.copy_source_values
+ @resource[:owner].should be_nil
+ end
+ end
+ end
- # Metadata calls it checksum, we call it content.
- @resource[:content].must == @metadata.checksum
- end
+ describe "and the source is a link" do
+ it "should set the target to the link destination" do
+ @metadata.stubs(:ftype).returns "link"
+ @resource.stubs(:[])
+ @resource.stubs(:[]=)
- it "should not copy the metadata's owner to the resource if it is already set" do
- @resource[:owner] = 1
- @resource[:group] = 2
- @resource[:mode] = 3
- @resource[:content] = "foobar"
+ @metadata.expects(:destination).returns "/path/to/symlink"
- @source.copy_source_values
+ @resource.expects(:[]=).with(:target, "/path/to/symlink")
+ @source.copy_source_values
+ end
+ end
+ end
- @resource[:owner].must == 1
- @resource[:group].must == 2
- @resource[:mode].must == 3
- @resource[:content].should_not == @metadata.checksum
- end
+ it "should have a local? method" do
+ source.new(:resource => @resource).must be_respond_to(:local?)
+ end
- describe "and puppet is not running as root" do
- it "should not try to set the owner" do
- Puppet.features.expects(:root?).returns false
+ context "when accessing source properties" do
+ before(:each) do
+ @source = source.new(:resource => @resource)
+ @metadata = stub_everything
+ @source.stubs(:metadata).returns(@metadata)
+ end
- @source.copy_source_values
- @resource[:owner].should be_nil
- end
- end
- end
+ describe "for local sources" do
+ before(:each) do
+ @metadata.stubs(:ftype).returns "file"
+ @metadata.stubs(:source).returns("file:///path/to/source")
+ end
- describe "and the source is a link" do
- it "should set the target to the link destination" do
- @metadata.stubs(:ftype).returns "link"
- @resource.stubs(:[])
- @resource.stubs(:[]=)
+ it "should be local" do
+ @source.must be_local
+ end
- @metadata.expects(:destination).returns "/path/to/symlink"
+ it "should be local if there is no scheme" do
+ @metadata.stubs(:source).returns("/path/to/source")
+ @source.must be_local
+ end
- @resource.expects(:[]=).with(:target, "/path/to/symlink")
- @source.copy_source_values
- end
- end
+ it "should be able to return the metadata source full path" do
+ @source.full_path.should == "/path/to/source"
+ end
end
- it "should have a local? method" do
- source.new(:resource => @resource).must be_respond_to(:local?)
- end
+ describe "for remote sources" do
+ before(:each) do
+ @metadata.stubs(:ftype).returns "file"
+ @metadata.stubs(:source).returns("puppet://server:8192/path/to/source")
+ end
- context "when accessing source properties" do
- before(:each) do
- @source = source.new(:resource => @resource)
- @metadata = stub_everything
- @source.stubs(:metadata).returns(@metadata)
- end
+ it "should not be local" do
+ @source.should_not be_local
+ end
+
+ it "should be able to return the metadata source full path" do
+ @source.full_path.should == "/path/to/source"
+ end
- describe "for local sources" do
- before(:each) do
- @metadata.stubs(:ftype).returns "file"
- @metadata.stubs(:source).returns("file:///path/to/source")
- end
+ it "should be able to return the source server" do
+ @source.server.should == "server"
+ end
- it "should be local" do
- @source.must be_local
- end
+ it "should be able to return the source port" do
+ @source.port.should == 8192
+ end
- it "should be local if there is no scheme" do
- @metadata.stubs(:source).returns("/path/to/source")
- @source.must be_local
- end
+ describe "which don't specify server or port" do
+ before(:each) do
+ @metadata.stubs(:source).returns("puppet:///path/to/source")
+ end
- it "should be able to return the metadata source full path" do
- @source.full_path.should == "/path/to/source"
- end
+ it "should return the default source server" do
+ Puppet.settings.expects(:[]).with(:server).returns("myserver")
+ @source.server.should == "myserver"
end
- describe "for remote sources" do
- before(:each) do
- @metadata.stubs(:ftype).returns "file"
- @metadata.stubs(:source).returns("puppet://server:8192/path/to/source")
- end
-
- it "should not be local" do
- @source.should_not be_local
- end
-
- it "should be able to return the metadata source full path" do
- @source.full_path.should == "/path/to/source"
- end
-
- it "should be able to return the source server" do
- @source.server.should == "server"
- end
-
- it "should be able to return the source port" do
- @source.port.should == 8192
- end
-
- describe "which don't specify server or port" do
- before(:each) do
- @metadata.stubs(:source).returns("puppet:///path/to/source")
- end
-
- it "should return the default source server" do
- Puppet.settings.expects(:[]).with(:server).returns("myserver")
- @source.server.should == "myserver"
- end
-
- it "should return the default source port" do
- Puppet.settings.expects(:[]).with(:masterport).returns(1234)
- @source.port.should == 1234
- end
- end
+ it "should return the default source port" do
+ Puppet.settings.expects(:[]).with(:masterport).returns(1234)
+ @source.port.should == 1234
end
+ end
end
+ end
end
diff --git a/spec/unit/type/file_spec.rb b/spec/unit/type/file_spec.rb
index 5388dc2..845bf3d 100755
--- a/spec/unit/type/file_spec.rb
+++ b/spec/unit/type/file_spec.rb
@@ -3,1054 +3,1054 @@
require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::Type.type(:file) do
- before do
- Puppet.settings.stubs(:use)
- @real_posix = Puppet.features.posix?
- Puppet.features.stubs("posix?").returns(true)
-
- @path = Tempfile.new("puppetspec")
- pathname = @path.path
- @path.close!()
- @path = pathname
- @file = Puppet::Type::File.new(:name => @path)
-
- @catalog = Puppet::Resource::Catalog.new
- @file.catalog = @catalog
+ before do
+ Puppet.settings.stubs(:use)
+ @real_posix = Puppet.features.posix?
+ Puppet.features.stubs("posix?").returns(true)
+
+ @path = Tempfile.new("puppetspec")
+ pathname = @path.path
+ @path.close!()
+ @path = pathname
+ @file = Puppet::Type::File.new(:name => @path)
+
+ @catalog = Puppet::Resource::Catalog.new
+ @file.catalog = @catalog
+ end
+
+ describe "when determining if recursion is enabled" do
+ it "should default to recursion being disabled" do
+ @file.should_not be_recurse
+ end
+ [true, "true", 10, "inf", "remote"].each do |value|
+ it "should consider #{value} to enable recursion" do
+ @file[:recurse] = value
+ @file.must be_recurse
+ end
end
- describe "when determining if recursion is enabled" do
- it "should default to recursion being disabled" do
- @file.should_not be_recurse
- end
- [true, "true", 10, "inf", "remote"].each do |value|
- it "should consider #{value} to enable recursion" do
- @file[:recurse] = value
- @file.must be_recurse
- end
- end
-
- [false, "false", 0].each do |value|
- it "should consider #{value} to disable recursion" do
- @file[:recurse] = value
- @file.should_not be_recurse
- end
- end
+ [false, "false", 0].each do |value|
+ it "should consider #{value} to disable recursion" do
+ @file[:recurse] = value
+ @file.should_not be_recurse
+ end
end
+ end
- describe "#write" do
+ describe "#write" do
- it "should propagate failures encountered when renaming the temporary file" do
- File.stubs(:open)
+ it "should propagate failures encountered when renaming the temporary file" do
+ File.stubs(:open)
- File.expects(:rename).raises ArgumentError
- file = Puppet::Type::File.new(:name => "/my/file", :backup => "puppet")
+ File.expects(:rename).raises ArgumentError
+ file = Puppet::Type::File.new(:name => "/my/file", :backup => "puppet")
- file.stubs(:validate_checksum?).returns(false)
+ file.stubs(:validate_checksum?).returns(false)
- property = stub('content_property', :actual_content => "something", :length => "something".length)
- file.stubs(:property).with(:content).returns(property)
+ property = stub('content_property', :actual_content => "something", :length => "something".length)
+ file.stubs(:property).with(:content).returns(property)
- lambda { file.write(:content) }.should raise_error(Puppet::Error)
- end
+ lambda { file.write(:content) }.should raise_error(Puppet::Error)
+ end
- it "should delegate writing to the content property" do
- filehandle = stub_everything 'fh'
- File.stubs(:open).yields(filehandle)
- File.stubs(:rename)
- property = stub('content_property', :actual_content => "something", :length => "something".length)
- file = Puppet::Type::File.new(:name => "/my/file", :backup => "puppet")
- file.stubs(:validate_checksum?).returns(false)
- file.stubs(:property).with(:content).returns(property)
+ it "should delegate writing to the content property" do
+ filehandle = stub_everything 'fh'
+ File.stubs(:open).yields(filehandle)
+ File.stubs(:rename)
+ property = stub('content_property', :actual_content => "something", :length => "something".length)
+ file = Puppet::Type::File.new(:name => "/my/file", :backup => "puppet")
+ file.stubs(:validate_checksum?).returns(false)
+ file.stubs(:property).with(:content).returns(property)
- property.expects(:write).with(filehandle)
+ property.expects(:write).with(filehandle)
- file.write(:content)
- end
+ file.write(:content)
+ end
- describe "when validating the checksum" do
- before { @file.stubs(:validate_checksum?).returns(true) }
+ describe "when validating the checksum" do
+ before { @file.stubs(:validate_checksum?).returns(true) }
- it "should fail if the checksum parameter and content checksums do not match" do
- checksum = stub('checksum_parameter', :sum => 'checksum_b')
- @file.stubs(:parameter).with(:checksum).returns(checksum)
+ it "should fail if the checksum parameter and content checksums do not match" do
+ checksum = stub('checksum_parameter', :sum => 'checksum_b')
+ @file.stubs(:parameter).with(:checksum).returns(checksum)
- property = stub('content_property', :actual_content => "something", :length => "something".length, :write => 'checksum_a')
- @file.stubs(:property).with(:content).returns(property)
+ property = stub('content_property', :actual_content => "something", :length => "something".length, :write => 'checksum_a')
+ @file.stubs(:property).with(:content).returns(property)
- lambda { @file.write :NOTUSED }.should raise_error(Puppet::Error)
- end
- end
+ lambda { @file.write :NOTUSED }.should raise_error(Puppet::Error)
+ end
+ end
- describe "when not validating the checksum" do
- before { @file.stubs(:validate_checksum?).returns(false) }
+ describe "when not validating the checksum" do
+ before { @file.stubs(:validate_checksum?).returns(false) }
- it "should not fail if the checksum property and content checksums do not match" do
- checksum = stub('checksum_parameter', :sum => 'checksum_b')
- @file.stubs(:parameter).with(:checksum).returns(checksum)
+ it "should not fail if the checksum property and content checksums do not match" do
+ checksum = stub('checksum_parameter', :sum => 'checksum_b')
+ @file.stubs(:parameter).with(:checksum).returns(checksum)
- property = stub('content_property', :actual_content => "something", :length => "something".length, :write => 'checksum_a')
- @file.stubs(:property).with(:content).returns(property)
+ property = stub('content_property', :actual_content => "something", :length => "something".length, :write => 'checksum_a')
+ @file.stubs(:property).with(:content).returns(property)
- lambda { @file.write :NOTUSED }.should_not raise_error(Puppet::Error)
- end
+ lambda { @file.write :NOTUSED }.should_not raise_error(Puppet::Error)
+ end
- end
end
-
- it "should have a method for determining if the file is present" do
- @file.must respond_to(:exist?)
+ end
+
+ it "should have a method for determining if the file is present" do
+ @file.must respond_to(:exist?)
+ end
+
+ it "should be considered existent if it can be stat'ed" do
+ @file.expects(:stat).returns mock('stat')
+ @file.must be_exist
+ end
+
+ it "should be considered nonexistent if it can not be stat'ed" do
+ @file.expects(:stat).returns nil
+ @file.must_not be_exist
+ end
+
+ it "should have a method for determining if the file should be a normal file" do
+ @file.must respond_to(:should_be_file?)
+ end
+
+ it "should be a file if :ensure is set to :file" do
+ @file[:ensure] = :file
+ @file.must be_should_be_file
+ end
+
+ it "should be a file if :ensure is set to :present and the file exists as a normal file" do
+ @file.stubs(:stat).returns(mock('stat', :ftype => "file"))
+ @file[:ensure] = :present
+ @file.must be_should_be_file
+ end
+
+ it "should not be a file if :ensure is set to something other than :file" do
+ @file[:ensure] = :directory
+ @file.must_not be_should_be_file
+ end
+
+ it "should not be a file if :ensure is set to :present and the file exists but is not a normal file" do
+ @file.stubs(:stat).returns(mock('stat', :ftype => "directory"))
+ @file[:ensure] = :present
+ @file.must_not be_should_be_file
+ end
+
+ it "should be a file if :ensure is not set and :content is" do
+ @file[:content] = "foo"
+ @file.must be_should_be_file
+ end
+
+ it "should be a file if neither :ensure nor :content is set but the file exists as a normal file" do
+ @file.stubs(:stat).returns(mock("stat", :ftype => "file"))
+ @file.must be_should_be_file
+ end
+
+ it "should not be a file if neither :ensure nor :content is set but the file exists but not as a normal file" do
+ @file.stubs(:stat).returns(mock("stat", :ftype => "directory"))
+ @file.must_not be_should_be_file
+ end
+
+ describe "when using POSIX filenames" do
+ describe "on POSIX systems" do
+ before do
+ Puppet.features.stubs(:posix?).returns(true)
+ Puppet.features.stubs(:microsoft_windows?).returns(false)
+ end
+
+ it "should autorequire its parent directory" do
+ file = Puppet::Type::File.new(:path => "/foo/bar")
+ dir = Puppet::Type::File.new(:path => "/foo")
+ @catalog.add_resource file
+ @catalog.add_resource dir
+ reqs = file.autorequire
+ reqs[0].source.must == dir
+ reqs[0].target.must == file
+ end
+
+ it "should not autorequire its parent dir if its parent dir is itself" do
+ file = Puppet::Type::File.new(:path => "/")
+ @catalog.add_resource file
+ file.autorequire.should be_empty
+ end
+
+ it "should remove trailing slashes" do
+ file = Puppet::Type::File.new(:path => "/foo/bar/baz/")
+ file[:path].should == "/foo/bar/baz"
+ end
+
+ it "should remove double slashes" do
+ file = Puppet::Type::File.new(:path => "/foo/bar//baz")
+ file[:path].should == "/foo/bar/baz"
+ end
+
+ it "should remove trailing double slashes" do
+ file = Puppet::Type::File.new(:path => "/foo/bar/baz//")
+ file[:path].should == "/foo/bar/baz"
+ end
+
+ it "should leave a single slash alone" do
+ file = Puppet::Type::File.new(:path => "/")
+ file[:path].should == "/"
+ end
end
- it "should be considered existent if it can be stat'ed" do
- @file.expects(:stat).returns mock('stat')
- @file.must be_exist
- end
+ describe "on Microsoft Windows systems" do
+ before do
+ Puppet.features.stubs(:posix?).returns(false)
+ Puppet.features.stubs(:microsoft_windows?).returns(true)
+ end
- it "should be considered nonexistent if it can not be stat'ed" do
- @file.expects(:stat).returns nil
- @file.must_not be_exist
+ it "should refuse to work" do
+ lambda { Puppet::Type::File.new(:path => "/foo/bar") }.should raise_error(Puppet::Error)
+ end
end
-
- it "should have a method for determining if the file should be a normal file" do
- @file.must respond_to(:should_be_file?)
+ end
+
+ describe "when using Microsoft Windows filenames" do
+ confine "Only works on Microsoft Windows" => Puppet.features.microsoft_windows?
+ describe "on Microsoft Windows systems" do
+ before do
+ Puppet.features.stubs(:posix?).returns(false)
+ Puppet.features.stubs(:microsoft_windows?).returns(true)
+ end
+
+ it "should autorequire its parent directory" do
+ file = Puppet::Type::File.new(:path => "X:/foo/bar")
+ dir = Puppet::Type::File.new(:path => "X:/foo")
+ @catalog.add_resource file
+ @catalog.add_resource dir
+ reqs = file.autorequire
+ reqs[0].source.must == dir
+ reqs[0].target.must == file
+ end
+
+ it "should not autorequire its parent dir if its parent dir is itself" do
+ file = Puppet::Type::File.new(:path => "X:/")
+ @catalog.add_resource file
+ file.autorequire.should be_empty
+ end
+
+ it "should remove trailing slashes" do
+ file = Puppet::Type::File.new(:path => "X:/foo/bar/baz/")
+ file[:path].should == "X:/foo/bar/baz"
+ end
+
+ it "should remove double slashes" do
+ file = Puppet::Type::File.new(:path => "X:/foo/bar//baz")
+ file[:path].should == "X:/foo/bar/baz"
+ end
+
+ it "should remove trailing double slashes" do
+ file = Puppet::Type::File.new(:path => "X:/foo/bar/baz//")
+ file[:path].should == "X:/foo/bar/baz"
+ end
+
+ it "should leave a drive letter with a slash alone" do
+ file = Puppet::Type::File.new(:path => "X:/")
+ file[:path].should == "X:/"
+ end
+
+ it "should add a slash to a drive letter" do
+ file = Puppet::Type::File.new(:path => "X:")
+ file[:path].should == "X:/"
+ end
end
- it "should be a file if :ensure is set to :file" do
- @file[:ensure] = :file
- @file.must be_should_be_file
- end
+ describe "on POSIX systems" do
+ before do
+ Puppet.features.stubs(:posix?).returns(true)
+ Puppet.features.stubs(:microsoft_windows?).returns(false)
+ end
- it "should be a file if :ensure is set to :present and the file exists as a normal file" do
- @file.stubs(:stat).returns(mock('stat', :ftype => "file"))
- @file[:ensure] = :present
- @file.must be_should_be_file
+ it "should refuse to work" do
+ lambda { Puppet::Type::File.new(:path => "X:/foo/bar") }.should raise_error(Puppet::Error)
+ end
end
-
- it "should not be a file if :ensure is set to something other than :file" do
- @file[:ensure] = :directory
- @file.must_not be_should_be_file
+ end
+
+ describe "when using UNC filenames" do
+ describe "on Microsoft Windows systems" do
+ confine "Only works on Microsoft Windows" => Puppet.features.microsoft_windows?
+ before do
+ Puppet.features.stubs(:posix?).returns(false)
+ Puppet.features.stubs(:microsoft_windows?).returns(true)
+ end
+
+ it "should autorequire its parent directory" do
+ file = Puppet::Type::File.new(:path => "//server/foo/bar")
+ dir = Puppet::Type::File.new(:path => "//server/foo")
+ @catalog.add_resource file
+ @catalog.add_resource dir
+ reqs = file.autorequire
+ reqs[0].source.must == dir
+ reqs[0].target.must == file
+ end
+
+ it "should not autorequire its parent dir if its parent dir is itself" do
+ file = Puppet::Type::File.new(:path => "//server/foo")
+ @catalog.add_resource file
+ puts file.autorequire
+ file.autorequire.should be_empty
+ end
+
+ it "should remove trailing slashes" do
+ file = Puppet::Type::File.new(:path => "//server/foo/bar/baz/")
+ file[:path].should == "//server/foo/bar/baz"
+ end
+
+ it "should remove double slashes" do
+ file = Puppet::Type::File.new(:path => "//server/foo/bar//baz")
+ file[:path].should == "//server/foo/bar/baz"
+ end
+
+ it "should remove trailing double slashes" do
+ file = Puppet::Type::File.new(:path => "//server/foo/bar/baz//")
+ file[:path].should == "//server/foo/bar/baz"
+ end
+
+ it "should remove a trailing slash from a sharename" do
+ file = Puppet::Type::File.new(:path => "//server/foo/")
+ file[:path].should == "//server/foo"
+ end
+
+ it "should not modify a sharename" do
+ file = Puppet::Type::File.new(:path => "//server/foo")
+ file[:path].should == "//server/foo"
+ end
end
- it "should not be a file if :ensure is set to :present and the file exists but is not a normal file" do
- @file.stubs(:stat).returns(mock('stat', :ftype => "directory"))
- @file[:ensure] = :present
- @file.must_not be_should_be_file
+ describe "on POSIX systems" do
+ before do
+ Puppet.features.stubs(:posix?).returns(true)
+ Puppet.features.stubs(:microsoft_windows?).returns(false)
+ end
+
+ it "should refuse to work" do
+ lambda { Puppet::Type::File.new(:path => "X:/foo/bar") }.should raise_error(Puppet::Error)
+ end
end
+ end
- it "should be a file if :ensure is not set and :content is" do
- @file[:content] = "foo"
- @file.must be_should_be_file
+ describe "when initializing" do
+ it "should set a desired 'ensure' value if none is set and 'content' is set" do
+ file = Puppet::Type::File.new(:name => "/my/file", :content => "/foo/bar")
+ file[:ensure].should == :file
end
- it "should be a file if neither :ensure nor :content is set but the file exists as a normal file" do
- @file.stubs(:stat).returns(mock("stat", :ftype => "file"))
- @file.must be_should_be_file
+ it "should set a desired 'ensure' value if none is set and 'target' is set" do
+ file = Puppet::Type::File.new(:name => "/my/file", :target => "/foo/bar")
+ file[:ensure].should == :symlink
end
+ end
- it "should not be a file if neither :ensure nor :content is set but the file exists but not as a normal file" do
- @file.stubs(:stat).returns(mock("stat", :ftype => "directory"))
- @file.must_not be_should_be_file
+ describe "when validating attributes" do
+ %w{path checksum backup recurse recurselimit source replace force ignore links purge sourceselect}.each do |attr|
+ it "should have a '#{attr}' parameter" do
+ Puppet::Type.type(:file).attrtype(attr.intern).should == :param
+ end
end
- describe "when using POSIX filenames" do
- describe "on POSIX systems" do
- before do
- Puppet.features.stubs(:posix?).returns(true)
- Puppet.features.stubs(:microsoft_windows?).returns(false)
- end
+ %w{content target ensure owner group mode type}.each do |attr|
+ it "should have a '#{attr}' property" do
+ Puppet::Type.type(:file).attrtype(attr.intern).should == :property
+ end
+ end
- it "should autorequire its parent directory" do
- file = Puppet::Type::File.new(:path => "/foo/bar")
- dir = Puppet::Type::File.new(:path => "/foo")
- @catalog.add_resource file
- @catalog.add_resource dir
- reqs = file.autorequire
- reqs[0].source.must == dir
- reqs[0].target.must == file
- end
+ it "should have its 'path' attribute set as its namevar" do
+ Puppet::Type.type(:file).key_attributes.should == [:path]
+ end
+ end
- it "should not autorequire its parent dir if its parent dir is itself" do
- file = Puppet::Type::File.new(:path => "/")
- @catalog.add_resource file
- file.autorequire.should be_empty
- end
+ describe "when managing links" do
+ require 'puppettest/support/assertions'
+ include PuppetTest
+ require 'tempfile'
- it "should remove trailing slashes" do
- file = Puppet::Type::File.new(:path => "/foo/bar/baz/")
- file[:path].should == "/foo/bar/baz"
- end
+ if @real_posix
+ describe "on POSIX systems" do
+ before do
+ @basedir = tempfile
+ Dir.mkdir(@basedir)
+ @file = File.join(@basedir, "file")
+ @link = File.join(@basedir, "link")
- it "should remove double slashes" do
- file = Puppet::Type::File.new(:path => "/foo/bar//baz")
- file[:path].should == "/foo/bar/baz"
- end
+ File.open(@file, "w", 0644) { |f| f.puts "yayness"; f.flush }
+ File.symlink(@file, @link)
- it "should remove trailing double slashes" do
- file = Puppet::Type::File.new(:path => "/foo/bar/baz//")
- file[:path].should == "/foo/bar/baz"
- end
- it "should leave a single slash alone" do
- file = Puppet::Type::File.new(:path => "/")
- file[:path].should == "/"
- end
+ @resource = Puppet::Type.type(:file).new(
+
+ :path => @link,
+
+ :mode => "755"
+ )
+ @catalog.add_resource @resource
end
- describe "on Microsoft Windows systems" do
- before do
- Puppet.features.stubs(:posix?).returns(false)
- Puppet.features.stubs(:microsoft_windows?).returns(true)
- end
-
- it "should refuse to work" do
- lambda { Puppet::Type::File.new(:path => "/foo/bar") }.should raise_error(Puppet::Error)
- end
+ after do
+ remove_tmp_files
end
- end
- describe "when using Microsoft Windows filenames" do
- confine "Only works on Microsoft Windows" => Puppet.features.microsoft_windows?
- describe "on Microsoft Windows systems" do
- before do
- Puppet.features.stubs(:posix?).returns(false)
- Puppet.features.stubs(:microsoft_windows?).returns(true)
- end
-
- it "should autorequire its parent directory" do
- file = Puppet::Type::File.new(:path => "X:/foo/bar")
- dir = Puppet::Type::File.new(:path => "X:/foo")
- @catalog.add_resource file
- @catalog.add_resource dir
- reqs = file.autorequire
- reqs[0].source.must == dir
- reqs[0].target.must == file
- end
-
- it "should not autorequire its parent dir if its parent dir is itself" do
- file = Puppet::Type::File.new(:path => "X:/")
- @catalog.add_resource file
- file.autorequire.should be_empty
- end
-
- it "should remove trailing slashes" do
- file = Puppet::Type::File.new(:path => "X:/foo/bar/baz/")
- file[:path].should == "X:/foo/bar/baz"
- end
-
- it "should remove double slashes" do
- file = Puppet::Type::File.new(:path => "X:/foo/bar//baz")
- file[:path].should == "X:/foo/bar/baz"
- end
-
- it "should remove trailing double slashes" do
- file = Puppet::Type::File.new(:path => "X:/foo/bar/baz//")
- file[:path].should == "X:/foo/bar/baz"
- end
-
- it "should leave a drive letter with a slash alone" do
- file = Puppet::Type::File.new(:path => "X:/")
- file[:path].should == "X:/"
- end
-
- it "should add a slash to a drive letter" do
- file = Puppet::Type::File.new(:path => "X:")
- file[:path].should == "X:/"
- end
+ it "should default to managing the link" do
+ @catalog.apply
+ # I convert them to strings so they display correctly if there's an error.
+ ("%o" % (File.stat(@file).mode & 007777)).should == "%o" % 0644
end
- describe "on POSIX systems" do
- before do
- Puppet.features.stubs(:posix?).returns(true)
- Puppet.features.stubs(:microsoft_windows?).returns(false)
- end
+ it "should be able to follow links" do
+ @resource[:links] = :follow
+ @catalog.apply
- it "should refuse to work" do
- lambda { Puppet::Type::File.new(:path => "X:/foo/bar") }.should raise_error(Puppet::Error)
- end
+ ("%o" % (File.stat(@file).mode & 007777)).should == "%o" % 0755
end
+ end
+ else # @real_posix
+ # should recode tests using expectations instead of using the filesystem
end
- describe "when using UNC filenames" do
- describe "on Microsoft Windows systems" do
- confine "Only works on Microsoft Windows" => Puppet.features.microsoft_windows?
- before do
- Puppet.features.stubs(:posix?).returns(false)
- Puppet.features.stubs(:microsoft_windows?).returns(true)
- end
-
- it "should autorequire its parent directory" do
- file = Puppet::Type::File.new(:path => "//server/foo/bar")
- dir = Puppet::Type::File.new(:path => "//server/foo")
- @catalog.add_resource file
- @catalog.add_resource dir
- reqs = file.autorequire
- reqs[0].source.must == dir
- reqs[0].target.must == file
- end
-
- it "should not autorequire its parent dir if its parent dir is itself" do
- file = Puppet::Type::File.new(:path => "//server/foo")
- @catalog.add_resource file
- puts file.autorequire
- file.autorequire.should be_empty
- end
-
- it "should remove trailing slashes" do
- file = Puppet::Type::File.new(:path => "//server/foo/bar/baz/")
- file[:path].should == "//server/foo/bar/baz"
- end
-
- it "should remove double slashes" do
- file = Puppet::Type::File.new(:path => "//server/foo/bar//baz")
- file[:path].should == "//server/foo/bar/baz"
- end
-
- it "should remove trailing double slashes" do
- file = Puppet::Type::File.new(:path => "//server/foo/bar/baz//")
- file[:path].should == "//server/foo/bar/baz"
- end
-
- it "should remove a trailing slash from a sharename" do
- file = Puppet::Type::File.new(:path => "//server/foo/")
- file[:path].should == "//server/foo"
- end
-
- it "should not modify a sharename" do
- file = Puppet::Type::File.new(:path => "//server/foo")
- file[:path].should == "//server/foo"
- end
- end
-
- describe "on POSIX systems" do
- before do
- Puppet.features.stubs(:posix?).returns(true)
- Puppet.features.stubs(:microsoft_windows?).returns(false)
- end
+ describe "on Microsoft Windows systems" do
+ before do
+ Puppet.features.stubs(:posix?).returns(false)
+ Puppet.features.stubs(:microsoft_windows?).returns(true)
+ end
- it "should refuse to work" do
- lambda { Puppet::Type::File.new(:path => "X:/foo/bar") }.should raise_error(Puppet::Error)
- end
- end
+ it "should refuse to work with links"
end
+ end
- describe "when initializing" do
- it "should set a desired 'ensure' value if none is set and 'content' is set" do
- file = Puppet::Type::File.new(:name => "/my/file", :content => "/foo/bar")
- file[:ensure].should == :file
- end
+ it "should be able to retrieve a stat instance for the file it is managing" do
+ Puppet::Type.type(:file).new(:path => "/foo/bar", :source => "/bar/foo").should respond_to(:stat)
+ end
- it "should set a desired 'ensure' value if none is set and 'target' is set" do
- file = Puppet::Type::File.new(:name => "/my/file", :target => "/foo/bar")
- file[:ensure].should == :symlink
- end
+ describe "when stat'ing its file" do
+ before do
+ @resource = Puppet::Type.type(:file).new(:path => "/foo/bar")
+ @resource[:links] = :manage # so we always use :lstat
end
- describe "when validating attributes" do
- %w{path checksum backup recurse recurselimit source replace force ignore links purge sourceselect}.each do |attr|
- it "should have a '#{attr}' parameter" do
- Puppet::Type.type(:file).attrtype(attr.intern).should == :param
- end
- end
+ it "should use :stat if it is following links" do
+ @resource[:links] = :follow
+ File.expects(:stat)
- %w{content target ensure owner group mode type}.each do |attr|
- it "should have a '#{attr}' property" do
- Puppet::Type.type(:file).attrtype(attr.intern).should == :property
- end
- end
-
- it "should have its 'path' attribute set as its namevar" do
- Puppet::Type.type(:file).key_attributes.should == [:path]
- end
+ @resource.stat
end
- describe "when managing links" do
- require 'puppettest/support/assertions'
- include PuppetTest
- require 'tempfile'
-
- if @real_posix
- describe "on POSIX systems" do
- before do
- @basedir = tempfile
- Dir.mkdir(@basedir)
- @file = File.join(@basedir, "file")
- @link = File.join(@basedir, "link")
+ it "should use :lstat if is it not following links" do
+ @resource[:links] = :manage
+ File.expects(:lstat)
- File.open(@file, "w", 0644) { |f| f.puts "yayness"; f.flush }
- File.symlink(@file, @link)
-
-
- @resource = Puppet::Type.type(:file).new(
-
- :path => @link,
-
- :mode => "755"
- )
- @catalog.add_resource @resource
- end
-
- after do
- remove_tmp_files
- end
-
- it "should default to managing the link" do
- @catalog.apply
- # I convert them to strings so they display correctly if there's an error.
- ("%o" % (File.stat(@file).mode & 007777)).should == "%o" % 0644
- end
-
- it "should be able to follow links" do
- @resource[:links] = :follow
- @catalog.apply
-
- ("%o" % (File.stat(@file).mode & 007777)).should == "%o" % 0755
- end
- end
- else # @real_posix
- # should recode tests using expectations instead of using the filesystem
- end
-
- describe "on Microsoft Windows systems" do
- before do
- Puppet.features.stubs(:posix?).returns(false)
- Puppet.features.stubs(:microsoft_windows?).returns(true)
- end
-
- it "should refuse to work with links"
- end
+ @resource.stat
end
- it "should be able to retrieve a stat instance for the file it is managing" do
- Puppet::Type.type(:file).new(:path => "/foo/bar", :source => "/bar/foo").should respond_to(:stat)
+ it "should stat the path of the file" do
+ File.expects(:lstat).with("/foo/bar")
+
+ @resource.stat
end
- describe "when stat'ing its file" do
- before do
- @resource = Puppet::Type.type(:file).new(:path => "/foo/bar")
- @resource[:links] = :manage # so we always use :lstat
- end
+ # This only happens in testing.
+ it "should return nil if the stat does not exist" do
+ File.expects(:lstat).returns nil
- it "should use :stat if it is following links" do
- @resource[:links] = :follow
- File.expects(:stat)
+ @resource.stat.should be_nil
+ end
- @resource.stat
- end
+ it "should return nil if the file does not exist" do
+ File.expects(:lstat).raises(Errno::ENOENT)
- it "should use :lstat if is it not following links" do
- @resource[:links] = :manage
- File.expects(:lstat)
+ @resource.stat.should be_nil
+ end
- @resource.stat
- end
+ it "should return nil if the file cannot be stat'ed" do
+ File.expects(:lstat).raises(Errno::EACCES)
- it "should stat the path of the file" do
- File.expects(:lstat).with("/foo/bar")
+ @resource.stat.should be_nil
+ end
- @resource.stat
- end
+ it "should return the stat instance" do
+ File.expects(:lstat).returns "mystat"
- # This only happens in testing.
- it "should return nil if the stat does not exist" do
- File.expects(:lstat).returns nil
+ @resource.stat.should == "mystat"
+ end
- @resource.stat.should be_nil
- end
+ it "should cache the stat instance if it has a catalog and is applying" do
+ stat = mock 'stat'
+ File.expects(:lstat).returns stat
- it "should return nil if the file does not exist" do
- File.expects(:lstat).raises(Errno::ENOENT)
+ catalog = Puppet::Resource::Catalog.new
+ @resource.catalog = catalog
- @resource.stat.should be_nil
- end
+ catalog.stubs(:applying?).returns true
- it "should return nil if the file cannot be stat'ed" do
- File.expects(:lstat).raises(Errno::EACCES)
+ @resource.stat.should equal(@resource.stat)
+ end
+ end
- @resource.stat.should be_nil
- end
+ describe "when flushing" do
+ it "should flush all properties that respond to :flush" do
+ @resource = Puppet::Type.type(:file).new(:path => "/foo/bar", :source => "/bar/foo")
+ @resource.parameter(:source).expects(:flush)
+ @resource.flush
+ end
- it "should return the stat instance" do
- File.expects(:lstat).returns "mystat"
+ it "should reset its stat reference" do
+ @resource = Puppet::Type.type(:file).new(:path => "/foo/bar")
+ File.expects(:lstat).times(2).returns("stat1").then.returns("stat2")
+ @resource.stat.should == "stat1"
+ @resource.flush
+ @resource.stat.should == "stat2"
+ end
+ end
- @resource.stat.should == "mystat"
- end
+ it "should have a method for performing recursion" do
+ @file.must respond_to(:perform_recursion)
+ end
- it "should cache the stat instance if it has a catalog and is applying" do
- stat = mock 'stat'
- File.expects(:lstat).returns stat
+ describe "when executing a recursive search" do
+ it "should use Metadata to do its recursion" do
+ Puppet::FileServing::Metadata.expects(:search)
+ @file.perform_recursion(@file[:path])
+ end
- catalog = Puppet::Resource::Catalog.new
- @resource.catalog = catalog
+ it "should use the provided path as the key to the search" do
+ Puppet::FileServing::Metadata.expects(:search).with { |key, options| key == "/foo" }
+ @file.perform_recursion("/foo")
+ end
- catalog.stubs(:applying?).returns true
+ it "should return the results of the metadata search" do
+ Puppet::FileServing::Metadata.expects(:search).returns "foobar"
+ @file.perform_recursion(@file[:path]).should == "foobar"
+ end
- @resource.stat.should equal(@resource.stat)
- end
+ it "should pass its recursion value to the search" do
+ @file[:recurse] = true
+ Puppet::FileServing::Metadata.expects(:search).with { |key, options| options[:recurse] == true }
+ @file.perform_recursion(@file[:path])
end
- describe "when flushing" do
- it "should flush all properties that respond to :flush" do
- @resource = Puppet::Type.type(:file).new(:path => "/foo/bar", :source => "/bar/foo")
- @resource.parameter(:source).expects(:flush)
- @resource.flush
- end
+ it "should pass true if recursion is remote" do
+ @file[:recurse] = :remote
+ Puppet::FileServing::Metadata.expects(:search).with { |key, options| options[:recurse] == true }
+ @file.perform_recursion(@file[:path])
+ end
- it "should reset its stat reference" do
- @resource = Puppet::Type.type(:file).new(:path => "/foo/bar")
- File.expects(:lstat).times(2).returns("stat1").then.returns("stat2")
- @resource.stat.should == "stat1"
- @resource.flush
- @resource.stat.should == "stat2"
- end
+ it "should pass its recursion limit value to the search" do
+ @file[:recurselimit] = 10
+ Puppet::FileServing::Metadata.expects(:search).with { |key, options| options[:recurselimit] == 10 }
+ @file.perform_recursion(@file[:path])
end
- it "should have a method for performing recursion" do
- @file.must respond_to(:perform_recursion)
+ it "should configure the search to ignore or manage links" do
+ @file[:links] = :manage
+ Puppet::FileServing::Metadata.expects(:search).with { |key, options| options[:links] == :manage }
+ @file.perform_recursion(@file[:path])
end
- describe "when executing a recursive search" do
- it "should use Metadata to do its recursion" do
- Puppet::FileServing::Metadata.expects(:search)
- @file.perform_recursion(@file[:path])
- end
+ it "should pass its 'ignore' setting to the search if it has one" do
+ @file[:ignore] = %w{.svn CVS}
+ Puppet::FileServing::Metadata.expects(:search).with { |key, options| options[:ignore] == %w{.svn CVS} }
+ @file.perform_recursion(@file[:path])
+ end
+ end
- it "should use the provided path as the key to the search" do
- Puppet::FileServing::Metadata.expects(:search).with { |key, options| key == "/foo" }
- @file.perform_recursion("/foo")
- end
+ it "should have a method for performing local recursion" do
+ @file.must respond_to(:recurse_local)
+ end
- it "should return the results of the metadata search" do
- Puppet::FileServing::Metadata.expects(:search).returns "foobar"
- @file.perform_recursion(@file[:path]).should == "foobar"
- end
+ describe "when doing local recursion" do
+ before do
+ @metadata = stub 'metadata', :relative_path => "my/file"
+ end
- it "should pass its recursion value to the search" do
- @file[:recurse] = true
- Puppet::FileServing::Metadata.expects(:search).with { |key, options| options[:recurse] == true }
- @file.perform_recursion(@file[:path])
- end
+ it "should pass its path to the :perform_recursion method" do
+ @file.expects(:perform_recursion).with(@file[:path]).returns [@metadata]
+ @file.stubs(:newchild)
+ @file.recurse_local
+ end
- it "should pass true if recursion is remote" do
- @file[:recurse] = :remote
- Puppet::FileServing::Metadata.expects(:search).with { |key, options| options[:recurse] == true }
- @file.perform_recursion(@file[:path])
- end
+ it "should return an empty hash if the recursion returns nothing" do
+ @file.expects(:perform_recursion).returns nil
+ @file.recurse_local.should == {}
+ end
- it "should pass its recursion limit value to the search" do
- @file[:recurselimit] = 10
- Puppet::FileServing::Metadata.expects(:search).with { |key, options| options[:recurselimit] == 10 }
- @file.perform_recursion(@file[:path])
- end
+ it "should create a new child resource with each generated metadata instance's relative path" do
+ @file.expects(:perform_recursion).returns [@metadata]
+ @file.expects(:newchild).with(@metadata.relative_path).returns "fiebar"
+ @file.recurse_local
+ end
- it "should configure the search to ignore or manage links" do
- @file[:links] = :manage
- Puppet::FileServing::Metadata.expects(:search).with { |key, options| options[:links] == :manage }
- @file.perform_recursion(@file[:path])
- end
+ it "should not create a new child resource for the '.' directory" do
+ @metadata.stubs(:relative_path).returns "."
- it "should pass its 'ignore' setting to the search if it has one" do
- @file[:ignore] = %w{.svn CVS}
- Puppet::FileServing::Metadata.expects(:search).with { |key, options| options[:ignore] == %w{.svn CVS} }
- @file.perform_recursion(@file[:path])
- end
+ @file.expects(:perform_recursion).returns [@metadata]
+ @file.expects(:newchild).never
+ @file.recurse_local
end
- it "should have a method for performing local recursion" do
- @file.must respond_to(:recurse_local)
+ it "should return a hash of the created resources with the relative paths as the hash keys" do
+ @file.expects(:perform_recursion).returns [@metadata]
+ @file.expects(:newchild).with("my/file").returns "fiebar"
+ @file.recurse_local.should == {"my/file" => "fiebar"}
end
- describe "when doing local recursion" do
- before do
- @metadata = stub 'metadata', :relative_path => "my/file"
- end
-
- it "should pass its path to the :perform_recursion method" do
- @file.expects(:perform_recursion).with(@file[:path]).returns [@metadata]
- @file.stubs(:newchild)
- @file.recurse_local
- end
+ it "should set checksum_type to none if this file checksum is none" do
+ @file[:checksum] = :none
+ Puppet::FileServing::Metadata.expects(:search).with { |path,params| params[:checksum_type] == :none }.returns [@metadata]
+ @file.expects(:newchild).with("my/file").returns "fiebar"
+ @file.recurse_local
+ end
+ end
- it "should return an empty hash if the recursion returns nothing" do
- @file.expects(:perform_recursion).returns nil
- @file.recurse_local.should == {}
- end
+ it "should have a method for performing link recursion" do
+ @file.must respond_to(:recurse_link)
+ end
- it "should create a new child resource with each generated metadata instance's relative path" do
- @file.expects(:perform_recursion).returns [@metadata]
- @file.expects(:newchild).with(@metadata.relative_path).returns "fiebar"
- @file.recurse_local
- end
+ describe "when doing link recursion" do
+ before do
+ @first = stub 'first', :relative_path => "first", :full_path => "/my/first", :ftype => "directory"
+ @second = stub 'second', :relative_path => "second", :full_path => "/my/second", :ftype => "file"
- it "should not create a new child resource for the '.' directory" do
- @metadata.stubs(:relative_path).returns "."
+ @resource = stub 'file', :[]= => nil
+ end
- @file.expects(:perform_recursion).returns [@metadata]
- @file.expects(:newchild).never
- @file.recurse_local
- end
+ it "should pass its target to the :perform_recursion method" do
+ @file[:target] = "mylinks"
+ @file.expects(:perform_recursion).with("mylinks").returns [@first]
+ @file.stubs(:newchild).returns @resource
+ @file.recurse_link({})
+ end
- it "should return a hash of the created resources with the relative paths as the hash keys" do
- @file.expects(:perform_recursion).returns [@metadata]
- @file.expects(:newchild).with("my/file").returns "fiebar"
- @file.recurse_local.should == {"my/file" => "fiebar"}
- end
+ it "should ignore the recursively-found '.' file and configure the top-level file to create a directory" do
+ @first.stubs(:relative_path).returns "."
+ @file[:target] = "mylinks"
+ @file.expects(:perform_recursion).with("mylinks").returns [@first]
+ @file.stubs(:newchild).never
+ @file.expects(:[]=).with(:ensure, :directory)
+ @file.recurse_link({})
+ end
- it "should set checksum_type to none if this file checksum is none" do
- @file[:checksum] = :none
- Puppet::FileServing::Metadata.expects(:search).with { |path,params| params[:checksum_type] == :none }.returns [@metadata]
- @file.expects(:newchild).with("my/file").returns "fiebar"
- @file.recurse_local
- end
+ it "should create a new child resource for each generated metadata instance's relative path that doesn't already exist in the children hash" do
+ @file.expects(:perform_recursion).returns [@first, @second]
+ @file.expects(:newchild).with(@first.relative_path).returns @resource
+ @file.recurse_link("second" => @resource)
end
- it "should have a method for performing link recursion" do
- @file.must respond_to(:recurse_link)
+ it "should not create a new child resource for paths that already exist in the children hash" do
+ @file.expects(:perform_recursion).returns [@first]
+ @file.expects(:newchild).never
+ @file.recurse_link("first" => @resource)
end
- describe "when doing link recursion" do
- before do
- @first = stub 'first', :relative_path => "first", :full_path => "/my/first", :ftype => "directory"
- @second = stub 'second', :relative_path => "second", :full_path => "/my/second", :ftype => "file"
+ it "should set the target to the full path of discovered file and set :ensure to :link if the file is not a directory" do
+ file = stub 'file'
+ file.expects(:[]=).with(:target, "/my/second")
+ file.expects(:[]=).with(:ensure, :link)
- @resource = stub 'file', :[]= => nil
- end
+ @file.stubs(:perform_recursion).returns [@first, @second]
+ @file.recurse_link("first" => @resource, "second" => file)
+ end
- it "should pass its target to the :perform_recursion method" do
- @file[:target] = "mylinks"
- @file.expects(:perform_recursion).with("mylinks").returns [@first]
- @file.stubs(:newchild).returns @resource
- @file.recurse_link({})
- end
+ it "should :ensure to :directory if the file is a directory" do
+ file = stub 'file'
+ file.expects(:[]=).with(:ensure, :directory)
- it "should ignore the recursively-found '.' file and configure the top-level file to create a directory" do
- @first.stubs(:relative_path).returns "."
- @file[:target] = "mylinks"
- @file.expects(:perform_recursion).with("mylinks").returns [@first]
- @file.stubs(:newchild).never
- @file.expects(:[]=).with(:ensure, :directory)
- @file.recurse_link({})
- end
+ @file.stubs(:perform_recursion).returns [@first, @second]
+ @file.recurse_link("first" => file, "second" => @resource)
+ end
- it "should create a new child resource for each generated metadata instance's relative path that doesn't already exist in the children hash" do
- @file.expects(:perform_recursion).returns [@first, @second]
- @file.expects(:newchild).with(@first.relative_path).returns @resource
- @file.recurse_link("second" => @resource)
- end
+ it "should return a hash with both created and existing resources with the relative paths as the hash keys" do
+ file = stub 'file', :[]= => nil
- it "should not create a new child resource for paths that already exist in the children hash" do
- @file.expects(:perform_recursion).returns [@first]
- @file.expects(:newchild).never
- @file.recurse_link("first" => @resource)
- end
+ @file.expects(:perform_recursion).returns [@first, @second]
+ @file.stubs(:newchild).returns file
+ @file.recurse_link("second" => @resource).should == {"second" => @resource, "first" => file}
+ end
+ end
- it "should set the target to the full path of discovered file and set :ensure to :link if the file is not a directory" do
- file = stub 'file'
- file.expects(:[]=).with(:target, "/my/second")
- file.expects(:[]=).with(:ensure, :link)
+ it "should have a method for performing remote recursion" do
+ @file.must respond_to(:recurse_remote)
+ end
- @file.stubs(:perform_recursion).returns [@first, @second]
- @file.recurse_link("first" => @resource, "second" => file)
- end
+ describe "when doing remote recursion" do
+ before do
+ @file[:source] = "puppet://foo/bar"
- it "should :ensure to :directory if the file is a directory" do
- file = stub 'file'
- file.expects(:[]=).with(:ensure, :directory)
+ @first = Puppet::FileServing::Metadata.new("/my", :relative_path => "first")
+ @second = Puppet::FileServing::Metadata.new("/my", :relative_path => "second")
+ @first.stubs(:ftype).returns "directory"
+ @second.stubs(:ftype).returns "directory"
- @file.stubs(:perform_recursion).returns [@first, @second]
- @file.recurse_link("first" => file, "second" => @resource)
- end
+ @parameter = stub 'property', :metadata= => nil
+ @resource = stub 'file', :[]= => nil, :parameter => @parameter
+ end
- it "should return a hash with both created and existing resources with the relative paths as the hash keys" do
- file = stub 'file', :[]= => nil
+ it "should pass its source to the :perform_recursion method" do
+ data = Puppet::FileServing::Metadata.new("/whatever", :relative_path => "foobar")
+ @file.expects(:perform_recursion).with("puppet://foo/bar").returns [data]
+ @file.stubs(:newchild).returns @resource
+ @file.recurse_remote({})
+ end
- @file.expects(:perform_recursion).returns [@first, @second]
- @file.stubs(:newchild).returns file
- @file.recurse_link("second" => @resource).should == {"second" => @resource, "first" => file}
- end
+ it "should not recurse when the remote file is not a directory" do
+ data = Puppet::FileServing::Metadata.new("/whatever", :relative_path => ".")
+ data.stubs(:ftype).returns "file"
+ @file.expects(:perform_recursion).with("puppet://foo/bar").returns [data]
+ @file.expects(:newchild).never
+ @file.recurse_remote({})
end
- it "should have a method for performing remote recursion" do
- @file.must respond_to(:recurse_remote)
+ it "should set the source of each returned file to the searched-for URI plus the found relative path" do
+ @first.expects(:source=).with File.join("puppet://foo/bar", @first.relative_path)
+ @file.expects(:perform_recursion).returns [@first]
+ @file.stubs(:newchild).returns @resource
+ @file.recurse_remote({})
end
- describe "when doing remote recursion" do
- before do
- @file[:source] = "puppet://foo/bar"
+ it "should create a new resource for any relative file paths that do not already have a resource" do
+ @file.stubs(:perform_recursion).returns [@first]
+ @file.expects(:newchild).with("first").returns @resource
+ @file.recurse_remote({}).should == {"first" => @resource}
+ end
- @first = Puppet::FileServing::Metadata.new("/my", :relative_path => "first")
- @second = Puppet::FileServing::Metadata.new("/my", :relative_path => "second")
- @first.stubs(:ftype).returns "directory"
- @second.stubs(:ftype).returns "directory"
+ it "should not create a new resource for any relative file paths that do already have a resource" do
+ @file.stubs(:perform_recursion).returns [@first]
+ @file.expects(:newchild).never
+ @file.recurse_remote("first" => @resource)
+ end
- @parameter = stub 'property', :metadata= => nil
- @resource = stub 'file', :[]= => nil, :parameter => @parameter
- end
+ it "should set the source of each resource to the source of the metadata" do
+ @file.stubs(:perform_recursion).returns [@first]
+ @resource.stubs(:[]=)
+ @resource.expects(:[]=).with(:source, File.join("puppet://foo/bar", @first.relative_path))
+ @file.recurse_remote("first" => @resource)
+ end
- it "should pass its source to the :perform_recursion method" do
- data = Puppet::FileServing::Metadata.new("/whatever", :relative_path => "foobar")
- @file.expects(:perform_recursion).with("puppet://foo/bar").returns [data]
- @file.stubs(:newchild).returns @resource
- @file.recurse_remote({})
- end
+ # LAK:FIXME This is a bug, but I can't think of a fix for it. Fortunately it's already
+ # filed, and when it's fixed, we'll just fix the whole flow.
+ it "should set the checksum type to :md5 if the remote file is a file" do
+ @first.stubs(:ftype).returns "file"
+ @file.stubs(:perform_recursion).returns [@first]
+ @resource.stubs(:[]=)
+ @resource.expects(:[]=).with(:checksum, :md5)
+ @file.recurse_remote("first" => @resource)
+ end
- it "should not recurse when the remote file is not a directory" do
- data = Puppet::FileServing::Metadata.new("/whatever", :relative_path => ".")
- data.stubs(:ftype).returns "file"
- @file.expects(:perform_recursion).with("puppet://foo/bar").returns [data]
- @file.expects(:newchild).never
- @file.recurse_remote({})
- end
+ it "should store the metadata in the source property for each resource so the source does not have to requery the metadata" do
+ @file.stubs(:perform_recursion).returns [@first]
+ @resource.expects(:parameter).with(:source).returns @parameter
- it "should set the source of each returned file to the searched-for URI plus the found relative path" do
- @first.expects(:source=).with File.join("puppet://foo/bar", @first.relative_path)
- @file.expects(:perform_recursion).returns [@first]
- @file.stubs(:newchild).returns @resource
- @file.recurse_remote({})
- end
+ @parameter.expects(:metadata=).with(@first)
- it "should create a new resource for any relative file paths that do not already have a resource" do
- @file.stubs(:perform_recursion).returns [@first]
- @file.expects(:newchild).with("first").returns @resource
- @file.recurse_remote({}).should == {"first" => @resource}
- end
+ @file.recurse_remote("first" => @resource)
+ end
- it "should not create a new resource for any relative file paths that do already have a resource" do
- @file.stubs(:perform_recursion).returns [@first]
- @file.expects(:newchild).never
- @file.recurse_remote("first" => @resource)
- end
+ it "should not create a new resource for the '.' file" do
+ @first.stubs(:relative_path).returns "."
+ @file.stubs(:perform_recursion).returns [@first]
- it "should set the source of each resource to the source of the metadata" do
- @file.stubs(:perform_recursion).returns [@first]
- @resource.stubs(:[]=)
- @resource.expects(:[]=).with(:source, File.join("puppet://foo/bar", @first.relative_path))
- @file.recurse_remote("first" => @resource)
- end
+ @file.expects(:newchild).never
- # LAK:FIXME This is a bug, but I can't think of a fix for it. Fortunately it's already
- # filed, and when it's fixed, we'll just fix the whole flow.
- it "should set the checksum type to :md5 if the remote file is a file" do
- @first.stubs(:ftype).returns "file"
- @file.stubs(:perform_recursion).returns [@first]
- @resource.stubs(:[]=)
- @resource.expects(:[]=).with(:checksum, :md5)
- @file.recurse_remote("first" => @resource)
- end
+ @file.recurse_remote({})
+ end
- it "should store the metadata in the source property for each resource so the source does not have to requery the metadata" do
- @file.stubs(:perform_recursion).returns [@first]
- @resource.expects(:parameter).with(:source).returns @parameter
+ it "should store the metadata in the main file's source property if the relative path is '.'" do
+ @first.stubs(:relative_path).returns "."
+ @file.stubs(:perform_recursion).returns [@first]
- @parameter.expects(:metadata=).with(@first)
+ @file.parameter(:source).expects(:metadata=).with @first
- @file.recurse_remote("first" => @resource)
- end
+ @file.recurse_remote("first" => @resource)
+ end
- it "should not create a new resource for the '.' file" do
- @first.stubs(:relative_path).returns "."
- @file.stubs(:perform_recursion).returns [@first]
+ describe "and multiple sources are provided" do
+ describe "and :sourceselect is set to :first" do
+ it "should create file instances for the results for the first source to return any values" do
+ data = Puppet::FileServing::Metadata.new("/whatever", :relative_path => "foobar")
+ @file[:source] = %w{/one /two /three /four}
+ @file.expects(:perform_recursion).with("/one").returns nil
+ @file.expects(:perform_recursion).with("/two").returns []
+ @file.expects(:perform_recursion).with("/three").returns [data]
+ @file.expects(:perform_recursion).with("/four").never
+ @file.expects(:newchild).with("foobar").returns @resource
+ @file.recurse_remote({})
+ end
+ end
+
+ describe "and :sourceselect is set to :all" do
+ before do
+ @file[:sourceselect] = :all
+ end
- @file.expects(:newchild).never
+ it "should return every found file that is not in a previous source" do
+ klass = Puppet::FileServing::Metadata
+ @file[:source] = %w{/one /two /three /four}
+ @file.stubs(:newchild).returns @resource
- @file.recurse_remote({})
- end
+ one = [klass.new("/one", :relative_path => "a")]
+ @file.expects(:perform_recursion).with("/one").returns one
+ @file.expects(:newchild).with("a").returns @resource
- it "should store the metadata in the main file's source property if the relative path is '.'" do
- @first.stubs(:relative_path).returns "."
- @file.stubs(:perform_recursion).returns [@first]
+ two = [klass.new("/two", :relative_path => "a"), klass.new("/two", :relative_path => "b")]
+ @file.expects(:perform_recursion).with("/two").returns two
+ @file.expects(:newchild).with("b").returns @resource
- @file.parameter(:source).expects(:metadata=).with @first
+ three = [klass.new("/three", :relative_path => "a"), klass.new("/three", :relative_path => "c")]
+ @file.expects(:perform_recursion).with("/three").returns three
+ @file.expects(:newchild).with("c").returns @resource
- @file.recurse_remote("first" => @resource)
- end
+ @file.expects(:perform_recursion).with("/four").returns []
- describe "and multiple sources are provided" do
- describe "and :sourceselect is set to :first" do
- it "should create file instances for the results for the first source to return any values" do
- data = Puppet::FileServing::Metadata.new("/whatever", :relative_path => "foobar")
- @file[:source] = %w{/one /two /three /four}
- @file.expects(:perform_recursion).with("/one").returns nil
- @file.expects(:perform_recursion).with("/two").returns []
- @file.expects(:perform_recursion).with("/three").returns [data]
- @file.expects(:perform_recursion).with("/four").never
- @file.expects(:newchild).with("foobar").returns @resource
- @file.recurse_remote({})
- end
- end
-
- describe "and :sourceselect is set to :all" do
- before do
- @file[:sourceselect] = :all
- end
-
- it "should return every found file that is not in a previous source" do
- klass = Puppet::FileServing::Metadata
- @file[:source] = %w{/one /two /three /four}
- @file.stubs(:newchild).returns @resource
-
- one = [klass.new("/one", :relative_path => "a")]
- @file.expects(:perform_recursion).with("/one").returns one
- @file.expects(:newchild).with("a").returns @resource
-
- two = [klass.new("/two", :relative_path => "a"), klass.new("/two", :relative_path => "b")]
- @file.expects(:perform_recursion).with("/two").returns two
- @file.expects(:newchild).with("b").returns @resource
-
- three = [klass.new("/three", :relative_path => "a"), klass.new("/three", :relative_path => "c")]
- @file.expects(:perform_recursion).with("/three").returns three
- @file.expects(:newchild).with("c").returns @resource
-
- @file.expects(:perform_recursion).with("/four").returns []
-
- @file.recurse_remote({})
- end
- end
+ @file.recurse_remote({})
end
+ end
end
+ end
- describe "when returning resources with :eval_generate" do
- before do
- @graph = stub 'graph', :add_edge => nil
- @catalog.stubs(:relationship_graph).returns @graph
+ describe "when returning resources with :eval_generate" do
+ before do
+ @graph = stub 'graph', :add_edge => nil
+ @catalog.stubs(:relationship_graph).returns @graph
- @file.catalog = @catalog
- @file[:recurse] = true
- end
+ @file.catalog = @catalog
+ @file[:recurse] = true
+ end
- it "should recurse if recursion is enabled" do
- resource = stub('resource', :[] => "resource")
- @file.expects(:recurse?).returns true
- @file.expects(:recurse).returns [resource]
- @file.eval_generate.should == [resource]
- end
+ it "should recurse if recursion is enabled" do
+ resource = stub('resource', :[] => "resource")
+ @file.expects(:recurse?).returns true
+ @file.expects(:recurse).returns [resource]
+ @file.eval_generate.should == [resource]
+ end
- it "should not recurse if recursion is disabled" do
- @file.expects(:recurse?).returns false
- @file.expects(:recurse).never
- @file.eval_generate.should == []
- end
+ it "should not recurse if recursion is disabled" do
+ @file.expects(:recurse?).returns false
+ @file.expects(:recurse).never
+ @file.eval_generate.should == []
+ end
- it "should return each resource found through recursion" do
- foo = stub 'foo', :[] => "/foo"
- bar = stub 'bar', :[] => "/bar"
- bar2 = stub 'bar2', :[] => "/bar"
+ it "should return each resource found through recursion" do
+ foo = stub 'foo', :[] => "/foo"
+ bar = stub 'bar', :[] => "/bar"
+ bar2 = stub 'bar2', :[] => "/bar"
- @file.expects(:recurse).returns [foo, bar]
+ @file.expects(:recurse).returns [foo, bar]
- @file.eval_generate.should == [foo, bar]
- end
+ @file.eval_generate.should == [foo, bar]
end
+ end
- describe "when recursing" do
- before do
- @file[:recurse] = true
- @metadata = Puppet::FileServing::Metadata
- end
+ describe "when recursing" do
+ before do
+ @file[:recurse] = true
+ @metadata = Puppet::FileServing::Metadata
+ end
- describe "and a source is set" do
- before { @file[:source] = "/my/source" }
+ describe "and a source is set" do
+ before { @file[:source] = "/my/source" }
- it "should pass the already-discovered resources to recurse_remote" do
- @file.stubs(:recurse_local).returns(:foo => "bar")
- @file.expects(:recurse_remote).with(:foo => "bar").returns []
- @file.recurse
- end
- end
+ it "should pass the already-discovered resources to recurse_remote" do
+ @file.stubs(:recurse_local).returns(:foo => "bar")
+ @file.expects(:recurse_remote).with(:foo => "bar").returns []
+ @file.recurse
+ end
+ end
- describe "and a target is set" do
- before { @file[:target] = "/link/target" }
+ describe "and a target is set" do
+ before { @file[:target] = "/link/target" }
- it "should use recurse_link" do
- @file.stubs(:recurse_local).returns(:foo => "bar")
- @file.expects(:recurse_link).with(:foo => "bar").returns []
- @file.recurse
- end
- end
+ it "should use recurse_link" do
+ @file.stubs(:recurse_local).returns(:foo => "bar")
+ @file.expects(:recurse_link).with(:foo => "bar").returns []
+ @file.recurse
+ end
+ end
- it "should use recurse_local if recurse is not remote" do
- @file.expects(:recurse_local).returns({})
- @file.recurse
- end
+ it "should use recurse_local if recurse is not remote" do
+ @file.expects(:recurse_local).returns({})
+ @file.recurse
+ end
- it "should not use recurse_local if recurse remote" do
- @file[:recurse] = :remote
- @file.expects(:recurse_local).never
- @file.recurse
- end
+ it "should not use recurse_local if recurse remote" do
+ @file[:recurse] = :remote
+ @file.expects(:recurse_local).never
+ @file.recurse
+ end
- it "should return the generated resources as an array sorted by file path" do
- one = stub 'one', :[] => "/one"
- two = stub 'two', :[] => "/one/two"
- three = stub 'three', :[] => "/three"
- @file.expects(:recurse_local).returns(:one => one, :two => two, :three => three)
- @file.recurse.should == [one, two, three]
- end
+ it "should return the generated resources as an array sorted by file path" do
+ one = stub 'one', :[] => "/one"
+ two = stub 'two', :[] => "/one/two"
+ three = stub 'three', :[] => "/three"
+ @file.expects(:recurse_local).returns(:one => one, :two => two, :three => three)
+ @file.recurse.should == [one, two, three]
+ end
- describe "and purging is enabled" do
- before do
- @file[:purge] = true
- end
+ describe "and purging is enabled" do
+ before do
+ @file[:purge] = true
+ end
- it "should configure each file to be removed" do
- local = stub 'local'
- local.stubs(:[]).with(:source).returns nil # Thus, a local file
- local.stubs(:[]).with(:path).returns "foo"
- @file.expects(:recurse_local).returns("local" => local)
- local.expects(:[]=).with(:ensure, :absent)
+ it "should configure each file to be removed" do
+ local = stub 'local'
+ local.stubs(:[]).with(:source).returns nil # Thus, a local file
+ local.stubs(:[]).with(:path).returns "foo"
+ @file.expects(:recurse_local).returns("local" => local)
+ local.expects(:[]=).with(:ensure, :absent)
- @file.recurse
- end
+ @file.recurse
+ end
- it "should not remove files that exist in the remote repository" do
- @file["source"] = "/my/file"
- @file.expects(:recurse_local).returns({})
+ it "should not remove files that exist in the remote repository" do
+ @file["source"] = "/my/file"
+ @file.expects(:recurse_local).returns({})
- remote = stub 'remote'
- remote.stubs(:[]).with(:source).returns "/whatever" # Thus, a remote file
- remote.stubs(:[]).with(:path).returns "foo"
+ remote = stub 'remote'
+ remote.stubs(:[]).with(:source).returns "/whatever" # Thus, a remote file
+ remote.stubs(:[]).with(:path).returns "foo"
- @file.expects(:recurse_remote).with { |hash| hash["remote"] = remote }
- remote.expects(:[]=).with(:ensure, :absent).never
+ @file.expects(:recurse_remote).with { |hash| hash["remote"] = remote }
+ remote.expects(:[]=).with(:ensure, :absent).never
- @file.recurse
- end
- end
+ @file.recurse
+ end
+ end
- describe "and making a new child resource" do
- it "should not copy the parent resource's parent" do
- Puppet::Type.type(:file).expects(:new).with { |options| ! options.include?(:parent) }
- @file.newchild("my/path")
- end
+ describe "and making a new child resource" do
+ it "should not copy the parent resource's parent" do
+ Puppet::Type.type(:file).expects(:new).with { |options| ! options.include?(:parent) }
+ @file.newchild("my/path")
+ end
- {:recurse => true, :target => "/foo/bar", :ensure => :present, :alias => "yay", :source => "/foo/bar"}.each do |param, value|
- it "should not pass on #{param} to the sub resource" do
- @file = Puppet::Type::File.new(:name => @path, param => value, :catalog => @catalog)
+ {:recurse => true, :target => "/foo/bar", :ensure => :present, :alias => "yay", :source => "/foo/bar"}.each do |param, value|
+ it "should not pass on #{param} to the sub resource" do
+ @file = Puppet::Type::File.new(:name => @path, param => value, :catalog => @catalog)
- @file.class.expects(:new).with { |params| params[param].nil? }
+ @file.class.expects(:new).with { |params| params[param].nil? }
- @file.newchild("sub/file")
- end
- end
+ @file.newchild("sub/file")
+ end
+ end
- it "should copy all of the parent resource's 'should' values that were set at initialization" do
- file = @file.class.new(:path => "/foo/bar", :owner => "root", :group => "wheel")
- @catalog.add_resource(file)
- file.class.expects(:new).with { |options| options[:owner] == "root" and options[:group] == "wheel" }
- file.newchild("my/path")
- end
+ it "should copy all of the parent resource's 'should' values that were set at initialization" do
+ file = @file.class.new(:path => "/foo/bar", :owner => "root", :group => "wheel")
+ @catalog.add_resource(file)
+ file.class.expects(:new).with { |options| options[:owner] == "root" and options[:group] == "wheel" }
+ file.newchild("my/path")
+ end
- it "should not copy default values to the new child" do
- @file.class.expects(:new).with { |params| params[:backup].nil? }
- @file.newchild("my/path")
- end
+ it "should not copy default values to the new child" do
+ @file.class.expects(:new).with { |params| params[:backup].nil? }
+ @file.newchild("my/path")
+ end
- it "should not copy values to the child which were set by the source" do
- @file[:source] = "/foo/bar"
- metadata = stub 'metadata', :owner => "root", :group => "root", :mode => 0755, :ftype => "file", :checksum => "{md5}whatever"
- @file.parameter(:source).stubs(:metadata).returns metadata
+ it "should not copy values to the child which were set by the source" do
+ @file[:source] = "/foo/bar"
+ metadata = stub 'metadata', :owner => "root", :group => "root", :mode => 0755, :ftype => "file", :checksum => "{md5}whatever"
+ @file.parameter(:source).stubs(:metadata).returns metadata
- @file.parameter(:source).copy_source_values
+ @file.parameter(:source).copy_source_values
- @file.class.expects(:new).with { |params| params[:group].nil? }
- @file.newchild("my/path")
- end
- end
+ @file.class.expects(:new).with { |params| params[:group].nil? }
+ @file.newchild("my/path")
+ end
end
+ end
- describe "when setting the backup" do
- it "should default to 'puppet'" do
- Puppet::Type::File.new(:name => "/my/file")[:backup].should == "puppet"
- end
+ describe "when setting the backup" do
+ it "should default to 'puppet'" do
+ Puppet::Type::File.new(:name => "/my/file")[:backup].should == "puppet"
+ end
- it "should allow setting backup to 'false'" do
- (!Puppet::Type::File.new(:name => "/my/file", :backup => false)[:backup]).should be_true
- end
+ it "should allow setting backup to 'false'" do
+ (!Puppet::Type::File.new(:name => "/my/file", :backup => false)[:backup]).should be_true
+ end
- it "should set the backup to '.puppet-bak' if it is set to true" do
- Puppet::Type::File.new(:name => "/my/file", :backup => true)[:backup].should == ".puppet-bak"
- end
+ it "should set the backup to '.puppet-bak' if it is set to true" do
+ Puppet::Type::File.new(:name => "/my/file", :backup => true)[:backup].should == ".puppet-bak"
+ end
- it "should support any other backup extension" do
- Puppet::Type::File.new(:name => "/my/file", :backup => ".bak")[:backup].should == ".bak"
- end
+ it "should support any other backup extension" do
+ Puppet::Type::File.new(:name => "/my/file", :backup => ".bak")[:backup].should == ".bak"
+ end
- it "should set the filebucket when backup is set to a string matching the name of a filebucket in the catalog" do
- catalog = Puppet::Resource::Catalog.new
- bucket_resource = Puppet::Type.type(:filebucket).new :name => "foo", :path => "/my/file/bucket"
- catalog.add_resource bucket_resource
+ it "should set the filebucket when backup is set to a string matching the name of a filebucket in the catalog" do
+ catalog = Puppet::Resource::Catalog.new
+ bucket_resource = Puppet::Type.type(:filebucket).new :name => "foo", :path => "/my/file/bucket"
+ catalog.add_resource bucket_resource
- file = Puppet::Type::File.new(:name => "/my/file")
- catalog.add_resource file
+ file = Puppet::Type::File.new(:name => "/my/file")
+ catalog.add_resource file
- file[:backup] = "foo"
- file.bucket.should == bucket_resource.bucket
- end
+ file[:backup] = "foo"
+ file.bucket.should == bucket_resource.bucket
+ end
- it "should find filebuckets added to the catalog after the file resource was created" do
- catalog = Puppet::Resource::Catalog.new
+ it "should find filebuckets added to the catalog after the file resource was created" do
+ catalog = Puppet::Resource::Catalog.new
- file = Puppet::Type::File.new(:name => "/my/file", :backup => "foo")
- catalog.add_resource file
+ file = Puppet::Type::File.new(:name => "/my/file", :backup => "foo")
+ catalog.add_resource file
- bucket_resource = Puppet::Type.type(:filebucket).new :name => "foo", :path => "/my/file/bucket"
- catalog.add_resource bucket_resource
+ bucket_resource = Puppet::Type.type(:filebucket).new :name => "foo", :path => "/my/file/bucket"
+ catalog.add_resource bucket_resource
- file.bucket.should == bucket_resource.bucket
- end
+ file.bucket.should == bucket_resource.bucket
+ end
- it "should have a nil filebucket if backup is false" do
- catalog = Puppet::Resource::Catalog.new
- bucket_resource = Puppet::Type.type(:filebucket).new :name => "foo", :path => "/my/file/bucket"
- catalog.add_resource bucket_resource
+ it "should have a nil filebucket if backup is false" do
+ catalog = Puppet::Resource::Catalog.new
+ bucket_resource = Puppet::Type.type(:filebucket).new :name => "foo", :path => "/my/file/bucket"
+ catalog.add_resource bucket_resource
- file = Puppet::Type::File.new(:name => "/my/file", :backup => false)
- catalog.add_resource file
+ file = Puppet::Type::File.new(:name => "/my/file", :backup => false)
+ catalog.add_resource file
- file.bucket.should be_nil
- end
+ file.bucket.should be_nil
+ end
- it "should have a nil filebucket if backup is set to a string starting with '.'" do
- catalog = Puppet::Resource::Catalog.new
- bucket_resource = Puppet::Type.type(:filebucket).new :name => "foo", :path => "/my/file/bucket"
- catalog.add_resource bucket_resource
+ it "should have a nil filebucket if backup is set to a string starting with '.'" do
+ catalog = Puppet::Resource::Catalog.new
+ bucket_resource = Puppet::Type.type(:filebucket).new :name => "foo", :path => "/my/file/bucket"
+ catalog.add_resource bucket_resource
- file = Puppet::Type::File.new(:name => "/my/file", :backup => ".foo")
- catalog.add_resource file
+ file = Puppet::Type::File.new(:name => "/my/file", :backup => ".foo")
+ catalog.add_resource file
- file.bucket.should be_nil
- end
+ file.bucket.should be_nil
+ end
- it "should fail if there's no catalog and backup is not false" do
- file = Puppet::Type::File.new(:name => "/my/file", :backup => "foo")
+ it "should fail if there's no catalog and backup is not false" do
+ file = Puppet::Type::File.new(:name => "/my/file", :backup => "foo")
- lambda { file.bucket }.should raise_error(Puppet::Error)
- end
+ lambda { file.bucket }.should raise_error(Puppet::Error)
+ end
- it "should fail if a non-existent catalog is specified" do
- file = Puppet::Type::File.new(:name => "/my/file", :backup => "foo")
- catalog = Puppet::Resource::Catalog.new
- catalog.add_resource file
+ it "should fail if a non-existent catalog is specified" do
+ file = Puppet::Type::File.new(:name => "/my/file", :backup => "foo")
+ catalog = Puppet::Resource::Catalog.new
+ catalog.add_resource file
- lambda { file.bucket }.should raise_error(Puppet::Error)
- end
+ lambda { file.bucket }.should raise_error(Puppet::Error)
+ end
- it "should be able to use the default filebucket without a catalog" do
- file = Puppet::Type::File.new(:name => "/my/file", :backup => "puppet")
- file.bucket.should be_instance_of(Puppet::FileBucket::Dipper)
- end
+ it "should be able to use the default filebucket without a catalog" do
+ file = Puppet::Type::File.new(:name => "/my/file", :backup => "puppet")
+ file.bucket.should be_instance_of(Puppet::FileBucket::Dipper)
+ end
- it "should look up the filebucket during finish()" do
- file = Puppet::Type::File.new(:name => "/my/file", :backup => ".foo")
- file.expects(:bucket)
- file.finish
- end
+ it "should look up the filebucket during finish()" do
+ file = Puppet::Type::File.new(:name => "/my/file", :backup => ".foo")
+ file.expects(:bucket)
+ file.finish
end
+ end
- describe "when retrieving the current file state" do
- it "should copy the source values if the 'source' parameter is set" do
- file = Puppet::Type::File.new(:name => "/my/file", :source => "/foo/bar")
- file.parameter(:source).expects(:copy_source_values)
- file.retrieve
- end
+ describe "when retrieving the current file state" do
+ it "should copy the source values if the 'source' parameter is set" do
+ file = Puppet::Type::File.new(:name => "/my/file", :source => "/foo/bar")
+ file.parameter(:source).expects(:copy_source_values)
+ file.retrieve
end
+ end
end
diff --git a/spec/unit/type/filebucket_spec.rb b/spec/unit/type/filebucket_spec.rb
index f3efc98..0b8ea50 100644
--- a/spec/unit/type/filebucket_spec.rb
+++ b/spec/unit/type/filebucket_spec.rb
@@ -3,72 +3,72 @@
require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::Type.type(:filebucket) do
- describe "when validating attributes" do
- %w{name server port path}.each do |attr|
- it "should have a '#{attr}' parameter" do
- Puppet::Type.type(:filebucket).attrtype(attr.intern).should == :param
- end
- end
-
- it "should have its 'name' attribute set as its namevar" do
- Puppet::Type.type(:filebucket).key_attributes.should == [:name]
- end
+ describe "when validating attributes" do
+ %w{name server port path}.each do |attr|
+ it "should have a '#{attr}' parameter" do
+ Puppet::Type.type(:filebucket).attrtype(attr.intern).should == :param
+ end
end
- it "should use the clientbucketdir as the path by default path" do
- Puppet.settings[:clientbucketdir] = "/my/bucket"
- Puppet::Type.type(:filebucket).new(:name => "main")[:path].should == Puppet[:clientbucketdir]
+ it "should have its 'name' attribute set as its namevar" do
+ Puppet::Type.type(:filebucket).key_attributes.should == [:name]
end
+ end
- it "should use the masterport as the path by default port" do
- Puppet.settings[:masterport] = 50
- Puppet::Type.type(:filebucket).new(:name => "main")[:port].should == Puppet[:masterport]
- end
+ it "should use the clientbucketdir as the path by default path" do
+ Puppet.settings[:clientbucketdir] = "/my/bucket"
+ Puppet::Type.type(:filebucket).new(:name => "main")[:path].should == Puppet[:clientbucketdir]
+ end
- it "should use the server as the path by default server" do
- Puppet.settings[:server] = "myserver"
- Puppet::Type.type(:filebucket).new(:name => "main")[:server].should == Puppet[:server]
- end
+ it "should use the masterport as the path by default port" do
+ Puppet.settings[:masterport] = 50
+ Puppet::Type.type(:filebucket).new(:name => "main")[:port].should == Puppet[:masterport]
+ end
- it "be local by default" do
- bucket = Puppet::Type.type(:filebucket).new :name => "main"
+ it "should use the server as the path by default server" do
+ Puppet.settings[:server] = "myserver"
+ Puppet::Type.type(:filebucket).new(:name => "main")[:server].should == Puppet[:server]
+ end
- bucket.bucket.should be_local
- end
+ it "be local by default" do
+ bucket = Puppet::Type.type(:filebucket).new :name => "main"
- it "not be local if path is false" do
- bucket = Puppet::Type.type(:filebucket).new :name => "main", :path => false
+ bucket.bucket.should be_local
+ end
- bucket.bucket.should_not be_local
- end
+ it "not be local if path is false" do
+ bucket = Puppet::Type.type(:filebucket).new :name => "main", :path => false
- it "be local if both a path and a server are specified" do
- bucket = Puppet::Type.type(:filebucket).new :name => "main", :server => "puppet", :path => "/my/path"
+ bucket.bucket.should_not be_local
+ end
- bucket.bucket.should be_local
- end
+ it "be local if both a path and a server are specified" do
+ bucket = Puppet::Type.type(:filebucket).new :name => "main", :server => "puppet", :path => "/my/path"
+
+ bucket.bucket.should be_local
+ end
- describe "when creating the filebucket" do
- before do
- @bucket = stub 'bucket', :name= => nil
- end
+ describe "when creating the filebucket" do
+ before do
+ @bucket = stub 'bucket', :name= => nil
+ end
- it "should use any provided path" do
- bucket = Puppet::Type.type(:filebucket).new :name => "main", :path => "/foo/bar"
- Puppet::FileBucket::Dipper.expects(:new).with(:Path => "/foo/bar").returns @bucket
- bucket.bucket
- end
- it "should use any provided server and port" do
- bucket = Puppet::Type.type(:filebucket).new :name => "main", :server => "myserv", :port => "myport", :path => false
- Puppet::FileBucket::Dipper.expects(:new).with(:Server => "myserv", :Port => "myport").returns @bucket
- bucket.bucket
- end
+ it "should use any provided path" do
+ bucket = Puppet::Type.type(:filebucket).new :name => "main", :path => "/foo/bar"
+ Puppet::FileBucket::Dipper.expects(:new).with(:Path => "/foo/bar").returns @bucket
+ bucket.bucket
+ end
+ it "should use any provided server and port" do
+ bucket = Puppet::Type.type(:filebucket).new :name => "main", :server => "myserv", :port => "myport", :path => false
+ Puppet::FileBucket::Dipper.expects(:new).with(:Server => "myserv", :Port => "myport").returns @bucket
+ bucket.bucket
+ end
- it "should use the default server if the path is unset and no server is provided" do
- Puppet.settings[:server] = "myserv"
- bucket = Puppet::Type.type(:filebucket).new :name => "main", :path => false
- Puppet::FileBucket::Dipper.expects(:new).with { |args| args[:Server] == "myserv" }.returns @bucket
- bucket.bucket
- end
+ it "should use the default server if the path is unset and no server is provided" do
+ Puppet.settings[:server] = "myserv"
+ bucket = Puppet::Type.type(:filebucket).new :name => "main", :path => false
+ Puppet::FileBucket::Dipper.expects(:new).with { |args| args[:Server] == "myserv" }.returns @bucket
+ bucket.bucket
end
+ end
end
diff --git a/spec/unit/type/group_spec.rb b/spec/unit/type/group_spec.rb
index c563d13..b41ce71 100755
--- a/spec/unit/type/group_spec.rb
+++ b/spec/unit/type/group_spec.rb
@@ -3,55 +3,55 @@
require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::Type.type(:group) do
- before do
- ENV["PATH"] += File::PATH_SEPARATOR + "/usr/sbin" unless ENV["PATH"].split(File::PATH_SEPARATOR).include?("/usr/sbin")
- @class = Puppet::Type.type(:group)
+ before do
+ ENV["PATH"] += File::PATH_SEPARATOR + "/usr/sbin" unless ENV["PATH"].split(File::PATH_SEPARATOR).include?("/usr/sbin")
+ @class = Puppet::Type.type(:group)
+ end
+
+ it "should have a default provider" do
+ @class.defaultprovider.should_not be_nil
+ end
+
+ it "should have a default provider inheriting from Puppet::Provider" do
+ @class.defaultprovider.ancestors.should be_include(Puppet::Provider)
+ end
+
+ describe "when validating attributes" do
+ [:name, :allowdupe].each do |param|
+ it "should have a #{param} parameter" do
+ @class.attrtype(param).should == :param
+ end
end
- it "should have a default provider" do
- @class.defaultprovider.should_not be_nil
+ [:ensure, :gid].each do |param|
+ it "should have a #{param} property" do
+ @class.attrtype(param).should == :property
+ end
end
- it "should have a default provider inheriting from Puppet::Provider" do
- @class.defaultprovider.ancestors.should be_include(Puppet::Provider)
+ it "should convert gids provided as strings into integers" do
+ @class.new(:name => "foo", :gid => "15")[:gid].should == 15
end
- describe "when validating attributes" do
- [:name, :allowdupe].each do |param|
- it "should have a #{param} parameter" do
- @class.attrtype(param).should == :param
- end
- end
-
- [:ensure, :gid].each do |param|
- it "should have a #{param} property" do
- @class.attrtype(param).should == :property
- end
- end
-
- it "should convert gids provided as strings into integers" do
- @class.new(:name => "foo", :gid => "15")[:gid].should == 15
- end
-
- it "should accepts gids provided as integers" do
- @class.new(:name => "foo", :gid => 15)[:gid].should == 15
- end
- end
-
- # #1407 - we need to declare the allowdupe param as boolean.
- it "should have a boolean method for determining if duplicates are allowed" do
- @class.new(:name => "foo").methods.should be_include("allowdupe?")
- end
-
- it "should call 'create' to create the group" do
- group = @class.new(:name => "foo", :ensure => :present)
- group.provider.expects(:create)
- group.parameter(:ensure).sync
- end
-
- it "should call 'delete' to remove the group" do
- group = @class.new(:name => "foo", :ensure => :absent)
- group.provider.expects(:delete)
- group.parameter(:ensure).sync
+ it "should accepts gids provided as integers" do
+ @class.new(:name => "foo", :gid => 15)[:gid].should == 15
end
+ end
+
+ # #1407 - we need to declare the allowdupe param as boolean.
+ it "should have a boolean method for determining if duplicates are allowed" do
+ @class.new(:name => "foo").methods.should be_include("allowdupe?")
+ end
+
+ it "should call 'create' to create the group" do
+ group = @class.new(:name => "foo", :ensure => :present)
+ group.provider.expects(:create)
+ group.parameter(:ensure).sync
+ end
+
+ it "should call 'delete' to remove the group" do
+ group = @class.new(:name => "foo", :ensure => :absent)
+ group.provider.expects(:delete)
+ group.parameter(:ensure).sync
+ end
end
diff --git a/spec/unit/type/macauthorization_spec.rb b/spec/unit/type/macauthorization_spec.rb
index c5305d5..544f07f 100755
--- a/spec/unit/type/macauthorization_spec.rb
+++ b/spec/unit/type/macauthorization_spec.rb
@@ -6,106 +6,106 @@ macauth_type = Puppet::Type.type(:macauthorization)
describe Puppet::Type.type(:macauthorization), "when checking macauthorization objects" do
- before do
- authplist = {}
- authplist["rules"] = { "foorule" => "foo" }
- authplist["rights"] = { "fooright" => "foo" }
- provider_class = macauth_type.provider(macauth_type.providers[0])
- Plist.stubs(:parse_xml).with("/etc/authorization").returns(authplist)
- macauth_type.stubs(:defaultprovider).returns provider_class
- @resource = macauth_type.new(:name => 'foo')
+ before do
+ authplist = {}
+ authplist["rules"] = { "foorule" => "foo" }
+ authplist["rights"] = { "fooright" => "foo" }
+ provider_class = macauth_type.provider(macauth_type.providers[0])
+ Plist.stubs(:parse_xml).with("/etc/authorization").returns(authplist)
+ macauth_type.stubs(:defaultprovider).returns provider_class
+ @resource = macauth_type.new(:name => 'foo')
+ end
+
+ describe "when validating attributes" do
+
+ parameters = [:name,]
+ properties = [:auth_type, :allow_root, :authenticate_user, :auth_class,
+ :comment, :group, :k_of_n, :mechanisms, :rule,
+ :session_owner, :shared, :timeout, :tries]
+
+ parameters.each do |parameter|
+ it "should have a #{parameter} parameter" do
+ macauth_type.attrclass(parameter).ancestors.should be_include(Puppet::Parameter)
+ end
+
+ it "should have documentation for its #{parameter} parameter" do
+ macauth_type.attrclass(parameter).doc.should be_instance_of(String)
+ end
end
- describe "when validating attributes" do
-
- parameters = [:name,]
- properties = [:auth_type, :allow_root, :authenticate_user, :auth_class,
- :comment, :group, :k_of_n, :mechanisms, :rule,
- :session_owner, :shared, :timeout, :tries]
-
- parameters.each do |parameter|
- it "should have a #{parameter} parameter" do
- macauth_type.attrclass(parameter).ancestors.should be_include(Puppet::Parameter)
- end
-
- it "should have documentation for its #{parameter} parameter" do
- macauth_type.attrclass(parameter).doc.should be_instance_of(String)
- end
- end
-
- properties.each do |property|
- it "should have a #{property} property" do
- macauth_type.attrclass(property).ancestors.should be_include(Puppet::Property)
- end
-
- it "should have documentation for its #{property} property" do
- macauth_type.attrclass(property).doc.should be_instance_of(String)
- end
- end
+ properties.each do |property|
+ it "should have a #{property} property" do
+ macauth_type.attrclass(property).ancestors.should be_include(Puppet::Property)
+ end
+ it "should have documentation for its #{property} property" do
+ macauth_type.attrclass(property).doc.should be_instance_of(String)
+ end
end
- describe "when validating properties" do
+ end
- it "should have a default provider inheriting from Puppet::Provider" do
- macauth_type.defaultprovider.ancestors.should be_include(Puppet::Provider)
- end
+ describe "when validating properties" do
- it "should be able to create an instance" do
- lambda {
- macauth_type.new(:name => 'foo')
- }.should_not raise_error
- end
-
- it "should support :present as a value to :ensure" do
- lambda {
- macauth_type.new(:name => "foo", :ensure => :present)
- }.should_not raise_error
- end
+ it "should have a default provider inheriting from Puppet::Provider" do
+ macauth_type.defaultprovider.ancestors.should be_include(Puppet::Provider)
+ end
- it "should support :absent as a value to :ensure" do
- lambda {
- macauth_type.new(:name => "foo", :ensure => :absent)
- }.should_not raise_error
- end
+ it "should be able to create an instance" do
+ lambda {
+ macauth_type.new(:name => 'foo')
+ }.should_not raise_error
+ end
+ it "should support :present as a value to :ensure" do
+ lambda {
+ macauth_type.new(:name => "foo", :ensure => :present)
+ }.should_not raise_error
end
- [:k_of_n, :timeout, :tries].each do |property|
- describe "when managing the #{property} property" do
- it "should convert number-looking strings into actual numbers" do
- prop = macauth_type.attrclass(property).new(:resource => @resource)
- prop.should = "300"
- prop.should.must == 300
- end
- it "should support integers as a value" do
- prop = macauth_type.attrclass(property).new(:resource => @resource)
- prop.should = 300
- prop.should.must == 300
- end
- it "should raise an error for non-integer values" do
- prop = macauth_type.attrclass(property).new(:resource => @resource)
- lambda { prop.should = "foo" }.should raise_error(Puppet::Error)
- end
- end
+ it "should support :absent as a value to :ensure" do
+ lambda {
+ macauth_type.new(:name => "foo", :ensure => :absent)
+ }.should_not raise_error
end
- [:allow_root, :authenticate_user, :session_owner, :shared].each do |property|
- describe "when managing the #{property} property" do
- it "should convert boolean-looking false strings into actual booleans" do
- prop = macauth_type.attrclass(property).new(:resource => @resource)
- prop.should = "false"
- prop.should.must == :false
- end
- it "should convert boolean-looking true strings into actual booleans" do
- prop = macauth_type.attrclass(property).new(:resource => @resource)
- prop.should = "true"
- prop.should.must == :true
- end
- it "should raise an error for non-boolean values" do
- prop = macauth_type.attrclass(property).new(:resource => @resource)
- lambda { prop.should = "foo" }.should raise_error(Puppet::Error)
- end
- end
+ end
+
+ [:k_of_n, :timeout, :tries].each do |property|
+ describe "when managing the #{property} property" do
+ it "should convert number-looking strings into actual numbers" do
+ prop = macauth_type.attrclass(property).new(:resource => @resource)
+ prop.should = "300"
+ prop.should.must == 300
+ end
+ it "should support integers as a value" do
+ prop = macauth_type.attrclass(property).new(:resource => @resource)
+ prop.should = 300
+ prop.should.must == 300
+ end
+ it "should raise an error for non-integer values" do
+ prop = macauth_type.attrclass(property).new(:resource => @resource)
+ lambda { prop.should = "foo" }.should raise_error(Puppet::Error)
+ end
+ end
+ end
+
+ [:allow_root, :authenticate_user, :session_owner, :shared].each do |property|
+ describe "when managing the #{property} property" do
+ it "should convert boolean-looking false strings into actual booleans" do
+ prop = macauth_type.attrclass(property).new(:resource => @resource)
+ prop.should = "false"
+ prop.should.must == :false
+ end
+ it "should convert boolean-looking true strings into actual booleans" do
+ prop = macauth_type.attrclass(property).new(:resource => @resource)
+ prop.should = "true"
+ prop.should.must == :true
+ end
+ it "should raise an error for non-boolean values" do
+ prop = macauth_type.attrclass(property).new(:resource => @resource)
+ lambda { prop.should = "foo" }.should raise_error(Puppet::Error)
+ end
end
+ end
end
diff --git a/spec/unit/type/maillist_spec.rb b/spec/unit/type/maillist_spec.rb
index 5dac051..04acea7 100755
--- a/spec/unit/type/maillist_spec.rb
+++ b/spec/unit/type/maillist_spec.rb
@@ -5,38 +5,38 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
maillist = Puppet::Type.type(:maillist)
describe maillist do
- before do
- @provider_class = Puppet::Type.type(:maillist).provider(:mailman)
+ before do
+ @provider_class = Puppet::Type.type(:maillist).provider(:mailman)
- @provider = stub 'provider', :class => @provider_class, :clear => nil
- @provider.stubs(:respond_to).with(:aliases).returns(true)
+ @provider = stub 'provider', :class => @provider_class, :clear => nil
+ @provider.stubs(:respond_to).with(:aliases).returns(true)
- @provider_class.stubs(:new).returns(@provider)
+ @provider_class.stubs(:new).returns(@provider)
- Puppet::Type.type(:maillist).stubs(:defaultprovider).returns(@provider_class)
+ Puppet::Type.type(:maillist).stubs(:defaultprovider).returns(@provider_class)
- @maillist = Puppet::Type.type(:maillist).new( :name => 'test' )
+ @maillist = Puppet::Type.type(:maillist).new( :name => 'test' )
- @catalog = Puppet::Resource::Catalog.new
- @maillist.catalog = @catalog
- end
+ @catalog = Puppet::Resource::Catalog.new
+ @maillist.catalog = @catalog
+ end
- it "should generate aliases unless they already exist" do
- # Mail List aliases are careful not to stomp on managed Mail Alias aliases
+ it "should generate aliases unless they already exist" do
+ # Mail List aliases are careful not to stomp on managed Mail Alias aliases
- # test1 is an unmanaged alias from /etc/aliases
- Puppet::Type.type(:mailalias).provider(:aliases).stubs(:target_object).returns( StringIO.new("test1: root\n") )
+ # test1 is an unmanaged alias from /etc/aliases
+ Puppet::Type.type(:mailalias).provider(:aliases).stubs(:target_object).returns( StringIO.new("test1: root\n") )
- # test2 is a managed alias from the manifest
- dupe = Puppet::Type.type(:mailalias).new( :name => 'test2' )
- @catalog.add_resource dupe
+ # test2 is a managed alias from the manifest
+ dupe = Puppet::Type.type(:mailalias).new( :name => 'test2' )
+ @catalog.add_resource dupe
- @provider.stubs(:aliases).returns({"test1" => 'this will get included', "test2" => 'this will dropped', "test3" => 'this will get included'})
+ @provider.stubs(:aliases).returns({"test1" => 'this will get included', "test2" => 'this will dropped', "test3" => 'this will get included'})
- generated = @maillist.generate
- generated.map{ |x| x.name }.sort.should == ['test1', 'test3']
- generated.map{ |x| x.class }.should == [Puppet::Type::Mailalias, Puppet::Type::Mailalias]
+ generated = @maillist.generate
+ generated.map{ |x| x.name }.sort.should == ['test1', 'test3']
+ generated.map{ |x| x.class }.should == [Puppet::Type::Mailalias, Puppet::Type::Mailalias]
- end
+ end
end
diff --git a/spec/unit/type/mcx_spec.rb b/spec/unit/type/mcx_spec.rb
index 8b5dfb0..703ecb4 100755
--- a/spec/unit/type/mcx_spec.rb
+++ b/spec/unit/type/mcx_spec.rb
@@ -28,73 +28,73 @@ mcx_type = Puppet::Type.type(:mcx)
describe mcx_type, "when validating attributes" do
- properties = [:ensure, :content]
- parameters = [:name, :ds_type, :ds_name]
-
- parameters.each do |p|
- it "should have a #{p} parameter" do
- mcx_type.attrclass(p).ancestors.should be_include(Puppet::Parameter)
- end
- it "should have documentation for its #{p} parameter" do
- mcx_type.attrclass(p).doc.should be_instance_of(String)
- end
+ properties = [:ensure, :content]
+ parameters = [:name, :ds_type, :ds_name]
+
+ parameters.each do |p|
+ it "should have a #{p} parameter" do
+ mcx_type.attrclass(p).ancestors.should be_include(Puppet::Parameter)
+ end
+ it "should have documentation for its #{p} parameter" do
+ mcx_type.attrclass(p).doc.should be_instance_of(String)
end
+ end
- properties.each do |p|
- it "should have a #{p} property" do
- mcx_type.attrclass(p).ancestors.should be_include(Puppet::Property)
- end
- it "should have documentation for its #{p} property" do
- mcx_type.attrclass(p).doc.should be_instance_of(String)
- end
+ properties.each do |p|
+ it "should have a #{p} property" do
+ mcx_type.attrclass(p).ancestors.should be_include(Puppet::Property)
end
+ it "should have documentation for its #{p} property" do
+ mcx_type.attrclass(p).doc.should be_instance_of(String)
+ end
+ end
end
describe mcx_type, "default values" do
- before :each do
- provider_class = mcx_type.provider(mcx_type.providers[0])
- mcx_type.stubs(:defaultprovider).returns provider_class
- end
+ before :each do
+ provider_class = mcx_type.provider(mcx_type.providers[0])
+ mcx_type.stubs(:defaultprovider).returns provider_class
+ end
- it "should be nil for :ds_type" do
- mcx_type.new(:name => '/Foo/bar')[:ds_type].should be_nil
- end
+ it "should be nil for :ds_type" do
+ mcx_type.new(:name => '/Foo/bar')[:ds_type].should be_nil
+ end
- it "should be nil for :ds_name" do
- mcx_type.new(:name => '/Foo/bar')[:ds_name].should be_nil
- end
+ it "should be nil for :ds_name" do
+ mcx_type.new(:name => '/Foo/bar')[:ds_name].should be_nil
+ end
- it "should be nil for :content" do
- mcx_type.new(:name => '/Foo/bar')[:content].should be_nil
- end
+ it "should be nil for :content" do
+ mcx_type.new(:name => '/Foo/bar')[:content].should be_nil
+ end
end
describe mcx_type, "when validating properties" do
- before :each do
- provider_class = mcx_type.provider(mcx_type.providers[0])
- mcx_type.stubs(:defaultprovider).returns provider_class
- end
-
- it "should be able to create an instance" do
- lambda {
- mcx_type.new(:name => '/Foo/bar')
- }.should_not raise_error
- end
-
- it "should support :present as a value to :ensure" do
- lambda {
- mcx_type.new(:name => "/Foo/bar", :ensure => :present)
- }.should_not raise_error
- end
-
- it "should support :absent as a value to :ensure" do
- lambda {
- mcx_type.new(:name => "/Foo/bar", :ensure => :absent)
- }.should_not raise_error
- end
+ before :each do
+ provider_class = mcx_type.provider(mcx_type.providers[0])
+ mcx_type.stubs(:defaultprovider).returns provider_class
+ end
+
+ it "should be able to create an instance" do
+ lambda {
+ mcx_type.new(:name => '/Foo/bar')
+ }.should_not raise_error
+ end
+
+ it "should support :present as a value to :ensure" do
+ lambda {
+ mcx_type.new(:name => "/Foo/bar", :ensure => :present)
+ }.should_not raise_error
+ end
+
+ it "should support :absent as a value to :ensure" do
+ lambda {
+ mcx_type.new(:name => "/Foo/bar", :ensure => :absent)
+ }.should_not raise_error
+ end
end
diff --git a/spec/unit/type/mount_spec.rb b/spec/unit/type/mount_spec.rb
index 30c3aaf..ce82cb5 100755
--- a/spec/unit/type/mount_spec.rb
+++ b/spec/unit/type/mount_spec.rb
@@ -3,259 +3,259 @@
require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::Type.type(:mount) do
- it "should have a :refreshable feature that requires the :remount method" do
- Puppet::Type.type(:mount).provider_feature(:refreshable).methods.should == [:remount]
- end
-
- it "should have no default value for :ensure" do
- mount = Puppet::Type.type(:mount).new(:name => "yay")
- mount.should(:ensure).should be_nil
- end
+ it "should have a :refreshable feature that requires the :remount method" do
+ Puppet::Type.type(:mount).provider_feature(:refreshable).methods.should == [:remount]
+ end
+
+ it "should have no default value for :ensure" do
+ mount = Puppet::Type.type(:mount).new(:name => "yay")
+ mount.should(:ensure).should be_nil
+ end
end
describe Puppet::Type.type(:mount), "when validating attributes" do
- [:name, :remounts].each do |param|
- it "should have a #{param} parameter" do
- Puppet::Type.type(:mount).attrtype(param).should == :param
- end
+ [:name, :remounts].each do |param|
+ it "should have a #{param} parameter" do
+ Puppet::Type.type(:mount).attrtype(param).should == :param
end
+ end
- [:ensure, :device, :blockdevice, :fstype, :options, :pass, :dump, :atboot, :target].each do |param|
- it "should have a #{param} property" do
- Puppet::Type.type(:mount).attrtype(param).should == :property
- end
+ [:ensure, :device, :blockdevice, :fstype, :options, :pass, :dump, :atboot, :target].each do |param|
+ it "should have a #{param} property" do
+ Puppet::Type.type(:mount).attrtype(param).should == :property
end
+ end
end
describe Puppet::Type.type(:mount)::Ensure, "when validating values" do
- before do
- @provider = stub 'provider', :class => Puppet::Type.type(:mount).defaultprovider, :clear => nil
- Puppet::Type.type(:mount).defaultprovider.expects(:new).returns(@provider)
+ before do
+ @provider = stub 'provider', :class => Puppet::Type.type(:mount).defaultprovider, :clear => nil
+ Puppet::Type.type(:mount).defaultprovider.expects(:new).returns(@provider)
+ end
+
+ it "should alias :present to :defined as a value to :ensure" do
+ mount = Puppet::Type.type(:mount).new(:name => "yay", :ensure => :present)
+ mount.should(:ensure).should == :defined
+ end
+
+ it "should support :unmounted as a value to :ensure" do
+ mount = Puppet::Type.type(:mount).new(:name => "yay", :ensure => :unmounted)
+ mount.should(:ensure).should == :unmounted
+ end
+
+ it "should support :absent as a value to :ensure" do
+ Puppet::Type.type(:mount).new(:name => "yay", :ensure => :absent)
+ end
+
+ it "should support :mounted as a value to :ensure" do
+ Puppet::Type.type(:mount).new(:name => "yay", :ensure => :mounted)
+ end
+end
+
+describe Puppet::Type.type(:mount)::Ensure do
+ before :each do
+ @provider = stub 'provider', :class => Puppet::Type.type(:mount).defaultprovider, :clear => nil, :satisfies? => true, :name => :mock
+ Puppet::Type.type(:mount).defaultprovider.stubs(:new).returns(@provider)
+ @mount = Puppet::Type.type(:mount).new(:name => "yay", :check => :ensure)
+
+ @ensure = @mount.property(:ensure)
+ end
+
+ def mount_stub(params)
+ Puppet::Type.type(:mount).validproperties.each do |prop|
+ unless params[prop]
+ params[prop] = :absent
+ @mount[prop] = :absent
+ end
end
- it "should alias :present to :defined as a value to :ensure" do
- mount = Puppet::Type.type(:mount).new(:name => "yay", :ensure => :present)
- mount.should(:ensure).should == :defined
+ params.each do |param, value|
+ @provider.stubs(param).returns(value)
end
+ end
- it "should support :unmounted as a value to :ensure" do
- mount = Puppet::Type.type(:mount).new(:name => "yay", :ensure => :unmounted)
- mount.should(:ensure).should == :unmounted
+ describe Puppet::Type.type(:mount)::Ensure, "when retrieving its current state" do
+
+ it "should return the provider's value if it is :absent" do
+ @provider.expects(:ensure).returns(:absent)
+ @ensure.retrieve.should == :absent
end
- it "should support :absent as a value to :ensure" do
- Puppet::Type.type(:mount).new(:name => "yay", :ensure => :absent)
+ it "should return :mounted if the provider indicates it is mounted and the value is not :absent" do
+ @provider.expects(:ensure).returns(:present)
+ @provider.expects(:mounted?).returns(true)
+ @ensure.retrieve.should == :mounted
end
- it "should support :mounted as a value to :ensure" do
- Puppet::Type.type(:mount).new(:name => "yay", :ensure => :mounted)
+ it "should return :unmounted if the provider indicates it is not mounted and the value is not :absent" do
+ @provider.expects(:ensure).returns(:present)
+ @provider.expects(:mounted?).returns(false)
+ @ensure.retrieve.should == :unmounted
end
-end
+ end
-describe Puppet::Type.type(:mount)::Ensure do
- before :each do
- @provider = stub 'provider', :class => Puppet::Type.type(:mount).defaultprovider, :clear => nil, :satisfies? => true, :name => :mock
- Puppet::Type.type(:mount).defaultprovider.stubs(:new).returns(@provider)
- @mount = Puppet::Type.type(:mount).new(:name => "yay", :check => :ensure)
+ describe Puppet::Type.type(:mount)::Ensure, "when changing the host" do
+
+ it "should destroy itself if it should be absent" do
+ @provider.stubs(:mounted?).returns(false)
+ @provider.expects(:destroy)
+ @ensure.should = :absent
+ @ensure.sync
+ end
- @ensure = @mount.property(:ensure)
+ it "should unmount itself before destroying if it is mounted and should be absent" do
+ @provider.expects(:mounted?).returns(true)
+ @provider.expects(:unmount)
+ @provider.expects(:destroy)
+ @ensure.should = :absent
+ @ensure.sync
end
- def mount_stub(params)
- Puppet::Type.type(:mount).validproperties.each do |prop|
- unless params[prop]
- params[prop] = :absent
- @mount[prop] = :absent
- end
- end
-
- params.each do |param, value|
- @provider.stubs(param).returns(value)
- end
+ it "should create itself if it is absent and should be defined" do
+ @provider.stubs(:ensure).returns(:absent)
+ @provider.stubs(:mounted?).returns(true)
+
+ @provider.stubs(:mounted?).returns(false)
+ @provider.expects(:create)
+ @ensure.should = :defined
+ @ensure.sync
end
- describe Puppet::Type.type(:mount)::Ensure, "when retrieving its current state" do
+ it "should not unmount itself if it is mounted and should be defined" do
+ @provider.stubs(:ensure).returns(:mounted)
+ @provider.stubs(:mounted?).returns(true)
- it "should return the provider's value if it is :absent" do
- @provider.expects(:ensure).returns(:absent)
- @ensure.retrieve.should == :absent
- end
+ @provider.stubs(:create)
+ @provider.expects(:mount).never
+ @provider.expects(:unmount).never
+ @ensure.should = :defined
+ @ensure.sync
+ end
- it "should return :mounted if the provider indicates it is mounted and the value is not :absent" do
- @provider.expects(:ensure).returns(:present)
- @provider.expects(:mounted?).returns(true)
- @ensure.retrieve.should == :mounted
- end
+ it "should not mount itself if it is unmounted and should be defined" do
+ @provider.stubs(:ensure).returns(:unmounted)
+ @provider.stubs(:mounted?).returns(false)
- it "should return :unmounted if the provider indicates it is not mounted and the value is not :absent" do
- @provider.expects(:ensure).returns(:present)
- @provider.expects(:mounted?).returns(false)
- @ensure.retrieve.should == :unmounted
- end
+ @ensure.stubs(:syncothers)
+ @provider.stubs(:create)
+ @provider.expects(:mount).never
+ @provider.expects(:unmount).never
+ @ensure.should = :present
+ @ensure.sync
end
- describe Puppet::Type.type(:mount)::Ensure, "when changing the host" do
-
- it "should destroy itself if it should be absent" do
- @provider.stubs(:mounted?).returns(false)
- @provider.expects(:destroy)
- @ensure.should = :absent
- @ensure.sync
- end
-
- it "should unmount itself before destroying if it is mounted and should be absent" do
- @provider.expects(:mounted?).returns(true)
- @provider.expects(:unmount)
- @provider.expects(:destroy)
- @ensure.should = :absent
- @ensure.sync
- end
-
- it "should create itself if it is absent and should be defined" do
- @provider.stubs(:ensure).returns(:absent)
- @provider.stubs(:mounted?).returns(true)
-
- @provider.stubs(:mounted?).returns(false)
- @provider.expects(:create)
- @ensure.should = :defined
- @ensure.sync
- end
-
- it "should not unmount itself if it is mounted and should be defined" do
- @provider.stubs(:ensure).returns(:mounted)
- @provider.stubs(:mounted?).returns(true)
-
- @provider.stubs(:create)
- @provider.expects(:mount).never
- @provider.expects(:unmount).never
- @ensure.should = :defined
- @ensure.sync
- end
-
- it "should not mount itself if it is unmounted and should be defined" do
- @provider.stubs(:ensure).returns(:unmounted)
- @provider.stubs(:mounted?).returns(false)
-
- @ensure.stubs(:syncothers)
- @provider.stubs(:create)
- @provider.expects(:mount).never
- @provider.expects(:unmount).never
- @ensure.should = :present
- @ensure.sync
- end
-
- it "should unmount itself if it is mounted and should be unmounted" do
- @provider.stubs(:ensure).returns(:present)
- @provider.stubs(:mounted?).returns(true)
-
- @ensure.stubs(:syncothers)
- @provider.expects(:unmount)
- @ensure.should = :unmounted
- @ensure.sync
- end
-
- it "should create and mount itself if it does not exist and should be mounted" do
- @provider.stubs(:ensure).returns(:absent)
- @provider.stubs(:mounted?).returns(false)
- @provider.expects(:create)
- @ensure.stubs(:syncothers)
- @provider.expects(:mount)
- @ensure.should = :mounted
- @ensure.sync
- end
-
- it "should mount itself if it is present and should be mounted" do
- @provider.stubs(:ensure).returns(:present)
- @provider.stubs(:mounted?).returns(false)
- @ensure.stubs(:syncothers)
- @provider.expects(:mount)
- @ensure.should = :mounted
- @ensure.sync
- end
-
- it "should create but not mount itself if it is absent and mounted and should be mounted" do
- @provider.stubs(:ensure).returns(:absent)
- @provider.stubs(:mounted?).returns(true)
- @ensure.stubs(:syncothers)
- @provider.expects(:create)
- @ensure.should = :mounted
- @ensure.sync
- end
-
- it "should be insync if it is mounted and should be defined" do
- @ensure.should = :defined
- @ensure.insync?(:mounted).should == true
- end
-
- it "should be insync if it is unmounted and should be defined" do
- @ensure.should = :defined
- @ensure.insync?(:unmounted).should == true
- end
-
- it "should be insync if it is mounted and should be present" do
- @ensure.should = :present
- @ensure.insync?(:mounted).should == true
- end
-
- it "should be insync if it is unmounted and should be present" do
- @ensure.should = :present
- @ensure.insync?(:unmounted).should == true
- end
+ it "should unmount itself if it is mounted and should be unmounted" do
+ @provider.stubs(:ensure).returns(:present)
+ @provider.stubs(:mounted?).returns(true)
+
+ @ensure.stubs(:syncothers)
+ @provider.expects(:unmount)
+ @ensure.should = :unmounted
+ @ensure.sync
end
- describe Puppet::Type.type(:mount), "when responding to events" do
+ it "should create and mount itself if it does not exist and should be mounted" do
+ @provider.stubs(:ensure).returns(:absent)
+ @provider.stubs(:mounted?).returns(false)
+ @provider.expects(:create)
+ @ensure.stubs(:syncothers)
+ @provider.expects(:mount)
+ @ensure.should = :mounted
+ @ensure.sync
+ end
- it "should remount if it is currently mounted" do
- @provider.expects(:mounted?).returns(true)
- @provider.expects(:remount)
+ it "should mount itself if it is present and should be mounted" do
+ @provider.stubs(:ensure).returns(:present)
+ @provider.stubs(:mounted?).returns(false)
+ @ensure.stubs(:syncothers)
+ @provider.expects(:mount)
+ @ensure.should = :mounted
+ @ensure.sync
+ end
- @mount.refresh
- end
+ it "should create but not mount itself if it is absent and mounted and should be mounted" do
+ @provider.stubs(:ensure).returns(:absent)
+ @provider.stubs(:mounted?).returns(true)
+ @ensure.stubs(:syncothers)
+ @provider.expects(:create)
+ @ensure.should = :mounted
+ @ensure.sync
+ end
- it "should not remount if it is not currently mounted" do
- @provider.expects(:mounted?).returns(false)
- @provider.expects(:remount).never
+ it "should be insync if it is mounted and should be defined" do
+ @ensure.should = :defined
+ @ensure.insync?(:mounted).should == true
+ end
- @mount.refresh
- end
+ it "should be insync if it is unmounted and should be defined" do
+ @ensure.should = :defined
+ @ensure.insync?(:unmounted).should == true
+ end
- it "should not remount swap filesystems" do
- @mount[:fstype] = "swap"
- @provider.expects(:remount).never
+ it "should be insync if it is mounted and should be present" do
+ @ensure.should = :present
+ @ensure.insync?(:mounted).should == true
+ end
- @mount.refresh
- end
+ it "should be insync if it is unmounted and should be present" do
+ @ensure.should = :present
+ @ensure.insync?(:unmounted).should == true
end
-end
+ end
-describe Puppet::Type.type(:mount), "when modifying an existing mount entry" do
- before do
- @provider = stub 'provider', :class => Puppet::Type.type(:mount).defaultprovider, :clear => nil, :satisfies? => true, :name => :mock, :remount => nil
- Puppet::Type.type(:mount).defaultprovider.stubs(:new).returns(@provider)
- @mount = Puppet::Type.type(:mount).new(:name => "yay", :ensure => :mounted)
+ describe Puppet::Type.type(:mount), "when responding to events" do
- {:device => "/foo/bar", :blockdevice => "/other/bar", :target => "/what/ever", :fstype => 'eh', :options => "", :pass => 0, :dump => 0, :atboot => 0,
- :ensure => :mounted}.each do
- |param, value|
- @mount.provider.stubs(param).returns value
- @mount[param] = value
- end
+ it "should remount if it is currently mounted" do
+ @provider.expects(:mounted?).returns(true)
+ @provider.expects(:remount)
- @mount.provider.stubs(:mounted?).returns true
+ @mount.refresh
+ end
- # stub this to not try to create state.yaml
- Puppet::Util::Storage.stubs(:store)
+ it "should not remount if it is not currently mounted" do
+ @provider.expects(:mounted?).returns(false)
+ @provider.expects(:remount).never
- @catalog = Puppet::Resource::Catalog.new
- @catalog.add_resource @mount
+ @mount.refresh
end
- it "should use the provider to change the dump value" do
- @mount.provider.expects(:dump).returns 0
- @mount.provider.expects(:dump=).with(1)
+ it "should not remount swap filesystems" do
+ @mount[:fstype] = "swap"
+ @provider.expects(:remount).never
- @mount[:dump] = 1
+ @mount.refresh
+ end
+ end
+end
- @catalog.apply
+describe Puppet::Type.type(:mount), "when modifying an existing mount entry" do
+ before do
+ @provider = stub 'provider', :class => Puppet::Type.type(:mount).defaultprovider, :clear => nil, :satisfies? => true, :name => :mock, :remount => nil
+ Puppet::Type.type(:mount).defaultprovider.stubs(:new).returns(@provider)
+ @mount = Puppet::Type.type(:mount).new(:name => "yay", :ensure => :mounted)
+
+ {:device => "/foo/bar", :blockdevice => "/other/bar", :target => "/what/ever", :fstype => 'eh', :options => "", :pass => 0, :dump => 0, :atboot => 0,
+ :ensure => :mounted}.each do
+ |param, value|
+ @mount.provider.stubs(param).returns value
+ @mount[param] = value
end
+
+ @mount.provider.stubs(:mounted?).returns true
+
+ # stub this to not try to create state.yaml
+ Puppet::Util::Storage.stubs(:store)
+
+ @catalog = Puppet::Resource::Catalog.new
+ @catalog.add_resource @mount
+ end
+
+ it "should use the provider to change the dump value" do
+ @mount.provider.expects(:dump).returns 0
+ @mount.provider.expects(:dump=).with(1)
+
+ @mount[:dump] = 1
+
+ @catalog.apply
+ end
end
diff --git a/spec/unit/type/nagios_spec.rb b/spec/unit/type/nagios_spec.rb
index bb891e6..2acbd39 100755
--- a/spec/unit/type/nagios_spec.rb
+++ b/spec/unit/type/nagios_spec.rb
@@ -5,59 +5,59 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/external/nagios'
describe "Nagios resource types" do
- Nagios::Base.eachtype do |name, nagios_type|
- puppet_type = Puppet::Type.type("nagios_#{name}")
+ Nagios::Base.eachtype do |name, nagios_type|
+ puppet_type = Puppet::Type.type("nagios_#{name}")
- it "should have a valid type for #{name}" do
- puppet_type.should_not be_nil
- end
+ it "should have a valid type for #{name}" do
+ puppet_type.should_not be_nil
+ end
- next unless puppet_type
+ next unless puppet_type
- describe puppet_type do
- it "should be defined as a Puppet resource type" do
- puppet_type.should_not be_nil
- end
+ describe puppet_type do
+ it "should be defined as a Puppet resource type" do
+ puppet_type.should_not be_nil
+ end
- it "should have documentation" do
- puppet_type.instance_variable_get("@doc").should_not == ""
- end
+ it "should have documentation" do
+ puppet_type.instance_variable_get("@doc").should_not == ""
+ end
- it "should have #{nagios_type.namevar} as its key attribute" do
- puppet_type.key_attributes.should == [nagios_type.namevar]
- end
+ it "should have #{nagios_type.namevar} as its key attribute" do
+ puppet_type.key_attributes.should == [nagios_type.namevar]
+ end
- it "should have documentation for its #{nagios_type.namevar} parameter" do
- puppet_type.attrclass(nagios_type.namevar).instance_variable_get("@doc").should_not be_nil
- end
+ it "should have documentation for its #{nagios_type.namevar} parameter" do
+ puppet_type.attrclass(nagios_type.namevar).instance_variable_get("@doc").should_not be_nil
+ end
- it "should have an ensure property" do
- puppet_type.should be_validproperty(:ensure)
- end
+ it "should have an ensure property" do
+ puppet_type.should be_validproperty(:ensure)
+ end
- it "should have a target property" do
- puppet_type.should be_validproperty(:target)
- end
+ it "should have a target property" do
+ puppet_type.should be_validproperty(:target)
+ end
- it "should have documentation for its target property" do
- puppet_type.attrclass(:target).instance_variable_get("@doc").should_not be_nil
- end
+ it "should have documentation for its target property" do
+ puppet_type.attrclass(:target).instance_variable_get("@doc").should_not be_nil
+ end
- nagios_type.parameters.reject { |param| param == nagios_type.namevar or param.to_s =~ /^[0-9]/ }.each do |param|
- it "should have a #{param} property" do
- puppet_type.should be_validproperty(param)
- end
+ nagios_type.parameters.reject { |param| param == nagios_type.namevar or param.to_s =~ /^[0-9]/ }.each do |param|
+ it "should have a #{param} property" do
+ puppet_type.should be_validproperty(param)
+ end
- it "should have documentation for its #{param} property" do
- puppet_type.attrclass(param).instance_variable_get("@doc").should_not be_nil
- end
- end
+ it "should have documentation for its #{param} property" do
+ puppet_type.attrclass(param).instance_variable_get("@doc").should_not be_nil
+ end
+ end
- nagios_type.parameters.find_all { |param| param.to_s =~ /^[0-9]/ }.each do |param|
- it "should have not have a #{param} property" do
- puppet_type.should_not be_validproperty(:param)
- end
- end
+ nagios_type.parameters.find_all { |param| param.to_s =~ /^[0-9]/ }.each do |param|
+ it "should have not have a #{param} property" do
+ puppet_type.should_not be_validproperty(:param)
end
+ end
end
+ end
end
diff --git a/spec/unit/type/noop_metaparam_spec.rb b/spec/unit/type/noop_metaparam_spec.rb
index 2c4b6dc..5ab2d9b 100755
--- a/spec/unit/type/noop_metaparam_spec.rb
+++ b/spec/unit/type/noop_metaparam_spec.rb
@@ -5,33 +5,33 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/type'
describe Puppet::Type.type(:file).attrclass(:noop) do
- before do
- Puppet.settings.stubs(:use)
- @file = Puppet::Type.newfile :path => "/what/ever"
+ before do
+ Puppet.settings.stubs(:use)
+ @file = Puppet::Type.newfile :path => "/what/ever"
+ end
+
+ it "should accept true as a value" do
+ lambda { @file[:noop] = true }.should_not raise_error
+ end
+
+ it "should accept false as a value" do
+ lambda { @file[:noop] = false }.should_not raise_error
+ end
+
+ describe "when set on a resource" do
+ it "should default to the :noop setting" do
+ Puppet.settings.expects(:value).with(:noop).returns "myval"
+ @file.noop.should == "myval"
end
- it "should accept true as a value" do
- lambda { @file[:noop] = true }.should_not raise_error
+ it "should prefer true values from the attribute" do
+ @file[:noop] = true
+ @file.noop.should be_true
end
- it "should accept false as a value" do
- lambda { @file[:noop] = false }.should_not raise_error
- end
-
- describe "when set on a resource" do
- it "should default to the :noop setting" do
- Puppet.settings.expects(:value).with(:noop).returns "myval"
- @file.noop.should == "myval"
- end
-
- it "should prefer true values from the attribute" do
- @file[:noop] = true
- @file.noop.should be_true
- end
-
- it "should prefer false values from the attribute" do
- @file[:noop] = false
- @file.noop.should be_false
- end
+ it "should prefer false values from the attribute" do
+ @file[:noop] = false
+ @file.noop.should be_false
end
+ end
end
diff --git a/spec/unit/type/package_spec.rb b/spec/unit/type/package_spec.rb
index 02f3f9f..b0c5d22 100755
--- a/spec/unit/type/package_spec.rb
+++ b/spec/unit/type/package_spec.rb
@@ -3,238 +3,238 @@
require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::Type.type(:package) do
- before do
- Puppet::Util::Storage.stubs(:store)
+ before do
+ Puppet::Util::Storage.stubs(:store)
+ end
+
+ it "should have an :installable feature that requires the :install method" do
+ Puppet::Type.type(:package).provider_feature(:installable).methods.should == [:install]
+ end
+
+ it "should have an :uninstallable feature that requires the :uninstall method" do
+ Puppet::Type.type(:package).provider_feature(:uninstallable).methods.should == [:uninstall]
+ end
+
+ it "should have an :upgradeable feature that requires :update and :latest methods" do
+ Puppet::Type.type(:package).provider_feature(:upgradeable).methods.should == [:update, :latest]
+ end
+
+ it "should have a :purgeable feature that requires the :purge latest method" do
+ Puppet::Type.type(:package).provider_feature(:purgeable).methods.should == [:purge]
+ end
+
+ it "should have a :versionable feature" do
+ Puppet::Type.type(:package).provider_feature(:versionable).should_not be_nil
+ end
+
+ it "should default to being installed" do
+ pkg = Puppet::Type.type(:package).new(:name => "yay")
+ pkg.should(:ensure).should == :present
+ end
+
+ describe "when validating attributes" do
+ [:name, :source, :instance, :status, :adminfile, :responsefile, :configfiles, :category, :platform, :root, :vendor, :description, :allowcdrom].each do |param|
+ it "should have a #{param} parameter" do
+ Puppet::Type.type(:package).attrtype(param).should == :param
+ end
end
- it "should have an :installable feature that requires the :install method" do
- Puppet::Type.type(:package).provider_feature(:installable).methods.should == [:install]
+ it "should have an ensure property" do
+ Puppet::Type.type(:package).attrtype(:ensure).should == :property
end
+ end
- it "should have an :uninstallable feature that requires the :uninstall method" do
- Puppet::Type.type(:package).provider_feature(:uninstallable).methods.should == [:uninstall]
+ describe "when validating attribute values" do
+ before do
+ @provider = stub 'provider', :class => Puppet::Type.type(:package).defaultprovider, :clear => nil
+ Puppet::Type.type(:package).defaultprovider.expects(:new).returns(@provider)
end
- it "should have an :upgradeable feature that requires :update and :latest methods" do
- Puppet::Type.type(:package).provider_feature(:upgradeable).methods.should == [:update, :latest]
+ it "should support :present as a value to :ensure" do
+ Puppet::Type.type(:package).new(:name => "yay", :ensure => :present)
end
- it "should have a :purgeable feature that requires the :purge latest method" do
- Puppet::Type.type(:package).provider_feature(:purgeable).methods.should == [:purge]
+ it "should alias :installed to :present as a value to :ensure" do
+ pkg = Puppet::Type.type(:package).new(:name => "yay", :ensure => :installed)
+ pkg.should(:ensure).should == :present
end
- it "should have a :versionable feature" do
- Puppet::Type.type(:package).provider_feature(:versionable).should_not be_nil
+ it "should support :absent as a value to :ensure" do
+ Puppet::Type.type(:package).new(:name => "yay", :ensure => :absent)
end
- it "should default to being installed" do
- pkg = Puppet::Type.type(:package).new(:name => "yay")
- pkg.should(:ensure).should == :present
+ it "should support :purged as a value to :ensure if the provider has the :purgeable feature" do
+ @provider.expects(:satisfies?).with([:purgeable]).returns(true)
+ Puppet::Type.type(:package).new(:name => "yay", :ensure => :purged)
end
- describe "when validating attributes" do
- [:name, :source, :instance, :status, :adminfile, :responsefile, :configfiles, :category, :platform, :root, :vendor, :description, :allowcdrom].each do |param|
- it "should have a #{param} parameter" do
- Puppet::Type.type(:package).attrtype(param).should == :param
- end
- end
+ it "should not support :purged as a value to :ensure if the provider does not have the :purgeable feature" do
+ @provider.expects(:satisfies?).with([:purgeable]).returns(false)
+ proc { Puppet::Type.type(:package).new(:name => "yay", :ensure => :purged) }.should raise_error(Puppet::Error)
+ end
- it "should have an ensure property" do
- Puppet::Type.type(:package).attrtype(:ensure).should == :property
- end
+ it "should support :latest as a value to :ensure if the provider has the :upgradeable feature" do
+ @provider.expects(:satisfies?).with([:upgradeable]).returns(true)
+ Puppet::Type.type(:package).new(:name => "yay", :ensure => :latest)
end
- describe "when validating attribute values" do
- before do
- @provider = stub 'provider', :class => Puppet::Type.type(:package).defaultprovider, :clear => nil
- Puppet::Type.type(:package).defaultprovider.expects(:new).returns(@provider)
- end
+ it "should not support :latest as a value to :ensure if the provider does not have the :upgradeable feature" do
+ @provider.expects(:satisfies?).with([:upgradeable]).returns(false)
+ proc { Puppet::Type.type(:package).new(:name => "yay", :ensure => :latest) }.should raise_error(Puppet::Error)
+ end
- it "should support :present as a value to :ensure" do
- Puppet::Type.type(:package).new(:name => "yay", :ensure => :present)
- end
+ it "should support version numbers as a value to :ensure if the provider has the :versionable feature" do
+ @provider.expects(:satisfies?).with([:versionable]).returns(true)
+ Puppet::Type.type(:package).new(:name => "yay", :ensure => "1.0")
+ end
- it "should alias :installed to :present as a value to :ensure" do
- pkg = Puppet::Type.type(:package).new(:name => "yay", :ensure => :installed)
- pkg.should(:ensure).should == :present
- end
+ it "should not support version numbers as a value to :ensure if the provider does not have the :versionable feature" do
+ @provider.expects(:satisfies?).with([:versionable]).returns(false)
+ proc { Puppet::Type.type(:package).new(:name => "yay", :ensure => "1.0") }.should raise_error(Puppet::Error)
+ end
- it "should support :absent as a value to :ensure" do
- Puppet::Type.type(:package).new(:name => "yay", :ensure => :absent)
- end
+ it "should accept any string as an argument to :source" do
+ proc { Puppet::Type.type(:package).new(:name => "yay", :source => "stuff") }.should_not raise_error(Puppet::Error)
+ end
+ end
- it "should support :purged as a value to :ensure if the provider has the :purgeable feature" do
- @provider.expects(:satisfies?).with([:purgeable]).returns(true)
- Puppet::Type.type(:package).new(:name => "yay", :ensure => :purged)
- end
+ module PackageEvaluationTesting
+ def setprops(properties)
+ @provider.stubs(:properties).returns(properties)
+ end
+ end
- it "should not support :purged as a value to :ensure if the provider does not have the :purgeable feature" do
- @provider.expects(:satisfies?).with([:purgeable]).returns(false)
- proc { Puppet::Type.type(:package).new(:name => "yay", :ensure => :purged) }.should raise_error(Puppet::Error)
- end
+ describe Puppet::Type.type(:package) do
+ before :each do
+ @provider = stub 'provider', :class => Puppet::Type.type(:package).defaultprovider, :clear => nil, :satisfies? => true, :name => :mock
+ Puppet::Type.type(:package).defaultprovider.stubs(:new).returns(@provider)
+ Puppet::Type.type(:package).defaultprovider.stubs(:instances).returns([])
+ @package = Puppet::Type.type(:package).new(:name => "yay")
- it "should support :latest as a value to :ensure if the provider has the :upgradeable feature" do
- @provider.expects(:satisfies?).with([:upgradeable]).returns(true)
- Puppet::Type.type(:package).new(:name => "yay", :ensure => :latest)
- end
+ @catalog = Puppet::Resource::Catalog.new
+ @catalog.add_resource(@package)
+ end
- it "should not support :latest as a value to :ensure if the provider does not have the :upgradeable feature" do
- @provider.expects(:satisfies?).with([:upgradeable]).returns(false)
- proc { Puppet::Type.type(:package).new(:name => "yay", :ensure => :latest) }.should raise_error(Puppet::Error)
- end
+ describe Puppet::Type.type(:package), "when it should be purged" do
+ include PackageEvaluationTesting
- it "should support version numbers as a value to :ensure if the provider has the :versionable feature" do
- @provider.expects(:satisfies?).with([:versionable]).returns(true)
- Puppet::Type.type(:package).new(:name => "yay", :ensure => "1.0")
- end
+ before { @package[:ensure] = :purged }
- it "should not support version numbers as a value to :ensure if the provider does not have the :versionable feature" do
- @provider.expects(:satisfies?).with([:versionable]).returns(false)
- proc { Puppet::Type.type(:package).new(:name => "yay", :ensure => "1.0") }.should raise_error(Puppet::Error)
- end
+ it "should do nothing if it is :purged" do
+ @provider.expects(:properties).returns(:ensure => :purged)
+ @catalog.apply
+ end
- it "should accept any string as an argument to :source" do
- proc { Puppet::Type.type(:package).new(:name => "yay", :source => "stuff") }.should_not raise_error(Puppet::Error)
+ [:absent, :installed, :present, :latest].each do |state|
+ it "should purge if it is #{state.to_s}" do
+ @provider.stubs(:properties).returns(:ensure => state)
+ @provider.expects(:purge)
+ @catalog.apply
end
+ end
end
- module PackageEvaluationTesting
- def setprops(properties)
- @provider.stubs(:properties).returns(properties)
- end
- end
+ describe Puppet::Type.type(:package), "when it should be absent" do
+ include PackageEvaluationTesting
- describe Puppet::Type.type(:package) do
- before :each do
- @provider = stub 'provider', :class => Puppet::Type.type(:package).defaultprovider, :clear => nil, :satisfies? => true, :name => :mock
- Puppet::Type.type(:package).defaultprovider.stubs(:new).returns(@provider)
- Puppet::Type.type(:package).defaultprovider.stubs(:instances).returns([])
- @package = Puppet::Type.type(:package).new(:name => "yay")
+ before { @package[:ensure] = :absent }
- @catalog = Puppet::Resource::Catalog.new
- @catalog.add_resource(@package)
+ [:purged, :absent].each do |state|
+ it "should do nothing if it is #{state.to_s}" do
+ @provider.expects(:properties).returns(:ensure => state)
+ @catalog.apply
end
+ end
- describe Puppet::Type.type(:package), "when it should be purged" do
- include PackageEvaluationTesting
+ [:installed, :present, :latest].each do |state|
+ it "should uninstall if it is #{state.to_s}" do
+ @provider.stubs(:properties).returns(:ensure => state)
+ @provider.expects(:uninstall)
+ @catalog.apply
+ end
+ end
+ end
- before { @package[:ensure] = :purged }
+ describe Puppet::Type.type(:package), "when it should be present" do
+ include PackageEvaluationTesting
- it "should do nothing if it is :purged" do
- @provider.expects(:properties).returns(:ensure => :purged)
- @catalog.apply
- end
+ before { @package[:ensure] = :present }
- [:absent, :installed, :present, :latest].each do |state|
- it "should purge if it is #{state.to_s}" do
- @provider.stubs(:properties).returns(:ensure => state)
- @provider.expects(:purge)
- @catalog.apply
- end
- end
+ [:present, :latest, "1.0"].each do |state|
+ it "should do nothing if it is #{state.to_s}" do
+ @provider.expects(:properties).returns(:ensure => state)
+ @catalog.apply
end
+ end
- describe Puppet::Type.type(:package), "when it should be absent" do
- include PackageEvaluationTesting
-
- before { @package[:ensure] = :absent }
-
- [:purged, :absent].each do |state|
- it "should do nothing if it is #{state.to_s}" do
- @provider.expects(:properties).returns(:ensure => state)
- @catalog.apply
- end
- end
-
- [:installed, :present, :latest].each do |state|
- it "should uninstall if it is #{state.to_s}" do
- @provider.stubs(:properties).returns(:ensure => state)
- @provider.expects(:uninstall)
- @catalog.apply
- end
- end
+ [:purged, :absent].each do |state|
+ it "should install if it is #{state.to_s}" do
+ @provider.stubs(:properties).returns(:ensure => state)
+ @provider.expects(:install)
+ @catalog.apply
end
+ end
+ end
- describe Puppet::Type.type(:package), "when it should be present" do
- include PackageEvaluationTesting
-
- before { @package[:ensure] = :present }
-
- [:present, :latest, "1.0"].each do |state|
- it "should do nothing if it is #{state.to_s}" do
- @provider.expects(:properties).returns(:ensure => state)
- @catalog.apply
- end
- end
-
- [:purged, :absent].each do |state|
- it "should install if it is #{state.to_s}" do
- @provider.stubs(:properties).returns(:ensure => state)
- @provider.expects(:install)
- @catalog.apply
- end
- end
- end
+ describe Puppet::Type.type(:package), "when it should be latest" do
+ include PackageEvaluationTesting
+
+ before { @package[:ensure] = :latest }
+
+ [:purged, :absent].each do |state|
+ it "should upgrade if it is #{state.to_s}" do
+ @provider.stubs(:properties).returns(:ensure => state)
+ @provider.expects(:update)
+ @catalog.apply
+ end
+ end
+
+ it "should upgrade if the current version is not equal to the latest version" do
+ @provider.stubs(:properties).returns(:ensure => "1.0")
+ @provider.stubs(:latest).returns("2.0")
+ @provider.expects(:update)
+ @catalog.apply
+ end
+
+ it "should do nothing if it is equal to the latest version" do
+ @provider.stubs(:properties).returns(:ensure => "1.0")
+ @provider.stubs(:latest).returns("1.0")
+ @provider.expects(:update).never
+ @catalog.apply
+ end
+
+ it "should do nothing if the provider returns :present as the latest version" do
+ @provider.stubs(:properties).returns(:ensure => :present)
+ @provider.stubs(:latest).returns("1.0")
+ @provider.expects(:update).never
+ @catalog.apply
+ end
+ end
- describe Puppet::Type.type(:package), "when it should be latest" do
- include PackageEvaluationTesting
-
- before { @package[:ensure] = :latest }
-
- [:purged, :absent].each do |state|
- it "should upgrade if it is #{state.to_s}" do
- @provider.stubs(:properties).returns(:ensure => state)
- @provider.expects(:update)
- @catalog.apply
- end
- end
-
- it "should upgrade if the current version is not equal to the latest version" do
- @provider.stubs(:properties).returns(:ensure => "1.0")
- @provider.stubs(:latest).returns("2.0")
- @provider.expects(:update)
- @catalog.apply
- end
-
- it "should do nothing if it is equal to the latest version" do
- @provider.stubs(:properties).returns(:ensure => "1.0")
- @provider.stubs(:latest).returns("1.0")
- @provider.expects(:update).never
- @catalog.apply
- end
-
- it "should do nothing if the provider returns :present as the latest version" do
- @provider.stubs(:properties).returns(:ensure => :present)
- @provider.stubs(:latest).returns("1.0")
- @provider.expects(:update).never
- @catalog.apply
- end
- end
+ describe Puppet::Type.type(:package), "when it should be a specific version" do
+ include PackageEvaluationTesting
+
+ before { @package[:ensure] = "1.0" }
- describe Puppet::Type.type(:package), "when it should be a specific version" do
- include PackageEvaluationTesting
-
- before { @package[:ensure] = "1.0" }
-
- [:purged, :absent].each do |state|
- it "should install if it is #{state.to_s}" do
- @provider.stubs(:properties).returns(:ensure => state)
- @provider.expects(:install)
- @catalog.apply
- end
- end
-
- it "should do nothing if the current version is equal to the desired version" do
- @provider.stubs(:properties).returns(:ensure => "1.0")
- @provider.expects(:install).never
- @catalog.apply
- end
-
- it "should install if the current version is not equal to the specified version" do
- @provider.stubs(:properties).returns(:ensure => "2.0")
- @provider.expects(:install)
- @catalog.apply
- end
+ [:purged, :absent].each do |state|
+ it "should install if it is #{state.to_s}" do
+ @provider.stubs(:properties).returns(:ensure => state)
+ @provider.expects(:install)
+ @catalog.apply
end
+ end
+
+ it "should do nothing if the current version is equal to the desired version" do
+ @provider.stubs(:properties).returns(:ensure => "1.0")
+ @provider.expects(:install).never
+ @catalog.apply
+ end
+
+ it "should install if the current version is not equal to the specified version" do
+ @provider.stubs(:properties).returns(:ensure => "2.0")
+ @provider.expects(:install)
+ @catalog.apply
+ end
end
+ end
end
diff --git a/spec/unit/type/resources_spec.rb b/spec/unit/type/resources_spec.rb
index 2e1cb3a..9d95559 100644
--- a/spec/unit/type/resources_spec.rb
+++ b/spec/unit/type/resources_spec.rb
@@ -6,97 +6,97 @@ resources = Puppet::Type.type(:resources)
# There are still plenty of tests to port over from test/.
describe resources do
- describe "when initializing" do
- it "should fail if the specified resource type does not exist" do
- Puppet::Type.stubs(:type).with { |x| x.to_s.downcase == "resources"}.returns resources
- Puppet::Type.expects(:type).with("nosuchtype").returns nil
- lambda { resources.new :name => "nosuchtype" }.should raise_error(Puppet::Error)
- end
+ describe "when initializing" do
+ it "should fail if the specified resource type does not exist" do
+ Puppet::Type.stubs(:type).with { |x| x.to_s.downcase == "resources"}.returns resources
+ Puppet::Type.expects(:type).with("nosuchtype").returns nil
+ lambda { resources.new :name => "nosuchtype" }.should raise_error(Puppet::Error)
+ end
+
+ it "should not fail when the specified resource type exists" do
+ lambda { resources.new :name => "file" }.should_not raise_error
+ end
+
+ it "should set its :resource_type attribute" do
+ resources.new(:name => "file").resource_type.should == Puppet::Type.type(:file)
+ end
+ end
- it "should not fail when the specified resource type exists" do
- lambda { resources.new :name => "file" }.should_not raise_error
+ describe "#generate" do
+ before do
+ @host1 = Puppet::Type.type(:host).new(:name => 'localhost', :ip => '127.0.0.1')
+ @catalog = Puppet::Resource::Catalog.new
+ @context = Puppet::Transaction.new(@catalog)
+ end
+
+ describe "when dealing with non-purging resources" do
+ before do
+ @resources = Puppet::Type.type(:resources).new(:name => 'host')
end
- it "should set its :resource_type attribute" do
- resources.new(:name => "file").resource_type.should == Puppet::Type.type(:file)
+ it "should not generate any resource" do
+ @resources.generate.should be_empty
end
- end
+ end
- describe "#generate" do
+ describe "when the catalog contains a purging resource" do
before do
- @host1 = Puppet::Type.type(:host).new(:name => 'localhost', :ip => '127.0.0.1')
- @catalog = Puppet::Resource::Catalog.new
- @context = Puppet::Transaction.new(@catalog)
+ @resources = Puppet::Type.type(:resources).new(:name => 'host', :purge => true)
+ @purgeable_resource = Puppet::Type.type(:host).new(:name => 'localhost', :ip => '127.0.0.1')
+ @catalog.add_resource @resources
end
- describe "when dealing with non-purging resources" do
- before do
- @resources = Puppet::Type.type(:resources).new(:name => 'host')
- end
-
- it "should not generate any resource" do
- @resources.generate.should be_empty
- end
- end
-
- describe "when the catalog contains a purging resource" do
- before do
- @resources = Puppet::Type.type(:resources).new(:name => 'host', :purge => true)
- @purgeable_resource = Puppet::Type.type(:host).new(:name => 'localhost', :ip => '127.0.0.1')
- @catalog.add_resource @resources
- end
-
- it "should not generate a duplicate of that resource" do
- Puppet::Type.type(:host).stubs(:instances).returns [@host1]
- @catalog.add_resource @host1
- @resources.generate.collect { |r| r.ref }.should_not include(@host1.ref)
- end
-
- it "should not include the skipped users" do
- res = Puppet::Type.type(:resources).new :name => :user, :purge => true
- res.catalog = Puppet::Resource::Catalog.new
-
- users = [
- Puppet::Type.type(:user).new(:name => "root")
- ]
- Puppet::Type.type(:user).expects(:instances).returns users
- list = res.generate
-
- names = list.collect { |r| r[:name] }
- names.should_not be_include("root")
- end
-
- describe "when generating a purgeable resource" do
- it "should be included in the generated resources" do
- Puppet::Type.type(:host).stubs(:instances).returns [@purgeable_resource]
- @resources.generate.collect { |r| r.ref }.should include(@purgeable_resource.ref)
- end
- end
-
- describe "when the instance's do not have an ensure property" do
- it "should not be included in the generated resources" do
- @no_ensure_resource = Puppet::Type.type(:exec).new(:name => '/usr/bin/env echo')
- Puppet::Type.type(:host).stubs(:instances).returns [@no_ensure_resource]
- @resources.generate.collect { |r| r.ref }.should_not include(@no_ensure_resource.ref)
- end
- end
-
- describe "when the instance's ensure property does not accept absent" do
- it "should not be included in the generated resources" do
- @no_absent_resource = Puppet::Type.type(:service).new(:name => 'foobar')
- Puppet::Type.type(:host).stubs(:instances).returns [@no_absent_resource]
- @resources.generate.collect { |r| r.ref }.should_not include(@no_absent_resource.ref)
- end
- end
-
- describe "when checking the instance fails" do
- it "should not be included in the generated resources" do
- @purgeable_resource = Puppet::Type.type(:host).new(:name => 'foobar')
- Puppet::Type.type(:host).stubs(:instances).returns [@purgeable_resource]
- @resources.expects(:check).with(@purgeable_resource).returns(false)
- @resources.generate.collect { |r| r.ref }.should_not include(@purgeable_resource.ref)
- end
- end
- end
- end
+ it "should not generate a duplicate of that resource" do
+ Puppet::Type.type(:host).stubs(:instances).returns [@host1]
+ @catalog.add_resource @host1
+ @resources.generate.collect { |r| r.ref }.should_not include(@host1.ref)
+ end
+
+ it "should not include the skipped users" do
+ res = Puppet::Type.type(:resources).new :name => :user, :purge => true
+ res.catalog = Puppet::Resource::Catalog.new
+
+ users = [
+ Puppet::Type.type(:user).new(:name => "root")
+ ]
+ Puppet::Type.type(:user).expects(:instances).returns users
+ list = res.generate
+
+ names = list.collect { |r| r[:name] }
+ names.should_not be_include("root")
+ end
+
+ describe "when generating a purgeable resource" do
+ it "should be included in the generated resources" do
+ Puppet::Type.type(:host).stubs(:instances).returns [@purgeable_resource]
+ @resources.generate.collect { |r| r.ref }.should include(@purgeable_resource.ref)
+ end
+ end
+
+ describe "when the instance's do not have an ensure property" do
+ it "should not be included in the generated resources" do
+ @no_ensure_resource = Puppet::Type.type(:exec).new(:name => '/usr/bin/env echo')
+ Puppet::Type.type(:host).stubs(:instances).returns [@no_ensure_resource]
+ @resources.generate.collect { |r| r.ref }.should_not include(@no_ensure_resource.ref)
+ end
+ end
+
+ describe "when the instance's ensure property does not accept absent" do
+ it "should not be included in the generated resources" do
+ @no_absent_resource = Puppet::Type.type(:service).new(:name => 'foobar')
+ Puppet::Type.type(:host).stubs(:instances).returns [@no_absent_resource]
+ @resources.generate.collect { |r| r.ref }.should_not include(@no_absent_resource.ref)
+ end
+ end
+
+ describe "when checking the instance fails" do
+ it "should not be included in the generated resources" do
+ @purgeable_resource = Puppet::Type.type(:host).new(:name => 'foobar')
+ Puppet::Type.type(:host).stubs(:instances).returns [@purgeable_resource]
+ @resources.expects(:check).with(@purgeable_resource).returns(false)
+ @resources.generate.collect { |r| r.ref }.should_not include(@purgeable_resource.ref)
+ end
+ end
+ end
+ end
end
diff --git a/spec/unit/type/schedule_spec.rb b/spec/unit/type/schedule_spec.rb
index 0a13654..6975529 100755
--- a/spec/unit/type/schedule_spec.rb
+++ b/spec/unit/type/schedule_spec.rb
@@ -4,330 +4,330 @@ require File.dirname(__FILE__) + '/../../spec_helper'
module ScheduleTesting
- def format(time)
- time.strftime("%H:%M:%S")
- end
+ def format(time)
+ time.strftime("%H:%M:%S")
+ end
- def diff(unit, incr, method, count)
- diff = Time.now.to_i.send(method, incr * count)
- Time.at(diff)
- end
+ def diff(unit, incr, method, count)
+ diff = Time.now.to_i.send(method, incr * count)
+ Time.at(diff)
+ end
- def month(method, count)
- diff(:hour, 3600 * 24 * 30, method, count)
- end
+ def month(method, count)
+ diff(:hour, 3600 * 24 * 30, method, count)
+ end
- def week(method, count)
- diff(:hour, 3600 * 24 * 7, method, count)
- end
+ def week(method, count)
+ diff(:hour, 3600 * 24 * 7, method, count)
+ end
- def day(method, count)
- diff(:hour, 3600 * 24, method, count)
- end
+ def day(method, count)
+ diff(:hour, 3600 * 24, method, count)
+ end
- def hour(method, count)
- diff(:hour, 3600, method, count)
- end
+ def hour(method, count)
+ diff(:hour, 3600, method, count)
+ end
- def min(method, count)
- diff(:min, 60, method, count)
- end
+ def min(method, count)
+ diff(:min, 60, method, count)
+ end
- def sec(method, count)
- diff(:sec, 1, method, count)
- end
+ def sec(method, count)
+ diff(:sec, 1, method, count)
+ end
end
describe Puppet::Type.type(:schedule) do
- before :each do
- Puppet.settings.stubs(:value).with(:ignoreschedules).returns(false)
+ before :each do
+ Puppet.settings.stubs(:value).with(:ignoreschedules).returns(false)
- @schedule = Puppet::Type.type(:schedule).new(:name => "testing")
- end
+ @schedule = Puppet::Type.type(:schedule).new(:name => "testing")
+ end
- describe Puppet::Type.type(:schedule) do
- include ScheduleTesting
+ describe Puppet::Type.type(:schedule) do
+ include ScheduleTesting
- it "should default to :distance for period-matching" do
- @schedule[:periodmatch].should == :distance
- end
+ it "should default to :distance for period-matching" do
+ @schedule[:periodmatch].should == :distance
+ end
- it "should default to a :repeat of 1" do
- @schedule[:repeat].should == 1
- end
+ it "should default to a :repeat of 1" do
+ @schedule[:repeat].should == 1
+ end
- it "should never match when the period is :never" do
- @schedule[:period] = :never
- @schedule.match?.should be_false
- end
+ it "should never match when the period is :never" do
+ @schedule[:period] = :never
+ @schedule.match?.should be_false
end
+ end
- describe Puppet::Type.type(:schedule), "when producing default schedules" do
- include ScheduleTesting
+ describe Puppet::Type.type(:schedule), "when producing default schedules" do
+ include ScheduleTesting
- %w{hourly daily weekly monthly never}.each do |period|
- period = period.to_sym
- it "should produce a #{period} schedule with the period set appropriately" do
- schedules = Puppet::Type.type(:schedule).mkdefaultschedules
- schedules.find { |s| s[:name] == period.to_s and s[:period] == period }.should be_instance_of(Puppet::Type.type(:schedule))
- end
- end
+ %w{hourly daily weekly monthly never}.each do |period|
+ period = period.to_sym
+ it "should produce a #{period} schedule with the period set appropriately" do
+ schedules = Puppet::Type.type(:schedule).mkdefaultschedules
+ schedules.find { |s| s[:name] == period.to_s and s[:period] == period }.should be_instance_of(Puppet::Type.type(:schedule))
+ end
+ end
- it "should produce a schedule named puppet with a period of hourly and a repeat of 2" do
- schedules = Puppet::Type.type(:schedule).mkdefaultschedules
- schedules.find { |s|
- s[:name] == "puppet" and s[:period] == :hourly and s[:repeat] == 2
- }.should be_instance_of(Puppet::Type.type(:schedule))
- end
+ it "should produce a schedule named puppet with a period of hourly and a repeat of 2" do
+ schedules = Puppet::Type.type(:schedule).mkdefaultschedules
+ schedules.find { |s|
+ s[:name] == "puppet" and s[:period] == :hourly and s[:repeat] == 2
+ }.should be_instance_of(Puppet::Type.type(:schedule))
end
+ end
- describe Puppet::Type.type(:schedule), "when matching ranges" do
- include ScheduleTesting
+ describe Puppet::Type.type(:schedule), "when matching ranges" do
+ include ScheduleTesting
- it "should match when the start time is before the current time and the end time is after the current time" do
- @schedule[:range] = "#{format(Time.now - 10)} - #{format(Time.now + 10)}"
- @schedule.match?.should be_true
- end
+ it "should match when the start time is before the current time and the end time is after the current time" do
+ @schedule[:range] = "#{format(Time.now - 10)} - #{format(Time.now + 10)}"
+ @schedule.match?.should be_true
+ end
- it "should not match when the start time is after the current time" do
- @schedule[:range] = "#{format(Time.now + 5)} - #{format(Time.now + 10)}"
- @schedule.match?.should be_false
- end
+ it "should not match when the start time is after the current time" do
+ @schedule[:range] = "#{format(Time.now + 5)} - #{format(Time.now + 10)}"
+ @schedule.match?.should be_false
+ end
- it "should not match when the end time is previous to the current time" do
- @schedule[:range] = "#{format(Time.now - 10)} - #{format(Time.now - 5)}"
- @schedule.match?.should be_false
- end
+ it "should not match when the end time is previous to the current time" do
+ @schedule[:range] = "#{format(Time.now - 10)} - #{format(Time.now - 5)}"
+ @schedule.match?.should be_false
end
+ end
- describe Puppet::Type.type(:schedule), "when matching hourly by distance" do
- include ScheduleTesting
+ describe Puppet::Type.type(:schedule), "when matching hourly by distance" do
+ include ScheduleTesting
- before do
- @schedule[:period] = :hourly
- @schedule[:periodmatch] = :distance
- end
+ before do
+ @schedule[:period] = :hourly
+ @schedule[:periodmatch] = :distance
+ end
- it "should match an hour ago" do
- @schedule.match?(hour("-", 1)).should be_true
- end
+ it "should match an hour ago" do
+ @schedule.match?(hour("-", 1)).should be_true
+ end
- it "should not match now" do
- @schedule.match?(Time.now).should be_false
- end
+ it "should not match now" do
+ @schedule.match?(Time.now).should be_false
+ end
- it "should not match 59 minutes ago" do
- @schedule.match?(min("-", 59)).should be_false
- end
+ it "should not match 59 minutes ago" do
+ @schedule.match?(min("-", 59)).should be_false
end
+ end
- describe Puppet::Type.type(:schedule), "when matching daily by distance" do
- include ScheduleTesting
+ describe Puppet::Type.type(:schedule), "when matching daily by distance" do
+ include ScheduleTesting
- before do
- @schedule[:period] = :daily
- @schedule[:periodmatch] = :distance
- end
+ before do
+ @schedule[:period] = :daily
+ @schedule[:periodmatch] = :distance
+ end
- it "should match when the previous time was one day ago" do
- @schedule.match?(day("-", 1)).should be_true
- end
+ it "should match when the previous time was one day ago" do
+ @schedule.match?(day("-", 1)).should be_true
+ end
- it "should not match when the previous time is now" do
- @schedule.match?(Time.now).should be_false
- end
+ it "should not match when the previous time is now" do
+ @schedule.match?(Time.now).should be_false
+ end
- it "should not match when the previous time was 23 hours ago" do
- @schedule.match?(hour("-", 23)).should be_false
- end
+ it "should not match when the previous time was 23 hours ago" do
+ @schedule.match?(hour("-", 23)).should be_false
end
+ end
- describe Puppet::Type.type(:schedule), "when matching weekly by distance" do
- include ScheduleTesting
+ describe Puppet::Type.type(:schedule), "when matching weekly by distance" do
+ include ScheduleTesting
- before do
- @schedule[:period] = :weekly
- @schedule[:periodmatch] = :distance
- end
+ before do
+ @schedule[:period] = :weekly
+ @schedule[:periodmatch] = :distance
+ end
- it "should match seven days ago" do
- @schedule.match?(day("-", 7)).should be_true
- end
+ it "should match seven days ago" do
+ @schedule.match?(day("-", 7)).should be_true
+ end
- it "should not match now" do
- @schedule.match?(Time.now).should be_false
- end
+ it "should not match now" do
+ @schedule.match?(Time.now).should be_false
+ end
- it "should not match six days ago" do
- @schedule.match?(day("-", 6)).should be_false
- end
+ it "should not match six days ago" do
+ @schedule.match?(day("-", 6)).should be_false
end
+ end
- describe Puppet::Type.type(:schedule), "when matching monthly by distance" do
- include ScheduleTesting
+ describe Puppet::Type.type(:schedule), "when matching monthly by distance" do
+ include ScheduleTesting
- before do
- @schedule[:period] = :monthly
- @schedule[:periodmatch] = :distance
- end
+ before do
+ @schedule[:period] = :monthly
+ @schedule[:periodmatch] = :distance
+ end
- it "should match 32 days ago" do
- @schedule.match?(day("-", 32)).should be_true
- end
+ it "should match 32 days ago" do
+ @schedule.match?(day("-", 32)).should be_true
+ end
- it "should not match now" do
- @schedule.match?(Time.now).should be_false
- end
+ it "should not match now" do
+ @schedule.match?(Time.now).should be_false
+ end
- it "should not match 27 days ago" do
- @schedule.match?(day("-", 27)).should be_false
- end
+ it "should not match 27 days ago" do
+ @schedule.match?(day("-", 27)).should be_false
end
+ end
- describe Puppet::Type.type(:schedule), "when matching hourly by number" do
- include ScheduleTesting
+ describe Puppet::Type.type(:schedule), "when matching hourly by number" do
+ include ScheduleTesting
- before do
- @schedule[:period] = :hourly
- @schedule[:periodmatch] = :number
- end
+ before do
+ @schedule[:period] = :hourly
+ @schedule[:periodmatch] = :number
+ end
- it "should match if the times are one minute apart and the current minute is 0" do
- current = Time.now
+ it "should match if the times are one minute apart and the current minute is 0" do
+ current = Time.now
- # Subtract an hour, reset the minute to zero, then add 59 minutes, so we're the previous hour plus 59 minutes.
- previous = (current - 3600 - (current.min * 60) + (59 * 60))
+ # Subtract an hour, reset the minute to zero, then add 59 minutes, so we're the previous hour plus 59 minutes.
+ previous = (current - 3600 - (current.min * 60) + (59 * 60))
- # Now set the "current" time to the zero minute of the current hour.
- now = (current - (current.min * 60))
- Time.stubs(:now).returns(now)
- @schedule.match?(previous).should be_true
- end
+ # Now set the "current" time to the zero minute of the current hour.
+ now = (current - (current.min * 60))
+ Time.stubs(:now).returns(now)
+ @schedule.match?(previous).should be_true
+ end
- it "should not match if the times are 58 minutes apart and the current minute is 59" do
- current = Time.now
+ it "should not match if the times are 58 minutes apart and the current minute is 59" do
+ current = Time.now
- # reset the minute to zero
- previous = current - (current.min * 60)
+ # reset the minute to zero
+ previous = current - (current.min * 60)
- # Now set the "current" time to the 59th minute of the current hour.
- now = (current - (current.min * 60) + (59 * 60))
- Time.stubs(:now).returns(now)
- @schedule.match?(previous).should be_false
- end
+ # Now set the "current" time to the 59th minute of the current hour.
+ now = (current - (current.min * 60) + (59 * 60))
+ Time.stubs(:now).returns(now)
+ @schedule.match?(previous).should be_false
end
+ end
- describe Puppet::Type.type(:schedule), "when matching daily by number" do
- include ScheduleTesting
+ describe Puppet::Type.type(:schedule), "when matching daily by number" do
+ include ScheduleTesting
- before do
- @schedule[:period] = :daily
- @schedule[:periodmatch] = :number
- end
+ before do
+ @schedule[:period] = :daily
+ @schedule[:periodmatch] = :number
+ end
- it "should match if the times are one minute apart and the current minute and hour are 0" do
- zero = Time.now
+ it "should match if the times are one minute apart and the current minute and hour are 0" do
+ zero = Time.now
- # Reset the current time to X:00:00
- current = zero - (zero.hour * 3600) - (zero.min * 60) - zero.sec
+ # Reset the current time to X:00:00
+ current = zero - (zero.hour * 3600) - (zero.min * 60) - zero.sec
- # Now set the previous time to one minute before that
- previous = current - 60
+ # Now set the previous time to one minute before that
+ previous = current - 60
- Time.stubs(:now).returns(current)
- @schedule.match?(previous).should be_true
- end
+ Time.stubs(:now).returns(current)
+ @schedule.match?(previous).should be_true
+ end
- it "should not match if the times are 23 hours and 58 minutes apart and the current hour is 23 and the current minute is 59" do
- zero = Time.now
+ it "should not match if the times are 23 hours and 58 minutes apart and the current hour is 23 and the current minute is 59" do
+ zero = Time.now
- # Reset the previous time to 00:00:00
- previous = zero - (zero.hour * 3600) - (zero.min * 60) - zero.sec
+ # Reset the previous time to 00:00:00
+ previous = zero - (zero.hour * 3600) - (zero.min * 60) - zero.sec
- # Set the current time to 23:59
- now = previous + (23 * 3600) + (59 * 60)
+ # Set the current time to 23:59
+ now = previous + (23 * 3600) + (59 * 60)
- Time.stubs(:now).returns(now)
- @schedule.match?(previous).should be_false
- end
+ Time.stubs(:now).returns(now)
+ @schedule.match?(previous).should be_false
end
+ end
- describe Puppet::Type.type(:schedule), "when matching weekly by number" do
- include ScheduleTesting
+ describe Puppet::Type.type(:schedule), "when matching weekly by number" do
+ include ScheduleTesting
- before do
- @schedule[:period] = :weekly
- @schedule[:periodmatch] = :number
- end
+ before do
+ @schedule[:period] = :weekly
+ @schedule[:periodmatch] = :number
+ end
- it "should match if the previous time is prior to the most recent Sunday" do
- now = Time.now
+ it "should match if the previous time is prior to the most recent Sunday" do
+ now = Time.now
- # Subtract the number days we've progressed into the week, plus one because we're zero-indexed.
- previous = now - (3600 * 24 * (now.wday + 1))
+ # Subtract the number days we've progressed into the week, plus one because we're zero-indexed.
+ previous = now - (3600 * 24 * (now.wday + 1))
- @schedule.match?(previous).should be_true
- end
+ @schedule.match?(previous).should be_true
+ end
- it "should not match if the previous time is after the most recent Saturday" do
- now = Time.now
+ it "should not match if the previous time is after the most recent Saturday" do
+ now = Time.now
- # Subtract the number days we've progressed into the week
- previous = now - (3600 * 24 * now.wday)
+ # Subtract the number days we've progressed into the week
+ previous = now - (3600 * 24 * now.wday)
- @schedule.match?(previous).should be_false
- end
+ @schedule.match?(previous).should be_false
end
+ end
- describe Puppet::Type.type(:schedule), "when matching monthly by number" do
- include ScheduleTesting
+ describe Puppet::Type.type(:schedule), "when matching monthly by number" do
+ include ScheduleTesting
- before do
- @schedule[:period] = :monthly
- @schedule[:periodmatch] = :number
- end
+ before do
+ @schedule[:period] = :monthly
+ @schedule[:periodmatch] = :number
+ end
- it "should match when the previous time is prior to the first day of this month" do
- now = Time.now
+ it "should match when the previous time is prior to the first day of this month" do
+ now = Time.now
- # Subtract the number days we've progressed into the month
- previous = now - (3600 * 24 * now.day)
+ # Subtract the number days we've progressed into the month
+ previous = now - (3600 * 24 * now.day)
- @schedule.match?(previous).should be_true
- end
+ @schedule.match?(previous).should be_true
+ end
- it "should not match when the previous time is after the last day of last month" do
- now = Time.now
+ it "should not match when the previous time is after the last day of last month" do
+ now = Time.now
- # Subtract the number days we've progressed into the month, minus one
- previous = now - (3600 * 24 * (now.day - 1))
+ # Subtract the number days we've progressed into the month, minus one
+ previous = now - (3600 * 24 * (now.day - 1))
- @schedule.match?(previous).should be_false
- end
+ @schedule.match?(previous).should be_false
end
+ end
- describe Puppet::Type.type(:schedule), "when matching with a repeat greater than one" do
- include ScheduleTesting
+ describe Puppet::Type.type(:schedule), "when matching with a repeat greater than one" do
+ include ScheduleTesting
- before do
- @schedule[:period] = :daily
- @schedule[:repeat] = 2
- end
+ before do
+ @schedule[:period] = :daily
+ @schedule[:repeat] = 2
+ end
- it "should fail if the periodmatch is 'number'" do
- @schedule[:periodmatch] = :number
- proc { @schedule[:repeat] = 2 }.should raise_error(Puppet::Error)
- end
+ it "should fail if the periodmatch is 'number'" do
+ @schedule[:periodmatch] = :number
+ proc { @schedule[:repeat] = 2 }.should raise_error(Puppet::Error)
+ end
- it "should match if the previous run was further away than the distance divided by the repeat" do
- previous = Time.now - (3600 * 13)
- @schedule.match?(previous).should be_true
- end
+ it "should match if the previous run was further away than the distance divided by the repeat" do
+ previous = Time.now - (3600 * 13)
+ @schedule.match?(previous).should be_true
+ end
- it "should not match if the previous run was closer than the distance divided by the repeat" do
- previous = Time.now - (3600 * 11)
- @schedule.match?(previous).should be_false
- end
+ it "should not match if the previous run was closer than the distance divided by the repeat" do
+ previous = Time.now - (3600 * 11)
+ @schedule.match?(previous).should be_false
end
+ end
end
diff --git a/spec/unit/type/selboolean_spec.rb b/spec/unit/type/selboolean_spec.rb
index 7f719b4..3b31f43 100755
--- a/spec/unit/type/selboolean_spec.rb
+++ b/spec/unit/type/selboolean_spec.rb
@@ -3,43 +3,43 @@
Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") }
describe Puppet::Type.type(:selboolean), "when validating attributes" do
- [:name, :persistent].each do |param|
- it "should have a #{param} parameter" do
- Puppet::Type.type(:selboolean).attrtype(param).should == :param
- end
+ [:name, :persistent].each do |param|
+ it "should have a #{param} parameter" do
+ Puppet::Type.type(:selboolean).attrtype(param).should == :param
end
+ end
- it "should have a value property" do
- Puppet::Type.type(:selboolean).attrtype(:value).should == :property
- end
+ it "should have a value property" do
+ Puppet::Type.type(:selboolean).attrtype(:value).should == :property
+ end
end
describe Puppet::Type.type(:selboolean), "when validating values" do
- before do
- @class = Puppet::Type.type(:selboolean)
+ before do
+ @class = Puppet::Type.type(:selboolean)
- @provider_class = stub 'provider_class', :name => "fake", :suitable? => true, :supports_parameter? => true
- @class.stubs(:defaultprovider).returns(@provider_class)
- @class.stubs(:provider).returns(@provider_class)
+ @provider_class = stub 'provider_class', :name => "fake", :suitable? => true, :supports_parameter? => true
+ @class.stubs(:defaultprovider).returns(@provider_class)
+ @class.stubs(:provider).returns(@provider_class)
- @provider = stub 'provider', :class => @provider_class, :clear => nil
- @provider_class.stubs(:new).returns(@provider)
- end
+ @provider = stub 'provider', :class => @provider_class, :clear => nil
+ @provider_class.stubs(:new).returns(@provider)
+ end
- it "should support :on as a value to :value" do
- Puppet::Type.type(:selboolean).new(:name => "yay", :value => :on)
- end
+ it "should support :on as a value to :value" do
+ Puppet::Type.type(:selboolean).new(:name => "yay", :value => :on)
+ end
- it "should support :off as a value to :value" do
- Puppet::Type.type(:selboolean).new(:name => "yay", :value => :off)
- end
+ it "should support :off as a value to :value" do
+ Puppet::Type.type(:selboolean).new(:name => "yay", :value => :off)
+ end
- it "should support :true as a value to :persistent" do
- Puppet::Type.type(:selboolean).new(:name => "yay", :value => :on, :persistent => :true)
- end
+ it "should support :true as a value to :persistent" do
+ Puppet::Type.type(:selboolean).new(:name => "yay", :value => :on, :persistent => :true)
+ end
- it "should support :false as a value to :persistent" do
- Puppet::Type.type(:selboolean).new(:name => "yay", :value => :on, :persistent => :false)
- end
+ it "should support :false as a value to :persistent" do
+ Puppet::Type.type(:selboolean).new(:name => "yay", :value => :on, :persistent => :false)
+ end
end
diff --git a/spec/unit/type/selmodule_spec.rb b/spec/unit/type/selmodule_spec.rb
index f14bea9..3d12625 100755
--- a/spec/unit/type/selmodule_spec.rb
+++ b/spec/unit/type/selmodule_spec.rb
@@ -3,16 +3,16 @@
Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") }
describe Puppet::Type.type(:selmodule), "when validating attributes" do
- [:name, :selmoduledir, :selmodulepath].each do |param|
- it "should have a #{param} parameter" do
- Puppet::Type.type(:selmodule).attrtype(param).should == :param
- end
+ [:name, :selmoduledir, :selmodulepath].each do |param|
+ it "should have a #{param} parameter" do
+ Puppet::Type.type(:selmodule).attrtype(param).should == :param
end
+ end
- [:ensure, :syncversion].each do |param|
- it "should have a #{param} property" do
- Puppet::Type.type(:selmodule).attrtype(param).should == :property
- end
+ [:ensure, :syncversion].each do |param|
+ it "should have a #{param} property" do
+ Puppet::Type.type(:selmodule).attrtype(param).should == :property
end
+ end
end
diff --git a/spec/unit/type/service_spec.rb b/spec/unit/type/service_spec.rb
index 48d87ba..0f4a507 100755
--- a/spec/unit/type/service_spec.rb
+++ b/spec/unit/type/service_spec.rb
@@ -3,220 +3,220 @@
require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::Type.type(:service) do
- it "should have an :enableable feature that requires the :enable, :disable, and :enabled? methods" do
- Puppet::Type.type(:service).provider_feature(:enableable).methods.should == [:disable, :enable, :enabled?]
- end
+ it "should have an :enableable feature that requires the :enable, :disable, and :enabled? methods" do
+ Puppet::Type.type(:service).provider_feature(:enableable).methods.should == [:disable, :enable, :enabled?]
+ end
- it "should have a :refreshable feature that requires the :restart method" do
- Puppet::Type.type(:service).provider_feature(:refreshable).methods.should == [:restart]
- end
+ it "should have a :refreshable feature that requires the :restart method" do
+ Puppet::Type.type(:service).provider_feature(:refreshable).methods.should == [:restart]
+ end
end
describe Puppet::Type.type(:service), "when validating attributes" do
- [:name, :binary, :hasstatus, :path, :pattern, :start, :restart, :stop, :status, :hasrestart, :control].each do |param|
- it "should have a #{param} parameter" do
- Puppet::Type.type(:service).attrtype(param).should == :param
- end
+ [:name, :binary, :hasstatus, :path, :pattern, :start, :restart, :stop, :status, :hasrestart, :control].each do |param|
+ it "should have a #{param} parameter" do
+ Puppet::Type.type(:service).attrtype(param).should == :param
end
+ end
- [:ensure, :enable].each do |param|
- it "should have an #{param} property" do
- Puppet::Type.type(:service).attrtype(param).should == :property
- end
+ [:ensure, :enable].each do |param|
+ it "should have an #{param} property" do
+ Puppet::Type.type(:service).attrtype(param).should == :property
end
+ end
end
describe Puppet::Type.type(:service), "when validating attribute values" do
- before do
- @provider = stub 'provider', :class => Puppet::Type.type(:service).defaultprovider, :clear => nil, :controllable? => false
- Puppet::Type.type(:service).defaultprovider.stubs(:new).returns(@provider)
- end
-
- it "should support :running as a value to :ensure" do
- Puppet::Type.type(:service).new(:name => "yay", :ensure => :running)
- end
-
- it "should support :stopped as a value to :ensure" do
- Puppet::Type.type(:service).new(:name => "yay", :ensure => :stopped)
- end
-
- it "should alias the value :true to :running in :ensure" do
- svc = Puppet::Type.type(:service).new(:name => "yay", :ensure => true)
- svc.should(:ensure).should == :running
- end
-
- it "should alias the value :false to :stopped in :ensure" do
- svc = Puppet::Type.type(:service).new(:name => "yay", :ensure => false)
- svc.should(:ensure).should == :stopped
- end
-
- it "should support :true as a value to :enable" do
- Puppet::Type.type(:service).new(:name => "yay", :enable => :true)
- end
-
- it "should support :false as a value to :enable" do
- Puppet::Type.type(:service).new(:name => "yay", :enable => :false)
- end
-
- it "should support :true as a value to :hasstatus" do
- Puppet::Type.type(:service).new(:name => "yay", :hasstatus => :true)
- end
-
- it "should support :false as a value to :hasstatus" do
- Puppet::Type.type(:service).new(:name => "yay", :hasstatus => :false)
- end
-
- it "should support :true as a value to :hasrestart" do
- Puppet::Type.type(:service).new(:name => "yay", :hasrestart => :true)
- end
-
- it "should support :false as a value to :hasrestart" do
- Puppet::Type.type(:service).new(:name => "yay", :hasrestart => :false)
- end
-
- it "should allow setting the :enable parameter if the provider has the :enableable feature" do
- Puppet::Type.type(:service).defaultprovider.stubs(:supports_parameter?).returns(true)
- svc = Puppet::Type.type(:service).new(:name => "yay", :enable => true)
- svc.should(:enable).should == :true
- end
-
- it "should split paths on ':'" do
- FileTest.stubs(:exist?).returns(true)
- FileTest.stubs(:directory?).returns(true)
- svc = Puppet::Type.type(:service).new(:name => "yay", :path => "/one/two:/three/four")
- svc[:path].should == %w{/one/two /three/four}
- end
-
- it "should accept arrays of paths joined by ':'" do
- FileTest.stubs(:exist?).returns(true)
- FileTest.stubs(:directory?).returns(true)
- svc = Puppet::Type.type(:service).new(:name => "yay", :path => ["/one:/two", "/three:/four"])
- svc[:path].should == %w{/one /two /three /four}
- end
+ before do
+ @provider = stub 'provider', :class => Puppet::Type.type(:service).defaultprovider, :clear => nil, :controllable? => false
+ Puppet::Type.type(:service).defaultprovider.stubs(:new).returns(@provider)
+ end
+
+ it "should support :running as a value to :ensure" do
+ Puppet::Type.type(:service).new(:name => "yay", :ensure => :running)
+ end
+
+ it "should support :stopped as a value to :ensure" do
+ Puppet::Type.type(:service).new(:name => "yay", :ensure => :stopped)
+ end
+
+ it "should alias the value :true to :running in :ensure" do
+ svc = Puppet::Type.type(:service).new(:name => "yay", :ensure => true)
+ svc.should(:ensure).should == :running
+ end
+
+ it "should alias the value :false to :stopped in :ensure" do
+ svc = Puppet::Type.type(:service).new(:name => "yay", :ensure => false)
+ svc.should(:ensure).should == :stopped
+ end
+
+ it "should support :true as a value to :enable" do
+ Puppet::Type.type(:service).new(:name => "yay", :enable => :true)
+ end
+
+ it "should support :false as a value to :enable" do
+ Puppet::Type.type(:service).new(:name => "yay", :enable => :false)
+ end
+
+ it "should support :true as a value to :hasstatus" do
+ Puppet::Type.type(:service).new(:name => "yay", :hasstatus => :true)
+ end
+
+ it "should support :false as a value to :hasstatus" do
+ Puppet::Type.type(:service).new(:name => "yay", :hasstatus => :false)
+ end
+
+ it "should support :true as a value to :hasrestart" do
+ Puppet::Type.type(:service).new(:name => "yay", :hasrestart => :true)
+ end
+
+ it "should support :false as a value to :hasrestart" do
+ Puppet::Type.type(:service).new(:name => "yay", :hasrestart => :false)
+ end
+
+ it "should allow setting the :enable parameter if the provider has the :enableable feature" do
+ Puppet::Type.type(:service).defaultprovider.stubs(:supports_parameter?).returns(true)
+ svc = Puppet::Type.type(:service).new(:name => "yay", :enable => true)
+ svc.should(:enable).should == :true
+ end
+
+ it "should split paths on ':'" do
+ FileTest.stubs(:exist?).returns(true)
+ FileTest.stubs(:directory?).returns(true)
+ svc = Puppet::Type.type(:service).new(:name => "yay", :path => "/one/two:/three/four")
+ svc[:path].should == %w{/one/two /three/four}
+ end
+
+ it "should accept arrays of paths joined by ':'" do
+ FileTest.stubs(:exist?).returns(true)
+ FileTest.stubs(:directory?).returns(true)
+ svc = Puppet::Type.type(:service).new(:name => "yay", :path => ["/one:/two", "/three:/four"])
+ svc[:path].should == %w{/one /two /three /four}
+ end
end
describe Puppet::Type.type(:service), "when setting default attribute values" do
- it "should default to the provider's default path if one is available" do
- FileTest.stubs(:directory?).returns(true)
- FileTest.stubs(:exist?).returns(true)
-
- Puppet::Type.type(:service).defaultprovider.stubs(:respond_to?).returns(true)
- Puppet::Type.type(:service).defaultprovider.stubs(:defpath).returns("testing")
- svc = Puppet::Type.type(:service).new(:name => "other")
- svc[:path].should == ["testing"]
- end
-
- it "should default 'pattern' to the binary if one is provided" do
- svc = Puppet::Type.type(:service).new(:name => "other", :binary => "/some/binary")
- svc[:pattern].should == "/some/binary"
- end
-
- it "should default 'pattern' to the name if no pattern is provided" do
- svc = Puppet::Type.type(:service).new(:name => "other")
- svc[:pattern].should == "other"
- end
-
- it "should default 'control' to the upcased service name with periods replaced by underscores if the provider supports the 'controllable' feature" do
- provider = stub 'provider', :controllable? => true, :class => Puppet::Type.type(:service).defaultprovider, :clear => nil
- Puppet::Type.type(:service).defaultprovider.stubs(:new).returns(provider)
- svc = Puppet::Type.type(:service).new(:name => "nfs.client")
- svc[:control].should == "NFS_CLIENT_START"
- end
+ it "should default to the provider's default path if one is available" do
+ FileTest.stubs(:directory?).returns(true)
+ FileTest.stubs(:exist?).returns(true)
+
+ Puppet::Type.type(:service).defaultprovider.stubs(:respond_to?).returns(true)
+ Puppet::Type.type(:service).defaultprovider.stubs(:defpath).returns("testing")
+ svc = Puppet::Type.type(:service).new(:name => "other")
+ svc[:path].should == ["testing"]
+ end
+
+ it "should default 'pattern' to the binary if one is provided" do
+ svc = Puppet::Type.type(:service).new(:name => "other", :binary => "/some/binary")
+ svc[:pattern].should == "/some/binary"
+ end
+
+ it "should default 'pattern' to the name if no pattern is provided" do
+ svc = Puppet::Type.type(:service).new(:name => "other")
+ svc[:pattern].should == "other"
+ end
+
+ it "should default 'control' to the upcased service name with periods replaced by underscores if the provider supports the 'controllable' feature" do
+ provider = stub 'provider', :controllable? => true, :class => Puppet::Type.type(:service).defaultprovider, :clear => nil
+ Puppet::Type.type(:service).defaultprovider.stubs(:new).returns(provider)
+ svc = Puppet::Type.type(:service).new(:name => "nfs.client")
+ svc[:control].should == "NFS_CLIENT_START"
+ end
end
describe Puppet::Type.type(:service), "when retrieving the host's current state" do
- before do
- @service = Puppet::Type.type(:service).new(:name => "yay")
- end
-
- it "should use the provider's status to determine whether the service is running" do
- @service.provider.expects(:status).returns(:yepper)
- @service[:ensure] = :running
- @service.property(:ensure).retrieve.should == :yepper
- end
-
- it "should ask the provider whether it is enabled" do
- @service.provider.class.stubs(:supports_parameter?).returns(true)
- @service.provider.expects(:enabled?).returns(:yepper)
- @service[:enable] = true
- @service.property(:enable).retrieve.should == :yepper
- end
+ before do
+ @service = Puppet::Type.type(:service).new(:name => "yay")
+ end
+
+ it "should use the provider's status to determine whether the service is running" do
+ @service.provider.expects(:status).returns(:yepper)
+ @service[:ensure] = :running
+ @service.property(:ensure).retrieve.should == :yepper
+ end
+
+ it "should ask the provider whether it is enabled" do
+ @service.provider.class.stubs(:supports_parameter?).returns(true)
+ @service.provider.expects(:enabled?).returns(:yepper)
+ @service[:enable] = true
+ @service.property(:enable).retrieve.should == :yepper
+ end
end
describe Puppet::Type.type(:service), "when changing the host" do
- before do
- @service = Puppet::Type.type(:service).new(:name => "yay")
- end
-
- it "should start the service if it is supposed to be running" do
- @service[:ensure] = :running
- @service.provider.expects(:start)
- @service.property(:ensure).sync
- end
-
- it "should stop the service if it is supposed to be stopped" do
- @service[:ensure] = :stopped
- @service.provider.expects(:stop)
- @service.property(:ensure).sync
- end
-
- it "should enable the service if it is supposed to be enabled" do
- @service.provider.class.stubs(:supports_parameter?).returns(true)
- @service[:enable] = true
- @service.provider.expects(:enable)
- @service.property(:enable).sync
- end
-
- it "should disable the service if it is supposed to be disabled" do
- @service.provider.class.stubs(:supports_parameter?).returns(true)
- @service[:enable] = false
- @service.provider.expects(:disable)
- @service.property(:enable).sync
- end
-
- it "should sync the service's enable state when changing the state of :ensure if :enable is being managed" do
- @service.provider.class.stubs(:supports_parameter?).returns(true)
- @service[:enable] = false
- @service[:ensure] = :stopped
-
- @service.property(:enable).expects(:retrieve).returns("whatever")
- @service.property(:enable).expects(:insync?).returns(false)
- @service.property(:enable).expects(:sync)
-
- @service.provider.stubs(:stop)
-
- @service.property(:ensure).sync
- end
+ before do
+ @service = Puppet::Type.type(:service).new(:name => "yay")
+ end
+
+ it "should start the service if it is supposed to be running" do
+ @service[:ensure] = :running
+ @service.provider.expects(:start)
+ @service.property(:ensure).sync
+ end
+
+ it "should stop the service if it is supposed to be stopped" do
+ @service[:ensure] = :stopped
+ @service.provider.expects(:stop)
+ @service.property(:ensure).sync
+ end
+
+ it "should enable the service if it is supposed to be enabled" do
+ @service.provider.class.stubs(:supports_parameter?).returns(true)
+ @service[:enable] = true
+ @service.provider.expects(:enable)
+ @service.property(:enable).sync
+ end
+
+ it "should disable the service if it is supposed to be disabled" do
+ @service.provider.class.stubs(:supports_parameter?).returns(true)
+ @service[:enable] = false
+ @service.provider.expects(:disable)
+ @service.property(:enable).sync
+ end
+
+ it "should sync the service's enable state when changing the state of :ensure if :enable is being managed" do
+ @service.provider.class.stubs(:supports_parameter?).returns(true)
+ @service[:enable] = false
+ @service[:ensure] = :stopped
+
+ @service.property(:enable).expects(:retrieve).returns("whatever")
+ @service.property(:enable).expects(:insync?).returns(false)
+ @service.property(:enable).expects(:sync)
+
+ @service.provider.stubs(:stop)
+
+ @service.property(:ensure).sync
+ end
end
describe Puppet::Type.type(:service), "when refreshing the service" do
- before do
- @service = Puppet::Type.type(:service).new(:name => "yay")
- end
-
- it "should restart the service if it is running" do
- @service[:ensure] = :running
- @service.provider.expects(:status).returns(:running)
- @service.provider.expects(:restart)
- @service.refresh
- end
-
- it "should restart the service if it is running, even if it is supposed to stopped" do
- @service[:ensure] = :stopped
- @service.provider.expects(:status).returns(:running)
- @service.provider.expects(:restart)
- @service.refresh
- end
-
- it "should not restart the service if it is not running" do
- @service[:ensure] = :running
- @service.provider.expects(:status).returns(:stopped)
- @service.refresh
- end
-
- it "should add :ensure as a property if it is not being managed" do
- @service.provider.expects(:status).returns(:running)
- @service.provider.expects(:restart)
- @service.refresh
- end
+ before do
+ @service = Puppet::Type.type(:service).new(:name => "yay")
+ end
+
+ it "should restart the service if it is running" do
+ @service[:ensure] = :running
+ @service.provider.expects(:status).returns(:running)
+ @service.provider.expects(:restart)
+ @service.refresh
+ end
+
+ it "should restart the service if it is running, even if it is supposed to stopped" do
+ @service[:ensure] = :stopped
+ @service.provider.expects(:status).returns(:running)
+ @service.provider.expects(:restart)
+ @service.refresh
+ end
+
+ it "should not restart the service if it is not running" do
+ @service[:ensure] = :running
+ @service.provider.expects(:status).returns(:stopped)
+ @service.refresh
+ end
+
+ it "should add :ensure as a property if it is not being managed" do
+ @service.provider.expects(:status).returns(:running)
+ @service.provider.expects(:restart)
+ @service.refresh
+ end
end
diff --git a/spec/unit/type/ssh_authorized_key_spec.rb b/spec/unit/type/ssh_authorized_key_spec.rb
index e2262df..a0b435f 100755
--- a/spec/unit/type/ssh_authorized_key_spec.rb
+++ b/spec/unit/type/ssh_authorized_key_spec.rb
@@ -5,148 +5,148 @@ require File.dirname(__FILE__) + '/../../spec_helper'
ssh_authorized_key = Puppet::Type.type(:ssh_authorized_key)
describe ssh_authorized_key do
- before do
- @class = Puppet::Type.type(:ssh_authorized_key)
+ before do
+ @class = Puppet::Type.type(:ssh_authorized_key)
- @provider_class = stub 'provider_class', :name => "fake", :suitable? => true, :supports_parameter? => true
- @class.stubs(:defaultprovider).returns(@provider_class)
- @class.stubs(:provider).returns(@provider_class)
+ @provider_class = stub 'provider_class', :name => "fake", :suitable? => true, :supports_parameter? => true
+ @class.stubs(:defaultprovider).returns(@provider_class)
+ @class.stubs(:provider).returns(@provider_class)
- @provider = stub 'provider', :class => @provider_class, :file_path => "/tmp/whatever", :clear => nil
- @provider_class.stubs(:new).returns(@provider)
- @catalog = Puppet::Resource::Catalog.new
- end
+ @provider = stub 'provider', :class => @provider_class, :file_path => "/tmp/whatever", :clear => nil
+ @provider_class.stubs(:new).returns(@provider)
+ @catalog = Puppet::Resource::Catalog.new
+ end
- it "should have a name parameter" do
- @class.attrtype(:name).should == :param
- end
+ it "should have a name parameter" do
+ @class.attrtype(:name).should == :param
+ end
- it "should have :name be its namevar" do
- @class.key_attributes.should == [:name]
- end
+ it "should have :name be its namevar" do
+ @class.key_attributes.should == [:name]
+ end
- it "should have a :provider parameter" do
- @class.attrtype(:provider).should == :param
- end
+ it "should have a :provider parameter" do
+ @class.attrtype(:provider).should == :param
+ end
- it "should have an ensure property" do
- @class.attrtype(:ensure).should == :property
- end
+ it "should have an ensure property" do
+ @class.attrtype(:ensure).should == :property
+ end
- it "should support :present as a value for :ensure" do
- proc { @class.new(:name => "whev", :ensure => :present, :user => "nobody") }.should_not raise_error
- end
+ it "should support :present as a value for :ensure" do
+ proc { @class.new(:name => "whev", :ensure => :present, :user => "nobody") }.should_not raise_error
+ end
- it "should support :absent as a value for :ensure" do
- proc { @class.new(:name => "whev", :ensure => :absent, :user => "nobody") }.should_not raise_error
- end
+ it "should support :absent as a value for :ensure" do
+ proc { @class.new(:name => "whev", :ensure => :absent, :user => "nobody") }.should_not raise_error
+ end
- it "should have an type property" do
- @class.attrtype(:type).should == :property
- end
- it "should support ssh-dss as an type value" do
- proc { @class.new(:name => "whev", :type => "ssh-dss", :user => "nobody") }.should_not raise_error
- end
- it "should support ssh-rsa as an type value" do
- proc { @class.new(:name => "whev", :type => "ssh-rsa", :user => "nobody") }.should_not raise_error
- end
- it "should support :dsa as an type value" do
- proc { @class.new(:name => "whev", :type => :dsa, :user => "nobody") }.should_not raise_error
- end
- it "should support :rsa as an type value" do
- proc { @class.new(:name => "whev", :type => :rsa, :user => "nobody") }.should_not raise_error
- end
+ it "should have an type property" do
+ @class.attrtype(:type).should == :property
+ end
+ it "should support ssh-dss as an type value" do
+ proc { @class.new(:name => "whev", :type => "ssh-dss", :user => "nobody") }.should_not raise_error
+ end
+ it "should support ssh-rsa as an type value" do
+ proc { @class.new(:name => "whev", :type => "ssh-rsa", :user => "nobody") }.should_not raise_error
+ end
+ it "should support :dsa as an type value" do
+ proc { @class.new(:name => "whev", :type => :dsa, :user => "nobody") }.should_not raise_error
+ end
+ it "should support :rsa as an type value" do
+ proc { @class.new(:name => "whev", :type => :rsa, :user => "nobody") }.should_not raise_error
+ end
- it "should not support values other than ssh-dss, ssh-rsa, dsa, rsa in the ssh_authorized_key_type" do
- proc { @class.new(:name => "whev", :type => :something) }.should raise_error(Puppet::Error)
- end
+ it "should not support values other than ssh-dss, ssh-rsa, dsa, rsa in the ssh_authorized_key_type" do
+ proc { @class.new(:name => "whev", :type => :something) }.should raise_error(Puppet::Error)
+ end
- it "should have an key property" do
- @class.attrtype(:key).should == :property
- end
+ it "should have an key property" do
+ @class.attrtype(:key).should == :property
+ end
- it "should have an user property" do
- @class.attrtype(:user).should == :property
- end
+ it "should have an user property" do
+ @class.attrtype(:user).should == :property
+ end
- it "should have an options property" do
- @class.attrtype(:options).should == :property
- end
+ it "should have an options property" do
+ @class.attrtype(:options).should == :property
+ end
- it "'s options property should return well formed string of arrays from is_to_s" do
- resource = @class.new(:name => "whev", :type => :rsa, :user => "nobody", :options => ["a","b","c"])
+ it "'s options property should return well formed string of arrays from is_to_s" do
+ resource = @class.new(:name => "whev", :type => :rsa, :user => "nobody", :options => ["a","b","c"])
- resource.property(:options).is_to_s(["a","b","c"]).should == "a,b,c"
- end
+ resource.property(:options).is_to_s(["a","b","c"]).should == "a,b,c"
+ end
- it "'s options property should return well formed string of arrays from is_to_s" do
- resource = @class.new(:name => "whev", :type => :rsa, :user => "nobody", :options => ["a","b","c"])
+ it "'s options property should return well formed string of arrays from is_to_s" do
+ resource = @class.new(:name => "whev", :type => :rsa, :user => "nobody", :options => ["a","b","c"])
- resource.property(:options).should_to_s(["a","b","c"]).should == "a,b,c"
- end
+ resource.property(:options).should_to_s(["a","b","c"]).should == "a,b,c"
+ end
- it "should have a target property" do
- @class.attrtype(:target).should == :property
- end
+ it "should have a target property" do
+ @class.attrtype(:target).should == :property
+ end
- describe "when neither user nor target is specified" do
- it "should raise an error" do
- proc do
+ describe "when neither user nor target is specified" do
+ it "should raise an error" do
+ proc do
- @class.create(
+ @class.create(
- :name => "Test",
- :key => "AAA",
- :type => "ssh-rsa",
+ :name => "Test",
+ :key => "AAA",
+ :type => "ssh-rsa",
- :ensure => :present)
- end.should raise_error(Puppet::Error)
- end
+ :ensure => :present)
+ end.should raise_error(Puppet::Error)
end
+ end
- describe "when both target and user are specified" do
- it "should use target" do
+ describe "when both target and user are specified" do
+ it "should use target" do
- resource = @class.create(
+ resource = @class.create(
- :name => "Test",
- :user => "root",
+ :name => "Test",
+ :user => "root",
- :target => "/tmp/blah")
- resource.should(:target).should == "/tmp/blah"
- end
+ :target => "/tmp/blah")
+ resource.should(:target).should == "/tmp/blah"
end
+ end
- describe "when user is specified" do
- it "should determine target" do
+ describe "when user is specified" do
+ it "should determine target" do
- resource = @class.create(
+ resource = @class.create(
- :name => "Test",
+ :name => "Test",
- :user => "root")
- target = File.expand_path("~root/.ssh/authorized_keys")
- resource.should(:target).should == target
- end
+ :user => "root")
+ target = File.expand_path("~root/.ssh/authorized_keys")
+ resource.should(:target).should == target
+ end
- # Bug #2124 - ssh_authorized_key always changes target if target is not defined
- it "should not raise spurious change events" do
- resource = @class.new(:name => "Test", :user => "root")
- target = File.expand_path("~root/.ssh/authorized_keys")
- resource.property(:target).insync?(target).should == true
- end
+ # Bug #2124 - ssh_authorized_key always changes target if target is not defined
+ it "should not raise spurious change events" do
+ resource = @class.new(:name => "Test", :user => "root")
+ target = File.expand_path("~root/.ssh/authorized_keys")
+ resource.property(:target).insync?(target).should == true
end
+ end
- describe "when calling validate" do
- it "should not crash on a non-existant user" do
+ describe "when calling validate" do
+ it "should not crash on a non-existant user" do
- resource = @class.create(
+ resource = @class.create(
- :name => "Test",
+ :name => "Test",
- :user => "ihopesuchuserdoesnotexist")
- proc { resource.validate }.should_not raise_error
- end
+ :user => "ihopesuchuserdoesnotexist")
+ proc { resource.validate }.should_not raise_error
end
+ end
end
diff --git a/spec/unit/type/stage_spec.rb b/spec/unit/type/stage_spec.rb
index 6884652..bcde7c4 100644
--- a/spec/unit/type/stage_spec.rb
+++ b/spec/unit/type/stage_spec.rb
@@ -3,7 +3,7 @@
require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::Type.type(:stage) do
- it "should have a 'name' parameter'" do
- Puppet::Type.type(:stage).new(:name => :foo)[:name].should == :foo
- end
+ it "should have a 'name' parameter'" do
+ Puppet::Type.type(:stage).new(:name => :foo)[:name].should == :foo
+ end
end
diff --git a/spec/unit/type/tidy_spec.rb b/spec/unit/type/tidy_spec.rb
index f39ccb5..11edbfb 100755
--- a/spec/unit/type/tidy_spec.rb
+++ b/spec/unit/type/tidy_spec.rb
@@ -6,419 +6,419 @@ require 'puppet/file_bucket/dipper'
tidy = Puppet::Type.type(:tidy)
describe tidy do
- before do
- @basepath = Puppet.features.posix? ? "/what/ever" : "C:/tmp"
- Puppet.settings.stubs(:use)
-
- # for an unknown reason some of these specs fails when run individually
- # with a failed expectation on File.lstat in the autoloader.
- File.stubs(:lstat)
- end
-
- it "should use :lstat when stating a file" do
- resource = tidy.new :path => "/foo/bar", :age => "1d"
- stat = mock 'stat'
- File.expects(:lstat).with("/foo/bar").returns stat
- resource.stat("/foo/bar").should == stat
+ before do
+ @basepath = Puppet.features.posix? ? "/what/ever" : "C:/tmp"
+ Puppet.settings.stubs(:use)
+
+ # for an unknown reason some of these specs fails when run individually
+ # with a failed expectation on File.lstat in the autoloader.
+ File.stubs(:lstat)
+ end
+
+ it "should use :lstat when stating a file" do
+ resource = tidy.new :path => "/foo/bar", :age => "1d"
+ stat = mock 'stat'
+ File.expects(:lstat).with("/foo/bar").returns stat
+ resource.stat("/foo/bar").should == stat
+ end
+
+ [:age, :size, :path, :matches, :type, :recurse, :rmdirs].each do |param|
+ it "should have a #{param} parameter" do
+ Puppet::Type.type(:tidy).attrclass(param).ancestors.should be_include(Puppet::Parameter)
end
- [:age, :size, :path, :matches, :type, :recurse, :rmdirs].each do |param|
- it "should have a #{param} parameter" do
- Puppet::Type.type(:tidy).attrclass(param).ancestors.should be_include(Puppet::Parameter)
- end
-
- it "should have documentation for its #{param} param" do
- Puppet::Type.type(:tidy).attrclass(param).doc.should be_instance_of(String)
- end
+ it "should have documentation for its #{param} param" do
+ Puppet::Type.type(:tidy).attrclass(param).doc.should be_instance_of(String)
end
+ end
- describe "when validating parameter values" do
- describe "for 'recurse'" do
- before do
- @tidy = Puppet::Type.type(:tidy).new :path => "/tmp", :age => "100d"
- end
+ describe "when validating parameter values" do
+ describe "for 'recurse'" do
+ before do
+ @tidy = Puppet::Type.type(:tidy).new :path => "/tmp", :age => "100d"
+ end
- it "should allow 'true'" do
- lambda { @tidy[:recurse] = true }.should_not raise_error
- end
+ it "should allow 'true'" do
+ lambda { @tidy[:recurse] = true }.should_not raise_error
+ end
- it "should allow 'false'" do
- lambda { @tidy[:recurse] = false }.should_not raise_error
- end
+ it "should allow 'false'" do
+ lambda { @tidy[:recurse] = false }.should_not raise_error
+ end
- it "should allow integers" do
- lambda { @tidy[:recurse] = 10 }.should_not raise_error
- end
+ it "should allow integers" do
+ lambda { @tidy[:recurse] = 10 }.should_not raise_error
+ end
- it "should allow string representations of integers" do
- lambda { @tidy[:recurse] = "10" }.should_not raise_error
- end
+ it "should allow string representations of integers" do
+ lambda { @tidy[:recurse] = "10" }.should_not raise_error
+ end
- it "should allow 'inf'" do
- lambda { @tidy[:recurse] = "inf" }.should_not raise_error
- end
+ it "should allow 'inf'" do
+ lambda { @tidy[:recurse] = "inf" }.should_not raise_error
+ end
- it "should not allow arbitrary values" do
- lambda { @tidy[:recurse] = "whatever" }.should raise_error
- end
- end
+ it "should not allow arbitrary values" do
+ lambda { @tidy[:recurse] = "whatever" }.should raise_error
+ end
+ end
- describe "for 'matches'" do
- before do
- @tidy = Puppet::Type.type(:tidy).new :path => "/tmp", :age => "100d"
- end
-
- it "should object if matches is given with recurse is not specified" do
- lambda { @tidy[:matches] = '*.doh' }.should raise_error
- end
- it "should object if matches is given and recurse is 0" do
- lambda { @tidy[:recurse] = 0; @tidy[:matches] = '*.doh' }.should raise_error
- end
- it "should object if matches is given and recurse is false" do
- lambda { @tidy[:recurse] = false; @tidy[:matches] = '*.doh' }.should raise_error
- end
- it "should not object if matches is given and recurse is > 0" do
- lambda { @tidy[:recurse] = 1; @tidy[:matches] = '*.doh' }.should_not raise_error
- end
- it "should not object if matches is given and recurse is true" do
- lambda { @tidy[:recurse] = true; @tidy[:matches] = '*.doh' }.should_not raise_error
- end
- end
+ describe "for 'matches'" do
+ before do
+ @tidy = Puppet::Type.type(:tidy).new :path => "/tmp", :age => "100d"
+ end
+
+ it "should object if matches is given with recurse is not specified" do
+ lambda { @tidy[:matches] = '*.doh' }.should raise_error
+ end
+ it "should object if matches is given and recurse is 0" do
+ lambda { @tidy[:recurse] = 0; @tidy[:matches] = '*.doh' }.should raise_error
+ end
+ it "should object if matches is given and recurse is false" do
+ lambda { @tidy[:recurse] = false; @tidy[:matches] = '*.doh' }.should raise_error
+ end
+ it "should not object if matches is given and recurse is > 0" do
+ lambda { @tidy[:recurse] = 1; @tidy[:matches] = '*.doh' }.should_not raise_error
+ end
+ it "should not object if matches is given and recurse is true" do
+ lambda { @tidy[:recurse] = true; @tidy[:matches] = '*.doh' }.should_not raise_error
+ end
end
+ end
- describe "when matching files by age" do
- convertors = {
- :second => 1,
- :minute => 60
- }
+ describe "when matching files by age" do
+ convertors = {
+ :second => 1,
+ :minute => 60
+ }
- convertors[:hour] = convertors[:minute] * 60
- convertors[:day] = convertors[:hour] * 24
- convertors[:week] = convertors[:day] * 7
+ convertors[:hour] = convertors[:minute] * 60
+ convertors[:day] = convertors[:hour] * 24
+ convertors[:week] = convertors[:day] * 7
- convertors.each do |unit, multiple|
- it "should consider a #{unit} to be #{multiple} seconds" do
- @tidy = Puppet::Type.type(:tidy).new :path => @basepath, :age => "5#{unit.to_s[0..0]}"
+ convertors.each do |unit, multiple|
+ it "should consider a #{unit} to be #{multiple} seconds" do
+ @tidy = Puppet::Type.type(:tidy).new :path => @basepath, :age => "5#{unit.to_s[0..0]}"
- @tidy[:age].should == 5 * multiple
- end
- end
+ @tidy[:age].should == 5 * multiple
+ end
end
-
- describe "when matching files by size" do
- convertors = {
- :b => 0,
- :kb => 1,
- :mb => 2,
- :gb => 3
- }
-
- convertors.each do |unit, multiple|
- it "should consider a #{unit} to be 1024^#{multiple} bytes" do
- @tidy = Puppet::Type.type(:tidy).new :path => @basepath, :size => "5#{unit}"
-
- total = 5
- multiple.times { total *= 1024 }
- @tidy[:size].should == total
- end
- end
+ end
+
+ describe "when matching files by size" do
+ convertors = {
+ :b => 0,
+ :kb => 1,
+ :mb => 2,
+ :gb => 3
+ }
+
+ convertors.each do |unit, multiple|
+ it "should consider a #{unit} to be 1024^#{multiple} bytes" do
+ @tidy = Puppet::Type.type(:tidy).new :path => @basepath, :size => "5#{unit}"
+
+ total = 5
+ multiple.times { total *= 1024 }
+ @tidy[:size].should == total
+ end
end
+ end
- describe "when tidying" do
- before do
- @tidy = Puppet::Type.type(:tidy).new :path => @basepath
- @stat = stub 'stat', :ftype => "directory"
- File.stubs(:lstat).with(@basepath).returns @stat
- end
+ describe "when tidying" do
+ before do
+ @tidy = Puppet::Type.type(:tidy).new :path => @basepath
+ @stat = stub 'stat', :ftype => "directory"
+ File.stubs(:lstat).with(@basepath).returns @stat
+ end
- describe "and generating files" do
- it "should set the backup on the file if backup is set on the tidy instance" do
- @tidy[:backup] = "whatever"
- Puppet::Type.type(:file).expects(:new).with { |args| args[:backup] == "whatever" }
+ describe "and generating files" do
+ it "should set the backup on the file if backup is set on the tidy instance" do
+ @tidy[:backup] = "whatever"
+ Puppet::Type.type(:file).expects(:new).with { |args| args[:backup] == "whatever" }
- @tidy.mkfile(@basepath)
- end
+ @tidy.mkfile(@basepath)
+ end
- it "should set the file's path to the tidy's path" do
- Puppet::Type.type(:file).expects(:new).with { |args| args[:path] == @basepath }
+ it "should set the file's path to the tidy's path" do
+ Puppet::Type.type(:file).expects(:new).with { |args| args[:path] == @basepath }
- @tidy.mkfile(@basepath)
- end
+ @tidy.mkfile(@basepath)
+ end
- it "should configure the file for deletion" do
- Puppet::Type.type(:file).expects(:new).with { |args| args[:ensure] == :absent }
+ it "should configure the file for deletion" do
+ Puppet::Type.type(:file).expects(:new).with { |args| args[:ensure] == :absent }
- @tidy.mkfile(@basepath)
- end
+ @tidy.mkfile(@basepath)
+ end
- it "should force deletion on the file" do
- Puppet::Type.type(:file).expects(:new).with { |args| args[:force] == true }
+ it "should force deletion on the file" do
+ Puppet::Type.type(:file).expects(:new).with { |args| args[:force] == true }
- @tidy.mkfile(@basepath)
- end
+ @tidy.mkfile(@basepath)
+ end
- it "should do nothing if the targeted file does not exist" do
- File.expects(:lstat).with(@basepath).raises Errno::ENOENT
+ it "should do nothing if the targeted file does not exist" do
+ File.expects(:lstat).with(@basepath).raises Errno::ENOENT
- @tidy.generate.should == []
- end
- end
+ @tidy.generate.should == []
+ end
+ end
- describe "and recursion is not used" do
- it "should generate a file resource if the file should be tidied" do
- @tidy.expects(:tidy?).with(@basepath).returns true
- file = Puppet::Type.type(:file).new(:path => @basepath+"/eh")
- @tidy.expects(:mkfile).with(@basepath).returns file
+ describe "and recursion is not used" do
+ it "should generate a file resource if the file should be tidied" do
+ @tidy.expects(:tidy?).with(@basepath).returns true
+ file = Puppet::Type.type(:file).new(:path => @basepath+"/eh")
+ @tidy.expects(:mkfile).with(@basepath).returns file
- @tidy.generate.should == [file]
- end
+ @tidy.generate.should == [file]
+ end
- it "should do nothing if the file should not be tidied" do
- @tidy.expects(:tidy?).with(@basepath).returns false
- @tidy.expects(:mkfile).never
+ it "should do nothing if the file should not be tidied" do
+ @tidy.expects(:tidy?).with(@basepath).returns false
+ @tidy.expects(:mkfile).never
- @tidy.generate.should == []
- end
- end
+ @tidy.generate.should == []
+ end
+ end
- describe "and recursion is used" do
- before do
- @tidy[:recurse] = true
- Puppet::FileServing::Fileset.any_instance.stubs(:stat).returns mock("stat")
- @fileset = Puppet::FileServing::Fileset.new(@basepath)
- Puppet::FileServing::Fileset.stubs(:new).returns @fileset
- end
+ describe "and recursion is used" do
+ before do
+ @tidy[:recurse] = true
+ Puppet::FileServing::Fileset.any_instance.stubs(:stat).returns mock("stat")
+ @fileset = Puppet::FileServing::Fileset.new(@basepath)
+ Puppet::FileServing::Fileset.stubs(:new).returns @fileset
+ end
- it "should use a Fileset for infinite recursion" do
- Puppet::FileServing::Fileset.expects(:new).with(@basepath, :recurse => true).returns @fileset
- @fileset.expects(:files).returns %w{. one two}
- @tidy.stubs(:tidy?).returns false
+ it "should use a Fileset for infinite recursion" do
+ Puppet::FileServing::Fileset.expects(:new).with(@basepath, :recurse => true).returns @fileset
+ @fileset.expects(:files).returns %w{. one two}
+ @tidy.stubs(:tidy?).returns false
- @tidy.generate
- end
+ @tidy.generate
+ end
- it "should use a Fileset for limited recursion" do
- @tidy[:recurse] = 42
- Puppet::FileServing::Fileset.expects(:new).with(@basepath, :recurse => true, :recurselimit => 42).returns @fileset
- @fileset.expects(:files).returns %w{. one two}
- @tidy.stubs(:tidy?).returns false
+ it "should use a Fileset for limited recursion" do
+ @tidy[:recurse] = 42
+ Puppet::FileServing::Fileset.expects(:new).with(@basepath, :recurse => true, :recurselimit => 42).returns @fileset
+ @fileset.expects(:files).returns %w{. one two}
+ @tidy.stubs(:tidy?).returns false
- @tidy.generate
- end
+ @tidy.generate
+ end
- it "should generate a file resource for every file that should be tidied but not for files that should not be tidied" do
- @fileset.expects(:files).returns %w{. one two}
+ it "should generate a file resource for every file that should be tidied but not for files that should not be tidied" do
+ @fileset.expects(:files).returns %w{. one two}
- @tidy.expects(:tidy?).with(@basepath).returns true
- @tidy.expects(:tidy?).with(@basepath+"/one").returns true
- @tidy.expects(:tidy?).with(@basepath+"/two").returns false
+ @tidy.expects(:tidy?).with(@basepath).returns true
+ @tidy.expects(:tidy?).with(@basepath+"/one").returns true
+ @tidy.expects(:tidy?).with(@basepath+"/two").returns false
- file = Puppet::Type.type(:file).new(:path => @basepath+"/eh")
- @tidy.expects(:mkfile).with(@basepath).returns file
- @tidy.expects(:mkfile).with(@basepath+"/one").returns file
+ file = Puppet::Type.type(:file).new(:path => @basepath+"/eh")
+ @tidy.expects(:mkfile).with(@basepath).returns file
+ @tidy.expects(:mkfile).with(@basepath+"/one").returns file
- @tidy.generate
- end
- end
+ @tidy.generate
+ end
+ end
- describe "and determining whether a file matches provided glob patterns" do
- before do
- @tidy = Puppet::Type.type(:tidy).new :path => @basepath, :recurse => 1
- @tidy[:matches] = %w{*foo* *bar*}
+ describe "and determining whether a file matches provided glob patterns" do
+ before do
+ @tidy = Puppet::Type.type(:tidy).new :path => @basepath, :recurse => 1
+ @tidy[:matches] = %w{*foo* *bar*}
- @stat = mock 'stat'
+ @stat = mock 'stat'
- @matcher = @tidy.parameter(:matches)
- end
+ @matcher = @tidy.parameter(:matches)
+ end
- it "should always convert the globs to an array" do
- @matcher.value = "*foo*"
- @matcher.value.should == %w{*foo*}
- end
+ it "should always convert the globs to an array" do
+ @matcher.value = "*foo*"
+ @matcher.value.should == %w{*foo*}
+ end
- it "should return true if any pattern matches the last part of the file" do
- @matcher.value = %w{*foo* *bar*}
- @matcher.must be_tidy("/file/yaybarness", @stat)
- end
+ it "should return true if any pattern matches the last part of the file" do
+ @matcher.value = %w{*foo* *bar*}
+ @matcher.must be_tidy("/file/yaybarness", @stat)
+ end
- it "should return false if no pattern matches the last part of the file" do
- @matcher.value = %w{*foo* *bar*}
- @matcher.should_not be_tidy("/file/yayness", @stat)
- end
- end
+ it "should return false if no pattern matches the last part of the file" do
+ @matcher.value = %w{*foo* *bar*}
+ @matcher.should_not be_tidy("/file/yayness", @stat)
+ end
+ end
- describe "and determining whether a file is too old" do
- before do
- @tidy = Puppet::Type.type(:tidy).new :path => @basepath
- @stat = stub 'stat'
+ describe "and determining whether a file is too old" do
+ before do
+ @tidy = Puppet::Type.type(:tidy).new :path => @basepath
+ @stat = stub 'stat'
- @tidy[:age] = "1s"
- @tidy[:type] = "mtime"
- @ager = @tidy.parameter(:age)
- end
+ @tidy[:age] = "1s"
+ @tidy[:type] = "mtime"
+ @ager = @tidy.parameter(:age)
+ end
- it "should use the age type specified" do
- @tidy[:type] = :ctime
- @stat.expects(:ctime).returns(Time.now)
+ it "should use the age type specified" do
+ @tidy[:type] = :ctime
+ @stat.expects(:ctime).returns(Time.now)
- @ager.tidy?(@basepath, @stat)
- end
+ @ager.tidy?(@basepath, @stat)
+ end
- it "should return false if the file is more recent than the specified age" do
- @stat.expects(:mtime).returns(Time.now)
+ it "should return false if the file is more recent than the specified age" do
+ @stat.expects(:mtime).returns(Time.now)
- @ager.should_not be_tidy(@basepath, @stat)
- end
+ @ager.should_not be_tidy(@basepath, @stat)
+ end
- it "should return true if the file is older than the specified age" do
- @stat.expects(:mtime).returns(Time.now - 10)
+ it "should return true if the file is older than the specified age" do
+ @stat.expects(:mtime).returns(Time.now - 10)
- @ager.must be_tidy(@basepath, @stat)
- end
- end
+ @ager.must be_tidy(@basepath, @stat)
+ end
+ end
- describe "and determining whether a file is too large" do
- before do
- @tidy = Puppet::Type.type(:tidy).new :path => @basepath
- @stat = stub 'stat', :ftype => "file"
+ describe "and determining whether a file is too large" do
+ before do
+ @tidy = Puppet::Type.type(:tidy).new :path => @basepath
+ @stat = stub 'stat', :ftype => "file"
- @tidy[:size] = "1kb"
- @sizer = @tidy.parameter(:size)
- end
+ @tidy[:size] = "1kb"
+ @sizer = @tidy.parameter(:size)
+ end
- it "should return false if the file is smaller than the specified size" do
- @stat.expects(:size).returns(4) # smaller than a kilobyte
+ it "should return false if the file is smaller than the specified size" do
+ @stat.expects(:size).returns(4) # smaller than a kilobyte
- @sizer.should_not be_tidy(@basepath, @stat)
- end
+ @sizer.should_not be_tidy(@basepath, @stat)
+ end
- it "should return true if the file is larger than the specified size" do
- @stat.expects(:size).returns(1500) # larger than a kilobyte
+ it "should return true if the file is larger than the specified size" do
+ @stat.expects(:size).returns(1500) # larger than a kilobyte
- @sizer.must be_tidy(@basepath, @stat)
- end
+ @sizer.must be_tidy(@basepath, @stat)
+ end
- it "should return true if the file is equal to the specified size" do
- @stat.expects(:size).returns(1024)
+ it "should return true if the file is equal to the specified size" do
+ @stat.expects(:size).returns(1024)
- @sizer.must be_tidy(@basepath, @stat)
- end
- end
+ @sizer.must be_tidy(@basepath, @stat)
+ end
+ end
- describe "and determining whether a file should be tidied" do
- before do
- @tidy = Puppet::Type.type(:tidy).new :path => @basepath
- @stat = stub 'stat', :ftype => "file"
- File.stubs(:lstat).with(@basepath).returns @stat
- end
+ describe "and determining whether a file should be tidied" do
+ before do
+ @tidy = Puppet::Type.type(:tidy).new :path => @basepath
+ @stat = stub 'stat', :ftype => "file"
+ File.stubs(:lstat).with(@basepath).returns @stat
+ end
- it "should not try to recurse if the file does not exist" do
- @tidy[:recurse] = true
+ it "should not try to recurse if the file does not exist" do
+ @tidy[:recurse] = true
- File.stubs(:lstat).with(@basepath).returns nil
+ File.stubs(:lstat).with(@basepath).returns nil
- @tidy.generate.should == []
- end
+ @tidy.generate.should == []
+ end
- it "should not be tidied if the file does not exist" do
- File.expects(:lstat).with(@basepath).raises Errno::ENOENT
+ it "should not be tidied if the file does not exist" do
+ File.expects(:lstat).with(@basepath).raises Errno::ENOENT
- @tidy.should_not be_tidy(@basepath)
- end
+ @tidy.should_not be_tidy(@basepath)
+ end
- it "should not be tidied if the user has no access to the file" do
- File.expects(:lstat).with(@basepath).raises Errno::EACCES
+ it "should not be tidied if the user has no access to the file" do
+ File.expects(:lstat).with(@basepath).raises Errno::EACCES
- @tidy.should_not be_tidy(@basepath)
- end
+ @tidy.should_not be_tidy(@basepath)
+ end
- it "should not be tidied if it is a directory and rmdirs is set to false" do
- stat = mock 'stat', :ftype => "directory"
- File.expects(:lstat).with(@basepath).returns stat
+ it "should not be tidied if it is a directory and rmdirs is set to false" do
+ stat = mock 'stat', :ftype => "directory"
+ File.expects(:lstat).with(@basepath).returns stat
- @tidy.should_not be_tidy(@basepath)
- end
+ @tidy.should_not be_tidy(@basepath)
+ end
- it "should return false if it does not match any provided globs" do
- @tidy[:recurse] = 1
- @tidy[:matches] = "globs"
+ it "should return false if it does not match any provided globs" do
+ @tidy[:recurse] = 1
+ @tidy[:matches] = "globs"
- matches = @tidy.parameter(:matches)
- matches.expects(:tidy?).with(@basepath, @stat).returns false
- @tidy.should_not be_tidy(@basepath)
- end
+ matches = @tidy.parameter(:matches)
+ matches.expects(:tidy?).with(@basepath, @stat).returns false
+ @tidy.should_not be_tidy(@basepath)
+ end
- it "should return false if it does not match aging requirements" do
- @tidy[:age] = "1d"
+ it "should return false if it does not match aging requirements" do
+ @tidy[:age] = "1d"
- ager = @tidy.parameter(:age)
- ager.expects(:tidy?).with(@basepath, @stat).returns false
- @tidy.should_not be_tidy(@basepath)
- end
+ ager = @tidy.parameter(:age)
+ ager.expects(:tidy?).with(@basepath, @stat).returns false
+ @tidy.should_not be_tidy(@basepath)
+ end
- it "should return false if it does not match size requirements" do
- @tidy[:size] = "1b"
+ it "should return false if it does not match size requirements" do
+ @tidy[:size] = "1b"
- sizer = @tidy.parameter(:size)
- sizer.expects(:tidy?).with(@basepath, @stat).returns false
- @tidy.should_not be_tidy(@basepath)
- end
+ sizer = @tidy.parameter(:size)
+ sizer.expects(:tidy?).with(@basepath, @stat).returns false
+ @tidy.should_not be_tidy(@basepath)
+ end
- it "should tidy a file if age and size are set but only size matches" do
- @tidy[:size] = "1b"
- @tidy[:age] = "1d"
+ it "should tidy a file if age and size are set but only size matches" do
+ @tidy[:size] = "1b"
+ @tidy[:age] = "1d"
- @tidy.parameter(:size).stubs(:tidy?).returns true
- @tidy.parameter(:age).stubs(:tidy?).returns false
- @tidy.should be_tidy(@basepath)
- end
+ @tidy.parameter(:size).stubs(:tidy?).returns true
+ @tidy.parameter(:age).stubs(:tidy?).returns false
+ @tidy.should be_tidy(@basepath)
+ end
- it "should tidy a file if age and size are set but only age matches" do
- @tidy[:size] = "1b"
- @tidy[:age] = "1d"
+ it "should tidy a file if age and size are set but only age matches" do
+ @tidy[:size] = "1b"
+ @tidy[:age] = "1d"
- @tidy.parameter(:size).stubs(:tidy?).returns false
- @tidy.parameter(:age).stubs(:tidy?).returns true
- @tidy.should be_tidy(@basepath)
- end
+ @tidy.parameter(:size).stubs(:tidy?).returns false
+ @tidy.parameter(:age).stubs(:tidy?).returns true
+ @tidy.should be_tidy(@basepath)
+ end
- it "should tidy all files if neither age nor size is set" do
- @tidy.must be_tidy(@basepath)
- end
+ it "should tidy all files if neither age nor size is set" do
+ @tidy.must be_tidy(@basepath)
+ end
- it "should sort the results inversely by path length, so files are added to the catalog before their directories" do
- @tidy[:recurse] = true
- @tidy[:rmdirs] = true
- fileset = Puppet::FileServing::Fileset.new(@basepath)
- Puppet::FileServing::Fileset.expects(:new).returns fileset
- fileset.expects(:files).returns %w{. one one/two}
+ it "should sort the results inversely by path length, so files are added to the catalog before their directories" do
+ @tidy[:recurse] = true
+ @tidy[:rmdirs] = true
+ fileset = Puppet::FileServing::Fileset.new(@basepath)
+ Puppet::FileServing::Fileset.expects(:new).returns fileset
+ fileset.expects(:files).returns %w{. one one/two}
- @tidy.stubs(:tidy?).returns true
+ @tidy.stubs(:tidy?).returns true
- @tidy.generate.collect { |r| r[:path] }.should == [@basepath+"/one/two", @basepath+"/one", @basepath]
- end
- end
+ @tidy.generate.collect { |r| r[:path] }.should == [@basepath+"/one/two", @basepath+"/one", @basepath]
+ end
+ end
- it "should configure directories to require their contained files if rmdirs is enabled, so the files will be deleted first" do
- @tidy[:recurse] = true
- @tidy[:rmdirs] = true
- fileset = mock 'fileset'
- Puppet::FileServing::Fileset.expects(:new).with(@basepath, :recurse => true).returns fileset
- fileset.expects(:files).returns %w{. one two one/subone two/subtwo one/subone/ssone}
- @tidy.stubs(:tidy?).returns true
-
- result = @tidy.generate.inject({}) { |hash, res| hash[res[:path]] = res; hash }
- {
- @basepath => [ @basepath+"/one", @basepath+"/two" ],
- @basepath+"/one" => [@basepath+"/one/subone"],
- @basepath+"/two" => [@basepath+"/two/subtwo"],
- @basepath+"/one/subone" => [@basepath+"/one/subone/ssone"]
- }.each do |parent, children|
- children.each do |child|
- ref = Puppet::Resource.new(:file, child)
- result[parent][:require].find { |req| req.to_s == ref.to_s }.should_not be_nil
- end
- end
+ it "should configure directories to require their contained files if rmdirs is enabled, so the files will be deleted first" do
+ @tidy[:recurse] = true
+ @tidy[:rmdirs] = true
+ fileset = mock 'fileset'
+ Puppet::FileServing::Fileset.expects(:new).with(@basepath, :recurse => true).returns fileset
+ fileset.expects(:files).returns %w{. one two one/subone two/subtwo one/subone/ssone}
+ @tidy.stubs(:tidy?).returns true
+
+ result = @tidy.generate.inject({}) { |hash, res| hash[res[:path]] = res; hash }
+ {
+ @basepath => [ @basepath+"/one", @basepath+"/two" ],
+ @basepath+"/one" => [@basepath+"/one/subone"],
+ @basepath+"/two" => [@basepath+"/two/subtwo"],
+ @basepath+"/one/subone" => [@basepath+"/one/subone/ssone"]
+ }.each do |parent, children|
+ children.each do |child|
+ ref = Puppet::Resource.new(:file, child)
+ result[parent][:require].find { |req| req.to_s == ref.to_s }.should_not be_nil
end
+ end
end
+ end
end
diff --git a/spec/unit/type/user_spec.rb b/spec/unit/type/user_spec.rb
index c1953bc..abe1893 100755
--- a/spec/unit/type/user_spec.rb
+++ b/spec/unit/type/user_spec.rb
@@ -5,277 +5,277 @@ require File.dirname(__FILE__) + '/../../spec_helper'
user = Puppet::Type.type(:user)
describe user do
- before do
- ENV["PATH"] += File::PATH_SEPARATOR + "/usr/sbin" unless ENV["PATH"].split(File::PATH_SEPARATOR).include?("/usr/sbin")
- @provider = stub 'provider'
- @resource = stub 'resource', :resource => nil, :provider => @provider, :line => nil, :file => nil
+ before do
+ ENV["PATH"] += File::PATH_SEPARATOR + "/usr/sbin" unless ENV["PATH"].split(File::PATH_SEPARATOR).include?("/usr/sbin")
+ @provider = stub 'provider'
+ @resource = stub 'resource', :resource => nil, :provider => @provider, :line => nil, :file => nil
+ end
+
+ it "should have a default provider inheriting from Puppet::Provider" do
+ user.defaultprovider.ancestors.should be_include(Puppet::Provider)
+ end
+
+ it "should be able to create a instance" do
+ user.new(:name => "foo").should_not be_nil
+ end
+
+ it "should have an allows_duplicates feature" do
+ user.provider_feature(:allows_duplicates).should_not be_nil
+ end
+
+ it "should have an manages_homedir feature" do
+ user.provider_feature(:manages_homedir).should_not be_nil
+ end
+
+ it "should have an manages_passwords feature" do
+ user.provider_feature(:manages_passwords).should_not be_nil
+ end
+
+ it "should have a manages_solaris_rbac feature" do
+ user.provider_feature(:manages_solaris_rbac).should_not be_nil
+ end
+
+ describe "instances" do
+ it "should have a valid provider" do
+ user.new(:name => "foo").provider.class.ancestors.should be_include(Puppet::Provider)
+ end
+
+ it "should delegate existence questions to its provider" do
+ instance = user.new(:name => "foo")
+ instance.provider.expects(:exists?).returns "eh"
+ instance.exists?.should == "eh"
+ end
+ end
+
+ properties = [:ensure, :uid, :gid, :home, :comment, :shell, :password, :groups, :roles, :auths, :profiles, :project, :keys]
+
+ properties.each do |property|
+ it "should have a #{property} property" do
+ user.attrclass(property).ancestors.should be_include(Puppet::Property)
end
- it "should have a default provider inheriting from Puppet::Provider" do
- user.defaultprovider.ancestors.should be_include(Puppet::Provider)
+ it "should have documentation for its #{property} property" do
+ user.attrclass(property).doc.should be_instance_of(String)
end
+ end
- it "should be able to create a instance" do
- user.new(:name => "foo").should_not be_nil
+ list_properties = [:groups, :roles, :auths]
+
+ list_properties.each do |property|
+ it "should have a list '#{property}'" do
+ user.attrclass(property).ancestors.should be_include(Puppet::Property::List)
end
+ end
+
+ it "should have an ordered list 'profiles'" do
+ user.attrclass(:profiles).ancestors.should be_include(Puppet::Property::OrderedList)
+ end
- it "should have an allows_duplicates feature" do
- user.provider_feature(:allows_duplicates).should_not be_nil
+ it "should have key values 'keys'" do
+ user.attrclass(:keys).ancestors.should be_include(Puppet::Property::KeyValue)
+ end
+
+ describe "when retrieving all current values" do
+ before do
+ @user = user.new(:name => "foo", :uid => 10)
end
- it "should have an manages_homedir feature" do
- user.provider_feature(:manages_homedir).should_not be_nil
+ it "should return a hash containing values for all set properties" do
+ @user[:gid] = 10
+ @user.property(:ensure).expects(:retrieve).returns :present
+ @user.property(:uid).expects(:retrieve).returns 15
+ @user.property(:gid).expects(:retrieve).returns 15
+ values = @user.retrieve
+ [@user.property(:uid), @user.property(:gid)].each { |property| values.should be_include(property) }
end
- it "should have an manages_passwords feature" do
- user.provider_feature(:manages_passwords).should_not be_nil
+ it "should set all values to :absent if the user is absent" do
+ @user.property(:ensure).expects(:retrieve).returns :absent
+ @user.property(:uid).expects(:retrieve).never
+ @user.retrieve[@user.property(:uid)].should == :absent
end
- it "should have a manages_solaris_rbac feature" do
- user.provider_feature(:manages_solaris_rbac).should_not be_nil
+ it "should include the result of retrieving each property's current value if the user is present" do
+ @user.property(:ensure).expects(:retrieve).returns :present
+ @user.property(:uid).expects(:retrieve).returns 15
+ @user.retrieve[@user.property(:uid)].should == 15
end
+ end
- describe "instances" do
- it "should have a valid provider" do
- user.new(:name => "foo").provider.class.ancestors.should be_include(Puppet::Provider)
- end
+ describe "when managing the ensure property" do
+ before do
+ @ensure = user.attrclass(:ensure).new(:resource => @resource)
+ end
- it "should delegate existence questions to its provider" do
- instance = user.new(:name => "foo")
- instance.provider.expects(:exists?).returns "eh"
- instance.exists?.should == "eh"
- end
+ it "should support a :present value" do
+ lambda { @ensure.should = :present }.should_not raise_error
end
- properties = [:ensure, :uid, :gid, :home, :comment, :shell, :password, :groups, :roles, :auths, :profiles, :project, :keys]
+ it "should support an :absent value" do
+ lambda { @ensure.should = :absent }.should_not raise_error
+ end
- properties.each do |property|
- it "should have a #{property} property" do
- user.attrclass(property).ancestors.should be_include(Puppet::Property)
- end
+ it "should call :create on the provider when asked to sync to the :present state" do
+ @provider.expects(:create)
+ @ensure.should = :present
+ @ensure.sync
+ end
- it "should have documentation for its #{property} property" do
- user.attrclass(property).doc.should be_instance_of(String)
- end
+ it "should call :delete on the provider when asked to sync to the :absent state" do
+ @provider.expects(:delete)
+ @ensure.should = :absent
+ @ensure.sync
end
- list_properties = [:groups, :roles, :auths]
+ describe "and determining the current state" do
+ it "should return :present when the provider indicates the user exists" do
+ @provider.expects(:exists?).returns true
+ @ensure.retrieve.should == :present
+ end
+
+ it "should return :absent when the provider indicates the user does not exist" do
+ @provider.expects(:exists?).returns false
+ @ensure.retrieve.should == :absent
+ end
+ end
+ end
- list_properties.each do |property|
- it "should have a list '#{property}'" do
- user.attrclass(property).ancestors.should be_include(Puppet::Property::List)
- end
+ describe "when managing the uid property" do
+ it "should convert number-looking strings into actual numbers" do
+ uid = user.attrclass(:uid).new(:resource => @resource)
+ uid.should = "50"
+ uid.should.must == 50
end
- it "should have an ordered list 'profiles'" do
- user.attrclass(:profiles).ancestors.should be_include(Puppet::Property::OrderedList)
+ it "should support UIDs as numbers" do
+ uid = user.attrclass(:uid).new(:resource => @resource)
+ uid.should = 50
+ uid.should.must == 50
end
- it "should have key values 'keys'" do
- user.attrclass(:keys).ancestors.should be_include(Puppet::Property::KeyValue)
+ it "should :absent as a value" do
+ uid = user.attrclass(:uid).new(:resource => @resource)
+ uid.should = :absent
+ uid.should.must == :absent
end
+ end
- describe "when retrieving all current values" do
- before do
- @user = user.new(:name => "foo", :uid => 10)
- end
+ describe "when managing the gid" do
+ it "should :absent as a value" do
+ gid = user.attrclass(:gid).new(:resource => @resource)
+ gid.should = :absent
+ gid.should.must == :absent
+ end
- it "should return a hash containing values for all set properties" do
- @user[:gid] = 10
- @user.property(:ensure).expects(:retrieve).returns :present
- @user.property(:uid).expects(:retrieve).returns 15
- @user.property(:gid).expects(:retrieve).returns 15
- values = @user.retrieve
- [@user.property(:uid), @user.property(:gid)].each { |property| values.should be_include(property) }
- end
+ it "should convert number-looking strings into actual numbers" do
+ gid = user.attrclass(:gid).new(:resource => @resource)
+ gid.should = "50"
+ gid.should.must == 50
+ end
- it "should set all values to :absent if the user is absent" do
- @user.property(:ensure).expects(:retrieve).returns :absent
- @user.property(:uid).expects(:retrieve).never
- @user.retrieve[@user.property(:uid)].should == :absent
- end
+ it "should support GIDs specified as integers" do
+ gid = user.attrclass(:gid).new(:resource => @resource)
+ gid.should = 50
+ gid.should.must == 50
+ end
- it "should include the result of retrieving each property's current value if the user is present" do
- @user.property(:ensure).expects(:retrieve).returns :present
- @user.property(:uid).expects(:retrieve).returns 15
- @user.retrieve[@user.property(:uid)].should == 15
- end
+ it "should support groups specified by name" do
+ gid = user.attrclass(:gid).new(:resource => @resource)
+ gid.should = "foo"
+ gid.should.must == "foo"
end
- describe "when managing the ensure property" do
- before do
- @ensure = user.attrclass(:ensure).new(:resource => @resource)
- end
+ describe "when testing whether in sync" do
+ before do
+ @gid = user.attrclass(:gid).new(:resource => @resource, :should => %w{foo bar})
+ end
+
+ it "should return true if no 'should' values are set" do
+ @gid = user.attrclass(:gid).new(:resource => @resource)
- it "should support a :present value" do
- lambda { @ensure.should = :present }.should_not raise_error
- end
+ @gid.must be_insync(500)
+ end
- it "should support an :absent value" do
- lambda { @ensure.should = :absent }.should_not raise_error
- end
+ it "should return true if any of the specified groups are equal to the current integer" do
+ Puppet::Util.expects(:gid).with("foo").returns 300
+ Puppet::Util.expects(:gid).with("bar").returns 500
+
+ @gid.must be_insync(500)
+ end
+
+ it "should return false if none of the specified groups are equal to the current integer" do
+ Puppet::Util.expects(:gid).with("foo").returns 300
+ Puppet::Util.expects(:gid).with("bar").returns 500
+
+ @gid.should_not be_insync(700)
+ end
+ end
- it "should call :create on the provider when asked to sync to the :present state" do
- @provider.expects(:create)
- @ensure.should = :present
- @ensure.sync
- end
+ describe "when syncing" do
+ before do
+ @gid = user.attrclass(:gid).new(:resource => @resource, :should => %w{foo bar})
+ end
- it "should call :delete on the provider when asked to sync to the :absent state" do
- @provider.expects(:delete)
- @ensure.should = :absent
- @ensure.sync
- end
+ it "should use the first found, specified group as the desired value and send it to the provider" do
+ Puppet::Util.expects(:gid).with("foo").returns nil
+ Puppet::Util.expects(:gid).with("bar").returns 500
- describe "and determining the current state" do
- it "should return :present when the provider indicates the user exists" do
- @provider.expects(:exists?).returns true
- @ensure.retrieve.should == :present
- end
+ @provider.expects(:gid=).with 500
- it "should return :absent when the provider indicates the user does not exist" do
- @provider.expects(:exists?).returns false
- @ensure.retrieve.should == :absent
- end
- end
- end
+ @gid.sync
+ end
+ end
+ end
- describe "when managing the uid property" do
- it "should convert number-looking strings into actual numbers" do
- uid = user.attrclass(:uid).new(:resource => @resource)
- uid.should = "50"
- uid.should.must == 50
- end
-
- it "should support UIDs as numbers" do
- uid = user.attrclass(:uid).new(:resource => @resource)
- uid.should = 50
- uid.should.must == 50
- end
-
- it "should :absent as a value" do
- uid = user.attrclass(:uid).new(:resource => @resource)
- uid.should = :absent
- uid.should.must == :absent
- end
- end
-
- describe "when managing the gid" do
- it "should :absent as a value" do
- gid = user.attrclass(:gid).new(:resource => @resource)
- gid.should = :absent
- gid.should.must == :absent
- end
-
- it "should convert number-looking strings into actual numbers" do
- gid = user.attrclass(:gid).new(:resource => @resource)
- gid.should = "50"
- gid.should.must == 50
- end
-
- it "should support GIDs specified as integers" do
- gid = user.attrclass(:gid).new(:resource => @resource)
- gid.should = 50
- gid.should.must == 50
- end
-
- it "should support groups specified by name" do
- gid = user.attrclass(:gid).new(:resource => @resource)
- gid.should = "foo"
- gid.should.must == "foo"
- end
-
- describe "when testing whether in sync" do
- before do
- @gid = user.attrclass(:gid).new(:resource => @resource, :should => %w{foo bar})
- end
-
- it "should return true if no 'should' values are set" do
- @gid = user.attrclass(:gid).new(:resource => @resource)
-
- @gid.must be_insync(500)
- end
-
- it "should return true if any of the specified groups are equal to the current integer" do
- Puppet::Util.expects(:gid).with("foo").returns 300
- Puppet::Util.expects(:gid).with("bar").returns 500
-
- @gid.must be_insync(500)
- end
-
- it "should return false if none of the specified groups are equal to the current integer" do
- Puppet::Util.expects(:gid).with("foo").returns 300
- Puppet::Util.expects(:gid).with("bar").returns 500
-
- @gid.should_not be_insync(700)
- end
- end
-
- describe "when syncing" do
- before do
- @gid = user.attrclass(:gid).new(:resource => @resource, :should => %w{foo bar})
- end
-
- it "should use the first found, specified group as the desired value and send it to the provider" do
- Puppet::Util.expects(:gid).with("foo").returns nil
- Puppet::Util.expects(:gid).with("bar").returns 500
-
- @provider.expects(:gid=).with 500
-
- @gid.sync
- end
- end
- end
-
- describe "when managing passwords" do
- before do
- @password = user.attrclass(:password).new(:resource => @resource, :should => "mypass")
- end
+ describe "when managing passwords" do
+ before do
+ @password = user.attrclass(:password).new(:resource => @resource, :should => "mypass")
+ end
- it "should not include the password in the change log when adding the password" do
- @password.change_to_s(:absent, "mypass").should_not be_include("mypass")
- end
+ it "should not include the password in the change log when adding the password" do
+ @password.change_to_s(:absent, "mypass").should_not be_include("mypass")
+ end
- it "should not include the password in the change log when changing the password" do
- @password.change_to_s("other", "mypass").should_not be_include("mypass")
- end
+ it "should not include the password in the change log when changing the password" do
+ @password.change_to_s("other", "mypass").should_not be_include("mypass")
+ end
- it "should fail if a ':' is included in the password" do
- lambda { @password.should = "some:thing" }.should raise_error(Puppet::Error)
- end
+ it "should fail if a ':' is included in the password" do
+ lambda { @password.should = "some:thing" }.should raise_error(Puppet::Error)
+ end
- it "should allow the value to be set to :absent" do
- lambda { @password.should = :absent }.should_not raise_error
- end
+ it "should allow the value to be set to :absent" do
+ lambda { @password.should = :absent }.should_not raise_error
end
+ end
- describe "when manages_solaris_rbac is enabled" do
- before do
- @provider.stubs(:satisfies?).returns(false)
- @provider.expects(:satisfies?).with([:manages_solaris_rbac]).returns(true)
- end
+ describe "when manages_solaris_rbac is enabled" do
+ before do
+ @provider.stubs(:satisfies?).returns(false)
+ @provider.expects(:satisfies?).with([:manages_solaris_rbac]).returns(true)
+ end
- it "should support a :role value for ensure" do
- @ensure = user.attrclass(:ensure).new(:resource => @resource)
- lambda { @ensure.should = :role }.should_not raise_error
- end
+ it "should support a :role value for ensure" do
+ @ensure = user.attrclass(:ensure).new(:resource => @resource)
+ lambda { @ensure.should = :role }.should_not raise_error
end
+ end
- describe "when user has roles" do
- it "should autorequire roles" do
- testuser = Puppet::Type.type(:user).new(:name => "testuser")
- testuser[:roles] = "testrole"
+ describe "when user has roles" do
+ it "should autorequire roles" do
+ testuser = Puppet::Type.type(:user).new(:name => "testuser")
+ testuser[:roles] = "testrole"
- testrole = Puppet::Type.type(:user).new(:name => "testrole")
+ testrole = Puppet::Type.type(:user).new(:name => "testrole")
- config = Puppet::Resource::Catalog.new :testing do |conf|
- [testuser, testrole].each { |resource| conf.add_resource resource }
- end
- Puppet::Type::User::ProviderDirectoryservice.stubs(:get_macosx_version_major).returns "10.5"
+ config = Puppet::Resource::Catalog.new :testing do |conf|
+ [testuser, testrole].each { |resource| conf.add_resource resource }
+ end
+ Puppet::Type::User::ProviderDirectoryservice.stubs(:get_macosx_version_major).returns "10.5"
- rel = testuser.autorequire[0]
- rel.source.ref.should == testrole.ref
- rel.target.ref.should == testuser.ref
- end
+ rel = testuser.autorequire[0]
+ rel.source.ref.should == testrole.ref
+ rel.target.ref.should == testuser.ref
end
+ end
end
diff --git a/spec/unit/type/zfs_spec.rb b/spec/unit/type/zfs_spec.rb
index 7c12a84..6b0b17f 100755
--- a/spec/unit/type/zfs_spec.rb
+++ b/spec/unit/type/zfs_spec.rb
@@ -5,41 +5,41 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
zfs = Puppet::Type.type(:zfs)
describe zfs do
- properties = [:ensure, :mountpoint, :compression, :copies, :quota, :reservation, :sharenfs, :snapdir]
+ properties = [:ensure, :mountpoint, :compression, :copies, :quota, :reservation, :sharenfs, :snapdir]
- properties.each do |property|
- it "should have a #{property} property" do
- zfs.attrclass(property).ancestors.should be_include(Puppet::Property)
- end
+ properties.each do |property|
+ it "should have a #{property} property" do
+ zfs.attrclass(property).ancestors.should be_include(Puppet::Property)
end
+ end
- parameters = [:name]
+ parameters = [:name]
- parameters.each do |parameter|
- it "should have a #{parameter} parameter" do
- zfs.attrclass(parameter).ancestors.should be_include(Puppet::Parameter)
- end
+ parameters.each do |parameter|
+ it "should have a #{parameter} parameter" do
+ zfs.attrclass(parameter).ancestors.should be_include(Puppet::Parameter)
end
+ end
- it "should autorequire the containing zfss and the zpool" do
- provider = mock "provider"
- provider.stubs(:name).returns(:solaris)
- zfs.stubs(:defaultprovider).returns(provider)
- Puppet::Type.type(:zpool).stubs(:defaultprovider).returns(provider)
+ it "should autorequire the containing zfss and the zpool" do
+ provider = mock "provider"
+ provider.stubs(:name).returns(:solaris)
+ zfs.stubs(:defaultprovider).returns(provider)
+ Puppet::Type.type(:zpool).stubs(:defaultprovider).returns(provider)
- foo_pool = Puppet::Type.type(:zpool).new(:name => "foo")
+ foo_pool = Puppet::Type.type(:zpool).new(:name => "foo")
- foo_bar_zfs = Puppet::Type.type(:zfs).new(:name => "foo/bar")
- foo_bar_baz_zfs = Puppet::Type.type(:zfs).new(:name => "foo/bar/baz")
- foo_bar_baz_buz_zfs = Puppet::Type.type(:zfs).new(:name => "foo/bar/baz/buz")
+ foo_bar_zfs = Puppet::Type.type(:zfs).new(:name => "foo/bar")
+ foo_bar_baz_zfs = Puppet::Type.type(:zfs).new(:name => "foo/bar/baz")
+ foo_bar_baz_buz_zfs = Puppet::Type.type(:zfs).new(:name => "foo/bar/baz/buz")
- config = Puppet::Resource::Catalog.new :testing do |conf|
- [foo_pool, foo_bar_zfs, foo_bar_baz_zfs, foo_bar_baz_buz_zfs].each { |resource| conf.add_resource resource }
- end
+ config = Puppet::Resource::Catalog.new :testing do |conf|
+ [foo_pool, foo_bar_zfs, foo_bar_baz_zfs, foo_bar_baz_buz_zfs].each { |resource| conf.add_resource resource }
+ end
- req = foo_bar_baz_buz_zfs.autorequire.collect { |edge| edge.source.ref }
+ req = foo_bar_baz_buz_zfs.autorequire.collect { |edge| edge.source.ref }
- [foo_pool.ref, foo_bar_zfs.ref, foo_bar_baz_zfs.ref].each { |ref| req.include?(ref).should == true }
- end
+ [foo_pool.ref, foo_bar_zfs.ref, foo_bar_baz_zfs.ref].each { |ref| req.include?(ref).should == true }
+ end
end
diff --git a/spec/unit/type/zone_spec.rb b/spec/unit/type/zone_spec.rb
index 302334b..726ccc2 100755
--- a/spec/unit/type/zone_spec.rb
+++ b/spec/unit/type/zone_spec.rb
@@ -5,56 +5,56 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
zone = Puppet::Type.type(:zone)
describe zone do
- before do
- zone = Puppet::Type.type(:zone)
- provider = stub 'provider'
- provider.stubs(:name).returns(:solaris)
- zone.stubs(:defaultprovider).returns(provider)
- resource = stub 'resource', :resource => nil, :provider => provider, :line => nil, :file => nil
- end
+ before do
+ zone = Puppet::Type.type(:zone)
+ provider = stub 'provider'
+ provider.stubs(:name).returns(:solaris)
+ zone.stubs(:defaultprovider).returns(provider)
+ resource = stub 'resource', :resource => nil, :provider => provider, :line => nil, :file => nil
+ end
- parameters = [:create_args, :install_args, :sysidcfg, :path, :realhostname]
+ parameters = [:create_args, :install_args, :sysidcfg, :path, :realhostname]
- parameters.each do |parameter|
- it "should have a #{parameter} parameter" do
- zone.attrclass(parameter).ancestors.should be_include(Puppet::Parameter)
- end
+ parameters.each do |parameter|
+ it "should have a #{parameter} parameter" do
+ zone.attrclass(parameter).ancestors.should be_include(Puppet::Parameter)
end
+ end
- properties = [:ip, :iptype, :autoboot, :pool, :shares, :inherit]
+ properties = [:ip, :iptype, :autoboot, :pool, :shares, :inherit]
- properties.each do |property|
- it "should have a #{property} property" do
- zone.attrclass(property).ancestors.should be_include(Puppet::Property)
- end
+ properties.each do |property|
+ it "should have a #{property} property" do
+ zone.attrclass(property).ancestors.should be_include(Puppet::Property)
end
+ end
- it "should be invalid when :path is missing" do
- lambda { zone.new(:name => "dummy") }.should raise_error
- end
+ it "should be invalid when :path is missing" do
+ lambda { zone.new(:name => "dummy") }.should raise_error
+ end
- it "should be invalid when :ip is missing a \":\" and iptype is :shared" do
- lambda { zone.new(:name => "dummy", :ip => "if") }.should raise_error
- end
+ it "should be invalid when :ip is missing a \":\" and iptype is :shared" do
+ lambda { zone.new(:name => "dummy", :ip => "if") }.should raise_error
+ end
- it "should be invalid when :ip has a \":\" and iptype is :exclusive" do
- lambda { zone.new(:name => "dummy", :ip => "if:1.2.3.4", :iptype => :exclusive) }.should raise_error
- end
+ it "should be invalid when :ip has a \":\" and iptype is :exclusive" do
+ lambda { zone.new(:name => "dummy", :ip => "if:1.2.3.4", :iptype => :exclusive) }.should raise_error
+ end
- it "should be invalid when :ip has two \":\" and iptype is :exclusive" do
- lambda { zone.new(:name => "dummy", :ip => "if:1.2.3.4:2.3.4.5", :iptype => :exclusive) }.should raise_error
- end
+ it "should be invalid when :ip has two \":\" and iptype is :exclusive" do
+ lambda { zone.new(:name => "dummy", :ip => "if:1.2.3.4:2.3.4.5", :iptype => :exclusive) }.should raise_error
+ end
- it "should be valid when :iptype is :shared and using interface and ip" do
- zone.new(:name => "dummy", :path => "/dummy", :ip => "if:1.2.3.4")
- end
+ it "should be valid when :iptype is :shared and using interface and ip" do
+ zone.new(:name => "dummy", :path => "/dummy", :ip => "if:1.2.3.4")
+ end
- it "should be valid when :iptype is :shared and using interface, ip and default route" do
- zone.new(:name => "dummy", :path => "/dummy", :ip => "if:1.2.3.4:2.3.4.5")
- end
+ it "should be valid when :iptype is :shared and using interface, ip and default route" do
+ zone.new(:name => "dummy", :path => "/dummy", :ip => "if:1.2.3.4:2.3.4.5")
+ end
- it "should be valid when :iptype is :exclusive and using interface" do
- zone.new(:name => "dummy", :path => "/dummy", :ip => "if", :iptype => :exclusive)
- end
+ it "should be valid when :iptype is :exclusive and using interface" do
+ zone.new(:name => "dummy", :path => "/dummy", :ip => "if", :iptype => :exclusive)
+ end
end
diff --git a/spec/unit/type/zpool_spec.rb b/spec/unit/type/zpool_spec.rb
index f2aa3cf..db12459 100755
--- a/spec/unit/type/zpool_spec.rb
+++ b/spec/unit/type/zpool_spec.rb
@@ -5,106 +5,106 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
zpool = Puppet::Type.type(:zpool)
describe zpool do
- before do
- @provider = stub 'provider'
- @resource = stub 'resource', :resource => nil, :provider => @provider, :line => nil, :file => nil
- end
+ before do
+ @provider = stub 'provider'
+ @resource = stub 'resource', :resource => nil, :provider => @provider, :line => nil, :file => nil
+ end
- properties = [:ensure, :disk, :mirror, :raidz, :spare, :log]
+ properties = [:ensure, :disk, :mirror, :raidz, :spare, :log]
- properties.each do |property|
- it "should have a #{property} property" do
- zpool.attrclass(property).ancestors.should be_include(Puppet::Property)
- end
+ properties.each do |property|
+ it "should have a #{property} property" do
+ zpool.attrclass(property).ancestors.should be_include(Puppet::Property)
end
+ end
- parameters = [:pool, :raid_parity]
+ parameters = [:pool, :raid_parity]
- parameters.each do |parameter|
- it "should have a #{parameter} parameter" do
- zpool.attrclass(parameter).ancestors.should be_include(Puppet::Parameter)
- end
+ parameters.each do |parameter|
+ it "should have a #{parameter} parameter" do
+ zpool.attrclass(parameter).ancestors.should be_include(Puppet::Parameter)
end
+ end
end
vdev_property = Puppet::Property::VDev
describe vdev_property do
- before do
- vdev_property.initvars
- @resource = stub 'resource', :[]= => nil, :property => nil
- @property = vdev_property.new(:resource => @resource)
- end
-
- it "should be insync if the devices are the same" do
- @property.should = ["dev1 dev2"]
- @property.insync?(["dev2 dev1"]).must be_true
- end
-
- it "should be out of sync if the devices are not the same" do
- @property.should = ["dev1 dev3"]
- @property.insync?(["dev2 dev1"]).must be_false
- end
-
- it "should be insync if the devices are the same and the should values are comma seperated" do
- @property.should = ["dev1", "dev2"]
- @property.insync?(["dev2 dev1"]).must be_true
- end
-
- it "should be out of sync if the device is absent and should has a value" do
- @property.should = ["dev1", "dev2"]
- @property.insync?(:absent).must be_false
- end
-
- it "should be insync if the device is absent and should is absent" do
- @property.should = [:absent]
- @property.insync?(:absent).must be_true
- end
+ before do
+ vdev_property.initvars
+ @resource = stub 'resource', :[]= => nil, :property => nil
+ @property = vdev_property.new(:resource => @resource)
+ end
+
+ it "should be insync if the devices are the same" do
+ @property.should = ["dev1 dev2"]
+ @property.insync?(["dev2 dev1"]).must be_true
+ end
+
+ it "should be out of sync if the devices are not the same" do
+ @property.should = ["dev1 dev3"]
+ @property.insync?(["dev2 dev1"]).must be_false
+ end
+
+ it "should be insync if the devices are the same and the should values are comma seperated" do
+ @property.should = ["dev1", "dev2"]
+ @property.insync?(["dev2 dev1"]).must be_true
+ end
+
+ it "should be out of sync if the device is absent and should has a value" do
+ @property.should = ["dev1", "dev2"]
+ @property.insync?(:absent).must be_false
+ end
+
+ it "should be insync if the device is absent and should is absent" do
+ @property.should = [:absent]
+ @property.insync?(:absent).must be_true
+ end
end
multi_vdev_property = Puppet::Property::MultiVDev
describe multi_vdev_property do
- before do
- multi_vdev_property.initvars
- @resource = stub 'resource', :[]= => nil, :property => nil
- @property = multi_vdev_property.new(:resource => @resource)
- end
-
- it "should be insync if the devices are the same" do
- @property.should = ["dev1 dev2"]
- @property.insync?(["dev2 dev1"]).must be_true
- end
-
- it "should be out of sync if the devices are not the same" do
- @property.should = ["dev1 dev3"]
- @property.insync?(["dev2 dev1"]).must be_false
- end
-
- it "should be out of sync if the device is absent and should has a value" do
- @property.should = ["dev1", "dev2"]
- @property.insync?(:absent).must be_false
+ before do
+ multi_vdev_property.initvars
+ @resource = stub 'resource', :[]= => nil, :property => nil
+ @property = multi_vdev_property.new(:resource => @resource)
+ end
+
+ it "should be insync if the devices are the same" do
+ @property.should = ["dev1 dev2"]
+ @property.insync?(["dev2 dev1"]).must be_true
+ end
+
+ it "should be out of sync if the devices are not the same" do
+ @property.should = ["dev1 dev3"]
+ @property.insync?(["dev2 dev1"]).must be_false
+ end
+
+ it "should be out of sync if the device is absent and should has a value" do
+ @property.should = ["dev1", "dev2"]
+ @property.insync?(:absent).must be_false
+ end
+
+ it "should be insync if the device is absent and should is absent" do
+ @property.should = [:absent]
+ @property.insync?(:absent).must be_true
+ end
+
+ describe "when there are multiple lists of devices" do
+ it "should be in sync if each group has the same devices" do
+ @property.should = ["dev1 dev2", "dev3 dev4"]
+ @property.insync?(["dev2 dev1", "dev3 dev4"]).must be_true
end
- it "should be insync if the device is absent and should is absent" do
- @property.should = [:absent]
- @property.insync?(:absent).must be_true
+ it "should be out of sync if any group has the different devices" do
+ @property.should = ["dev1 devX", "dev3 dev4"]
+ @property.insync?(["dev2 dev1", "dev3 dev4"]).must be_false
end
- describe "when there are multiple lists of devices" do
- it "should be in sync if each group has the same devices" do
- @property.should = ["dev1 dev2", "dev3 dev4"]
- @property.insync?(["dev2 dev1", "dev3 dev4"]).must be_true
- end
-
- it "should be out of sync if any group has the different devices" do
- @property.should = ["dev1 devX", "dev3 dev4"]
- @property.insync?(["dev2 dev1", "dev3 dev4"]).must be_false
- end
-
- it "should be out of sync if devices are in the wrong group" do
- @property.should = ["dev1 dev2", "dev3 dev4"]
- @property.insync?(["dev2 dev3", "dev1 dev4"]).must be_false
- end
+ it "should be out of sync if devices are in the wrong group" do
+ @property.should = ["dev1 dev2", "dev3 dev4"]
+ @property.insync?(["dev2 dev3", "dev1 dev4"]).must be_false
end
+ end
end
diff --git a/spec/unit/type_spec.rb b/spec/unit/type_spec.rb
index 70597f7..683529d 100755
--- a/spec/unit/type_spec.rb
+++ b/spec/unit/type_spec.rb
@@ -3,527 +3,527 @@
require File.dirname(__FILE__) + '/../spec_helper'
describe Puppet::Type do
- it "should include the Cacher module" do
- Puppet::Type.ancestors.should be_include(Puppet::Util::Cacher)
- end
+ it "should include the Cacher module" do
+ Puppet::Type.ancestors.should be_include(Puppet::Util::Cacher)
+ end
+
+ it "should consider a parameter to be valid if it is a valid parameter" do
+ Puppet::Type.type(:mount).should be_valid_parameter(:path)
+ end
+
+ it "should consider a parameter to be valid if it is a valid property" do
+ Puppet::Type.type(:mount).should be_valid_parameter(:fstype)
+ end
+
+ it "should consider a parameter to be valid if it is a valid metaparam" do
+ Puppet::Type.type(:mount).should be_valid_parameter(:noop)
+ end
+
+ it "should use its catalog as its expirer" do
+ catalog = Puppet::Resource::Catalog.new
+ resource = Puppet::Type.type(:mount).new(:name => "foo", :fstype => "bar", :pass => 1, :ensure => :present)
+ resource.catalog = catalog
+ resource.expirer.should equal(catalog)
+ end
+
+ it "should do nothing when asked to expire when it has no catalog" do
+ resource = Puppet::Type.type(:mount).new(:name => "foo", :fstype => "bar", :pass => 1, :ensure => :present)
+ lambda { resource.expire }.should_not raise_error
+ end
+
+ it "should be able to retrieve a property by name" do
+ resource = Puppet::Type.type(:mount).new(:name => "foo", :fstype => "bar", :pass => 1, :ensure => :present)
+ resource.property(:fstype).must be_instance_of(Puppet::Type.type(:mount).attrclass(:fstype))
+ end
+
+ it "should be able to retrieve a parameter by name" do
+ resource = Puppet::Type.type(:mount).new(:name => "foo", :fstype => "bar", :pass => 1, :ensure => :present)
+ resource.parameter(:name).must be_instance_of(Puppet::Type.type(:mount).attrclass(:name))
+ end
+
+ it "should be able to retrieve a property by name using the :parameter method" do
+ resource = Puppet::Type.type(:mount).new(:name => "foo", :fstype => "bar", :pass => 1, :ensure => :present)
+ resource.parameter(:fstype).must be_instance_of(Puppet::Type.type(:mount).attrclass(:fstype))
+ end
+
+ it "should be able to retrieve all set properties" do
+ resource = Puppet::Type.type(:mount).new(:name => "foo", :fstype => "bar", :pass => 1, :ensure => :present)
+ props = resource.properties
+ props.should_not be_include(nil)
+ [:fstype, :ensure, :pass].each do |name|
+ props.should be_include(resource.parameter(name))
+ end
+ end
+
+ it "should have a method for setting default values for resources" do
+ Puppet::Type.type(:mount).new(:name => "foo").should respond_to(:set_default)
+ end
+
+ it "should do nothing for attributes that have no defaults and no specified value" do
+ Puppet::Type.type(:mount).new(:name => "foo").parameter(:noop).should be_nil
+ end
+
+ it "should have a method for adding tags" do
+ Puppet::Type.type(:mount).new(:name => "foo").should respond_to(:tags)
+ end
+
+ it "should use the tagging module" do
+ Puppet::Type.type(:mount).ancestors.should be_include(Puppet::Util::Tagging)
+ end
+
+ it "should delegate to the tagging module when tags are added" do
+ resource = Puppet::Type.type(:mount).new(:name => "foo")
+ resource.stubs(:tag).with(:mount)
+
+ resource.expects(:tag).with(:tag1, :tag2)
+
+ resource.tags = [:tag1,:tag2]
+ end
+
+ it "should add the current type as tag" do
+ resource = Puppet::Type.type(:mount).new(:name => "foo")
+ resource.stubs(:tag)
+
+ resource.expects(:tag).with(:mount)
+
+ resource.tags = [:tag1,:tag2]
+ end
+
+ it "should have a method to know if the resource is exported" do
+ Puppet::Type.type(:mount).new(:name => "foo").should respond_to(:exported?)
+ end
+
+ it "should have a method to know if the resource is virtual" do
+ Puppet::Type.type(:mount).new(:name => "foo").should respond_to(:virtual?)
+ end
+
+ it "should consider its version to be its catalog version" do
+ resource = Puppet::Type.type(:mount).new(:name => "foo")
+ catalog = Puppet::Resource::Catalog.new
+ catalog.version = 50
+ catalog.add_resource resource
+
+ resource.version.should == 50
+ end
- it "should consider a parameter to be valid if it is a valid parameter" do
- Puppet::Type.type(:mount).should be_valid_parameter(:path)
- end
+ it "should consider its version to be zero if it has no catalog" do
+ Puppet::Type.type(:mount).new(:name => "foo").version.should == 0
+ end
- it "should consider a parameter to be valid if it is a valid property" do
- Puppet::Type.type(:mount).should be_valid_parameter(:fstype)
- end
+ it "should provide source_descriptors" do
+ resource = Puppet::Type.type(:mount).new(:name => "foo")
+ catalog = Puppet::Resource::Catalog.new
+ catalog.version = 50
+ catalog.add_resource resource
+
+ resource.source_descriptors.should == {:version=>50, :tags=>["mount", "foo"], :path=>"/Mount[foo]"}
+ end
- it "should consider a parameter to be valid if it is a valid metaparam" do
- Puppet::Type.type(:mount).should be_valid_parameter(:noop)
- end
+ it "should consider its type to be the name of its class" do
+ Puppet::Type.type(:mount).new(:name => "foo").type.should == :mount
+ end
- it "should use its catalog as its expirer" do
- catalog = Puppet::Resource::Catalog.new
- resource = Puppet::Type.type(:mount).new(:name => "foo", :fstype => "bar", :pass => 1, :ensure => :present)
- resource.catalog = catalog
- resource.expirer.should equal(catalog)
+ describe "when creating an event" do
+ before do
+ @resource = Puppet::Type.type(:mount).new :name => "foo"
end
- it "should do nothing when asked to expire when it has no catalog" do
- resource = Puppet::Type.type(:mount).new(:name => "foo", :fstype => "bar", :pass => 1, :ensure => :present)
- lambda { resource.expire }.should_not raise_error
+ it "should have the resource's reference as the resource" do
+ @resource.event.resource.should == "Mount[foo]"
end
- it "should be able to retrieve a property by name" do
- resource = Puppet::Type.type(:mount).new(:name => "foo", :fstype => "bar", :pass => 1, :ensure => :present)
- resource.property(:fstype).must be_instance_of(Puppet::Type.type(:mount).attrclass(:fstype))
+ it "should have the resource's log level as the default log level" do
+ @resource[:loglevel] = :warning
+ @resource.event.default_log_level.should == :warning
end
- it "should be able to retrieve a parameter by name" do
- resource = Puppet::Type.type(:mount).new(:name => "foo", :fstype => "bar", :pass => 1, :ensure => :present)
- resource.parameter(:name).must be_instance_of(Puppet::Type.type(:mount).attrclass(:name))
+ {:file => "/my/file", :line => 50, :tags => %{foo bar}, :version => 50}.each do |attr, value|
+ it "should set the #{attr}" do
+ @resource.stubs(attr).returns value
+ @resource.event.send(attr).should == value
+ end
end
- it "should be able to retrieve a property by name using the :parameter method" do
- resource = Puppet::Type.type(:mount).new(:name => "foo", :fstype => "bar", :pass => 1, :ensure => :present)
- resource.parameter(:fstype).must be_instance_of(Puppet::Type.type(:mount).attrclass(:fstype))
+ it "should allow specification of event attributes" do
+ @resource.event(:status => "noop").status.should == "noop"
end
+ end
- it "should be able to retrieve all set properties" do
- resource = Puppet::Type.type(:mount).new(:name => "foo", :fstype => "bar", :pass => 1, :ensure => :present)
- props = resource.properties
- props.should_not be_include(nil)
- [:fstype, :ensure, :pass].each do |name|
- props.should be_include(resource.parameter(name))
- end
- end
+ describe "when choosing a default provider" do
+ it "should choose the provider with the highest specificity" do
+ # Make a fake type
+ type = Puppet::Type.newtype(:defaultprovidertest) do
+ newparam(:name) do end
+ end
- it "should have a method for setting default values for resources" do
- Puppet::Type.type(:mount).new(:name => "foo").should respond_to(:set_default)
- end
+ basic = type.provide(:basic) {}
+ greater = type.provide(:greater) {}
- it "should do nothing for attributes that have no defaults and no specified value" do
- Puppet::Type.type(:mount).new(:name => "foo").parameter(:noop).should be_nil
- end
+ basic.stubs(:specificity).returns 1
+ greater.stubs(:specificity).returns 2
- it "should have a method for adding tags" do
- Puppet::Type.type(:mount).new(:name => "foo").should respond_to(:tags)
+ type.defaultprovider.should equal(greater)
end
+ end
- it "should use the tagging module" do
- Puppet::Type.type(:mount).ancestors.should be_include(Puppet::Util::Tagging)
+ describe "when initializing" do
+ describe "and passed a TransObject" do
+ it "should fail" do
+ trans = Puppet::TransObject.new("/foo", :mount)
+ lambda { Puppet::Type.type(:mount).new(trans) }.should raise_error(Puppet::DevError)
+ end
end
- it "should delegate to the tagging module when tags are added" do
- resource = Puppet::Type.type(:mount).new(:name => "foo")
- resource.stubs(:tag).with(:mount)
-
- resource.expects(:tag).with(:tag1, :tag2)
+ describe "and passed a Puppet::Resource instance" do
+ it "should set its title to the title of the resource if the resource type is equal to the current type" do
+ resource = Puppet::Resource.new(:mount, "/foo", :parameters => {:name => "/other"})
+ Puppet::Type.type(:mount).new(resource).title.should == "/foo"
+ end
- resource.tags = [:tag1,:tag2]
- end
+ it "should set its title to the resource reference if the resource type is not equal to the current type" do
+ resource = Puppet::Resource.new(:user, "foo")
+ Puppet::Type.type(:mount).new(resource).title.should == "User[foo]"
+ end
- it "should add the current type as tag" do
- resource = Puppet::Type.type(:mount).new(:name => "foo")
- resource.stubs(:tag)
+ [:line, :file, :catalog, :exported, :virtual].each do |param|
+ it "should copy '#{param}' from the resource if present" do
+ resource = Puppet::Resource.new(:mount, "/foo")
+ resource.send(param.to_s + "=", "foo")
+ resource.send(param.to_s + "=", "foo")
+ Puppet::Type.type(:mount).new(resource).send(param).should == "foo"
+ end
+ end
- resource.expects(:tag).with(:mount)
+ it "should copy any tags from the resource" do
+ resource = Puppet::Resource.new(:mount, "/foo")
+ resource.tag "one", "two"
+ tags = Puppet::Type.type(:mount).new(resource).tags
+ tags.should be_include("one")
+ tags.should be_include("two")
+ end
- resource.tags = [:tag1,:tag2]
+ it "should copy the resource's parameters as its own" do
+ resource = Puppet::Resource.new(:mount, "/foo", :parameters => {:atboot => true, :fstype => "boo"})
+ params = Puppet::Type.type(:mount).new(resource).to_hash
+ params[:fstype].should == "boo"
+ params[:atboot].should == true
+ end
end
- it "should have a method to know if the resource is exported" do
- Puppet::Type.type(:mount).new(:name => "foo").should respond_to(:exported?)
- end
+ describe "and passed a Hash" do
+ it "should extract the title from the hash" do
+ Puppet::Type.type(:mount).new(:title => "/yay").title.should == "/yay"
+ end
- it "should have a method to know if the resource is virtual" do
- Puppet::Type.type(:mount).new(:name => "foo").should respond_to(:virtual?)
- end
+ it "should work when hash keys are provided as strings" do
+ Puppet::Type.type(:mount).new("title" => "/yay").title.should == "/yay"
+ end
- it "should consider its version to be its catalog version" do
- resource = Puppet::Type.type(:mount).new(:name => "foo")
- catalog = Puppet::Resource::Catalog.new
- catalog.version = 50
- catalog.add_resource resource
+ it "should work when hash keys are provided as symbols" do
+ Puppet::Type.type(:mount).new(:title => "/yay").title.should == "/yay"
+ end
- resource.version.should == 50
- end
+ it "should use the name from the hash as the title if no explicit title is provided" do
+ Puppet::Type.type(:mount).new(:name => "/yay").title.should == "/yay"
+ end
- it "should consider its version to be zero if it has no catalog" do
- Puppet::Type.type(:mount).new(:name => "foo").version.should == 0
- end
+ it "should use the Resource Type's namevar to determine how to find the name in the hash" do
+ Puppet::Type.type(:file).new(:path => "/yay").title.should == "/yay"
+ end
- it "should provide source_descriptors" do
- resource = Puppet::Type.type(:mount).new(:name => "foo")
- catalog = Puppet::Resource::Catalog.new
- catalog.version = 50
- catalog.add_resource resource
+ [:catalog].each do |param|
+ it "should extract '#{param}' from the hash if present" do
+ Puppet::Type.type(:mount).new(:name => "/yay", param => "foo").send(param).should == "foo"
+ end
+ end
- resource.source_descriptors.should == {:version=>50, :tags=>["mount", "foo"], :path=>"/Mount[foo]"}
+ it "should use any remaining hash keys as its parameters" do
+ resource = Puppet::Type.type(:mount).new(:title => "/foo", :catalog => "foo", :atboot => true, :fstype => "boo")
+ resource[:fstype].must == "boo"
+ resource[:atboot].must == true
+ end
end
- it "should consider its type to be the name of its class" do
- Puppet::Type.type(:mount).new(:name => "foo").type.should == :mount
+ it "should fail if any invalid attributes have been provided" do
+ lambda { Puppet::Type.type(:mount).new(:title => "/foo", :nosuchattr => "whatever") }.should raise_error(Puppet::Error)
end
- describe "when creating an event" do
- before do
- @resource = Puppet::Type.type(:mount).new :name => "foo"
- end
-
- it "should have the resource's reference as the resource" do
- @resource.event.resource.should == "Mount[foo]"
- end
-
- it "should have the resource's log level as the default log level" do
- @resource[:loglevel] = :warning
- @resource.event.default_log_level.should == :warning
- end
+ it "should set its name to the resource's title if the resource does not have a :name or namevar parameter set" do
+ resource = Puppet::Resource.new(:mount, "/foo")
- {:file => "/my/file", :line => 50, :tags => %{foo bar}, :version => 50}.each do |attr, value|
- it "should set the #{attr}" do
- @resource.stubs(attr).returns value
- @resource.event.send(attr).should == value
- end
- end
-
- it "should allow specification of event attributes" do
- @resource.event(:status => "noop").status.should == "noop"
- end
+ Puppet::Type.type(:mount).new(resource).name.should == "/foo"
end
- describe "when choosing a default provider" do
- it "should choose the provider with the highest specificity" do
- # Make a fake type
- type = Puppet::Type.newtype(:defaultprovidertest) do
- newparam(:name) do end
- end
-
- basic = type.provide(:basic) {}
- greater = type.provide(:greater) {}
-
- basic.stubs(:specificity).returns 1
- greater.stubs(:specificity).returns 2
-
- type.defaultprovider.should equal(greater)
- end
+ it "should fail if no title, name, or namevar are provided" do
+ lambda { Puppet::Type.type(:file).new(:atboot => true) }.should raise_error(Puppet::Error)
end
- describe "when initializing" do
- describe "and passed a TransObject" do
- it "should fail" do
- trans = Puppet::TransObject.new("/foo", :mount)
- lambda { Puppet::Type.type(:mount).new(trans) }.should raise_error(Puppet::DevError)
- end
- end
-
- describe "and passed a Puppet::Resource instance" do
- it "should set its title to the title of the resource if the resource type is equal to the current type" do
- resource = Puppet::Resource.new(:mount, "/foo", :parameters => {:name => "/other"})
- Puppet::Type.type(:mount).new(resource).title.should == "/foo"
- end
-
- it "should set its title to the resource reference if the resource type is not equal to the current type" do
- resource = Puppet::Resource.new(:user, "foo")
- Puppet::Type.type(:mount).new(resource).title.should == "User[foo]"
- end
-
- [:line, :file, :catalog, :exported, :virtual].each do |param|
- it "should copy '#{param}' from the resource if present" do
- resource = Puppet::Resource.new(:mount, "/foo")
- resource.send(param.to_s + "=", "foo")
- resource.send(param.to_s + "=", "foo")
- Puppet::Type.type(:mount).new(resource).send(param).should == "foo"
- end
- end
-
- it "should copy any tags from the resource" do
- resource = Puppet::Resource.new(:mount, "/foo")
- resource.tag "one", "two"
- tags = Puppet::Type.type(:mount).new(resource).tags
- tags.should be_include("one")
- tags.should be_include("two")
- end
-
- it "should copy the resource's parameters as its own" do
- resource = Puppet::Resource.new(:mount, "/foo", :parameters => {:atboot => true, :fstype => "boo"})
- params = Puppet::Type.type(:mount).new(resource).to_hash
- params[:fstype].should == "boo"
- params[:atboot].should == true
- end
- end
-
- describe "and passed a Hash" do
- it "should extract the title from the hash" do
- Puppet::Type.type(:mount).new(:title => "/yay").title.should == "/yay"
- end
-
- it "should work when hash keys are provided as strings" do
- Puppet::Type.type(:mount).new("title" => "/yay").title.should == "/yay"
- end
-
- it "should work when hash keys are provided as symbols" do
- Puppet::Type.type(:mount).new(:title => "/yay").title.should == "/yay"
- end
-
- it "should use the name from the hash as the title if no explicit title is provided" do
- Puppet::Type.type(:mount).new(:name => "/yay").title.should == "/yay"
- end
-
- it "should use the Resource Type's namevar to determine how to find the name in the hash" do
- Puppet::Type.type(:file).new(:path => "/yay").title.should == "/yay"
- end
-
- [:catalog].each do |param|
- it "should extract '#{param}' from the hash if present" do
- Puppet::Type.type(:mount).new(:name => "/yay", param => "foo").send(param).should == "foo"
- end
- end
-
- it "should use any remaining hash keys as its parameters" do
- resource = Puppet::Type.type(:mount).new(:title => "/foo", :catalog => "foo", :atboot => true, :fstype => "boo")
- resource[:fstype].must == "boo"
- resource[:atboot].must == true
- end
- end
-
- it "should fail if any invalid attributes have been provided" do
- lambda { Puppet::Type.type(:mount).new(:title => "/foo", :nosuchattr => "whatever") }.should raise_error(Puppet::Error)
- end
+ it "should set the attributes in the order returned by the class's :allattrs method" do
+ Puppet::Type.type(:mount).stubs(:allattrs).returns([:name, :atboot, :noop])
+ resource = Puppet::Resource.new(:mount, "/foo", :parameters => {:name => "myname", :atboot => "myboot", :noop => "whatever"})
- it "should set its name to the resource's title if the resource does not have a :name or namevar parameter set" do
- resource = Puppet::Resource.new(:mount, "/foo")
+ set = []
- Puppet::Type.type(:mount).new(resource).name.should == "/foo"
- end
+ Puppet::Type.type(:mount).any_instance.stubs(:newattr).with do |param, hash|
+ set << param
+ true
+ end.returns(stub_everything("a property"))
- it "should fail if no title, name, or namevar are provided" do
- lambda { Puppet::Type.type(:file).new(:atboot => true) }.should raise_error(Puppet::Error)
- end
+ Puppet::Type.type(:mount).new(resource)
- it "should set the attributes in the order returned by the class's :allattrs method" do
- Puppet::Type.type(:mount).stubs(:allattrs).returns([:name, :atboot, :noop])
- resource = Puppet::Resource.new(:mount, "/foo", :parameters => {:name => "myname", :atboot => "myboot", :noop => "whatever"})
-
- set = []
-
- Puppet::Type.type(:mount).any_instance.stubs(:newattr).with do |param, hash|
- set << param
- true
- end.returns(stub_everything("a property"))
-
- Puppet::Type.type(:mount).new(resource)
-
- set[-1].should == :noop
- set[-2].should == :atboot
- end
-
- it "should always set the name and then default provider before anything else" do
- Puppet::Type.type(:mount).stubs(:allattrs).returns([:provider, :name, :atboot])
- resource = Puppet::Resource.new(:mount, "/foo", :parameters => {:name => "myname", :atboot => "myboot"})
+ set[-1].should == :noop
+ set[-2].should == :atboot
+ end
- set = []
+ it "should always set the name and then default provider before anything else" do
+ Puppet::Type.type(:mount).stubs(:allattrs).returns([:provider, :name, :atboot])
+ resource = Puppet::Resource.new(:mount, "/foo", :parameters => {:name => "myname", :atboot => "myboot"})
- Puppet::Type.type(:mount).any_instance.stubs(:newattr).with do |param, hash|
- set << param
- true
- end.returns(stub_everything("a property"))
+ set = []
- Puppet::Type.type(:mount).new(resource)
- set[0].should == :name
- set[1].should == :provider
- end
+ Puppet::Type.type(:mount).any_instance.stubs(:newattr).with do |param, hash|
+ set << param
+ true
+ end.returns(stub_everything("a property"))
- # This one is really hard to test :/
- it "should each default immediately if no value is provided" do
- defaults = []
- Puppet::Type.type(:package).any_instance.stubs(:set_default).with { |value| defaults << value; true }
+ Puppet::Type.type(:mount).new(resource)
+ set[0].should == :name
+ set[1].should == :provider
+ end
- Puppet::Type.type(:package).new :name => "whatever"
+ # This one is really hard to test :/
+ it "should each default immediately if no value is provided" do
+ defaults = []
+ Puppet::Type.type(:package).any_instance.stubs(:set_default).with { |value| defaults << value; true }
- defaults[0].should == :provider
- end
+ Puppet::Type.type(:package).new :name => "whatever"
- it "should retain a copy of the originally provided parameters" do
- Puppet::Type.type(:mount).new(:name => "foo", :atboot => true, :noop => false).original_parameters.should == {:atboot => true, :noop => false}
- end
+ defaults[0].should == :provider
+ end
- it "should delete the name via the namevar from the originally provided parameters" do
- Puppet::Type.type(:file).new(:name => "/foo").original_parameters[:path].should be_nil
- end
+ it "should retain a copy of the originally provided parameters" do
+ Puppet::Type.type(:mount).new(:name => "foo", :atboot => true, :noop => false).original_parameters.should == {:atboot => true, :noop => false}
end
- it "should have a class method for converting a hash into a Puppet::Resource instance" do
- Puppet::Type.type(:mount).must respond_to(:hash2resource)
+ it "should delete the name via the namevar from the originally provided parameters" do
+ Puppet::Type.type(:file).new(:name => "/foo").original_parameters[:path].should be_nil
end
+ end
- describe "when converting a hash to a Puppet::Resource instance" do
- before do
- @type = Puppet::Type.type(:mount)
- end
+ it "should have a class method for converting a hash into a Puppet::Resource instance" do
+ Puppet::Type.type(:mount).must respond_to(:hash2resource)
+ end
- it "should treat a :title key as the title of the resource" do
- @type.hash2resource(:name => "/foo", :title => "foo").title.should == "foo"
- end
+ describe "when converting a hash to a Puppet::Resource instance" do
+ before do
+ @type = Puppet::Type.type(:mount)
+ end
- it "should use the name from the hash as the title if no explicit title is provided" do
- @type.hash2resource(:name => "foo").title.should == "foo"
- end
+ it "should treat a :title key as the title of the resource" do
+ @type.hash2resource(:name => "/foo", :title => "foo").title.should == "foo"
+ end
- it "should use the Resource Type's namevar to determine how to find the name in the hash" do
- @type.stubs(:key_attributes).returns([ :myname ])
+ it "should use the name from the hash as the title if no explicit title is provided" do
+ @type.hash2resource(:name => "foo").title.should == "foo"
+ end
- @type.hash2resource(:myname => "foo").title.should == "foo"
- end
+ it "should use the Resource Type's namevar to determine how to find the name in the hash" do
+ @type.stubs(:key_attributes).returns([ :myname ])
- [:catalog].each do |attr|
- it "should use any provided #{attr}" do
- @type.hash2resource(:name => "foo", attr => "eh").send(attr).should == "eh"
- end
- end
+ @type.hash2resource(:myname => "foo").title.should == "foo"
+ end
- it "should set all provided parameters on the resource" do
- @type.hash2resource(:name => "foo", :fstype => "boo", :boot => "fee").to_hash.should == {:name => "foo", :fstype => "boo", :boot => "fee"}
- end
+ [:catalog].each do |attr|
+ it "should use any provided #{attr}" do
+ @type.hash2resource(:name => "foo", attr => "eh").send(attr).should == "eh"
+ end
+ end
- it "should not set the title as a parameter on the resource" do
- @type.hash2resource(:name => "foo", :title => "eh")[:title].should be_nil
- end
+ it "should set all provided parameters on the resource" do
+ @type.hash2resource(:name => "foo", :fstype => "boo", :boot => "fee").to_hash.should == {:name => "foo", :fstype => "boo", :boot => "fee"}
+ end
- it "should not set the catalog as a parameter on the resource" do
- @type.hash2resource(:name => "foo", :catalog => "eh")[:catalog].should be_nil
- end
+ it "should not set the title as a parameter on the resource" do
+ @type.hash2resource(:name => "foo", :title => "eh")[:title].should be_nil
+ end
- it "should treat hash keys equivalently whether provided as strings or symbols" do
- resource = @type.hash2resource("name" => "foo", "title" => "eh", "fstype" => "boo")
- resource.title.should == "eh"
- resource[:name].should == "foo"
- resource[:fstype].should == "boo"
- end
+ it "should not set the catalog as a parameter on the resource" do
+ @type.hash2resource(:name => "foo", :catalog => "eh")[:catalog].should be_nil
end
- describe "when retrieving current property values" do
- before do
- @resource = Puppet::Type.type(:mount).new(:name => "foo", :fstype => "bar", :pass => 1, :ensure => :present)
- @resource.property(:ensure).stubs(:retrieve).returns :absent
- end
+ it "should treat hash keys equivalently whether provided as strings or symbols" do
+ resource = @type.hash2resource("name" => "foo", "title" => "eh", "fstype" => "boo")
+ resource.title.should == "eh"
+ resource[:name].should == "foo"
+ resource[:fstype].should == "boo"
+ end
+ end
- it "should fail if its provider is unsuitable" do
- @resource = Puppet::Type.type(:mount).new(:name => "foo", :fstype => "bar", :pass => 1, :ensure => :present)
- @resource.provider.class.expects(:suitable?).returns false
- lambda { @resource.retrieve_resource }.should raise_error(Puppet::Error)
- end
+ describe "when retrieving current property values" do
+ before do
+ @resource = Puppet::Type.type(:mount).new(:name => "foo", :fstype => "bar", :pass => 1, :ensure => :present)
+ @resource.property(:ensure).stubs(:retrieve).returns :absent
+ end
- it "should return a Puppet::Resource instance with its type and title set appropriately" do
- result = @resource.retrieve_resource
- result.should be_instance_of(Puppet::Resource)
- result.type.should == "Mount"
- result.title.should == "foo"
- end
+ it "should fail if its provider is unsuitable" do
+ @resource = Puppet::Type.type(:mount).new(:name => "foo", :fstype => "bar", :pass => 1, :ensure => :present)
+ @resource.provider.class.expects(:suitable?).returns false
+ lambda { @resource.retrieve_resource }.should raise_error(Puppet::Error)
+ end
- it "should set the name of the returned resource if its own name and title differ" do
- @resource[:name] = "my name"
- @resource.title = "other name"
- @resource.retrieve_resource[:name].should == "my name"
- end
+ it "should return a Puppet::Resource instance with its type and title set appropriately" do
+ result = @resource.retrieve_resource
+ result.should be_instance_of(Puppet::Resource)
+ result.type.should == "Mount"
+ result.title.should == "foo"
+ end
- it "should provide a value for all set properties" do
- values = @resource.retrieve_resource
- [:ensure, :fstype, :pass].each { |property| values[property].should_not be_nil }
- end
+ it "should set the name of the returned resource if its own name and title differ" do
+ @resource[:name] = "my name"
+ @resource.title = "other name"
+ @resource.retrieve_resource[:name].should == "my name"
+ end
- it "should provide a value for 'ensure' even if no desired value is provided" do
- @resource = Puppet::Type.type(:file).new(:path => "/my/file/that/can't/exist")
- end
+ it "should provide a value for all set properties" do
+ values = @resource.retrieve_resource
+ [:ensure, :fstype, :pass].each { |property| values[property].should_not be_nil }
+ end
- it "should not call retrieve on non-ensure properties if the resource is absent and should consider the property absent" do
- @resource.property(:ensure).expects(:retrieve).returns :absent
- @resource.property(:fstype).expects(:retrieve).never
- @resource.retrieve_resource[:fstype].should == :absent
- end
+ it "should provide a value for 'ensure' even if no desired value is provided" do
+ @resource = Puppet::Type.type(:file).new(:path => "/my/file/that/can't/exist")
+ end
- it "should include the result of retrieving each property's current value if the resource is present" do
- @resource.property(:ensure).expects(:retrieve).returns :present
- @resource.property(:fstype).expects(:retrieve).returns 15
- @resource.retrieve_resource[:fstype] == 15
- end
+ it "should not call retrieve on non-ensure properties if the resource is absent and should consider the property absent" do
+ @resource.property(:ensure).expects(:retrieve).returns :absent
+ @resource.property(:fstype).expects(:retrieve).never
+ @resource.retrieve_resource[:fstype].should == :absent
end
+ it "should include the result of retrieving each property's current value if the resource is present" do
+ @resource.property(:ensure).expects(:retrieve).returns :present
+ @resource.property(:fstype).expects(:retrieve).returns 15
+ @resource.retrieve_resource[:fstype] == 15
+ end
+ end
- describe "when in a catalog" do
- before do
- @catalog = Puppet::Resource::Catalog.new
- @container = Puppet::Type.type(:component).new(:name => "container")
- @one = Puppet::Type.type(:file).new(:path => "/file/one")
- @two = Puppet::Type.type(:file).new(:path => "/file/two")
- @catalog.add_resource @container
- @catalog.add_resource @one
- @catalog.add_resource @two
- @catalog.add_edge @container, @one
- @catalog.add_edge @container, @two
- end
+ describe "when in a catalog" do
+ before do
+ @catalog = Puppet::Resource::Catalog.new
+ @container = Puppet::Type.type(:component).new(:name => "container")
+ @one = Puppet::Type.type(:file).new(:path => "/file/one")
+ @two = Puppet::Type.type(:file).new(:path => "/file/two")
- it "should have no parent if there is no in edge" do
- @container.parent.should be_nil
- end
+ @catalog.add_resource @container
+ @catalog.add_resource @one
+ @catalog.add_resource @two
+ @catalog.add_edge @container, @one
+ @catalog.add_edge @container, @two
+ end
- it "should set its parent to its in edge" do
- @one.parent.ref.should == @container.ref
- end
+ it "should have no parent if there is no in edge" do
+ @container.parent.should be_nil
+ end
- after do
- @catalog.clear(true)
- end
+ it "should set its parent to its in edge" do
+ @one.parent.ref.should == @container.ref
end
- it "should have a 'stage' metaparam" do
- Puppet::Type.metaparamclass(:stage).should be_instance_of(Class)
+ after do
+ @catalog.clear(true)
end
+ end
+
+ it "should have a 'stage' metaparam" do
+ Puppet::Type.metaparamclass(:stage).should be_instance_of(Class)
+ end
end
describe Puppet::Type::RelationshipMetaparam do
- it "should be a subclass of Puppet::Parameter" do
- Puppet::Type::RelationshipMetaparam.superclass.should equal(Puppet::Parameter)
- end
+ it "should be a subclass of Puppet::Parameter" do
+ Puppet::Type::RelationshipMetaparam.superclass.should equal(Puppet::Parameter)
+ end
- it "should be able to produce a list of subclasses" do
- Puppet::Type::RelationshipMetaparam.should respond_to(:subclasses)
- end
-
- describe "when munging relationships" do
- before do
- @resource = Puppet::Type.type(:mount).new :name => "/foo"
- @metaparam = Puppet::Type.metaparamclass(:require).new :resource => @resource
- end
+ it "should be able to produce a list of subclasses" do
+ Puppet::Type::RelationshipMetaparam.should respond_to(:subclasses)
+ end
- it "should accept Puppet::Resource instances" do
- ref = Puppet::Resource.new(:file, "/foo")
- @metaparam.munge(ref)[0].should equal(ref)
- end
+ describe "when munging relationships" do
+ before do
+ @resource = Puppet::Type.type(:mount).new :name => "/foo"
+ @metaparam = Puppet::Type.metaparamclass(:require).new :resource => @resource
+ end
- it "should turn any string into a Puppet::Resource" do
- @metaparam.munge("File[/ref]")[0].should be_instance_of(Puppet::Resource)
- end
+ it "should accept Puppet::Resource instances" do
+ ref = Puppet::Resource.new(:file, "/foo")
+ @metaparam.munge(ref)[0].should equal(ref)
end
- it "should be able to validate relationships" do
- Puppet::Type.metaparamclass(:require).new(:resource => mock("resource")).should respond_to(:validate_relationship)
+ it "should turn any string into a Puppet::Resource" do
+ @metaparam.munge("File[/ref]")[0].should be_instance_of(Puppet::Resource)
end
+ end
- it "should fail if any specified resource is not found in the catalog" do
- catalog = mock 'catalog'
- resource = stub 'resource', :catalog => catalog, :ref => "resource"
+ it "should be able to validate relationships" do
+ Puppet::Type.metaparamclass(:require).new(:resource => mock("resource")).should respond_to(:validate_relationship)
+ end
- param = Puppet::Type.metaparamclass(:require).new(:resource => resource, :value => %w{Foo[bar] Class[test]})
+ it "should fail if any specified resource is not found in the catalog" do
+ catalog = mock 'catalog'
+ resource = stub 'resource', :catalog => catalog, :ref => "resource"
- catalog.expects(:resource).with("Foo[bar]").returns "something"
- catalog.expects(:resource).with("Class[Test]").returns nil
+ param = Puppet::Type.metaparamclass(:require).new(:resource => resource, :value => %w{Foo[bar] Class[test]})
- param.expects(:fail).with { |string| string.include?("Class[Test]") }
+ catalog.expects(:resource).with("Foo[bar]").returns "something"
+ catalog.expects(:resource).with("Class[Test]").returns nil
- param.validate_relationship
- end
+ param.expects(:fail).with { |string| string.include?("Class[Test]") }
+
+ param.validate_relationship
+ end
end
describe Puppet::Type.metaparamclass(:check) do
- it "should warn and create an instance of ':audit'" do
- file = Puppet::Type.type(:file).new :path => "/foo"
- file.expects(:warning)
- file[:check] = :mode
- file[:audit].should == [:mode]
- end
+ it "should warn and create an instance of ':audit'" do
+ file = Puppet::Type.type(:file).new :path => "/foo"
+ file.expects(:warning)
+ file[:check] = :mode
+ file[:audit].should == [:mode]
+ end
end
describe Puppet::Type.metaparamclass(:audit) do
- before do
- @resource = Puppet::Type.type(:file).new :path => "/foo"
- end
-
- it "should default to being nil" do
- @resource[:audit].should be_nil
- end
-
- it "should specify all possible properties when asked to audit all properties" do
- @resource[:audit] = :all
-
- list = @resource.class.properties.collect { |p| p.name }
- @resource[:audit].should == list
- end
-
- it "should fail if asked to audit an invalid property" do
- lambda { @resource[:audit] = :foobar }.should raise_error(Puppet::Error)
- end
-
- it "should create an attribute instance for each auditable property" do
- @resource[:audit] = :mode
- @resource.parameter(:mode).should_not be_nil
- end
-
- it "should accept properties specified as a string" do
- @resource[:audit] = "mode"
- @resource.parameter(:mode).should_not be_nil
- end
-
- it "should not create attribute instances for parameters, only properties" do
- @resource[:audit] = :noop
- @resource.parameter(:noop).should be_nil
- end
+ before do
+ @resource = Puppet::Type.type(:file).new :path => "/foo"
+ end
+
+ it "should default to being nil" do
+ @resource[:audit].should be_nil
+ end
+
+ it "should specify all possible properties when asked to audit all properties" do
+ @resource[:audit] = :all
+
+ list = @resource.class.properties.collect { |p| p.name }
+ @resource[:audit].should == list
+ end
+
+ it "should fail if asked to audit an invalid property" do
+ lambda { @resource[:audit] = :foobar }.should raise_error(Puppet::Error)
+ end
+
+ it "should create an attribute instance for each auditable property" do
+ @resource[:audit] = :mode
+ @resource.parameter(:mode).should_not be_nil
+ end
+
+ it "should accept properties specified as a string" do
+ @resource[:audit] = "mode"
+ @resource.parameter(:mode).should_not be_nil
+ end
+
+ it "should not create attribute instances for parameters, only properties" do
+ @resource[:audit] = :noop
+ @resource.parameter(:noop).should be_nil
+ end
end
diff --git a/spec/unit/util/autoload/file_cache_spec.rb b/spec/unit/util/autoload/file_cache_spec.rb
index d52ea45..c94ec71 100755
--- a/spec/unit/util/autoload/file_cache_spec.rb
+++ b/spec/unit/util/autoload/file_cache_spec.rb
@@ -4,156 +4,156 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/util/autoload/file_cache'
class FileCacheTester
- include Puppet::Util::Autoload::FileCache
+ include Puppet::Util::Autoload::FileCache
end
describe Puppet::Util::Autoload::FileCache do
+ before do
+ @cacher = FileCacheTester.new
+ end
+
+ after do
+ Puppet::Util::Autoload::FileCache.clear
+ end
+
+ describe "when checking whether files exist" do
+ it "should have a method for testing whether a file exists" do
+ @cacher.should respond_to(:file_exist?)
+ end
+
+ it "should use lstat to determine whether a file exists" do
+ File.expects(:lstat).with("/my/file")
+ @cacher.file_exist?("/my/file")
+ end
+
+ it "should consider a file as absent if its lstat fails" do
+ File.expects(:lstat).with("/my/file").raises Errno::ENOENT
+ @cacher.should_not be_file_exist("/my/file")
+ end
+
+ it "should consider a file as absent if the directory is absent" do
+ File.expects(:lstat).with("/my/file").raises Errno::ENOTDIR
+ @cacher.should_not be_file_exist("/my/file")
+ end
+
+ it "should consider a file as absent permissions are missing" do
+ File.expects(:lstat).with("/my/file").raises Errno::EACCES
+ @cacher.should_not be_file_exist("/my/file")
+ end
+
+ it "should raise non-fs exceptions" do
+ File.expects(:lstat).with("/my/file").raises ArgumentError
+ lambda { @cacher.file_exist?("/my/file") }.should raise_error(ArgumentError)
+ end
+
+ it "should consider a file as present if its lstat succeeds" do
+ File.expects(:lstat).with("/my/file").returns mock("stat")
+ @cacher.should be_file_exist("/my/file")
+ end
+
+ it "should not stat a file twice in quick succession when the file is missing" do
+ File.expects(:lstat).with("/my/file").once.raises Errno::ENOENT
+ @cacher.should_not be_file_exist("/my/file")
+ @cacher.should_not be_file_exist("/my/file")
+ end
+
+ it "should not stat a file twice in quick succession when the file is present" do
+ File.expects(:lstat).with("/my/file").once.returns mock("stat")
+ @cacher.should be_file_exist("/my/file")
+ @cacher.should be_file_exist("/my/file")
+ end
+
+ it "should expire cached data after 15 seconds" do
+ now = Time.now
+
+ later = now + 16
+
+ Time.expects(:now).times(3).returns(now).then.returns(later).then.returns(later)
+ File.expects(:lstat).with("/my/file").times(2).returns(mock("stat")).then.raises Errno::ENOENT
+ @cacher.should be_file_exist("/my/file")
+ @cacher.should_not be_file_exist("/my/file")
+ end
+
+ it "should share cached data across autoload instances" do
+ File.expects(:lstat).with("/my/file").once.returns mock("stat")
+ other = Puppet::Util::Autoload.new("bar", "tmp")
+
+ @cacher.should be_file_exist("/my/file")
+ other.should be_file_exist("/my/file")
+ end
+ end
+
+ describe "when checking whether files exist" do
before do
- @cacher = FileCacheTester.new
- end
+ @stat = stub 'stat', :directory? => true
+ end
+
+ it "should have a method for determining whether a directory exists" do
+ @cacher.should respond_to(:directory_exist?)
+ end
+
+ it "should use lstat to determine whether a directory exists" do
+ File.expects(:lstat).with("/my/file").returns @stat
+ @cacher.directory_exist?("/my/file")
+ end
+
+ it "should consider a directory as absent if its lstat fails" do
+ File.expects(:lstat).with("/my/file").raises Errno::ENOENT
+ @cacher.should_not be_directory_exist("/my/file")
+ end
+
+ it "should consider a file as absent if the directory is absent" do
+ File.expects(:lstat).with("/my/file").raises Errno::ENOTDIR
+ @cacher.should_not be_directory_exist("/my/file")
+ end
+
+ it "should consider a file as absent permissions are missing" do
+ File.expects(:lstat).with("/my/file").raises Errno::EACCES
+ @cacher.should_not be_directory_exist("/my/file")
+ end
+
+ it "should raise non-fs exceptions" do
+ File.expects(:lstat).with("/my/file").raises ArgumentError
+ lambda { @cacher.directory_exist?("/my/file") }.should raise_error(ArgumentError)
+ end
+
+ it "should consider a directory as present if its lstat succeeds and the stat is of a directory" do
+ @stat.expects(:directory?).returns true
+ File.expects(:lstat).with("/my/file").returns @stat
+ @cacher.should be_directory_exist("/my/file")
+ end
+
+ it "should consider a directory as absent if its lstat succeeds and the stat is not of a directory" do
+ @stat.expects(:directory?).returns false
+ File.expects(:lstat).with("/my/file").returns @stat
+ @cacher.should_not be_directory_exist("/my/file")
+ end
+
+ it "should not stat a directory twice in quick succession when the file is missing" do
+ File.expects(:lstat).with("/my/file").once.raises Errno::ENOENT
+ @cacher.should_not be_directory_exist("/my/file")
+ @cacher.should_not be_directory_exist("/my/file")
+ end
+
+ it "should not stat a directory twice in quick succession when the file is present" do
+ File.expects(:lstat).with("/my/file").once.returns @stat
+ @cacher.should be_directory_exist("/my/file")
+ @cacher.should be_directory_exist("/my/file")
+ end
+
+ it "should not consider a file to be a directory based on cached data" do
+ @stat.stubs(:directory?).returns false
+ File.stubs(:lstat).with("/my/file").returns @stat
+ @cacher.file_exist?("/my/file")
+ @cacher.should_not be_directory_exist("/my/file")
+ end
+
+ it "should share cached data across autoload instances" do
+ File.expects(:lstat).with("/my/file").once.returns @stat
+ other = Puppet::Util::Autoload.new("bar", "tmp")
- after do
- Puppet::Util::Autoload::FileCache.clear
- end
-
- describe "when checking whether files exist" do
- it "should have a method for testing whether a file exists" do
- @cacher.should respond_to(:file_exist?)
- end
-
- it "should use lstat to determine whether a file exists" do
- File.expects(:lstat).with("/my/file")
- @cacher.file_exist?("/my/file")
- end
-
- it "should consider a file as absent if its lstat fails" do
- File.expects(:lstat).with("/my/file").raises Errno::ENOENT
- @cacher.should_not be_file_exist("/my/file")
- end
-
- it "should consider a file as absent if the directory is absent" do
- File.expects(:lstat).with("/my/file").raises Errno::ENOTDIR
- @cacher.should_not be_file_exist("/my/file")
- end
-
- it "should consider a file as absent permissions are missing" do
- File.expects(:lstat).with("/my/file").raises Errno::EACCES
- @cacher.should_not be_file_exist("/my/file")
- end
-
- it "should raise non-fs exceptions" do
- File.expects(:lstat).with("/my/file").raises ArgumentError
- lambda { @cacher.file_exist?("/my/file") }.should raise_error(ArgumentError)
- end
-
- it "should consider a file as present if its lstat succeeds" do
- File.expects(:lstat).with("/my/file").returns mock("stat")
- @cacher.should be_file_exist("/my/file")
- end
-
- it "should not stat a file twice in quick succession when the file is missing" do
- File.expects(:lstat).with("/my/file").once.raises Errno::ENOENT
- @cacher.should_not be_file_exist("/my/file")
- @cacher.should_not be_file_exist("/my/file")
- end
-
- it "should not stat a file twice in quick succession when the file is present" do
- File.expects(:lstat).with("/my/file").once.returns mock("stat")
- @cacher.should be_file_exist("/my/file")
- @cacher.should be_file_exist("/my/file")
- end
-
- it "should expire cached data after 15 seconds" do
- now = Time.now
-
- later = now + 16
-
- Time.expects(:now).times(3).returns(now).then.returns(later).then.returns(later)
- File.expects(:lstat).with("/my/file").times(2).returns(mock("stat")).then.raises Errno::ENOENT
- @cacher.should be_file_exist("/my/file")
- @cacher.should_not be_file_exist("/my/file")
- end
-
- it "should share cached data across autoload instances" do
- File.expects(:lstat).with("/my/file").once.returns mock("stat")
- other = Puppet::Util::Autoload.new("bar", "tmp")
-
- @cacher.should be_file_exist("/my/file")
- other.should be_file_exist("/my/file")
- end
- end
-
- describe "when checking whether files exist" do
- before do
- @stat = stub 'stat', :directory? => true
- end
-
- it "should have a method for determining whether a directory exists" do
- @cacher.should respond_to(:directory_exist?)
- end
-
- it "should use lstat to determine whether a directory exists" do
- File.expects(:lstat).with("/my/file").returns @stat
- @cacher.directory_exist?("/my/file")
- end
-
- it "should consider a directory as absent if its lstat fails" do
- File.expects(:lstat).with("/my/file").raises Errno::ENOENT
- @cacher.should_not be_directory_exist("/my/file")
- end
-
- it "should consider a file as absent if the directory is absent" do
- File.expects(:lstat).with("/my/file").raises Errno::ENOTDIR
- @cacher.should_not be_directory_exist("/my/file")
- end
-
- it "should consider a file as absent permissions are missing" do
- File.expects(:lstat).with("/my/file").raises Errno::EACCES
- @cacher.should_not be_directory_exist("/my/file")
- end
-
- it "should raise non-fs exceptions" do
- File.expects(:lstat).with("/my/file").raises ArgumentError
- lambda { @cacher.directory_exist?("/my/file") }.should raise_error(ArgumentError)
- end
-
- it "should consider a directory as present if its lstat succeeds and the stat is of a directory" do
- @stat.expects(:directory?).returns true
- File.expects(:lstat).with("/my/file").returns @stat
- @cacher.should be_directory_exist("/my/file")
- end
-
- it "should consider a directory as absent if its lstat succeeds and the stat is not of a directory" do
- @stat.expects(:directory?).returns false
- File.expects(:lstat).with("/my/file").returns @stat
- @cacher.should_not be_directory_exist("/my/file")
- end
-
- it "should not stat a directory twice in quick succession when the file is missing" do
- File.expects(:lstat).with("/my/file").once.raises Errno::ENOENT
- @cacher.should_not be_directory_exist("/my/file")
- @cacher.should_not be_directory_exist("/my/file")
- end
-
- it "should not stat a directory twice in quick succession when the file is present" do
- File.expects(:lstat).with("/my/file").once.returns @stat
- @cacher.should be_directory_exist("/my/file")
- @cacher.should be_directory_exist("/my/file")
- end
-
- it "should not consider a file to be a directory based on cached data" do
- @stat.stubs(:directory?).returns false
- File.stubs(:lstat).with("/my/file").returns @stat
- @cacher.file_exist?("/my/file")
- @cacher.should_not be_directory_exist("/my/file")
- end
-
- it "should share cached data across autoload instances" do
- File.expects(:lstat).with("/my/file").once.returns @stat
- other = Puppet::Util::Autoload.new("bar", "tmp")
-
- @cacher.should be_directory_exist("/my/file")
- other.should be_directory_exist("/my/file")
- end
+ @cacher.should be_directory_exist("/my/file")
+ other.should be_directory_exist("/my/file")
end
+ end
end
diff --git a/spec/unit/util/autoload_spec.rb b/spec/unit/util/autoload_spec.rb
index 4186a1f..eb0b705 100755
--- a/spec/unit/util/autoload_spec.rb
+++ b/spec/unit/util/autoload_spec.rb
@@ -5,116 +5,116 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
require 'puppet/util/autoload'
describe Puppet::Util::Autoload do
- before do
- @autoload = Puppet::Util::Autoload.new("foo", "tmp")
-
- @autoload.stubs(:eachdir).yields "/my/dir"
+ before do
+ @autoload = Puppet::Util::Autoload.new("foo", "tmp")
+
+ @autoload.stubs(:eachdir).yields "/my/dir"
+ end
+
+ it "should use the Cacher module" do
+ Puppet::Util::Autoload.ancestors.should be_include(Puppet::Util::Cacher)
+ end
+
+ describe "when building the search path" do
+ it "should collect all of the plugins and lib directories that exist in the current environment's module path" do
+ Puppet.settings.expects(:value).with(:environment).returns "foo"
+ Puppet.settings.expects(:value).with(:modulepath, :foo).returns "/a:/b:/c"
+ Dir.expects(:entries).with("/a").returns %w{one two}
+ Dir.expects(:entries).with("/b").returns %w{one two}
+
+ FileTest.stubs(:directory?).returns false
+ FileTest.expects(:directory?).with("/a").returns true
+ FileTest.expects(:directory?).with("/b").returns true
+ %w{/a/one/plugins /a/two/lib /b/one/plugins /b/two/lib}.each do |d|
+ FileTest.expects(:directory?).with(d).returns true
+ end
+
+ @autoload.module_directories.should == %w{/a/one/plugins /a/two/lib /b/one/plugins /b/two/lib}
end
- it "should use the Cacher module" do
- Puppet::Util::Autoload.ancestors.should be_include(Puppet::Util::Cacher)
+ it "should not look for lib directories in directories starting with '.'" do
+ Puppet.settings.expects(:value).with(:environment).returns "foo"
+ Puppet.settings.expects(:value).with(:modulepath, :foo).returns "/a"
+ Dir.expects(:entries).with("/a").returns %w{. ..}
+
+ FileTest.expects(:directory?).with("/a").returns true
+ FileTest.expects(:directory?).with("/a/./lib").never
+ FileTest.expects(:directory?).with("/a/./plugins").never
+ FileTest.expects(:directory?).with("/a/../lib").never
+ FileTest.expects(:directory?).with("/a/../plugins").never
+
+ @autoload.module_directories
end
- describe "when building the search path" do
- it "should collect all of the plugins and lib directories that exist in the current environment's module path" do
- Puppet.settings.expects(:value).with(:environment).returns "foo"
- Puppet.settings.expects(:value).with(:modulepath, :foo).returns "/a:/b:/c"
- Dir.expects(:entries).with("/a").returns %w{one two}
- Dir.expects(:entries).with("/b").returns %w{one two}
-
- FileTest.stubs(:directory?).returns false
- FileTest.expects(:directory?).with("/a").returns true
- FileTest.expects(:directory?).with("/b").returns true
- %w{/a/one/plugins /a/two/lib /b/one/plugins /b/two/lib}.each do |d|
- FileTest.expects(:directory?).with(d).returns true
- end
-
- @autoload.module_directories.should == %w{/a/one/plugins /a/two/lib /b/one/plugins /b/two/lib}
- end
-
- it "should not look for lib directories in directories starting with '.'" do
- Puppet.settings.expects(:value).with(:environment).returns "foo"
- Puppet.settings.expects(:value).with(:modulepath, :foo).returns "/a"
- Dir.expects(:entries).with("/a").returns %w{. ..}
-
- FileTest.expects(:directory?).with("/a").returns true
- FileTest.expects(:directory?).with("/a/./lib").never
- FileTest.expects(:directory?).with("/a/./plugins").never
- FileTest.expects(:directory?).with("/a/../lib").never
- FileTest.expects(:directory?).with("/a/../plugins").never
-
- @autoload.module_directories
- end
-
- it "should include the module directories, the Puppet libdir, and all of the Ruby load directories" do
- Puppet.stubs(:[]).with(:libdir).returns(%w{/libdir1 /lib/dir/two /third/lib/dir}.join(File::PATH_SEPARATOR))
- @autoload.expects(:module_directories).returns %w{/one /two}
- @autoload.search_directories.should == %w{/one /two /libdir1 /lib/dir/two /third/lib/dir} + $LOAD_PATH
- end
-
- it "should include in its search path all of the search directories that have a subdirectory matching the autoload path" do
- @autoload = Puppet::Util::Autoload.new("foo", "loaddir")
- @autoload.expects(:search_directories).returns %w{/one /two /three}
- FileTest.expects(:directory?).with("/one/loaddir").returns true
- FileTest.expects(:directory?).with("/two/loaddir").returns false
- FileTest.expects(:directory?).with("/three/loaddir").returns true
- @autoload.searchpath.should == ["/one/loaddir", "/three/loaddir"]
- end
+ it "should include the module directories, the Puppet libdir, and all of the Ruby load directories" do
+ Puppet.stubs(:[]).with(:libdir).returns(%w{/libdir1 /lib/dir/two /third/lib/dir}.join(File::PATH_SEPARATOR))
+ @autoload.expects(:module_directories).returns %w{/one /two}
+ @autoload.search_directories.should == %w{/one /two /libdir1 /lib/dir/two /third/lib/dir} + $LOAD_PATH
end
- it "should include its FileCache module" do
- Puppet::Util::Autoload.ancestors.should be_include(Puppet::Util::Autoload::FileCache)
+ it "should include in its search path all of the search directories that have a subdirectory matching the autoload path" do
+ @autoload = Puppet::Util::Autoload.new("foo", "loaddir")
+ @autoload.expects(:search_directories).returns %w{/one /two /three}
+ FileTest.expects(:directory?).with("/one/loaddir").returns true
+ FileTest.expects(:directory?).with("/two/loaddir").returns false
+ FileTest.expects(:directory?).with("/three/loaddir").returns true
+ @autoload.searchpath.should == ["/one/loaddir", "/three/loaddir"]
end
+ end
+
+ it "should include its FileCache module" do
+ Puppet::Util::Autoload.ancestors.should be_include(Puppet::Util::Autoload::FileCache)
+ end
- describe "when loading a file" do
- before do
- @autoload.stubs(:searchpath).returns %w{/a}
- end
+ describe "when loading a file" do
+ before do
+ @autoload.stubs(:searchpath).returns %w{/a}
+ end
- [RuntimeError, LoadError, SyntaxError].each do |error|
- it "should die with Puppet::Error if a #{error.to_s} exception is thrown" do
- @autoload.stubs(:file_exist?).returns true
+ [RuntimeError, LoadError, SyntaxError].each do |error|
+ it "should die with Puppet::Error if a #{error.to_s} exception is thrown" do
+ @autoload.stubs(:file_exist?).returns true
- Kernel.expects(:load).raises error
+ Kernel.expects(:load).raises error
- lambda { @autoload.load("foo") }.should raise_error(Puppet::Error)
- end
- end
+ lambda { @autoload.load("foo") }.should raise_error(Puppet::Error)
+ end
+ end
- it "should not raise an error if the file is missing" do
- @autoload.load("foo").should == false
- end
+ it "should not raise an error if the file is missing" do
+ @autoload.load("foo").should == false
+ end
- it "should register loaded files with the main loaded file list so they are not reloaded by ruby" do
- @autoload.stubs(:file_exist?).returns true
- Kernel.stubs(:load)
+ it "should register loaded files with the main loaded file list so they are not reloaded by ruby" do
+ @autoload.stubs(:file_exist?).returns true
+ Kernel.stubs(:load)
- @autoload.load("myfile")
+ @autoload.load("myfile")
- $LOADED_FEATURES.should be_include("tmp/myfile.rb")
- end
+ $LOADED_FEATURES.should be_include("tmp/myfile.rb")
end
+ end
- describe "when loading all files" do
- before do
- @autoload.stubs(:searchpath).returns %w{/a}
- Dir.stubs(:glob).returns "/path/to/file.rb"
+ describe "when loading all files" do
+ before do
+ @autoload.stubs(:searchpath).returns %w{/a}
+ Dir.stubs(:glob).returns "/path/to/file.rb"
- @autoload.class.stubs(:loaded?).returns(false)
- end
+ @autoload.class.stubs(:loaded?).returns(false)
+ end
- [RuntimeError, LoadError, SyntaxError].each do |error|
- it "should die an if a #{error.to_s} exception is thrown" do
- Kernel.expects(:require).raises error
+ [RuntimeError, LoadError, SyntaxError].each do |error|
+ it "should die an if a #{error.to_s} exception is thrown" do
+ Kernel.expects(:require).raises error
- lambda { @autoload.loadall }.should raise_error(Puppet::Error)
- end
- end
+ lambda { @autoload.loadall }.should raise_error(Puppet::Error)
+ end
+ end
- it "should require the full path to the file" do
- Kernel.expects(:require).with("/path/to/file.rb")
+ it "should require the full path to the file" do
+ Kernel.expects(:require).with("/path/to/file.rb")
- @autoload.loadall
- end
+ @autoload.loadall
end
+ end
end
diff --git a/spec/unit/util/backups_spec.rb b/spec/unit/util/backups_spec.rb
index fa6756e..5c10d4c 100755
--- a/spec/unit/util/backups_spec.rb
+++ b/spec/unit/util/backups_spec.rb
@@ -6,154 +6,154 @@ require 'puppet/util/backups'
include PuppetTest
describe Puppet::Util::Backups do
- before do
- FileTest.stubs(:exists?).returns true
- end
+ before do
+ FileTest.stubs(:exists?).returns true
+ end
- describe "when backing up a file" do
- it "should noop if the file does not exist" do
- FileTest.expects(:exists?).returns false
- file = Puppet::Type.type(:file).new(:name => '/no/such/file')
- file.expects(:bucket).never
+ describe "when backing up a file" do
+ it "should noop if the file does not exist" do
+ FileTest.expects(:exists?).returns false
+ file = Puppet::Type.type(:file).new(:name => '/no/such/file')
+ file.expects(:bucket).never
- file.perform_backup
- end
+ file.perform_backup
+ end
- it "should succeed silently if self[:backup] is false" do
- file = Puppet::Type.type(:file).new(:name => '/no/such/file', :backup => false)
- file.expects(:bucket).never
- FileTest.expects(:exists?).never
- file.perform_backup
- end
+ it "should succeed silently if self[:backup] is false" do
+ file = Puppet::Type.type(:file).new(:name => '/no/such/file', :backup => false)
+ file.expects(:bucket).never
+ FileTest.expects(:exists?).never
+ file.perform_backup
+ end
- it "a bucket should be used when provided" do
- path = '/my/file'
+ it "a bucket should be used when provided" do
+ path = '/my/file'
- File.stubs(:stat).with(path).returns(mock('stat', :ftype => 'file'))
+ File.stubs(:stat).with(path).returns(mock('stat', :ftype => 'file'))
- file = Puppet::Type.type(:file).new(:name => path, :backup => 'foo')
- bucket = stub('bucket', 'name' => 'foo')
- file.stubs(:bucket).returns bucket
+ file = Puppet::Type.type(:file).new(:name => path, :backup => 'foo')
+ bucket = stub('bucket', 'name' => 'foo')
+ file.stubs(:bucket).returns bucket
- bucket.expects(:backup).with(path).returns("mysum")
+ bucket.expects(:backup).with(path).returns("mysum")
- file.perform_backup
- end
+ file.perform_backup
+ end
- it "should propagate any exceptions encountered when backing up to a filebucket" do
- path = '/my/file'
+ it "should propagate any exceptions encountered when backing up to a filebucket" do
+ path = '/my/file'
- File.stubs(:stat).with(path).returns(mock('stat', :ftype => 'file'))
+ File.stubs(:stat).with(path).returns(mock('stat', :ftype => 'file'))
- file = Puppet::Type.type(:file).new(:name => path, :backup => 'foo')
- bucket = stub('bucket', 'name' => 'foo')
- file.stubs(:bucket).returns bucket
+ file = Puppet::Type.type(:file).new(:name => path, :backup => 'foo')
+ bucket = stub('bucket', 'name' => 'foo')
+ file.stubs(:bucket).returns bucket
- bucket.expects(:backup).raises ArgumentError
+ bucket.expects(:backup).raises ArgumentError
- lambda { file.perform_backup }.should raise_error(ArgumentError)
- end
+ lambda { file.perform_backup }.should raise_error(ArgumentError)
+ end
- describe "and no filebucket is configured" do
- it "should remove any local backup if one exists" do
- path = '/my/file'
- FileTest.stubs(:exists?).returns true
+ describe "and no filebucket is configured" do
+ it "should remove any local backup if one exists" do
+ path = '/my/file'
+ FileTest.stubs(:exists?).returns true
- backup = path + ".foo"
+ backup = path + ".foo"
- File.expects(:lstat).with(backup).returns stub("stat", :ftype => "file")
- File.expects(:unlink).with(backup)
+ File.expects(:lstat).with(backup).returns stub("stat", :ftype => "file")
+ File.expects(:unlink).with(backup)
- FileUtils.stubs(:cp_r)
+ FileUtils.stubs(:cp_r)
- file = Puppet::Type.type(:file).new(:name => path, :backup => '.foo')
- file.perform_backup
- end
+ file = Puppet::Type.type(:file).new(:name => path, :backup => '.foo')
+ file.perform_backup
+ end
- it "should fail when the old backup can't be removed" do
- path = '/my/file'
- FileTest.stubs(:exists?).returns true
+ it "should fail when the old backup can't be removed" do
+ path = '/my/file'
+ FileTest.stubs(:exists?).returns true
- backup = path + ".foo"
+ backup = path + ".foo"
- File.expects(:lstat).with(backup).returns stub("stat", :ftype => "file")
- File.expects(:unlink).raises ArgumentError
+ File.expects(:lstat).with(backup).returns stub("stat", :ftype => "file")
+ File.expects(:unlink).raises ArgumentError
- FileUtils.expects(:cp_r).never
+ FileUtils.expects(:cp_r).never
- file = Puppet::Type.type(:file).new(:name => path, :backup => '.foo')
- lambda { file.perform_backup }.should raise_error(Puppet::Error)
- end
+ file = Puppet::Type.type(:file).new(:name => path, :backup => '.foo')
+ lambda { file.perform_backup }.should raise_error(Puppet::Error)
+ end
- it "should not try to remove backups that don't exist" do
- path = '/my/file'
- FileTest.stubs(:exists?).returns true
+ it "should not try to remove backups that don't exist" do
+ path = '/my/file'
+ FileTest.stubs(:exists?).returns true
- backup = path + ".foo"
+ backup = path + ".foo"
- File.expects(:lstat).with(backup).raises(Errno::ENOENT)
- File.expects(:unlink).never
+ File.expects(:lstat).with(backup).raises(Errno::ENOENT)
+ File.expects(:unlink).never
- FileUtils.stubs(:cp_r)
+ FileUtils.stubs(:cp_r)
- file = Puppet::Type.type(:file).new(:name => path, :backup => '.foo')
- file.perform_backup
- end
+ file = Puppet::Type.type(:file).new(:name => path, :backup => '.foo')
+ file.perform_backup
+ end
- it "a copy should be created in the local directory" do
- path = '/my/file'
- FileTest.stubs(:exists?).with(path).returns true
+ it "a copy should be created in the local directory" do
+ path = '/my/file'
+ FileTest.stubs(:exists?).with(path).returns true
- FileUtils.expects(:cp_r).with(path, path + ".foo", :preserve => true)
+ FileUtils.expects(:cp_r).with(path, path + ".foo", :preserve => true)
- file = Puppet::Type.type(:file).new(:name => path, :backup => '.foo')
- file.perform_backup.should be_true
- end
+ file = Puppet::Type.type(:file).new(:name => path, :backup => '.foo')
+ file.perform_backup.should be_true
+ end
- it "should propagate exceptions if no backup can be created" do
- path = '/my/file'
- FileTest.stubs(:exists?).with(path).returns true
+ it "should propagate exceptions if no backup can be created" do
+ path = '/my/file'
+ FileTest.stubs(:exists?).with(path).returns true
- FileUtils.expects(:cp_r).raises ArgumentError
+ FileUtils.expects(:cp_r).raises ArgumentError
- file = Puppet::Type.type(:file).new(:name => path, :backup => '.foo')
- lambda { file.perform_backup }.should raise_error(Puppet::Error)
- end
- end
+ file = Puppet::Type.type(:file).new(:name => path, :backup => '.foo')
+ lambda { file.perform_backup }.should raise_error(Puppet::Error)
+ end
end
+ end
- describe "when backing up a directory" do
- it "a bucket should work when provided" do
- path = '/my/dir'
+ describe "when backing up a directory" do
+ it "a bucket should work when provided" do
+ path = '/my/dir'
- File.stubs(:file?).returns true
- Find.expects(:find).with(path).yields("/my/dir/file")
+ File.stubs(:file?).returns true
+ Find.expects(:find).with(path).yields("/my/dir/file")
- bucket = stub('bucket', :name => "eh")
- bucket.expects(:backup).with("/my/dir/file").returns true
+ bucket = stub('bucket', :name => "eh")
+ bucket.expects(:backup).with("/my/dir/file").returns true
- file = Puppet::Type.type(:file).new(:name => path, :backup => 'foo')
- file.stubs(:bucket).returns bucket
+ file = Puppet::Type.type(:file).new(:name => path, :backup => 'foo')
+ file.stubs(:bucket).returns bucket
- File.stubs(:stat).with(path).returns(stub('stat', :ftype => 'directory'))
+ File.stubs(:stat).with(path).returns(stub('stat', :ftype => 'directory'))
- file.perform_backup
- end
+ file.perform_backup
+ end
- it "should do nothing when recursing" do
- path = '/my/dir'
+ it "should do nothing when recursing" do
+ path = '/my/dir'
- bucket = stub('bucket', :name => "eh")
- bucket.expects(:backup).never
+ bucket = stub('bucket', :name => "eh")
+ bucket.expects(:backup).never
- file = Puppet::Type.type(:file).new(:name => path, :backup => 'foo', :recurse => true)
- file.stubs(:bucket).returns bucket
+ file = Puppet::Type.type(:file).new(:name => path, :backup => 'foo', :recurse => true)
+ file.stubs(:bucket).returns bucket
- File.stubs(:stat).with(path).returns(stub('stat', :ftype => 'directory'))
+ File.stubs(:stat).with(path).returns(stub('stat', :ftype => 'directory'))
- Find.expects(:find).never
+ Find.expects(:find).never
- file.perform_backup
- end
+ file.perform_backup
end
+ end
end
diff --git a/spec/unit/util/cache_accumulator_spec.rb b/spec/unit/util/cache_accumulator_spec.rb
index 3b5d681..469522a 100644
--- a/spec/unit/util/cache_accumulator_spec.rb
+++ b/spec/unit/util/cache_accumulator_spec.rb
@@ -4,72 +4,72 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/util/rails/cache_accumulator'
describe Puppet::Util::CacheAccumulator do
- before :each do
- @test_class = Class.new do
- attr_accessor :name
+ before :each do
+ @test_class = Class.new do
+ attr_accessor :name
- include Puppet::Util::CacheAccumulator
- accumulates :name
+ include Puppet::Util::CacheAccumulator
+ accumulates :name
- def initialize(n)
- self.name = n
- end
- end
+ def initialize(n)
+ self.name = n
+ end
end
+ end
- it 'should delegate to underlying find_or_create_by_* method and accumulate results' do
- @test_class.expects(:find_or_create_by_name).with('foo').returns(@test_class.new('foo')).once
- obj = @test_class.accumulate_by_name('foo')
- obj.name.should == 'foo'
- @test_class.accumulate_by_name('foo').should == obj
- end
+ it 'should delegate to underlying find_or_create_by_* method and accumulate results' do
+ @test_class.expects(:find_or_create_by_name).with('foo').returns(@test_class.new('foo')).once
+ obj = @test_class.accumulate_by_name('foo')
+ obj.name.should == 'foo'
+ @test_class.accumulate_by_name('foo').should == obj
+ end
- it 'should delegate bulk lookups to find with appropriate arguments and returning result count' do
+ it 'should delegate bulk lookups to find with appropriate arguments and returning result count' do
- @test_class.expects(:find).with(
- :all,
+ @test_class.expects(:find).with(
+ :all,
- :conditions => {:name => ['a', 'b', 'c']}
- ).returns(['a','b','c'].collect {|n| @test_class.new(n)}).once
- @test_class.accumulate_by_name('a', 'b', 'c').should == 3
- end
+ :conditions => {:name => ['a', 'b', 'c']}
+ ).returns(['a','b','c'].collect {|n| @test_class.new(n)}).once
+ @test_class.accumulate_by_name('a', 'b', 'c').should == 3
+ end
- it 'should only need find_or_create_by_name lookup for missing bulk entries' do
+ it 'should only need find_or_create_by_name lookup for missing bulk entries' do
- @test_class.expects(:find).with(
- :all,
+ @test_class.expects(:find).with(
+ :all,
- :conditions => {:name => ['a', 'b']}
- ).returns([ @test_class.new('a') ]).once
- @test_class.expects(:find_or_create_by_name).with('b').returns(@test_class.new('b')).once
- @test_class.expects(:find_or_create_by_name).with('a').never
- @test_class.accumulate_by_name('a','b').should == 1
- @test_class.accumulate_by_name('a').name.should == 'a'
- @test_class.accumulate_by_name('b').name.should == 'b'
- end
+ :conditions => {:name => ['a', 'b']}
+ ).returns([ @test_class.new('a') ]).once
+ @test_class.expects(:find_or_create_by_name).with('b').returns(@test_class.new('b')).once
+ @test_class.expects(:find_or_create_by_name).with('a').never
+ @test_class.accumulate_by_name('a','b').should == 1
+ @test_class.accumulate_by_name('a').name.should == 'a'
+ @test_class.accumulate_by_name('b').name.should == 'b'
+ end
- it 'should keep consumer classes separate' do
- @alt_class = Class.new do
- attr_accessor :name
-
- include Puppet::Util::CacheAccumulator
- accumulates :name
-
- def initialize(n)
- self.name = n
- end
- end
- name = 'foo'
- @test_class.expects(:find_or_create_by_name).with(name).returns(@test_class.new(name)).once
- @alt_class.expects(:find_or_create_by_name).with(name).returns(@alt_class.new(name)).once
-
- [@test_class, @alt_class].each do |klass|
- klass.accumulate_by_name(name).name.should == name
- klass.accumulate_by_name(name).class.should == klass
- end
+ it 'should keep consumer classes separate' do
+ @alt_class = Class.new do
+ attr_accessor :name
+
+ include Puppet::Util::CacheAccumulator
+ accumulates :name
+
+ def initialize(n)
+ self.name = n
+ end
end
+ name = 'foo'
+ @test_class.expects(:find_or_create_by_name).with(name).returns(@test_class.new(name)).once
+ @alt_class.expects(:find_or_create_by_name).with(name).returns(@alt_class.new(name)).once
- it 'should clear accumulated cache with reset_*_accumulator' do
- # figure out how to test this appropriately...
+ [@test_class, @alt_class].each do |klass|
+ klass.accumulate_by_name(name).name.should == name
+ klass.accumulate_by_name(name).class.should == klass
end
+ end
+
+ it 'should clear accumulated cache with reset_*_accumulator' do
+ # figure out how to test this appropriately...
+ end
end
diff --git a/spec/unit/util/cacher_spec.rb b/spec/unit/util/cacher_spec.rb
index eb8515e..89783ed 100755
--- a/spec/unit/util/cacher_spec.rb
+++ b/spec/unit/util/cacher_spec.rb
@@ -5,181 +5,181 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/util/cacher'
class ExpirerTest
- include Puppet::Util::Cacher::Expirer
+ include Puppet::Util::Cacher::Expirer
end
class CacheTest
- @@init_count = 0
+ @@init_count = 0
- include Puppet::Util::Cacher
- cached_attr(:instance_cache) { Time.now }
+ include Puppet::Util::Cacher
+ cached_attr(:instance_cache) { Time.now }
end
describe Puppet::Util::Cacher::Expirer do
- before do
- @expirer = ExpirerTest.new
- end
+ before do
+ @expirer = ExpirerTest.new
+ end
+
+ it "should be able to test whether a timestamp is expired" do
+ @expirer.should respond_to(:dependent_data_expired?)
+ end
+
+ it "should be able to expire all values" do
+ @expirer.should respond_to(:expire)
+ end
+
+ it "should consider any value to be valid if it has never been expired" do
+ @expirer.should_not be_dependent_data_expired(Time.now)
+ end
+
+ it "should consider any value created after expiration to be expired" do
+ @expirer.expire
+ @expirer.should be_dependent_data_expired(Time.now - 1)
+ end
+end
- it "should be able to test whether a timestamp is expired" do
- @expirer.should respond_to(:dependent_data_expired?)
- end
+describe Puppet::Util::Cacher do
+ it "should be extended with the Expirer module" do
+ Puppet::Util::Cacher.singleton_class.ancestors.should be_include(Puppet::Util::Cacher::Expirer)
+ end
- it "should be able to expire all values" do
- @expirer.should respond_to(:expire)
- end
+ it "should support defining cached attributes" do
+ CacheTest.methods.should be_include("cached_attr")
+ end
- it "should consider any value to be valid if it has never been expired" do
- @expirer.should_not be_dependent_data_expired(Time.now)
- end
+ it "should default to the Cacher module as its expirer" do
+ CacheTest.new.expirer.should equal(Puppet::Util::Cacher)
+ end
- it "should consider any value created after expiration to be expired" do
- @expirer.expire
- @expirer.should be_dependent_data_expired(Time.now - 1)
- end
-end
+ describe "when using cached attributes" do
+ before do
+ @expirer = ExpirerTest.new
+ @object = CacheTest.new
-describe Puppet::Util::Cacher do
- it "should be extended with the Expirer module" do
- Puppet::Util::Cacher.singleton_class.ancestors.should be_include(Puppet::Util::Cacher::Expirer)
+ @object.stubs(:expirer).returns @expirer
end
- it "should support defining cached attributes" do
- CacheTest.methods.should be_include("cached_attr")
+ it "should create a getter for the cached attribute" do
+ @object.should respond_to(:instance_cache)
end
- it "should default to the Cacher module as its expirer" do
- CacheTest.new.expirer.should equal(Puppet::Util::Cacher)
+ it "should return a value calculated from the provided block" do
+ time = Time.now
+ Time.stubs(:now).returns time
+ @object.instance_cache.should equal(time)
end
- describe "when using cached attributes" do
- before do
- @expirer = ExpirerTest.new
- @object = CacheTest.new
-
- @object.stubs(:expirer).returns @expirer
- end
-
- it "should create a getter for the cached attribute" do
- @object.should respond_to(:instance_cache)
- end
-
- it "should return a value calculated from the provided block" do
- time = Time.now
- Time.stubs(:now).returns time
- @object.instance_cache.should equal(time)
- end
+ it "should return the cached value from the getter every time if the value is not expired" do
+ @object.instance_cache.should equal(@object.instance_cache)
+ end
- it "should return the cached value from the getter every time if the value is not expired" do
- @object.instance_cache.should equal(@object.instance_cache)
- end
+ it "should regenerate and return a new value using the provided block if the value has been expired" do
+ value = @object.instance_cache
+ @expirer.expire
+ @object.instance_cache.should_not equal(value)
+ end
- it "should regenerate and return a new value using the provided block if the value has been expired" do
- value = @object.instance_cache
- @expirer.expire
- @object.instance_cache.should_not equal(value)
- end
+ it "should be able to trigger expiration on its expirer" do
+ @expirer.expects(:expire)
+ @object.expire
+ end
- it "should be able to trigger expiration on its expirer" do
- @expirer.expects(:expire)
- @object.expire
+ it "should do nothing when asked to expire when no expirer is available" do
+ cacher = CacheTest.new
+ class << cacher
+ def expirer
+ nil
end
+ end
+ lambda { cacher.expire }.should_not raise_error
+ end
- it "should do nothing when asked to expire when no expirer is available" do
- cacher = CacheTest.new
- class << cacher
- def expirer
- nil
- end
- end
- lambda { cacher.expire }.should_not raise_error
- end
+ it "should be able to cache false values" do
+ @object.expects(:init_instance_cache).returns false
+ @object.instance_cache.should be_false
+ @object.instance_cache.should be_false
+ end
- it "should be able to cache false values" do
- @object.expects(:init_instance_cache).returns false
- @object.instance_cache.should be_false
- @object.instance_cache.should be_false
- end
+ it "should cache values again after expiration" do
+ @object.instance_cache
+ @expirer.expire
+ @object.instance_cache.should equal(@object.instance_cache)
+ end
- it "should cache values again after expiration" do
- @object.instance_cache
- @expirer.expire
- @object.instance_cache.should equal(@object.instance_cache)
- end
+ it "should always consider a value expired if it has no expirer" do
+ @object.stubs(:expirer).returns nil
+ @object.instance_cache.should_not equal(@object.instance_cache)
+ end
- it "should always consider a value expired if it has no expirer" do
- @object.stubs(:expirer).returns nil
- @object.instance_cache.should_not equal(@object.instance_cache)
- end
+ it "should allow writing of the attribute" do
+ @object.should respond_to(:instance_cache=)
+ end
- it "should allow writing of the attribute" do
- @object.should respond_to(:instance_cache=)
- end
+ it "should correctly configure timestamps for expiration when the cached attribute is written to" do
+ @object.instance_cache = "foo"
+ @expirer.expire
+ @object.instance_cache.should_not == "foo"
+ end
- it "should correctly configure timestamps for expiration when the cached attribute is written to" do
- @object.instance_cache = "foo"
- @expirer.expire
- @object.instance_cache.should_not == "foo"
- end
+ it "should allow specification of a ttl for cached attributes" do
+ klass = Class.new do
+ include Puppet::Util::Cacher
+ end
- it "should allow specification of a ttl for cached attributes" do
- klass = Class.new do
- include Puppet::Util::Cacher
- end
+ klass.cached_attr(:myattr, :ttl => 5) { Time.now }
- klass.cached_attr(:myattr, :ttl => 5) { Time.now }
+ klass.attr_ttl(:myattr).should == 5
+ end
- klass.attr_ttl(:myattr).should == 5
- end
+ it "should allow specification of a ttl as a string" do
+ klass = Class.new do
+ include Puppet::Util::Cacher
+ end
- it "should allow specification of a ttl as a string" do
- klass = Class.new do
- include Puppet::Util::Cacher
- end
+ klass.cached_attr(:myattr, :ttl => "5") { Time.now }
- klass.cached_attr(:myattr, :ttl => "5") { Time.now }
+ klass.attr_ttl(:myattr).should == 5
+ end
- klass.attr_ttl(:myattr).should == 5
- end
+ it "should fail helpfully if the ttl cannot be converted to an integer" do
+ klass = Class.new do
+ include Puppet::Util::Cacher
+ end
- it "should fail helpfully if the ttl cannot be converted to an integer" do
- klass = Class.new do
- include Puppet::Util::Cacher
- end
+ lambda { klass.cached_attr(:myattr, :ttl => "yep") { Time.now } }.should raise_error(ArgumentError)
+ end
- lambda { klass.cached_attr(:myattr, :ttl => "yep") { Time.now } }.should raise_error(ArgumentError)
- end
+ it "should not check for a ttl expiration if the class does not support that method" do
+ klass = Class.new do
+ extend Puppet::Util::Cacher
+ end
- it "should not check for a ttl expiration if the class does not support that method" do
- klass = Class.new do
- extend Puppet::Util::Cacher
- end
+ klass.singleton_class.cached_attr(:myattr) { "eh" }
+ klass.myattr
+ end
- klass.singleton_class.cached_attr(:myattr) { "eh" }
- klass.myattr
+ it "should automatically expire cached attributes whose ttl has expired, even if no expirer is present" do
+ klass = Class.new do
+ def self.to_s
+ "CacheTestClass"
end
+ include Puppet::Util::Cacher
+ attr_accessor :value
+ end
- it "should automatically expire cached attributes whose ttl has expired, even if no expirer is present" do
- klass = Class.new do
- def self.to_s
- "CacheTestClass"
- end
- include Puppet::Util::Cacher
- attr_accessor :value
- end
+ klass.cached_attr(:myattr, :ttl => 5) { self.value += 1; self.value }
- klass.cached_attr(:myattr, :ttl => 5) { self.value += 1; self.value }
+ now = Time.now
+ later = Time.now + 15
- now = Time.now
- later = Time.now + 15
+ instance = klass.new
+ instance.value = 0
+ instance.myattr.should == 1
- instance = klass.new
- instance.value = 0
- instance.myattr.should == 1
+ Time.expects(:now).returns later
- Time.expects(:now).returns later
-
- # This call should get the new Time value, which should expire the old value
- instance.myattr.should == 2
- end
+ # This call should get the new Time value, which should expire the old value
+ instance.myattr.should == 2
end
+ end
end
diff --git a/spec/unit/util/checksums_spec.rb b/spec/unit/util/checksums_spec.rb
index af18a94..e018581 100755
--- a/spec/unit/util/checksums_spec.rb
+++ b/spec/unit/util/checksums_spec.rb
@@ -8,146 +8,146 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/util/checksums'
describe Puppet::Util::Checksums do
- before do
- @summer = Object.new
- @summer.extend(Puppet::Util::Checksums)
- end
+ before do
+ @summer = Object.new
+ @summer.extend(Puppet::Util::Checksums)
+ end
- content_sums = [:md5, :md5lite, :sha1, :sha1lite]
- file_only = [:ctime, :mtime, :none]
+ content_sums = [:md5, :md5lite, :sha1, :sha1lite]
+ file_only = [:ctime, :mtime, :none]
- content_sums.each do |sumtype|
- it "should be able to calculate #{sumtype} sums from strings" do
- @summer.should be_respond_to(sumtype)
- end
+ content_sums.each do |sumtype|
+ it "should be able to calculate #{sumtype} sums from strings" do
+ @summer.should be_respond_to(sumtype)
end
+ end
- [content_sums, file_only].flatten.each do |sumtype|
- it "should be able to calculate #{sumtype} sums from files" do
- @summer.should be_respond_to(sumtype.to_s + "_file")
- end
+ [content_sums, file_only].flatten.each do |sumtype|
+ it "should be able to calculate #{sumtype} sums from files" do
+ @summer.should be_respond_to(sumtype.to_s + "_file")
end
+ end
- [content_sums, file_only].flatten.each do |sumtype|
- it "should be able to calculate #{sumtype} sums from stream" do
- @summer.should be_respond_to(sumtype.to_s + "_stream")
- end
+ [content_sums, file_only].flatten.each do |sumtype|
+ it "should be able to calculate #{sumtype} sums from stream" do
+ @summer.should be_respond_to(sumtype.to_s + "_stream")
end
+ end
- it "should have a method for determining whether a given string is a checksum" do
- @summer.should respond_to(:checksum?)
- end
+ it "should have a method for determining whether a given string is a checksum" do
+ @summer.should respond_to(:checksum?)
+ end
- %w{{md5}asdfasdf {sha1}asdfasdf {ctime}asdasdf {mtime}asdfasdf}.each do |sum|
- it "should consider #{sum} to be a checksum" do
- @summer.should be_checksum(sum)
- end
+ %w{{md5}asdfasdf {sha1}asdfasdf {ctime}asdasdf {mtime}asdfasdf}.each do |sum|
+ it "should consider #{sum} to be a checksum" do
+ @summer.should be_checksum(sum)
end
+ end
- %w{{nosuchsum}asdfasdf {a}asdfasdf {ctime}}.each do |sum|
- it "should not consider #{sum} to be a checksum" do
- @summer.should_not be_checksum(sum)
- end
+ %w{{nosuchsum}asdfasdf {a}asdfasdf {ctime}}.each do |sum|
+ it "should not consider #{sum} to be a checksum" do
+ @summer.should_not be_checksum(sum)
end
+ end
- it "should have a method for stripping a sum type from an existing checksum" do
- @summer.sumtype("{md5}asdfasdfa").should == "md5"
- end
+ it "should have a method for stripping a sum type from an existing checksum" do
+ @summer.sumtype("{md5}asdfasdfa").should == "md5"
+ end
- it "should have a method for stripping the data from a checksum" do
- @summer.sumdata("{md5}asdfasdfa").should == "asdfasdfa"
- end
+ it "should have a method for stripping the data from a checksum" do
+ @summer.sumdata("{md5}asdfasdfa").should == "asdfasdfa"
+ end
- it "should return a nil sumtype if the checksum does not mention a checksum type" do
- @summer.sumtype("asdfasdfa").should be_nil
- end
+ it "should return a nil sumtype if the checksum does not mention a checksum type" do
+ @summer.sumtype("asdfasdfa").should be_nil
+ end
- {:md5 => Digest::MD5, :sha1 => Digest::SHA1}.each do |sum, klass|
- describe("when using #{sum}") do
- it "should use #{klass} to calculate string checksums" do
- klass.expects(:hexdigest).with("mycontent").returns "whatever"
- @summer.send(sum, "mycontent").should == "whatever"
- end
+ {:md5 => Digest::MD5, :sha1 => Digest::SHA1}.each do |sum, klass|
+ describe("when using #{sum}") do
+ it "should use #{klass} to calculate string checksums" do
+ klass.expects(:hexdigest).with("mycontent").returns "whatever"
+ @summer.send(sum, "mycontent").should == "whatever"
+ end
- it "should use incremental #{klass} sums to calculate file checksums" do
- digest = mock 'digest'
- klass.expects(:new).returns digest
+ it "should use incremental #{klass} sums to calculate file checksums" do
+ digest = mock 'digest'
+ klass.expects(:new).returns digest
- file = "/path/to/my/file"
+ file = "/path/to/my/file"
- fh = mock 'filehandle'
- fh.expects(:read).with(4096).times(3).returns("firstline").then.returns("secondline").then.returns(nil)
- #fh.expects(:read).with(512).returns("secondline")
- #fh.expects(:read).with(512).returns(nil)
+ fh = mock 'filehandle'
+ fh.expects(:read).with(4096).times(3).returns("firstline").then.returns("secondline").then.returns(nil)
+ #fh.expects(:read).with(512).returns("secondline")
+ #fh.expects(:read).with(512).returns(nil)
- File.expects(:open).with(file, "r").yields(fh)
+ File.expects(:open).with(file, "r").yields(fh)
- digest.expects(:<<).with "firstline"
- digest.expects(:<<).with "secondline"
- digest.expects(:hexdigest).returns :mydigest
+ digest.expects(:<<).with "firstline"
+ digest.expects(:<<).with "secondline"
+ digest.expects(:hexdigest).returns :mydigest
- @summer.send(sum.to_s + "_file", file).should == :mydigest
- end
+ @summer.send(sum.to_s + "_file", file).should == :mydigest
+ end
- it "should yield #{klass} to the given block to calculate stream checksums" do
- digest = mock 'digest'
- klass.expects(:new).returns digest
- digest.expects(:hexdigest).returns :mydigest
+ it "should yield #{klass} to the given block to calculate stream checksums" do
+ digest = mock 'digest'
+ klass.expects(:new).returns digest
+ digest.expects(:hexdigest).returns :mydigest
- @summer.send(sum.to_s + "_stream") do |sum|
- sum.should == digest
- end.should == :mydigest
- end
- end
+ @summer.send(sum.to_s + "_stream") do |sum|
+ sum.should == digest
+ end.should == :mydigest
+ end
end
+ end
- {:md5lite => Digest::MD5, :sha1lite => Digest::SHA1}.each do |sum, klass|
- describe("when using #{sum}") do
- it "should use #{klass} to calculate string checksums from the first 512 characters of the string" do
- content = "this is a test" * 100
- klass.expects(:hexdigest).with(content[0..511]).returns "whatever"
- @summer.send(sum, content).should == "whatever"
- end
+ {:md5lite => Digest::MD5, :sha1lite => Digest::SHA1}.each do |sum, klass|
+ describe("when using #{sum}") do
+ it "should use #{klass} to calculate string checksums from the first 512 characters of the string" do
+ content = "this is a test" * 100
+ klass.expects(:hexdigest).with(content[0..511]).returns "whatever"
+ @summer.send(sum, content).should == "whatever"
+ end
- it "should use #{klass} to calculate a sum from the first 512 characters in the file" do
- digest = mock 'digest'
- klass.expects(:new).returns digest
+ it "should use #{klass} to calculate a sum from the first 512 characters in the file" do
+ digest = mock 'digest'
+ klass.expects(:new).returns digest
- file = "/path/to/my/file"
+ file = "/path/to/my/file"
- fh = mock 'filehandle'
- fh.expects(:read).with(512).returns('my content')
+ fh = mock 'filehandle'
+ fh.expects(:read).with(512).returns('my content')
- File.expects(:open).with(file, "r").yields(fh)
+ File.expects(:open).with(file, "r").yields(fh)
- digest.expects(:<<).with "my content"
- digest.expects(:hexdigest).returns :mydigest
+ digest.expects(:<<).with "my content"
+ digest.expects(:hexdigest).returns :mydigest
- @summer.send(sum.to_s + "_file", file).should == :mydigest
- end
- end
+ @summer.send(sum.to_s + "_file", file).should == :mydigest
+ end
end
+ end
- [:ctime, :mtime].each do |sum|
- describe("when using #{sum}") do
- it "should use the '#{sum}' on the file to determine the ctime" do
- file = "/my/file"
- stat = mock 'stat', sum => "mysum"
+ [:ctime, :mtime].each do |sum|
+ describe("when using #{sum}") do
+ it "should use the '#{sum}' on the file to determine the ctime" do
+ file = "/my/file"
+ stat = mock 'stat', sum => "mysum"
- File.expects(:stat).with(file).returns(stat)
+ File.expects(:stat).with(file).returns(stat)
- @summer.send(sum.to_s + "_file", file).should == "mysum"
- end
+ @summer.send(sum.to_s + "_file", file).should == "mysum"
+ end
- it "should return nil for streams" do
- @summer.send(sum.to_s + "_stream").should be_nil
- end
- end
+ it "should return nil for streams" do
+ @summer.send(sum.to_s + "_stream").should be_nil
+ end
end
+ end
- describe "when using the none checksum" do
- it "should return an empty string" do
- @summer.none_file("/my/file").should == ""
- end
+ describe "when using the none checksum" do
+ it "should return an empty string" do
+ @summer.none_file("/my/file").should == ""
end
+ end
end
diff --git a/spec/unit/util/command_line_spec.rb b/spec/unit/util/command_line_spec.rb
index bb2d073..a83ad96 100644
--- a/spec/unit/util/command_line_spec.rb
+++ b/spec/unit/util/command_line_spec.rb
@@ -6,103 +6,103 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
require 'puppet/util/command_line'
describe Puppet::Util::CommandLine do
- before do
- @tty = stub("tty", :tty? => true )
- @pipe = stub("pipe", :tty? => false)
- end
+ before do
+ @tty = stub("tty", :tty? => true )
+ @pipe = stub("pipe", :tty? => false)
+ end
- it "should pull off the first argument if it looks like a subcommand" do
- command_line = Puppet::Util::CommandLine.new("puppet", %w{ client --help whatever.pp }, @tty )
+ it "should pull off the first argument if it looks like a subcommand" do
+ command_line = Puppet::Util::CommandLine.new("puppet", %w{ client --help whatever.pp }, @tty )
- command_line.subcommand_name.should == "client"
- command_line.args.should == %w{ --help whatever.pp }
- end
+ command_line.subcommand_name.should == "client"
+ command_line.args.should == %w{ --help whatever.pp }
+ end
- it "should use 'apply' if the first argument looks like a .pp file" do
- command_line = Puppet::Util::CommandLine.new("puppet", %w{ whatever.pp }, @tty )
+ it "should use 'apply' if the first argument looks like a .pp file" do
+ command_line = Puppet::Util::CommandLine.new("puppet", %w{ whatever.pp }, @tty )
- command_line.subcommand_name.should == "apply"
- command_line.args.should == %w{ whatever.pp }
- end
+ command_line.subcommand_name.should == "apply"
+ command_line.args.should == %w{ whatever.pp }
+ end
- it "should use 'apply' if the first argument looks like a .rb file" do
- command_line = Puppet::Util::CommandLine.new("puppet", %w{ whatever.rb }, @tty )
+ it "should use 'apply' if the first argument looks like a .rb file" do
+ command_line = Puppet::Util::CommandLine.new("puppet", %w{ whatever.rb }, @tty )
- command_line.subcommand_name.should == "apply"
- command_line.args.should == %w{ whatever.rb }
- end
+ command_line.subcommand_name.should == "apply"
+ command_line.args.should == %w{ whatever.rb }
+ end
- it "should use 'apply' if the first argument looks like a flag" do
- command_line = Puppet::Util::CommandLine.new("puppet", %w{ --debug }, @tty )
+ it "should use 'apply' if the first argument looks like a flag" do
+ command_line = Puppet::Util::CommandLine.new("puppet", %w{ --debug }, @tty )
- command_line.subcommand_name.should == "apply"
- command_line.args.should == %w{ --debug }
- end
+ command_line.subcommand_name.should == "apply"
+ command_line.args.should == %w{ --debug }
+ end
- it "should use 'apply' if the first argument is -" do
- command_line = Puppet::Util::CommandLine.new("puppet", %w{ - }, @tty )
+ it "should use 'apply' if the first argument is -" do
+ command_line = Puppet::Util::CommandLine.new("puppet", %w{ - }, @tty )
- command_line.subcommand_name.should == "apply"
- command_line.args.should == %w{ - }
- end
+ command_line.subcommand_name.should == "apply"
+ command_line.args.should == %w{ - }
+ end
- it "should return nil if the first argument is --help" do
- command_line = Puppet::Util::CommandLine.new("puppet", %w{ --help }, @tty )
+ it "should return nil if the first argument is --help" do
+ command_line = Puppet::Util::CommandLine.new("puppet", %w{ --help }, @tty )
- command_line.subcommand_name.should == nil
- end
+ command_line.subcommand_name.should == nil
+ end
- it "should return nil if there are no arguments on a tty" do
- command_line = Puppet::Util::CommandLine.new("puppet", [], @tty )
+ it "should return nil if there are no arguments on a tty" do
+ command_line = Puppet::Util::CommandLine.new("puppet", [], @tty )
- command_line.subcommand_name.should == nil
- command_line.args.should == []
- end
+ command_line.subcommand_name.should == nil
+ command_line.args.should == []
+ end
- it "should use 'apply' if there are no arguments on a pipe" do
- command_line = Puppet::Util::CommandLine.new("puppet", [], @pipe )
+ it "should use 'apply' if there are no arguments on a pipe" do
+ command_line = Puppet::Util::CommandLine.new("puppet", [], @pipe )
- command_line.subcommand_name.should == "apply"
- command_line.args.should == []
- end
+ command_line.subcommand_name.should == "apply"
+ command_line.args.should == []
+ end
- it "should return the executable name if it is not puppet" do
- command_line = Puppet::Util::CommandLine.new("puppetmasterd", [], @tty )
+ it "should return the executable name if it is not puppet" do
+ command_line = Puppet::Util::CommandLine.new("puppetmasterd", [], @tty )
- command_line.subcommand_name.should == "puppetmasterd"
- end
+ command_line.subcommand_name.should == "puppetmasterd"
+ end
- it "should translate subcommand names into their legacy equivalent" do
- command_line = Puppet::Util::CommandLine.new("puppet", ["master"], @tty)
- command_line.legacy_executable_name.should == "puppetmasterd"
- end
+ it "should translate subcommand names into their legacy equivalent" do
+ command_line = Puppet::Util::CommandLine.new("puppet", ["master"], @tty)
+ command_line.legacy_executable_name.should == "puppetmasterd"
+ end
- it "should leave legacy command names alone" do
- command_line = Puppet::Util::CommandLine.new("puppetmasterd", [], @tty)
- command_line.legacy_executable_name.should == "puppetmasterd"
- end
+ it "should leave legacy command names alone" do
+ command_line = Puppet::Util::CommandLine.new("puppetmasterd", [], @tty)
+ command_line.legacy_executable_name.should == "puppetmasterd"
+ end
- describe "when the subcommand is not implemented" do
- it "should find and invoke an executable with a hyphenated name" do
- commandline = Puppet::Util::CommandLine.new("puppet", ['whatever', 'argument'], @tty)
- Puppet::Util.expects(:binary).with('puppet-whatever').returns('/dev/null/puppet-whatever')
- commandline.expects(:system).with('/dev/null/puppet-whatever', 'argument')
+ describe "when the subcommand is not implemented" do
+ it "should find and invoke an executable with a hyphenated name" do
+ commandline = Puppet::Util::CommandLine.new("puppet", ['whatever', 'argument'], @tty)
+ Puppet::Util.expects(:binary).with('puppet-whatever').returns('/dev/null/puppet-whatever')
+ commandline.expects(:system).with('/dev/null/puppet-whatever', 'argument')
- commandline.execute
- end
+ commandline.execute
+ end
- describe "and an external implementation cannot be found" do
- it "should abort and show the usage message" do
- commandline = Puppet::Util::CommandLine.new("puppet", ['whatever', 'argument'], @tty)
- Puppet::Util.expects(:binary).with('puppet-whatever').returns(nil)
- commandline.expects(:system).never
+ describe "and an external implementation cannot be found" do
+ it "should abort and show the usage message" do
+ commandline = Puppet::Util::CommandLine.new("puppet", ['whatever', 'argument'], @tty)
+ Puppet::Util.expects(:binary).with('puppet-whatever').returns(nil)
+ commandline.expects(:system).never
- commandline.expects(:usage_message).returns("the usage message")
- commandline.expects(:abort).with{|x| x =~ /the usage message/}.raises("stubbed abort")
+ commandline.expects(:usage_message).returns("the usage message")
+ commandline.expects(:abort).with{|x| x =~ /the usage message/}.raises("stubbed abort")
- lambda{ commandline.execute }.should raise_error('stubbed abort')
- end
- end
+ lambda{ commandline.execute }.should raise_error('stubbed abort')
+ end
end
+ end
end
diff --git a/spec/unit/util/constant_inflector_spec.rb b/spec/unit/util/constant_inflector_spec.rb
index 5112e73..423ca8f 100755
--- a/spec/unit/util/constant_inflector_spec.rb
+++ b/spec/unit/util/constant_inflector_spec.rb
@@ -8,63 +8,63 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/util/constant_inflector'
describe Puppet::Util::ConstantInflector, "when converting file names to constants" do
- before do
- @inflector = Object.new
- @inflector.extend(Puppet::Util::ConstantInflector)
- end
-
- it "should capitalize terms" do
- @inflector.file2constant("file").should == "File"
- end
-
- it "should switch all '/' characters to double colons" do
- @inflector.file2constant("file/other").should == "File::Other"
- end
-
- it "should remove underscores and capitalize the proceeding letter" do
- @inflector.file2constant("file_other").should == "FileOther"
- end
-
- it "should correctly replace as many underscores as exist in the file name" do
- @inflector.file2constant("two_under_scores/with_some_more_underscores").should == "TwoUnderScores::WithSomeMoreUnderscores"
- end
-
- it "should collapse multiple underscores" do
- @inflector.file2constant("many___scores").should == "ManyScores"
- end
-
- it "should correctly handle file names deeper than two directories" do
- @inflector.file2constant("one_two/three_four/five_six").should == "OneTwo::ThreeFour::FiveSix"
- end
+ before do
+ @inflector = Object.new
+ @inflector.extend(Puppet::Util::ConstantInflector)
+ end
+
+ it "should capitalize terms" do
+ @inflector.file2constant("file").should == "File"
+ end
+
+ it "should switch all '/' characters to double colons" do
+ @inflector.file2constant("file/other").should == "File::Other"
+ end
+
+ it "should remove underscores and capitalize the proceeding letter" do
+ @inflector.file2constant("file_other").should == "FileOther"
+ end
+
+ it "should correctly replace as many underscores as exist in the file name" do
+ @inflector.file2constant("two_under_scores/with_some_more_underscores").should == "TwoUnderScores::WithSomeMoreUnderscores"
+ end
+
+ it "should collapse multiple underscores" do
+ @inflector.file2constant("many___scores").should == "ManyScores"
+ end
+
+ it "should correctly handle file names deeper than two directories" do
+ @inflector.file2constant("one_two/three_four/five_six").should == "OneTwo::ThreeFour::FiveSix"
+ end
end
describe Puppet::Util::ConstantInflector, "when converting constnats to file names" do
- before do
- @inflector = Object.new
- @inflector.extend(Puppet::Util::ConstantInflector)
- end
-
- it "should convert them to a string if necessary" do
- @inflector.constant2file(Puppet::Util::ConstantInflector).should be_instance_of(String)
- end
-
- it "should accept string inputs" do
- @inflector.constant2file("Puppet::Util::ConstantInflector").should be_instance_of(String)
- end
-
- it "should downcase all terms" do
- @inflector.constant2file("Puppet").should == "puppet"
- end
-
- it "should convert '::' to '/'" do
- @inflector.constant2file("Puppet::Util::Constant").should == "puppet/util/constant"
- end
-
- it "should convert mid-word capitalization to an underscore" do
- @inflector.constant2file("OneTwo::ThreeFour").should == "one_two/three_four"
- end
-
- it "should correctly handle constants with more than two parts" do
- @inflector.constant2file("OneTwoThree::FourFiveSixSeven").should == "one_two_three/four_five_six_seven"
- end
+ before do
+ @inflector = Object.new
+ @inflector.extend(Puppet::Util::ConstantInflector)
+ end
+
+ it "should convert them to a string if necessary" do
+ @inflector.constant2file(Puppet::Util::ConstantInflector).should be_instance_of(String)
+ end
+
+ it "should accept string inputs" do
+ @inflector.constant2file("Puppet::Util::ConstantInflector").should be_instance_of(String)
+ end
+
+ it "should downcase all terms" do
+ @inflector.constant2file("Puppet").should == "puppet"
+ end
+
+ it "should convert '::' to '/'" do
+ @inflector.constant2file("Puppet::Util::Constant").should == "puppet/util/constant"
+ end
+
+ it "should convert mid-word capitalization to an underscore" do
+ @inflector.constant2file("OneTwo::ThreeFour").should == "one_two/three_four"
+ end
+
+ it "should correctly handle constants with more than two parts" do
+ @inflector.constant2file("OneTwoThree::FourFiveSixSeven").should == "one_two_three/four_five_six_seven"
+ end
end
diff --git a/spec/unit/util/errors_spec.rb b/spec/unit/util/errors_spec.rb
index e30b85d..2500403 100755
--- a/spec/unit/util/errors_spec.rb
+++ b/spec/unit/util/errors_spec.rb
@@ -5,34 +5,34 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
require 'puppet/util/errors'
class ErrorTester
- include Puppet::Util::Errors
- attr_accessor :line, :file
+ include Puppet::Util::Errors
+ attr_accessor :line, :file
end
describe Puppet::Util::Errors do
- before do
- @tester = ErrorTester.new
- end
-
- it "should provide a 'fail' method" do
- @tester.should respond_to(:fail)
- end
-
- it "should provide a 'devfail' method" do
- @tester.should respond_to(:devfail)
- end
-
- it "should raise any provided error when failing" do
- lambda { @tester.fail(Puppet::ParseError, "stuff") }.should raise_error(Puppet::ParseError)
- end
-
- it "should default to Puppet::Error when failing" do
- lambda { @tester.fail("stuff") }.should raise_error(Puppet::Error)
- end
-
- it "should have a method for converting error context into a string" do
- @tester.file = "/my/file"
- @tester.line = 50
- @tester.error_context.should == " at /my/file:50"
- end
+ before do
+ @tester = ErrorTester.new
+ end
+
+ it "should provide a 'fail' method" do
+ @tester.should respond_to(:fail)
+ end
+
+ it "should provide a 'devfail' method" do
+ @tester.should respond_to(:devfail)
+ end
+
+ it "should raise any provided error when failing" do
+ lambda { @tester.fail(Puppet::ParseError, "stuff") }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should default to Puppet::Error when failing" do
+ lambda { @tester.fail("stuff") }.should raise_error(Puppet::Error)
+ end
+
+ it "should have a method for converting error context into a string" do
+ @tester.file = "/my/file"
+ @tester.line = 50
+ @tester.error_context.should == " at /my/file:50"
+ end
end
diff --git a/spec/unit/util/feature_spec.rb b/spec/unit/util/feature_spec.rb
index 576e19b..8cedade 100755
--- a/spec/unit/util/feature_spec.rb
+++ b/spec/unit/util/feature_spec.rb
@@ -5,68 +5,68 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
require 'puppet/util/feature'
describe Puppet::Util::Feature do
- before do
- @features = Puppet::Util::Feature.new("features")
- @features.stubs(:warn)
- end
-
- it "should consider undefined features to be absent" do
- @features.should_not be_defined_feature
- end
-
- it "should be able to add new features" do
- @features.add(:myfeature) {}
- @features.should respond_to(:myfeature?)
- end
-
- it "should call associated code when loading a feature" do
- $loaded_feature = false
- @features.add(:myfeature) { $loaded_feature = true}
- $loaded_feature.should be_true
- end
-
- it "should consider a feature absent when the feature load fails" do
- @features.add(:failer) { raise "foo" }
- @features.should_not be_failer
- end
-
- it "should consider a feature to be absent when the feature load returns false" do
- @features.add(:failer) { false }
- @features.should_not be_failer
- end
-
- it "should consider a feature to be present when the feature load returns true" do
- @features.add(:available) { true }
- @features.should be_available
- end
-
- it "should cache the results of a feature load" do
- $loaded_feature = 0
- @features.add(:myfeature) { $loaded_feature += 1 }
- @features.myfeature?
- @features.myfeature?
- $loaded_feature.should == 1
- end
-
- it "should support features with libraries" do
- lambda { @features.add(:puppet, :libs => %w{puppet}) }.should_not raise_error
- end
-
- it "should consider a feature to be present if all of its libraries are present" do
- @features.add(:myfeature, :libs => %w{foo bar})
- @features.expects(:require).with("foo")
- @features.expects(:require).with("bar")
-
- @features.should be_myfeature
- end
-
- it "should log and consider a feature to be absent if any of its libraries are absent" do
- @features.add(:myfeature, :libs => %w{foo bar})
- @features.expects(:require).with("foo").raises(LoadError)
- @features.stubs(:require).with("bar")
-
- Puppet.expects(:debug)
-
- @features.should_not be_myfeature
- end
+ before do
+ @features = Puppet::Util::Feature.new("features")
+ @features.stubs(:warn)
+ end
+
+ it "should consider undefined features to be absent" do
+ @features.should_not be_defined_feature
+ end
+
+ it "should be able to add new features" do
+ @features.add(:myfeature) {}
+ @features.should respond_to(:myfeature?)
+ end
+
+ it "should call associated code when loading a feature" do
+ $loaded_feature = false
+ @features.add(:myfeature) { $loaded_feature = true}
+ $loaded_feature.should be_true
+ end
+
+ it "should consider a feature absent when the feature load fails" do
+ @features.add(:failer) { raise "foo" }
+ @features.should_not be_failer
+ end
+
+ it "should consider a feature to be absent when the feature load returns false" do
+ @features.add(:failer) { false }
+ @features.should_not be_failer
+ end
+
+ it "should consider a feature to be present when the feature load returns true" do
+ @features.add(:available) { true }
+ @features.should be_available
+ end
+
+ it "should cache the results of a feature load" do
+ $loaded_feature = 0
+ @features.add(:myfeature) { $loaded_feature += 1 }
+ @features.myfeature?
+ @features.myfeature?
+ $loaded_feature.should == 1
+ end
+
+ it "should support features with libraries" do
+ lambda { @features.add(:puppet, :libs => %w{puppet}) }.should_not raise_error
+ end
+
+ it "should consider a feature to be present if all of its libraries are present" do
+ @features.add(:myfeature, :libs => %w{foo bar})
+ @features.expects(:require).with("foo")
+ @features.expects(:require).with("bar")
+
+ @features.should be_myfeature
+ end
+
+ it "should log and consider a feature to be absent if any of its libraries are absent" do
+ @features.add(:myfeature, :libs => %w{foo bar})
+ @features.expects(:require).with("foo").raises(LoadError)
+ @features.stubs(:require).with("bar")
+
+ Puppet.expects(:debug)
+
+ @features.should_not be_myfeature
+ end
end
diff --git a/spec/unit/util/file_locking_spec.rb b/spec/unit/util/file_locking_spec.rb
index 9a8fad1..1005106 100755
--- a/spec/unit/util/file_locking_spec.rb
+++ b/spec/unit/util/file_locking_spec.rb
@@ -5,152 +5,152 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
require 'puppet/util/file_locking'
class FileLocker
- include Puppet::Util::FileLocking
+ include Puppet::Util::FileLocking
end
describe Puppet::Util::FileLocking do
- it "should have a module method for getting a read lock on files" do
- Puppet::Util::FileLocking.should respond_to(:readlock)
+ it "should have a module method for getting a read lock on files" do
+ Puppet::Util::FileLocking.should respond_to(:readlock)
+ end
+
+ it "should have a module method for getting a write lock on files" do
+ Puppet::Util::FileLocking.should respond_to(:writelock)
+ end
+
+ it "should have an instance method for getting a read lock on files" do
+ FileLocker.new.private_methods.should be_include("readlock")
+ end
+
+ it "should have an instance method for getting a write lock on files" do
+ FileLocker.new.private_methods.should be_include("writelock")
+ end
+
+ describe "when acquiring a read lock" do
+ before do
+ File.stubs(:exists?).with('/file').returns true
+ File.stubs(:file?).with('/file').returns true
end
- it "should have a module method for getting a write lock on files" do
- Puppet::Util::FileLocking.should respond_to(:writelock)
- end
+ it "should use a global shared mutex" do
+ @sync = mock 'sync'
+ @sync.expects(:synchronize).with(Sync::SH).once
+ Puppet::Util.expects(:sync).with('/file').returns @sync
- it "should have an instance method for getting a read lock on files" do
- FileLocker.new.private_methods.should be_include("readlock")
+ Puppet::Util::FileLocking.readlock '/file'
end
- it "should have an instance method for getting a write lock on files" do
- FileLocker.new.private_methods.should be_include("writelock")
+ it "should use a shared lock on the file" do
+ @sync = mock 'sync'
+ @sync.stubs(:synchronize).yields
+ Puppet::Util.expects(:sync).with('/file').returns @sync
+
+ fh = mock 'filehandle'
+ File.expects(:open).with("/file").yields fh
+ fh.expects(:lock_shared).yields "locked_fh"
+
+ result = nil
+ Puppet::Util::FileLocking.readlock('/file') { |l| result = l }
+ result.should == "locked_fh"
end
- describe "when acquiring a read lock" do
- before do
- File.stubs(:exists?).with('/file').returns true
- File.stubs(:file?).with('/file').returns true
- end
-
- it "should use a global shared mutex" do
- @sync = mock 'sync'
- @sync.expects(:synchronize).with(Sync::SH).once
- Puppet::Util.expects(:sync).with('/file').returns @sync
-
- Puppet::Util::FileLocking.readlock '/file'
- end
-
- it "should use a shared lock on the file" do
- @sync = mock 'sync'
- @sync.stubs(:synchronize).yields
- Puppet::Util.expects(:sync).with('/file').returns @sync
-
- fh = mock 'filehandle'
- File.expects(:open).with("/file").yields fh
- fh.expects(:lock_shared).yields "locked_fh"
-
- result = nil
- Puppet::Util::FileLocking.readlock('/file') { |l| result = l }
- result.should == "locked_fh"
- end
-
- it "should only work on regular files" do
- File.expects(:file?).with('/file').returns false
- proc { Puppet::Util::FileLocking.readlock('/file') }.should raise_error(ArgumentError)
- end
-
- it "should create missing files" do
- @sync = mock 'sync'
- @sync.stubs(:synchronize).yields
- Puppet::Util.expects(:sync).with('/file').returns @sync
-
- File.expects(:exists?).with('/file').returns false
- File.expects(:open).with('/file').once
-
- Puppet::Util::FileLocking.readlock('/file')
- end
+ it "should only work on regular files" do
+ File.expects(:file?).with('/file').returns false
+ proc { Puppet::Util::FileLocking.readlock('/file') }.should raise_error(ArgumentError)
end
- describe "when acquiring a write lock" do
- before do
- @sync = mock 'sync'
- Puppet::Util.stubs(:sync).returns @sync
- @sync.stubs(:synchronize).yields
- File.stubs(:file?).with('/file').returns true
- File.stubs(:exists?).with('/file').returns true
- end
+ it "should create missing files" do
+ @sync = mock 'sync'
+ @sync.stubs(:synchronize).yields
+ Puppet::Util.expects(:sync).with('/file').returns @sync
- it "should fail if the parent directory does not exist" do
- FileTest.expects(:directory?).with("/my/dir").returns false
- File.stubs(:file?).with('/my/dir/file').returns true
- File.stubs(:exists?).with('/my/dir/file').returns true
+ File.expects(:exists?).with('/file').returns false
+ File.expects(:open).with('/file').once
- lambda { Puppet::Util::FileLocking.writelock('/my/dir/file') }.should raise_error(Puppet::DevError)
- end
+ Puppet::Util::FileLocking.readlock('/file')
+ end
+ end
+
+ describe "when acquiring a write lock" do
+ before do
+ @sync = mock 'sync'
+ Puppet::Util.stubs(:sync).returns @sync
+ @sync.stubs(:synchronize).yields
+ File.stubs(:file?).with('/file').returns true
+ File.stubs(:exists?).with('/file').returns true
+ end
- it "should use a global exclusive mutex" do
- sync = mock 'sync'
- sync.expects(:synchronize).with(Sync::EX)
- Puppet::Util.expects(:sync).with("/file").returns sync
+ it "should fail if the parent directory does not exist" do
+ FileTest.expects(:directory?).with("/my/dir").returns false
+ File.stubs(:file?).with('/my/dir/file').returns true
+ File.stubs(:exists?).with('/my/dir/file').returns true
- Puppet::Util::FileLocking.writelock '/file'
- end
+ lambda { Puppet::Util::FileLocking.writelock('/my/dir/file') }.should raise_error(Puppet::DevError)
+ end
- it "should use any specified mode when opening the file" do
- File.expects(:open).with("/file", "w", :mymode)
+ it "should use a global exclusive mutex" do
+ sync = mock 'sync'
+ sync.expects(:synchronize).with(Sync::EX)
+ Puppet::Util.expects(:sync).with("/file").returns sync
- Puppet::Util::FileLocking.writelock('/file', :mymode)
- end
+ Puppet::Util::FileLocking.writelock '/file'
+ end
- it "should use the mode of the existing file if no mode is specified" do
- File.expects(:stat).with("/file").returns(mock("stat", :mode => 0755))
- File.expects(:open).with("/file", "w", 0755)
+ it "should use any specified mode when opening the file" do
+ File.expects(:open).with("/file", "w", :mymode)
- Puppet::Util::FileLocking.writelock('/file')
- end
+ Puppet::Util::FileLocking.writelock('/file', :mymode)
+ end
- it "should use 0600 as the mode if no mode is specified and the file does not exist" do
- File.expects(:stat).raises(Errno::ENOENT)
- File.expects(:open).with("/file", "w", 0600)
+ it "should use the mode of the existing file if no mode is specified" do
+ File.expects(:stat).with("/file").returns(mock("stat", :mode => 0755))
+ File.expects(:open).with("/file", "w", 0755)
- Puppet::Util::FileLocking.writelock('/file')
- end
+ Puppet::Util::FileLocking.writelock('/file')
+ end
+
+ it "should use 0600 as the mode if no mode is specified and the file does not exist" do
+ File.expects(:stat).raises(Errno::ENOENT)
+ File.expects(:open).with("/file", "w", 0600)
- it "should create an exclusive file lock" do
- fh = mock 'fh'
- File.expects(:open).yields fh
- fh.expects(:lock_exclusive)
+ Puppet::Util::FileLocking.writelock('/file')
+ end
- Puppet::Util::FileLocking.writelock('/file')
- end
+ it "should create an exclusive file lock" do
+ fh = mock 'fh'
+ File.expects(:open).yields fh
+ fh.expects(:lock_exclusive)
- it "should allow the caller to write to the locked file" do
- fh = mock 'fh'
- File.expects(:open).yields fh
+ Puppet::Util::FileLocking.writelock('/file')
+ end
- lfh = mock 'locked_filehandle'
- fh.expects(:lock_exclusive).yields(lfh)
+ it "should allow the caller to write to the locked file" do
+ fh = mock 'fh'
+ File.expects(:open).yields fh
- lfh.expects(:print).with "foo"
+ lfh = mock 'locked_filehandle'
+ fh.expects(:lock_exclusive).yields(lfh)
- Puppet::Util::FileLocking.writelock('/file') do |f|
- f.print "foo"
- end
- end
+ lfh.expects(:print).with "foo"
- it "should only work on regular files" do
- File.expects(:file?).with('/file').returns false
- proc { Puppet::Util::FileLocking.writelock('/file') }.should raise_error(ArgumentError)
- end
+ Puppet::Util::FileLocking.writelock('/file') do |f|
+ f.print "foo"
+ end
+ end
+
+ it "should only work on regular files" do
+ File.expects(:file?).with('/file').returns false
+ proc { Puppet::Util::FileLocking.writelock('/file') }.should raise_error(ArgumentError)
+ end
- it "should create missing files" do
- @sync = mock 'sync'
- @sync.stubs(:synchronize).yields
- Puppet::Util.expects(:sync).with('/file').returns @sync
+ it "should create missing files" do
+ @sync = mock 'sync'
+ @sync.stubs(:synchronize).yields
+ Puppet::Util.expects(:sync).with('/file').returns @sync
- File.expects(:exists?).with('/file').returns false
- File.expects(:open).with('/file', 'w', 0600).once
+ File.expects(:exists?).with('/file').returns false
+ File.expects(:open).with('/file', 'w', 0600).once
- Puppet::Util::FileLocking.writelock('/file')
- end
+ Puppet::Util::FileLocking.writelock('/file')
end
+ end
end
diff --git a/spec/unit/util/filetype_spec.rb b/spec/unit/util/filetype_spec.rb
index cdc1b3f..68ef9d6 100644
--- a/spec/unit/util/filetype_spec.rb
+++ b/spec/unit/util/filetype_spec.rb
@@ -6,95 +6,95 @@ require 'puppet/util/filetype'
# XXX Import all of the tests into this file.
describe Puppet::Util::FileType do
- describe "when backing up a file" do
- before do
- @file = Puppet::Util::FileType.filetype(:flat).new("/my/file")
- end
+ describe "when backing up a file" do
+ before do
+ @file = Puppet::Util::FileType.filetype(:flat).new("/my/file")
+ end
+
+ it "should do nothing if the file does not exist" do
+ File.expects(:exists?).with("/my/file").returns false
+ @file.expects(:bucket).never
+ @file.backup
+ end
+
+ it "should use its filebucket to backup the file if it exists" do
+ File.expects(:exists?).with("/my/file").returns true
+
+ bucket = mock 'bucket'
+ bucket.expects(:backup).with("/my/file")
+
+ @file.expects(:bucket).returns bucket
+ @file.backup
+ end
- it "should do nothing if the file does not exist" do
- File.expects(:exists?).with("/my/file").returns false
- @file.expects(:bucket).never
- @file.backup
- end
+ it "should use the default filebucket" do
+ bucket = mock 'bucket'
+ bucket.expects(:bucket).returns "mybucket"
- it "should use its filebucket to backup the file if it exists" do
- File.expects(:exists?).with("/my/file").returns true
+ Puppet::Type.type(:filebucket).expects(:mkdefaultbucket).returns bucket
- bucket = mock 'bucket'
- bucket.expects(:backup).with("/my/file")
+ @file.bucket.should == "mybucket"
+ end
+ end
+
+ describe "the flat filetype" do
+ before do
+ @type = Puppet::Util::FileType.filetype(:flat)
+ end
+ it "should exist" do
+ @type.should_not be_nil
+ end
- @file.expects(:bucket).returns bucket
- @file.backup
- end
+ describe "when the file already exists" do
+ it "should return the file's contents when asked to read it" do
+ file = @type.new("/my/file")
+ File.expects(:exist?).with("/my/file").returns true
+ File.expects(:read).with("/my/file").returns "my text"
- it "should use the default filebucket" do
- bucket = mock 'bucket'
- bucket.expects(:bucket).returns "mybucket"
+ file.read.should == "my text"
+ end
+
+ it "should unlink the file when asked to remove it" do
+ file = @type.new("/my/file")
+ File.expects(:exist?).with("/my/file").returns true
+ File.expects(:unlink).with("/my/file")
+
+ file.remove
+ end
+ end
- Puppet::Type.type(:filebucket).expects(:mkdefaultbucket).returns bucket
+ describe "when the file does not exist" do
+ it "should return an empty string when asked to read the file" do
+ file = @type.new("/my/file")
+ File.expects(:exist?).with("/my/file").returns false
- @file.bucket.should == "mybucket"
- end
+ file.read.should == ""
+ end
end
- describe "the flat filetype" do
- before do
- @type = Puppet::Util::FileType.filetype(:flat)
- end
- it "should exist" do
- @type.should_not be_nil
- end
-
- describe "when the file already exists" do
- it "should return the file's contents when asked to read it" do
- file = @type.new("/my/file")
- File.expects(:exist?).with("/my/file").returns true
- File.expects(:read).with("/my/file").returns "my text"
-
- file.read.should == "my text"
- end
-
- it "should unlink the file when asked to remove it" do
- file = @type.new("/my/file")
- File.expects(:exist?).with("/my/file").returns true
- File.expects(:unlink).with("/my/file")
-
- file.remove
- end
- end
-
- describe "when the file does not exist" do
- it "should return an empty string when asked to read the file" do
- file = @type.new("/my/file")
- File.expects(:exist?).with("/my/file").returns false
-
- file.read.should == ""
- end
- end
-
- describe "when writing the file" do
- before do
- @file = @type.new("/my/file")
- FileUtils.stubs(:cp)
-
- @tempfile = stub 'tempfile', :print => nil, :close => nil, :flush => nil, :path => "/other/file"
- Tempfile.stubs(:new).returns @tempfile
- end
-
- it "should first create a temp file and copy its contents over to the file location" do
- Tempfile.expects(:new).with("puppet").returns @tempfile
- @tempfile.expects(:print).with("my text")
- @tempfile.expects(:flush)
- @tempfile.expects(:close)
- FileUtils.expects(:cp).with(@tempfile.path, "/my/file")
-
- @file.write "my text"
- end
-
- it "should set the selinux default context on the file" do
- @file.expects(:set_selinux_default_context).with("/my/file")
- @file.write "eh"
- end
- end
+ describe "when writing the file" do
+ before do
+ @file = @type.new("/my/file")
+ FileUtils.stubs(:cp)
+
+ @tempfile = stub 'tempfile', :print => nil, :close => nil, :flush => nil, :path => "/other/file"
+ Tempfile.stubs(:new).returns @tempfile
+ end
+
+ it "should first create a temp file and copy its contents over to the file location" do
+ Tempfile.expects(:new).with("puppet").returns @tempfile
+ @tempfile.expects(:print).with("my text")
+ @tempfile.expects(:flush)
+ @tempfile.expects(:close)
+ FileUtils.expects(:cp).with(@tempfile.path, "/my/file")
+
+ @file.write "my text"
+ end
+
+ it "should set the selinux default context on the file" do
+ @file.expects(:set_selinux_default_context).with("/my/file")
+ @file.write "eh"
+ end
end
+ end
end
diff --git a/spec/unit/util/inline_docs_spec.rb b/spec/unit/util/inline_docs_spec.rb
index a03939e..edfa405 100755
--- a/spec/unit/util/inline_docs_spec.rb
+++ b/spec/unit/util/inline_docs_spec.rb
@@ -5,28 +5,28 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
require 'puppet/util/inline_docs'
class InlineDoccer
- include Puppet::Util::InlineDocs
+ include Puppet::Util::InlineDocs
end
describe Puppet::Util::InlineDocs do
- describe "when included" do
- it "should create a class method for specifying that docs should be associated" do
- InlineDoccer.expects(:use_docs=).with true
- InlineDoccer.associates_doc
- end
+ describe "when included" do
+ it "should create a class method for specifying that docs should be associated" do
+ InlineDoccer.expects(:use_docs=).with true
+ InlineDoccer.associates_doc
+ end
- it "should default to not associating docs" do
- (!! InlineDoccer.use_docs).should be_false
- end
+ it "should default to not associating docs" do
+ (!! InlineDoccer.use_docs).should be_false
+ end
- it "should create an instance method for setting documentation" do
- instance = InlineDoccer.new
- instance.doc = "foo"
- instance.doc.should == "foo"
- end
+ it "should create an instance method for setting documentation" do
+ instance = InlineDoccer.new
+ instance.doc = "foo"
+ instance.doc.should == "foo"
+ end
- it "should default to an empty string for docs" do
- InlineDoccer.new.doc.should == ""
- end
+ it "should default to an empty string for docs" do
+ InlineDoccer.new.doc.should == ""
end
+ end
end
diff --git a/spec/unit/util/json_spec.rb b/spec/unit/util/json_spec.rb
index ce96486..4f6cea9 100755
--- a/spec/unit/util/json_spec.rb
+++ b/spec/unit/util/json_spec.rb
@@ -5,17 +5,17 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
require 'puppet/util/pson'
class PsonUtil
- include Puppet::Util::Pson
+ include Puppet::Util::Pson
end
describe Puppet::Util::Pson do
- it "should fail if no data is provided" do
- lambda { PsonUtil.new.pson_create("type" => "foo") }.should raise_error(ArgumentError)
- end
+ it "should fail if no data is provided" do
+ lambda { PsonUtil.new.pson_create("type" => "foo") }.should raise_error(ArgumentError)
+ end
- it "should call 'from_pson' with the provided data" do
- pson = PsonUtil.new
- pson.expects(:from_pson).with("mydata")
- pson.pson_create("type" => "foo", "data" => "mydata")
- end
+ it "should call 'from_pson' with the provided data" do
+ pson = PsonUtil.new
+ pson.expects(:from_pson).with("mydata")
+ pson.pson_create("type" => "foo", "data" => "mydata")
+ end
end
diff --git a/spec/unit/util/ldap/connection_spec.rb b/spec/unit/util/ldap/connection_spec.rb
index bead64d..557c42e 100755
--- a/spec/unit/util/ldap/connection_spec.rb
+++ b/spec/unit/util/ldap/connection_spec.rb
@@ -9,161 +9,161 @@ require 'puppet/util/ldap/connection'
# So our mocks and such all work, even when ldap isn't available.
unless Puppet.features.ldap?
- class LDAP
- class Conn
- def initialize(*args)
- end
- end
- class SSLConn < Conn; end
-
- LDAP_OPT_PROTOCOL_VERSION = 1
- LDAP_OPT_REFERRALS = 2
- LDAP_OPT_ON = 3
+ class LDAP
+ class Conn
+ def initialize(*args)
+ end
end
+ class SSLConn < Conn; end
+
+ LDAP_OPT_PROTOCOL_VERSION = 1
+ LDAP_OPT_REFERRALS = 2
+ LDAP_OPT_ON = 3
+ end
end
describe Puppet::Util::Ldap::Connection do
- before do
- Puppet.features.stubs(:ldap?).returns true
+ before do
+ Puppet.features.stubs(:ldap?).returns true
- @ldapconn = mock 'ldap'
- LDAP::Conn.stubs(:new).returns(@ldapconn)
- LDAP::SSLConn.stubs(:new).returns(@ldapconn)
+ @ldapconn = mock 'ldap'
+ LDAP::Conn.stubs(:new).returns(@ldapconn)
+ LDAP::SSLConn.stubs(:new).returns(@ldapconn)
- @ldapconn.stub_everything
+ @ldapconn.stub_everything
- @connection = Puppet::Util::Ldap::Connection.new("host", "port")
- end
+ @connection = Puppet::Util::Ldap::Connection.new("host", "port")
+ end
- describe "when creating connections" do
- it "should require the host and port" do
- lambda { Puppet::Util::Ldap::Connection.new("myhost") }.should raise_error(ArgumentError)
- end
+ describe "when creating connections" do
+ it "should require the host and port" do
+ lambda { Puppet::Util::Ldap::Connection.new("myhost") }.should raise_error(ArgumentError)
+ end
- it "should allow specification of a user and password" do
- lambda { Puppet::Util::Ldap::Connection.new("myhost", "myport", :user => "blah", :password => "boo") }.should_not raise_error
- end
+ it "should allow specification of a user and password" do
+ lambda { Puppet::Util::Ldap::Connection.new("myhost", "myport", :user => "blah", :password => "boo") }.should_not raise_error
+ end
- it "should allow specification of ssl" do
- lambda { Puppet::Util::Ldap::Connection.new("myhost", "myport", :ssl => :tsl) }.should_not raise_error
- end
+ it "should allow specification of ssl" do
+ lambda { Puppet::Util::Ldap::Connection.new("myhost", "myport", :ssl => :tsl) }.should_not raise_error
+ end
- it "should support requiring a new connection" do
- lambda { Puppet::Util::Ldap::Connection.new("myhost", "myport", :reset => true) }.should_not raise_error
- end
+ it "should support requiring a new connection" do
+ lambda { Puppet::Util::Ldap::Connection.new("myhost", "myport", :reset => true) }.should_not raise_error
+ end
- it "should fail if ldap is unavailable" do
- Puppet.features.expects(:ldap?).returns(false)
+ it "should fail if ldap is unavailable" do
+ Puppet.features.expects(:ldap?).returns(false)
- lambda { Puppet::Util::Ldap::Connection.new("host", "port") }.should raise_error(Puppet::Error)
- end
+ lambda { Puppet::Util::Ldap::Connection.new("host", "port") }.should raise_error(Puppet::Error)
+ end
- it "should use neither ssl nor tls by default" do
- LDAP::Conn.expects(:new).with("host", "port").returns(@ldapconn)
+ it "should use neither ssl nor tls by default" do
+ LDAP::Conn.expects(:new).with("host", "port").returns(@ldapconn)
- @connection.start
- end
+ @connection.start
+ end
- it "should use LDAP::SSLConn if ssl is requested" do
- LDAP::SSLConn.expects(:new).with("host", "port").returns(@ldapconn)
+ it "should use LDAP::SSLConn if ssl is requested" do
+ LDAP::SSLConn.expects(:new).with("host", "port").returns(@ldapconn)
- @connection.ssl = true
+ @connection.ssl = true
- @connection.start
- end
+ @connection.start
+ end
- it "should use LDAP::SSLConn and tls if tls is requested" do
- LDAP::SSLConn.expects(:new).with("host", "port", true).returns(@ldapconn)
+ it "should use LDAP::SSLConn and tls if tls is requested" do
+ LDAP::SSLConn.expects(:new).with("host", "port", true).returns(@ldapconn)
- @connection.ssl = :tls
+ @connection.ssl = :tls
- @connection.start
- end
+ @connection.start
+ end
- it "should set the protocol version to 3 and enable referrals" do
- @ldapconn.expects(:set_option).with(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
- @ldapconn.expects(:set_option).with(LDAP::LDAP_OPT_REFERRALS, LDAP::LDAP_OPT_ON)
- @connection.start
- end
+ it "should set the protocol version to 3 and enable referrals" do
+ @ldapconn.expects(:set_option).with(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
+ @ldapconn.expects(:set_option).with(LDAP::LDAP_OPT_REFERRALS, LDAP::LDAP_OPT_ON)
+ @connection.start
+ end
- it "should bind with the provided user and password" do
- @connection.user = "myuser"
- @connection.password = "mypassword"
- @ldapconn.expects(:simple_bind).with("myuser", "mypassword")
+ it "should bind with the provided user and password" do
+ @connection.user = "myuser"
+ @connection.password = "mypassword"
+ @ldapconn.expects(:simple_bind).with("myuser", "mypassword")
- @connection.start
- end
+ @connection.start
+ end
- it "should bind with no user and password if none has been provided" do
- @ldapconn.expects(:simple_bind).with(nil, nil)
- @connection.start
- end
+ it "should bind with no user and password if none has been provided" do
+ @ldapconn.expects(:simple_bind).with(nil, nil)
+ @connection.start
end
+ end
- describe "when closing connections" do
- it "should not close connections that are not open" do
- @connection.stubs(:connection).returns(@ldapconn)
+ describe "when closing connections" do
+ it "should not close connections that are not open" do
+ @connection.stubs(:connection).returns(@ldapconn)
- @ldapconn.expects(:bound?).returns false
- @ldapconn.expects(:unbind).never
+ @ldapconn.expects(:bound?).returns false
+ @ldapconn.expects(:unbind).never
- @connection.close
- end
+ @connection.close
end
+ end
- it "should have a class-level method for creating a default connection" do
- Puppet::Util::Ldap::Connection.should respond_to(:instance)
- end
+ it "should have a class-level method for creating a default connection" do
+ Puppet::Util::Ldap::Connection.should respond_to(:instance)
+ end
- describe "when creating a default connection" do
- before do
- Puppet.settings.stubs(:value).returns "whatever"
- end
+ describe "when creating a default connection" do
+ before do
+ Puppet.settings.stubs(:value).returns "whatever"
+ end
- it "should use the :ldapserver setting to determine the host" do
- Puppet.settings.expects(:value).with(:ldapserver).returns "myserv"
- Puppet::Util::Ldap::Connection.expects(:new).with { |host, port, options| host == "myserv" }
- Puppet::Util::Ldap::Connection.instance
- end
+ it "should use the :ldapserver setting to determine the host" do
+ Puppet.settings.expects(:value).with(:ldapserver).returns "myserv"
+ Puppet::Util::Ldap::Connection.expects(:new).with { |host, port, options| host == "myserv" }
+ Puppet::Util::Ldap::Connection.instance
+ end
- it "should use the :ldapport setting to determine the port" do
- Puppet.settings.expects(:value).with(:ldapport).returns "456"
- Puppet::Util::Ldap::Connection.expects(:new).with { |host, port, options| port == "456" }
- Puppet::Util::Ldap::Connection.instance
- end
+ it "should use the :ldapport setting to determine the port" do
+ Puppet.settings.expects(:value).with(:ldapport).returns "456"
+ Puppet::Util::Ldap::Connection.expects(:new).with { |host, port, options| port == "456" }
+ Puppet::Util::Ldap::Connection.instance
+ end
- it "should set ssl to :tls if tls is enabled" do
- Puppet.settings.expects(:value).with(:ldaptls).returns true
- Puppet::Util::Ldap::Connection.expects(:new).with { |host, port, options| options[:ssl] == :tls }
- Puppet::Util::Ldap::Connection.instance
- end
+ it "should set ssl to :tls if tls is enabled" do
+ Puppet.settings.expects(:value).with(:ldaptls).returns true
+ Puppet::Util::Ldap::Connection.expects(:new).with { |host, port, options| options[:ssl] == :tls }
+ Puppet::Util::Ldap::Connection.instance
+ end
- it "should set ssl to 'true' if ssl is enabled and tls is not" do
- Puppet.settings.expects(:value).with(:ldaptls).returns false
- Puppet.settings.expects(:value).with(:ldapssl).returns true
- Puppet::Util::Ldap::Connection.expects(:new).with { |host, port, options| options[:ssl] == true }
- Puppet::Util::Ldap::Connection.instance
- end
+ it "should set ssl to 'true' if ssl is enabled and tls is not" do
+ Puppet.settings.expects(:value).with(:ldaptls).returns false
+ Puppet.settings.expects(:value).with(:ldapssl).returns true
+ Puppet::Util::Ldap::Connection.expects(:new).with { |host, port, options| options[:ssl] == true }
+ Puppet::Util::Ldap::Connection.instance
+ end
- it "should set ssl to false if neither ssl nor tls are enabled" do
- Puppet.settings.expects(:value).with(:ldaptls).returns false
- Puppet.settings.expects(:value).with(:ldapssl).returns false
- Puppet::Util::Ldap::Connection.expects(:new).with { |host, port, options| options[:ssl] == false }
- Puppet::Util::Ldap::Connection.instance
- end
+ it "should set ssl to false if neither ssl nor tls are enabled" do
+ Puppet.settings.expects(:value).with(:ldaptls).returns false
+ Puppet.settings.expects(:value).with(:ldapssl).returns false
+ Puppet::Util::Ldap::Connection.expects(:new).with { |host, port, options| options[:ssl] == false }
+ Puppet::Util::Ldap::Connection.instance
+ end
- it "should set the ldapuser if one is set" do
- Puppet.settings.expects(:value).with(:ldapuser).returns "foo"
- Puppet::Util::Ldap::Connection.expects(:new).with { |host, port, options| options[:user] == "foo" }
- Puppet::Util::Ldap::Connection.instance
- end
+ it "should set the ldapuser if one is set" do
+ Puppet.settings.expects(:value).with(:ldapuser).returns "foo"
+ Puppet::Util::Ldap::Connection.expects(:new).with { |host, port, options| options[:user] == "foo" }
+ Puppet::Util::Ldap::Connection.instance
+ end
- it "should set the ldapuser and ldappassword if both is set" do
- Puppet.settings.expects(:value).with(:ldapuser).returns "foo"
- Puppet.settings.expects(:value).with(:ldappassword).returns "bar"
- Puppet::Util::Ldap::Connection.expects(:new).with { |host, port, options| options[:user] == "foo" and options[:password] == "bar" }
- Puppet::Util::Ldap::Connection.instance
- end
+ it "should set the ldapuser and ldappassword if both is set" do
+ Puppet.settings.expects(:value).with(:ldapuser).returns "foo"
+ Puppet.settings.expects(:value).with(:ldappassword).returns "bar"
+ Puppet::Util::Ldap::Connection.expects(:new).with { |host, port, options| options[:user] == "foo" and options[:password] == "bar" }
+ Puppet::Util::Ldap::Connection.instance
end
+ end
end
diff --git a/spec/unit/util/ldap/generator_spec.rb b/spec/unit/util/ldap/generator_spec.rb
index 8086dd9..1630cd1 100755
--- a/spec/unit/util/ldap/generator_spec.rb
+++ b/spec/unit/util/ldap/generator_spec.rb
@@ -8,47 +8,47 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/util/ldap/generator'
describe Puppet::Util::Ldap::Generator do
- before do
- @generator = Puppet::Util::Ldap::Generator.new(:uno)
- end
-
- it "should require a parameter name at initialization" do
- lambda { Puppet::Util::Ldap::Generator.new }.should raise_error
- end
-
- it "should always return its name as a string" do
- g = Puppet::Util::Ldap::Generator.new(:myname)
- g.name.should == "myname"
- end
-
- it "should provide a method for declaring the source parameter" do
- @generator.from(:dos)
- end
-
- it "should always return a set source as a string" do
- @generator.from(:dos)
- @generator.source.should == "dos"
- end
-
- it "should return the source as nil if there is no source" do
- @generator.source.should be_nil
- end
-
- it "should return itself when declaring the source" do
- @generator.from(:dos).should equal(@generator)
- end
-
- it "should run the provided block when asked to generate the value" do
- @generator.with { "yayness" }
- @generator.generate.should == "yayness"
- end
-
- it "should pass in any provided value to the block" do
- @generator.with { |value| value.upcase }
- @generator.generate("myval").should == "MYVAL"
- end
-
- it "should return itself when declaring the code used for generating" do
- @generator.with { |value| value.upcase }.should equal(@generator)
- end
+ before do
+ @generator = Puppet::Util::Ldap::Generator.new(:uno)
+ end
+
+ it "should require a parameter name at initialization" do
+ lambda { Puppet::Util::Ldap::Generator.new }.should raise_error
+ end
+
+ it "should always return its name as a string" do
+ g = Puppet::Util::Ldap::Generator.new(:myname)
+ g.name.should == "myname"
+ end
+
+ it "should provide a method for declaring the source parameter" do
+ @generator.from(:dos)
+ end
+
+ it "should always return a set source as a string" do
+ @generator.from(:dos)
+ @generator.source.should == "dos"
+ end
+
+ it "should return the source as nil if there is no source" do
+ @generator.source.should be_nil
+ end
+
+ it "should return itself when declaring the source" do
+ @generator.from(:dos).should equal(@generator)
+ end
+
+ it "should run the provided block when asked to generate the value" do
+ @generator.with { "yayness" }
+ @generator.generate.should == "yayness"
+ end
+
+ it "should pass in any provided value to the block" do
+ @generator.with { |value| value.upcase }
+ @generator.generate("myval").should == "MYVAL"
+ end
+
+ it "should return itself when declaring the code used for generating" do
+ @generator.with { |value| value.upcase }.should equal(@generator)
+ end
end
diff --git a/spec/unit/util/ldap/manager_spec.rb b/spec/unit/util/ldap/manager_spec.rb
index bc6b18d..ba693d5 100755
--- a/spec/unit/util/ldap/manager_spec.rb
+++ b/spec/unit/util/ldap/manager_spec.rb
@@ -10,645 +10,645 @@ require 'puppet/util/ldap/manager'
# If the ldap classes aren't available, go ahead and
# create some, so our tests will pass.
unless defined?(LDAP::Mod)
- class LDAP
- LDAP_MOD_ADD = :adding
- LDAP_MOD_REPLACE = :replacing
- LDAP_MOD_DELETE = :deleting
- class ResultError < RuntimeError; end
- class Mod
- def initialize(*args)
- end
- end
+ class LDAP
+ LDAP_MOD_ADD = :adding
+ LDAP_MOD_REPLACE = :replacing
+ LDAP_MOD_DELETE = :deleting
+ class ResultError < RuntimeError; end
+ class Mod
+ def initialize(*args)
+ end
end
+ end
end
describe Puppet::Util::Ldap::Manager do
- before do
- @manager = Puppet::Util::Ldap::Manager.new
- end
+ before do
+ @manager = Puppet::Util::Ldap::Manager.new
+ end
- it "should return self when specifying objectclasses" do
- @manager.manages(:one, :two).should equal(@manager)
- end
+ it "should return self when specifying objectclasses" do
+ @manager.manages(:one, :two).should equal(@manager)
+ end
- it "should allow specification of what objectclasses are managed" do
- @manager.manages(:one, :two).objectclasses.should == [:one, :two]
- end
+ it "should allow specification of what objectclasses are managed" do
+ @manager.manages(:one, :two).objectclasses.should == [:one, :two]
+ end
- it "should return self when specifying the relative base" do
- @manager.at("yay").should equal(@manager)
- end
+ it "should return self when specifying the relative base" do
+ @manager.at("yay").should equal(@manager)
+ end
- it "should allow specification of the relative base" do
- @manager.at("yay").location.should == "yay"
- end
+ it "should allow specification of the relative base" do
+ @manager.at("yay").location.should == "yay"
+ end
- it "should return self when specifying the attribute map" do
- @manager.maps(:one => :two).should equal(@manager)
- end
+ it "should return self when specifying the attribute map" do
+ @manager.maps(:one => :two).should equal(@manager)
+ end
- it "should allow specification of the rdn attribute" do
- @manager.named_by(:uid).rdn.should == :uid
- end
+ it "should allow specification of the rdn attribute" do
+ @manager.named_by(:uid).rdn.should == :uid
+ end
- it "should allow specification of the attribute map" do
- @manager.maps(:one => :two).puppet2ldap.should == {:one => :two}
- end
+ it "should allow specification of the attribute map" do
+ @manager.maps(:one => :two).puppet2ldap.should == {:one => :two}
+ end
- it "should have a no-op 'and' method that just returns self" do
- @manager.and.should equal(@manager)
- end
+ it "should have a no-op 'and' method that just returns self" do
+ @manager.and.should equal(@manager)
+ end
- it "should allow specification of generated attributes" do
- @manager.generates(:thing).should be_instance_of(Puppet::Util::Ldap::Generator)
- end
+ it "should allow specification of generated attributes" do
+ @manager.generates(:thing).should be_instance_of(Puppet::Util::Ldap::Generator)
+ end
- describe "when generating attributes" do
- before do
- @generator = stub 'generator', :source => "one", :name => "myparam"
+ describe "when generating attributes" do
+ before do
+ @generator = stub 'generator', :source => "one", :name => "myparam"
- Puppet::Util::Ldap::Generator.stubs(:new).with(:myparam).returns @generator
- end
+ Puppet::Util::Ldap::Generator.stubs(:new).with(:myparam).returns @generator
+ end
- it "should create a generator to do the parameter generation" do
- Puppet::Util::Ldap::Generator.expects(:new).with(:myparam).returns @generator
- @manager.generates(:myparam)
- end
+ it "should create a generator to do the parameter generation" do
+ Puppet::Util::Ldap::Generator.expects(:new).with(:myparam).returns @generator
+ @manager.generates(:myparam)
+ end
- it "should return the generator from the :generates method" do
- @manager.generates(:myparam).should equal(@generator)
- end
+ it "should return the generator from the :generates method" do
+ @manager.generates(:myparam).should equal(@generator)
+ end
- it "should not replace already present values" do
- @manager.generates(:myparam)
+ it "should not replace already present values" do
+ @manager.generates(:myparam)
- attrs = {"myparam" => "testing"}
- @generator.expects(:generate).never
+ attrs = {"myparam" => "testing"}
+ @generator.expects(:generate).never
- @manager.generate attrs
+ @manager.generate attrs
- attrs["myparam"].should == "testing"
- end
+ attrs["myparam"].should == "testing"
+ end
- it "should look for the parameter as a string, not a symbol" do
- @manager.generates(:myparam)
- @generator.expects(:generate).with("yay").returns %w{double yay}
- attrs = {"one" => "yay"}
- @manager.generate attrs
+ it "should look for the parameter as a string, not a symbol" do
+ @manager.generates(:myparam)
+ @generator.expects(:generate).with("yay").returns %w{double yay}
+ attrs = {"one" => "yay"}
+ @manager.generate attrs
- attrs["myparam"].should == %w{double yay}
- end
+ attrs["myparam"].should == %w{double yay}
+ end
- it "should fail if a source is specified and no source value is not defined" do
- @manager.generates(:myparam)
- lambda { @manager.generate "two" => "yay" }.should raise_error(ArgumentError)
- end
+ it "should fail if a source is specified and no source value is not defined" do
+ @manager.generates(:myparam)
+ lambda { @manager.generate "two" => "yay" }.should raise_error(ArgumentError)
+ end
- it "should use the source value to generate the new value if a source attribute is specified" do
- @manager.generates(:myparam)
- @generator.expects(:generate).with("yay").returns %w{double yay}
- @manager.generate "one" => "yay"
- end
+ it "should use the source value to generate the new value if a source attribute is specified" do
+ @manager.generates(:myparam)
+ @generator.expects(:generate).with("yay").returns %w{double yay}
+ @manager.generate "one" => "yay"
+ end
- it "should not pass in any value if no source attribute is specified" do
- @generator.stubs(:source).returns nil
- @manager.generates(:myparam)
- @generator.expects(:generate).with.returns %w{double yay}
- @manager.generate "one" => "yay"
- end
+ it "should not pass in any value if no source attribute is specified" do
+ @generator.stubs(:source).returns nil
+ @manager.generates(:myparam)
+ @generator.expects(:generate).with.returns %w{double yay}
+ @manager.generate "one" => "yay"
+ end
- it "should convert any results to arrays of strings if necessary" do
- @generator.expects(:generate).returns :test
- @manager.generates(:myparam)
+ it "should convert any results to arrays of strings if necessary" do
+ @generator.expects(:generate).returns :test
+ @manager.generates(:myparam)
- attrs = {"one" => "two"}
- @manager.generate(attrs)
- attrs["myparam"].should == ["test"]
- end
+ attrs = {"one" => "two"}
+ @manager.generate(attrs)
+ attrs["myparam"].should == ["test"]
+ end
- it "should add the result to the passed-in attribute hash" do
- @generator.expects(:generate).returns %w{test}
- @manager.generates(:myparam)
+ it "should add the result to the passed-in attribute hash" do
+ @generator.expects(:generate).returns %w{test}
+ @manager.generates(:myparam)
- attrs = {"one" => "two"}
- @manager.generate(attrs)
- attrs["myparam"].should == %w{test}
- end
+ attrs = {"one" => "two"}
+ @manager.generate(attrs)
+ attrs["myparam"].should == %w{test}
end
-
- it "should be considered invalid if it is missing a location" do
- @manager.manages :me
- @manager.maps :me => :you
- @manager.should_not be_valid
+ end
+
+ it "should be considered invalid if it is missing a location" do
+ @manager.manages :me
+ @manager.maps :me => :you
+ @manager.should_not be_valid
+ end
+
+ it "should be considered invalid if it is missing an objectclass list" do
+ @manager.maps :me => :you
+ @manager.at "ou=yayness"
+ @manager.should_not be_valid
+ end
+
+ it "should be considered invalid if it is missing an attribute map" do
+ @manager.manages :me
+ @manager.at "ou=yayness"
+ @manager.should_not be_valid
+ end
+
+ it "should be considered valid if it has an attribute map, location, and objectclass list" do
+ @manager.maps :me => :you
+ @manager.manages :me
+ @manager.at "ou=yayness"
+ @manager.should be_valid
+ end
+
+ it "should calculate an instance's dn using the :ldapbase setting and the relative base" do
+ Puppet.settings.expects(:value).with(:ldapbase).returns "dc=testing"
+ @manager.at "ou=mybase"
+ @manager.dn("me").should == "cn=me,ou=mybase,dc=testing"
+ end
+
+ it "should use the specified rdn when calculating an instance's dn" do
+ Puppet.settings.expects(:value).with(:ldapbase).returns "dc=testing"
+ @manager.named_by :uid
+ @manager.at "ou=mybase"
+ @manager.dn("me").should =~ /^uid=me/
+ end
+
+ it "should calculate its base using the :ldapbase setting and the relative base" do
+ Puppet.settings.expects(:value).with(:ldapbase).returns "dc=testing"
+ @manager.at "ou=mybase"
+ @manager.base.should == "ou=mybase,dc=testing"
+ end
+
+ describe "when generating its search filter" do
+ it "should using a single 'objectclass=<name>' filter if a single objectclass is specified" do
+ @manager.manages("testing")
+ @manager.filter.should == "objectclass=testing"
end
- it "should be considered invalid if it is missing an objectclass list" do
- @manager.maps :me => :you
- @manager.at "ou=yayness"
- @manager.should_not be_valid
+ it "should create an LDAP AND filter if multiple objectclasses are specified" do
+ @manager.manages "testing", "okay", "done"
+ @manager.filter.should == "(&(objectclass=testing)(objectclass=okay)(objectclass=done))"
end
+ end
- it "should be considered invalid if it is missing an attribute map" do
- @manager.manages :me
- @manager.at "ou=yayness"
- @manager.should_not be_valid
- end
+ it "should have a method for converting a Puppet attribute name to an LDAP attribute name as a string" do
+ @manager.maps :puppet_attr => :ldap_attr
+ @manager.ldap_name(:puppet_attr).should == "ldap_attr"
+ end
- it "should be considered valid if it has an attribute map, location, and objectclass list" do
- @manager.maps :me => :you
- @manager.manages :me
- @manager.at "ou=yayness"
- @manager.should be_valid
- end
+ it "should have a method for converting an LDAP attribute name to a Puppet attribute name" do
+ @manager.maps :puppet_attr => :ldap_attr
+ @manager.puppet_name(:ldap_attr).should == :puppet_attr
+ end
- it "should calculate an instance's dn using the :ldapbase setting and the relative base" do
- Puppet.settings.expects(:value).with(:ldapbase).returns "dc=testing"
- @manager.at "ou=mybase"
- @manager.dn("me").should == "cn=me,ou=mybase,dc=testing"
- end
+ it "should have a :create method for creating ldap entries" do
+ @manager.should respond_to(:create)
+ end
- it "should use the specified rdn when calculating an instance's dn" do
- Puppet.settings.expects(:value).with(:ldapbase).returns "dc=testing"
- @manager.named_by :uid
- @manager.at "ou=mybase"
- @manager.dn("me").should =~ /^uid=me/
- end
+ it "should have a :delete method for deleting ldap entries" do
+ @manager.should respond_to(:delete)
+ end
- it "should calculate its base using the :ldapbase setting and the relative base" do
- Puppet.settings.expects(:value).with(:ldapbase).returns "dc=testing"
- @manager.at "ou=mybase"
- @manager.base.should == "ou=mybase,dc=testing"
- end
+ it "should have a :modify method for modifying ldap entries" do
+ @manager.should respond_to(:modify)
+ end
- describe "when generating its search filter" do
- it "should using a single 'objectclass=<name>' filter if a single objectclass is specified" do
- @manager.manages("testing")
- @manager.filter.should == "objectclass=testing"
- end
+ it "should have a method for finding an entry by name in ldap" do
+ @manager.should respond_to(:find)
+ end
- it "should create an LDAP AND filter if multiple objectclasses are specified" do
- @manager.manages "testing", "okay", "done"
- @manager.filter.should == "(&(objectclass=testing)(objectclass=okay)(objectclass=done))"
- end
- end
+ describe "when converting ldap entries to hashes for providers" do
+ before do
+ @manager.maps :uno => :one, :dos => :two
- it "should have a method for converting a Puppet attribute name to an LDAP attribute name as a string" do
- @manager.maps :puppet_attr => :ldap_attr
- @manager.ldap_name(:puppet_attr).should == "ldap_attr"
+ @result = @manager.entry2provider("dn" => ["cn=one,ou=people,dc=madstop"], "one" => ["two"], "three" => %w{four}, "objectclass" => %w{yay ness})
end
- it "should have a method for converting an LDAP attribute name to a Puppet attribute name" do
- @manager.maps :puppet_attr => :ldap_attr
- @manager.puppet_name(:ldap_attr).should == :puppet_attr
+ it "should set the name to the short portion of the dn" do
+ @result[:name].should == "one"
end
- it "should have a :create method for creating ldap entries" do
- @manager.should respond_to(:create)
+ it "should remove the objectclasses" do
+ @result["objectclass"].should be_nil
end
- it "should have a :delete method for deleting ldap entries" do
- @manager.should respond_to(:delete)
+ it "should remove any attributes that are not mentioned in the map" do
+ @result["three"].should be_nil
end
- it "should have a :modify method for modifying ldap entries" do
- @manager.should respond_to(:modify)
+ it "should rename convert to symbols all attributes to their puppet names" do
+ @result[:uno].should == %w{two}
end
- it "should have a method for finding an entry by name in ldap" do
- @manager.should respond_to(:find)
+ it "should set the value of all unset puppet attributes as :absent" do
+ @result[:dos].should == :absent
end
+ end
- describe "when converting ldap entries to hashes for providers" do
- before do
- @manager.maps :uno => :one, :dos => :two
-
- @result = @manager.entry2provider("dn" => ["cn=one,ou=people,dc=madstop"], "one" => ["two"], "three" => %w{four}, "objectclass" => %w{yay ness})
- end
-
- it "should set the name to the short portion of the dn" do
- @result[:name].should == "one"
- end
-
- it "should remove the objectclasses" do
- @result["objectclass"].should be_nil
- end
-
- it "should remove any attributes that are not mentioned in the map" do
- @result["three"].should be_nil
- end
-
- it "should rename convert to symbols all attributes to their puppet names" do
- @result[:uno].should == %w{two}
- end
-
- it "should set the value of all unset puppet attributes as :absent" do
- @result[:dos].should == :absent
- end
+ describe "when using an ldap connection" do
+ before do
+ @ldapconn = mock 'ldapconn'
+ @conn = stub 'connection', :connection => @ldapconn, :start => nil, :close => nil
+ Puppet::Util::Ldap::Connection.stubs(:new).returns(@conn)
end
- describe "when using an ldap connection" do
- before do
- @ldapconn = mock 'ldapconn'
- @conn = stub 'connection', :connection => @ldapconn, :start => nil, :close => nil
- Puppet::Util::Ldap::Connection.stubs(:new).returns(@conn)
- end
-
- it "should fail unless a block is given" do
- lambda { @manager.connect }.should raise_error(ArgumentError)
- end
+ it "should fail unless a block is given" do
+ lambda { @manager.connect }.should raise_error(ArgumentError)
+ end
- it "should open the connection with its server set to :ldapserver" do
- Puppet.settings.stubs(:value).returns(false)
- Puppet.settings.expects(:value).with(:ldapserver).returns("myserver")
- Puppet::Util::Ldap::Connection.expects(:new).with { |*args| args[0] == "myserver" }.returns @conn
+ it "should open the connection with its server set to :ldapserver" do
+ Puppet.settings.stubs(:value).returns(false)
+ Puppet.settings.expects(:value).with(:ldapserver).returns("myserver")
+ Puppet::Util::Ldap::Connection.expects(:new).with { |*args| args[0] == "myserver" }.returns @conn
- @manager.connect { |c| }
- end
+ @manager.connect { |c| }
+ end
- it "should open the connection with its port set to the :ldapport" do
- Puppet.settings.stubs(:value).returns(false)
- Puppet.settings.expects(:value).with(:ldapport).returns("28")
- Puppet::Util::Ldap::Connection.expects(:new).with { |*args| args[1] == "28" }.returns @conn
+ it "should open the connection with its port set to the :ldapport" do
+ Puppet.settings.stubs(:value).returns(false)
+ Puppet.settings.expects(:value).with(:ldapport).returns("28")
+ Puppet::Util::Ldap::Connection.expects(:new).with { |*args| args[1] == "28" }.returns @conn
- @manager.connect { |c| }
- end
+ @manager.connect { |c| }
+ end
- it "should open the connection with no user if :ldapuser is not set" do
- Puppet.settings.stubs(:value).returns(false)
- Puppet.settings.expects(:value).with(:ldapuser).returns("")
- Puppet::Util::Ldap::Connection.expects(:new).with { |*args| args[2][:user].nil? }.returns @conn
+ it "should open the connection with no user if :ldapuser is not set" do
+ Puppet.settings.stubs(:value).returns(false)
+ Puppet.settings.expects(:value).with(:ldapuser).returns("")
+ Puppet::Util::Ldap::Connection.expects(:new).with { |*args| args[2][:user].nil? }.returns @conn
- @manager.connect { |c| }
- end
+ @manager.connect { |c| }
+ end
- it "should open the connection with its user set to the :ldapuser if it is set" do
- Puppet.settings.stubs(:value).returns(false)
- Puppet.settings.expects(:value).with(:ldapuser).returns("mypass")
- Puppet::Util::Ldap::Connection.expects(:new).with { |*args| args[2][:user] == "mypass" }.returns @conn
+ it "should open the connection with its user set to the :ldapuser if it is set" do
+ Puppet.settings.stubs(:value).returns(false)
+ Puppet.settings.expects(:value).with(:ldapuser).returns("mypass")
+ Puppet::Util::Ldap::Connection.expects(:new).with { |*args| args[2][:user] == "mypass" }.returns @conn
- @manager.connect { |c| }
- end
+ @manager.connect { |c| }
+ end
- it "should open the connection with no password if :ldappassword is not set" do
- Puppet.settings.stubs(:value).returns(false)
- Puppet.settings.expects(:value).with(:ldappassword).returns("")
- Puppet::Util::Ldap::Connection.expects(:new).with { |*args| args[2][:password].nil? }.returns @conn
+ it "should open the connection with no password if :ldappassword is not set" do
+ Puppet.settings.stubs(:value).returns(false)
+ Puppet.settings.expects(:value).with(:ldappassword).returns("")
+ Puppet::Util::Ldap::Connection.expects(:new).with { |*args| args[2][:password].nil? }.returns @conn
- @manager.connect { |c| }
- end
+ @manager.connect { |c| }
+ end
- it "should open the connection with its password set to the :ldappassword if it is set" do
- Puppet.settings.stubs(:value).returns(false)
- Puppet.settings.expects(:value).with(:ldappassword).returns("mypass")
- Puppet::Util::Ldap::Connection.expects(:new).with { |*args| args[2][:password] == "mypass" }.returns @conn
+ it "should open the connection with its password set to the :ldappassword if it is set" do
+ Puppet.settings.stubs(:value).returns(false)
+ Puppet.settings.expects(:value).with(:ldappassword).returns("mypass")
+ Puppet::Util::Ldap::Connection.expects(:new).with { |*args| args[2][:password] == "mypass" }.returns @conn
- @manager.connect { |c| }
- end
+ @manager.connect { |c| }
+ end
- it "should set ssl to :tls if ldaptls is enabled" do
- Puppet.settings.stubs(:value).returns(false)
- Puppet.settings.expects(:value).with(:ldaptls).returns(true)
- Puppet::Util::Ldap::Connection.expects(:new).with { |*args| args[2][:ssl] == :tls }.returns @conn
+ it "should set ssl to :tls if ldaptls is enabled" do
+ Puppet.settings.stubs(:value).returns(false)
+ Puppet.settings.expects(:value).with(:ldaptls).returns(true)
+ Puppet::Util::Ldap::Connection.expects(:new).with { |*args| args[2][:ssl] == :tls }.returns @conn
- @manager.connect { |c| }
- end
+ @manager.connect { |c| }
+ end
- it "should set ssl to true if ldapssl is enabled" do
- Puppet.settings.stubs(:value).returns(false)
- Puppet.settings.expects(:value).with(:ldapssl).returns(true)
- Puppet::Util::Ldap::Connection.expects(:new).with { |*args| args[2][:ssl] == true }.returns @conn
+ it "should set ssl to true if ldapssl is enabled" do
+ Puppet.settings.stubs(:value).returns(false)
+ Puppet.settings.expects(:value).with(:ldapssl).returns(true)
+ Puppet::Util::Ldap::Connection.expects(:new).with { |*args| args[2][:ssl] == true }.returns @conn
- @manager.connect { |c| }
- end
+ @manager.connect { |c| }
+ end
- it "should set ssl to false if neither ldaptls nor ldapssl is enabled" do
- Puppet.settings.stubs(:value).returns(false)
- Puppet.settings.expects(:value).with(:ldapssl).returns(false)
- Puppet::Util::Ldap::Connection.expects(:new).with { |*args| args[2][:ssl] == false }.returns @conn
+ it "should set ssl to false if neither ldaptls nor ldapssl is enabled" do
+ Puppet.settings.stubs(:value).returns(false)
+ Puppet.settings.expects(:value).with(:ldapssl).returns(false)
+ Puppet::Util::Ldap::Connection.expects(:new).with { |*args| args[2][:ssl] == false }.returns @conn
- @manager.connect { |c| }
- end
+ @manager.connect { |c| }
+ end
- it "should open, yield, and then close the connection" do
- @conn.expects(:start)
- @conn.expects(:close)
- Puppet::Util::Ldap::Connection.expects(:new).returns(@conn)
- @ldapconn.expects(:test)
- @manager.connect { |c| c.test }
- end
+ it "should open, yield, and then close the connection" do
+ @conn.expects(:start)
+ @conn.expects(:close)
+ Puppet::Util::Ldap::Connection.expects(:new).returns(@conn)
+ @ldapconn.expects(:test)
+ @manager.connect { |c| c.test }
+ end
- it "should close the connection even if there's an exception in the passed block" do
- @conn.expects(:close)
- lambda { @manager.connect { |c| raise ArgumentError } }.should raise_error(ArgumentError)
- end
+ it "should close the connection even if there's an exception in the passed block" do
+ @conn.expects(:close)
+ lambda { @manager.connect { |c| raise ArgumentError } }.should raise_error(ArgumentError)
end
+ end
- describe "when using ldap" do
- before do
- @conn = mock 'connection'
- @manager.stubs(:connect).yields @conn
- @manager.stubs(:objectclasses).returns [:oc1, :oc2]
- @manager.maps :one => :uno, :two => :dos, :three => :tres, :four => :quatro
- end
+ describe "when using ldap" do
+ before do
+ @conn = mock 'connection'
+ @manager.stubs(:connect).yields @conn
+ @manager.stubs(:objectclasses).returns [:oc1, :oc2]
+ @manager.maps :one => :uno, :two => :dos, :three => :tres, :four => :quatro
+ end
- describe "to create entries" do
- it "should convert the first argument to its :create method to a full dn and pass the resulting argument list to its connection" do
- @manager.expects(:dn).with("myname").returns "mydn"
- @conn.expects(:add).with { |name, attrs| name == "mydn" }
+ describe "to create entries" do
+ it "should convert the first argument to its :create method to a full dn and pass the resulting argument list to its connection" do
+ @manager.expects(:dn).with("myname").returns "mydn"
+ @conn.expects(:add).with { |name, attrs| name == "mydn" }
- @manager.create("myname", {"attr" => "myattrs"})
- end
+ @manager.create("myname", {"attr" => "myattrs"})
+ end
- it "should add the objectclasses to the attributes" do
- @manager.expects(:dn).with("myname").returns "mydn"
- @conn.expects(:add).with { |name, attrs| attrs["objectClass"].include?("oc1") and attrs["objectClass"].include?("oc2") }
+ it "should add the objectclasses to the attributes" do
+ @manager.expects(:dn).with("myname").returns "mydn"
+ @conn.expects(:add).with { |name, attrs| attrs["objectClass"].include?("oc1") and attrs["objectClass"].include?("oc2") }
- @manager.create("myname", {:one => :testing})
- end
+ @manager.create("myname", {:one => :testing})
+ end
- it "should add the rdn to the attributes" do
- @manager.expects(:dn).with("myname").returns "mydn"
- @conn.expects(:add).with { |name, attrs| attrs["cn"] == %w{myname} }
+ it "should add the rdn to the attributes" do
+ @manager.expects(:dn).with("myname").returns "mydn"
+ @conn.expects(:add).with { |name, attrs| attrs["cn"] == %w{myname} }
- @manager.create("myname", {:one => :testing})
- end
+ @manager.create("myname", {:one => :testing})
+ end
- it "should add 'top' to the objectclasses if it is not listed" do
- @manager.expects(:dn).with("myname").returns "mydn"
- @conn.expects(:add).with { |name, attrs| attrs["objectClass"].include?("top") }
+ it "should add 'top' to the objectclasses if it is not listed" do
+ @manager.expects(:dn).with("myname").returns "mydn"
+ @conn.expects(:add).with { |name, attrs| attrs["objectClass"].include?("top") }
- @manager.create("myname", {:one => :testing})
- end
+ @manager.create("myname", {:one => :testing})
+ end
- it "should add any generated values that are defined" do
- generator = stub 'generator', :source => :one, :name => "myparam"
+ it "should add any generated values that are defined" do
+ generator = stub 'generator', :source => :one, :name => "myparam"
- Puppet::Util::Ldap::Generator.expects(:new).with(:myparam).returns generator
+ Puppet::Util::Ldap::Generator.expects(:new).with(:myparam).returns generator
- @manager.generates(:myparam)
+ @manager.generates(:myparam)
- @manager.stubs(:dn).with("myname").returns "mydn"
+ @manager.stubs(:dn).with("myname").returns "mydn"
- generator.expects(:generate).with(:testing).returns ["generated value"]
- @conn.expects(:add).with { |name, attrs| attrs["myparam"] == ["generated value"] }
+ generator.expects(:generate).with(:testing).returns ["generated value"]
+ @conn.expects(:add).with { |name, attrs| attrs["myparam"] == ["generated value"] }
- @manager.create("myname", {:one => :testing})
- end
+ @manager.create("myname", {:one => :testing})
+ end
- it "should convert any generated values to arrays of strings if necessary" do
- generator = stub 'generator', :source => :one, :name => "myparam"
+ it "should convert any generated values to arrays of strings if necessary" do
+ generator = stub 'generator', :source => :one, :name => "myparam"
- Puppet::Util::Ldap::Generator.expects(:new).with(:myparam).returns generator
+ Puppet::Util::Ldap::Generator.expects(:new).with(:myparam).returns generator
- @manager.generates(:myparam)
+ @manager.generates(:myparam)
- @manager.stubs(:dn).returns "mydn"
+ @manager.stubs(:dn).returns "mydn"
- generator.expects(:generate).returns :generated
- @conn.expects(:add).with { |name, attrs| attrs["myparam"] == ["generated"] }
+ generator.expects(:generate).returns :generated
+ @conn.expects(:add).with { |name, attrs| attrs["myparam"] == ["generated"] }
- @manager.create("myname", {:one => :testing})
- end
- end
+ @manager.create("myname", {:one => :testing})
+ end
+ end
- describe "do delete entries" do
- it "should convert the first argument to its :delete method to a full dn and pass the resulting argument list to its connection" do
- @manager.expects(:dn).with("myname").returns "mydn"
- @conn.expects(:delete).with("mydn")
+ describe "do delete entries" do
+ it "should convert the first argument to its :delete method to a full dn and pass the resulting argument list to its connection" do
+ @manager.expects(:dn).with("myname").returns "mydn"
+ @conn.expects(:delete).with("mydn")
- @manager.delete("myname")
- end
- end
+ @manager.delete("myname")
+ end
+ end
- describe "to modify entries" do
- it "should convert the first argument to its :modify method to a full dn and pass the resulting argument list to its connection" do
- @manager.expects(:dn).with("myname").returns "mydn"
- @conn.expects(:modify).with("mydn", :mymods)
+ describe "to modify entries" do
+ it "should convert the first argument to its :modify method to a full dn and pass the resulting argument list to its connection" do
+ @manager.expects(:dn).with("myname").returns "mydn"
+ @conn.expects(:modify).with("mydn", :mymods)
- @manager.modify("myname", :mymods)
- end
- end
+ @manager.modify("myname", :mymods)
+ end
+ end
- describe "to find a single entry" do
- it "should use the dn of the provided name as the search base, a scope of 0, and 'objectclass=*' as the filter for a search2 call" do
- @manager.expects(:dn).with("myname").returns "mydn"
- @conn.expects(:search2).with("mydn", 0, "objectclass=*")
+ describe "to find a single entry" do
+ it "should use the dn of the provided name as the search base, a scope of 0, and 'objectclass=*' as the filter for a search2 call" do
+ @manager.expects(:dn).with("myname").returns "mydn"
+ @conn.expects(:search2).with("mydn", 0, "objectclass=*")
- @manager.find("myname")
- end
+ @manager.find("myname")
+ end
- it "should return nil if an exception is thrown because no result is found" do
- @manager.expects(:dn).with("myname").returns "mydn"
- @conn.expects(:search2).raises LDAP::ResultError
+ it "should return nil if an exception is thrown because no result is found" do
+ @manager.expects(:dn).with("myname").returns "mydn"
+ @conn.expects(:search2).raises LDAP::ResultError
- @manager.find("myname").should be_nil
- end
+ @manager.find("myname").should be_nil
+ end
- it "should return a converted provider hash if the result is found" do
- @manager.expects(:dn).with("myname").returns "mydn"
- result = {"one" => "two"}
- @conn.expects(:search2).yields result
+ it "should return a converted provider hash if the result is found" do
+ @manager.expects(:dn).with("myname").returns "mydn"
+ result = {"one" => "two"}
+ @conn.expects(:search2).yields result
- @manager.expects(:entry2provider).with(result).returns "myprovider"
+ @manager.expects(:entry2provider).with(result).returns "myprovider"
- @manager.find("myname").should == "myprovider"
- end
- end
+ @manager.find("myname").should == "myprovider"
+ end
+ end
- describe "to search for multiple entries" do
- before do
- @manager.stubs(:filter).returns "myfilter"
- end
+ describe "to search for multiple entries" do
+ before do
+ @manager.stubs(:filter).returns "myfilter"
+ end
- it "should use the manager's search base as the dn of the provided name as the search base" do
- @manager.expects(:base).returns "mybase"
- @conn.expects(:search2).with { |base, scope, filter| base == "mybase" }
+ it "should use the manager's search base as the dn of the provided name as the search base" do
+ @manager.expects(:base).returns "mybase"
+ @conn.expects(:search2).with { |base, scope, filter| base == "mybase" }
- @manager.search
- end
+ @manager.search
+ end
- it "should use a scope of 1" do
- @conn.expects(:search2).with { |base, scope, filter| scope == 1 }
+ it "should use a scope of 1" do
+ @conn.expects(:search2).with { |base, scope, filter| scope == 1 }
- @manager.search
- end
+ @manager.search
+ end
- it "should use any specified search filter" do
- @manager.expects(:filter).never
- @conn.expects(:search2).with { |base, scope, filter| filter == "boo" }
+ it "should use any specified search filter" do
+ @manager.expects(:filter).never
+ @conn.expects(:search2).with { |base, scope, filter| filter == "boo" }
- @manager.search("boo")
- end
+ @manager.search("boo")
+ end
- it "should turn its objectclass list into its search filter if one is not specified" do
- @manager.expects(:filter).returns "yay"
- @conn.expects(:search2).with { |base, scope, filter| filter == "yay" }
+ it "should turn its objectclass list into its search filter if one is not specified" do
+ @manager.expects(:filter).returns "yay"
+ @conn.expects(:search2).with { |base, scope, filter| filter == "yay" }
- @manager.search
- end
+ @manager.search
+ end
- it "should return nil if no result is found" do
- @conn.expects(:search2)
+ it "should return nil if no result is found" do
+ @conn.expects(:search2)
- @manager.search.should be_nil
- end
+ @manager.search.should be_nil
+ end
- it "should return an array of the found results converted to provider hashes" do
- # LAK: AFAICT, it's impossible to yield multiple times in an expectation.
- one = {"dn" => "cn=one,dc=madstop,dc=com", "one" => "two"}
- @conn.expects(:search2).yields(one)
+ it "should return an array of the found results converted to provider hashes" do
+ # LAK: AFAICT, it's impossible to yield multiple times in an expectation.
+ one = {"dn" => "cn=one,dc=madstop,dc=com", "one" => "two"}
+ @conn.expects(:search2).yields(one)
- @manager.expects(:entry2provider).with(one).returns "myprov"
+ @manager.expects(:entry2provider).with(one).returns "myprov"
- @manager.search.should == ["myprov"]
- end
- end
+ @manager.search.should == ["myprov"]
+ end
end
+ end
- describe "when an instance" do
- before do
- @name = "myname"
- @manager.maps :one => :uno, :two => :dos, :three => :tres, :four => :quatro
- end
-
- describe "is being updated" do
- it "should get created if the current attribute list is empty and the desired attribute list has :ensure == :present" do
- @manager.expects(:create)
- @manager.update(@name, {}, {:ensure => :present})
- end
-
- it "should get created if the current attribute list has :ensure == :absent and the desired attribute list has :ensure == :present" do
- @manager.expects(:create)
- @manager.update(@name, {:ensure => :absent}, {:ensure => :present})
- end
-
- it "should get deleted if the current attribute list has :ensure == :present and the desired attribute list has :ensure == :absent" do
- @manager.expects(:delete)
- @manager.update(@name, {:ensure => :present}, {:ensure => :absent})
- end
-
- it "should get modified if both attribute lists have :ensure == :present" do
- @manager.expects(:modify)
- @manager.update(@name, {:ensure => :present, :one => :two}, {:ensure => :present, :one => :three})
- end
- end
+ describe "when an instance" do
+ before do
+ @name = "myname"
+ @manager.maps :one => :uno, :two => :dos, :three => :tres, :four => :quatro
+ end
- describe "is being deleted" do
- it "should call the :delete method with its name and manager" do
- @manager.expects(:delete).with(@name)
+ describe "is being updated" do
+ it "should get created if the current attribute list is empty and the desired attribute list has :ensure == :present" do
+ @manager.expects(:create)
+ @manager.update(@name, {}, {:ensure => :present})
+ end
+
+ it "should get created if the current attribute list has :ensure == :absent and the desired attribute list has :ensure == :present" do
+ @manager.expects(:create)
+ @manager.update(@name, {:ensure => :absent}, {:ensure => :present})
+ end
+
+ it "should get deleted if the current attribute list has :ensure == :present and the desired attribute list has :ensure == :absent" do
+ @manager.expects(:delete)
+ @manager.update(@name, {:ensure => :present}, {:ensure => :absent})
+ end
+
+ it "should get modified if both attribute lists have :ensure == :present" do
+ @manager.expects(:modify)
+ @manager.update(@name, {:ensure => :present, :one => :two}, {:ensure => :present, :one => :three})
+ end
+ end
- @manager.update(@name, {}, {:ensure => :absent})
- end
- end
+ describe "is being deleted" do
+ it "should call the :delete method with its name and manager" do
+ @manager.expects(:delete).with(@name)
- describe "is being created" do
- before do
- @is = {}
- @should = {:ensure => :present, :one => :yay, :two => :absent}
- end
-
- it "should call the :create method with its name" do
- @manager.expects(:create).with { |name, attrs| name == @name }
- @manager.update(@name, @is, @should)
- end
-
- it "should call the :create method with its property hash converted to ldap attribute names" do
- @manager.expects(:create).with { |name, attrs| attrs["uno"] == ["yay"] }
- @manager.update(@name, @is, @should)
- end
-
- it "should convert the property names to strings" do
- @manager.expects(:create).with { |name, attrs| attrs["uno"] == ["yay"] }
- @manager.update(@name, @is, @should)
- end
-
- it "should convert the property values to arrays if necessary" do
- @manager.expects(:create).with { |name, attrs| attrs["uno"] == ["yay"] }
- @manager.update(@name, @is, @should)
- end
-
- it "should convert the property values to strings if necessary" do
- @manager.expects(:create).with { |name, attrs| attrs["uno"] == ["yay"] }
- @manager.update(@name, @is, @should)
- end
-
- it "should not include :ensure in the properties sent" do
- @manager.expects(:create).with { |*args| args[1][:ensure].nil? }
- @manager.update(@name, @is, @should)
- end
-
- it "should not include attributes set to :absent in the properties sent" do
- @manager.expects(:create).with { |*args| args[1][:dos].nil? }
- @manager.update(@name, @is, @should)
- end
- end
+ @manager.update(@name, {}, {:ensure => :absent})
+ end
+ end
- describe "is being modified" do
- it "should call the :modify method with its name and an array of LDAP::Mod instances" do
- LDAP::Mod.stubs(:new).returns "whatever"
+ describe "is being created" do
+ before do
+ @is = {}
+ @should = {:ensure => :present, :one => :yay, :two => :absent}
+ end
+
+ it "should call the :create method with its name" do
+ @manager.expects(:create).with { |name, attrs| name == @name }
+ @manager.update(@name, @is, @should)
+ end
+
+ it "should call the :create method with its property hash converted to ldap attribute names" do
+ @manager.expects(:create).with { |name, attrs| attrs["uno"] == ["yay"] }
+ @manager.update(@name, @is, @should)
+ end
+
+ it "should convert the property names to strings" do
+ @manager.expects(:create).with { |name, attrs| attrs["uno"] == ["yay"] }
+ @manager.update(@name, @is, @should)
+ end
+
+ it "should convert the property values to arrays if necessary" do
+ @manager.expects(:create).with { |name, attrs| attrs["uno"] == ["yay"] }
+ @manager.update(@name, @is, @should)
+ end
+
+ it "should convert the property values to strings if necessary" do
+ @manager.expects(:create).with { |name, attrs| attrs["uno"] == ["yay"] }
+ @manager.update(@name, @is, @should)
+ end
+
+ it "should not include :ensure in the properties sent" do
+ @manager.expects(:create).with { |*args| args[1][:ensure].nil? }
+ @manager.update(@name, @is, @should)
+ end
+
+ it "should not include attributes set to :absent in the properties sent" do
+ @manager.expects(:create).with { |*args| args[1][:dos].nil? }
+ @manager.update(@name, @is, @should)
+ end
+ end
- @is = {:one => :yay}
- @should = {:one => :yay, :two => :foo}
+ describe "is being modified" do
+ it "should call the :modify method with its name and an array of LDAP::Mod instances" do
+ LDAP::Mod.stubs(:new).returns "whatever"
- @manager.expects(:modify).with { |name, mods| name == @name }
- @manager.update(@name, @is, @should)
- end
+ @is = {:one => :yay}
+ @should = {:one => :yay, :two => :foo}
- it "should create the LDAP::Mod with the property name converted to the ldap name as a string" do
- @is = {:one => :yay}
- @should = {:one => :yay, :two => :foo}
- mod = mock 'module'
- LDAP::Mod.expects(:new).with { |form, name, value| name == "dos" }.returns mod
+ @manager.expects(:modify).with { |name, mods| name == @name }
+ @manager.update(@name, @is, @should)
+ end
- @manager.stubs(:modify)
+ it "should create the LDAP::Mod with the property name converted to the ldap name as a string" do
+ @is = {:one => :yay}
+ @should = {:one => :yay, :two => :foo}
+ mod = mock 'module'
+ LDAP::Mod.expects(:new).with { |form, name, value| name == "dos" }.returns mod
- @manager.update(@name, @is, @should)
- end
+ @manager.stubs(:modify)
- it "should create an LDAP::Mod instance of type LDAP_MOD_ADD for each attribute being added, with the attribute value converted to a string of arrays" do
- @is = {:one => :yay}
- @should = {:one => :yay, :two => :foo}
- mod = mock 'module'
- LDAP::Mod.expects(:new).with(LDAP::LDAP_MOD_ADD, "dos", ["foo"]).returns mod
+ @manager.update(@name, @is, @should)
+ end
- @manager.stubs(:modify)
+ it "should create an LDAP::Mod instance of type LDAP_MOD_ADD for each attribute being added, with the attribute value converted to a string of arrays" do
+ @is = {:one => :yay}
+ @should = {:one => :yay, :two => :foo}
+ mod = mock 'module'
+ LDAP::Mod.expects(:new).with(LDAP::LDAP_MOD_ADD, "dos", ["foo"]).returns mod
- @manager.update(@name, @is, @should)
- end
+ @manager.stubs(:modify)
- it "should create an LDAP::Mod instance of type LDAP_MOD_DELETE for each attribute being deleted" do
- @is = {:one => :yay, :two => :foo}
- @should = {:one => :yay, :two => :absent}
- mod = mock 'module'
- LDAP::Mod.expects(:new).with(LDAP::LDAP_MOD_DELETE, "dos", []).returns mod
+ @manager.update(@name, @is, @should)
+ end
- @manager.stubs(:modify)
+ it "should create an LDAP::Mod instance of type LDAP_MOD_DELETE for each attribute being deleted" do
+ @is = {:one => :yay, :two => :foo}
+ @should = {:one => :yay, :two => :absent}
+ mod = mock 'module'
+ LDAP::Mod.expects(:new).with(LDAP::LDAP_MOD_DELETE, "dos", []).returns mod
- @manager.update(@name, @is, @should)
- end
+ @manager.stubs(:modify)
- it "should create an LDAP::Mod instance of type LDAP_MOD_REPLACE for each attribute being modified, with the attribute converted to a string of arrays" do
- @is = {:one => :yay, :two => :four}
- @should = {:one => :yay, :two => :five}
- mod = mock 'module'
- LDAP::Mod.expects(:new).with(LDAP::LDAP_MOD_REPLACE, "dos", ["five"]).returns mod
+ @manager.update(@name, @is, @should)
+ end
- @manager.stubs(:modify)
+ it "should create an LDAP::Mod instance of type LDAP_MOD_REPLACE for each attribute being modified, with the attribute converted to a string of arrays" do
+ @is = {:one => :yay, :two => :four}
+ @should = {:one => :yay, :two => :five}
+ mod = mock 'module'
+ LDAP::Mod.expects(:new).with(LDAP::LDAP_MOD_REPLACE, "dos", ["five"]).returns mod
- @manager.update(@name, @is, @should)
- end
+ @manager.stubs(:modify)
- it "should pass all created Mod instances to the modify method" do
- @is = {:one => :yay, :two => :foo, :three => :absent}
- @should = {:one => :yay, :two => :foe, :three => :fee, :four => :fie}
- LDAP::Mod.expects(:new).times(3).returns("mod1").then.returns("mod2").then.returns("mod3")
+ @manager.update(@name, @is, @should)
+ end
- @manager.expects(:modify).with do |name, mods|
- mods.sort == %w{mod1 mod2 mod3}.sort
- end
+ it "should pass all created Mod instances to the modify method" do
+ @is = {:one => :yay, :two => :foo, :three => :absent}
+ @should = {:one => :yay, :two => :foe, :three => :fee, :four => :fie}
+ LDAP::Mod.expects(:new).times(3).returns("mod1").then.returns("mod2").then.returns("mod3")
- @manager.update(@name, @is, @should)
- end
+ @manager.expects(:modify).with do |name, mods|
+ mods.sort == %w{mod1 mod2 mod3}.sort
end
+
+ @manager.update(@name, @is, @should)
+ end
end
+ end
end
diff --git a/spec/unit/util/loadedfile_spec.rb b/spec/unit/util/loadedfile_spec.rb
index 083120e..3bc26a4 100755
--- a/spec/unit/util/loadedfile_spec.rb
+++ b/spec/unit/util/loadedfile_spec.rb
@@ -6,60 +6,60 @@ require 'tempfile'
require 'puppet/util/loadedfile'
describe Puppet::Util::LoadedFile do
- before(:each) do
- @f = Tempfile.new('loadedfile_test')
- @f.puts "yayness"
- @f.flush
+ before(:each) do
+ @f = Tempfile.new('loadedfile_test')
+ @f.puts "yayness"
+ @f.flush
- @loaded = Puppet::Util::LoadedFile.new(@f.path)
+ @loaded = Puppet::Util::LoadedFile.new(@f.path)
- fake_ctime = Time.now - (2 * Puppet[:filetimeout])
- @stat = stub('stat', :ctime => fake_ctime)
- @fake_now = Time.now + (2 * Puppet[:filetimeout])
- end
+ fake_ctime = Time.now - (2 * Puppet[:filetimeout])
+ @stat = stub('stat', :ctime => fake_ctime)
+ @fake_now = Time.now + (2 * Puppet[:filetimeout])
+ end
- it "should recognize when the file has not changed" do
- # Use fake "now" so that we can be sure changed? actually checks, without sleeping
- # for Puppet[:filetimeout] seconds.
- Time.stubs(:now).returns(@fake_now)
- @loaded.changed?.should == false
- end
+ it "should recognize when the file has not changed" do
+ # Use fake "now" so that we can be sure changed? actually checks, without sleeping
+ # for Puppet[:filetimeout] seconds.
+ Time.stubs(:now).returns(@fake_now)
+ @loaded.changed?.should == false
+ end
- it "should recognize when the file has changed" do
- # Fake File.stat so we don't have to depend on the filesystem granularity. Doing a flush()
- # just didn't do the job.
- File.stubs(:stat).returns(@stat)
- # Use fake "now" so that we can be sure changed? actually checks, without sleeping
- # for Puppet[:filetimeout] seconds.
- Time.stubs(:now).returns(@fake_now)
- @loaded.changed?.should be_an_instance_of(Time)
- end
+ it "should recognize when the file has changed" do
+ # Fake File.stat so we don't have to depend on the filesystem granularity. Doing a flush()
+ # just didn't do the job.
+ File.stubs(:stat).returns(@stat)
+ # Use fake "now" so that we can be sure changed? actually checks, without sleeping
+ # for Puppet[:filetimeout] seconds.
+ Time.stubs(:now).returns(@fake_now)
+ @loaded.changed?.should be_an_instance_of(Time)
+ end
- it "should not catch a change until the timeout has elapsed" do
- # Fake File.stat so we don't have to depend on the filesystem granularity. Doing a flush()
- # just didn't do the job.
- File.stubs(:stat).returns(@stat)
- @loaded.changed?.should be(false)
- # Use fake "now" so that we can be sure changed? actually checks, without sleeping
- # for Puppet[:filetimeout] seconds.
- Time.stubs(:now).returns(@fake_now)
- @loaded.changed?.should_not be(false)
- end
+ it "should not catch a change until the timeout has elapsed" do
+ # Fake File.stat so we don't have to depend on the filesystem granularity. Doing a flush()
+ # just didn't do the job.
+ File.stubs(:stat).returns(@stat)
+ @loaded.changed?.should be(false)
+ # Use fake "now" so that we can be sure changed? actually checks, without sleeping
+ # for Puppet[:filetimeout] seconds.
+ Time.stubs(:now).returns(@fake_now)
+ @loaded.changed?.should_not be(false)
+ end
- it "should consider a file changed when that file is missing" do
- @f.close!
- # Use fake "now" so that we can be sure changed? actually checks, without sleeping
- # for Puppet[:filetimeout] seconds.
- Time.stubs(:now).returns(@fake_now)
- @loaded.changed?.should_not be(false)
- end
+ it "should consider a file changed when that file is missing" do
+ @f.close!
+ # Use fake "now" so that we can be sure changed? actually checks, without sleeping
+ # for Puppet[:filetimeout] seconds.
+ Time.stubs(:now).returns(@fake_now)
+ @loaded.changed?.should_not be(false)
+ end
- it "should disable checking if Puppet[:filetimeout] is negative" do
- Puppet[:filetimeout] = -1
- @loaded.changed?.should_not be(false)
- end
+ it "should disable checking if Puppet[:filetimeout] is negative" do
+ Puppet[:filetimeout] = -1
+ @loaded.changed?.should_not be(false)
+ end
- after(:each) do
- @f.close
- end
+ after(:each) do
+ @f.close
+ end
end
diff --git a/spec/unit/util/log/destinations_spec.rb b/spec/unit/util/log/destinations_spec.rb
index b43c757..6596c06 100755
--- a/spec/unit/util/log/destinations_spec.rb
+++ b/spec/unit/util/log/destinations_spec.rb
@@ -5,20 +5,20 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/util/log'
describe Puppet::Util::Log.desttypes[:report] do
- before do
- @dest = Puppet::Util::Log.desttypes[:report]
- end
+ before do
+ @dest = Puppet::Util::Log.desttypes[:report]
+ end
- it "should require a report at initialization" do
- @dest.new("foo").report.should == "foo"
- end
+ it "should require a report at initialization" do
+ @dest.new("foo").report.should == "foo"
+ end
- it "should send new messages to the report" do
- report = mock 'report'
- dest = @dest.new(report)
+ it "should send new messages to the report" do
+ report = mock 'report'
+ dest = @dest.new(report)
- report.expects(:<<).with("my log")
+ report.expects(:<<).with("my log")
- dest.handle "my log"
- end
+ dest.handle "my log"
+ end
end
diff --git a/spec/unit/util/log_spec.rb b/spec/unit/util/log_spec.rb
index b622422..7d96fe1 100755
--- a/spec/unit/util/log_spec.rb
+++ b/spec/unit/util/log_spec.rb
@@ -5,211 +5,211 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
require 'puppet/util/log'
describe Puppet::Util::Log do
- it "should write a given message to the specified destination" do
- arraydest = []
- Puppet::Util::Log.newdestination(arraydest)
- Puppet::Util::Log.new(:level => :notice, :message => "foo")
- message = arraydest.last.message
- message.should == "foo"
+ it "should write a given message to the specified destination" do
+ arraydest = []
+ Puppet::Util::Log.newdestination(arraydest)
+ Puppet::Util::Log.new(:level => :notice, :message => "foo")
+ message = arraydest.last.message
+ message.should == "foo"
+ end
+
+ describe Puppet::Util::Log::DestConsole do
+ before do
+ @console = Puppet::Util::Log::DestConsole.new
end
- describe Puppet::Util::Log::DestConsole do
- before do
- @console = Puppet::Util::Log::DestConsole.new
- end
-
- it "should colorize if Puppet[:color] is :ansi" do
- Puppet[:color] = :ansi
+ it "should colorize if Puppet[:color] is :ansi" do
+ Puppet[:color] = :ansi
- @console.colorize(:alert, "abc").should == "\e[0;31mabc\e[0m"
- end
+ @console.colorize(:alert, "abc").should == "\e[0;31mabc\e[0m"
+ end
- it "should colorize if Puppet[:color] is 'yes'" do
- Puppet[:color] = "yes"
+ it "should colorize if Puppet[:color] is 'yes'" do
+ Puppet[:color] = "yes"
- @console.colorize(:alert, "abc").should == "\e[0;31mabc\e[0m"
- end
+ @console.colorize(:alert, "abc").should == "\e[0;31mabc\e[0m"
+ end
- it "should htmlize if Puppet[:color] is :html" do
- Puppet[:color] = :html
+ it "should htmlize if Puppet[:color] is :html" do
+ Puppet[:color] = :html
- @console.colorize(:alert, "abc").should == "<span style=\"color: FFA0A0\">abc</span>"
- end
+ @console.colorize(:alert, "abc").should == "<span style=\"color: FFA0A0\">abc</span>"
+ end
- it "should do nothing if Puppet[:color] is false" do
- Puppet[:color] = false
+ it "should do nothing if Puppet[:color] is false" do
+ Puppet[:color] = false
- @console.colorize(:alert, "abc").should == "abc"
- end
+ @console.colorize(:alert, "abc").should == "abc"
+ end
- it "should do nothing if Puppet[:color] is invalid" do
- Puppet[:color] = "invalid option"
+ it "should do nothing if Puppet[:color] is invalid" do
+ Puppet[:color] = "invalid option"
- @console.colorize(:alert, "abc").should == "abc"
- end
+ @console.colorize(:alert, "abc").should == "abc"
end
+ end
- describe "instances" do
- before do
- Puppet::Util::Log.stubs(:newmessage)
- end
+ describe "instances" do
+ before do
+ Puppet::Util::Log.stubs(:newmessage)
+ end
- [:level, :message, :time, :remote].each do |attr|
- it "should have a #{attr} attribute" do
- log = Puppet::Util::Log.new :level => :notice, :message => "A test message"
- log.should respond_to(attr)
- log.should respond_to(attr.to_s + "=")
- end
- end
+ [:level, :message, :time, :remote].each do |attr|
+ it "should have a #{attr} attribute" do
+ log = Puppet::Util::Log.new :level => :notice, :message => "A test message"
+ log.should respond_to(attr)
+ log.should respond_to(attr.to_s + "=")
+ end
+ end
- it "should fail if created without a level" do
- lambda { Puppet::Util::Log.new(:message => "A test message") }.should raise_error(ArgumentError)
- end
+ it "should fail if created without a level" do
+ lambda { Puppet::Util::Log.new(:message => "A test message") }.should raise_error(ArgumentError)
+ end
- it "should fail if created without a message" do
- lambda { Puppet::Util::Log.new(:level => :notice) }.should raise_error(ArgumentError)
- end
+ it "should fail if created without a message" do
+ lambda { Puppet::Util::Log.new(:level => :notice) }.should raise_error(ArgumentError)
+ end
- it "should make available the level passed in at initialization" do
- Puppet::Util::Log.new(:level => :notice, :message => "A test message").level.should == :notice
- end
+ it "should make available the level passed in at initialization" do
+ Puppet::Util::Log.new(:level => :notice, :message => "A test message").level.should == :notice
+ end
- it "should make available the message passed in at initialization" do
- Puppet::Util::Log.new(:level => :notice, :message => "A test message").message.should == "A test message"
- end
+ it "should make available the message passed in at initialization" do
+ Puppet::Util::Log.new(:level => :notice, :message => "A test message").message.should == "A test message"
+ end
- # LAK:NOTE I don't know why this behavior is here, I'm just testing what's in the code,
- # at least at first.
- it "should always convert messages to strings" do
- Puppet::Util::Log.new(:level => :notice, :message => :foo).message.should == "foo"
- end
+ # LAK:NOTE I don't know why this behavior is here, I'm just testing what's in the code,
+ # at least at first.
+ it "should always convert messages to strings" do
+ Puppet::Util::Log.new(:level => :notice, :message => :foo).message.should == "foo"
+ end
- it "should flush the log queue when the first destination is specified" do
- Puppet::Util::Log.close_all
- Puppet::Util::Log.expects(:flushqueue)
- Puppet::Util::Log.newdestination([])
- end
+ it "should flush the log queue when the first destination is specified" do
+ Puppet::Util::Log.close_all
+ Puppet::Util::Log.expects(:flushqueue)
+ Puppet::Util::Log.newdestination([])
+ end
- it "should convert the level to a symbol if it's passed in as a string" do
- Puppet::Util::Log.new(:level => "notice", :message => :foo).level.should == :notice
- end
+ it "should convert the level to a symbol if it's passed in as a string" do
+ Puppet::Util::Log.new(:level => "notice", :message => :foo).level.should == :notice
+ end
- it "should fail if the level is not a symbol or string" do
- lambda { Puppet::Util::Log.new(:level => 50, :message => :foo) }.should raise_error(ArgumentError)
- end
+ it "should fail if the level is not a symbol or string" do
+ lambda { Puppet::Util::Log.new(:level => 50, :message => :foo) }.should raise_error(ArgumentError)
+ end
- it "should fail if the provided level is not valid" do
- Puppet::Util::Log.expects(:validlevel?).with(:notice).returns false
- lambda { Puppet::Util::Log.new(:level => :notice, :message => :foo) }.should raise_error(ArgumentError)
- end
+ it "should fail if the provided level is not valid" do
+ Puppet::Util::Log.expects(:validlevel?).with(:notice).returns false
+ lambda { Puppet::Util::Log.new(:level => :notice, :message => :foo) }.should raise_error(ArgumentError)
+ end
- it "should set its time to the initialization time" do
- time = mock 'time'
- Time.expects(:now).returns time
- Puppet::Util::Log.new(:level => "notice", :message => :foo).time.should equal(time)
- end
+ it "should set its time to the initialization time" do
+ time = mock 'time'
+ Time.expects(:now).returns time
+ Puppet::Util::Log.new(:level => "notice", :message => :foo).time.should equal(time)
+ end
- it "should make available any passed-in tags" do
- log = Puppet::Util::Log.new(:level => "notice", :message => :foo, :tags => %w{foo bar})
- log.tags.should be_include("foo")
- log.tags.should be_include("bar")
- end
+ it "should make available any passed-in tags" do
+ log = Puppet::Util::Log.new(:level => "notice", :message => :foo, :tags => %w{foo bar})
+ log.tags.should be_include("foo")
+ log.tags.should be_include("bar")
+ end
- it "should use an passed-in source" do
- Puppet::Util::Log.any_instance.expects(:source=).with "foo"
- Puppet::Util::Log.new(:level => "notice", :message => :foo, :source => "foo")
- end
+ it "should use an passed-in source" do
+ Puppet::Util::Log.any_instance.expects(:source=).with "foo"
+ Puppet::Util::Log.new(:level => "notice", :message => :foo, :source => "foo")
+ end
- [:file, :line, :version].each do |attr|
- it "should use #{attr} if provided" do
- Puppet::Util::Log.any_instance.expects(attr.to_s + "=").with "foo"
- Puppet::Util::Log.new(:level => "notice", :message => :foo, attr => "foo")
- end
- end
+ [:file, :line, :version].each do |attr|
+ it "should use #{attr} if provided" do
+ Puppet::Util::Log.any_instance.expects(attr.to_s + "=").with "foo"
+ Puppet::Util::Log.new(:level => "notice", :message => :foo, attr => "foo")
+ end
+ end
- it "should default to 'Puppet' as its source" do
- Puppet::Util::Log.new(:level => "notice", :message => :foo).source.should == "Puppet"
- end
+ it "should default to 'Puppet' as its source" do
+ Puppet::Util::Log.new(:level => "notice", :message => :foo).source.should == "Puppet"
+ end
- it "should register itself with Log" do
- Puppet::Util::Log.expects(:newmessage)
- Puppet::Util::Log.new(:level => "notice", :message => :foo)
- end
+ it "should register itself with Log" do
+ Puppet::Util::Log.expects(:newmessage)
+ Puppet::Util::Log.new(:level => "notice", :message => :foo)
+ end
- it "should have a method for determining if a tag is present" do
- Puppet::Util::Log.new(:level => "notice", :message => :foo).should respond_to(:tagged?)
- end
+ it "should have a method for determining if a tag is present" do
+ Puppet::Util::Log.new(:level => "notice", :message => :foo).should respond_to(:tagged?)
+ end
- it "should match a tag if any of the tags are equivalent to the passed tag as a string" do
- Puppet::Util::Log.new(:level => "notice", :message => :foo, :tags => %w{one two}).should be_tagged(:one)
- end
+ it "should match a tag if any of the tags are equivalent to the passed tag as a string" do
+ Puppet::Util::Log.new(:level => "notice", :message => :foo, :tags => %w{one two}).should be_tagged(:one)
+ end
- it "should tag itself with its log level" do
- Puppet::Util::Log.new(:level => "notice", :message => :foo).should be_tagged(:notice)
- end
+ it "should tag itself with its log level" do
+ Puppet::Util::Log.new(:level => "notice", :message => :foo).should be_tagged(:notice)
+ end
- it "should return its message when converted to a string" do
- Puppet::Util::Log.new(:level => "notice", :message => :foo).to_s.should == "foo"
- end
+ it "should return its message when converted to a string" do
+ Puppet::Util::Log.new(:level => "notice", :message => :foo).to_s.should == "foo"
+ end
- it "should include its time, source, level, and message when prepared for reporting" do
- log = Puppet::Util::Log.new(:level => "notice", :message => :foo)
- report = log.to_report
- report.should be_include("notice")
- report.should be_include("foo")
- report.should be_include(log.source)
- report.should be_include(log.time.to_s)
- end
+ it "should include its time, source, level, and message when prepared for reporting" do
+ log = Puppet::Util::Log.new(:level => "notice", :message => :foo)
+ report = log.to_report
+ report.should be_include("notice")
+ report.should be_include("foo")
+ report.should be_include(log.source)
+ report.should be_include(log.time.to_s)
+ end
- describe "when setting the source as a RAL object" do
- it "should tag itself with any tags the source has" do
- source = Puppet::Type.type(:file).new :path => "/foo/bar"
- log = Puppet::Util::Log.new(:level => "notice", :message => :foo, :source => source)
- source.tags.each do |tag|
- log.tags.should be_include(tag)
- end
- end
-
- it "should use the source_descriptors" do
- source = stub "source"
- source.stubs(:source_descriptors).returns(:tags => ["tag","tag2"], :path => "path", :version => 100)
-
- log = Puppet::Util::Log.new(:level => "notice", :message => :foo)
- log.expects(:tag).with("tag")
- log.expects(:tag).with("tag2")
- log.expects(:version=).with(100)
-
- log.source = source
-
- log.source.should == "path"
- end
-
- it "should copy over any version information" do
- catalog = Puppet::Resource::Catalog.new
- catalog.version = 25
- source = Puppet::Type.type(:file).new :path => "/foo/bar"
- catalog.add_resource source
-
- log = Puppet::Util::Log.new(:level => "notice", :message => :foo, :source => source)
- log.version.should == 25
- end
-
- it "should copy over any file and line information" do
- source = Puppet::Type.type(:file).new :path => "/foo/bar"
- source.file = "/my/file"
- source.line = 50
- log = Puppet::Util::Log.new(:level => "notice", :message => :foo, :source => source)
- log.file.should == "/my/file"
- log.line.should == 50
- end
- end
+ describe "when setting the source as a RAL object" do
+ it "should tag itself with any tags the source has" do
+ source = Puppet::Type.type(:file).new :path => "/foo/bar"
+ log = Puppet::Util::Log.new(:level => "notice", :message => :foo, :source => source)
+ source.tags.each do |tag|
+ log.tags.should be_include(tag)
+ end
+ end
+
+ it "should use the source_descriptors" do
+ source = stub "source"
+ source.stubs(:source_descriptors).returns(:tags => ["tag","tag2"], :path => "path", :version => 100)
+
+ log = Puppet::Util::Log.new(:level => "notice", :message => :foo)
+ log.expects(:tag).with("tag")
+ log.expects(:tag).with("tag2")
+ log.expects(:version=).with(100)
+
+ log.source = source
+
+ log.source.should == "path"
+ end
+
+ it "should copy over any version information" do
+ catalog = Puppet::Resource::Catalog.new
+ catalog.version = 25
+ source = Puppet::Type.type(:file).new :path => "/foo/bar"
+ catalog.add_resource source
+
+ log = Puppet::Util::Log.new(:level => "notice", :message => :foo, :source => source)
+ log.version.should == 25
+ end
+
+ it "should copy over any file and line information" do
+ source = Puppet::Type.type(:file).new :path => "/foo/bar"
+ source.file = "/my/file"
+ source.line = 50
+ log = Puppet::Util::Log.new(:level => "notice", :message => :foo, :source => source)
+ log.file.should == "/my/file"
+ log.line.should == 50
+ end
+ end
- describe "when setting the source as a non-RAL object" do
- it "should not try to copy over file, version, line, or tag information" do
- source = Puppet::Module.new("foo")
- source.expects(:file).never
- log = Puppet::Util::Log.new(:level => "notice", :message => :foo, :source => source)
- end
- end
+ describe "when setting the source as a non-RAL object" do
+ it "should not try to copy over file, version, line, or tag information" do
+ source = Puppet::Module.new("foo")
+ source.expects(:file).never
+ log = Puppet::Util::Log.new(:level => "notice", :message => :foo, :source => source)
+ end
end
+ end
end
diff --git a/spec/unit/util/logging_spec.rb b/spec/unit/util/logging_spec.rb
index 62a66fc..46ae538 100755
--- a/spec/unit/util/logging_spec.rb
+++ b/spec/unit/util/logging_spec.rb
@@ -5,91 +5,91 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
require 'puppet/util/logging'
class LoggingTester
- include Puppet::Util::Logging
+ include Puppet::Util::Logging
end
describe Puppet::Util::Logging do
- before do
- @logger = LoggingTester.new
- end
+ before do
+ @logger = LoggingTester.new
+ end
- Puppet::Util::Log.eachlevel do |level|
- it "should have a method for sending '#{level}' logs" do
- @logger.should respond_to(level)
- end
+ Puppet::Util::Log.eachlevel do |level|
+ it "should have a method for sending '#{level}' logs" do
+ @logger.should respond_to(level)
end
+ end
- it "should have a method for sending a log with a specified log level" do
- @logger.expects(:to_s).returns "I'm a string!"
- Puppet::Util::Log.expects(:create).with { |args| args[:source] == "I'm a string!" and args[:level] == "loglevel" and args[:message] == "mymessage" }
+ it "should have a method for sending a log with a specified log level" do
+ @logger.expects(:to_s).returns "I'm a string!"
+ Puppet::Util::Log.expects(:create).with { |args| args[:source] == "I'm a string!" and args[:level] == "loglevel" and args[:message] == "mymessage" }
- @logger.send_log "loglevel", "mymessage"
- end
+ @logger.send_log "loglevel", "mymessage"
+ end
- describe "when sending a log" do
- it "should use the Log's 'create' entrance method" do
- Puppet::Util::Log.expects(:create)
+ describe "when sending a log" do
+ it "should use the Log's 'create' entrance method" do
+ Puppet::Util::Log.expects(:create)
- @logger.notice "foo"
- end
+ @logger.notice "foo"
+ end
- it "should send itself converted to a string as the log source" do
- @logger.expects(:to_s).returns "I'm a string!"
- Puppet::Util::Log.expects(:create).with { |args| args[:source] == "I'm a string!" }
+ it "should send itself converted to a string as the log source" do
+ @logger.expects(:to_s).returns "I'm a string!"
+ Puppet::Util::Log.expects(:create).with { |args| args[:source] == "I'm a string!" }
- @logger.notice "foo"
- end
+ @logger.notice "foo"
+ end
- it "should queue logs sent without a specified destination" do
- Puppet::Util::Log.close_all
- Puppet::Util::Log.expects(:queuemessage)
+ it "should queue logs sent without a specified destination" do
+ Puppet::Util::Log.close_all
+ Puppet::Util::Log.expects(:queuemessage)
- @logger.notice "foo"
- end
+ @logger.notice "foo"
+ end
- it "should use the path of any provided resource type" do
- resource = Puppet::Type.type(:mount).new :name => "foo"
+ it "should use the path of any provided resource type" do
+ resource = Puppet::Type.type(:mount).new :name => "foo"
- resource.expects(:path).returns "/path/to/mount".to_sym
+ resource.expects(:path).returns "/path/to/mount".to_sym
- Puppet::Util::Log.expects(:create).with { |args| args[:source] == "/path/to/mount" }
+ Puppet::Util::Log.expects(:create).with { |args| args[:source] == "/path/to/mount" }
- resource.notice "foo"
- end
+ resource.notice "foo"
+ end
- it "should use the path of any provided resource parameter" do
- resource = Puppet::Type.type(:mount).new :name => "foo"
+ it "should use the path of any provided resource parameter" do
+ resource = Puppet::Type.type(:mount).new :name => "foo"
- param = resource.parameter(:name)
+ param = resource.parameter(:name)
- param.expects(:path).returns "/path/to/param".to_sym
+ param.expects(:path).returns "/path/to/param".to_sym
- Puppet::Util::Log.expects(:create).with { |args| args[:source] == "/path/to/param" }
+ Puppet::Util::Log.expects(:create).with { |args| args[:source] == "/path/to/param" }
- param.notice "foo"
- end
+ param.notice "foo"
+ end
- it "should send the provided argument as the log message" do
- Puppet::Util::Log.expects(:create).with { |args| args[:message] == "foo" }
+ it "should send the provided argument as the log message" do
+ Puppet::Util::Log.expects(:create).with { |args| args[:message] == "foo" }
- @logger.notice "foo"
- end
+ @logger.notice "foo"
+ end
- it "should join any provided arguments into a single string for the message" do
- Puppet::Util::Log.expects(:create).with { |args| args[:message] == "foo bar baz" }
+ it "should join any provided arguments into a single string for the message" do
+ Puppet::Util::Log.expects(:create).with { |args| args[:message] == "foo bar baz" }
- @logger.notice ["foo", "bar", "baz"]
- end
+ @logger.notice ["foo", "bar", "baz"]
+ end
- [:file, :line, :version, :tags].each do |attr|
- it "should include #{attr} if available" do
- @logger.singleton_class.send(:attr_accessor, attr)
+ [:file, :line, :version, :tags].each do |attr|
+ it "should include #{attr} if available" do
+ @logger.singleton_class.send(:attr_accessor, attr)
- @logger.send(attr.to_s + "=", "myval")
+ @logger.send(attr.to_s + "=", "myval")
- Puppet::Util::Log.expects(:create).with { |args| args[attr] == "myval" }
- @logger.notice "foo"
- end
- end
+ Puppet::Util::Log.expects(:create).with { |args| args[attr] == "myval" }
+ @logger.notice "foo"
+ end
end
+ end
end
diff --git a/spec/unit/util/metric_spec.rb b/spec/unit/util/metric_spec.rb
index 41ab4cc..72571ee 100755
--- a/spec/unit/util/metric_spec.rb
+++ b/spec/unit/util/metric_spec.rb
@@ -5,91 +5,91 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
require 'puppet/util/metric'
describe Puppet::Util::Metric do
- before do
- @metric = Puppet::Util::Metric.new("foo")
- end
+ before do
+ @metric = Puppet::Util::Metric.new("foo")
+ end
- it "should be aliased to Puppet::Metric" do
- Puppet::Util::Metric.should equal(Puppet::Metric)
- end
+ it "should be aliased to Puppet::Metric" do
+ Puppet::Util::Metric.should equal(Puppet::Metric)
+ end
- [:type, :name, :value, :label, :basedir].each do |name|
- it "should have a #{name} attribute" do
- @metric.should respond_to(name)
- @metric.should respond_to(name.to_s + "=")
- end
+ [:type, :name, :value, :label, :basedir].each do |name|
+ it "should have a #{name} attribute" do
+ @metric.should respond_to(name)
+ @metric.should respond_to(name.to_s + "=")
end
+ end
- it "should default to the :rrdir as the basedir "do
- Puppet.settings.expects(:value).with(:rrddir).returns "myrrd"
- @metric.basedir.should == "myrrd"
- end
+ it "should default to the :rrdir as the basedir "do
+ Puppet.settings.expects(:value).with(:rrddir).returns "myrrd"
+ @metric.basedir.should == "myrrd"
+ end
- it "should use any provided basedir" do
- @metric.basedir = "foo"
- @metric.basedir.should == "foo"
- end
+ it "should use any provided basedir" do
+ @metric.basedir = "foo"
+ @metric.basedir.should == "foo"
+ end
- it "should require a name at initialization" do
- lambda { Puppet::Util::Metric.new }.should raise_error(ArgumentError)
- end
+ it "should require a name at initialization" do
+ lambda { Puppet::Util::Metric.new }.should raise_error(ArgumentError)
+ end
- it "should always convert its name to a string" do
- Puppet::Util::Metric.new(:foo).name.should == "foo"
- end
+ it "should always convert its name to a string" do
+ Puppet::Util::Metric.new(:foo).name.should == "foo"
+ end
- it "should support a label" do
- Puppet::Util::Metric.new("foo", "mylabel").label.should == "mylabel"
- end
+ it "should support a label" do
+ Puppet::Util::Metric.new("foo", "mylabel").label.should == "mylabel"
+ end
- it "should autogenerate a label if none is provided" do
- Puppet::Util::Metric.new("foo_bar").label.should == "Foo bar"
- end
+ it "should autogenerate a label if none is provided" do
+ Puppet::Util::Metric.new("foo_bar").label.should == "Foo bar"
+ end
- it "should have a method for adding values" do
- @metric.should respond_to(:newvalue)
- end
+ it "should have a method for adding values" do
+ @metric.should respond_to(:newvalue)
+ end
- it "should have a method for returning values" do
- @metric.should respond_to(:values)
- end
+ it "should have a method for returning values" do
+ @metric.should respond_to(:values)
+ end
- it "should require a name and value for its values" do
- lambda { @metric.newvalue }.should raise_error(ArgumentError)
- end
+ it "should require a name and value for its values" do
+ lambda { @metric.newvalue }.should raise_error(ArgumentError)
+ end
- it "should support a label for values" do
- @metric.newvalue(:foo, 10, "label")
- @metric.values[0][1].should == "label"
- end
+ it "should support a label for values" do
+ @metric.newvalue(:foo, 10, "label")
+ @metric.values[0][1].should == "label"
+ end
- it "should autogenerate value labels if none is provided" do
- @metric.newvalue("foo_bar", 10)
- @metric.values[0][1].should == "Foo bar"
- end
+ it "should autogenerate value labels if none is provided" do
+ @metric.newvalue("foo_bar", 10)
+ @metric.values[0][1].should == "Foo bar"
+ end
- it "should return its values sorted by label" do
- @metric.newvalue(:foo, 10, "b")
- @metric.newvalue(:bar, 10, "a")
+ it "should return its values sorted by label" do
+ @metric.newvalue(:foo, 10, "b")
+ @metric.newvalue(:bar, 10, "a")
- @metric.values.should == [[:bar, "a", 10], [:foo, "b", 10]]
- end
+ @metric.values.should == [[:bar, "a", 10], [:foo, "b", 10]]
+ end
- it "should use an array indexer method to retrieve individual values" do
- @metric.newvalue(:foo, 10)
- @metric[:foo].should == 10
- end
+ it "should use an array indexer method to retrieve individual values" do
+ @metric.newvalue(:foo, 10)
+ @metric[:foo].should == 10
+ end
- it "should return nil if the named value cannot be found" do
- @metric[:foo].should == 0
- end
+ it "should return nil if the named value cannot be found" do
+ @metric[:foo].should == 0
+ end
- # LAK: I'm not taking the time to develop these tests right now.
- # I expect they should actually be extracted into a separate class
- # anyway.
- it "should be able to graph metrics using RRDTool"
+ # LAK: I'm not taking the time to develop these tests right now.
+ # I expect they should actually be extracted into a separate class
+ # anyway.
+ it "should be able to graph metrics using RRDTool"
- it "should be able to create a new RRDTool database"
+ it "should be able to create a new RRDTool database"
- it "should be able to store metrics into an RRDTool database"
+ it "should be able to store metrics into an RRDTool database"
end
diff --git a/spec/unit/util/nagios_maker_spec.rb b/spec/unit/util/nagios_maker_spec.rb
index 1e1aefc..5cda987 100755
--- a/spec/unit/util/nagios_maker_spec.rb
+++ b/spec/unit/util/nagios_maker_spec.rb
@@ -8,119 +8,119 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/util/nagios_maker'
describe Puppet::Util::NagiosMaker do
- before do
- @module = Puppet::Util::NagiosMaker
+ before do
+ @module = Puppet::Util::NagiosMaker
- @nagtype = stub 'nagios type', :parameters => [], :namevar => :name
- Nagios::Base.stubs(:type).with(:test).returns(@nagtype)
+ @nagtype = stub 'nagios type', :parameters => [], :namevar => :name
+ Nagios::Base.stubs(:type).with(:test).returns(@nagtype)
- @provider = stub 'provider', :nagios_type => nil
- @type = stub 'type', :newparam => nil, :newproperty => nil, :provide => @provider, :desc => nil, :ensurable => nil
- end
+ @provider = stub 'provider', :nagios_type => nil
+ @type = stub 'type', :newparam => nil, :newproperty => nil, :provide => @provider, :desc => nil, :ensurable => nil
+ end
- it "should be able to create a new nagios type" do
- @module.should respond_to(:create_nagios_type)
- end
+ it "should be able to create a new nagios type" do
+ @module.should respond_to(:create_nagios_type)
+ end
- it "should fail if it cannot find the named Naginator type" do
- Nagios::Base.stubs(:type).returns(nil)
+ it "should fail if it cannot find the named Naginator type" do
+ Nagios::Base.stubs(:type).returns(nil)
- lambda { @module.create_nagios_type(:no_such_type) }.should raise_error(Puppet::DevError)
- end
+ lambda { @module.create_nagios_type(:no_such_type) }.should raise_error(Puppet::DevError)
+ end
- it "should create a new RAL type with the provided name prefixed with 'nagios_'" do
- Puppet::Type.expects(:newtype).with(:nagios_test).returns(@type)
- @module.create_nagios_type(:test)
- end
+ it "should create a new RAL type with the provided name prefixed with 'nagios_'" do
+ Puppet::Type.expects(:newtype).with(:nagios_test).returns(@type)
+ @module.create_nagios_type(:test)
+ end
- it "should mark the created type as ensurable" do
- @type.expects(:ensurable)
+ it "should mark the created type as ensurable" do
+ @type.expects(:ensurable)
- Puppet::Type.expects(:newtype).with(:nagios_test).returns(@type)
- @module.create_nagios_type(:test)
- end
+ Puppet::Type.expects(:newtype).with(:nagios_test).returns(@type)
+ @module.create_nagios_type(:test)
+ end
- it "should create a namevar parameter for the nagios type's name parameter" do
- @type.expects(:newparam).with(:name, :namevar => true)
+ it "should create a namevar parameter for the nagios type's name parameter" do
+ @type.expects(:newparam).with(:name, :namevar => true)
- Puppet::Type.expects(:newtype).with(:nagios_test).returns(@type)
- @module.create_nagios_type(:test)
- end
+ Puppet::Type.expects(:newtype).with(:nagios_test).returns(@type)
+ @module.create_nagios_type(:test)
+ end
- it "should create a property for all non-namevar parameters" do
- @nagtype.stubs(:parameters).returns([:one, :two])
+ it "should create a property for all non-namevar parameters" do
+ @nagtype.stubs(:parameters).returns([:one, :two])
- @type.expects(:newproperty).with(:one)
- @type.expects(:newproperty).with(:two)
- @type.expects(:newproperty).with(:target)
+ @type.expects(:newproperty).with(:one)
+ @type.expects(:newproperty).with(:two)
+ @type.expects(:newproperty).with(:target)
- Puppet::Type.expects(:newtype).with(:nagios_test).returns(@type)
- @module.create_nagios_type(:test)
- end
+ Puppet::Type.expects(:newtype).with(:nagios_test).returns(@type)
+ @module.create_nagios_type(:test)
+ end
- it "should skip parameters that start with integers" do
- @nagtype.stubs(:parameters).returns(["2dcoords".to_sym, :other])
+ it "should skip parameters that start with integers" do
+ @nagtype.stubs(:parameters).returns(["2dcoords".to_sym, :other])
- @type.expects(:newproperty).with(:other)
- @type.expects(:newproperty).with(:target)
+ @type.expects(:newproperty).with(:other)
+ @type.expects(:newproperty).with(:target)
- Puppet::Type.expects(:newtype).with(:nagios_test).returns(@type)
- @module.create_nagios_type(:test)
- end
+ Puppet::Type.expects(:newtype).with(:nagios_test).returns(@type)
+ @module.create_nagios_type(:test)
+ end
- it "should deduplicate the parameter list" do
- @nagtype.stubs(:parameters).returns([:one, :one])
+ it "should deduplicate the parameter list" do
+ @nagtype.stubs(:parameters).returns([:one, :one])
- @type.expects(:newproperty).with(:one)
- @type.expects(:newproperty).with(:target)
+ @type.expects(:newproperty).with(:one)
+ @type.expects(:newproperty).with(:target)
- Puppet::Type.expects(:newtype).with(:nagios_test).returns(@type)
- @module.create_nagios_type(:test)
- end
+ Puppet::Type.expects(:newtype).with(:nagios_test).returns(@type)
+ @module.create_nagios_type(:test)
+ end
- it "should create a target property" do
- @type.expects(:newproperty).with(:target)
+ it "should create a target property" do
+ @type.expects(:newproperty).with(:target)
- Puppet::Type.expects(:newtype).with(:nagios_test).returns(@type)
- @module.create_nagios_type(:test)
- end
+ Puppet::Type.expects(:newtype).with(:nagios_test).returns(@type)
+ @module.create_nagios_type(:test)
+ end
end
describe Puppet::Util::NagiosMaker, " when creating the naginator provider" do
- before do
- @module = Puppet::Util::NagiosMaker
- @provider = stub 'provider', :nagios_type => nil
+ before do
+ @module = Puppet::Util::NagiosMaker
+ @provider = stub 'provider', :nagios_type => nil
- @nagtype = stub 'nagios type', :parameters => [], :namevar => :name
- Nagios::Base.stubs(:type).with(:test).returns(@nagtype)
+ @nagtype = stub 'nagios type', :parameters => [], :namevar => :name
+ Nagios::Base.stubs(:type).with(:test).returns(@nagtype)
- @type = stub 'type', :newparam => nil, :ensurable => nil, :newproperty => nil, :desc => nil
- Puppet::Type.stubs(:newtype).with(:nagios_test).returns(@type)
- end
+ @type = stub 'type', :newparam => nil, :ensurable => nil, :newproperty => nil, :desc => nil
+ Puppet::Type.stubs(:newtype).with(:nagios_test).returns(@type)
+ end
- it "should add a naginator provider" do
- @type.expects(:provide).with { |name, options| name == :naginator }.returns @provider
+ it "should add a naginator provider" do
+ @type.expects(:provide).with { |name, options| name == :naginator }.returns @provider
- @module.create_nagios_type(:test)
- end
+ @module.create_nagios_type(:test)
+ end
- it "should set Puppet::Provider::Naginator as the parent class of the provider" do
- @type.expects(:provide).with { |name, options| options[:parent] == Puppet::Provider::Naginator }.returns @provider
+ it "should set Puppet::Provider::Naginator as the parent class of the provider" do
+ @type.expects(:provide).with { |name, options| options[:parent] == Puppet::Provider::Naginator }.returns @provider
- @module.create_nagios_type(:test)
- end
+ @module.create_nagios_type(:test)
+ end
- it "should use /etc/nagios/$name.cfg as the default target" do
- @type.expects(:provide).with { |name, options| options[:default_target] == "/etc/nagios/nagios_test.cfg" }.returns @provider
+ it "should use /etc/nagios/$name.cfg as the default target" do
+ @type.expects(:provide).with { |name, options| options[:default_target] == "/etc/nagios/nagios_test.cfg" }.returns @provider
- @module.create_nagios_type(:test)
- end
+ @module.create_nagios_type(:test)
+ end
- it "should trigger the lookup of the Nagios class" do
- @type.expects(:provide).returns @provider
+ it "should trigger the lookup of the Nagios class" do
+ @type.expects(:provide).returns @provider
- @provider.expects(:nagios_type)
+ @provider.expects(:nagios_type)
- @module.create_nagios_type(:test)
- end
+ @module.create_nagios_type(:test)
+ end
end
diff --git a/spec/unit/util/package_spec.rb b/spec/unit/util/package_spec.rb
index 45eef46..09b2221 100644
--- a/spec/unit/util/package_spec.rb
+++ b/spec/unit/util/package_spec.rb
@@ -6,16 +6,16 @@ require 'puppet/util/package'
describe Puppet::Util::Package, " versioncmp" do
- it "should be able to be used as a module function" do
- Puppet::Util::Package.should respond_to(:versioncmp)
- end
+ it "should be able to be used as a module function" do
+ Puppet::Util::Package.should respond_to(:versioncmp)
+ end
- it "should be able to sort a long set of various unordered versions" do
- ary = %w{ 1.1.6 2.3 1.1a 3.0 1.5 1 2.4 1.1-4 2.3.1 1.2 2.3.0 1.1-3 2.4b 2.4 2.40.2 2.3a.1 3.1 0002 1.1-5 1.1.a 1.06}
+ it "should be able to sort a long set of various unordered versions" do
+ ary = %w{ 1.1.6 2.3 1.1a 3.0 1.5 1 2.4 1.1-4 2.3.1 1.2 2.3.0 1.1-3 2.4b 2.4 2.40.2 2.3a.1 3.1 0002 1.1-5 1.1.a 1.06}
- newary = ary.sort { |a, b| Puppet::Util::Package.versioncmp(a,b) }
+ newary = ary.sort { |a, b| Puppet::Util::Package.versioncmp(a,b) }
- newary.should == ["0002", "1", "1.06", "1.1-3", "1.1-4", "1.1-5", "1.1.6", "1.1.a", "1.1a", "1.2", "1.5", "2.3", "2.3.0", "2.3.1", "2.3a.1", "2.4", "2.4", "2.4b", "2.40.2", "3.0", "3.1"]
- end
+ newary.should == ["0002", "1", "1.06", "1.1-3", "1.1-4", "1.1-5", "1.1.6", "1.1.a", "1.1a", "1.2", "1.5", "2.3", "2.3.0", "2.3.1", "2.3a.1", "2.4", "2.4", "2.4b", "2.40.2", "3.0", "3.1"]
+ end
end
diff --git a/spec/unit/util/posix_spec.rb b/spec/unit/util/posix_spec.rb
index 33aa4a6..dbc90d9 100755
--- a/spec/unit/util/posix_spec.rb
+++ b/spec/unit/util/posix_spec.rb
@@ -5,252 +5,252 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
require 'puppet/util/posix'
class PosixTest
- include Puppet::Util::POSIX
+ include Puppet::Util::POSIX
end
describe Puppet::Util::POSIX do
- before do
- @posix = PosixTest.new
- end
+ before do
+ @posix = PosixTest.new
+ end
- [:group, :gr].each do |name|
- it "should return :gid as the field for #{name}" do
- @posix.idfield(name).should == :gid
- end
+ [:group, :gr].each do |name|
+ it "should return :gid as the field for #{name}" do
+ @posix.idfield(name).should == :gid
+ end
- it "should return :getgrgid as the id method for #{name}" do
- @posix.methodbyid(name).should == :getgrgid
- end
+ it "should return :getgrgid as the id method for #{name}" do
+ @posix.methodbyid(name).should == :getgrgid
+ end
- it "should return :getgrnam as the name method for #{name}" do
- @posix.methodbyname(name).should == :getgrnam
- end
+ it "should return :getgrnam as the name method for #{name}" do
+ @posix.methodbyname(name).should == :getgrnam
end
+ end
- [:user, :pw, :passwd].each do |name|
- it "should return :uid as the field for #{name}" do
- @posix.idfield(name).should == :uid
- end
+ [:user, :pw, :passwd].each do |name|
+ it "should return :uid as the field for #{name}" do
+ @posix.idfield(name).should == :uid
+ end
- it "should return :getpwuid as the id method for #{name}" do
- @posix.methodbyid(name).should == :getpwuid
- end
+ it "should return :getpwuid as the id method for #{name}" do
+ @posix.methodbyid(name).should == :getpwuid
+ end
- it "should return :getpwnam as the name method for #{name}" do
- @posix.methodbyname(name).should == :getpwnam
- end
+ it "should return :getpwnam as the name method for #{name}" do
+ @posix.methodbyname(name).should == :getpwnam
end
+ end
- describe "when retrieving a posix field" do
- before do
- @thing = stub 'thing', :field => "asdf"
- end
+ describe "when retrieving a posix field" do
+ before do
+ @thing = stub 'thing', :field => "asdf"
+ end
- it "should fail if no id was passed" do
- lambda { @posix.get_posix_field("asdf", "bar", nil) }.should raise_error(Puppet::DevError)
- end
+ it "should fail if no id was passed" do
+ lambda { @posix.get_posix_field("asdf", "bar", nil) }.should raise_error(Puppet::DevError)
+ end
- describe "and the id is an integer" do
- it "should log an error and return nil if the specified id is greater than the maximum allowed ID" do
- Puppet.settings.expects(:value).with(:maximum_uid).returns 100
- Puppet.expects(:err)
+ describe "and the id is an integer" do
+ it "should log an error and return nil if the specified id is greater than the maximum allowed ID" do
+ Puppet.settings.expects(:value).with(:maximum_uid).returns 100
+ Puppet.expects(:err)
- @posix.get_posix_field("asdf", "bar", 200).should be_nil
- end
+ @posix.get_posix_field("asdf", "bar", 200).should be_nil
+ end
- it "should use the method return by :methodbyid and return the specified field" do
- Etc.expects(:getgrgid).returns @thing
+ it "should use the method return by :methodbyid and return the specified field" do
+ Etc.expects(:getgrgid).returns @thing
- @thing.expects(:field).returns "myval"
+ @thing.expects(:field).returns "myval"
- @posix.get_posix_field(:gr, :field, 200).should == "myval"
- end
+ @posix.get_posix_field(:gr, :field, 200).should == "myval"
+ end
- it "should return nil if the method throws an exception" do
- Etc.expects(:getgrgid).raises ArgumentError
+ it "should return nil if the method throws an exception" do
+ Etc.expects(:getgrgid).raises ArgumentError
- @thing.expects(:field).never
+ @thing.expects(:field).never
- @posix.get_posix_field(:gr, :field, 200).should be_nil
- end
- end
+ @posix.get_posix_field(:gr, :field, 200).should be_nil
+ end
+ end
- describe "and the id is not an integer" do
- it "should use the method return by :methodbyid and return the specified field" do
- Etc.expects(:getgrnam).returns @thing
+ describe "and the id is not an integer" do
+ it "should use the method return by :methodbyid and return the specified field" do
+ Etc.expects(:getgrnam).returns @thing
- @thing.expects(:field).returns "myval"
+ @thing.expects(:field).returns "myval"
- @posix.get_posix_field(:gr, :field, "asdf").should == "myval"
- end
+ @posix.get_posix_field(:gr, :field, "asdf").should == "myval"
+ end
- it "should return nil if the method throws an exception" do
- Etc.expects(:getgrnam).raises ArgumentError
+ it "should return nil if the method throws an exception" do
+ Etc.expects(:getgrnam).raises ArgumentError
- @thing.expects(:field).never
+ @thing.expects(:field).never
- @posix.get_posix_field(:gr, :field, "asdf").should be_nil
- end
- end
+ @posix.get_posix_field(:gr, :field, "asdf").should be_nil
+ end
end
+ end
- describe "when returning the gid" do
- before do
- @posix.stubs(:get_posix_field)
- end
+ describe "when returning the gid" do
+ before do
+ @posix.stubs(:get_posix_field)
+ end
- describe "and the group is an integer" do
- it "should convert integers specified as a string into an integer" do
- @posix.expects(:get_posix_field).with(:group, :name, 100)
+ describe "and the group is an integer" do
+ it "should convert integers specified as a string into an integer" do
+ @posix.expects(:get_posix_field).with(:group, :name, 100)
- @posix.gid("100")
- end
+ @posix.gid("100")
+ end
- it "should look up the name for the group" do
- @posix.expects(:get_posix_field).with(:group, :name, 100)
+ it "should look up the name for the group" do
+ @posix.expects(:get_posix_field).with(:group, :name, 100)
- @posix.gid(100)
- end
+ @posix.gid(100)
+ end
- it "should return nil if the group cannot be found" do
- @posix.expects(:get_posix_field).once.returns nil
- @posix.expects(:search_posix_field).never
+ it "should return nil if the group cannot be found" do
+ @posix.expects(:get_posix_field).once.returns nil
+ @posix.expects(:search_posix_field).never
- @posix.gid(100).should be_nil
- end
+ @posix.gid(100).should be_nil
+ end
- it "should use the found name to look up the id" do
- @posix.expects(:get_posix_field).with(:group, :name, 100).returns "asdf"
- @posix.expects(:get_posix_field).with(:group, :gid, "asdf").returns 100
+ it "should use the found name to look up the id" do
+ @posix.expects(:get_posix_field).with(:group, :name, 100).returns "asdf"
+ @posix.expects(:get_posix_field).with(:group, :gid, "asdf").returns 100
- @posix.gid(100).should == 100
- end
+ @posix.gid(100).should == 100
+ end
- # LAK: This is because some platforms have a broken Etc module that always return
- # the same group.
- it "should use :search_posix_field if the discovered id does not match the passed-in id" do
- @posix.expects(:get_posix_field).with(:group, :name, 100).returns "asdf"
- @posix.expects(:get_posix_field).with(:group, :gid, "asdf").returns 50
+ # LAK: This is because some platforms have a broken Etc module that always return
+ # the same group.
+ it "should use :search_posix_field if the discovered id does not match the passed-in id" do
+ @posix.expects(:get_posix_field).with(:group, :name, 100).returns "asdf"
+ @posix.expects(:get_posix_field).with(:group, :gid, "asdf").returns 50
- @posix.expects(:search_posix_field).with(:group, :gid, 100).returns "asdf"
+ @posix.expects(:search_posix_field).with(:group, :gid, 100).returns "asdf"
- @posix.gid(100).should == "asdf"
- end
- end
+ @posix.gid(100).should == "asdf"
+ end
+ end
- describe "and the group is a string" do
- it "should look up the gid for the group" do
- @posix.expects(:get_posix_field).with(:group, :gid, "asdf")
+ describe "and the group is a string" do
+ it "should look up the gid for the group" do
+ @posix.expects(:get_posix_field).with(:group, :gid, "asdf")
- @posix.gid("asdf")
- end
+ @posix.gid("asdf")
+ end
- it "should return nil if the group cannot be found" do
- @posix.expects(:get_posix_field).once.returns nil
- @posix.expects(:search_posix_field).never
+ it "should return nil if the group cannot be found" do
+ @posix.expects(:get_posix_field).once.returns nil
+ @posix.expects(:search_posix_field).never
- @posix.gid("asdf").should be_nil
- end
+ @posix.gid("asdf").should be_nil
+ end
- it "should use the found gid to look up the nam" do
- @posix.expects(:get_posix_field).with(:group, :gid, "asdf").returns 100
- @posix.expects(:get_posix_field).with(:group, :name, 100).returns "asdf"
+ it "should use the found gid to look up the nam" do
+ @posix.expects(:get_posix_field).with(:group, :gid, "asdf").returns 100
+ @posix.expects(:get_posix_field).with(:group, :name, 100).returns "asdf"
- @posix.gid("asdf").should == 100
- end
+ @posix.gid("asdf").should == 100
+ end
- it "should use :search_posix_field if the discovered name does not match the passed-in name" do
- @posix.expects(:get_posix_field).with(:group, :gid, "asdf").returns 100
- @posix.expects(:get_posix_field).with(:group, :name, 100).returns "boo"
+ it "should use :search_posix_field if the discovered name does not match the passed-in name" do
+ @posix.expects(:get_posix_field).with(:group, :gid, "asdf").returns 100
+ @posix.expects(:get_posix_field).with(:group, :name, 100).returns "boo"
- @posix.expects(:search_posix_field).with(:group, :gid, "asdf").returns "asdf"
+ @posix.expects(:search_posix_field).with(:group, :gid, "asdf").returns "asdf"
- @posix.gid("asdf").should == "asdf"
- end
- end
+ @posix.gid("asdf").should == "asdf"
+ end
end
+ end
- describe "when returning the uid" do
- before do
- @posix.stubs(:get_posix_field)
- end
+ describe "when returning the uid" do
+ before do
+ @posix.stubs(:get_posix_field)
+ end
- describe "and the group is an integer" do
- it "should convert integers specified as a string into an integer" do
- @posix.expects(:get_posix_field).with(:passwd, :name, 100)
+ describe "and the group is an integer" do
+ it "should convert integers specified as a string into an integer" do
+ @posix.expects(:get_posix_field).with(:passwd, :name, 100)
- @posix.uid("100")
- end
+ @posix.uid("100")
+ end
- it "should look up the name for the group" do
- @posix.expects(:get_posix_field).with(:passwd, :name, 100)
+ it "should look up the name for the group" do
+ @posix.expects(:get_posix_field).with(:passwd, :name, 100)
- @posix.uid(100)
- end
+ @posix.uid(100)
+ end
- it "should return nil if the group cannot be found" do
- @posix.expects(:get_posix_field).once.returns nil
- @posix.expects(:search_posix_field).never
+ it "should return nil if the group cannot be found" do
+ @posix.expects(:get_posix_field).once.returns nil
+ @posix.expects(:search_posix_field).never
- @posix.uid(100).should be_nil
- end
+ @posix.uid(100).should be_nil
+ end
- it "should use the found name to look up the id" do
- @posix.expects(:get_posix_field).with(:passwd, :name, 100).returns "asdf"
- @posix.expects(:get_posix_field).with(:passwd, :uid, "asdf").returns 100
+ it "should use the found name to look up the id" do
+ @posix.expects(:get_posix_field).with(:passwd, :name, 100).returns "asdf"
+ @posix.expects(:get_posix_field).with(:passwd, :uid, "asdf").returns 100
- @posix.uid(100).should == 100
- end
+ @posix.uid(100).should == 100
+ end
- # LAK: This is because some platforms have a broken Etc module that always return
- # the same group.
- it "should use :search_posix_field if the discovered id does not match the passed-in id" do
- @posix.expects(:get_posix_field).with(:passwd, :name, 100).returns "asdf"
- @posix.expects(:get_posix_field).with(:passwd, :uid, "asdf").returns 50
+ # LAK: This is because some platforms have a broken Etc module that always return
+ # the same group.
+ it "should use :search_posix_field if the discovered id does not match the passed-in id" do
+ @posix.expects(:get_posix_field).with(:passwd, :name, 100).returns "asdf"
+ @posix.expects(:get_posix_field).with(:passwd, :uid, "asdf").returns 50
- @posix.expects(:search_posix_field).with(:passwd, :uid, 100).returns "asdf"
+ @posix.expects(:search_posix_field).with(:passwd, :uid, 100).returns "asdf"
- @posix.uid(100).should == "asdf"
- end
- end
+ @posix.uid(100).should == "asdf"
+ end
+ end
- describe "and the group is a string" do
- it "should look up the uid for the group" do
- @posix.expects(:get_posix_field).with(:passwd, :uid, "asdf")
+ describe "and the group is a string" do
+ it "should look up the uid for the group" do
+ @posix.expects(:get_posix_field).with(:passwd, :uid, "asdf")
- @posix.uid("asdf")
- end
+ @posix.uid("asdf")
+ end
- it "should return nil if the group cannot be found" do
- @posix.expects(:get_posix_field).once.returns nil
- @posix.expects(:search_posix_field).never
+ it "should return nil if the group cannot be found" do
+ @posix.expects(:get_posix_field).once.returns nil
+ @posix.expects(:search_posix_field).never
- @posix.uid("asdf").should be_nil
- end
+ @posix.uid("asdf").should be_nil
+ end
- it "should use the found uid to look up the nam" do
- @posix.expects(:get_posix_field).with(:passwd, :uid, "asdf").returns 100
- @posix.expects(:get_posix_field).with(:passwd, :name, 100).returns "asdf"
+ it "should use the found uid to look up the nam" do
+ @posix.expects(:get_posix_field).with(:passwd, :uid, "asdf").returns 100
+ @posix.expects(:get_posix_field).with(:passwd, :name, 100).returns "asdf"
- @posix.uid("asdf").should == 100
- end
+ @posix.uid("asdf").should == 100
+ end
- it "should use :search_posix_field if the discovered name does not match the passed-in name" do
- @posix.expects(:get_posix_field).with(:passwd, :uid, "asdf").returns 100
- @posix.expects(:get_posix_field).with(:passwd, :name, 100).returns "boo"
+ it "should use :search_posix_field if the discovered name does not match the passed-in name" do
+ @posix.expects(:get_posix_field).with(:passwd, :uid, "asdf").returns 100
+ @posix.expects(:get_posix_field).with(:passwd, :name, 100).returns "boo"
- @posix.expects(:search_posix_field).with(:passwd, :uid, "asdf").returns "asdf"
+ @posix.expects(:search_posix_field).with(:passwd, :uid, "asdf").returns "asdf"
- @posix.uid("asdf").should == "asdf"
- end
- end
+ @posix.uid("asdf").should == "asdf"
+ end
end
+ end
- it "should be able to iteratively search for posix values" do
- @posix.should respond_to(:search_posix_field)
- end
+ it "should be able to iteratively search for posix values" do
+ @posix.should respond_to(:search_posix_field)
+ end
- describe "when searching for posix values iteratively" do
- it "should iterate across all of the structs returned by Etc and return the appropriate field from the first matching value"
- end
+ describe "when searching for posix values iteratively" do
+ it "should iterate across all of the structs returned by Etc and return the appropriate field from the first matching value"
+ end
end
diff --git a/spec/unit/util/queue/stomp_spec.rb b/spec/unit/util/queue/stomp_spec.rb
index fec1790..9f1d284 100755
--- a/spec/unit/util/queue/stomp_spec.rb
+++ b/spec/unit/util/queue/stomp_spec.rb
@@ -4,137 +4,137 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/util/queue'
describe Puppet::Util::Queue do
- confine "Missing Stomp" => Puppet.features.stomp?
+ confine "Missing Stomp" => Puppet.features.stomp?
- it 'should load :stomp client appropriately' do
- Puppet.settings.stubs(:value).returns 'faux_queue_source'
- Puppet::Util::Queue.queue_type_to_class(:stomp).name.should == 'Puppet::Util::Queue::Stomp'
- end
+ it 'should load :stomp client appropriately' do
+ Puppet.settings.stubs(:value).returns 'faux_queue_source'
+ Puppet::Util::Queue.queue_type_to_class(:stomp).name.should == 'Puppet::Util::Queue::Stomp'
+ end
end
describe 'Puppet::Util::Queue::Stomp' do
- confine "Missing Stomp" => Puppet.features.stomp?
-
- before do
- # So we make sure we never create a real client instance.
- # Otherwise we'll try to connect, and that's bad.
- Stomp::Client.stubs(:new).returns stub("client")
+ confine "Missing Stomp" => Puppet.features.stomp?
+
+ before do
+ # So we make sure we never create a real client instance.
+ # Otherwise we'll try to connect, and that's bad.
+ Stomp::Client.stubs(:new).returns stub("client")
+ end
+
+ it 'should be registered with Puppet::Util::Queue as :stomp type' do
+ Puppet::Util::Queue.queue_type_to_class(:stomp).should == Puppet::Util::Queue::Stomp
+ end
+
+ describe "when initializing" do
+ it "should create a Stomp client instance" do
+ Stomp::Client.expects(:new).returns stub("stomp_client")
+ Puppet::Util::Queue::Stomp.new
end
- it 'should be registered with Puppet::Util::Queue as :stomp type' do
- Puppet::Util::Queue.queue_type_to_class(:stomp).should == Puppet::Util::Queue::Stomp
- end
-
- describe "when initializing" do
- it "should create a Stomp client instance" do
- Stomp::Client.expects(:new).returns stub("stomp_client")
- Puppet::Util::Queue::Stomp.new
- end
-
- it "should provide helpful failures when the queue source is not a valid source" do
- # Stub rather than expect, so we can include the source in the error
- Puppet.settings.stubs(:value).with(:queue_source).returns "-----"
+ it "should provide helpful failures when the queue source is not a valid source" do
+ # Stub rather than expect, so we can include the source in the error
+ Puppet.settings.stubs(:value).with(:queue_source).returns "-----"
- lambda { Puppet::Util::Queue::Stomp.new }.should raise_error(ArgumentError)
- end
+ lambda { Puppet::Util::Queue::Stomp.new }.should raise_error(ArgumentError)
+ end
- it "should fail unless the queue source is a stomp URL" do
- # Stub rather than expect, so we can include the source in the error
- Puppet.settings.stubs(:value).with(:queue_source).returns "http://foo/bar"
+ it "should fail unless the queue source is a stomp URL" do
+ # Stub rather than expect, so we can include the source in the error
+ Puppet.settings.stubs(:value).with(:queue_source).returns "http://foo/bar"
- lambda { Puppet::Util::Queue::Stomp.new }.should raise_error(ArgumentError)
- end
+ lambda { Puppet::Util::Queue::Stomp.new }.should raise_error(ArgumentError)
+ end
- it "should fail somewhat helpfully if the Stomp client cannot be created" do
- Stomp::Client.expects(:new).raises RuntimeError
- lambda { Puppet::Util::Queue::Stomp.new }.should raise_error(ArgumentError)
- end
+ it "should fail somewhat helpfully if the Stomp client cannot be created" do
+ Stomp::Client.expects(:new).raises RuntimeError
+ lambda { Puppet::Util::Queue::Stomp.new }.should raise_error(ArgumentError)
+ end
- list = %w{user password host port}
- {"user" => "myuser", "password" => "mypass", "host" => "foohost", "port" => 42}.each do |name, value|
- it "should use the #{name} from the queue source as the queueing #{name}" do
- Puppet.settings.expects(:value).with(:queue_source).returns "stomp://myuser:mypass@foohost:42/"
+ list = %w{user password host port}
+ {"user" => "myuser", "password" => "mypass", "host" => "foohost", "port" => 42}.each do |name, value|
+ it "should use the #{name} from the queue source as the queueing #{name}" do
+ Puppet.settings.expects(:value).with(:queue_source).returns "stomp://myuser:mypass@foohost:42/"
- Stomp::Client.expects(:new).with { |*args| args[list.index(name)] == value }
- Puppet::Util::Queue::Stomp.new
- end
- end
+ Stomp::Client.expects(:new).with { |*args| args[list.index(name)] == value }
+ Puppet::Util::Queue::Stomp.new
+ end
+ end
- it "should create a reliable client instance" do
- Puppet.settings.expects(:value).with(:queue_source).returns "stomp://myuser@foohost:42/"
+ it "should create a reliable client instance" do
+ Puppet.settings.expects(:value).with(:queue_source).returns "stomp://myuser@foohost:42/"
- Stomp::Client.expects(:new).with { |*args| args[4] == true }
- Puppet::Util::Queue::Stomp.new
- end
+ Stomp::Client.expects(:new).with { |*args| args[4] == true }
+ Puppet::Util::Queue::Stomp.new
end
+ end
- describe "when sending a message" do
- before do
- @client = stub 'client'
- Stomp::Client.stubs(:new).returns @client
- @queue = Puppet::Util::Queue::Stomp.new
- end
+ describe "when sending a message" do
+ before do
+ @client = stub 'client'
+ Stomp::Client.stubs(:new).returns @client
+ @queue = Puppet::Util::Queue::Stomp.new
+ end
- it "should send it to the queue client instance" do
- @client.expects(:send).with { |queue, msg, options| msg == "Smite!" }
- @queue.send_message('fooqueue', 'Smite!')
- end
+ it "should send it to the queue client instance" do
+ @client.expects(:send).with { |queue, msg, options| msg == "Smite!" }
+ @queue.send_message('fooqueue', 'Smite!')
+ end
- it "should send it to the transformed queue name" do
- @client.expects(:send).with { |queue, msg, options| queue == "/queue/fooqueue" }
- @queue.send_message('fooqueue', 'Smite!')
- end
+ it "should send it to the transformed queue name" do
+ @client.expects(:send).with { |queue, msg, options| queue == "/queue/fooqueue" }
+ @queue.send_message('fooqueue', 'Smite!')
+ end
- it "should send it as a persistent message" do
- @client.expects(:send).with { |queue, msg, options| options[:persistent] == true }
- @queue.send_message('fooqueue', 'Smite!')
- end
+ it "should send it as a persistent message" do
+ @client.expects(:send).with { |queue, msg, options| options[:persistent] == true }
+ @queue.send_message('fooqueue', 'Smite!')
end
+ end
- describe "when subscribing to a queue" do
- before do
- @client = stub 'client', :acknowledge => true
- Stomp::Client.stubs(:new).returns @client
- @queue = Puppet::Util::Queue::Stomp.new
- end
+ describe "when subscribing to a queue" do
+ before do
+ @client = stub 'client', :acknowledge => true
+ Stomp::Client.stubs(:new).returns @client
+ @queue = Puppet::Util::Queue::Stomp.new
+ end
- it "should subscribe via the queue client instance" do
- @client.expects(:subscribe)
- @queue.subscribe('fooqueue')
- end
+ it "should subscribe via the queue client instance" do
+ @client.expects(:subscribe)
+ @queue.subscribe('fooqueue')
+ end
- it "should subscribe to the transformed queue name" do
- @client.expects(:subscribe).with { |queue, options| queue == "/queue/fooqueue" }
- @queue.subscribe('fooqueue')
- end
+ it "should subscribe to the transformed queue name" do
+ @client.expects(:subscribe).with { |queue, options| queue == "/queue/fooqueue" }
+ @queue.subscribe('fooqueue')
+ end
- it "should specify that its messages should be acknowledged" do
- @client.expects(:subscribe).with { |queue, options| options[:ack] == :client }
- @queue.subscribe('fooqueue')
- end
+ it "should specify that its messages should be acknowledged" do
+ @client.expects(:subscribe).with { |queue, options| options[:ack] == :client }
+ @queue.subscribe('fooqueue')
+ end
- it "should yield the body of any received message" do
- message = mock 'message'
- message.expects(:body).returns "mybody"
+ it "should yield the body of any received message" do
+ message = mock 'message'
+ message.expects(:body).returns "mybody"
- @client.expects(:subscribe).yields(message)
+ @client.expects(:subscribe).yields(message)
- body = nil
- @queue.subscribe('fooqueue') { |b| body = b }
- body.should == "mybody"
- end
+ body = nil
+ @queue.subscribe('fooqueue') { |b| body = b }
+ body.should == "mybody"
+ end
- it "should acknowledge all successfully processed messages" do
- message = stub 'message', :body => "mybode"
+ it "should acknowledge all successfully processed messages" do
+ message = stub 'message', :body => "mybode"
- @client.stubs(:subscribe).yields(message)
- @client.expects(:acknowledge).with(message)
+ @client.stubs(:subscribe).yields(message)
+ @client.expects(:acknowledge).with(message)
- @queue.subscribe('fooqueue') { |b| "eh" }
- end
+ @queue.subscribe('fooqueue') { |b| "eh" }
end
+ end
- it 'should transform the simple queue name to "/queue/<queue_name>"' do
- Puppet::Util::Queue::Stomp.new.stompify_target('blah').should == '/queue/blah'
- end
+ it 'should transform the simple queue name to "/queue/<queue_name>"' do
+ Puppet::Util::Queue::Stomp.new.stompify_target('blah').should == '/queue/blah'
+ end
end
diff --git a/spec/unit/util/queue_spec.rb b/spec/unit/util/queue_spec.rb
index c8a7555..571bddd 100755
--- a/spec/unit/util/queue_spec.rb
+++ b/spec/unit/util/queue_spec.rb
@@ -5,92 +5,92 @@ require 'puppet/util/queue'
require 'spec/mocks'
def make_test_client_class(n)
- c = Class.new do
- class <<self
- attr_accessor :name
- def to_s
- name
- end
- end
+ c = Class.new do
+ class <<self
+ attr_accessor :name
+ def to_s
+ name
+ end
end
- c.name = n
- c
+ end
+ c.name = n
+ c
end
mod = Puppet::Util::Queue
client_classes = { :default => make_test_client_class('Bogus::Default'), :setup => make_test_client_class('Bogus::Setup') }
describe Puppet::Util::Queue do
- before :all do
- mod.register_queue_type(client_classes[:default], :default)
- mod.register_queue_type(client_classes[:setup], :setup)
+ before :all do
+ mod.register_queue_type(client_classes[:default], :default)
+ mod.register_queue_type(client_classes[:setup], :setup)
+ end
+
+ before :each do
+ @class = Class.new do
+ extend mod
end
+ end
- before :each do
- @class = Class.new do
- extend mod
- end
+ after :all do
+ instances = mod.instance_hash(:queue_clients)
+ [:default, :setup, :bogus, :aardvark, :conflict, :test_a, :test_b].each{ |x| instances.delete(x) }
+ end
+
+ context 'when determining a type name from a class' do
+ it 'should handle a simple one-word class name' do
+ mod.queue_type_from_class(make_test_client_class('Foo')).should == :foo
+ end
+
+ it 'should handle a simple two-word class name' do
+ mod.queue_type_from_class(make_test_client_class('FooBar')).should == :foo_bar
+ end
+
+ it 'should handle a two-part class name with one terminating word' do
+ mod.queue_type_from_class(make_test_client_class('Foo::Bar')).should == :bar
end
- after :all do
- instances = mod.instance_hash(:queue_clients)
- [:default, :setup, :bogus, :aardvark, :conflict, :test_a, :test_b].each{ |x| instances.delete(x) }
+ it 'should handle a two-part class name with two terminating words' do
+ mod.queue_type_from_class(make_test_client_class('Foo::BarBah')).should == :bar_bah
end
+ end
- context 'when determining a type name from a class' do
- it 'should handle a simple one-word class name' do
- mod.queue_type_from_class(make_test_client_class('Foo')).should == :foo
- end
+ context 'when registering a queue client class' do
+ c = make_test_client_class('Foo::Bogus')
+ it 'uses the proper default name logic when type is unspecified' do
+ mod.register_queue_type(c)
+ mod.queue_type_to_class(:bogus).should == c
+ end
- it 'should handle a simple two-word class name' do
- mod.queue_type_from_class(make_test_client_class('FooBar')).should == :foo_bar
- end
+ it 'uses an explicit type name when provided' do
+ mod.register_queue_type(c, :aardvark)
+ mod.queue_type_to_class(:aardvark).should == c
+ end
- it 'should handle a two-part class name with one terminating word' do
- mod.queue_type_from_class(make_test_client_class('Foo::Bar')).should == :bar
- end
+ it 'throws an exception when type names conflict' do
+ mod.register_queue_type( make_test_client_class('Conflict') )
+ lambda { mod.register_queue_type( c, :conflict) }.should raise_error
+ end
- it 'should handle a two-part class name with two terminating words' do
- mod.queue_type_from_class(make_test_client_class('Foo::BarBah')).should == :bar_bah
- end
+ it 'handle multiple, non-conflicting registrations' do
+ a = make_test_client_class('TestA')
+ b = make_test_client_class('TestB')
+ mod.register_queue_type(a)
+ mod.register_queue_type(b)
+ mod.queue_type_to_class(:test_a).should == a
+ mod.queue_type_to_class(:test_b).should == b
end
- context 'when registering a queue client class' do
- c = make_test_client_class('Foo::Bogus')
- it 'uses the proper default name logic when type is unspecified' do
- mod.register_queue_type(c)
- mod.queue_type_to_class(:bogus).should == c
- end
-
- it 'uses an explicit type name when provided' do
- mod.register_queue_type(c, :aardvark)
- mod.queue_type_to_class(:aardvark).should == c
- end
-
- it 'throws an exception when type names conflict' do
- mod.register_queue_type( make_test_client_class('Conflict') )
- lambda { mod.register_queue_type( c, :conflict) }.should raise_error
- end
-
- it 'handle multiple, non-conflicting registrations' do
- a = make_test_client_class('TestA')
- b = make_test_client_class('TestB')
- mod.register_queue_type(a)
- mod.register_queue_type(b)
- mod.queue_type_to_class(:test_a).should == a
- mod.queue_type_to_class(:test_b).should == b
- end
-
- it 'throws an exception when type name is unknown' do
- lambda { mod.queue_type_to_class(:nope) }.should raise_error
- end
+ it 'throws an exception when type name is unknown' do
+ lambda { mod.queue_type_to_class(:nope) }.should raise_error
end
+ end
- context 'when determining client type' do
- it 'returns client class based on the :queue_type setting' do
- Puppet.settings.expects(:value).with(:queue_type).returns(:myqueue)
- Puppet::Util::Queue.expects(:queue_type_to_class).with(:myqueue).returns "eh"
- @class.client_class.should == "eh"
- end
+ context 'when determining client type' do
+ it 'returns client class based on the :queue_type setting' do
+ Puppet.settings.expects(:value).with(:queue_type).returns(:myqueue)
+ Puppet::Util::Queue.expects(:queue_type_to_class).with(:myqueue).returns "eh"
+ @class.client_class.should == "eh"
end
+ end
end
diff --git a/spec/unit/util/rdoc/parser_spec.rb b/spec/unit/util/rdoc/parser_spec.rb
index a020372..a9c8190 100755
--- a/spec/unit/util/rdoc/parser_spec.rb
+++ b/spec/unit/util/rdoc/parser_spec.rb
@@ -9,532 +9,532 @@ require 'rdoc/options'
require 'rdoc/rdoc'
describe RDoc::Parser do
- before :each do
- File.stubs(:stat).with("init.pp")
- @top_level = stub_everything 'toplevel', :file_relative_name => "init.pp"
- @parser = RDoc::Parser.new(@top_level, "module/manifests/init.pp", nil, Options.instance, RDoc::Stats.new)
+ before :each do
+ File.stubs(:stat).with("init.pp")
+ @top_level = stub_everything 'toplevel', :file_relative_name => "init.pp"
+ @parser = RDoc::Parser.new(@top_level, "module/manifests/init.pp", nil, Options.instance, RDoc::Stats.new)
+ end
+
+ describe "when scanning files" do
+ it "should parse puppet files with the puppet parser" do
+ @parser.stubs(:scan_top_level)
+ parser = stub 'parser'
+ Puppet::Parser::Parser.expects(:new).returns(parser)
+ parser.expects(:parse)
+ parser.expects(:file=).with("module/manifests/init.pp")
+
+ @parser.scan
end
- describe "when scanning files" do
- it "should parse puppet files with the puppet parser" do
- @parser.stubs(:scan_top_level)
- parser = stub 'parser'
- Puppet::Parser::Parser.expects(:new).returns(parser)
- parser.expects(:parse)
- parser.expects(:file=).with("module/manifests/init.pp")
-
- @parser.scan
- end
+ it "should scan the ast for Puppet files" do
+ parser = stub_everything 'parser'
+ Puppet::Parser::Parser.stubs(:new).returns(parser)
- it "should scan the ast for Puppet files" do
- parser = stub_everything 'parser'
- Puppet::Parser::Parser.stubs(:new).returns(parser)
+ @parser.expects(:scan_top_level)
- @parser.expects(:scan_top_level)
-
- @parser.scan
- end
+ @parser.scan
+ end
- it "should return a PuppetTopLevel to RDoc" do
- parser = stub_everything 'parser'
- Puppet::Parser::Parser.stubs(:new).returns(parser)
+ it "should return a PuppetTopLevel to RDoc" do
+ parser = stub_everything 'parser'
+ Puppet::Parser::Parser.stubs(:new).returns(parser)
- @parser.expects(:scan_top_level)
+ @parser.expects(:scan_top_level)
- @parser.scan.should be_a(RDoc::PuppetTopLevel)
- end
+ @parser.scan.should be_a(RDoc::PuppetTopLevel)
end
+ end
- describe "when scanning top level entities" do
- before :each do
- @resource_type_collection = stub_everything 'resource_type_collection'
- @parser.ast = @resource_type_collection
- @parser.stubs(:split_module).returns("module")
-
- @topcontainer = stub_everything 'topcontainer'
- @container = stub_everything 'container'
- @module = stub_everything 'module'
- @container.stubs(:add_module).returns(@module)
- @parser.stubs(:get_class_or_module).returns([@container, "module"])
- end
+ describe "when scanning top level entities" do
+ before :each do
+ @resource_type_collection = stub_everything 'resource_type_collection'
+ @parser.ast = @resource_type_collection
+ @parser.stubs(:split_module).returns("module")
+
+ @topcontainer = stub_everything 'topcontainer'
+ @container = stub_everything 'container'
+ @module = stub_everything 'module'
+ @container.stubs(:add_module).returns(@module)
+ @parser.stubs(:get_class_or_module).returns([@container, "module"])
+ end
- it "should read any present README as module documentation" do
- FileTest.stubs(:readable?).returns(true)
- File.stubs(:open).returns("readme")
- @parser.stubs(:parse_elements)
+ it "should read any present README as module documentation" do
+ FileTest.stubs(:readable?).returns(true)
+ File.stubs(:open).returns("readme")
+ @parser.stubs(:parse_elements)
- @module.expects(:comment=).with("readme")
+ @module.expects(:comment=).with("readme")
- @parser.scan_top_level(@topcontainer)
- end
+ @parser.scan_top_level(@topcontainer)
+ end
- it "should tell the container its module name" do
- @parser.stubs(:parse_elements)
+ it "should tell the container its module name" do
+ @parser.stubs(:parse_elements)
- @topcontainer.expects(:module_name=).with("module")
+ @topcontainer.expects(:module_name=).with("module")
- @parser.scan_top_level(@topcontainer)
- end
+ @parser.scan_top_level(@topcontainer)
+ end
- it "should not document our toplevel if it isn't a valid module" do
- @parser.stubs(:split_module).returns(nil)
+ it "should not document our toplevel if it isn't a valid module" do
+ @parser.stubs(:split_module).returns(nil)
- @topcontainer.expects(:document_self=).with(false)
- @parser.expects(:parse_elements).never
+ @topcontainer.expects(:document_self=).with(false)
+ @parser.expects(:parse_elements).never
- @parser.scan_top_level(@topcontainer)
- end
+ @parser.scan_top_level(@topcontainer)
+ end
- it "should set the module as global if we parse the global manifests (ie <site> module)" do
- @parser.stubs(:split_module).returns("<site>")
- @parser.stubs(:parse_elements)
+ it "should set the module as global if we parse the global manifests (ie <site> module)" do
+ @parser.stubs(:split_module).returns("<site>")
+ @parser.stubs(:parse_elements)
- @topcontainer.expects(:global=).with(true)
+ @topcontainer.expects(:global=).with(true)
- @parser.scan_top_level(@topcontainer)
- end
+ @parser.scan_top_level(@topcontainer)
+ end
- it "should attach this module container to the toplevel container" do
- @parser.stubs(:parse_elements)
+ it "should attach this module container to the toplevel container" do
+ @parser.stubs(:parse_elements)
- @container.expects(:add_module).with(RDoc::PuppetModule, "module").returns(@module)
+ @container.expects(:add_module).with(RDoc::PuppetModule, "module").returns(@module)
- @parser.scan_top_level(@topcontainer)
- end
+ @parser.scan_top_level(@topcontainer)
+ end
- it "should defer ast parsing to parse_elements for this module" do
- @parser.expects(:parse_elements).with(@module)
+ it "should defer ast parsing to parse_elements for this module" do
+ @parser.expects(:parse_elements).with(@module)
- @parser.scan_top_level(@topcontainer)
- end
+ @parser.scan_top_level(@topcontainer)
+ end
- it "should defer plugins parsing to parse_plugins for this module" do
- @parser.input_file_name = "module/lib/puppet/parser/function.rb"
+ it "should defer plugins parsing to parse_plugins for this module" do
+ @parser.input_file_name = "module/lib/puppet/parser/function.rb"
- @parser.expects(:parse_plugins).with(@module)
+ @parser.expects(:parse_plugins).with(@module)
- @parser.scan_top_level(@topcontainer)
- end
+ @parser.scan_top_level(@topcontainer)
end
+ end
- describe "when finding modules from filepath" do
- before :each do
- Puppet::Module.stubs(:modulepath).returns("/path/to/modules")
- end
+ describe "when finding modules from filepath" do
+ before :each do
+ Puppet::Module.stubs(:modulepath).returns("/path/to/modules")
+ end
- it "should return the module name for modulized puppet manifests" do
- File.stubs(:expand_path).returns("/path/to/module/manifests/init.pp")
- File.stubs(:identical?).with("/path/to", "/path/to/modules").returns(true)
- @parser.split_module("/path/to/modules/mymodule/manifests/init.pp").should == "module"
- end
+ it "should return the module name for modulized puppet manifests" do
+ File.stubs(:expand_path).returns("/path/to/module/manifests/init.pp")
+ File.stubs(:identical?).with("/path/to", "/path/to/modules").returns(true)
+ @parser.split_module("/path/to/modules/mymodule/manifests/init.pp").should == "module"
+ end
- it "should return <site> for manifests not under module path" do
- File.stubs(:expand_path).returns("/path/to/manifests/init.pp")
- File.stubs(:identical?).returns(false)
- @parser.split_module("/path/to/manifests/init.pp").should == "<site>"
- end
+ it "should return <site> for manifests not under module path" do
+ File.stubs(:expand_path).returns("/path/to/manifests/init.pp")
+ File.stubs(:identical?).returns(false)
+ @parser.split_module("/path/to/manifests/init.pp").should == "<site>"
end
+ end
- describe "when parsing AST elements" do
- before :each do
- @klass = stub_everything 'klass', :file => "module/manifests/init.pp", :name => "myclass", :type => :hostclass
- @definition = stub_everything 'definition', :file => "module/manifests/init.pp", :type => :definition, :name => "mydef"
- @node = stub_everything 'node', :file => "module/manifests/init.pp", :type => :node, :name => "mynode"
+ describe "when parsing AST elements" do
+ before :each do
+ @klass = stub_everything 'klass', :file => "module/manifests/init.pp", :name => "myclass", :type => :hostclass
+ @definition = stub_everything 'definition', :file => "module/manifests/init.pp", :type => :definition, :name => "mydef"
+ @node = stub_everything 'node', :file => "module/manifests/init.pp", :type => :node, :name => "mynode"
- @resource_type_collection = Puppet::Resource::TypeCollection.new("env")
- @parser.ast = @resource_type_collection
+ @resource_type_collection = Puppet::Resource::TypeCollection.new("env")
+ @parser.ast = @resource_type_collection
- @container = stub_everything 'container'
- end
+ @container = stub_everything 'container'
+ end
- it "should document classes in the parsed file" do
- @resource_type_collection.add_hostclass(@klass)
+ it "should document classes in the parsed file" do
+ @resource_type_collection.add_hostclass(@klass)
- @parser.expects(:document_class).with("myclass", @klass, @container)
+ @parser.expects(:document_class).with("myclass", @klass, @container)
- @parser.parse_elements(@container)
- end
+ @parser.parse_elements(@container)
+ end
- it "should not document class parsed in an other file" do
- @klass.stubs(:file).returns("/not/same/path/file.pp")
- @resource_type_collection.add_hostclass(@klass)
+ it "should not document class parsed in an other file" do
+ @klass.stubs(:file).returns("/not/same/path/file.pp")
+ @resource_type_collection.add_hostclass(@klass)
- @parser.expects(:document_class).with("myclass", @klass, @container).never
+ @parser.expects(:document_class).with("myclass", @klass, @container).never
- @parser.parse_elements(@container)
- end
+ @parser.parse_elements(@container)
+ end
- it "should document vardefs for the main class" do
- @klass.stubs(:name).returns :main
- @resource_type_collection.add_hostclass(@klass)
+ it "should document vardefs for the main class" do
+ @klass.stubs(:name).returns :main
+ @resource_type_collection.add_hostclass(@klass)
- code = stub 'code', :is_a? => false
- @klass.stubs(:name).returns("")
- @klass.stubs(:code).returns(code)
+ code = stub 'code', :is_a? => false
+ @klass.stubs(:name).returns("")
+ @klass.stubs(:code).returns(code)
- @parser.expects(:scan_for_vardef).with(@container, code)
+ @parser.expects(:scan_for_vardef).with(@container, code)
- @parser.parse_elements(@container)
- end
+ @parser.parse_elements(@container)
+ end
- it "should document definitions in the parsed file" do
- @resource_type_collection.add_definition(@definition)
+ it "should document definitions in the parsed file" do
+ @resource_type_collection.add_definition(@definition)
- @parser.expects(:document_define).with("mydef", @definition, @container)
+ @parser.expects(:document_define).with("mydef", @definition, @container)
- @parser.parse_elements(@container)
- end
+ @parser.parse_elements(@container)
+ end
- it "should not document definitions parsed in an other file" do
- @definition.stubs(:file).returns("/not/same/path/file.pp")
- @resource_type_collection.add_definition(@definition)
+ it "should not document definitions parsed in an other file" do
+ @definition.stubs(:file).returns("/not/same/path/file.pp")
+ @resource_type_collection.add_definition(@definition)
- @parser.expects(:document_define).with("mydef", @definition, @container).never
+ @parser.expects(:document_define).with("mydef", @definition, @container).never
- @parser.parse_elements(@container)
- end
+ @parser.parse_elements(@container)
+ end
- it "should document nodes in the parsed file" do
- @resource_type_collection.add_node(@node)
+ it "should document nodes in the parsed file" do
+ @resource_type_collection.add_node(@node)
- @parser.expects(:document_node).with("mynode", @node, @container)
+ @parser.expects(:document_node).with("mynode", @node, @container)
- @parser.parse_elements(@container)
- end
+ @parser.parse_elements(@container)
+ end
- it "should not document node parsed in an other file" do
- @node.stubs(:file).returns("/not/same/path/file.pp")
- @resource_type_collection.add_node(@node)
+ it "should not document node parsed in an other file" do
+ @node.stubs(:file).returns("/not/same/path/file.pp")
+ @resource_type_collection.add_node(@node)
- @parser.expects(:document_node).with("mynode", @node, @container).never
+ @parser.expects(:document_node).with("mynode", @node, @container).never
- @parser.parse_elements(@container)
- end
+ @parser.parse_elements(@container)
end
+ end
- describe "when documenting definition" do
- before(:each) do
- @define = stub_everything 'define', :arguments => [], :doc => "mydoc", :file => "file", :line => 42
- @class = stub_everything 'class'
- @parser.stubs(:get_class_or_module).returns([@class, "mydef"])
- end
+ describe "when documenting definition" do
+ before(:each) do
+ @define = stub_everything 'define', :arguments => [], :doc => "mydoc", :file => "file", :line => 42
+ @class = stub_everything 'class'
+ @parser.stubs(:get_class_or_module).returns([@class, "mydef"])
+ end
- it "should register a RDoc method to the current container" do
- @class.expects(:add_method).with { |m| m.name == "mydef"}
- @parser.document_define("mydef", @define, @class)
- end
+ it "should register a RDoc method to the current container" do
+ @class.expects(:add_method).with { |m| m.name == "mydef"}
+ @parser.document_define("mydef", @define, @class)
+ end
- it "should attach the documentation to this method" do
- @class.expects(:add_method).with { |m| m.comment = "mydoc" }
+ it "should attach the documentation to this method" do
+ @class.expects(:add_method).with { |m| m.comment = "mydoc" }
- @parser.document_define("mydef", @define, @class)
- end
+ @parser.document_define("mydef", @define, @class)
+ end
- it "should produce a better error message on unhandled exception" do
- @class.expects(:add_method).raises(ArgumentError)
+ it "should produce a better error message on unhandled exception" do
+ @class.expects(:add_method).raises(ArgumentError)
- lambda { @parser.document_define("mydef", @define, @class) }.should raise_error(Puppet::ParseError, /in file at line 42/)
- end
+ lambda { @parser.document_define("mydef", @define, @class) }.should raise_error(Puppet::ParseError, /in file at line 42/)
+ end
- it "should convert all definition parameter to string" do
- arg = stub 'arg'
- val = stub 'val'
+ it "should convert all definition parameter to string" do
+ arg = stub 'arg'
+ val = stub 'val'
- @define.stubs(:arguments).returns({arg => val})
+ @define.stubs(:arguments).returns({arg => val})
- arg.expects(:to_s).returns("arg")
- val.expects(:to_s).returns("val")
+ arg.expects(:to_s).returns("arg")
+ val.expects(:to_s).returns("val")
- @parser.document_define("mydef", @define, @class)
- end
+ @parser.document_define("mydef", @define, @class)
end
+ end
- describe "when documenting nodes" do
- before :each do
- @code = stub_everything 'code'
- @node = stub_everything 'node', :doc => "mydoc", :parent => "parent", :code => @code, :file => "file", :line => 42
- @rdoc_node = stub_everything 'rdocnode'
+ describe "when documenting nodes" do
+ before :each do
+ @code = stub_everything 'code'
+ @node = stub_everything 'node', :doc => "mydoc", :parent => "parent", :code => @code, :file => "file", :line => 42
+ @rdoc_node = stub_everything 'rdocnode'
- @class = stub_everything 'class'
- @class.stubs(:add_node).returns(@rdoc_node)
- end
+ @class = stub_everything 'class'
+ @class.stubs(:add_node).returns(@rdoc_node)
+ end
- it "should add a node to the current container" do
- @class.expects(:add_node).with("mynode", "parent").returns(@rdoc_node)
- @parser.document_node("mynode", @node, @class)
- end
+ it "should add a node to the current container" do
+ @class.expects(:add_node).with("mynode", "parent").returns(@rdoc_node)
+ @parser.document_node("mynode", @node, @class)
+ end
- it "should associate the node documentation to the rdoc node" do
- @rdoc_node.expects(:comment=).with("mydoc")
- @parser.document_node("mynode", @node, @class)
- end
+ it "should associate the node documentation to the rdoc node" do
+ @rdoc_node.expects(:comment=).with("mydoc")
+ @parser.document_node("mynode", @node, @class)
+ end
- it "should scan for include and require" do
- @parser.expects(:scan_for_include_or_require).with(@rdoc_node, @code)
- @parser.document_node("mynode", @node, @class)
- end
+ it "should scan for include and require" do
+ @parser.expects(:scan_for_include_or_require).with(@rdoc_node, @code)
+ @parser.document_node("mynode", @node, @class)
+ end
- it "should scan for variable definition" do
- @parser.expects(:scan_for_vardef).with(@rdoc_node, @code)
- @parser.document_node("mynode", @node, @class)
- end
+ it "should scan for variable definition" do
+ @parser.expects(:scan_for_vardef).with(@rdoc_node, @code)
+ @parser.document_node("mynode", @node, @class)
+ end
- it "should scan for resources if needed" do
- Puppet.settings.stubs(:[]).with(:document_all).returns(true)
- @parser.expects(:scan_for_resource).with(@rdoc_node, @code)
- @parser.document_node("mynode", @node, @class)
- end
+ it "should scan for resources if needed" do
+ Puppet.settings.stubs(:[]).with(:document_all).returns(true)
+ @parser.expects(:scan_for_resource).with(@rdoc_node, @code)
+ @parser.document_node("mynode", @node, @class)
+ end
- it "should produce a better error message on unhandled exception" do
- @class.stubs(:add_node).raises(ArgumentError)
+ it "should produce a better error message on unhandled exception" do
+ @class.stubs(:add_node).raises(ArgumentError)
- lambda { @parser.document_node("mynode", @node, @class) }.should raise_error(Puppet::ParseError, /in file at line 42/)
- end
+ lambda { @parser.document_node("mynode", @node, @class) }.should raise_error(Puppet::ParseError, /in file at line 42/)
end
+ end
- describe "when documenting classes" do
- before :each do
- @code = stub_everything 'code'
- @class = stub_everything 'class', :doc => "mydoc", :parent => "parent", :code => @code, :file => "file", :line => 42
- @rdoc_class = stub_everything 'rdoc-class'
+ describe "when documenting classes" do
+ before :each do
+ @code = stub_everything 'code'
+ @class = stub_everything 'class', :doc => "mydoc", :parent => "parent", :code => @code, :file => "file", :line => 42
+ @rdoc_class = stub_everything 'rdoc-class'
- @module = stub_everything 'class'
- @module.stubs(:add_class).returns(@rdoc_class)
- @parser.stubs(:get_class_or_module).returns([@module, "myclass"])
- end
+ @module = stub_everything 'class'
+ @module.stubs(:add_class).returns(@rdoc_class)
+ @parser.stubs(:get_class_or_module).returns([@module, "myclass"])
+ end
- it "should add a class to the current container" do
- @module.expects(:add_class).with(RDoc::PuppetClass, "myclass", "parent").returns(@rdoc_class)
- @parser.document_class("mynode", @class, @module)
- end
+ it "should add a class to the current container" do
+ @module.expects(:add_class).with(RDoc::PuppetClass, "myclass", "parent").returns(@rdoc_class)
+ @parser.document_class("mynode", @class, @module)
+ end
- it "should set the superclass" do
- @rdoc_class.expects(:superclass=).with("parent")
- @parser.document_class("mynode", @class, @module)
- end
+ it "should set the superclass" do
+ @rdoc_class.expects(:superclass=).with("parent")
+ @parser.document_class("mynode", @class, @module)
+ end
- it "should associate the node documentation to the rdoc class" do
- @rdoc_class.expects(:comment=).with("mydoc")
- @parser.document_class("mynode", @class, @module)
- end
+ it "should associate the node documentation to the rdoc class" do
+ @rdoc_class.expects(:comment=).with("mydoc")
+ @parser.document_class("mynode", @class, @module)
+ end
- it "should scan for include and require" do
- @parser.expects(:scan_for_include_or_require).with(@rdoc_class, @code)
- @parser.document_class("mynode", @class, @module)
- end
+ it "should scan for include and require" do
+ @parser.expects(:scan_for_include_or_require).with(@rdoc_class, @code)
+ @parser.document_class("mynode", @class, @module)
+ end
- it "should scan for resources if needed" do
- Puppet.settings.stubs(:[]).with(:document_all).returns(true)
- @parser.expects(:scan_for_resource).with(@rdoc_class, @code)
- @parser.document_class("mynode", @class, @module)
- end
+ it "should scan for resources if needed" do
+ Puppet.settings.stubs(:[]).with(:document_all).returns(true)
+ @parser.expects(:scan_for_resource).with(@rdoc_class, @code)
+ @parser.document_class("mynode", @class, @module)
+ end
- it "should produce a better error message on unhandled exception" do
- @module.stubs(:add_class).raises(ArgumentError)
+ it "should produce a better error message on unhandled exception" do
+ @module.stubs(:add_class).raises(ArgumentError)
- lambda { @parser.document_class("mynode", @class, @module) }.should raise_error(Puppet::ParseError, /in file at line 42/)
- end
+ lambda { @parser.document_class("mynode", @class, @module) }.should raise_error(Puppet::ParseError, /in file at line 42/)
end
+ end
- describe "when scanning for includes and requires" do
+ describe "when scanning for includes and requires" do
- def create_stmt(name)
- stmt_value = stub "#{name}_value", :value => "myclass"
- stmt = stub_everything 'stmt', :name => name, :arguments => [stmt_value], :doc => "mydoc"
- stmt.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(false)
- stmt.stubs(:is_a?).with(Puppet::Parser::AST::Function).returns(true)
- stmt
- end
+ def create_stmt(name)
+ stmt_value = stub "#{name}_value", :value => "myclass"
+ stmt = stub_everything 'stmt', :name => name, :arguments => [stmt_value], :doc => "mydoc"
+ stmt.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(false)
+ stmt.stubs(:is_a?).with(Puppet::Parser::AST::Function).returns(true)
+ stmt
+ end
- before(:each) do
- @class = stub_everything 'class'
- @code = stub_everything 'code'
- @code.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(true)
- end
+ before(:each) do
+ @class = stub_everything 'class'
+ @code = stub_everything 'code'
+ @code.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(true)
+ end
- it "should also scan mono-instruction code" do
- @class.expects(:add_include).with { |i| i.is_a?(RDoc::Include) and i.name == "myclass" and i.comment == "mydoc" }
+ it "should also scan mono-instruction code" do
+ @class.expects(:add_include).with { |i| i.is_a?(RDoc::Include) and i.name == "myclass" and i.comment == "mydoc" }
- @parser.scan_for_include_or_require(@class,create_stmt("include"))
- end
+ @parser.scan_for_include_or_require(@class,create_stmt("include"))
+ end
- it "should register recursively includes to the current container" do
- @code.stubs(:children).returns([ create_stmt("include") ])
+ it "should register recursively includes to the current container" do
+ @code.stubs(:children).returns([ create_stmt("include") ])
- @class.expects(:add_include).with { |i| i.is_a?(RDoc::Include) and i.name == "myclass" and i.comment == "mydoc" }
- @parser.scan_for_include_or_require(@class, [@code])
- end
+ @class.expects(:add_include).with { |i| i.is_a?(RDoc::Include) and i.name == "myclass" and i.comment == "mydoc" }
+ @parser.scan_for_include_or_require(@class, [@code])
+ end
- it "should register requires to the current container" do
- @code.stubs(:children).returns([ create_stmt("require") ])
+ it "should register requires to the current container" do
+ @code.stubs(:children).returns([ create_stmt("require") ])
- @class.expects(:add_require).with { |i| i.is_a?(RDoc::Include) and i.name == "myclass" and i.comment == "mydoc" }
- @parser.scan_for_include_or_require(@class, [@code])
- end
+ @class.expects(:add_require).with { |i| i.is_a?(RDoc::Include) and i.name == "myclass" and i.comment == "mydoc" }
+ @parser.scan_for_include_or_require(@class, [@code])
end
+ end
- describe "when scanning for realized virtual resources" do
+ describe "when scanning for realized virtual resources" do
- def create_stmt
- stmt_value = stub "resource_ref", :to_s => "File[\"/tmp/a\"]"
- stmt = stub_everything 'stmt', :name => "realize", :arguments => [stmt_value], :doc => "mydoc"
- stmt.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(false)
- stmt.stubs(:is_a?).with(Puppet::Parser::AST::Function).returns(true)
- stmt
- end
+ def create_stmt
+ stmt_value = stub "resource_ref", :to_s => "File[\"/tmp/a\"]"
+ stmt = stub_everything 'stmt', :name => "realize", :arguments => [stmt_value], :doc => "mydoc"
+ stmt.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(false)
+ stmt.stubs(:is_a?).with(Puppet::Parser::AST::Function).returns(true)
+ stmt
+ end
- before(:each) do
- @class = stub_everything 'class'
- @code = stub_everything 'code'
- @code.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(true)
- end
+ before(:each) do
+ @class = stub_everything 'class'
+ @code = stub_everything 'code'
+ @code.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(true)
+ end
- it "should also scan mono-instruction code" do
- @class.expects(:add_realize).with { |i| i.is_a?(RDoc::Include) and i.name == "File[\"/tmp/a\"]" and i.comment == "mydoc" }
+ it "should also scan mono-instruction code" do
+ @class.expects(:add_realize).with { |i| i.is_a?(RDoc::Include) and i.name == "File[\"/tmp/a\"]" and i.comment == "mydoc" }
- @parser.scan_for_realize(@class,create_stmt)
- end
+ @parser.scan_for_realize(@class,create_stmt)
+ end
- it "should register recursively includes to the current container" do
- @code.stubs(:children).returns([ create_stmt ])
+ it "should register recursively includes to the current container" do
+ @code.stubs(:children).returns([ create_stmt ])
- @class.expects(:add_realize).with { |i| i.is_a?(RDoc::Include) and i.name == "File[\"/tmp/a\"]" and i.comment == "mydoc" }
- @parser.scan_for_realize(@class, [@code])
- end
+ @class.expects(:add_realize).with { |i| i.is_a?(RDoc::Include) and i.name == "File[\"/tmp/a\"]" and i.comment == "mydoc" }
+ @parser.scan_for_realize(@class, [@code])
end
+ end
- describe "when scanning for variable definition" do
- before :each do
- @class = stub_everything 'class'
+ describe "when scanning for variable definition" do
+ before :each do
+ @class = stub_everything 'class'
- @stmt = stub_everything 'stmt', :name => "myvar", :value => "myvalue", :doc => "mydoc"
- @stmt.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(false)
- @stmt.stubs(:is_a?).with(Puppet::Parser::AST::VarDef).returns(true)
+ @stmt = stub_everything 'stmt', :name => "myvar", :value => "myvalue", :doc => "mydoc"
+ @stmt.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(false)
+ @stmt.stubs(:is_a?).with(Puppet::Parser::AST::VarDef).returns(true)
- @code = stub_everything 'code'
- @code.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(true)
- end
+ @code = stub_everything 'code'
+ @code.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(true)
+ end
- it "should recursively register variables to the current container" do
- @code.stubs(:children).returns([ @stmt ])
+ it "should recursively register variables to the current container" do
+ @code.stubs(:children).returns([ @stmt ])
- @class.expects(:add_constant).with { |i| i.is_a?(RDoc::Constant) and i.name == "myvar" and i.comment == "mydoc" }
- @parser.scan_for_vardef(@class, [ @code ])
- end
+ @class.expects(:add_constant).with { |i| i.is_a?(RDoc::Constant) and i.name == "myvar" and i.comment == "mydoc" }
+ @parser.scan_for_vardef(@class, [ @code ])
+ end
- it "should also scan mono-instruction code" do
- @class.expects(:add_constant).with { |i| i.is_a?(RDoc::Constant) and i.name == "myvar" and i.comment == "mydoc" }
+ it "should also scan mono-instruction code" do
+ @class.expects(:add_constant).with { |i| i.is_a?(RDoc::Constant) and i.name == "myvar" and i.comment == "mydoc" }
- @parser.scan_for_vardef(@class, @stmt)
- end
+ @parser.scan_for_vardef(@class, @stmt)
end
+ end
- describe "when scanning for resources" do
- before :each do
- @class = stub_everything 'class'
+ describe "when scanning for resources" do
+ before :each do
+ @class = stub_everything 'class'
- param = stub 'params', :children => []
- @stmt = stub_everything 'stmt', :type => "File", :title => "myfile", :doc => "mydoc", :params => param
- @stmt.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(false)
- @stmt.stubs(:is_a?).with(Puppet::Parser::AST::Resource).returns(true)
+ param = stub 'params', :children => []
+ @stmt = stub_everything 'stmt', :type => "File", :title => "myfile", :doc => "mydoc", :params => param
+ @stmt.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(false)
+ @stmt.stubs(:is_a?).with(Puppet::Parser::AST::Resource).returns(true)
- @code = stub_everything 'code'
- @code.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(true)
- end
+ @code = stub_everything 'code'
+ @code.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(true)
+ end
- it "should register a PuppetResource to the current container" do
- @code.stubs(:children).returns([ @stmt ])
+ it "should register a PuppetResource to the current container" do
+ @code.stubs(:children).returns([ @stmt ])
- @class.expects(:add_resource).with { |i| i.is_a?(RDoc::PuppetResource) and i.title == "myfile" and i.comment == "mydoc" }
- @parser.scan_for_resource(@class, [ @code ])
- end
+ @class.expects(:add_resource).with { |i| i.is_a?(RDoc::PuppetResource) and i.title == "myfile" and i.comment == "mydoc" }
+ @parser.scan_for_resource(@class, [ @code ])
+ end
- it "should also scan mono-instruction code" do
- @class.expects(:add_resource).with { |i| i.is_a?(RDoc::PuppetResource) and i.title == "myfile" and i.comment == "mydoc" }
+ it "should also scan mono-instruction code" do
+ @class.expects(:add_resource).with { |i| i.is_a?(RDoc::PuppetResource) and i.title == "myfile" and i.comment == "mydoc" }
- @parser.scan_for_resource(@class, @stmt)
- end
+ @parser.scan_for_resource(@class, @stmt)
end
+ end
- describe "when parsing plugins" do
- before :each do
- @container = stub 'container'
- end
+ describe "when parsing plugins" do
+ before :each do
+ @container = stub 'container'
+ end
- it "should delegate parsing custom facts to parse_facts" do
- @parser = RDoc::Parser.new(@top_level, "module/manifests/lib/puppet/facter/test.rb", nil, Options.instance, RDoc::Stats.new)
+ it "should delegate parsing custom facts to parse_facts" do
+ @parser = RDoc::Parser.new(@top_level, "module/manifests/lib/puppet/facter/test.rb", nil, Options.instance, RDoc::Stats.new)
- @parser.expects(:parse_fact).with(@container)
- @parser.parse_plugins(@container)
- end
+ @parser.expects(:parse_fact).with(@container)
+ @parser.parse_plugins(@container)
+ end
- it "should delegate parsing plugins to parse_plugins" do
- @parser = RDoc::Parser.new(@top_level, "module/manifests/lib/puppet/functions/test.rb", nil, Options.instance, RDoc::Stats.new)
+ it "should delegate parsing plugins to parse_plugins" do
+ @parser = RDoc::Parser.new(@top_level, "module/manifests/lib/puppet/functions/test.rb", nil, Options.instance, RDoc::Stats.new)
- @parser.expects(:parse_puppet_plugin).with(@container)
- @parser.parse_plugins(@container)
- end
+ @parser.expects(:parse_puppet_plugin).with(@container)
+ @parser.parse_plugins(@container)
end
+ end
- describe "when parsing plugins" do
- before :each do
- @container = stub_everything 'container'
- end
+ describe "when parsing plugins" do
+ before :each do
+ @container = stub_everything 'container'
+ end
- it "should add custom functions to the container" do
- File.stubs(:open).yields("# documentation
- module Puppet::Parser::Functions
- newfunction(:myfunc, :type => :rvalue) do |args|
- File.dirname(args[0])
- end
- end".split("\n"))
+ it "should add custom functions to the container" do
+ File.stubs(:open).yields("# documentation
+ module Puppet::Parser::Functions
+ newfunction(:myfunc, :type => :rvalue) do |args|
+ File.dirname(args[0])
+ end
+ end".split("\n"))
- @container.expects(:add_plugin).with do |plugin|
- plugin.comment == "documentation\n" #and
- plugin.name == "myfunc"
- end
+ @container.expects(:add_plugin).with do |plugin|
+ plugin.comment == "documentation\n" #and
+ plugin.name == "myfunc"
+ end
- @parser.parse_puppet_plugin(@container)
- end
+ @parser.parse_puppet_plugin(@container)
+ end
- it "should add custom types to the container" do
- File.stubs(:open).yields("# documentation
- Puppet::Type.newtype(:mytype) do
- end".split("\n"))
+ it "should add custom types to the container" do
+ File.stubs(:open).yields("# documentation
+ Puppet::Type.newtype(:mytype) do
+ end".split("\n"))
- @container.expects(:add_plugin).with do |plugin|
- plugin.comment == "documentation\n" #and
- plugin.name == "mytype"
- end
+ @container.expects(:add_plugin).with do |plugin|
+ plugin.comment == "documentation\n" #and
+ plugin.name == "mytype"
+ end
- @parser.parse_puppet_plugin(@container)
- end
+ @parser.parse_puppet_plugin(@container)
end
+ end
- describe "when parsing facts" do
- before :each do
- @container = stub_everything 'container'
- File.stubs(:open).yields(["# documentation", "Facter.add('myfact') do", "confine :kernel => :linux", "end"])
- end
+ describe "when parsing facts" do
+ before :each do
+ @container = stub_everything 'container'
+ File.stubs(:open).yields(["# documentation", "Facter.add('myfact') do", "confine :kernel => :linux", "end"])
+ end
- it "should add facts to the container" do
- @container.expects(:add_fact).with do |fact|
- fact.comment == "documentation\n" and
- fact.name == "myfact"
- end
+ it "should add facts to the container" do
+ @container.expects(:add_fact).with do |fact|
+ fact.comment == "documentation\n" and
+ fact.name == "myfact"
+ end
- @parser.parse_fact(@container)
- end
+ @parser.parse_fact(@container)
+ end
- it "should add confine to the parsed facts" do
- ourfact = nil
- @container.expects(:add_fact).with do |fact|
- ourfact = fact
- true
- end
+ it "should add confine to the parsed facts" do
+ ourfact = nil
+ @container.expects(:add_fact).with do |fact|
+ ourfact = fact
+ true
+ end
- @parser.parse_fact(@container)
- ourfact.confine.should == { :type => "kernel", :value => ":linux" }
- end
+ @parser.parse_fact(@container)
+ ourfact.confine.should == { :type => "kernel", :value => ":linux" }
end
+ end
end
diff --git a/spec/unit/util/rdoc_spec.rb b/spec/unit/util/rdoc_spec.rb
index 4417fca..65df261 100755
--- a/spec/unit/util/rdoc_spec.rb
+++ b/spec/unit/util/rdoc_spec.rb
@@ -7,159 +7,159 @@ require 'rdoc/rdoc'
describe Puppet::Util::RDoc do
- describe "when generating RDoc HTML documentation" do
- before :each do
- @rdoc = stub_everything 'rdoc'
- RDoc::RDoc.stubs(:new).returns(@rdoc)
- end
+ describe "when generating RDoc HTML documentation" do
+ before :each do
+ @rdoc = stub_everything 'rdoc'
+ RDoc::RDoc.stubs(:new).returns(@rdoc)
+ end
- it "should tell the parser to ignore import" do
- Puppet.expects(:[]=).with(:ignoreimport, true)
+ it "should tell the parser to ignore import" do
+ Puppet.expects(:[]=).with(:ignoreimport, true)
- Puppet::Util::RDoc.rdoc("output", [])
- end
+ Puppet::Util::RDoc.rdoc("output", [])
+ end
- it "should install the Puppet HTML Generator into RDoc generators" do
- Puppet::Util::RDoc.rdoc("output", [])
+ it "should install the Puppet HTML Generator into RDoc generators" do
+ Puppet::Util::RDoc.rdoc("output", [])
- RDoc::RDoc::GENERATORS["puppet"].file_name.should == "puppet/util/rdoc/generators/puppet_generator.rb"
- end
+ RDoc::RDoc::GENERATORS["puppet"].file_name.should == "puppet/util/rdoc/generators/puppet_generator.rb"
+ end
- it "should tell RDoc to generate documentation using the Puppet generator" do
- @rdoc.expects(:document).with { |args| args.include?("--fmt") and args.include?("puppet") }
+ it "should tell RDoc to generate documentation using the Puppet generator" do
+ @rdoc.expects(:document).with { |args| args.include?("--fmt") and args.include?("puppet") }
- Puppet::Util::RDoc.rdoc("output", [])
- end
+ Puppet::Util::RDoc.rdoc("output", [])
+ end
- it "should tell RDoc to be quiet" do
- @rdoc.expects(:document).with { |args| args.include?("--quiet") }
+ it "should tell RDoc to be quiet" do
+ @rdoc.expects(:document).with { |args| args.include?("--quiet") }
- Puppet::Util::RDoc.rdoc("output", [])
- end
+ Puppet::Util::RDoc.rdoc("output", [])
+ end
- it "should pass charset to RDoc" do
- @rdoc.expects(:document).with { |args| args.include?("--charset") and args.include?("utf-8") }
+ it "should pass charset to RDoc" do
+ @rdoc.expects(:document).with { |args| args.include?("--charset") and args.include?("utf-8") }
- Puppet::Util::RDoc.rdoc("output", [], "utf-8")
- end
+ Puppet::Util::RDoc.rdoc("output", [], "utf-8")
+ end
- it "should tell RDoc to force updates of indices" do
- @rdoc.expects(:document).with { |args| args.include?("--force-update") }
+ it "should tell RDoc to force updates of indices" do
+ @rdoc.expects(:document).with { |args| args.include?("--force-update") }
- Puppet::Util::RDoc.rdoc("output", [])
- end
+ Puppet::Util::RDoc.rdoc("output", [])
+ end
- it "should tell RDoc to use the given outputdir" do
- @rdoc.expects(:document).with { |args| args.include?("--op") and args.include?("myoutputdir") }
+ it "should tell RDoc to use the given outputdir" do
+ @rdoc.expects(:document).with { |args| args.include?("--op") and args.include?("myoutputdir") }
- Puppet::Util::RDoc.rdoc("myoutputdir", [])
- end
+ Puppet::Util::RDoc.rdoc("myoutputdir", [])
+ end
- it "should tell RDoc to exclude .pp files under any modules/<mod>/files section" do
- @rdoc.expects(:document).with { |args| args.include?("--exclude") and args.include?("/modules/[^/]*/files/.*\.pp$") }
+ it "should tell RDoc to exclude .pp files under any modules/<mod>/files section" do
+ @rdoc.expects(:document).with { |args| args.include?("--exclude") and args.include?("/modules/[^/]*/files/.*\.pp$") }
- Puppet::Util::RDoc.rdoc("myoutputdir", [])
- end
+ Puppet::Util::RDoc.rdoc("myoutputdir", [])
+ end
- it "should give all the source directories to RDoc" do
- @rdoc.expects(:document).with { |args| args.include?("sourcedir") }
+ it "should give all the source directories to RDoc" do
+ @rdoc.expects(:document).with { |args| args.include?("sourcedir") }
- Puppet::Util::RDoc.rdoc("output", ["sourcedir"])
- end
+ Puppet::Util::RDoc.rdoc("output", ["sourcedir"])
end
+ end
- describe "when running a manifest documentation" do
- it "should tell the parser to ignore import" do
- Puppet.expects(:[]=).with(:ignoreimport, true)
+ describe "when running a manifest documentation" do
+ it "should tell the parser to ignore import" do
+ Puppet.expects(:[]=).with(:ignoreimport, true)
- Puppet::Util::RDoc.manifestdoc([])
- end
+ Puppet::Util::RDoc.manifestdoc([])
+ end
- it "should puppet parse all given files" do
- FileTest.stubs(:file?).returns(true)
- Puppet::Util::RDoc.stubs(:output)
+ it "should puppet parse all given files" do
+ FileTest.stubs(:file?).returns(true)
+ Puppet::Util::RDoc.stubs(:output)
- parser = stub_everything
- Puppet::Parser::Parser.stubs(:new).returns(parser)
+ parser = stub_everything
+ Puppet::Parser::Parser.stubs(:new).returns(parser)
- parser.expects(:file=).with("file")
- parser.expects(:parse)
+ parser.expects(:file=).with("file")
+ parser.expects(:parse)
- Puppet::Util::RDoc.manifestdoc(["file"])
- end
+ Puppet::Util::RDoc.manifestdoc(["file"])
+ end
- it "should call output for each parsed file" do
- FileTest.stubs(:file?).returns(true)
+ it "should call output for each parsed file" do
+ FileTest.stubs(:file?).returns(true)
- ast = stub_everything
- parser = stub_everything
- Puppet::Parser::Parser.stubs(:new).returns(parser)
- parser.stubs(:parse).returns(ast)
+ ast = stub_everything
+ parser = stub_everything
+ Puppet::Parser::Parser.stubs(:new).returns(parser)
+ parser.stubs(:parse).returns(ast)
- Puppet::Util::RDoc.expects(:output).with("file", ast)
+ Puppet::Util::RDoc.expects(:output).with("file", ast)
- Puppet::Util::RDoc.manifestdoc(["file"])
- end
+ Puppet::Util::RDoc.manifestdoc(["file"])
+ end
- describe "when outputing documentation" do
- before :each do
- @node = stub 'node', :file => "file", :line => 1, :doc => ""
- @class = stub 'class', :file => "file", :line => 4, :doc => ""
- @definition = stub 'definition', :file => "file", :line => 3, :doc => ""
- @ast = stub 'ast', :nodes => { :node => @node }, :hostclasses => { :class => @class }, :definitions => { :definition => @definition }
- end
+ describe "when outputing documentation" do
+ before :each do
+ @node = stub 'node', :file => "file", :line => 1, :doc => ""
+ @class = stub 'class', :file => "file", :line => 4, :doc => ""
+ @definition = stub 'definition', :file => "file", :line => 3, :doc => ""
+ @ast = stub 'ast', :nodes => { :node => @node }, :hostclasses => { :class => @class }, :definitions => { :definition => @definition }
+ end
- it "should output doc for ast nodes" do
- @node.expects(:doc)
+ it "should output doc for ast nodes" do
+ @node.expects(:doc)
- Puppet::Util::RDoc.output("file", @ast)
- end
+ Puppet::Util::RDoc.output("file", @ast)
+ end
- it "should output doc for ast classes" do
- @class.expects(:doc)
+ it "should output doc for ast classes" do
+ @class.expects(:doc)
- Puppet::Util::RDoc.output("file", @ast)
- end
+ Puppet::Util::RDoc.output("file", @ast)
+ end
- it "should output doc for ast definitions" do
- @definition.expects(:doc)
+ it "should output doc for ast definitions" do
+ @definition.expects(:doc)
- Puppet::Util::RDoc.output("file", @ast)
- end
+ Puppet::Util::RDoc.output("file", @ast)
+ end
- it "should output doc in order of increasing line number" do
- byline = sequence('byline')
- @node.expects(:doc).in_sequence(byline)
- @definition.expects(:doc).in_sequence(byline)
- @class.expects(:doc).in_sequence(byline)
+ it "should output doc in order of increasing line number" do
+ byline = sequence('byline')
+ @node.expects(:doc).in_sequence(byline)
+ @definition.expects(:doc).in_sequence(byline)
+ @class.expects(:doc).in_sequence(byline)
- Puppet::Util::RDoc.output("file", @ast)
- end
+ Puppet::Util::RDoc.output("file", @ast)
+ end
- it "should not output documentation of ast object of another node" do
- klass = stub 'otherclass', :file => "otherfile", :line => 12, :doc => ""
- @ast.stubs(:hostclasses).returns({ :otherclass => klass })
+ it "should not output documentation of ast object of another node" do
+ klass = stub 'otherclass', :file => "otherfile", :line => 12, :doc => ""
+ @ast.stubs(:hostclasses).returns({ :otherclass => klass })
- klass.expects(:doc).never
+ klass.expects(:doc).never
- Puppet::Util::RDoc.output("file", @ast)
- end
+ Puppet::Util::RDoc.output("file", @ast)
+ end
- it "should output resource documentation if needed" do
- Puppet.settings.stubs(:[]).with(:document_all).returns(true)
- [@node, at definition].each do |o|
- o.stubs(:code).returns([])
- end
+ it "should output resource documentation if needed" do
+ Puppet.settings.stubs(:[]).with(:document_all).returns(true)
+ [@node, at definition].each do |o|
+ o.stubs(:code).returns([])
+ end
- resource = stub_everything 'resource', :line => 1
- resource.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(false)
- resource.stubs(:is_a?).with(Puppet::Parser::AST::Resource).returns(true)
- @class.stubs(:code).returns([resource])
+ resource = stub_everything 'resource', :line => 1
+ resource.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(false)
+ resource.stubs(:is_a?).with(Puppet::Parser::AST::Resource).returns(true)
+ @class.stubs(:code).returns([resource])
- resource.expects(:doc)
+ resource.expects(:doc)
- Puppet::Util::RDoc.output("file", @ast)
- end
- end
+ Puppet::Util::RDoc.output("file", @ast)
+ end
end
+ end
end
diff --git a/spec/unit/util/reference_serializer_spec.rb b/spec/unit/util/reference_serializer_spec.rb
index cfabec4..6e7d8a6 100644
--- a/spec/unit/util/reference_serializer_spec.rb
+++ b/spec/unit/util/reference_serializer_spec.rb
@@ -4,49 +4,49 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/util/rails/reference_serializer'
class SerializeTester
- include Puppet::Util::ReferenceSerializer
+ include Puppet::Util::ReferenceSerializer
end
describe Puppet::Util::ReferenceSerializer do
- before do
- @tester = SerializeTester.new
+ before do
+ @tester = SerializeTester.new
+ end
+
+ describe "when serializing" do
+ it "should yaml-dump resource references" do
+ ref = Puppet::Resource.new("file", "/foo")
+ @tester.serialize_value(ref).should =~ /^---/
end
- describe "when serializing" do
- it "should yaml-dump resource references" do
- ref = Puppet::Resource.new("file", "/foo")
- @tester.serialize_value(ref).should =~ /^---/
- end
-
- it "should convert the boolean 'true' into the string 'true'" do
- @tester.serialize_value(true).should == "true"
- end
+ it "should convert the boolean 'true' into the string 'true'" do
+ @tester.serialize_value(true).should == "true"
+ end
- it "should convert the boolean 'false' into the string 'false'" do
- @tester.serialize_value(false).should == "false"
- end
+ it "should convert the boolean 'false' into the string 'false'" do
+ @tester.serialize_value(false).should == "false"
+ end
- it "should return all other values" do
- @tester.serialize_value("foo").should == "foo"
- end
+ it "should return all other values" do
+ @tester.serialize_value("foo").should == "foo"
end
+ end
- describe "when unserializing" do
- it "should yaml-load values that look like yaml" do
- yaml = YAML.dump(%w{a b c})
- @tester.unserialize_value(yaml).should == %w{a b c}
- end
+ describe "when unserializing" do
+ it "should yaml-load values that look like yaml" do
+ yaml = YAML.dump(%w{a b c})
+ @tester.unserialize_value(yaml).should == %w{a b c}
+ end
- it "should convert the string 'true' into the boolean 'true'" do
- @tester.unserialize_value("true").should == true
- end
+ it "should convert the string 'true' into the boolean 'true'" do
+ @tester.unserialize_value("true").should == true
+ end
- it "should convert the string 'false' into the boolean 'false'" do
- @tester.unserialize_value("false").should == false
- end
+ it "should convert the string 'false' into the boolean 'false'" do
+ @tester.unserialize_value("false").should == false
+ end
- it "should return all other values" do
- @tester.unserialize_value("foo").should == "foo"
- end
+ it "should return all other values" do
+ @tester.unserialize_value("foo").should == "foo"
end
+ end
end
diff --git a/spec/unit/util/resource_template_spec.rb b/spec/unit/util/resource_template_spec.rb
index b4d529e..2eab2cf 100755
--- a/spec/unit/util/resource_template_spec.rb
+++ b/spec/unit/util/resource_template_spec.rb
@@ -5,54 +5,54 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/util/resource_template'
describe Puppet::Util::ResourceTemplate do
- describe "when initializing" do
- it "should fail if the template does not exist" do
- FileTest.expects(:exist?).with("/my/template").returns false
- lambda { Puppet::Util::ResourceTemplate.new("/my/template", mock('resource')) }.should raise_error(ArgumentError)
- end
-
- it "should not create the ERB template" do
- ERB.expects(:new).never
- FileTest.expects(:exist?).with("/my/template").returns true
- Puppet::Util::ResourceTemplate.new("/my/template", mock('resource'))
- end
+ describe "when initializing" do
+ it "should fail if the template does not exist" do
+ FileTest.expects(:exist?).with("/my/template").returns false
+ lambda { Puppet::Util::ResourceTemplate.new("/my/template", mock('resource')) }.should raise_error(ArgumentError)
end
- describe "when evaluating" do
- before do
- FileTest.stubs(:exist?).returns true
- File.stubs(:read).returns "eh"
+ it "should not create the ERB template" do
+ ERB.expects(:new).never
+ FileTest.expects(:exist?).with("/my/template").returns true
+ Puppet::Util::ResourceTemplate.new("/my/template", mock('resource'))
+ end
+ end
- @template = stub 'template', :result => nil
- ERB.stubs(:new).returns @template
+ describe "when evaluating" do
+ before do
+ FileTest.stubs(:exist?).returns true
+ File.stubs(:read).returns "eh"
- @resource = mock 'resource'
- @wrapper = Puppet::Util::ResourceTemplate.new("/my/template", @resource)
- end
+ @template = stub 'template', :result => nil
+ ERB.stubs(:new).returns @template
- it "should set all of the resource's parameters as instance variables" do
- @resource.expects(:to_hash).returns(:one => "uno", :two => "dos")
- @template.expects(:result).with do |bind|
- eval("@one", bind) == "uno" and eval("@two", bind) == "dos"
- end
- @wrapper.evaluate
- end
+ @resource = mock 'resource'
+ @wrapper = Puppet::Util::ResourceTemplate.new("/my/template", @resource)
+ end
- it "should create a template instance with the contents of the file" do
- File.expects(:read).with("/my/template").returns "yay"
- ERB.expects(:new).with("yay", 0, "-").returns(@template)
+ it "should set all of the resource's parameters as instance variables" do
+ @resource.expects(:to_hash).returns(:one => "uno", :two => "dos")
+ @template.expects(:result).with do |bind|
+ eval("@one", bind) == "uno" and eval("@two", bind) == "dos"
+ end
+ @wrapper.evaluate
+ end
- @wrapper.stubs :set_resource_variables
+ it "should create a template instance with the contents of the file" do
+ File.expects(:read).with("/my/template").returns "yay"
+ ERB.expects(:new).with("yay", 0, "-").returns(@template)
- @wrapper.evaluate
- end
+ @wrapper.stubs :set_resource_variables
+
+ @wrapper.evaluate
+ end
- it "should return the result of the template" do
- @wrapper.stubs :set_resource_variables
+ it "should return the result of the template" do
+ @wrapper.stubs :set_resource_variables
- @wrapper.expects(:binding).returns "mybinding"
- @template.expects(:result).with("mybinding").returns "myresult"
- @wrapper.evaluate.should == "myresult"
- end
+ @wrapper.expects(:binding).returns "mybinding"
+ @template.expects(:result).with("mybinding").returns "myresult"
+ @wrapper.evaluate.should == "myresult"
end
+ end
end
diff --git a/spec/unit/util/selinux_spec.rb b/spec/unit/util/selinux_spec.rb
index 0965347..e927843 100755
--- a/spec/unit/util/selinux_spec.rb
+++ b/spec/unit/util/selinux_spec.rb
@@ -6,273 +6,273 @@ require 'puppet/util/selinux'
include Puppet::Util::SELinux
unless defined?(Selinux)
- module Selinux
- def self.is_selinux_enabled
- false
- end
+ module Selinux
+ def self.is_selinux_enabled
+ false
end
+ end
end
describe Puppet::Util::SELinux do
- describe "selinux_support?" do
- before do
- end
- it "should return :true if this system has SELinux enabled" do
- Selinux.expects(:is_selinux_enabled).returns 1
- selinux_support?.should be_true
- end
-
- it "should return :false if this system lacks SELinux" do
- Selinux.expects(:is_selinux_enabled).returns 0
- selinux_support?.should be_false
- end
+ describe "selinux_support?" do
+ before do
+ end
+ it "should return :true if this system has SELinux enabled" do
+ Selinux.expects(:is_selinux_enabled).returns 1
+ selinux_support?.should be_true
+ end
- it "should return nil if /proc/mounts does not exist" do
- File.stubs(:open).with("/proc/mounts").raises("No such file or directory - /proc/mounts")
- read_mounts.should == nil
- end
+ it "should return :false if this system lacks SELinux" do
+ Selinux.expects(:is_selinux_enabled).returns 0
+ selinux_support?.should be_false
end
- describe "filesystem detection" do
- before :each do
- fh = stub 'fh', :close => nil
- File.stubs(:open).with("/proc/mounts").returns fh
- fh.expects(:read_nonblock).times(2).returns("rootfs / rootfs rw 0 0\n/dev/root / ext3 rw,relatime,errors=continue,user_xattr,acl,data=ordered 0 0\n/dev /dev tmpfs rw,relatime,mode=755 0 0\n/proc /proc proc rw,relatime 0 0\n/sys /sys sysfs rw,relatime 0 0\n192.168.1.1:/var/export /mnt/nfs nfs rw,relatime,vers=3,rsize=32768,wsize=32768,namlen=255,hard,nointr,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=192.168.1.1,mountvers=3,mountproto=udp,addr=192.168.1.1 0 0\n").then.raises EOFError
- end
+ it "should return nil if /proc/mounts does not exist" do
+ File.stubs(:open).with("/proc/mounts").raises("No such file or directory - /proc/mounts")
+ read_mounts.should == nil
+ end
+ end
- it "should parse the contents of /proc/mounts" do
- read_mounts.should == {
- '/' => 'ext3',
- '/sys' => 'sysfs',
- '/mnt/nfs' => 'nfs',
- '/proc' => 'proc',
- '/dev' => 'tmpfs' }
- end
+ describe "filesystem detection" do
+ before :each do
+ fh = stub 'fh', :close => nil
+ File.stubs(:open).with("/proc/mounts").returns fh
+ fh.expects(:read_nonblock).times(2).returns("rootfs / rootfs rw 0 0\n/dev/root / ext3 rw,relatime,errors=continue,user_xattr,acl,data=ordered 0 0\n/dev /dev tmpfs rw,relatime,mode=755 0 0\n/proc /proc proc rw,relatime 0 0\n/sys /sys sysfs rw,relatime 0 0\n192.168.1.1:/var/export /mnt/nfs nfs rw,relatime,vers=3,rsize=32768,wsize=32768,namlen=255,hard,nointr,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=192.168.1.1,mountvers=3,mountproto=udp,addr=192.168.1.1 0 0\n").then.raises EOFError
+ end
- it "should match a path on / to ext3" do
- find_fs('/etc/puppet/testfile').should == "ext3"
- end
+ it "should parse the contents of /proc/mounts" do
+ read_mounts.should == {
+ '/' => 'ext3',
+ '/sys' => 'sysfs',
+ '/mnt/nfs' => 'nfs',
+ '/proc' => 'proc',
+ '/dev' => 'tmpfs' }
+ end
- it "should match a path on /mnt/nfs to nfs" do
- find_fs('/mnt/nfs/testfile/foobar').should == "nfs"
- end
+ it "should match a path on / to ext3" do
+ find_fs('/etc/puppet/testfile').should == "ext3"
+ end
- it "should reture true for a capable filesystem" do
- selinux_label_support?('/etc/puppet/testfile').should be_true
- end
+ it "should match a path on /mnt/nfs to nfs" do
+ find_fs('/mnt/nfs/testfile/foobar').should == "nfs"
+ end
- it "should return false for a noncapable filesystem" do
- selinux_label_support?('/mnt/nfs/testfile').should be_false
- end
+ it "should reture true for a capable filesystem" do
+ selinux_label_support?('/etc/puppet/testfile').should be_true
+ end
- it "should follow symlinks when determining file systems" do
- self.stubs(:realpath).with('/mnt/symlink/testfile').returns('/mnt/nfs/dest/testfile')
+ it "should return false for a noncapable filesystem" do
+ selinux_label_support?('/mnt/nfs/testfile').should be_false
+ end
- selinux_label_support?('/mnt/symlink/testfile').should be_false
- end
+ it "should follow symlinks when determining file systems" do
+ self.stubs(:realpath).with('/mnt/symlink/testfile').returns('/mnt/nfs/dest/testfile')
+ selinux_label_support?('/mnt/symlink/testfile').should be_false
end
- describe "realpath" do
- it "should handle files that don't exist" do
+ end
- # Since I'm stubbing Pathname.new for this test,
- # I need to also stub the internal calls to Pathname.new,
- # which happen in Pathname.dirname and Parthname.basename
- # I want those to return real Pathname objects,
- # so I'm creating them before the stub is in place.
- realpaths = Hash.new {|hash, path| hash[path] = Pathname.new(path) }
- paths = ['symlink', '/mnt']
- paths.each { |path| realpaths[path] }
+ describe "realpath" do
+ it "should handle files that don't exist" do
- realpaths['/mnt/symlink'] = stubs "Pathname"
- realpaths['/mnt/symlink'].stubs(:realpath).returns(realpaths['/mnt/nfs/dest'])
- realpaths['/mnt/symlink'].stubs(:exist?).returns(true)
+ # Since I'm stubbing Pathname.new for this test,
+ # I need to also stub the internal calls to Pathname.new,
+ # which happen in Pathname.dirname and Parthname.basename
+ # I want those to return real Pathname objects,
+ # so I'm creating them before the stub is in place.
+ realpaths = Hash.new {|hash, path| hash[path] = Pathname.new(path) }
+ paths = ['symlink', '/mnt']
+ paths.each { |path| realpaths[path] }
- realpaths['/mnt/symlink/nonexistant'] = stubs "Pathname"
- realpaths['/mnt/symlink/nonexistant'].stubs(:realpath).raises(Errno::ENOENT)
- realpaths['/mnt/symlink/nonexistant'].stubs(:exist?).returns(false)
- realpaths['/mnt/symlink/nonexistant'].stubs(:dirname).returns(realpaths['/mnt/symlink'])
- realpaths['/mnt/symlink/nonexistant'].stubs(:basename).returns(realpaths['nonexistant'])
+ realpaths['/mnt/symlink'] = stubs "Pathname"
+ realpaths['/mnt/symlink'].stubs(:realpath).returns(realpaths['/mnt/nfs/dest'])
+ realpaths['/mnt/symlink'].stubs(:exist?).returns(true)
- realpaths.each do |path, value|
- Pathname.stubs(:new).with(path).returns(value)
- end
+ realpaths['/mnt/symlink/nonexistant'] = stubs "Pathname"
+ realpaths['/mnt/symlink/nonexistant'].stubs(:realpath).raises(Errno::ENOENT)
+ realpaths['/mnt/symlink/nonexistant'].stubs(:exist?).returns(false)
+ realpaths['/mnt/symlink/nonexistant'].stubs(:dirname).returns(realpaths['/mnt/symlink'])
+ realpaths['/mnt/symlink/nonexistant'].stubs(:basename).returns(realpaths['nonexistant'])
- realpath('/mnt/symlink/nonexistant').should == '/mnt/nfs/dest/nonexistant'
- end
- end
+ realpaths.each do |path, value|
+ Pathname.stubs(:new).with(path).returns(value)
+ end
- describe "get_selinux_current_context" do
- it "should return nil if no SELinux support" do
- self.expects(:selinux_support?).returns false
- get_selinux_current_context("/foo").should be_nil
- end
+ realpath('/mnt/symlink/nonexistant').should == '/mnt/nfs/dest/nonexistant'
+ end
+ end
- it "should return a context" do
- self.expects(:selinux_support?).returns true
- Selinux.expects(:lgetfilecon).with("/foo").returns [0, "user_u:role_r:type_t:s0"]
- get_selinux_current_context("/foo").should == "user_u:role_r:type_t:s0"
- end
+ describe "get_selinux_current_context" do
+ it "should return nil if no SELinux support" do
+ self.expects(:selinux_support?).returns false
+ get_selinux_current_context("/foo").should be_nil
+ end
- it "should return nil if lgetfilecon fails" do
- self.expects(:selinux_support?).returns true
- Selinux.expects(:lgetfilecon).with("/foo").returns -1
- get_selinux_current_context("/foo").should be_nil
- end
+ it "should return a context" do
+ self.expects(:selinux_support?).returns true
+ Selinux.expects(:lgetfilecon).with("/foo").returns [0, "user_u:role_r:type_t:s0"]
+ get_selinux_current_context("/foo").should == "user_u:role_r:type_t:s0"
end
- describe "get_selinux_default_context" do
- it "should return nil if no SELinux support" do
- self.expects(:selinux_support?).returns false
- get_selinux_default_context("/foo").should be_nil
- end
+ it "should return nil if lgetfilecon fails" do
+ self.expects(:selinux_support?).returns true
+ Selinux.expects(:lgetfilecon).with("/foo").returns -1
+ get_selinux_current_context("/foo").should be_nil
+ end
+ end
- it "should return a context if a default context exists" do
- self.expects(:selinux_support?).returns true
- fstat = stub 'File::Stat', :mode => 0
- File.expects(:lstat).with("/foo").returns fstat
- self.expects(:find_fs).with("/foo").returns "ext3"
- Selinux.expects(:matchpathcon).with("/foo", 0).returns [0, "user_u:role_r:type_t:s0"]
- get_selinux_default_context("/foo").should == "user_u:role_r:type_t:s0"
- end
+ describe "get_selinux_default_context" do
+ it "should return nil if no SELinux support" do
+ self.expects(:selinux_support?).returns false
+ get_selinux_default_context("/foo").should be_nil
+ end
- it "should return nil if matchpathcon returns failure" do
- self.expects(:selinux_support?).returns true
- fstat = stub 'File::Stat', :mode => 0
- File.expects(:lstat).with("/foo").returns fstat
- self.expects(:find_fs).with("/foo").returns "ext3"
- Selinux.expects(:matchpathcon).with("/foo", 0).returns -1
- get_selinux_default_context("/foo").should be_nil
- end
+ it "should return a context if a default context exists" do
+ self.expects(:selinux_support?).returns true
+ fstat = stub 'File::Stat', :mode => 0
+ File.expects(:lstat).with("/foo").returns fstat
+ self.expects(:find_fs).with("/foo").returns "ext3"
+ Selinux.expects(:matchpathcon).with("/foo", 0).returns [0, "user_u:role_r:type_t:s0"]
+ get_selinux_default_context("/foo").should == "user_u:role_r:type_t:s0"
+ end
- it "should return nil if selinux_label_support returns false" do
- self.expects(:selinux_support?).returns true
- self.expects(:find_fs).with("/foo").returns "nfs"
- get_selinux_default_context("/foo").should be_nil
- end
+ it "should return nil if matchpathcon returns failure" do
+ self.expects(:selinux_support?).returns true
+ fstat = stub 'File::Stat', :mode => 0
+ File.expects(:lstat).with("/foo").returns fstat
+ self.expects(:find_fs).with("/foo").returns "ext3"
+ Selinux.expects(:matchpathcon).with("/foo", 0).returns -1
+ get_selinux_default_context("/foo").should be_nil
+ end
+ it "should return nil if selinux_label_support returns false" do
+ self.expects(:selinux_support?).returns true
+ self.expects(:find_fs).with("/foo").returns "nfs"
+ get_selinux_default_context("/foo").should be_nil
end
- describe "parse_selinux_context" do
- it "should return nil if no context is passed" do
- parse_selinux_context(:seluser, nil).should be_nil
- end
+ end
- it "should return nil if the context is 'unlabeled'" do
- parse_selinux_context(:seluser, "unlabeled").should be_nil
- end
+ describe "parse_selinux_context" do
+ it "should return nil if no context is passed" do
+ parse_selinux_context(:seluser, nil).should be_nil
+ end
- it "should return the user type when called with :seluser" do
- parse_selinux_context(:seluser, "user_u:role_r:type_t:s0").should == "user_u"
- end
+ it "should return nil if the context is 'unlabeled'" do
+ parse_selinux_context(:seluser, "unlabeled").should be_nil
+ end
- it "should return the role type when called with :selrole" do
- parse_selinux_context(:selrole, "user_u:role_r:type_t:s0").should == "role_r"
- end
+ it "should return the user type when called with :seluser" do
+ parse_selinux_context(:seluser, "user_u:role_r:type_t:s0").should == "user_u"
+ end
- it "should return the type type when called with :seltype" do
- parse_selinux_context(:seltype, "user_u:role_r:type_t:s0").should == "type_t"
- end
+ it "should return the role type when called with :selrole" do
+ parse_selinux_context(:selrole, "user_u:role_r:type_t:s0").should == "role_r"
+ end
- it "should return nil for :selrange when no range is returned" do
- parse_selinux_context(:selrange, "user_u:role_r:type_t").should be_nil
- end
+ it "should return the type type when called with :seltype" do
+ parse_selinux_context(:seltype, "user_u:role_r:type_t:s0").should == "type_t"
+ end
- it "should return the range type when called with :selrange" do
- parse_selinux_context(:selrange, "user_u:role_r:type_t:s0").should == "s0"
- end
+ it "should return nil for :selrange when no range is returned" do
+ parse_selinux_context(:selrange, "user_u:role_r:type_t").should be_nil
+ end
- describe "with a variety of SELinux range formats" do
- ['s0', 's0:c3', 's0:c3.c123', 's0:c3,c5,c8', 'TopSecret', 'TopSecret,Classified', 'Patient_Record'].each do |range|
- it "should parse range '#{range}'" do
- parse_selinux_context(:selrange, "user_u:role_r:type_t:#{range}").should == range
- end
- end
- end
+ it "should return the range type when called with :selrange" do
+ parse_selinux_context(:selrange, "user_u:role_r:type_t:s0").should == "s0"
end
- describe "set_selinux_context" do
- before :each do
- fh = stub 'fh', :close => nil
- File.stubs(:open).with("/proc/mounts").returns fh
- fh.stubs(:read_nonblock).returns(
- "rootfs / rootfs rw 0 0\n/dev/root / ext3 rw,relatime,errors=continue,user_xattr,acl,data=ordered 0 0\n"+
- "/dev /dev tmpfs rw,relatime,mode=755 0 0\n/proc /proc proc rw,relatime 0 0\n"+
- "/sys /sys sysfs rw,relatime 0 0\n"
- ).then.raises EOFError
+ describe "with a variety of SELinux range formats" do
+ ['s0', 's0:c3', 's0:c3.c123', 's0:c3,c5,c8', 'TopSecret', 'TopSecret,Classified', 'Patient_Record'].each do |range|
+ it "should parse range '#{range}'" do
+ parse_selinux_context(:selrange, "user_u:role_r:type_t:#{range}").should == range
end
+ end
+ end
+ end
+
+ describe "set_selinux_context" do
+ before :each do
+ fh = stub 'fh', :close => nil
+ File.stubs(:open).with("/proc/mounts").returns fh
+ fh.stubs(:read_nonblock).returns(
+ "rootfs / rootfs rw 0 0\n/dev/root / ext3 rw,relatime,errors=continue,user_xattr,acl,data=ordered 0 0\n"+
+ "/dev /dev tmpfs rw,relatime,mode=755 0 0\n/proc /proc proc rw,relatime 0 0\n"+
+ "/sys /sys sysfs rw,relatime 0 0\n"
+ ).then.raises EOFError
+ end
- it "should return nil if there is no SELinux support" do
- self.expects(:selinux_support?).returns false
- set_selinux_context("/foo", "user_u:role_r:type_t:s0").should be_nil
- end
+ it "should return nil if there is no SELinux support" do
+ self.expects(:selinux_support?).returns false
+ set_selinux_context("/foo", "user_u:role_r:type_t:s0").should be_nil
+ end
- it "should return nil if selinux_label_support returns false" do
- self.expects(:selinux_support?).returns true
- self.expects(:selinux_label_support?).with("/foo").returns false
- set_selinux_context("/foo", "user_u:role_r:type_t:s0").should be_nil
- end
+ it "should return nil if selinux_label_support returns false" do
+ self.expects(:selinux_support?).returns true
+ self.expects(:selinux_label_support?).with("/foo").returns false
+ set_selinux_context("/foo", "user_u:role_r:type_t:s0").should be_nil
+ end
- it "should use lsetfilecon to set a context" do
- self.expects(:selinux_support?).returns true
- Selinux.expects(:lsetfilecon).with("/foo", "user_u:role_r:type_t:s0").returns 0
- set_selinux_context("/foo", "user_u:role_r:type_t:s0").should be_true
- end
+ it "should use lsetfilecon to set a context" do
+ self.expects(:selinux_support?).returns true
+ Selinux.expects(:lsetfilecon).with("/foo", "user_u:role_r:type_t:s0").returns 0
+ set_selinux_context("/foo", "user_u:role_r:type_t:s0").should be_true
+ end
- it "should use lsetfilecon to set user_u user context" do
- self.expects(:selinux_support?).returns true
- Selinux.expects(:lgetfilecon).with("/foo").returns [0, "foo:role_r:type_t:s0"]
- Selinux.expects(:lsetfilecon).with("/foo", "user_u:role_r:type_t:s0").returns 0
- set_selinux_context("/foo", "user_u", :seluser).should be_true
- end
+ it "should use lsetfilecon to set user_u user context" do
+ self.expects(:selinux_support?).returns true
+ Selinux.expects(:lgetfilecon).with("/foo").returns [0, "foo:role_r:type_t:s0"]
+ Selinux.expects(:lsetfilecon).with("/foo", "user_u:role_r:type_t:s0").returns 0
+ set_selinux_context("/foo", "user_u", :seluser).should be_true
+ end
- it "should use lsetfilecon to set role_r role context" do
- self.expects(:selinux_support?).returns true
- Selinux.expects(:lgetfilecon).with("/foo").returns [0, "user_u:foo:type_t:s0"]
- Selinux.expects(:lsetfilecon).with("/foo", "user_u:role_r:type_t:s0").returns 0
- set_selinux_context("/foo", "role_r", :selrole).should be_true
- end
+ it "should use lsetfilecon to set role_r role context" do
+ self.expects(:selinux_support?).returns true
+ Selinux.expects(:lgetfilecon).with("/foo").returns [0, "user_u:foo:type_t:s0"]
+ Selinux.expects(:lsetfilecon).with("/foo", "user_u:role_r:type_t:s0").returns 0
+ set_selinux_context("/foo", "role_r", :selrole).should be_true
+ end
- it "should use lsetfilecon to set type_t type context" do
- self.expects(:selinux_support?).returns true
- Selinux.expects(:lgetfilecon).with("/foo").returns [0, "user_u:role_r:foo:s0"]
- Selinux.expects(:lsetfilecon).with("/foo", "user_u:role_r:type_t:s0").returns 0
- set_selinux_context("/foo", "type_t", :seltype).should be_true
- end
+ it "should use lsetfilecon to set type_t type context" do
+ self.expects(:selinux_support?).returns true
+ Selinux.expects(:lgetfilecon).with("/foo").returns [0, "user_u:role_r:foo:s0"]
+ Selinux.expects(:lsetfilecon).with("/foo", "user_u:role_r:type_t:s0").returns 0
+ set_selinux_context("/foo", "type_t", :seltype).should be_true
+ end
- it "should use lsetfilecon to set s0:c3,c5 range context" do
- self.expects(:selinux_support?).returns true
- Selinux.expects(:lgetfilecon).with("/foo").returns [0, "user_u:role_r:type_t:s0"]
- Selinux.expects(:lsetfilecon).with("/foo", "user_u:role_r:type_t:s0:c3,c5").returns 0
- set_selinux_context("/foo", "s0:c3,c5", :selrange).should be_true
- end
+ it "should use lsetfilecon to set s0:c3,c5 range context" do
+ self.expects(:selinux_support?).returns true
+ Selinux.expects(:lgetfilecon).with("/foo").returns [0, "user_u:role_r:type_t:s0"]
+ Selinux.expects(:lsetfilecon).with("/foo", "user_u:role_r:type_t:s0:c3,c5").returns 0
+ set_selinux_context("/foo", "s0:c3,c5", :selrange).should be_true
end
+ end
- describe "set_selinux_default_context" do
- it "should return nil if there is no SELinux support" do
- self.expects(:selinux_support?).returns false
- set_selinux_default_context("/foo").should be_nil
- end
+ describe "set_selinux_default_context" do
+ it "should return nil if there is no SELinux support" do
+ self.expects(:selinux_support?).returns false
+ set_selinux_default_context("/foo").should be_nil
+ end
- it "should return nil if no default context exists" do
- self.expects(:get_selinux_default_context).with("/foo").returns nil
- set_selinux_default_context("/foo").should be_nil
- end
+ it "should return nil if no default context exists" do
+ self.expects(:get_selinux_default_context).with("/foo").returns nil
+ set_selinux_default_context("/foo").should be_nil
+ end
- it "should do nothing and return nil if the current context matches the default context" do
- self.expects(:get_selinux_default_context).with("/foo").returns "user_u:role_r:type_t"
- self.expects(:get_selinux_current_context).with("/foo").returns "user_u:role_r:type_t"
- set_selinux_default_context("/foo").should be_nil
- end
+ it "should do nothing and return nil if the current context matches the default context" do
+ self.expects(:get_selinux_default_context).with("/foo").returns "user_u:role_r:type_t"
+ self.expects(:get_selinux_current_context).with("/foo").returns "user_u:role_r:type_t"
+ set_selinux_default_context("/foo").should be_nil
+ end
- it "should set and return the default context if current and default do not match" do
- self.expects(:get_selinux_default_context).with("/foo").returns "user_u:role_r:type_t"
- self.expects(:get_selinux_current_context).with("/foo").returns "olduser_u:role_r:type_t"
- self.expects(:set_selinux_context).with("/foo", "user_u:role_r:type_t").returns true
- set_selinux_default_context("/foo").should == "user_u:role_r:type_t"
- end
+ it "should set and return the default context if current and default do not match" do
+ self.expects(:get_selinux_default_context).with("/foo").returns "user_u:role_r:type_t"
+ self.expects(:get_selinux_current_context).with("/foo").returns "olduser_u:role_r:type_t"
+ self.expects(:set_selinux_context).with("/foo", "user_u:role_r:type_t").returns true
+ set_selinux_default_context("/foo").should == "user_u:role_r:type_t"
end
+ end
end
diff --git a/spec/unit/util/settings/file_setting_spec.rb b/spec/unit/util/settings/file_setting_spec.rb
index 1fe372c..2870fbb 100755
--- a/spec/unit/util/settings/file_setting_spec.rb
+++ b/spec/unit/util/settings/file_setting_spec.rb
@@ -6,251 +6,251 @@ require 'puppet/util/settings'
require 'puppet/util/settings/file_setting'
describe Puppet::Util::Settings::FileSetting do
- FileSetting = Puppet::Util::Settings::FileSetting
+ FileSetting = Puppet::Util::Settings::FileSetting
+ before do
+ @basepath = Puppet.features.posix? ? "/somepath" : "C:/somepath"
+ end
+
+ describe "when determining whether the service user should be used" do
+ before do
+ @settings = mock 'settings'
+ @settings.stubs(:[]).with(:mkusers).returns false
+ @settings.stubs(:service_user_available?).returns true
+ end
+
+ it "should be true if the service user is available" do
+ @settings.expects(:service_user_available?).returns true
+ setting = FileSetting.new(:settings => @settings, :owner => "root", :desc => "a setting")
+ setting.should be_use_service_user
+ end
+
+ it "should be true if 'mkusers' is set" do
+ @settings.expects(:[]).with(:mkusers).returns true
+ setting = FileSetting.new(:settings => @settings, :owner => "root", :desc => "a setting")
+ setting.should be_use_service_user
+ end
+
+ it "should be false if the service user is not available and 'mkusers' is unset" do
+ setting = FileSetting.new(:settings => @settings, :owner => "root", :desc => "a setting")
+ setting.should be_use_service_user
+ end
+ end
+
+ describe "when setting the owner" do
+ it "should allow the file to be owned by root" do
+ root_owner = lambda { FileSetting.new(:settings => mock("settings"), :owner => "root", :desc => "a setting") }
+ root_owner.should_not raise_error
+ end
+
+ it "should allow the file to be owned by the service user" do
+ service_owner = lambda { FileSetting.new(:settings => mock("settings"), :owner => "service", :desc => "a setting") }
+ service_owner.should_not raise_error
+ end
+
+ it "should allow the ownership of the file to be unspecified" do
+ no_owner = lambda { FileSetting.new(:settings => mock("settings"), :desc => "a setting") }
+ no_owner.should_not raise_error
+ end
+
+ it "should not allow other owners" do
+ invalid_owner = lambda { FileSetting.new(:settings => mock("settings"), :owner => "invalid", :desc => "a setting") }
+ invalid_owner.should raise_error(FileSetting::SettingError)
+ end
+ end
+
+ describe "when reading the owner" do
+ it "should be root when the setting specifies root" do
+ setting = FileSetting.new(:settings => mock("settings"), :owner => "root", :desc => "a setting")
+ setting.owner.should == "root"
+ end
+
+ it "should be the owner of the service when the setting specifies service and the service user should be used" do
+ settings = mock("settings")
+ settings.stubs(:[]).returns "the_service"
+
+ setting = FileSetting.new(:settings => settings, :owner => "service", :desc => "a setting")
+ setting.expects(:use_service_user?).returns true
+ setting.owner.should == "the_service"
+ end
+
+ it "should be the root when the setting specifies service and the service user should not be used" do
+ settings = mock("settings")
+ settings.stubs(:[]).returns "the_service"
+
+ setting = FileSetting.new(:settings => settings, :owner => "service", :desc => "a setting")
+ setting.expects(:use_service_user?).returns false
+ setting.owner.should == "root"
+ end
+
+ it "should be nil when the owner is unspecified" do
+ FileSetting.new(:settings => mock("settings"), :desc => "a setting").owner.should be_nil
+ end
+ end
+
+ describe "when setting the group" do
+ it "should allow the group to be service" do
+ service_group = lambda { FileSetting.new(:settings => mock("settings"), :group => "service", :desc => "a setting") }
+ service_group.should_not raise_error
+ end
+
+ it "should allow the group to be unspecified" do
+ no_group = lambda { FileSetting.new(:settings => mock("settings"), :desc => "a setting") }
+ no_group.should_not raise_error
+ end
+
+ it "should not allow invalid groups" do
+ invalid_group = lambda { FileSetting.new(:settings => mock("settings"), :group => "invalid", :desc => "a setting") }
+ invalid_group.should raise_error(FileSetting::SettingError)
+ end
+ end
+
+ describe "when reading the group" do
+ it "should be service when the setting specifies service" do
+ setting = FileSetting.new(:settings => mock("settings", :[] => "the_service"), :group => "service", :desc => "a setting")
+ setting.group.should == "the_service"
+ end
+
+ it "should be nil when the group is unspecified" do
+ FileSetting.new(:settings => mock("settings"), :desc => "a setting").group.should be_nil
+ end
+ end
+
+ it "should be able to be converted into a resource" do
+ FileSetting.new(:settings => mock("settings"), :desc => "eh").should respond_to(:to_resource)
+ end
+
+ describe "when being converted to a resource" do
before do
- @basepath = Puppet.features.posix? ? "/somepath" : "C:/somepath"
- end
-
- describe "when determining whether the service user should be used" do
- before do
- @settings = mock 'settings'
- @settings.stubs(:[]).with(:mkusers).returns false
- @settings.stubs(:service_user_available?).returns true
- end
+ @settings = mock 'settings'
+ @file = Puppet::Util::Settings::FileSetting.new(:settings => @settings, :desc => "eh", :name => :mydir, :section => "mysect")
+ @settings.stubs(:value).with(:mydir).returns @basepath
+ end
+
+ it "should skip files that cannot determine their types" do
+ @file.expects(:type).returns nil
+ @file.to_resource.should be_nil
+ end
+
+ it "should skip non-existent files if 'create_files' is not enabled" do
+ @file.expects(:create_files?).returns false
+ @file.expects(:type).returns :file
+ File.expects(:exist?).with(@basepath).returns false
+ @file.to_resource.should be_nil
+ end
+
+ it "should manage existent files even if 'create_files' is not enabled" do
+ @file.expects(:create_files?).returns false
+ @file.expects(:type).returns :file
+ File.expects(:exist?).with(@basepath).returns true
+ @file.to_resource.should be_instance_of(Puppet::Resource)
+ end
+
+ describe "on POSIX systems" do
+ confine "no /dev on Microsoft Windows" => Puppet.features.posix?
+
+ it "should skip files in /dev" do
+ @settings.stubs(:value).with(:mydir).returns "/dev/file"
+ @file.to_resource.should be_nil
+ end
+ end
+
+ it "should skip files whose paths are not strings" do
+ @settings.stubs(:value).with(:mydir).returns :foo
+ @file.to_resource.should be_nil
+ end
+
+ it "should return a file resource with the path set appropriately" do
+ resource = @file.to_resource
+ resource.type.should == "File"
+ resource.title.should == @basepath
+ end
+
+ it "should fully qualified returned files if necessary (#795)" do
+ @settings.stubs(:value).with(:mydir).returns "myfile"
+ @file.to_resource.title.should == File.join(Dir.getwd, "myfile")
+ end
+
+ it "should set the mode on the file if a mode is provided" do
+ @file.mode = 0755
+
+ @file.to_resource[:mode].should == 0755
+ end
+
+ it "should not set the mode on a the file if manage_internal_file_permissions is disabled" do
+ Puppet[:manage_internal_file_permissions] = false
+
+ @file.stubs(:mode).returns(0755)
+
+ @file.to_resource[:mode].should == nil
+ end
+
+ it "should set the owner if running as root and the owner is provided" do
+ Puppet.features.expects(:root?).returns true
+ @file.stubs(:owner).returns "foo"
+ @file.to_resource[:owner].should == "foo"
+ end
+
+ it "should not set the owner if manage_internal_file_permissions is disabled" do
+ Puppet[:manage_internal_file_permissions] = false
+ Puppet.features.stubs(:root?).returns true
+ @file.stubs(:owner).returns "foo"
+
+ @file.to_resource[:owner].should == nil
+ end
+
+ it "should set the group if running as root and the group is provided" do
+ Puppet.features.expects(:root?).returns true
+ @file.stubs(:group).returns "foo"
+ @file.to_resource[:group].should == "foo"
+ end
+
+ it "should not set the group if manage_internal_file_permissions is disabled" do
+ Puppet[:manage_internal_file_permissions] = false
+ Puppet.features.stubs(:root?).returns true
+ @file.stubs(:group).returns "foo"
+
+ @file.to_resource[:group].should == nil
+ end
+
+
+ it "should not set owner if not running as root" do
+ Puppet.features.expects(:root?).returns false
+ @file.stubs(:owner).returns "foo"
+ @file.to_resource[:owner].should be_nil
+ end
+
+ it "should not set group if not running as root" do
+ Puppet.features.expects(:root?).returns false
+ @file.stubs(:group).returns "foo"
+ @file.to_resource[:group].should be_nil
+ end
+
+ it "should set :ensure to the file type" do
+ @file.expects(:type).returns :directory
+ @file.to_resource[:ensure].should == :directory
+ end
+
+ it "should set the loglevel to :debug" do
+ @file.to_resource[:loglevel].should == :debug
+ end
+
+ it "should set the backup to false" do
+ @file.to_resource[:backup].should be_false
+ end
+
+ it "should tag the resource with the settings section" do
+ @file.expects(:section).returns "mysect"
+ @file.to_resource.should be_tagged("mysect")
+ end
+
+ it "should tag the resource with the setting name" do
+ @file.to_resource.should be_tagged("mydir")
+ end
- it "should be true if the service user is available" do
- @settings.expects(:service_user_available?).returns true
- setting = FileSetting.new(:settings => @settings, :owner => "root", :desc => "a setting")
- setting.should be_use_service_user
- end
-
- it "should be true if 'mkusers' is set" do
- @settings.expects(:[]).with(:mkusers).returns true
- setting = FileSetting.new(:settings => @settings, :owner => "root", :desc => "a setting")
- setting.should be_use_service_user
- end
-
- it "should be false if the service user is not available and 'mkusers' is unset" do
- setting = FileSetting.new(:settings => @settings, :owner => "root", :desc => "a setting")
- setting.should be_use_service_user
- end
- end
-
- describe "when setting the owner" do
- it "should allow the file to be owned by root" do
- root_owner = lambda { FileSetting.new(:settings => mock("settings"), :owner => "root", :desc => "a setting") }
- root_owner.should_not raise_error
- end
-
- it "should allow the file to be owned by the service user" do
- service_owner = lambda { FileSetting.new(:settings => mock("settings"), :owner => "service", :desc => "a setting") }
- service_owner.should_not raise_error
- end
-
- it "should allow the ownership of the file to be unspecified" do
- no_owner = lambda { FileSetting.new(:settings => mock("settings"), :desc => "a setting") }
- no_owner.should_not raise_error
- end
-
- it "should not allow other owners" do
- invalid_owner = lambda { FileSetting.new(:settings => mock("settings"), :owner => "invalid", :desc => "a setting") }
- invalid_owner.should raise_error(FileSetting::SettingError)
- end
- end
-
- describe "when reading the owner" do
- it "should be root when the setting specifies root" do
- setting = FileSetting.new(:settings => mock("settings"), :owner => "root", :desc => "a setting")
- setting.owner.should == "root"
- end
-
- it "should be the owner of the service when the setting specifies service and the service user should be used" do
- settings = mock("settings")
- settings.stubs(:[]).returns "the_service"
-
- setting = FileSetting.new(:settings => settings, :owner => "service", :desc => "a setting")
- setting.expects(:use_service_user?).returns true
- setting.owner.should == "the_service"
- end
-
- it "should be the root when the setting specifies service and the service user should not be used" do
- settings = mock("settings")
- settings.stubs(:[]).returns "the_service"
-
- setting = FileSetting.new(:settings => settings, :owner => "service", :desc => "a setting")
- setting.expects(:use_service_user?).returns false
- setting.owner.should == "root"
- end
-
- it "should be nil when the owner is unspecified" do
- FileSetting.new(:settings => mock("settings"), :desc => "a setting").owner.should be_nil
- end
- end
-
- describe "when setting the group" do
- it "should allow the group to be service" do
- service_group = lambda { FileSetting.new(:settings => mock("settings"), :group => "service", :desc => "a setting") }
- service_group.should_not raise_error
- end
-
- it "should allow the group to be unspecified" do
- no_group = lambda { FileSetting.new(:settings => mock("settings"), :desc => "a setting") }
- no_group.should_not raise_error
- end
-
- it "should not allow invalid groups" do
- invalid_group = lambda { FileSetting.new(:settings => mock("settings"), :group => "invalid", :desc => "a setting") }
- invalid_group.should raise_error(FileSetting::SettingError)
- end
- end
-
- describe "when reading the group" do
- it "should be service when the setting specifies service" do
- setting = FileSetting.new(:settings => mock("settings", :[] => "the_service"), :group => "service", :desc => "a setting")
- setting.group.should == "the_service"
- end
-
- it "should be nil when the group is unspecified" do
- FileSetting.new(:settings => mock("settings"), :desc => "a setting").group.should be_nil
- end
- end
-
- it "should be able to be converted into a resource" do
- FileSetting.new(:settings => mock("settings"), :desc => "eh").should respond_to(:to_resource)
- end
-
- describe "when being converted to a resource" do
- before do
- @settings = mock 'settings'
- @file = Puppet::Util::Settings::FileSetting.new(:settings => @settings, :desc => "eh", :name => :mydir, :section => "mysect")
- @settings.stubs(:value).with(:mydir).returns @basepath
- end
-
- it "should skip files that cannot determine their types" do
- @file.expects(:type).returns nil
- @file.to_resource.should be_nil
- end
-
- it "should skip non-existent files if 'create_files' is not enabled" do
- @file.expects(:create_files?).returns false
- @file.expects(:type).returns :file
- File.expects(:exist?).with(@basepath).returns false
- @file.to_resource.should be_nil
- end
-
- it "should manage existent files even if 'create_files' is not enabled" do
- @file.expects(:create_files?).returns false
- @file.expects(:type).returns :file
- File.expects(:exist?).with(@basepath).returns true
- @file.to_resource.should be_instance_of(Puppet::Resource)
- end
-
- describe "on POSIX systems" do
- confine "no /dev on Microsoft Windows" => Puppet.features.posix?
-
- it "should skip files in /dev" do
- @settings.stubs(:value).with(:mydir).returns "/dev/file"
- @file.to_resource.should be_nil
- end
- end
-
- it "should skip files whose paths are not strings" do
- @settings.stubs(:value).with(:mydir).returns :foo
- @file.to_resource.should be_nil
- end
-
- it "should return a file resource with the path set appropriately" do
- resource = @file.to_resource
- resource.type.should == "File"
- resource.title.should == @basepath
- end
-
- it "should fully qualified returned files if necessary (#795)" do
- @settings.stubs(:value).with(:mydir).returns "myfile"
- @file.to_resource.title.should == File.join(Dir.getwd, "myfile")
- end
-
- it "should set the mode on the file if a mode is provided" do
- @file.mode = 0755
-
- @file.to_resource[:mode].should == 0755
- end
-
- it "should not set the mode on a the file if manage_internal_file_permissions is disabled" do
- Puppet[:manage_internal_file_permissions] = false
-
- @file.stubs(:mode).returns(0755)
-
- @file.to_resource[:mode].should == nil
- end
-
- it "should set the owner if running as root and the owner is provided" do
- Puppet.features.expects(:root?).returns true
- @file.stubs(:owner).returns "foo"
- @file.to_resource[:owner].should == "foo"
- end
-
- it "should not set the owner if manage_internal_file_permissions is disabled" do
- Puppet[:manage_internal_file_permissions] = false
- Puppet.features.stubs(:root?).returns true
- @file.stubs(:owner).returns "foo"
-
- @file.to_resource[:owner].should == nil
- end
-
- it "should set the group if running as root and the group is provided" do
- Puppet.features.expects(:root?).returns true
- @file.stubs(:group).returns "foo"
- @file.to_resource[:group].should == "foo"
- end
-
- it "should not set the group if manage_internal_file_permissions is disabled" do
- Puppet[:manage_internal_file_permissions] = false
- Puppet.features.stubs(:root?).returns true
- @file.stubs(:group).returns "foo"
-
- @file.to_resource[:group].should == nil
- end
-
-
- it "should not set owner if not running as root" do
- Puppet.features.expects(:root?).returns false
- @file.stubs(:owner).returns "foo"
- @file.to_resource[:owner].should be_nil
- end
-
- it "should not set group if not running as root" do
- Puppet.features.expects(:root?).returns false
- @file.stubs(:group).returns "foo"
- @file.to_resource[:group].should be_nil
- end
-
- it "should set :ensure to the file type" do
- @file.expects(:type).returns :directory
- @file.to_resource[:ensure].should == :directory
- end
-
- it "should set the loglevel to :debug" do
- @file.to_resource[:loglevel].should == :debug
- end
-
- it "should set the backup to false" do
- @file.to_resource[:backup].should be_false
- end
-
- it "should tag the resource with the settings section" do
- @file.expects(:section).returns "mysect"
- @file.to_resource.should be_tagged("mysect")
- end
-
- it "should tag the resource with the setting name" do
- @file.to_resource.should be_tagged("mydir")
- end
-
- it "should tag the resource with 'settings'" do
- @file.to_resource.should be_tagged("settings")
- end
+ it "should tag the resource with 'settings'" do
+ @file.to_resource.should be_tagged("settings")
end
+ end
end
diff --git a/spec/unit/util/settings_spec.rb b/spec/unit/util/settings_spec.rb
index d792510..81cab79 100755
--- a/spec/unit/util/settings_spec.rb
+++ b/spec/unit/util/settings_spec.rb
@@ -3,1120 +3,1120 @@
require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::Util::Settings do
- describe "when specifying defaults" do
- before do
- @settings = Puppet::Util::Settings.new
- end
+ describe "when specifying defaults" do
+ before do
+ @settings = Puppet::Util::Settings.new
+ end
- it "should start with no defined parameters" do
- @settings.params.length.should == 0
- end
+ it "should start with no defined parameters" do
+ @settings.params.length.should == 0
+ end
- it "should allow specification of default values associated with a section as an array" do
- @settings.setdefaults(:section, :myvalue => ["defaultval", "my description"])
- end
+ it "should allow specification of default values associated with a section as an array" do
+ @settings.setdefaults(:section, :myvalue => ["defaultval", "my description"])
+ end
- it "should not allow duplicate parameter specifications" do
- @settings.setdefaults(:section, :myvalue => ["a", "b"])
- lambda { @settings.setdefaults(:section, :myvalue => ["c", "d"]) }.should raise_error(ArgumentError)
- end
+ it "should not allow duplicate parameter specifications" do
+ @settings.setdefaults(:section, :myvalue => ["a", "b"])
+ lambda { @settings.setdefaults(:section, :myvalue => ["c", "d"]) }.should raise_error(ArgumentError)
+ end
- it "should allow specification of default values associated with a section as a hash" do
- @settings.setdefaults(:section, :myvalue => {:default => "defaultval", :desc => "my description"})
- end
+ it "should allow specification of default values associated with a section as a hash" do
+ @settings.setdefaults(:section, :myvalue => {:default => "defaultval", :desc => "my description"})
+ end
- it "should consider defined parameters to be valid" do
- @settings.setdefaults(:section, :myvalue => ["defaultval", "my description"])
- @settings.valid?(:myvalue).should be_true
- end
+ it "should consider defined parameters to be valid" do
+ @settings.setdefaults(:section, :myvalue => ["defaultval", "my description"])
+ @settings.valid?(:myvalue).should be_true
+ end
- it "should require a description when defaults are specified with an array" do
- lambda { @settings.setdefaults(:section, :myvalue => ["a value"]) }.should raise_error(ArgumentError)
- end
+ it "should require a description when defaults are specified with an array" do
+ lambda { @settings.setdefaults(:section, :myvalue => ["a value"]) }.should raise_error(ArgumentError)
+ end
- it "should require a description when defaults are specified with a hash" do
- lambda { @settings.setdefaults(:section, :myvalue => {:default => "a value"}) }.should raise_error(ArgumentError)
- end
+ it "should require a description when defaults are specified with a hash" do
+ lambda { @settings.setdefaults(:section, :myvalue => {:default => "a value"}) }.should raise_error(ArgumentError)
+ end
- it "should raise an error if we can't guess the type" do
- lambda { @settings.setdefaults(:section, :myvalue => {:default => Object.new, :desc => "An impossible object"}) }.should raise_error(ArgumentError)
- end
+ it "should raise an error if we can't guess the type" do
+ lambda { @settings.setdefaults(:section, :myvalue => {:default => Object.new, :desc => "An impossible object"}) }.should raise_error(ArgumentError)
+ end
- it "should support specifying owner, group, and mode when specifying files" do
- @settings.setdefaults(:section, :myvalue => {:default => "/some/file", :owner => "service", :mode => "boo", :group => "service", :desc => "whatever"})
- end
+ it "should support specifying owner, group, and mode when specifying files" do
+ @settings.setdefaults(:section, :myvalue => {:default => "/some/file", :owner => "service", :mode => "boo", :group => "service", :desc => "whatever"})
+ end
- it "should support specifying a short name" do
- @settings.setdefaults(:section, :myvalue => {:default => "w", :desc => "b", :short => "m"})
- end
+ it "should support specifying a short name" do
+ @settings.setdefaults(:section, :myvalue => {:default => "w", :desc => "b", :short => "m"})
+ end
- it "should support specifying the setting type" do
- @settings.setdefaults(:section, :myvalue => {:default => "/w", :desc => "b", :type => :setting})
- @settings.setting(:myvalue).should be_instance_of(Puppet::Util::Settings::Setting)
- end
+ it "should support specifying the setting type" do
+ @settings.setdefaults(:section, :myvalue => {:default => "/w", :desc => "b", :type => :setting})
+ @settings.setting(:myvalue).should be_instance_of(Puppet::Util::Settings::Setting)
+ end
- it "should fail if an invalid setting type is specified" do
- lambda { @settings.setdefaults(:section, :myvalue => {:default => "w", :desc => "b", :type => :foo}) }.should raise_error(ArgumentError)
- end
+ it "should fail if an invalid setting type is specified" do
+ lambda { @settings.setdefaults(:section, :myvalue => {:default => "w", :desc => "b", :type => :foo}) }.should raise_error(ArgumentError)
+ end
- it "should fail when short names conflict" do
- @settings.setdefaults(:section, :myvalue => {:default => "w", :desc => "b", :short => "m"})
- lambda { @settings.setdefaults(:section, :myvalue => {:default => "w", :desc => "b", :short => "m"}) }.should raise_error(ArgumentError)
- end
+ it "should fail when short names conflict" do
+ @settings.setdefaults(:section, :myvalue => {:default => "w", :desc => "b", :short => "m"})
+ lambda { @settings.setdefaults(:section, :myvalue => {:default => "w", :desc => "b", :short => "m"}) }.should raise_error(ArgumentError)
end
+ end
- describe "when setting values" do
- before do
- @settings = Puppet::Util::Settings.new
- @settings.setdefaults :main, :myval => ["val", "desc"]
- @settings.setdefaults :main, :bool => [true, "desc"]
- end
+ describe "when setting values" do
+ before do
+ @settings = Puppet::Util::Settings.new
+ @settings.setdefaults :main, :myval => ["val", "desc"]
+ @settings.setdefaults :main, :bool => [true, "desc"]
+ end
- it "should provide a method for setting values from other objects" do
- @settings[:myval] = "something else"
- @settings[:myval].should == "something else"
- end
+ it "should provide a method for setting values from other objects" do
+ @settings[:myval] = "something else"
+ @settings[:myval].should == "something else"
+ end
- it "should support a getopt-specific mechanism for setting values" do
- @settings.handlearg("--myval", "newval")
- @settings[:myval].should == "newval"
- end
+ it "should support a getopt-specific mechanism for setting values" do
+ @settings.handlearg("--myval", "newval")
+ @settings[:myval].should == "newval"
+ end
- it "should support a getopt-specific mechanism for turning booleans off" do
- @settings[:bool] = true
- @settings.handlearg("--no-bool", "")
- @settings[:bool].should == false
- end
+ it "should support a getopt-specific mechanism for turning booleans off" do
+ @settings[:bool] = true
+ @settings.handlearg("--no-bool", "")
+ @settings[:bool].should == false
+ end
- it "should support a getopt-specific mechanism for turning booleans on" do
- # Turn it off first
- @settings[:bool] = false
- @settings.handlearg("--bool", "")
- @settings[:bool].should == true
- end
+ it "should support a getopt-specific mechanism for turning booleans on" do
+ # Turn it off first
+ @settings[:bool] = false
+ @settings.handlearg("--bool", "")
+ @settings[:bool].should == true
+ end
- it "should consider a cli setting with no argument to be a boolean" do
- # Turn it off first
- @settings[:bool] = false
- @settings.handlearg("--bool")
- @settings[:bool].should == true
- end
+ it "should consider a cli setting with no argument to be a boolean" do
+ # Turn it off first
+ @settings[:bool] = false
+ @settings.handlearg("--bool")
+ @settings[:bool].should == true
+ end
- it "should consider a cli setting with an empty string as an argument to be a boolean, if the setting itself is a boolean" do
- # Turn it off first
- @settings[:bool] = false
- @settings.handlearg("--bool", "")
- @settings[:bool].should == true
- end
+ it "should consider a cli setting with an empty string as an argument to be a boolean, if the setting itself is a boolean" do
+ # Turn it off first
+ @settings[:bool] = false
+ @settings.handlearg("--bool", "")
+ @settings[:bool].should == true
+ end
- it "should consider a cli setting with an empty string as an argument to be an empty argument, if the setting itself is not a boolean" do
- @settings[:myval] = "bob"
- @settings.handlearg("--myval", "")
- @settings[:myval].should == ""
- end
+ it "should consider a cli setting with an empty string as an argument to be an empty argument, if the setting itself is not a boolean" do
+ @settings[:myval] = "bob"
+ @settings.handlearg("--myval", "")
+ @settings[:myval].should == ""
+ end
- it "should consider a cli setting with a boolean as an argument to be a boolean" do
- # Turn it off first
- @settings[:bool] = false
- @settings.handlearg("--bool", "true")
- @settings[:bool].should == true
- end
+ it "should consider a cli setting with a boolean as an argument to be a boolean" do
+ # Turn it off first
+ @settings[:bool] = false
+ @settings.handlearg("--bool", "true")
+ @settings[:bool].should == true
+ end
- it "should not consider a cli setting of a non boolean with a boolean as an argument to be a boolean" do
- # Turn it off first
- @settings[:myval] = "bob"
- @settings.handlearg("--no-myval", "")
- @settings[:myval].should == ""
- end
+ it "should not consider a cli setting of a non boolean with a boolean as an argument to be a boolean" do
+ # Turn it off first
+ @settings[:myval] = "bob"
+ @settings.handlearg("--no-myval", "")
+ @settings[:myval].should == ""
+ end
- it "should clear the cache when setting getopt-specific values" do
- @settings.setdefaults :mysection, :one => ["whah", "yay"], :two => ["$one yay", "bah"]
- @settings[:two].should == "whah yay"
- @settings.handlearg("--one", "else")
- @settings[:two].should == "else yay"
- end
+ it "should clear the cache when setting getopt-specific values" do
+ @settings.setdefaults :mysection, :one => ["whah", "yay"], :two => ["$one yay", "bah"]
+ @settings[:two].should == "whah yay"
+ @settings.handlearg("--one", "else")
+ @settings[:two].should == "else yay"
+ end
- it "should not clear other values when setting getopt-specific values" do
- @settings[:myval] = "yay"
- @settings.handlearg("--no-bool", "")
- @settings[:myval].should == "yay"
- end
+ it "should not clear other values when setting getopt-specific values" do
+ @settings[:myval] = "yay"
+ @settings.handlearg("--no-bool", "")
+ @settings[:myval].should == "yay"
+ end
- it "should clear the list of used sections" do
- @settings.expects(:clearused)
- @settings[:myval] = "yay"
- end
+ it "should clear the list of used sections" do
+ @settings.expects(:clearused)
+ @settings[:myval] = "yay"
+ end
- it "should call passed blocks when values are set" do
- values = []
- @settings.setdefaults(:section, :hooker => {:default => "yay", :desc => "boo", :hook => lambda { |v| values << v }})
- values.should == []
+ it "should call passed blocks when values are set" do
+ values = []
+ @settings.setdefaults(:section, :hooker => {:default => "yay", :desc => "boo", :hook => lambda { |v| values << v }})
+ values.should == []
- @settings[:hooker] = "something"
- values.should == %w{something}
- end
+ @settings[:hooker] = "something"
+ values.should == %w{something}
+ end
- it "should call passed blocks when values are set via the command line" do
- values = []
- @settings.setdefaults(:section, :hooker => {:default => "yay", :desc => "boo", :hook => lambda { |v| values << v }})
- values.should == []
+ it "should call passed blocks when values are set via the command line" do
+ values = []
+ @settings.setdefaults(:section, :hooker => {:default => "yay", :desc => "boo", :hook => lambda { |v| values << v }})
+ values.should == []
- @settings.handlearg("--hooker", "yay")
+ @settings.handlearg("--hooker", "yay")
- values.should == %w{yay}
- end
+ values.should == %w{yay}
+ end
- it "should provide an option to call passed blocks during definition" do
- values = []
- @settings.setdefaults(:section, :hooker => {:default => "yay", :desc => "boo", :call_on_define => true, :hook => lambda { |v| values << v }})
- values.should == %w{yay}
- end
+ it "should provide an option to call passed blocks during definition" do
+ values = []
+ @settings.setdefaults(:section, :hooker => {:default => "yay", :desc => "boo", :call_on_define => true, :hook => lambda { |v| values << v }})
+ values.should == %w{yay}
+ end
- it "should pass the fully interpolated value to the hook when called on definition" do
- values = []
- @settings.setdefaults(:section, :one => ["test", "a"])
- @settings.setdefaults(:section, :hooker => {:default => "$one/yay", :desc => "boo", :call_on_define => true, :hook => lambda { |v| values << v }})
- values.should == %w{test/yay}
- end
+ it "should pass the fully interpolated value to the hook when called on definition" do
+ values = []
+ @settings.setdefaults(:section, :one => ["test", "a"])
+ @settings.setdefaults(:section, :hooker => {:default => "$one/yay", :desc => "boo", :call_on_define => true, :hook => lambda { |v| values << v }})
+ values.should == %w{test/yay}
+ end
- it "should munge values using the setting-specific methods" do
- @settings[:bool] = "false"
- @settings[:bool].should == false
- end
+ it "should munge values using the setting-specific methods" do
+ @settings[:bool] = "false"
+ @settings[:bool].should == false
+ end
- it "should prefer cli values to values set in Ruby code" do
- @settings.handlearg("--myval", "cliarg")
- @settings[:myval] = "memarg"
- @settings[:myval].should == "cliarg"
- end
+ it "should prefer cli values to values set in Ruby code" do
+ @settings.handlearg("--myval", "cliarg")
+ @settings[:myval] = "memarg"
+ @settings[:myval].should == "cliarg"
+ end
- it "should clear the list of environments" do
- Puppet::Node::Environment.expects(:clear).at_least(1)
- @settings[:myval] = "memarg"
- end
+ it "should clear the list of environments" do
+ Puppet::Node::Environment.expects(:clear).at_least(1)
+ @settings[:myval] = "memarg"
+ end
- it "should raise an error if we try to set 'name'" do
- lambda{ @settings[:name] = "foo" }.should raise_error(ArgumentError)
- end
+ it "should raise an error if we try to set 'name'" do
+ lambda{ @settings[:name] = "foo" }.should raise_error(ArgumentError)
+ end
- it "should raise an error if we try to set 'run_mode'" do
- lambda{ @settings[:run_mode] = "foo" }.should raise_error(ArgumentError)
- end
+ it "should raise an error if we try to set 'run_mode'" do
+ lambda{ @settings[:run_mode] = "foo" }.should raise_error(ArgumentError)
+ end
- it "should warn and use [master] if we ask for [puppetmasterd]" do
- Puppet.expects(:warning)
- @settings.set_value(:myval, "foo", :puppetmasterd)
+ it "should warn and use [master] if we ask for [puppetmasterd]" do
+ Puppet.expects(:warning)
+ @settings.set_value(:myval, "foo", :puppetmasterd)
- @settings.stubs(:run_mode).returns(:master)
- @settings.value(:myval).should == "foo"
- end
+ @settings.stubs(:run_mode).returns(:master)
+ @settings.value(:myval).should == "foo"
+ end
- it "should warn and use [agent] if we ask for [puppetd]" do
- Puppet.expects(:warning)
- @settings.set_value(:myval, "foo", :puppetd)
+ it "should warn and use [agent] if we ask for [puppetd]" do
+ Puppet.expects(:warning)
+ @settings.set_value(:myval, "foo", :puppetd)
- @settings.stubs(:run_mode).returns(:agent)
- @settings.value(:myval).should == "foo"
- end
+ @settings.stubs(:run_mode).returns(:agent)
+ @settings.value(:myval).should == "foo"
end
+ end
- describe "when returning values" do
- before do
- @settings = Puppet::Util::Settings.new
- @settings.setdefaults :section, :config => ["/my/file", "eh"], :one => ["ONE", "a"], :two => ["$one TWO", "b"], :three => ["$one $two THREE", "c"], :four => ["$two $three FOUR", "d"]
- FileTest.stubs(:exist?).returns true
- end
+ describe "when returning values" do
+ before do
+ @settings = Puppet::Util::Settings.new
+ @settings.setdefaults :section, :config => ["/my/file", "eh"], :one => ["ONE", "a"], :two => ["$one TWO", "b"], :three => ["$one $two THREE", "c"], :four => ["$two $three FOUR", "d"]
+ FileTest.stubs(:exist?).returns true
+ end
- it "should provide a mechanism for returning set values" do
- @settings[:one] = "other"
- @settings[:one].should == "other"
- end
+ it "should provide a mechanism for returning set values" do
+ @settings[:one] = "other"
+ @settings[:one].should == "other"
+ end
- it "should interpolate default values for other parameters into returned parameter values" do
- @settings[:one].should == "ONE"
- @settings[:two].should == "ONE TWO"
- @settings[:three].should == "ONE ONE TWO THREE"
- end
+ it "should interpolate default values for other parameters into returned parameter values" do
+ @settings[:one].should == "ONE"
+ @settings[:two].should == "ONE TWO"
+ @settings[:three].should == "ONE ONE TWO THREE"
+ end
- it "should interpolate default values that themselves need to be interpolated" do
- @settings[:four].should == "ONE TWO ONE ONE TWO THREE FOUR"
- end
+ it "should interpolate default values that themselves need to be interpolated" do
+ @settings[:four].should == "ONE TWO ONE ONE TWO THREE FOUR"
+ end
- it "should provide a method for returning uninterpolated values" do
- @settings[:two] = "$one tw0"
- @settings.uninterpolated_value(:two).should == "$one tw0"
- @settings.uninterpolated_value(:four).should == "$two $three FOUR"
- end
+ it "should provide a method for returning uninterpolated values" do
+ @settings[:two] = "$one tw0"
+ @settings.uninterpolated_value(:two).should == "$one tw0"
+ @settings.uninterpolated_value(:four).should == "$two $three FOUR"
+ end
- it "should interpolate set values for other parameters into returned parameter values" do
- @settings[:one] = "on3"
- @settings[:two] = "$one tw0"
- @settings[:three] = "$one $two thr33"
- @settings[:four] = "$one $two $three f0ur"
- @settings[:one].should == "on3"
- @settings[:two].should == "on3 tw0"
- @settings[:three].should == "on3 on3 tw0 thr33"
- @settings[:four].should == "on3 on3 tw0 on3 on3 tw0 thr33 f0ur"
- end
+ it "should interpolate set values for other parameters into returned parameter values" do
+ @settings[:one] = "on3"
+ @settings[:two] = "$one tw0"
+ @settings[:three] = "$one $two thr33"
+ @settings[:four] = "$one $two $three f0ur"
+ @settings[:one].should == "on3"
+ @settings[:two].should == "on3 tw0"
+ @settings[:three].should == "on3 on3 tw0 thr33"
+ @settings[:four].should == "on3 on3 tw0 on3 on3 tw0 thr33 f0ur"
+ end
- it "should not cache interpolated values such that stale information is returned" do
- @settings[:two].should == "ONE TWO"
- @settings[:one] = "one"
- @settings[:two].should == "one TWO"
- end
+ it "should not cache interpolated values such that stale information is returned" do
+ @settings[:two].should == "ONE TWO"
+ @settings[:one] = "one"
+ @settings[:two].should == "one TWO"
+ end
- it "should not cache values such that information from one environment is returned for another environment" do
- text = "[env1]\none = oneval\n[env2]\none = twoval\n"
- @settings.stubs(:read_file).returns(text)
- @settings.parse
+ it "should not cache values such that information from one environment is returned for another environment" do
+ text = "[env1]\none = oneval\n[env2]\none = twoval\n"
+ @settings.stubs(:read_file).returns(text)
+ @settings.parse
- @settings.value(:one, "env1").should == "oneval"
- @settings.value(:one, "env2").should == "twoval"
- end
+ @settings.value(:one, "env1").should == "oneval"
+ @settings.value(:one, "env2").should == "twoval"
+ end
- it "should have a run_mode that defaults to user" do
- @settings.run_mode.should == :user
- end
+ it "should have a run_mode that defaults to user" do
+ @settings.run_mode.should == :user
+ end
+ end
+
+ describe "when choosing which value to return" do
+ before do
+ @settings = Puppet::Util::Settings.new
+ @settings.setdefaults :section,
+ :config => ["/my/file", "a"],
+ :one => ["ONE", "a"]
+ FileTest.stubs(:exist?).returns true
+ Puppet.stubs(:run_mode).returns stub('run_mode', :name => :mymode)
end
- describe "when choosing which value to return" do
- before do
- @settings = Puppet::Util::Settings.new
- @settings.setdefaults :section,
- :config => ["/my/file", "a"],
- :one => ["ONE", "a"]
- FileTest.stubs(:exist?).returns true
- Puppet.stubs(:run_mode).returns stub('run_mode', :name => :mymode)
- end
+ it "should return default values if no values have been set" do
+ @settings[:one].should == "ONE"
+ end
- it "should return default values if no values have been set" do
- @settings[:one].should == "ONE"
- end
+ it "should return values set on the cli before values set in the configuration file" do
+ text = "[main]\none = fileval\n"
+ @settings.stubs(:read_file).returns(text)
+ @settings.handlearg("--one", "clival")
+ @settings.parse
- it "should return values set on the cli before values set in the configuration file" do
- text = "[main]\none = fileval\n"
- @settings.stubs(:read_file).returns(text)
- @settings.handlearg("--one", "clival")
- @settings.parse
+ @settings[:one].should == "clival"
+ end
- @settings[:one].should == "clival"
- end
+ it "should return values set on the cli before values set in Ruby" do
+ @settings[:one] = "rubyval"
+ @settings.handlearg("--one", "clival")
+ @settings[:one].should == "clival"
+ end
- it "should return values set on the cli before values set in Ruby" do
- @settings[:one] = "rubyval"
- @settings.handlearg("--one", "clival")
- @settings[:one].should == "clival"
- end
+ it "should return values set in the mode-specific section before values set in the main section" do
+ text = "[main]\none = mainval\n[mymode]\none = modeval\n"
+ @settings.stubs(:read_file).returns(text)
+ @settings.parse
- it "should return values set in the mode-specific section before values set in the main section" do
- text = "[main]\none = mainval\n[mymode]\none = modeval\n"
- @settings.stubs(:read_file).returns(text)
- @settings.parse
+ @settings[:one].should == "modeval"
+ end
- @settings[:one].should == "modeval"
- end
+ it "should not return values outside of its search path" do
+ text = "[other]\none = oval\n"
+ file = "/some/file"
+ @settings.stubs(:read_file).returns(text)
+ @settings.parse
+ @settings[:one].should == "ONE"
+ end
- it "should not return values outside of its search path" do
- text = "[other]\none = oval\n"
- file = "/some/file"
- @settings.stubs(:read_file).returns(text)
- @settings.parse
- @settings[:one].should == "ONE"
- end
+ it "should return values in a specified environment" do
+ text = "[env]\none = envval\n"
+ @settings.stubs(:read_file).returns(text)
+ @settings.parse
+ @settings.value(:one, "env").should == "envval"
+ end
- it "should return values in a specified environment" do
- text = "[env]\none = envval\n"
- @settings.stubs(:read_file).returns(text)
- @settings.parse
- @settings.value(:one, "env").should == "envval"
- end
+ it "should interpolate found values using the current environment" do
+ @settings.setdefaults :main, :myval => ["$environment/foo", "mydocs"]
- it "should interpolate found values using the current environment" do
- @settings.setdefaults :main, :myval => ["$environment/foo", "mydocs"]
+ @settings.value(:myval, "myenv").should == "myenv/foo"
+ end
- @settings.value(:myval, "myenv").should == "myenv/foo"
- end
+ it "should return values in a specified environment before values in the main or name sections" do
+ text = "[env]\none = envval\n[main]\none = mainval\n[myname]\none = nameval\n"
+ @settings.stubs(:read_file).returns(text)
+ @settings.parse
+ @settings.value(:one, "env").should == "envval"
+ end
+ end
+
+ describe "when parsing its configuration" do
+ before do
+ @settings = Puppet::Util::Settings.new
+ @settings.stubs(:service_user_available?).returns true
+ @file = "/some/file"
+ @settings.setdefaults :section, :user => ["suser", "doc"], :group => ["sgroup", "doc"]
+ @settings.setdefaults :section, :config => ["/some/file", "eh"], :one => ["ONE", "a"], :two => ["$one TWO", "b"], :three => ["$one $two THREE", "c"]
+ FileTest.stubs(:exist?).returns true
+ end
- it "should return values in a specified environment before values in the main or name sections" do
- text = "[env]\none = envval\n[main]\none = mainval\n[myname]\none = nameval\n"
- @settings.stubs(:read_file).returns(text)
- @settings.parse
- @settings.value(:one, "env").should == "envval"
- end
+ it "should not ignore the report setting" do
+ @settings.setdefaults :section, :report => ["false", "a"]
+ myfile = stub "myfile"
+ @settings[:config] = myfile
+ text = <<-CONF
+ [puppetd]
+ report=true
+ CONF
+ @settings.expects(:read_file).returns(text)
+ @settings.parse
+ @settings[:report].should be_true
end
- describe "when parsing its configuration" do
- before do
- @settings = Puppet::Util::Settings.new
- @settings.stubs(:service_user_available?).returns true
- @file = "/some/file"
- @settings.setdefaults :section, :user => ["suser", "doc"], :group => ["sgroup", "doc"]
- @settings.setdefaults :section, :config => ["/some/file", "eh"], :one => ["ONE", "a"], :two => ["$one TWO", "b"], :three => ["$one $two THREE", "c"]
- FileTest.stubs(:exist?).returns true
- end
+ it "should use its current ':config' value for the file to parse" do
+ myfile = Puppet.features.posix? ? "/my/file" : "C:/myfile" # do not stub expand_path here, as this leads to a stack overflow, when mocha tries to use it
+ @settings[:config] = myfile
- it "should not ignore the report setting" do
- @settings.setdefaults :section, :report => ["false", "a"]
- myfile = stub "myfile"
- @settings[:config] = myfile
- text = <<-CONF
- [puppetd]
- report=true
- CONF
- @settings.expects(:read_file).returns(text)
- @settings.parse
- @settings[:report].should be_true
- end
+ File.expects(:read).with(myfile).returns "[main]"
+
+ @settings.parse
+ end
- it "should use its current ':config' value for the file to parse" do
- myfile = Puppet.features.posix? ? "/my/file" : "C:/myfile" # do not stub expand_path here, as this leads to a stack overflow, when mocha tries to use it
- @settings[:config] = myfile
+ it "should fail if no configuration setting is defined" do
+ @settings = Puppet::Util::Settings.new
+ lambda { @settings.parse }.should raise_error(RuntimeError)
+ end
- File.expects(:read).with(myfile).returns "[main]"
+ it "should not try to parse non-existent files" do
+ FileTest.expects(:exist?).with("/some/file").returns false
- @settings.parse
- end
+ File.expects(:read).with("/some/file").never
- it "should fail if no configuration setting is defined" do
- @settings = Puppet::Util::Settings.new
- lambda { @settings.parse }.should raise_error(RuntimeError)
- end
+ @settings.parse
+ end
- it "should not try to parse non-existent files" do
- FileTest.expects(:exist?).with("/some/file").returns false
+ it "should set a timer that triggers reparsing, even if the file does not exist" do
+ FileTest.expects(:exist?).returns false
+ @settings.expects(:set_filetimeout_timer)
- File.expects(:read).with("/some/file").never
+ @settings.parse
+ end
- @settings.parse
- end
+ it "should return values set in the configuration file" do
+ text = "[main]
+ one = fileval
+ "
+ @settings.expects(:read_file).returns(text)
+ @settings.parse
+ @settings[:one].should == "fileval"
+ end
- it "should set a timer that triggers reparsing, even if the file does not exist" do
- FileTest.expects(:exist?).returns false
- @settings.expects(:set_filetimeout_timer)
+ #484 - this should probably be in the regression area
+ it "should not throw an exception on unknown parameters" do
+ text = "[main]\nnosuchparam = mval\n"
+ @settings.expects(:read_file).returns(text)
+ lambda { @settings.parse }.should_not raise_error
+ end
- @settings.parse
- end
+ it "should convert booleans in the configuration file into Ruby booleans" do
+ text = "[main]
+ one = true
+ two = false
+ "
+ @settings.expects(:read_file).returns(text)
+ @settings.parse
+ @settings[:one].should == true
+ @settings[:two].should == false
+ end
- it "should return values set in the configuration file" do
- text = "[main]
- one = fileval
- "
- @settings.expects(:read_file).returns(text)
- @settings.parse
- @settings[:one].should == "fileval"
- end
+ it "should convert integers in the configuration file into Ruby Integers" do
+ text = "[main]
+ one = 65
+ "
+ @settings.expects(:read_file).returns(text)
+ @settings.parse
+ @settings[:one].should == 65
+ end
- #484 - this should probably be in the regression area
- it "should not throw an exception on unknown parameters" do
- text = "[main]\nnosuchparam = mval\n"
- @settings.expects(:read_file).returns(text)
- lambda { @settings.parse }.should_not raise_error
- end
+ it "should support specifying all metadata (owner, group, mode) in the configuration file" do
+ @settings.setdefaults :section, :myfile => ["/myfile", "a"]
- it "should convert booleans in the configuration file into Ruby booleans" do
- text = "[main]
- one = true
- two = false
- "
- @settings.expects(:read_file).returns(text)
- @settings.parse
- @settings[:one].should == true
- @settings[:two].should == false
- end
+ text = "[main]
+ myfile = /other/file {owner = service, group = service, mode = 644}
+ "
+ @settings.expects(:read_file).returns(text)
+ @settings.parse
+ @settings[:myfile].should == "/other/file"
+ @settings.metadata(:myfile).should == {:owner => "suser", :group => "sgroup", :mode => "644"}
+ end
- it "should convert integers in the configuration file into Ruby Integers" do
- text = "[main]
- one = 65
- "
- @settings.expects(:read_file).returns(text)
- @settings.parse
- @settings[:one].should == 65
- end
+ it "should support specifying a single piece of metadata (owner, group, or mode) in the configuration file" do
+ @settings.setdefaults :section, :myfile => ["/myfile", "a"]
+
+ text = "[main]
+ myfile = /other/file {owner = service}
+ "
+ file = "/some/file"
+ @settings.expects(:read_file).returns(text)
+ @settings.parse
+ @settings[:myfile].should == "/other/file"
+ @settings.metadata(:myfile).should == {:owner => "suser"}
+ end
- it "should support specifying all metadata (owner, group, mode) in the configuration file" do
- @settings.setdefaults :section, :myfile => ["/myfile", "a"]
+ it "should call hooks associated with values set in the configuration file" do
+ values = []
+ @settings.setdefaults :section, :mysetting => {:default => "defval", :desc => "a", :hook => proc { |v| values << v }}
- text = "[main]
- myfile = /other/file {owner = service, group = service, mode = 644}
- "
- @settings.expects(:read_file).returns(text)
- @settings.parse
- @settings[:myfile].should == "/other/file"
- @settings.metadata(:myfile).should == {:owner => "suser", :group => "sgroup", :mode => "644"}
- end
+ text = "[main]
+ mysetting = setval
+ "
+ @settings.expects(:read_file).returns(text)
+ @settings.parse
+ values.should == ["setval"]
+ end
- it "should support specifying a single piece of metadata (owner, group, or mode) in the configuration file" do
- @settings.setdefaults :section, :myfile => ["/myfile", "a"]
-
- text = "[main]
- myfile = /other/file {owner = service}
- "
- file = "/some/file"
- @settings.expects(:read_file).returns(text)
- @settings.parse
- @settings[:myfile].should == "/other/file"
- @settings.metadata(:myfile).should == {:owner => "suser"}
- end
+ it "should not call the same hook for values set multiple times in the configuration file" do
+ values = []
+ @settings.setdefaults :section, :mysetting => {:default => "defval", :desc => "a", :hook => proc { |v| values << v }}
+
+ text = "[user]
+ mysetting = setval
+ [main]
+ mysetting = other
+ "
+ @settings.expects(:read_file).returns(text)
+ @settings.parse
+ values.should == ["setval"]
+ end
- it "should call hooks associated with values set in the configuration file" do
- values = []
- @settings.setdefaults :section, :mysetting => {:default => "defval", :desc => "a", :hook => proc { |v| values << v }}
+ it "should pass the environment-specific value to the hook when one is available" do
+ values = []
+ @settings.setdefaults :section, :mysetting => {:default => "defval", :desc => "a", :hook => proc { |v| values << v }}
+ @settings.setdefaults :section, :environment => ["yay", "a"]
+ @settings.setdefaults :section, :environments => ["yay,foo", "a"]
+
+ text = "[main]
+ mysetting = setval
+ [yay]
+ mysetting = other
+ "
+ @settings.expects(:read_file).returns(text)
+ @settings.parse
+ values.should == ["other"]
+ end
- text = "[main]
- mysetting = setval
- "
- @settings.expects(:read_file).returns(text)
- @settings.parse
- values.should == ["setval"]
- end
+ it "should pass the interpolated value to the hook when one is available" do
+ values = []
+ @settings.setdefaults :section, :base => {:default => "yay", :desc => "a", :hook => proc { |v| values << v }}
+ @settings.setdefaults :section, :mysetting => {:default => "defval", :desc => "a", :hook => proc { |v| values << v }}
+
+ text = "[main]
+ mysetting = $base/setval
+ "
+ @settings.expects(:read_file).returns(text)
+ @settings.parse
+ values.should == ["yay/setval"]
+ end
- it "should not call the same hook for values set multiple times in the configuration file" do
- values = []
- @settings.setdefaults :section, :mysetting => {:default => "defval", :desc => "a", :hook => proc { |v| values << v }}
-
- text = "[user]
- mysetting = setval
- [main]
- mysetting = other
- "
- @settings.expects(:read_file).returns(text)
- @settings.parse
- values.should == ["setval"]
- end
+ it "should allow empty values" do
+ @settings.setdefaults :section, :myarg => ["myfile", "a"]
- it "should pass the environment-specific value to the hook when one is available" do
- values = []
- @settings.setdefaults :section, :mysetting => {:default => "defval", :desc => "a", :hook => proc { |v| values << v }}
- @settings.setdefaults :section, :environment => ["yay", "a"]
- @settings.setdefaults :section, :environments => ["yay,foo", "a"]
-
- text = "[main]
- mysetting = setval
- [yay]
- mysetting = other
- "
- @settings.expects(:read_file).returns(text)
- @settings.parse
- values.should == ["other"]
- end
+ text = "[main]
+ myarg =
+ "
+ @settings.stubs(:read_file).returns(text)
+ @settings.parse
+ @settings[:myarg].should == ""
+ end
- it "should pass the interpolated value to the hook when one is available" do
- values = []
- @settings.setdefaults :section, :base => {:default => "yay", :desc => "a", :hook => proc { |v| values << v }}
- @settings.setdefaults :section, :mysetting => {:default => "defval", :desc => "a", :hook => proc { |v| values << v }}
-
- text = "[main]
- mysetting = $base/setval
- "
- @settings.expects(:read_file).returns(text)
- @settings.parse
- values.should == ["yay/setval"]
- end
+ describe "and when reading a non-positive filetimeout value from the config file" do
+ before do
+ @settings.setdefaults :foo, :filetimeout => [5, "eh"]
- it "should allow empty values" do
- @settings.setdefaults :section, :myarg => ["myfile", "a"]
+ somefile = "/some/file"
+ text = "[main]
+ filetimeout = -1
+ "
+ File.expects(:read).with(somefile).returns(text)
+ File.expects(:expand_path).with(somefile).returns somefile
+ @settings[:config] = somefile
+ end
- text = "[main]
- myarg =
- "
- @settings.stubs(:read_file).returns(text)
- @settings.parse
- @settings[:myarg].should == ""
- end
+ it "should not set a timer" do
+ EventLoop::Timer.expects(:new).never
+
+ @settings.parse
+ end
+ end
+ end
- describe "and when reading a non-positive filetimeout value from the config file" do
- before do
- @settings.setdefaults :foo, :filetimeout => [5, "eh"]
+ describe "when reparsing its configuration" do
+ before do
+ @settings = Puppet::Util::Settings.new
+ @settings.setdefaults :section, :config => ["/test/file", "a"], :one => ["ONE", "a"], :two => ["$one TWO", "b"], :three => ["$one $two THREE", "c"]
+ FileTest.stubs(:exist?).returns true
+ end
- somefile = "/some/file"
- text = "[main]
- filetimeout = -1
- "
- File.expects(:read).with(somefile).returns(text)
- File.expects(:expand_path).with(somefile).returns somefile
- @settings[:config] = somefile
- end
+ it "should use a LoadedFile instance to determine if the file has changed" do
+ file = mock 'file'
+ Puppet::Util::LoadedFile.expects(:new).with("/test/file").returns file
- it "should not set a timer" do
- EventLoop::Timer.expects(:new).never
+ file.expects(:changed?)
- @settings.parse
- end
- end
+ @settings.stubs(:parse)
+ @settings.reparse
end
- describe "when reparsing its configuration" do
- before do
- @settings = Puppet::Util::Settings.new
- @settings.setdefaults :section, :config => ["/test/file", "a"], :one => ["ONE", "a"], :two => ["$one TWO", "b"], :three => ["$one $two THREE", "c"]
- FileTest.stubs(:exist?).returns true
- end
+ it "should not create the LoadedFile instance and should not parse if the file does not exist" do
+ FileTest.expects(:exist?).with("/test/file").returns false
+ Puppet::Util::LoadedFile.expects(:new).never
- it "should use a LoadedFile instance to determine if the file has changed" do
- file = mock 'file'
- Puppet::Util::LoadedFile.expects(:new).with("/test/file").returns file
+ @settings.expects(:parse).never
- file.expects(:changed?)
+ @settings.reparse
+ end
- @settings.stubs(:parse)
- @settings.reparse
- end
+ it "should not reparse if the file has not changed" do
+ file = mock 'file'
+ Puppet::Util::LoadedFile.expects(:new).with("/test/file").returns file
- it "should not create the LoadedFile instance and should not parse if the file does not exist" do
- FileTest.expects(:exist?).with("/test/file").returns false
- Puppet::Util::LoadedFile.expects(:new).never
+ file.expects(:changed?).returns false
- @settings.expects(:parse).never
+ @settings.expects(:parse).never
- @settings.reparse
- end
+ @settings.reparse
+ end
- it "should not reparse if the file has not changed" do
- file = mock 'file'
- Puppet::Util::LoadedFile.expects(:new).with("/test/file").returns file
+ it "should reparse if the file has changed" do
+ file = stub 'file', :file => "/test/file"
+ Puppet::Util::LoadedFile.expects(:new).with("/test/file").returns file
- file.expects(:changed?).returns false
+ file.expects(:changed?).returns true
- @settings.expects(:parse).never
+ @settings.expects(:parse)
- @settings.reparse
- end
+ @settings.reparse
+ end
- it "should reparse if the file has changed" do
- file = stub 'file', :file => "/test/file"
- Puppet::Util::LoadedFile.expects(:new).with("/test/file").returns file
+ it "should use a cached LoadedFile instance" do
+ first = mock 'first'
+ second = mock 'second'
+ Puppet::Util::LoadedFile.expects(:new).times(2).with("/test/file").returns(first).then.returns(second)
- file.expects(:changed?).returns true
+ @settings.file.should equal(first)
+ Puppet::Util::Cacher.expire
+ @settings.file.should equal(second)
+ end
- @settings.expects(:parse)
+ it "should replace in-memory values with on-file values" do
+ # Init the value
+ text = "[main]\none = disk-init\n"
+ file = mock 'file'
+ file.stubs(:changed?).returns(true)
+ file.stubs(:file).returns("/test/file")
+ @settings[:one] = "init"
+ @settings.file = file
+
+ # Now replace the value
+ text = "[main]\none = disk-replace\n"
+
+ # This is kinda ridiculous - the reason it parses twice is that
+ # it goes to parse again when we ask for the value, because the
+ # mock always says it should get reparsed.
+ @settings.stubs(:read_file).returns(text)
+ @settings.reparse
+ @settings[:one].should == "disk-replace"
+ end
- @settings.reparse
- end
+ it "should retain parameters set by cli when configuration files are reparsed" do
+ @settings.handlearg("--one", "clival")
- it "should use a cached LoadedFile instance" do
- first = mock 'first'
- second = mock 'second'
- Puppet::Util::LoadedFile.expects(:new).times(2).with("/test/file").returns(first).then.returns(second)
+ text = "[main]\none = on-disk\n"
+ @settings.stubs(:read_file).returns(text)
+ @settings.parse
- @settings.file.should equal(first)
- Puppet::Util::Cacher.expire
- @settings.file.should equal(second)
- end
+ @settings[:one].should == "clival"
+ end
- it "should replace in-memory values with on-file values" do
- # Init the value
- text = "[main]\none = disk-init\n"
- file = mock 'file'
- file.stubs(:changed?).returns(true)
- file.stubs(:file).returns("/test/file")
- @settings[:one] = "init"
- @settings.file = file
-
- # Now replace the value
- text = "[main]\none = disk-replace\n"
-
- # This is kinda ridiculous - the reason it parses twice is that
- # it goes to parse again when we ask for the value, because the
- # mock always says it should get reparsed.
- @settings.stubs(:read_file).returns(text)
- @settings.reparse
- @settings[:one].should == "disk-replace"
- end
+ it "should remove in-memory values that are no longer set in the file" do
+ # Init the value
+ text = "[main]\none = disk-init\n"
+ @settings.expects(:read_file).returns(text)
+ @settings.parse
+ @settings[:one].should == "disk-init"
- it "should retain parameters set by cli when configuration files are reparsed" do
- @settings.handlearg("--one", "clival")
+ # Now replace the value
+ text = "[main]\ntwo = disk-replace\n"
+ @settings.expects(:read_file).returns(text)
+ @settings.parse
+ #@settings.reparse
- text = "[main]\none = on-disk\n"
- @settings.stubs(:read_file).returns(text)
- @settings.parse
+ # The originally-overridden value should be replaced with the default
+ @settings[:one].should == "ONE"
- @settings[:one].should == "clival"
- end
+ # and we should now have the new value in memory
+ @settings[:two].should == "disk-replace"
+ end
- it "should remove in-memory values that are no longer set in the file" do
- # Init the value
- text = "[main]\none = disk-init\n"
- @settings.expects(:read_file).returns(text)
- @settings.parse
- @settings[:one].should == "disk-init"
+ it "should retain in-memory values if the file has a syntax error" do
+ # Init the value
+ text = "[main]\none = initial-value\n"
+ @settings.expects(:read_file).returns(text)
+ @settings.parse
+ @settings[:one].should == "initial-value"
- # Now replace the value
- text = "[main]\ntwo = disk-replace\n"
- @settings.expects(:read_file).returns(text)
- @settings.parse
- #@settings.reparse
+ # Now replace the value with something bogus
+ text = "[main]\nkenny = killed-by-what-follows\n1 is 2, blah blah florp\n"
+ @settings.expects(:read_file).returns(text)
+ @settings.parse
- # The originally-overridden value should be replaced with the default
- @settings[:one].should == "ONE"
+ # The originally-overridden value should not be replaced with the default
+ @settings[:one].should == "initial-value"
- # and we should now have the new value in memory
- @settings[:two].should == "disk-replace"
- end
+ # and we should not have the new value in memory
+ @settings[:kenny].should be_nil
+ end
+ end
- it "should retain in-memory values if the file has a syntax error" do
- # Init the value
- text = "[main]\none = initial-value\n"
- @settings.expects(:read_file).returns(text)
- @settings.parse
- @settings[:one].should == "initial-value"
+ it "should provide a method for creating a catalog of resources from its configuration" do
+ Puppet::Util::Settings.new.should respond_to(:to_catalog)
+ end
- # Now replace the value with something bogus
- text = "[main]\nkenny = killed-by-what-follows\n1 is 2, blah blah florp\n"
- @settings.expects(:read_file).returns(text)
- @settings.parse
+ describe "when creating a catalog" do
+ before do
+ @settings = Puppet::Util::Settings.new
+ @settings.stubs(:service_user_available?).returns true
+ @prefix = Puppet.features.posix? ? "" : "C:"
+ end
- # The originally-overridden value should not be replaced with the default
- @settings[:one].should == "initial-value"
+ it "should add all file resources to the catalog if no sections have been specified" do
+ @settings.setdefaults :main, :maindir => [@prefix+"/maindir", "a"], :seconddir => [@prefix+"/seconddir", "a"]
+ @settings.setdefaults :other, :otherdir => [@prefix+"/otherdir", "a"]
- # and we should not have the new value in memory
- @settings[:kenny].should be_nil
- end
+ catalog = @settings.to_catalog
+
+ [@prefix+"/maindir", @prefix+"/seconddir", @prefix+"/otherdir"].each do |path|
+ catalog.resource(:file, path).should be_instance_of(Puppet::Resource)
+ end
end
- it "should provide a method for creating a catalog of resources from its configuration" do
- Puppet::Util::Settings.new.should respond_to(:to_catalog)
+ it "should add only files in the specified sections if section names are provided" do
+ @settings.setdefaults :main, :maindir => [@prefix+"/maindir", "a"]
+ @settings.setdefaults :other, :otherdir => [@prefix+"/otherdir", "a"]
+ catalog = @settings.to_catalog(:main)
+ catalog.resource(:file, @prefix+"/otherdir").should be_nil
+ catalog.resource(:file, @prefix+"/maindir").should be_instance_of(Puppet::Resource)
end
- describe "when creating a catalog" do
- before do
- @settings = Puppet::Util::Settings.new
- @settings.stubs(:service_user_available?).returns true
- @prefix = Puppet.features.posix? ? "" : "C:"
- end
+ it "should not try to add the same file twice" do
+ @settings.setdefaults :main, :maindir => [@prefix+"/maindir", "a"]
+ @settings.setdefaults :other, :otherdir => [@prefix+"/maindir", "a"]
+ lambda { @settings.to_catalog }.should_not raise_error
+ end
- it "should add all file resources to the catalog if no sections have been specified" do
- @settings.setdefaults :main, :maindir => [@prefix+"/maindir", "a"], :seconddir => [@prefix+"/seconddir", "a"]
- @settings.setdefaults :other, :otherdir => [@prefix+"/otherdir", "a"]
+ it "should ignore files whose :to_resource method returns nil" do
+ @settings.setdefaults :main, :maindir => [@prefix+"/maindir", "a"]
+ @settings.setting(:maindir).expects(:to_resource).returns nil
- catalog = @settings.to_catalog
+ Puppet::Resource::Catalog.any_instance.expects(:add_resource).never
+ @settings.to_catalog
+ end
- [@prefix+"/maindir", @prefix+"/seconddir", @prefix+"/otherdir"].each do |path|
- catalog.resource(:file, path).should be_instance_of(Puppet::Resource)
- end
- end
+ describe "when adding users and groups to the catalog" do
+ before do
+ Puppet.features.stubs(:root?).returns true
+ @settings.setdefaults :foo, :mkusers => [true, "e"], :user => ["suser", "doc"], :group => ["sgroup", "doc"]
+ @settings.setdefaults :other, :otherdir => {:default => "/otherdir", :desc => "a", :owner => "service", :group => "service"}
+
+ @catalog = @settings.to_catalog
+ end
+
+ it "should add each specified user and group to the catalog if :mkusers is a valid setting, is enabled, and we're running as root" do
+ @catalog.resource(:user, "suser").should be_instance_of(Puppet::Resource)
+ @catalog.resource(:group, "sgroup").should be_instance_of(Puppet::Resource)
+ end
+
+ it "should only add users and groups to the catalog from specified sections" do
+ @settings.setdefaults :yay, :yaydir => {:default => "/yaydir", :desc => "a", :owner => "service", :group => "service"}
+ catalog = @settings.to_catalog(:other)
+ catalog.resource(:user, "jane").should be_nil
+ catalog.resource(:group, "billy").should be_nil
+ end
+
+ it "should not add users or groups to the catalog if :mkusers not running as root" do
+ Puppet.features.stubs(:root?).returns false
+
+ catalog = @settings.to_catalog
+ catalog.resource(:user, "suser").should be_nil
+ catalog.resource(:group, "sgroup").should be_nil
+ end
+
+ it "should not add users or groups to the catalog if :mkusers is not a valid setting" do
+ Puppet.features.stubs(:root?).returns true
+ settings = Puppet::Util::Settings.new
+ settings.setdefaults :other, :otherdir => {:default => "/otherdir", :desc => "a", :owner => "service", :group => "service"}
+
+ catalog = settings.to_catalog
+ catalog.resource(:user, "suser").should be_nil
+ catalog.resource(:group, "sgroup").should be_nil
+ end
+
+ it "should not add users or groups to the catalog if :mkusers is a valid setting but is disabled" do
+ @settings[:mkusers] = false
+
+ catalog = @settings.to_catalog
+ catalog.resource(:user, "suser").should be_nil
+ catalog.resource(:group, "sgroup").should be_nil
+ end
+
+ it "should not try to add users or groups to the catalog twice" do
+ @settings.setdefaults :yay, :yaydir => {:default => "/yaydir", :desc => "a", :owner => "service", :group => "service"}
+
+ # This would fail if users/groups were added twice
+ lambda { @settings.to_catalog }.should_not raise_error
+ end
+
+ it "should set :ensure to :present on each created user and group" do
+ @catalog.resource(:user, "suser")[:ensure].should == :present
+ @catalog.resource(:group, "sgroup")[:ensure].should == :present
+ end
+
+ it "should set each created user's :gid to the service group" do
+ @settings.to_catalog.resource(:user, "suser")[:gid].should == "sgroup"
+ end
+
+ it "should not attempt to manage the root user" do
+ Puppet.features.stubs(:root?).returns true
+ @settings.setdefaults :foo, :foodir => {:default => "/foodir", :desc => "a", :owner => "root", :group => "service"}
+
+ @settings.to_catalog.resource(:user, "root").should be_nil
+ end
+ end
+ end
- it "should add only files in the specified sections if section names are provided" do
- @settings.setdefaults :main, :maindir => [@prefix+"/maindir", "a"]
- @settings.setdefaults :other, :otherdir => [@prefix+"/otherdir", "a"]
- catalog = @settings.to_catalog(:main)
- catalog.resource(:file, @prefix+"/otherdir").should be_nil
- catalog.resource(:file, @prefix+"/maindir").should be_instance_of(Puppet::Resource)
- end
+ it "should be able to be converted to a manifest" do
+ Puppet::Util::Settings.new.should respond_to(:to_manifest)
+ end
- it "should not try to add the same file twice" do
- @settings.setdefaults :main, :maindir => [@prefix+"/maindir", "a"]
- @settings.setdefaults :other, :otherdir => [@prefix+"/maindir", "a"]
- lambda { @settings.to_catalog }.should_not raise_error
- end
+ describe "when being converted to a manifest" do
+ it "should produce a string with the code for each resource joined by two carriage returns" do
+ @settings = Puppet::Util::Settings.new
+ @settings.setdefaults :main, :maindir => ["/maindir", "a"], :seconddir => ["/seconddir", "a"]
- it "should ignore files whose :to_resource method returns nil" do
- @settings.setdefaults :main, :maindir => [@prefix+"/maindir", "a"]
- @settings.setting(:maindir).expects(:to_resource).returns nil
+ main = stub 'main_resource', :ref => "File[/maindir]"
+ main.expects(:to_manifest).returns "maindir"
+ second = stub 'second_resource', :ref => "File[/seconddir]"
+ second.expects(:to_manifest).returns "seconddir"
+ @settings.setting(:maindir).expects(:to_resource).returns main
+ @settings.setting(:seconddir).expects(:to_resource).returns second
- Puppet::Resource::Catalog.any_instance.expects(:add_resource).never
- @settings.to_catalog
- end
+ @settings.to_manifest.split("\n\n").sort.should == %w{maindir seconddir}
+ end
+ end
+
+ describe "when using sections of the configuration to manage the local host" do
+ before do
+ @settings = Puppet::Util::Settings.new
+ @settings.stubs(:service_user_available?).returns true
+ @settings.setdefaults :main, :noop => [false, ""]
+ @settings.setdefaults :main, :maindir => ["/maindir", "a"], :seconddir => ["/seconddir", "a"]
+ @settings.setdefaults :main, :user => ["suser", "doc"], :group => ["sgroup", "doc"]
+ @settings.setdefaults :other, :otherdir => {:default => "/otherdir", :desc => "a", :owner => "service", :group => "service", :mode => 0755}
+ @settings.setdefaults :third, :thirddir => ["/thirddir", "b"]
+ @settings.setdefaults :files, :myfile => {:default => "/myfile", :desc => "a", :mode => 0755}
+ end
- describe "when adding users and groups to the catalog" do
- before do
- Puppet.features.stubs(:root?).returns true
- @settings.setdefaults :foo, :mkusers => [true, "e"], :user => ["suser", "doc"], :group => ["sgroup", "doc"]
- @settings.setdefaults :other, :otherdir => {:default => "/otherdir", :desc => "a", :owner => "service", :group => "service"}
-
- @catalog = @settings.to_catalog
- end
-
- it "should add each specified user and group to the catalog if :mkusers is a valid setting, is enabled, and we're running as root" do
- @catalog.resource(:user, "suser").should be_instance_of(Puppet::Resource)
- @catalog.resource(:group, "sgroup").should be_instance_of(Puppet::Resource)
- end
-
- it "should only add users and groups to the catalog from specified sections" do
- @settings.setdefaults :yay, :yaydir => {:default => "/yaydir", :desc => "a", :owner => "service", :group => "service"}
- catalog = @settings.to_catalog(:other)
- catalog.resource(:user, "jane").should be_nil
- catalog.resource(:group, "billy").should be_nil
- end
-
- it "should not add users or groups to the catalog if :mkusers not running as root" do
- Puppet.features.stubs(:root?).returns false
-
- catalog = @settings.to_catalog
- catalog.resource(:user, "suser").should be_nil
- catalog.resource(:group, "sgroup").should be_nil
- end
-
- it "should not add users or groups to the catalog if :mkusers is not a valid setting" do
- Puppet.features.stubs(:root?).returns true
- settings = Puppet::Util::Settings.new
- settings.setdefaults :other, :otherdir => {:default => "/otherdir", :desc => "a", :owner => "service", :group => "service"}
-
- catalog = settings.to_catalog
- catalog.resource(:user, "suser").should be_nil
- catalog.resource(:group, "sgroup").should be_nil
- end
-
- it "should not add users or groups to the catalog if :mkusers is a valid setting but is disabled" do
- @settings[:mkusers] = false
-
- catalog = @settings.to_catalog
- catalog.resource(:user, "suser").should be_nil
- catalog.resource(:group, "sgroup").should be_nil
- end
-
- it "should not try to add users or groups to the catalog twice" do
- @settings.setdefaults :yay, :yaydir => {:default => "/yaydir", :desc => "a", :owner => "service", :group => "service"}
-
- # This would fail if users/groups were added twice
- lambda { @settings.to_catalog }.should_not raise_error
- end
-
- it "should set :ensure to :present on each created user and group" do
- @catalog.resource(:user, "suser")[:ensure].should == :present
- @catalog.resource(:group, "sgroup")[:ensure].should == :present
- end
-
- it "should set each created user's :gid to the service group" do
- @settings.to_catalog.resource(:user, "suser")[:gid].should == "sgroup"
- end
-
- it "should not attempt to manage the root user" do
- Puppet.features.stubs(:root?).returns true
- @settings.setdefaults :foo, :foodir => {:default => "/foodir", :desc => "a", :owner => "root", :group => "service"}
-
- @settings.to_catalog.resource(:user, "root").should be_nil
- end
- end
+ it "should provide a method that writes files with the correct modes" do
+ @settings.should respond_to(:write)
end
- it "should be able to be converted to a manifest" do
- Puppet::Util::Settings.new.should respond_to(:to_manifest)
+ it "should provide a method that creates directories with the correct modes" do
+ Puppet::Util::SUIDManager.expects(:asuser).with("suser", "sgroup").yields
+ Dir.expects(:mkdir).with("/otherdir", 0755)
+ @settings.mkdir(:otherdir)
end
- describe "when being converted to a manifest" do
- it "should produce a string with the code for each resource joined by two carriage returns" do
- @settings = Puppet::Util::Settings.new
- @settings.setdefaults :main, :maindir => ["/maindir", "a"], :seconddir => ["/seconddir", "a"]
+ it "should create a catalog with the specified sections" do
+ @settings.expects(:to_catalog).with(:main, :other).returns Puppet::Resource::Catalog.new("foo")
+ @settings.use(:main, :other)
+ end
- main = stub 'main_resource', :ref => "File[/maindir]"
- main.expects(:to_manifest).returns "maindir"
- second = stub 'second_resource', :ref => "File[/seconddir]"
- second.expects(:to_manifest).returns "seconddir"
- @settings.setting(:maindir).expects(:to_resource).returns main
- @settings.setting(:seconddir).expects(:to_resource).returns second
+ it "should canonicalize the sections" do
+ @settings.expects(:to_catalog).with(:main, :other).returns Puppet::Resource::Catalog.new("foo")
+ @settings.use("main", "other")
+ end
- @settings.to_manifest.split("\n\n").sort.should == %w{maindir seconddir}
- end
+ it "should ignore sections that have already been used" do
+ @settings.expects(:to_catalog).with(:main).returns Puppet::Resource::Catalog.new("foo")
+ @settings.use(:main)
+ @settings.expects(:to_catalog).with(:other).returns Puppet::Resource::Catalog.new("foo")
+ @settings.use(:main, :other)
end
- describe "when using sections of the configuration to manage the local host" do
- before do
- @settings = Puppet::Util::Settings.new
- @settings.stubs(:service_user_available?).returns true
- @settings.setdefaults :main, :noop => [false, ""]
- @settings.setdefaults :main, :maindir => ["/maindir", "a"], :seconddir => ["/seconddir", "a"]
- @settings.setdefaults :main, :user => ["suser", "doc"], :group => ["sgroup", "doc"]
- @settings.setdefaults :other, :otherdir => {:default => "/otherdir", :desc => "a", :owner => "service", :group => "service", :mode => 0755}
- @settings.setdefaults :third, :thirddir => ["/thirddir", "b"]
- @settings.setdefaults :files, :myfile => {:default => "/myfile", :desc => "a", :mode => 0755}
- end
+ it "should ignore tags and schedules when creating files and directories"
- it "should provide a method that writes files with the correct modes" do
- @settings.should respond_to(:write)
- end
+ it "should be able to provide all of its parameters in a format compatible with GetOpt::Long" do
+ pending "Not converted from test/unit yet"
+ end
- it "should provide a method that creates directories with the correct modes" do
- Puppet::Util::SUIDManager.expects(:asuser).with("suser", "sgroup").yields
- Dir.expects(:mkdir).with("/otherdir", 0755)
- @settings.mkdir(:otherdir)
- end
+ it "should convert the created catalog to a RAL catalog" do
+ @catalog = Puppet::Resource::Catalog.new("foo")
+ @settings.expects(:to_catalog).with(:main).returns @catalog
- it "should create a catalog with the specified sections" do
- @settings.expects(:to_catalog).with(:main, :other).returns Puppet::Resource::Catalog.new("foo")
- @settings.use(:main, :other)
- end
+ @catalog.expects(:to_ral).returns @catalog
+ @settings.use(:main)
+ end
- it "should canonicalize the sections" do
- @settings.expects(:to_catalog).with(:main, :other).returns Puppet::Resource::Catalog.new("foo")
- @settings.use("main", "other")
- end
+ it "should specify that it is not managing a host catalog" do
+ catalog = Puppet::Resource::Catalog.new("foo")
+ catalog.expects(:apply)
+ @settings.expects(:to_catalog).returns catalog
- it "should ignore sections that have already been used" do
- @settings.expects(:to_catalog).with(:main).returns Puppet::Resource::Catalog.new("foo")
- @settings.use(:main)
- @settings.expects(:to_catalog).with(:other).returns Puppet::Resource::Catalog.new("foo")
- @settings.use(:main, :other)
- end
+ catalog.stubs(:to_ral).returns catalog
- it "should ignore tags and schedules when creating files and directories"
+ catalog.expects(:host_config=).with false
- it "should be able to provide all of its parameters in a format compatible with GetOpt::Long" do
- pending "Not converted from test/unit yet"
- end
+ @settings.use(:main)
+ end
- it "should convert the created catalog to a RAL catalog" do
- @catalog = Puppet::Resource::Catalog.new("foo")
- @settings.expects(:to_catalog).with(:main).returns @catalog
+ it "should support a method for re-using all currently used sections" do
+ @settings.expects(:to_catalog).with(:main, :third).times(2).returns Puppet::Resource::Catalog.new("foo")
- @catalog.expects(:to_ral).returns @catalog
- @settings.use(:main)
- end
+ @settings.use(:main, :third)
+ @settings.reuse
+ end
- it "should specify that it is not managing a host catalog" do
- catalog = Puppet::Resource::Catalog.new("foo")
- catalog.expects(:apply)
- @settings.expects(:to_catalog).returns catalog
+ it "should fail with an appropriate message if any resources fail" do
+ @catalog = Puppet::Resource::Catalog.new("foo")
+ @catalog.stubs(:to_ral).returns @catalog
+ @settings.expects(:to_catalog).returns @catalog
- catalog.stubs(:to_ral).returns catalog
+ @trans = mock("transaction")
+ @catalog.expects(:apply).yields(@trans)
- catalog.expects(:host_config=).with false
+ @trans.expects(:any_failed?).returns(true)
- @settings.use(:main)
- end
+ report = mock 'report'
+ @trans.expects(:report).returns report
- it "should support a method for re-using all currently used sections" do
- @settings.expects(:to_catalog).with(:main, :third).times(2).returns Puppet::Resource::Catalog.new("foo")
+ log = mock 'log', :to_s => "My failure", :level => :err
+ report.expects(:logs).returns [log]
- @settings.use(:main, :third)
- @settings.reuse
+ @settings.expects(:raise).with { |msg| msg.include?("My failure") }
+ @settings.use(:whatever)
+ end
+ end
+
+ describe "when dealing with printing configs" do
+ before do
+ @settings = Puppet::Util::Settings.new
+ #these are the magic default values
+ @settings.stubs(:value).with(:configprint).returns("")
+ @settings.stubs(:value).with(:genconfig).returns(false)
+ @settings.stubs(:value).with(:genmanifest).returns(false)
+ @settings.stubs(:value).with(:environment).returns(nil)
+ end
+
+ describe "when checking print_config?" do
+ it "should return false when the :configprint, :genconfig and :genmanifest are not set" do
+ @settings.print_configs?.should be_false
+ end
+
+ it "should return true when :configprint has a value" do
+ @settings.stubs(:value).with(:configprint).returns("something")
+ @settings.print_configs?.should be_true
+ end
+
+ it "should return true when :genconfig has a value" do
+ @settings.stubs(:value).with(:genconfig).returns(true)
+ @settings.print_configs?.should be_true
+ end
+
+ it "should return true when :genmanifest has a value" do
+ @settings.stubs(:value).with(:genmanifest).returns(true)
+ @settings.print_configs?.should be_true
+ end
+ end
+
+ describe "when printing configs" do
+ describe "when :configprint has a value" do
+ it "should call print_config_options" do
+ @settings.stubs(:value).with(:configprint).returns("something")
+ @settings.expects(:print_config_options)
+ @settings.print_configs
end
- it "should fail with an appropriate message if any resources fail" do
- @catalog = Puppet::Resource::Catalog.new("foo")
- @catalog.stubs(:to_ral).returns @catalog
- @settings.expects(:to_catalog).returns @catalog
+ it "should get the value of the option using the environment" do
+ @settings.stubs(:value).with(:configprint).returns("something")
+ @settings.stubs(:include?).with("something").returns(true)
+ @settings.expects(:value).with(:environment).returns("env")
+ @settings.expects(:value).with("something", "env").returns("foo")
+ @settings.stubs(:puts).with("foo")
+ @settings.print_configs
+ end
- @trans = mock("transaction")
- @catalog.expects(:apply).yields(@trans)
+ it "should print the value of the option" do
+ @settings.stubs(:value).with(:configprint).returns("something")
+ @settings.stubs(:include?).with("something").returns(true)
+ @settings.stubs(:value).with("something", nil).returns("foo")
+ @settings.expects(:puts).with("foo")
+ @settings.print_configs
+ end
- @trans.expects(:any_failed?).returns(true)
+ it "should print the value pairs if there are multiple options" do
+ @settings.stubs(:value).with(:configprint).returns("bar,baz")
+ @settings.stubs(:include?).with("bar").returns(true)
+ @settings.stubs(:include?).with("baz").returns(true)
+ @settings.stubs(:value).with("bar", nil).returns("foo")
+ @settings.stubs(:value).with("baz", nil).returns("fud")
+ @settings.expects(:puts).with("bar = foo")
+ @settings.expects(:puts).with("baz = fud")
+ @settings.print_configs
+ end
- report = mock 'report'
- @trans.expects(:report).returns report
+ it "should print a whole bunch of stuff if :configprint = all"
- log = mock 'log', :to_s => "My failure", :level => :err
- report.expects(:logs).returns [log]
+ it "should return true after printing" do
+ @settings.stubs(:value).with(:configprint).returns("something")
+ @settings.stubs(:include?).with("something").returns(true)
+ @settings.stubs(:value).with("something", nil).returns("foo")
+ @settings.stubs(:puts).with("foo")
+ @settings.print_configs.should be_true
+ end
- @settings.expects(:raise).with { |msg| msg.include?("My failure") }
- @settings.use(:whatever)
+ it "should return false if a config param is not found" do
+ @settings.stubs :puts
+ @settings.stubs(:value).with(:configprint).returns("something")
+ @settings.stubs(:include?).with("something").returns(false)
+ @settings.print_configs.should be_false
end
- end
+ end
- describe "when dealing with printing configs" do
+ describe "when genconfig is true" do
before do
- @settings = Puppet::Util::Settings.new
- #these are the magic default values
- @settings.stubs(:value).with(:configprint).returns("")
- @settings.stubs(:value).with(:genconfig).returns(false)
- @settings.stubs(:value).with(:genmanifest).returns(false)
- @settings.stubs(:value).with(:environment).returns(nil)
+ @settings.stubs :puts
end
- describe "when checking print_config?" do
- it "should return false when the :configprint, :genconfig and :genmanifest are not set" do
- @settings.print_configs?.should be_false
- end
-
- it "should return true when :configprint has a value" do
- @settings.stubs(:value).with(:configprint).returns("something")
- @settings.print_configs?.should be_true
- end
-
- it "should return true when :genconfig has a value" do
- @settings.stubs(:value).with(:genconfig).returns(true)
- @settings.print_configs?.should be_true
- end
-
- it "should return true when :genmanifest has a value" do
- @settings.stubs(:value).with(:genmanifest).returns(true)
- @settings.print_configs?.should be_true
- end
+ it "should call to_config" do
+ @settings.stubs(:value).with(:genconfig).returns(true)
+ @settings.expects(:to_config)
+ @settings.print_configs
end
- describe "when printing configs" do
- describe "when :configprint has a value" do
- it "should call print_config_options" do
- @settings.stubs(:value).with(:configprint).returns("something")
- @settings.expects(:print_config_options)
- @settings.print_configs
- end
-
- it "should get the value of the option using the environment" do
- @settings.stubs(:value).with(:configprint).returns("something")
- @settings.stubs(:include?).with("something").returns(true)
- @settings.expects(:value).with(:environment).returns("env")
- @settings.expects(:value).with("something", "env").returns("foo")
- @settings.stubs(:puts).with("foo")
- @settings.print_configs
- end
-
- it "should print the value of the option" do
- @settings.stubs(:value).with(:configprint).returns("something")
- @settings.stubs(:include?).with("something").returns(true)
- @settings.stubs(:value).with("something", nil).returns("foo")
- @settings.expects(:puts).with("foo")
- @settings.print_configs
- end
-
- it "should print the value pairs if there are multiple options" do
- @settings.stubs(:value).with(:configprint).returns("bar,baz")
- @settings.stubs(:include?).with("bar").returns(true)
- @settings.stubs(:include?).with("baz").returns(true)
- @settings.stubs(:value).with("bar", nil).returns("foo")
- @settings.stubs(:value).with("baz", nil).returns("fud")
- @settings.expects(:puts).with("bar = foo")
- @settings.expects(:puts).with("baz = fud")
- @settings.print_configs
- end
-
- it "should print a whole bunch of stuff if :configprint = all"
-
- it "should return true after printing" do
- @settings.stubs(:value).with(:configprint).returns("something")
- @settings.stubs(:include?).with("something").returns(true)
- @settings.stubs(:value).with("something", nil).returns("foo")
- @settings.stubs(:puts).with("foo")
- @settings.print_configs.should be_true
- end
-
- it "should return false if a config param is not found" do
- @settings.stubs :puts
- @settings.stubs(:value).with(:configprint).returns("something")
- @settings.stubs(:include?).with("something").returns(false)
- @settings.print_configs.should be_false
- end
- end
-
- describe "when genconfig is true" do
- before do
- @settings.stubs :puts
- end
-
- it "should call to_config" do
- @settings.stubs(:value).with(:genconfig).returns(true)
- @settings.expects(:to_config)
- @settings.print_configs
- end
-
- it "should return true from print_configs" do
- @settings.stubs(:value).with(:genconfig).returns(true)
- @settings.stubs(:to_config)
- @settings.print_configs.should be_true
- end
- end
-
- describe "when genmanifest is true" do
- before do
- @settings.stubs :puts
- end
-
- it "should call to_config" do
- @settings.stubs(:value).with(:genmanifest).returns(true)
- @settings.expects(:to_manifest)
- @settings.print_configs
- end
-
- it "should return true from print_configs" do
- @settings.stubs(:value).with(:genmanifest).returns(true)
- @settings.stubs(:to_manifest)
- @settings.print_configs.should be_true
- end
- end
+ it "should return true from print_configs" do
+ @settings.stubs(:value).with(:genconfig).returns(true)
+ @settings.stubs(:to_config)
+ @settings.print_configs.should be_true
end
- end
+ end
- describe "when setting a timer to trigger configuration file reparsing" do
+ describe "when genmanifest is true" do
before do
- @settings = Puppet::Util::Settings.new
- @settings.setdefaults :foo, :filetimeout => [5, "eh"]
+ @settings.stubs :puts
end
- it "should do nothing if no filetimeout setting is available" do
- @settings.expects(:value).with(:filetimeout).returns nil
- EventLoop::Timer.expects(:new).never
- @settings.set_filetimeout_timer
+ it "should call to_config" do
+ @settings.stubs(:value).with(:genmanifest).returns(true)
+ @settings.expects(:to_manifest)
+ @settings.print_configs
end
- it "should always convert the timer interval to an integer" do
- @settings.expects(:value).with(:filetimeout).returns "10"
- EventLoop::Timer.expects(:new).with(:interval => 10, :start? => true, :tolerance => 1)
- @settings.set_filetimeout_timer
+ it "should return true from print_configs" do
+ @settings.stubs(:value).with(:genmanifest).returns(true)
+ @settings.stubs(:to_manifest)
+ @settings.print_configs.should be_true
end
+ end
+ end
+ end
- it "should do nothing if the filetimeout setting is not greater than 0" do
- @settings.expects(:value).with(:filetimeout).returns -2
- EventLoop::Timer.expects(:new).never
- @settings.set_filetimeout_timer
- end
+ describe "when setting a timer to trigger configuration file reparsing" do
+ before do
+ @settings = Puppet::Util::Settings.new
+ @settings.setdefaults :foo, :filetimeout => [5, "eh"]
+ end
- it "should create a timer with its interval set to the filetimeout, start? set to true, and a tolerance of 1" do
- @settings.expects(:value).with(:filetimeout).returns 5
- EventLoop::Timer.expects(:new).with(:interval => 5, :start? => true, :tolerance => 1)
+ it "should do nothing if no filetimeout setting is available" do
+ @settings.expects(:value).with(:filetimeout).returns nil
+ EventLoop::Timer.expects(:new).never
+ @settings.set_filetimeout_timer
+ end
- @settings.set_filetimeout_timer
- end
+ it "should always convert the timer interval to an integer" do
+ @settings.expects(:value).with(:filetimeout).returns "10"
+ EventLoop::Timer.expects(:new).with(:interval => 10, :start? => true, :tolerance => 1)
+ @settings.set_filetimeout_timer
+ end
- it "should reparse when the timer goes off" do
- EventLoop::Timer.expects(:new).with(:interval => 5, :start? => true, :tolerance => 1).yields
+ it "should do nothing if the filetimeout setting is not greater than 0" do
+ @settings.expects(:value).with(:filetimeout).returns -2
+ EventLoop::Timer.expects(:new).never
+ @settings.set_filetimeout_timer
+ end
- @settings.expects(:reparse)
+ it "should create a timer with its interval set to the filetimeout, start? set to true, and a tolerance of 1" do
+ @settings.expects(:value).with(:filetimeout).returns 5
+ EventLoop::Timer.expects(:new).with(:interval => 5, :start? => true, :tolerance => 1)
- @settings.set_filetimeout_timer
- end
+ @settings.set_filetimeout_timer
end
- describe "when determining if the service user is available" do
- it "should return false if there is no user setting" do
- Puppet::Util::Settings.new.should_not be_service_user_available
- end
+ it "should reparse when the timer goes off" do
+ EventLoop::Timer.expects(:new).with(:interval => 5, :start? => true, :tolerance => 1).yields
- it "should return false if the user provider says the user is missing" do
- settings = Puppet::Util::Settings.new
- settings.setdefaults :main, :user => ["foo", "doc"]
+ @settings.expects(:reparse)
- user = mock 'user'
- user.expects(:exists?).returns false
+ @settings.set_filetimeout_timer
+ end
+ end
- Puppet::Type.type(:user).expects(:new).with { |args| args[:name] == "foo" }.returns user
+ describe "when determining if the service user is available" do
+ it "should return false if there is no user setting" do
+ Puppet::Util::Settings.new.should_not be_service_user_available
+ end
- settings.should_not be_service_user_available
- end
+ it "should return false if the user provider says the user is missing" do
+ settings = Puppet::Util::Settings.new
+ settings.setdefaults :main, :user => ["foo", "doc"]
+
+ user = mock 'user'
+ user.expects(:exists?).returns false
- it "should return true if the user provider says the user is present" do
- settings = Puppet::Util::Settings.new
- settings.setdefaults :main, :user => ["foo", "doc"]
+ Puppet::Type.type(:user).expects(:new).with { |args| args[:name] == "foo" }.returns user
- user = mock 'user'
- user.expects(:exists?).returns true
+ settings.should_not be_service_user_available
+ end
- Puppet::Type.type(:user).expects(:new).with { |args| args[:name] == "foo" }.returns user
+ it "should return true if the user provider says the user is present" do
+ settings = Puppet::Util::Settings.new
+ settings.setdefaults :main, :user => ["foo", "doc"]
- settings.should be_service_user_available
- end
+ user = mock 'user'
+ user.expects(:exists?).returns true
- it "should cache the result"
+ Puppet::Type.type(:user).expects(:new).with { |args| args[:name] == "foo" }.returns user
+
+ settings.should be_service_user_available
end
- describe "#without_noop" do
- before do
- @settings = Puppet::Util::Settings.new
- @settings.setdefaults :main, :noop => [true, ""]
- end
+ it "should cache the result"
+ end
- it "should set noop to false for the duration of the block" do
- @settings.without_noop { @settings.value(:noop, :cli).should be_false }
- end
+ describe "#without_noop" do
+ before do
+ @settings = Puppet::Util::Settings.new
+ @settings.setdefaults :main, :noop => [true, ""]
+ end
- it "should ensure that noop is returned to its previous value" do
- @settings.without_noop { raise } rescue nil
- @settings.value(:noop, :cli).should be_true
- end
+ it "should set noop to false for the duration of the block" do
+ @settings.without_noop { @settings.value(:noop, :cli).should be_false }
+ end
- it "should work even if no 'noop' setting is available" do
- settings = Puppet::Util::Settings.new
- stuff = nil
- settings.without_noop { stuff = "yay" }
- stuff.should == "yay"
- end
+ it "should ensure that noop is returned to its previous value" do
+ @settings.without_noop { raise } rescue nil
+ @settings.value(:noop, :cli).should be_true
+ end
+
+ it "should work even if no 'noop' setting is available" do
+ settings = Puppet::Util::Settings.new
+ stuff = nil
+ settings.without_noop { stuff = "yay" }
+ stuff.should == "yay"
end
+ end
end
diff --git a/spec/unit/util/storage_spec.rb b/spec/unit/util/storage_spec.rb
index c91702d..6c8baba 100755
--- a/spec/unit/util/storage_spec.rb
+++ b/spec/unit/util/storage_spec.rb
@@ -9,227 +9,227 @@ require 'puppet/util/storage'
describe Puppet::Util::Storage do
- before(:all) do
- @basepath = Puppet.features.posix? ? "/somepath" : "C:/somepath"
- Puppet[:statedir] = Dir.tmpdir
+ before(:all) do
+ @basepath = Puppet.features.posix? ? "/somepath" : "C:/somepath"
+ Puppet[:statedir] = Dir.tmpdir
+ end
+
+ after(:all) do
+ Puppet.settings.clear
+ end
+
+ before(:each) do
+ Puppet::Util::Storage.clear
+ end
+
+ describe "when caching a symbol" do
+ it "should return an empty hash" do
+ Puppet::Util::Storage.cache(:yayness).should == {}
+ Puppet::Util::Storage.cache(:more_yayness).should == {}
end
- after(:all) do
- Puppet.settings.clear
+ it "should add the symbol to its internal state" do
+ Puppet::Util::Storage.cache(:yayness)
+ Puppet::Util::Storage.state.should == {:yayness=>{}}
end
- before(:each) do
- Puppet::Util::Storage.clear
+ it "should not clobber existing state when caching additional objects" do
+ Puppet::Util::Storage.cache(:yayness)
+ Puppet::Util::Storage.state.should == {:yayness=>{}}
+ Puppet::Util::Storage.cache(:bubblyness)
+ Puppet::Util::Storage.state.should == {:yayness=>{},:bubblyness=>{}}
+ end
+ end
+
+ describe "when caching a Puppet::Type" do
+ before(:all) do
+ @file_test = Puppet::Type.type(:file).new(:name => @basepath+"/yayness", :check => %w{checksum type})
+ @exec_test = Puppet::Type.type(:exec).new(:name => @basepath+"/bin/ls /yayness")
end
- describe "when caching a symbol" do
- it "should return an empty hash" do
- Puppet::Util::Storage.cache(:yayness).should == {}
- Puppet::Util::Storage.cache(:more_yayness).should == {}
- end
+ it "should return an empty hash" do
+ Puppet::Util::Storage.cache(@file_test).should == {}
+ Puppet::Util::Storage.cache(@exec_test).should == {}
+ end
- it "should add the symbol to its internal state" do
- Puppet::Util::Storage.cache(:yayness)
- Puppet::Util::Storage.state.should == {:yayness=>{}}
- end
+ it "should add the resource ref to its internal state" do
+ Puppet::Util::Storage.state.should == {}
+ Puppet::Util::Storage.cache(@file_test)
+ Puppet::Util::Storage.state.should == {"File[#{@basepath}/yayness]"=>{}}
+ Puppet::Util::Storage.cache(@exec_test)
+ Puppet::Util::Storage.state.should == {"File[#{@basepath}/yayness]"=>{}, "Exec[#{@basepath}/bin/ls /yayness]"=>{}}
+ end
+ end
- it "should not clobber existing state when caching additional objects" do
- Puppet::Util::Storage.cache(:yayness)
- Puppet::Util::Storage.state.should == {:yayness=>{}}
- Puppet::Util::Storage.cache(:bubblyness)
- Puppet::Util::Storage.state.should == {:yayness=>{},:bubblyness=>{}}
- end
+ describe "when caching something other than a resource or symbol" do
+ it "should cache by converting to a string" do
+ data = Puppet::Util::Storage.cache(42)
+ data[:yay] = true
+ Puppet::Util::Storage.cache("42")[:yay].should be_true
+ end
+ end
+
+ it "should clear its internal state when clear() is called" do
+ Puppet::Util::Storage.cache(:yayness)
+ Puppet::Util::Storage.state.should == {:yayness=>{}}
+ Puppet::Util::Storage.clear
+ Puppet::Util::Storage.state.should == {}
+ end
+
+ describe "when loading from the state file" do
+ before do
+ Puppet.settings.stubs(:use).returns(true)
end
- describe "when caching a Puppet::Type" do
- before(:all) do
- @file_test = Puppet::Type.type(:file).new(:name => @basepath+"/yayness", :check => %w{checksum type})
- @exec_test = Puppet::Type.type(:exec).new(:name => @basepath+"/bin/ls /yayness")
- end
+ describe "when the state file/directory does not exist" do
+ before(:each) do
+ transient = Tempfile.new('storage_test')
+ @path = transient.path()
+ transient.close!()
+ end
- it "should return an empty hash" do
- Puppet::Util::Storage.cache(@file_test).should == {}
- Puppet::Util::Storage.cache(@exec_test).should == {}
- end
+ it "should not fail to load()" do
+ FileTest.exists?(@path).should be_false
+ Puppet[:statedir] = @path
+ proc { Puppet::Util::Storage.load }.should_not raise_error
+ Puppet[:statefile] = @path
+ proc { Puppet::Util::Storage.load }.should_not raise_error
+ end
- it "should add the resource ref to its internal state" do
- Puppet::Util::Storage.state.should == {}
- Puppet::Util::Storage.cache(@file_test)
- Puppet::Util::Storage.state.should == {"File[#{@basepath}/yayness]"=>{}}
- Puppet::Util::Storage.cache(@exec_test)
- Puppet::Util::Storage.state.should == {"File[#{@basepath}/yayness]"=>{}, "Exec[#{@basepath}/bin/ls /yayness]"=>{}}
- end
- end
+ it "should not lose its internal state when load() is called" do
+ FileTest.exists?(@path).should be_false
+
+ Puppet::Util::Storage.cache(:yayness)
+ Puppet::Util::Storage.state.should == {:yayness=>{}}
+
+ Puppet[:statefile] = @path
+ proc { Puppet::Util::Storage.load }.should_not raise_error
- describe "when caching something other than a resource or symbol" do
- it "should cache by converting to a string" do
- data = Puppet::Util::Storage.cache(42)
- data[:yay] = true
- Puppet::Util::Storage.cache("42")[:yay].should be_true
- end
+ Puppet::Util::Storage.state.should == {:yayness=>{}}
+ end
end
- it "should clear its internal state when clear() is called" do
+ describe "when the state file/directory exists" do
+ before(:each) do
+ @state_file = Tempfile.new('storage_test')
+ @saved_statefile = Puppet[:statefile]
+ Puppet[:statefile] = @state_file.path
+ end
+
+ it "should overwrite its internal state if load() is called" do
+ # Should the state be overwritten even if Puppet[:statefile] is not valid YAML?
Puppet::Util::Storage.cache(:yayness)
Puppet::Util::Storage.state.should == {:yayness=>{}}
- Puppet::Util::Storage.clear
+
+ proc { Puppet::Util::Storage.load }.should_not raise_error
Puppet::Util::Storage.state.should == {}
+ end
+
+ it "should restore its internal state if the state file contains valid YAML" do
+ test_yaml = {'File["/yayness"]'=>{"name"=>{:a=>:b,:c=>:d}}}
+ YAML.expects(:load).returns(test_yaml)
+
+ proc { Puppet::Util::Storage.load }.should_not raise_error
+ Puppet::Util::Storage.state.should == test_yaml
+ end
+
+ it "should initialize with a clear internal state if the state file does not contain valid YAML" do
+ @state_file.write(:booness)
+ @state_file.flush
+
+ proc { Puppet::Util::Storage.load }.should_not raise_error
+ Puppet::Util::Storage.state.should == {}
+ end
+
+ it "should raise an error if the state file does not contain valid YAML and cannot be renamed" do
+ @state_file.write(:booness)
+ @state_file.flush
+ YAML.expects(:load).raises(Puppet::Error)
+ File.expects(:rename).raises(SystemCallError)
+
+ proc { Puppet::Util::Storage.load }.should raise_error
+ end
+
+ it "should attempt to rename the state file if the file is corrupted" do
+ # We fake corruption by causing YAML.load to raise an exception
+ YAML.expects(:load).raises(Puppet::Error)
+ File.expects(:rename).at_least_once
+
+ proc { Puppet::Util::Storage.load }.should_not raise_error
+ end
+
+ it "should fail gracefully on load() if the state file is not a regular file" do
+ @state_file.close!()
+ Dir.mkdir(Puppet[:statefile])
+
+ proc { Puppet::Util::Storage.load }.should_not raise_error
+
+ Dir.rmdir(Puppet[:statefile])
+ end
+
+ it "should fail gracefully on load() if it cannot get a read lock on the state file" do
+ Puppet::Util::FileLocking.expects(:readlock).yields(false)
+ test_yaml = {'File["/yayness"]'=>{"name"=>{:a=>:b,:c=>:d}}}
+ YAML.expects(:load).returns(test_yaml)
+
+ proc { Puppet::Util::Storage.load }.should_not raise_error
+ Puppet::Util::Storage.state.should == test_yaml
+ end
+
+ after(:each) do
+ @state_file.close!()
+ Puppet[:statefile] = @saved_statefile
+ end
end
+ end
- describe "when loading from the state file" do
- before do
- Puppet.settings.stubs(:use).returns(true)
- end
-
- describe "when the state file/directory does not exist" do
- before(:each) do
- transient = Tempfile.new('storage_test')
- @path = transient.path()
- transient.close!()
- end
-
- it "should not fail to load()" do
- FileTest.exists?(@path).should be_false
- Puppet[:statedir] = @path
- proc { Puppet::Util::Storage.load }.should_not raise_error
- Puppet[:statefile] = @path
- proc { Puppet::Util::Storage.load }.should_not raise_error
- end
-
- it "should not lose its internal state when load() is called" do
- FileTest.exists?(@path).should be_false
-
- Puppet::Util::Storage.cache(:yayness)
- Puppet::Util::Storage.state.should == {:yayness=>{}}
-
- Puppet[:statefile] = @path
- proc { Puppet::Util::Storage.load }.should_not raise_error
-
- Puppet::Util::Storage.state.should == {:yayness=>{}}
- end
- end
+ describe "when storing to the state file" do
+ before(:each) do
+ @state_file = Tempfile.new('storage_test')
+ @saved_statefile = Puppet[:statefile]
+ Puppet[:statefile] = @state_file.path
+ end
- describe "when the state file/directory exists" do
- before(:each) do
- @state_file = Tempfile.new('storage_test')
- @saved_statefile = Puppet[:statefile]
- Puppet[:statefile] = @state_file.path
- end
+ it "should create the state file if it does not exist" do
+ @state_file.close!()
+ FileTest.exists?(Puppet[:statefile]).should be_false
+ Puppet::Util::Storage.cache(:yayness)
- it "should overwrite its internal state if load() is called" do
- # Should the state be overwritten even if Puppet[:statefile] is not valid YAML?
- Puppet::Util::Storage.cache(:yayness)
- Puppet::Util::Storage.state.should == {:yayness=>{}}
+ proc { Puppet::Util::Storage.store }.should_not raise_error
+ FileTest.exists?(Puppet[:statefile]).should be_true
+ end
- proc { Puppet::Util::Storage.load }.should_not raise_error
- Puppet::Util::Storage.state.should == {}
- end
-
- it "should restore its internal state if the state file contains valid YAML" do
- test_yaml = {'File["/yayness"]'=>{"name"=>{:a=>:b,:c=>:d}}}
- YAML.expects(:load).returns(test_yaml)
-
- proc { Puppet::Util::Storage.load }.should_not raise_error
- Puppet::Util::Storage.state.should == test_yaml
- end
-
- it "should initialize with a clear internal state if the state file does not contain valid YAML" do
- @state_file.write(:booness)
- @state_file.flush
-
- proc { Puppet::Util::Storage.load }.should_not raise_error
- Puppet::Util::Storage.state.should == {}
- end
-
- it "should raise an error if the state file does not contain valid YAML and cannot be renamed" do
- @state_file.write(:booness)
- @state_file.flush
- YAML.expects(:load).raises(Puppet::Error)
- File.expects(:rename).raises(SystemCallError)
-
- proc { Puppet::Util::Storage.load }.should raise_error
- end
-
- it "should attempt to rename the state file if the file is corrupted" do
- # We fake corruption by causing YAML.load to raise an exception
- YAML.expects(:load).raises(Puppet::Error)
- File.expects(:rename).at_least_once
-
- proc { Puppet::Util::Storage.load }.should_not raise_error
- end
-
- it "should fail gracefully on load() if the state file is not a regular file" do
- @state_file.close!()
- Dir.mkdir(Puppet[:statefile])
-
- proc { Puppet::Util::Storage.load }.should_not raise_error
-
- Dir.rmdir(Puppet[:statefile])
- end
-
- it "should fail gracefully on load() if it cannot get a read lock on the state file" do
- Puppet::Util::FileLocking.expects(:readlock).yields(false)
- test_yaml = {'File["/yayness"]'=>{"name"=>{:a=>:b,:c=>:d}}}
- YAML.expects(:load).returns(test_yaml)
-
- proc { Puppet::Util::Storage.load }.should_not raise_error
- Puppet::Util::Storage.state.should == test_yaml
- end
-
- after(:each) do
- @state_file.close!()
- Puppet[:statefile] = @saved_statefile
- end
- end
- end
-
- describe "when storing to the state file" do
- before(:each) do
- @state_file = Tempfile.new('storage_test')
- @saved_statefile = Puppet[:statefile]
- Puppet[:statefile] = @state_file.path
- end
-
- it "should create the state file if it does not exist" do
- @state_file.close!()
- FileTest.exists?(Puppet[:statefile]).should be_false
- Puppet::Util::Storage.cache(:yayness)
+ it "should raise an exception if the state file is not a regular file" do
+ @state_file.close!()
+ Dir.mkdir(Puppet[:statefile])
+ Puppet::Util::Storage.cache(:yayness)
- proc { Puppet::Util::Storage.store }.should_not raise_error
- FileTest.exists?(Puppet[:statefile]).should be_true
- end
+ proc { Puppet::Util::Storage.store }.should raise_error
- it "should raise an exception if the state file is not a regular file" do
- @state_file.close!()
- Dir.mkdir(Puppet[:statefile])
- Puppet::Util::Storage.cache(:yayness)
-
- proc { Puppet::Util::Storage.store }.should raise_error
-
- Dir.rmdir(Puppet[:statefile])
- end
-
- it "should raise an exception if it cannot get a write lock on the state file" do
- Puppet::Util::FileLocking.expects(:writelock).yields(false)
- Puppet::Util::Storage.cache(:yayness)
-
- proc { Puppet::Util::Storage.store }.should raise_error
- end
+ Dir.rmdir(Puppet[:statefile])
+ end
- it "should load() the same information that it store()s" do
- Puppet::Util::Storage.cache(:yayness)
+ it "should raise an exception if it cannot get a write lock on the state file" do
+ Puppet::Util::FileLocking.expects(:writelock).yields(false)
+ Puppet::Util::Storage.cache(:yayness)
- Puppet::Util::Storage.state.should == {:yayness=>{}}
- proc { Puppet::Util::Storage.store }.should_not raise_error
- Puppet::Util::Storage.clear
- Puppet::Util::Storage.state.should == {}
- proc { Puppet::Util::Storage.load }.should_not raise_error
- Puppet::Util::Storage.state.should == {:yayness=>{}}
- end
+ proc { Puppet::Util::Storage.store }.should raise_error
+ end
+
+ it "should load() the same information that it store()s" do
+ Puppet::Util::Storage.cache(:yayness)
+
+ Puppet::Util::Storage.state.should == {:yayness=>{}}
+ proc { Puppet::Util::Storage.store }.should_not raise_error
+ Puppet::Util::Storage.clear
+ Puppet::Util::Storage.state.should == {}
+ proc { Puppet::Util::Storage.load }.should_not raise_error
+ Puppet::Util::Storage.state.should == {:yayness=>{}}
+ end
- after(:each) do
- @state_file.close!()
- Puppet[:statefile] = @saved_statefile
- end
+ after(:each) do
+ @state_file.close!()
+ Puppet[:statefile] = @saved_statefile
end
+ end
end
diff --git a/spec/unit/util/tagging_spec.rb b/spec/unit/util/tagging_spec.rb
index 04800b3..8fd8552 100755
--- a/spec/unit/util/tagging_spec.rb
+++ b/spec/unit/util/tagging_spec.rb
@@ -8,95 +8,95 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/util/tagging'
describe Puppet::Util::Tagging, "when adding tags" do
- before do
- @tagger = Object.new
- @tagger.extend(Puppet::Util::Tagging)
- end
-
- it "should have a method for adding tags" do
- @tagger.should be_respond_to(:tag)
- end
-
- it "should have a method for returning all tags" do
- @tagger.should be_respond_to(:tags)
- end
-
- it "should add tags to the returned tag list" do
- @tagger.tag("one")
- @tagger.tags.should be_include("one")
- end
-
- it "should not add duplicate tags to the returned tag list" do
- @tagger.tag("one")
- @tagger.tag("one")
- @tagger.tags.should == ["one"]
- end
-
- it "should return a duplicate of the tag list, rather than the original" do
- @tagger.tag("one")
- tags = @tagger.tags
- tags << "two"
- @tagger.tags.should_not be_include("two")
- end
-
- it "should add all provided tags to the tag list" do
- @tagger.tag("one", "two")
- @tagger.tags.should be_include("one")
- @tagger.tags.should be_include("two")
- end
-
- it "should fail on tags containing '*' characters" do
- lambda { @tagger.tag("bad*tag") }.should raise_error(Puppet::ParseError)
- end
-
- it "should fail on tags starting with '-' characters" do
- lambda { @tagger.tag("-badtag") }.should raise_error(Puppet::ParseError)
- end
-
- it "should fail on tags containing ' ' characters" do
- lambda { @tagger.tag("bad tag") }.should raise_error(Puppet::ParseError)
- end
-
- it "should allow alpha tags" do
- lambda { @tagger.tag("good_tag") }.should_not raise_error(Puppet::ParseError)
- end
-
- it "should allow tags containing '.' characters" do
- lambda { @tagger.tag("good.tag") }.should_not raise_error(Puppet::ParseError)
- end
-
- it "should provide a method for testing tag validity" do
- @tagger.singleton_class.publicize_methods(:valid_tag?) { @tagger.should be_respond_to(:valid_tag?) }
- end
-
- it "should add qualified classes as tags" do
- @tagger.tag("one::two")
- @tagger.tags.should be_include("one::two")
- end
-
- it "should add each part of qualified classes as tags" do
- @tagger.tag("one::two::three")
- @tagger.tags.should be_include("one")
- @tagger.tags.should be_include("two")
- @tagger.tags.should be_include("three")
- end
-
- it "should indicate when the object is tagged with a provided tag" do
- @tagger.tag("one")
- @tagger.should be_tagged("one")
- end
-
- it "should indicate when the object is not tagged with a provided tag" do
- @tagger.should_not be_tagged("one")
- end
-
- it "should indicate when the object is tagged with any tag in an array" do
- @tagger.tag("one")
- @tagger.should be_tagged("one","two","three")
- end
-
- it "should indicate when the object is not tagged with any tag in an array" do
- @tagger.tag("one")
- @tagger.should_not be_tagged("two","three")
- end
+ before do
+ @tagger = Object.new
+ @tagger.extend(Puppet::Util::Tagging)
+ end
+
+ it "should have a method for adding tags" do
+ @tagger.should be_respond_to(:tag)
+ end
+
+ it "should have a method for returning all tags" do
+ @tagger.should be_respond_to(:tags)
+ end
+
+ it "should add tags to the returned tag list" do
+ @tagger.tag("one")
+ @tagger.tags.should be_include("one")
+ end
+
+ it "should not add duplicate tags to the returned tag list" do
+ @tagger.tag("one")
+ @tagger.tag("one")
+ @tagger.tags.should == ["one"]
+ end
+
+ it "should return a duplicate of the tag list, rather than the original" do
+ @tagger.tag("one")
+ tags = @tagger.tags
+ tags << "two"
+ @tagger.tags.should_not be_include("two")
+ end
+
+ it "should add all provided tags to the tag list" do
+ @tagger.tag("one", "two")
+ @tagger.tags.should be_include("one")
+ @tagger.tags.should be_include("two")
+ end
+
+ it "should fail on tags containing '*' characters" do
+ lambda { @tagger.tag("bad*tag") }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should fail on tags starting with '-' characters" do
+ lambda { @tagger.tag("-badtag") }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should fail on tags containing ' ' characters" do
+ lambda { @tagger.tag("bad tag") }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should allow alpha tags" do
+ lambda { @tagger.tag("good_tag") }.should_not raise_error(Puppet::ParseError)
+ end
+
+ it "should allow tags containing '.' characters" do
+ lambda { @tagger.tag("good.tag") }.should_not raise_error(Puppet::ParseError)
+ end
+
+ it "should provide a method for testing tag validity" do
+ @tagger.singleton_class.publicize_methods(:valid_tag?) { @tagger.should be_respond_to(:valid_tag?) }
+ end
+
+ it "should add qualified classes as tags" do
+ @tagger.tag("one::two")
+ @tagger.tags.should be_include("one::two")
+ end
+
+ it "should add each part of qualified classes as tags" do
+ @tagger.tag("one::two::three")
+ @tagger.tags.should be_include("one")
+ @tagger.tags.should be_include("two")
+ @tagger.tags.should be_include("three")
+ end
+
+ it "should indicate when the object is tagged with a provided tag" do
+ @tagger.tag("one")
+ @tagger.should be_tagged("one")
+ end
+
+ it "should indicate when the object is not tagged with a provided tag" do
+ @tagger.should_not be_tagged("one")
+ end
+
+ it "should indicate when the object is tagged with any tag in an array" do
+ @tagger.tag("one")
+ @tagger.should be_tagged("one","two","three")
+ end
+
+ it "should indicate when the object is not tagged with any tag in an array" do
+ @tagger.tag("one")
+ @tagger.should_not be_tagged("two","three")
+ end
end
diff --git a/spec/unit/util/user_attr_spec.rb b/spec/unit/util/user_attr_spec.rb
index 88f538b..61312ef 100644
--- a/spec/unit/util/user_attr_spec.rb
+++ b/spec/unit/util/user_attr_spec.rb
@@ -5,43 +5,43 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
require 'puppet/util/user_attr'
describe UserAttr do
- before do
- user_attr = ["foo::::type=role", "bar::::type=normal;profile=foobar"]
- File.stubs(:readlines).returns(user_attr)
+ before do
+ user_attr = ["foo::::type=role", "bar::::type=normal;profile=foobar"]
+ File.stubs(:readlines).returns(user_attr)
+ end
+
+ describe "when getting attributes by name" do
+ it "should return nil if there is no entry for that name" do
+ UserAttr.get_attributes_by_name('baz').should == nil
end
- describe "when getting attributes by name" do
- it "should return nil if there is no entry for that name" do
- UserAttr.get_attributes_by_name('baz').should == nil
- end
-
- it "should return a hash if there is an entry in /etc/user_attr" do
- UserAttr.get_attributes_by_name('foo').class.should == Hash
- end
-
- it "should return a hash with the name value from /etc/user_attr" do
- UserAttr.get_attributes_by_name('foo')[:name].should == 'foo'
- end
-
- #this test is contrived
- #there are a bunch of possible parameters that could be in the hash
- #the role/normal is just a the convention of the file
- describe "when the name is a role" do
- it "should contain :type = role" do
- UserAttr.get_attributes_by_name('foo')[:type].should == 'role'
- end
- end
-
- describe "when the name is not a role" do
- it "should contain :type = normal" do
- UserAttr.get_attributes_by_name('bar')[:type].should == 'normal'
- end
- end
-
- describe "when the name has more attributes" do
- it "should contain all the attributes" do
- UserAttr.get_attributes_by_name('bar')[:profile].should == 'foobar'
- end
- end
+ it "should return a hash if there is an entry in /etc/user_attr" do
+ UserAttr.get_attributes_by_name('foo').class.should == Hash
end
+
+ it "should return a hash with the name value from /etc/user_attr" do
+ UserAttr.get_attributes_by_name('foo')[:name].should == 'foo'
+ end
+
+ #this test is contrived
+ #there are a bunch of possible parameters that could be in the hash
+ #the role/normal is just a the convention of the file
+ describe "when the name is a role" do
+ it "should contain :type = role" do
+ UserAttr.get_attributes_by_name('foo')[:type].should == 'role'
+ end
+ end
+
+ describe "when the name is not a role" do
+ it "should contain :type = normal" do
+ UserAttr.get_attributes_by_name('bar')[:type].should == 'normal'
+ end
+ end
+
+ describe "when the name has more attributes" do
+ it "should contain all the attributes" do
+ UserAttr.get_attributes_by_name('bar')[:profile].should == 'foobar'
+ end
+ end
+ end
end
diff --git a/spec/unit/util/warnings_spec.rb b/spec/unit/util/warnings_spec.rb
index 7cdee00..c05c983 100755
--- a/spec/unit/util/warnings_spec.rb
+++ b/spec/unit/util/warnings_spec.rb
@@ -3,37 +3,37 @@
require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::Util::Warnings do
- before(:all) do
- @msg1 = "booness"
- @msg2 = "more booness"
- end
+ before(:all) do
+ @msg1 = "booness"
+ @msg2 = "more booness"
+ end
- {:notice => "notice_once", :warning => "warnonce"}.each do |log, method|
- describe "when registring '#{log}' messages" do
- it "should always return nil" do
- Puppet::Util::Warnings.send(method, @msg1).should be(nil)
- end
+ {:notice => "notice_once", :warning => "warnonce"}.each do |log, method|
+ describe "when registring '#{log}' messages" do
+ it "should always return nil" do
+ Puppet::Util::Warnings.send(method, @msg1).should be(nil)
+ end
- it "should issue a warning" do
- Puppet.expects(log).with(@msg1)
- Puppet::Util::Warnings.send(method, @msg1)
- end
+ it "should issue a warning" do
+ Puppet.expects(log).with(@msg1)
+ Puppet::Util::Warnings.send(method, @msg1)
+ end
- it "should issue a warning exactly once per unique message" do
- Puppet.expects(log).with(@msg1).once
- Puppet::Util::Warnings.send(method, @msg1)
- Puppet::Util::Warnings.send(method, @msg1)
- end
+ it "should issue a warning exactly once per unique message" do
+ Puppet.expects(log).with(@msg1).once
+ Puppet::Util::Warnings.send(method, @msg1)
+ Puppet::Util::Warnings.send(method, @msg1)
+ end
- it "should issue multiple warnings for multiple unique messages" do
- Puppet.expects(log).times(2)
- Puppet::Util::Warnings.send(method, @msg1)
- Puppet::Util::Warnings.send(method, @msg2)
- end
- end
+ it "should issue multiple warnings for multiple unique messages" do
+ Puppet.expects(log).times(2)
+ Puppet::Util::Warnings.send(method, @msg1)
+ Puppet::Util::Warnings.send(method, @msg2)
+ end
end
+ end
- after(:each) do
- Puppet::Util::Warnings.clear_warnings
- end
+ after(:each) do
+ Puppet::Util::Warnings.clear_warnings
+ end
end
diff --git a/spec/unit/util/zaml_spec.rb b/spec/unit/util/zaml_spec.rb
index e39dbdf..4de57e6 100644
--- a/spec/unit/util/zaml_spec.rb
+++ b/spec/unit/util/zaml_spec.rb
@@ -5,34 +5,34 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
require 'puppet/util/monkey_patches'
describe "Pure ruby yaml implementation" do
- {
- 7 => "--- 7",
- 3.14159 => "--- 3.14159",
- 'test' => "--- test",
- [] => "--- []",
- :symbol => "--- !ruby/sym symbol",
- {:a => "A"} => "--- \n !ruby/sym a: A"
- }.each { |o,y|
- it "should convert the #{o.class} #{o.inspect} to yaml" do
- o.to_yaml.should == y
- end
- it "should produce yaml for the #{o.class} #{o.inspect} that can be reconstituted" do
- YAML.load(o.to_yaml).should == o
- end
- }
- #
- # Can't test for equality on raw objects
- {
- Object.new => "--- !ruby/object {}",
- [Object.new] => "--- \n - !ruby/object {}",
- {Object.new => Object.new} => "--- \n ? !ruby/object {}\n : !ruby/object {}"
- }.each { |o,y|
- it "should convert the #{o.class} #{o.inspect} to yaml" do
- o.to_yaml.should == y
- end
- it "should produce yaml for the #{o.class} #{o.inspect} that can be reconstituted" do
- lambda { YAML.load(o.to_yaml) }.should_not raise_error
- end
- }
+ {
+ 7 => "--- 7",
+ 3.14159 => "--- 3.14159",
+ 'test' => "--- test",
+ [] => "--- []",
+ :symbol => "--- !ruby/sym symbol",
+ {:a => "A"} => "--- \n !ruby/sym a: A"
+ }.each { |o,y|
+ it "should convert the #{o.class} #{o.inspect} to yaml" do
+ o.to_yaml.should == y
+ end
+ it "should produce yaml for the #{o.class} #{o.inspect} that can be reconstituted" do
+ YAML.load(o.to_yaml).should == o
+ end
+ }
+ #
+ # Can't test for equality on raw objects
+ {
+ Object.new => "--- !ruby/object {}",
+ [Object.new] => "--- \n - !ruby/object {}",
+ {Object.new => Object.new} => "--- \n ? !ruby/object {}\n : !ruby/object {}"
+ }.each { |o,y|
+ it "should convert the #{o.class} #{o.inspect} to yaml" do
+ o.to_yaml.should == y
+ end
+ it "should produce yaml for the #{o.class} #{o.inspect} that can be reconstituted" do
+ lambda { YAML.load(o.to_yaml) }.should_not raise_error
+ end
+ }
end
diff --git a/test/certmgr/ca.rb b/test/certmgr/ca.rb
index 4ef6a0d..7e0498d 100755
--- a/test/certmgr/ca.rb
+++ b/test/certmgr/ca.rb
@@ -9,79 +9,79 @@ require 'puppettest/certificates'
require 'mocha'
class TestCA < Test::Unit::TestCase
- include PuppetTest
+ include PuppetTest
- def setup
- super
- Puppet::Util::SUIDManager.stubs(:asuser).yields
- end
+ def setup
+ super
+ Puppet::Util::SUIDManager.stubs(:asuser).yields
+ end
- def hosts
- %w{host.domain.com Other.Testing.Com}
- end
- def mkca
- Puppet::SSLCertificates::CA.new
- end
+ def hosts
+ %w{host.domain.com Other.Testing.Com}
+ end
+ def mkca
+ Puppet::SSLCertificates::CA.new
+ end
- def test_clean
- dirs = [:csrdir, :signeddir, :publickeydir, :privatekeydir, :certdir]
- ca = mkca
+ def test_clean
+ dirs = [:csrdir, :signeddir, :publickeydir, :privatekeydir, :certdir]
+ ca = mkca
- hosts.each do |host|
- files = []
- dirs.each do |dir|
- dir = Puppet[dir]
- # We handle case insensitivity through downcasing
- file = File.join(dir, host.downcase + ".pem")
- File.open(file, "w") do |f|
- f.puts "testing"
- end
- files << file
- end
- assert_nothing_raised do
- ca.clean(host)
- end
- files.each do |f|
- assert(! FileTest.exists?(f), "File #{f} was not deleted")
- end
+ hosts.each do |host|
+ files = []
+ dirs.each do |dir|
+ dir = Puppet[dir]
+ # We handle case insensitivity through downcasing
+ file = File.join(dir, host.downcase + ".pem")
+ File.open(file, "w") do |f|
+ f.puts "testing"
end
+ files << file
+ end
+ assert_nothing_raised do
+ ca.clean(host)
+ end
+ files.each do |f|
+ assert(! FileTest.exists?(f), "File #{f} was not deleted")
+ end
end
+ end
- def test_host2Xfile
- ca = mkca
- hosts.each do |host|
- {:signeddir => :host2certfile, :csrdir => :host2csrfile}.each do |dir, method|
- val = nil
- assert_nothing_raised do
- val = ca.send(method, host)
- end
- assert_equal(File.join(Puppet[dir], host.downcase + ".pem"), val,
- "incorrect response from #{method}")
- end
+ def test_host2Xfile
+ ca = mkca
+ hosts.each do |host|
+ {:signeddir => :host2certfile, :csrdir => :host2csrfile}.each do |dir, method|
+ val = nil
+ assert_nothing_raised do
+ val = ca.send(method, host)
end
+ assert_equal(File.join(Puppet[dir], host.downcase + ".pem"), val,
+ "incorrect response from #{method}")
+ end
end
+ end
- def test_list
- ca = mkca
- # Make a fake csr
- dir = Puppet[:csrdir]
- list = []
- hosts.each do |host|
- file = File.join(dir, host.downcase + ".pem")
- File.open(file, "w") { |f| f.puts "yay" }
- list << host.downcase
- end
-
- assert_equal(list.sort, ca.list.sort, "list was not correct")
+ def test_list
+ ca = mkca
+ # Make a fake csr
+ dir = Puppet[:csrdir]
+ list = []
+ hosts.each do |host|
+ file = File.join(dir, host.downcase + ".pem")
+ File.open(file, "w") { |f| f.puts "yay" }
+ list << host.downcase
end
- # #142 - test storing the public key
- def test_store_public_key
- ca = mkca
- assert_nothing_raised do
- ca.mkrootcert
- end
- assert(FileTest.exists?(Puppet[:capub]), "did not store public key")
+ assert_equal(list.sort, ca.list.sort, "list was not correct")
+ end
+
+ # #142 - test storing the public key
+ def test_store_public_key
+ ca = mkca
+ assert_nothing_raised do
+ ca.mkrootcert
end
+ assert(FileTest.exists?(Puppet[:capub]), "did not store public key")
+ end
end
diff --git a/test/certmgr/certmgr.rb b/test/certmgr/certmgr.rb
index 3cf743a..b78a138 100755
--- a/test/certmgr/certmgr.rb
+++ b/test/certmgr/certmgr.rb
@@ -9,300 +9,300 @@ require 'puppettest/certificates'
require 'mocha'
class TestCertMgr < Test::Unit::TestCase
- include PuppetTest::Certificates
- def setup
- super
- #@dir = File.join(Puppet[:certdir], "testing")
- @dir = File.join(@configpath, "certest")
- system("mkdir -p #{@dir}")
-
- Puppet::Util::SUIDManager.stubs(:asuser).yields
- end
-
- def testCreateSelfSignedCertificate
- cert = nil
- name = "testing"
- newcert = proc {
-
- Puppet::SSLCertificates::Certificate.new(
+ include PuppetTest::Certificates
+ def setup
+ super
+ #@dir = File.join(Puppet[:certdir], "testing")
+ @dir = File.join(@configpath, "certest")
+ system("mkdir -p #{@dir}")
+
+ Puppet::Util::SUIDManager.stubs(:asuser).yields
+ end
+
+ def testCreateSelfSignedCertificate
+ cert = nil
+ name = "testing"
+ newcert = proc {
+
+ Puppet::SSLCertificates::Certificate.new(
- :name => name,
+ :name => name,
- :selfsign => true
- )
- }
- assert_nothing_raised {
- cert = newcert.call
- }
- assert_nothing_raised {
- cert.mkselfsigned
- }
-
- assert_raise(Puppet::Error) {
- cert.mkselfsigned
- }
-
- assert_nothing_raised {
- cert.write
- }
-
- assert(FileTest.exists?(cert.certfile))
-
- assert_nothing_raised {
- cert.delete
- }
-
- assert_nothing_raised {
- cert = newcert.call
- }
- assert_nothing_raised {
- cert.mkselfsigned
- }
-
- assert_nothing_raised {
- cert.delete
- }
-
- end
-
- def disabled_testCreateEncryptedSelfSignedCertificate
- cert = nil
- name = "testing"
- keyfile = mkPassFile
- assert_nothing_raised {
-
- cert = Puppet::SSLCertificates::Certificate.new(
+ :selfsign => true
+ )
+ }
+ assert_nothing_raised {
+ cert = newcert.call
+ }
+ assert_nothing_raised {
+ cert.mkselfsigned
+ }
+
+ assert_raise(Puppet::Error) {
+ cert.mkselfsigned
+ }
+
+ assert_nothing_raised {
+ cert.write
+ }
+
+ assert(FileTest.exists?(cert.certfile))
+
+ assert_nothing_raised {
+ cert.delete
+ }
+
+ assert_nothing_raised {
+ cert = newcert.call
+ }
+ assert_nothing_raised {
+ cert.mkselfsigned
+ }
+
+ assert_nothing_raised {
+ cert.delete
+ }
+
+ end
+
+ def disabled_testCreateEncryptedSelfSignedCertificate
+ cert = nil
+ name = "testing"
+ keyfile = mkPassFile
+ assert_nothing_raised {
+
+ cert = Puppet::SSLCertificates::Certificate.new(
- :name => name,
- :selfsign => true,
+ :name => name,
+ :selfsign => true,
- :capass => keyfile
- )
- }
- assert_nothing_raised {
- cert.mkselfsigned
- }
- assert_nothing_raised {
- cert.mkhash
- }
-
- assert_raise(Puppet::Error) {
- cert.mkselfsigned
- }
-
- assert(FileTest.exists?(cert.certfile))
- assert(FileTest.exists?(cert.hash))
-
- assert_nothing_raised {
- cert.delete
- }
-
- assert_nothing_raised {
- cert.mkselfsigned
- }
-
- assert_nothing_raised {
- cert.delete
- }
-
- end
-
- def testCreateCA
- ca = nil
- assert_nothing_raised {
- ca = Puppet::SSLCertificates::CA.new
- }
-
- # make the CA again and verify it doesn't fail because everything
- # still exists
- assert_nothing_raised {
- ca = Puppet::SSLCertificates::CA.new
- }
-
- end
-
- def testSignCert
- ca = mkCA()
-
- cert = nil
- assert_nothing_raised {
-
- cert = Puppet::SSLCertificates::Certificate.new(
+ :capass => keyfile
+ )
+ }
+ assert_nothing_raised {
+ cert.mkselfsigned
+ }
+ assert_nothing_raised {
+ cert.mkhash
+ }
+
+ assert_raise(Puppet::Error) {
+ cert.mkselfsigned
+ }
+
+ assert(FileTest.exists?(cert.certfile))
+ assert(FileTest.exists?(cert.hash))
+
+ assert_nothing_raised {
+ cert.delete
+ }
+
+ assert_nothing_raised {
+ cert.mkselfsigned
+ }
+
+ assert_nothing_raised {
+ cert.delete
+ }
+
+ end
+
+ def testCreateCA
+ ca = nil
+ assert_nothing_raised {
+ ca = Puppet::SSLCertificates::CA.new
+ }
+
+ # make the CA again and verify it doesn't fail because everything
+ # still exists
+ assert_nothing_raised {
+ ca = Puppet::SSLCertificates::CA.new
+ }
+
+ end
+
+ def testSignCert
+ ca = mkCA()
+
+ cert = nil
+ assert_nothing_raised {
+
+ cert = Puppet::SSLCertificates::Certificate.new(
- :name => "signedcertest",
- :property => "TN",
- :city => "Nashville",
- :country => "US",
- :email => "luke at madstop.com",
- :org => "Puppet",
- :ou => "Development",
+ :name => "signedcertest",
+ :property => "TN",
+ :city => "Nashville",
+ :country => "US",
+ :email => "luke at madstop.com",
+ :org => "Puppet",
+ :ou => "Development",
- :encrypt => mkPassFile()
- )
-
- }
-
- assert_nothing_raised {
- cert.mkcsr
- }
-
- signedcert = nil
- cacert = nil
-
- assert_nothing_raised {
- signedcert, cacert = ca.sign(cert.csr)
- }
-
- assert_instance_of(OpenSSL::X509::Certificate, signedcert)
- assert_instance_of(OpenSSL::X509::Certificate, cacert)
-
- assert_nothing_raised {
- cert.cert = signedcert
- cert.cacert = cacert
- cert.write
- }
- #system("find #{Puppet[:ssldir]}")
- #system("cp -R #{Puppet[:ssldir]} /tmp/ssltesting")
-
- output = nil
- assert_nothing_raised {
- output = %x{openssl verify -CAfile #{Puppet[:cacert]} -purpose sslserver #{cert.certfile}}
- #output = %x{openssl verify -CApath #{Puppet[:certdir]} -purpose sslserver #{cert.certfile}}
- }
-
- assert_equal($CHILD_STATUS,0)
- assert_equal(File.join(Puppet[:certdir], "signedcertest.pem: OK\n"), output)
- end
-
-
- def test_interactiveca
- ca = nil
-
- assert_nothing_raised {
- ca = Puppet::SSLCertificates::CA.new
- }
-
- # basic initialization
- hostname = "test.hostname.com"
- cert = mkcert(hostname)
-
- # create the csr
- csr = nil
- assert_nothing_raised {
- csr = cert.mkcsr
- }
-
- assert_nothing_raised {
- ca.storeclientcsr(csr)
- }
-
- # store it
- pulledcsr = nil
- assert_nothing_raised {
- pulledcsr = ca.getclientcsr(hostname)
- }
-
- assert_equal(csr.to_pem, pulledcsr.to_pem)
-
- signedcert = nil
- assert_nothing_raised {
- signedcert, cacert = ca.sign(csr)
- }
-
- assert_instance_of(OpenSSL::X509::Certificate, signedcert)
- newsignedcert = nil
- assert_nothing_raised {
- newsignedcert, cacert = ca.getclientcert(hostname)
- }
-
- assert(newsignedcert)
-
- assert_equal(signedcert.to_pem, newsignedcert.to_pem)
- end
-
- def test_cafailures
- ca = mkCA()
- cert = cacert = nil
- assert_nothing_raised {
- cert, cacert = ca.getclientcert("nohost")
- }
- assert_nil(cert)
- end
-
- def test_crl
- ca = mkCA()
- h1 = mksignedcert(ca, "host1.example.com")
- h2 = mksignedcert(ca, "host2.example.com")
-
- assert(ca.cert.verify(ca.cert.public_key))
- assert(h1.verify(ca.cert.public_key))
- assert(h2.verify(ca.cert.public_key))
-
- crl = ca.crl
- assert_not_nil(crl)
-
- store = mkStore(ca)
- assert( store.verify(ca.cert))
- assert( store.verify(h1, [ca.cert]))
- assert( store.verify(h2, [ca.cert]))
-
- ca.revoke(h1.serial)
-
- oldcert = File.read(Puppet.settings[:cacert])
- oldserial = File.read(Puppet.settings[:serial])
-
- # Recreate the CA from disk
- ca = mkCA()
- newcert = File.read(Puppet.settings[:cacert])
- newserial = File.read(Puppet.settings[:serial])
- assert_equal(oldcert, newcert, "The certs are not equal after making a new CA.")
- assert_equal(oldserial, newserial, "The serials are not equal after making a new CA.")
- store = mkStore(ca)
- assert( store.verify(ca.cert), "Could not verify CA certs after reloading certs.")
- assert(!store.verify(h1, [ca.cert]), "Incorrectly verified revoked cert.")
- assert( store.verify(h2, [ca.cert]), "Could not verify certs with reloaded CA.")
-
- ca.revoke(h2.serial)
- assert_equal(1, ca.crl.extensions.size)
-
- # Recreate the CA from disk
- ca = mkCA()
- store = mkStore(ca)
- assert( store.verify(ca.cert))
- assert(!store.verify(h1, [ca.cert]), "first revoked cert passed")
- assert(!store.verify(h2, [ca.cert]), "second revoked cert passed")
- end
-
- def test_ttl
- cert = mksignedcert
- assert_equal(5 * 365 * 24 * 60 * 60, cert.not_after - cert.not_before)
-
- Puppet[:ca_ttl] = 7 * 24 * 60 * 60
- cert = mksignedcert
- assert_equal(7 * 24 * 60 * 60, cert.not_after - cert.not_before)
-
- Puppet[:ca_ttl] = "2y"
- cert = mksignedcert
- assert_equal(2 * 365 * 24 * 60 * 60, cert.not_after - cert.not_before)
-
- Puppet[:ca_ttl] = "2y"
- cert = mksignedcert
- assert_equal(2 * 365 * 24 * 60 * 60, cert.not_after - cert.not_before)
-
- Puppet[:ca_ttl] = "1h"
- cert = mksignedcert
- assert_equal(60 * 60, cert.not_after - cert.not_before)
-
- Puppet[:ca_ttl] = "900s"
- cert = mksignedcert
- assert_equal(900, cert.not_after - cert.not_before)
-
- # This needs to be last, to make sure that setting ca_days
- # overrides setting ca_ttl
- Puppet[:ca_days] = 3
- cert = mksignedcert
- assert_equal(3 * 24 * 60 * 60, cert.not_after - cert.not_before)
-
- end
+ :encrypt => mkPassFile()
+ )
+
+ }
+
+ assert_nothing_raised {
+ cert.mkcsr
+ }
+
+ signedcert = nil
+ cacert = nil
+
+ assert_nothing_raised {
+ signedcert, cacert = ca.sign(cert.csr)
+ }
+
+ assert_instance_of(OpenSSL::X509::Certificate, signedcert)
+ assert_instance_of(OpenSSL::X509::Certificate, cacert)
+
+ assert_nothing_raised {
+ cert.cert = signedcert
+ cert.cacert = cacert
+ cert.write
+ }
+ #system("find #{Puppet[:ssldir]}")
+ #system("cp -R #{Puppet[:ssldir]} /tmp/ssltesting")
+
+ output = nil
+ assert_nothing_raised {
+ output = %x{openssl verify -CAfile #{Puppet[:cacert]} -purpose sslserver #{cert.certfile}}
+ #output = %x{openssl verify -CApath #{Puppet[:certdir]} -purpose sslserver #{cert.certfile}}
+ }
+
+ assert_equal($CHILD_STATUS,0)
+ assert_equal(File.join(Puppet[:certdir], "signedcertest.pem: OK\n"), output)
+ end
+
+
+ def test_interactiveca
+ ca = nil
+
+ assert_nothing_raised {
+ ca = Puppet::SSLCertificates::CA.new
+ }
+
+ # basic initialization
+ hostname = "test.hostname.com"
+ cert = mkcert(hostname)
+
+ # create the csr
+ csr = nil
+ assert_nothing_raised {
+ csr = cert.mkcsr
+ }
+
+ assert_nothing_raised {
+ ca.storeclientcsr(csr)
+ }
+
+ # store it
+ pulledcsr = nil
+ assert_nothing_raised {
+ pulledcsr = ca.getclientcsr(hostname)
+ }
+
+ assert_equal(csr.to_pem, pulledcsr.to_pem)
+
+ signedcert = nil
+ assert_nothing_raised {
+ signedcert, cacert = ca.sign(csr)
+ }
+
+ assert_instance_of(OpenSSL::X509::Certificate, signedcert)
+ newsignedcert = nil
+ assert_nothing_raised {
+ newsignedcert, cacert = ca.getclientcert(hostname)
+ }
+
+ assert(newsignedcert)
+
+ assert_equal(signedcert.to_pem, newsignedcert.to_pem)
+ end
+
+ def test_cafailures
+ ca = mkCA()
+ cert = cacert = nil
+ assert_nothing_raised {
+ cert, cacert = ca.getclientcert("nohost")
+ }
+ assert_nil(cert)
+ end
+
+ def test_crl
+ ca = mkCA()
+ h1 = mksignedcert(ca, "host1.example.com")
+ h2 = mksignedcert(ca, "host2.example.com")
+
+ assert(ca.cert.verify(ca.cert.public_key))
+ assert(h1.verify(ca.cert.public_key))
+ assert(h2.verify(ca.cert.public_key))
+
+ crl = ca.crl
+ assert_not_nil(crl)
+
+ store = mkStore(ca)
+ assert( store.verify(ca.cert))
+ assert( store.verify(h1, [ca.cert]))
+ assert( store.verify(h2, [ca.cert]))
+
+ ca.revoke(h1.serial)
+
+ oldcert = File.read(Puppet.settings[:cacert])
+ oldserial = File.read(Puppet.settings[:serial])
+
+ # Recreate the CA from disk
+ ca = mkCA()
+ newcert = File.read(Puppet.settings[:cacert])
+ newserial = File.read(Puppet.settings[:serial])
+ assert_equal(oldcert, newcert, "The certs are not equal after making a new CA.")
+ assert_equal(oldserial, newserial, "The serials are not equal after making a new CA.")
+ store = mkStore(ca)
+ assert( store.verify(ca.cert), "Could not verify CA certs after reloading certs.")
+ assert(!store.verify(h1, [ca.cert]), "Incorrectly verified revoked cert.")
+ assert( store.verify(h2, [ca.cert]), "Could not verify certs with reloaded CA.")
+
+ ca.revoke(h2.serial)
+ assert_equal(1, ca.crl.extensions.size)
+
+ # Recreate the CA from disk
+ ca = mkCA()
+ store = mkStore(ca)
+ assert( store.verify(ca.cert))
+ assert(!store.verify(h1, [ca.cert]), "first revoked cert passed")
+ assert(!store.verify(h2, [ca.cert]), "second revoked cert passed")
+ end
+
+ def test_ttl
+ cert = mksignedcert
+ assert_equal(5 * 365 * 24 * 60 * 60, cert.not_after - cert.not_before)
+
+ Puppet[:ca_ttl] = 7 * 24 * 60 * 60
+ cert = mksignedcert
+ assert_equal(7 * 24 * 60 * 60, cert.not_after - cert.not_before)
+
+ Puppet[:ca_ttl] = "2y"
+ cert = mksignedcert
+ assert_equal(2 * 365 * 24 * 60 * 60, cert.not_after - cert.not_before)
+
+ Puppet[:ca_ttl] = "2y"
+ cert = mksignedcert
+ assert_equal(2 * 365 * 24 * 60 * 60, cert.not_after - cert.not_before)
+
+ Puppet[:ca_ttl] = "1h"
+ cert = mksignedcert
+ assert_equal(60 * 60, cert.not_after - cert.not_before)
+
+ Puppet[:ca_ttl] = "900s"
+ cert = mksignedcert
+ assert_equal(900, cert.not_after - cert.not_before)
+
+ # This needs to be last, to make sure that setting ca_days
+ # overrides setting ca_ttl
+ Puppet[:ca_days] = 3
+ cert = mksignedcert
+ assert_equal(3 * 24 * 60 * 60, cert.not_after - cert.not_before)
+
+ end
end
diff --git a/test/certmgr/inventory.rb b/test/certmgr/inventory.rb
index 1b2caf2..d1ba4c8 100755
--- a/test/certmgr/inventory.rb
+++ b/test/certmgr/inventory.rb
@@ -8,62 +8,62 @@ require 'puppet/sslcertificates/inventory.rb'
require 'mocha'
class TestCertInventory < Test::Unit::TestCase
- include PuppetTest::Certificates
+ include PuppetTest::Certificates
- Inventory = Puppet::SSLCertificates::Inventory
+ Inventory = Puppet::SSLCertificates::Inventory
- def setup
- super
- Puppet::Util::SUIDManager.stubs(:asuser).yields
- end
-
- def test_format
- cert = mksignedcert
+ def setup
+ super
+ Puppet::Util::SUIDManager.stubs(:asuser).yields
+ end
- format = nil
- assert_nothing_raised do
- format = Inventory.format(cert)
- end
+ def test_format
+ cert = mksignedcert
+ format = nil
+ assert_nothing_raised do
+ format = Inventory.format(cert)
+ end
- assert(
- format =~ /^0x0001 \S+ \S+ #{cert.subject}/,
- "Did not create correct format")
- end
+ assert(
+ format =~ /^0x0001 \S+ \S+ #{cert.subject}/,
- def test_init
- # First create a couple of certificates
- ca = mkCA
+ "Did not create correct format")
+ end
- cert1 = mksignedcert(ca, "host1.madstop.com")
- cert2 = mksignedcert(ca, "host2.madstop.com")
+ def test_init
+ # First create a couple of certificates
+ ca = mkCA
- init = nil
- assert_nothing_raised do
- init = Inventory.init
- end
+ cert1 = mksignedcert(ca, "host1.madstop.com")
+ cert2 = mksignedcert(ca, "host2.madstop.com")
- [cert1, cert2].each do |cert|
- assert(init.include?(cert.subject.to_s), "Did not catch #{cert.subject}")
- end
+ init = nil
+ assert_nothing_raised do
+ init = Inventory.init
end
- def test_add
- ca = mkCA
- cert = mksignedcert(ca, "host.domain.com")
-
- assert_nothing_raised do
- file = mock
- file.expects(:puts).with do |written|
- written.include? cert.subject.to_s
- end
- Puppet::Util::Settings.any_instance.stubs(:write)
- Puppet::Util::Settings.any_instance.expects(:write).
- with(:cert_inventory, 'a').yields(file)
-
- Puppet::SSLCertificates::Inventory.add(cert)
- end
+ [cert1, cert2].each do |cert|
+ assert(init.include?(cert.subject.to_s), "Did not catch #{cert.subject}")
+ end
+ end
+
+ def test_add
+ ca = mkCA
+ cert = mksignedcert(ca, "host.domain.com")
+
+ assert_nothing_raised do
+ file = mock
+ file.expects(:puts).with do |written|
+ written.include? cert.subject.to_s
+ end
+ Puppet::Util::Settings.any_instance.stubs(:write)
+ Puppet::Util::Settings.any_instance.expects(:write).
+ with(:cert_inventory, 'a').yields(file)
+
+ Puppet::SSLCertificates::Inventory.add(cert)
end
+ end
end
diff --git a/test/certmgr/support.rb b/test/certmgr/support.rb
index c241fab..3138c94 100755
--- a/test/certmgr/support.rb
+++ b/test/certmgr/support.rb
@@ -7,98 +7,98 @@ require 'puppet/sslcertificates/support'
require 'mocha'
class TestCertSupport < Test::Unit::TestCase
- include PuppetTest
- MissingCertificate = Puppet::SSLCertificates::Support::MissingCertificate
-
- class CertUser
- include Puppet::SSLCertificates::Support
+ include PuppetTest
+ MissingCertificate = Puppet::SSLCertificates::Support::MissingCertificate
+
+ class CertUser
+ include Puppet::SSLCertificates::Support
+ end
+
+ def setup
+ super
+ Puppet::Util::SUIDManager.stubs(:asuser).yields
+ @user = CertUser.new
+ @ca = Puppet::SSLCertificates::CA.new
+ @client = Puppet::Network::Client.ca.new(:CA => @ca)
+ end
+
+ # Yay, metaprogramming
+ def test_keytype
+ [:key, :csr, :cert, :ca_cert].each do |name|
+ assert(Puppet::SSLCertificates::Support.method_defined?(name), "No retrieval method for #{name}")
+ maker = "mk_#{name}"
+ assert(Puppet::SSLCertificates::Support.method_defined?(maker), "No maker method for #{name}")
end
+ end
- def setup
- super
- Puppet::Util::SUIDManager.stubs(:asuser).yields
- @user = CertUser.new
- @ca = Puppet::SSLCertificates::CA.new
- @client = Puppet::Network::Client.ca.new(:CA => @ca)
- end
+ def test_keys
+ keys = [:hostprivkey, :hostpubkey].each { |n| Puppet[n] = tempfile }
- # Yay, metaprogramming
- def test_keytype
- [:key, :csr, :cert, :ca_cert].each do |name|
- assert(Puppet::SSLCertificates::Support.method_defined?(name), "No retrieval method for #{name}")
- maker = "mk_#{name}"
- assert(Puppet::SSLCertificates::Support.method_defined?(maker), "No maker method for #{name}")
- end
+ key = nil
+ assert_nothing_raised do
+ key = @user.key
end
- def test_keys
- keys = [:hostprivkey, :hostpubkey].each { |n| Puppet[n] = tempfile }
-
- key = nil
- assert_nothing_raised do
- key = @user.key
- end
+ assert_logged(:info, /Creating a new SSL/, "Did not log about new key")
+ keys.each do |file|
- assert_logged(:info, /Creating a new SSL/, "Did not log about new key")
- keys.each do |file|
-
- assert(
- FileTest.exists?(Puppet[file]),
+ assert(
+ FileTest.exists?(Puppet[file]),
- "Did not create #{file} key file")
- end
-
- # Make sure it's a valid key
- assert_nothing_raised("Created key is invalid") do
- OpenSSL::PKey::RSA.new(File.read(Puppet[:hostprivkey]))
- end
+ "Did not create #{file} key file")
+ end
- # now make sure we can read it in
- other = CertUser.new
- assert_nothing_raised("Could not read key in") do
- other.key
- end
+ # Make sure it's a valid key
+ assert_nothing_raised("Created key is invalid") do
+ OpenSSL::PKey::RSA.new(File.read(Puppet[:hostprivkey]))
+ end
- assert_equal(@user.key.to_s, other.key.to_s, "Keys are not equal")
+ # now make sure we can read it in
+ other = CertUser.new
+ assert_nothing_raised("Could not read key in") do
+ other.key
end
- def test_csr
- csr = nil
- assert_nothing_raised("Could not create csr") do
- csr = @user.csr
- end
+ assert_equal(@user.key.to_s, other.key.to_s, "Keys are not equal")
+ end
- assert(FileTest.exists?(Puppet[:hostcsr]), "did not create csr file")
- assert_instance_of(OpenSSL::X509::Request, csr)
+ def test_csr
+ csr = nil
+ assert_nothing_raised("Could not create csr") do
+ csr = @user.csr
end
- def test_cacert
- @user = CertUser.new
+ assert(FileTest.exists?(Puppet[:hostcsr]), "did not create csr file")
+ assert_instance_of(OpenSSL::X509::Request, csr)
+ end
- assert_raise(MissingCertificate, "Did not fail when missing cacert") do
- @user.ca_cert
- end
- end
+ def test_cacert
+ @user = CertUser.new
- # Fixing #1382. This test will always fail on Darwin, because its
- # FS is case-insensitive.
- unless Facter.value(:operatingsystem) == "Darwin"
- def test_uppercase_files_are_renamed_and_read
- # Write a key out to disk in a file containing upper-case.
- key = OpenSSL::PKey::RSA.new(32)
- should_path = Puppet[:hostprivkey]
-
- dir, file = File.split(should_path)
- newfile = file.sub(/^([a-z.]+)\./) { $1.upcase + "."}
- upper_path = File.join(dir, newfile)
- File.open(upper_path, "w") { |f| f.print key.to_s }
-
- user = CertUser.new
-
- assert_equal(key.to_s, user.read_key.to_s, "Did not read key in from disk")
- assert(! FileTest.exist?(upper_path), "Upper case file was not removed")
- assert(FileTest.exist?(should_path), "File was not renamed to lower-case file")
- assert_equal(key.to_s, user.read_key.to_s, "Did not read key in from disk")
- end
+ assert_raise(MissingCertificate, "Did not fail when missing cacert") do
+ @user.ca_cert
+ end
+ end
+
+ # Fixing #1382. This test will always fail on Darwin, because its
+ # FS is case-insensitive.
+ unless Facter.value(:operatingsystem) == "Darwin"
+ def test_uppercase_files_are_renamed_and_read
+ # Write a key out to disk in a file containing upper-case.
+ key = OpenSSL::PKey::RSA.new(32)
+ should_path = Puppet[:hostprivkey]
+
+ dir, file = File.split(should_path)
+ newfile = file.sub(/^([a-z.]+)\./) { $1.upcase + "."}
+ upper_path = File.join(dir, newfile)
+ File.open(upper_path, "w") { |f| f.print key.to_s }
+
+ user = CertUser.new
+
+ assert_equal(key.to_s, user.read_key.to_s, "Did not read key in from disk")
+ assert(! FileTest.exist?(upper_path), "Upper case file was not removed")
+ assert(FileTest.exist?(should_path), "File was not renamed to lower-case file")
+ assert_equal(key.to_s, user.read_key.to_s, "Did not read key in from disk")
end
+ end
end
diff --git a/test/language/ast.rb b/test/language/ast.rb
index d11c87f..10b9fa3 100755
--- a/test/language/ast.rb
+++ b/test/language/ast.rb
@@ -8,83 +8,83 @@ require 'puppettest/resourcetesting'
require 'puppettest/parsertesting'
class TestAST < Test::Unit::TestCase
- include PuppetTest::ParserTesting
- include PuppetTest::ResourceTesting
-
- def test_if
- scope = mkscope
- astif = nil
- astelse = nil
- fakeelse = FakeAST.new(:else)
- faketest = FakeAST.new(true)
- fakeif = FakeAST.new(:if)
-
- assert_nothing_raised {
- astelse = AST::Else.new(:statements => fakeelse)
- }
- assert_nothing_raised {
-
- astif = AST::IfStatement.new(
+ include PuppetTest::ParserTesting
+ include PuppetTest::ResourceTesting
+
+ def test_if
+ scope = mkscope
+ astif = nil
+ astelse = nil
+ fakeelse = FakeAST.new(:else)
+ faketest = FakeAST.new(true)
+ fakeif = FakeAST.new(:if)
+
+ assert_nothing_raised {
+ astelse = AST::Else.new(:statements => fakeelse)
+ }
+ assert_nothing_raised {
+
+ astif = AST::IfStatement.new(
- :test => faketest,
- :statements => fakeif,
+ :test => faketest,
+ :statements => fakeif,
- :else => astelse
- )
- }
-
- # We initialized it to true, so we should get that first
- ret = nil
- assert_nothing_raised {
- ret = astif.evaluate(scope)
- }
- assert_equal(:if, ret)
-
- # Now set it to false and check that
- faketest.evaluate = false
- assert_nothing_raised {
- ret = astif.evaluate(scope)
- }
- assert_equal(:else, ret)
+ :else => astelse
+ )
+ }
+
+ # We initialized it to true, so we should get that first
+ ret = nil
+ assert_nothing_raised {
+ ret = astif.evaluate(scope)
+ }
+ assert_equal(:if, ret)
+
+ # Now set it to false and check that
+ faketest.evaluate = false
+ assert_nothing_raised {
+ ret = astif.evaluate(scope)
+ }
+ assert_equal(:else, ret)
+ end
+
+ # Make sure our override object behaves "correctly"
+ def test_override
+ scope = mkscope
+
+ ref = nil
+ assert_nothing_raised do
+ ref = resourceoverride("file", "/yayness", "owner" => "blah", "group" => "boo")
end
- # Make sure our override object behaves "correctly"
- def test_override
- scope = mkscope
+ scope.compiler.expects(:add_override).with { |res| res.is_a?(Puppet::Parser::Resource) }
+ ret = nil
+ assert_nothing_raised do
+ ret = ref.evaluate scope
+ end
- ref = nil
- assert_nothing_raised do
- ref = resourceoverride("file", "/yayness", "owner" => "blah", "group" => "boo")
- end
+ assert_instance_of(Puppet::Parser::Resource, ret, "Did not return override")
+ end
- scope.compiler.expects(:add_override).with { |res| res.is_a?(Puppet::Parser::Resource) }
- ret = nil
- assert_nothing_raised do
- ret = ref.evaluate scope
- end
+ def test_collection
+ scope = mkscope
- assert_instance_of(Puppet::Parser::Resource, ret, "Did not return override")
+ coll = nil
+ assert_nothing_raised do
+ coll = AST::Collection.new(:type => "file", :form => :virtual)
end
- def test_collection
- scope = mkscope
-
- coll = nil
- assert_nothing_raised do
- coll = AST::Collection.new(:type => "file", :form => :virtual)
- end
-
- assert_instance_of(AST::Collection, coll)
+ assert_instance_of(AST::Collection, coll)
- ret = nil
- assert_nothing_raised do
- ret = coll.evaluate scope
- end
+ ret = nil
+ assert_nothing_raised do
+ ret = coll.evaluate scope
+ end
- assert_instance_of(Puppet::Parser::Collector, ret)
+ assert_instance_of(Puppet::Parser::Collector, ret)
- # Now make sure we get it back from the scope
- colls = scope.compiler.instance_variable_get("@collections")
- assert_equal([ret], colls, "Did not store collector in config's collection list")
- end
+ # Now make sure we get it back from the scope
+ colls = scope.compiler.instance_variable_get("@collections")
+ assert_equal([ret], colls, "Did not store collector in config's collection list")
+ end
end
diff --git a/test/language/ast/variable.rb b/test/language/ast/variable.rb
index 6a8b028..8a7738b 100755
--- a/test/language/ast/variable.rb
+++ b/test/language/ast/variable.rb
@@ -9,21 +9,21 @@ require 'puppettest'
require 'puppettest/parsertesting'
class TestVariable < Test::Unit::TestCase
- include PuppetTest
- include PuppetTest::ParserTesting
- AST = Puppet::Parser::AST
+ include PuppetTest
+ include PuppetTest::ParserTesting
+ AST = Puppet::Parser::AST
- def setup
- super
- @scope = mkscope
- @name = "myvar"
- @var = AST::Variable.new(:value => @name)
- end
+ def setup
+ super
+ @scope = mkscope
+ @name = "myvar"
+ @var = AST::Variable.new(:value => @name)
+ end
- def test_evaluate
- assert_equal(:undef, @var.evaluate(@scope), "did not return :undef on unset var")
- @scope.setvar(@name, "something")
- assert_equal("something", @var.evaluate(@scope), "incorrect variable value")
- end
+ def test_evaluate
+ assert_equal(:undef, @var.evaluate(@scope), "did not return :undef on unset var")
+ @scope.setvar(@name, "something")
+ assert_equal("something", @var.evaluate(@scope), "incorrect variable value")
+ end
end
diff --git a/test/language/functions.rb b/test/language/functions.rb
index eedcd35..1d4ed82 100755
--- a/test/language/functions.rb
+++ b/test/language/functions.rb
@@ -9,535 +9,535 @@ require 'puppettest'
require 'puppettest/resourcetesting'
class TestLangFunctions < Test::Unit::TestCase
- include PuppetTest::ParserTesting
- include PuppetTest::ResourceTesting
- def test_functions
- Puppet::Node::Environment.stubs(:current).returns nil
- assert_nothing_raised do
+ include PuppetTest::ParserTesting
+ include PuppetTest::ResourceTesting
+ def test_functions
+ Puppet::Node::Environment.stubs(:current).returns nil
+ assert_nothing_raised do
- Puppet::Parser::AST::Function.new(
+ Puppet::Parser::AST::Function.new(
- :name => "fakefunction",
+ :name => "fakefunction",
- :arguments => AST::ASTArray.new(
- :children => [nameobj("avalue")]
- )
- )
- end
-
- assert_raise(Puppet::ParseError) do
-
- func = Puppet::Parser::AST::Function.new(
-
- :name => "fakefunction",
-
- :arguments => AST::ASTArray.new(
- :children => [nameobj("avalue")]
- )
- )
- func.evaluate(mkscope)
- end
-
- assert_nothing_raised do
- Puppet::Parser::Functions.newfunction(:fakefunction, :type => :rvalue) do |input|
- return "output #{input[0]}"
- end
- end
-
- func = nil
- assert_nothing_raised do
+ :arguments => AST::ASTArray.new(
+ :children => [nameobj("avalue")]
+ )
+ )
+ end
- func = Puppet::Parser::AST::Function.new(
+ assert_raise(Puppet::ParseError) do
- :name => "fakefunction",
- :ftype => :rvalue,
+ func = Puppet::Parser::AST::Function.new(
- :arguments => AST::ASTArray.new(
- :children => [nameobj("avalue")]
- )
- )
- end
+ :name => "fakefunction",
- scope = mkscope
- val = nil
- assert_nothing_raised do
- val = func.evaluate(scope)
- end
+ :arguments => AST::ASTArray.new(
+ :children => [nameobj("avalue")]
+ )
+ )
+ func.evaluate(mkscope)
+ end
- assert_equal("output avalue", val)
+ assert_nothing_raised do
+ Puppet::Parser::Functions.newfunction(:fakefunction, :type => :rvalue) do |input|
+ return "output #{input[0]}"
+ end
end
- def test_taggedfunction
- scope = mkscope
- scope.resource.tag("yayness")
+ func = nil
+ assert_nothing_raised do
- # Make sure the ast stuff does what it's supposed to
- {"yayness" => true, "booness" => false}.each do |tag, retval|
- func = taggedobj(tag, :rvalue)
+ func = Puppet::Parser::AST::Function.new(
- val = nil
- assert_nothing_raised do
- val = func.evaluate(scope)
- end
+ :name => "fakefunction",
+ :ftype => :rvalue,
- assert_equal(retval, val, "'tagged' returned #{val} for #{tag}")
- end
+ :arguments => AST::ASTArray.new(
+ :children => [nameobj("avalue")]
+ )
+ )
+ end
- # Now make sure we correctly get tags.
- scope.resource.tag("resourcetag")
- assert(scope.function_tagged("resourcetag"), "tagged function did not catch resource tags")
- scope.compiler.catalog.tag("configtag")
- assert(scope.function_tagged("configtag"), "tagged function did not catch catalog tags")
+ scope = mkscope
+ val = nil
+ assert_nothing_raised do
+ val = func.evaluate(scope)
end
- def test_failfunction
- func = nil
- assert_nothing_raised do
+ assert_equal("output avalue", val)
+ end
- func = Puppet::Parser::AST::Function.new(
+ def test_taggedfunction
+ scope = mkscope
+ scope.resource.tag("yayness")
- :name => "fail",
- :ftype => :statement,
+ # Make sure the ast stuff does what it's supposed to
+ {"yayness" => true, "booness" => false}.each do |tag, retval|
+ func = taggedobj(tag, :rvalue)
- :arguments => AST::ASTArray.new(
- :children => [stringobj("this is a failure"), stringobj("and another")]
- )
- )
- end
+ val = nil
+ assert_nothing_raised do
+ val = func.evaluate(scope)
+ end
- scope = mkscope
- val = nil
- assert_raise(Puppet::ParseError) do
- val = func.evaluate(scope)
- end
+ assert_equal(retval, val, "'tagged' returned #{val} for #{tag}")
end
- def test_multipletemplates
- Dir.mkdir(Puppet[:templatedir])
- onep = File.join(Puppet[:templatedir], "one")
- twop = File.join(Puppet[:templatedir], "two")
+ # Now make sure we correctly get tags.
+ scope.resource.tag("resourcetag")
+ assert(scope.function_tagged("resourcetag"), "tagged function did not catch resource tags")
+ scope.compiler.catalog.tag("configtag")
+ assert(scope.function_tagged("configtag"), "tagged function did not catch catalog tags")
+ end
- File.open(onep, "w") do |f|
- f.puts "<%- if @one.nil? then raise '@one undefined' end -%>template <%= @one %>"
- end
+ def test_failfunction
+ func = nil
+ assert_nothing_raised do
- File.open(twop, "w") do |f|
- f.puts "template <%= @two %>"
- end
- func = nil
- assert_nothing_raised do
+ func = Puppet::Parser::AST::Function.new(
- func = Puppet::Parser::AST::Function.new(
+ :name => "fail",
+ :ftype => :statement,
- :name => "template",
- :ftype => :rvalue,
+ :arguments => AST::ASTArray.new(
+ :children => [stringobj("this is a failure"), stringobj("and another")]
+ )
+ )
+ end
- :arguments => AST::ASTArray.new(
- :children => [stringobj("one"), stringobj("two")]
- )
- )
- end
- ast = varobj("output", func)
+ scope = mkscope
+ val = nil
+ assert_raise(Puppet::ParseError) do
+ val = func.evaluate(scope)
+ end
+ end
- scope = mkscope
+ def test_multipletemplates
+ Dir.mkdir(Puppet[:templatedir])
+ onep = File.join(Puppet[:templatedir], "one")
+ twop = File.join(Puppet[:templatedir], "two")
- # Test that our manual exception throw fails the parse
- assert_raise(Puppet::ParseError) do
- ast.evaluate(scope)
- end
+ File.open(onep, "w") do |f|
+ f.puts "<%- if @one.nil? then raise '@one undefined' end -%>template <%= @one %>"
+ end
- # Test that our use of an undefined instance variable does not throw
- # an exception, but only safely continues.
- scope.setvar("one", "One")
- assert_nothing_raised do
- ast.evaluate(scope)
- end
+ File.open(twop, "w") do |f|
+ f.puts "template <%= @two %>"
+ end
+ func = nil
+ assert_nothing_raised do
- # Ensure that we got the output we expected from that evaluation.
- assert_equal("template One\ntemplate \n", scope.lookupvar("output"), "Undefined template variables do not raise exceptions")
+ func = Puppet::Parser::AST::Function.new(
- # Now, fill in the last variable and make sure the whole thing
- # evaluates correctly.
- scope.setvar("two", "Two")
- scope.unsetvar("output")
- assert_nothing_raised do
- ast.evaluate(scope)
- end
+ :name => "template",
+ :ftype => :rvalue,
+ :arguments => AST::ASTArray.new(
+ :children => [stringobj("one"), stringobj("two")]
+ )
+ )
+ end
+ ast = varobj("output", func)
- assert_equal(
- "template One\ntemplate Two\n", scope.lookupvar("output"),
+ scope = mkscope
- "Templates were not handled correctly")
+ # Test that our manual exception throw fails the parse
+ assert_raise(Puppet::ParseError) do
+ ast.evaluate(scope)
end
- # Now make sure we can fully qualify files, and specify just one
- def test_singletemplates
- template = tempfile
-
- File.open(template, "w") do |f|
- f.puts "template <%= @yay.nil?() ? raise('yay undefined') : @yay %>"
- end
+ # Test that our use of an undefined instance variable does not throw
+ # an exception, but only safely continues.
+ scope.setvar("one", "One")
+ assert_nothing_raised do
+ ast.evaluate(scope)
+ end
- func = nil
- assert_nothing_raised do
+ # Ensure that we got the output we expected from that evaluation.
+ assert_equal("template One\ntemplate \n", scope.lookupvar("output"), "Undefined template variables do not raise exceptions")
- func = Puppet::Parser::AST::Function.new(
+ # Now, fill in the last variable and make sure the whole thing
+ # evaluates correctly.
+ scope.setvar("two", "Two")
+ scope.unsetvar("output")
+ assert_nothing_raised do
+ ast.evaluate(scope)
+ end
- :name => "template",
- :ftype => :rvalue,
- :arguments => AST::ASTArray.new(
- :children => [stringobj(template)]
- )
- )
- end
- ast = varobj("output", func)
+ assert_equal(
+ "template One\ntemplate Two\n", scope.lookupvar("output"),
- scope = mkscope
- assert_raise(Puppet::ParseError) do
- ast.evaluate(scope)
- end
+ "Templates were not handled correctly")
+ end
- scope.setvar("yay", "this is yay")
+ # Now make sure we can fully qualify files, and specify just one
+ def test_singletemplates
+ template = tempfile
- assert_nothing_raised do
- ast.evaluate(scope)
- end
+ File.open(template, "w") do |f|
+ f.puts "template <%= @yay.nil?() ? raise('yay undefined') : @yay %>"
+ end
+ func = nil
+ assert_nothing_raised do
- assert_equal(
- "template this is yay\n", scope.lookupvar("output"),
+ func = Puppet::Parser::AST::Function.new(
- "Templates were not handled correctly")
+ :name => "template",
+ :ftype => :rvalue,
+ :arguments => AST::ASTArray.new(
+ :children => [stringobj(template)]
+ )
+ )
end
+ ast = varobj("output", func)
- # Make sure that legacy template variable access works as expected.
- def test_legacyvariables
- template = tempfile
-
- File.open(template, "w") do |f|
- f.puts "template <%= deprecated %>"
- end
-
- func = nil
- assert_nothing_raised do
+ scope = mkscope
+ assert_raise(Puppet::ParseError) do
+ ast.evaluate(scope)
+ end
- func = Puppet::Parser::AST::Function.new(
+ scope.setvar("yay", "this is yay")
- :name => "template",
- :ftype => :rvalue,
+ assert_nothing_raised do
+ ast.evaluate(scope)
+ end
- :arguments => AST::ASTArray.new(
- :children => [stringobj(template)]
- )
- )
- end
- ast = varobj("output", func)
- # Verify that we get an exception using old-style accessors.
- scope = mkscope
- assert_raise(Puppet::ParseError) do
- ast.evaluate(scope)
- end
+ assert_equal(
+ "template this is yay\n", scope.lookupvar("output"),
- # Verify that we evaluate and return their value correctly.
- scope.setvar("deprecated", "deprecated value")
- assert_nothing_raised do
- ast.evaluate(scope)
- end
+ "Templates were not handled correctly")
+ end
- assert_equal(
- "template deprecated value\n", scope.lookupvar("output"),
+ # Make sure that legacy template variable access works as expected.
+ def test_legacyvariables
+ template = tempfile
- "Deprecated template variables were not handled correctly")
+ File.open(template, "w") do |f|
+ f.puts "template <%= deprecated %>"
end
- # Make sure that problems with kernel method visibility still exist.
- def test_kernel_module_shadows_deprecated_var_lookup
- template = tempfile
- File.open(template, "w").puts("<%= binding %>")
+ func = nil
+ assert_nothing_raised do
- func = nil
- assert_nothing_raised do
+ func = Puppet::Parser::AST::Function.new(
- func = Puppet::Parser::AST::Function.new(
+ :name => "template",
+ :ftype => :rvalue,
- :name => "template",
- :ftype => :rvalue,
+ :arguments => AST::ASTArray.new(
+ :children => [stringobj(template)]
+ )
+ )
+ end
+ ast = varobj("output", func)
- :arguments => AST::ASTArray.new(
- :children => [stringobj(template)]
- )
- )
- end
- ast = varobj("output", func)
+ # Verify that we get an exception using old-style accessors.
+ scope = mkscope
+ assert_raise(Puppet::ParseError) do
+ ast.evaluate(scope)
+ end
- # Verify that Kernel methods still shadow deprecated variable lookups.
- scope = mkscope
- assert_nothing_raised("No exception for Kernel shadowed variable names") do
- ast.evaluate(scope)
- end
+ # Verify that we evaluate and return their value correctly.
+ scope.setvar("deprecated", "deprecated value")
+ assert_nothing_raised do
+ ast.evaluate(scope)
end
- def test_tempatefunction_cannot_see_scopes
- template = tempfile
- File.open(template, "w") do |f|
- f.puts "<%= lookupvar('myvar') %>"
- end
+ assert_equal(
+ "template deprecated value\n", scope.lookupvar("output"),
- func = nil
- assert_nothing_raised do
+ "Deprecated template variables were not handled correctly")
+ end
- func = Puppet::Parser::AST::Function.new(
+ # Make sure that problems with kernel method visibility still exist.
+ def test_kernel_module_shadows_deprecated_var_lookup
+ template = tempfile
+ File.open(template, "w").puts("<%= binding %>")
- :name => "template",
- :ftype => :rvalue,
+ func = nil
+ assert_nothing_raised do
- :arguments => AST::ASTArray.new(
- :children => [stringobj(template)]
- )
- )
- end
- ast = varobj("output", func)
+ func = Puppet::Parser::AST::Function.new(
- scope = mkscope
- scope.setvar("myvar", "this is yayness")
- assert_raise(Puppet::ParseError) do
- ast.evaluate(scope)
- end
- end
+ :name => "template",
+ :ftype => :rvalue,
- def test_template_reparses
- template = tempfile
+ :arguments => AST::ASTArray.new(
+ :children => [stringobj(template)]
+ )
+ )
+ end
+ ast = varobj("output", func)
- File.open(template, "w") do |f|
- f.puts "original text"
- end
+ # Verify that Kernel methods still shadow deprecated variable lookups.
+ scope = mkscope
+ assert_nothing_raised("No exception for Kernel shadowed variable names") do
+ ast.evaluate(scope)
+ end
+ end
- file = tempfile
+ def test_tempatefunction_cannot_see_scopes
+ template = tempfile
- Puppet[:code] = %{file { "#{file}": content => template("#{template}") }}
- Puppet[:environment] = "yay"
- node = mknode
- node.stubs(:environment).returns Puppet::Node::Environment.new
+ File.open(template, "w") do |f|
+ f.puts "<%= lookupvar('myvar') %>"
+ end
- Puppet[:environment] = "yay"
+ func = nil
+ assert_nothing_raised do
- catalog = Puppet::Parser::Compiler.new(node).compile
+ func = Puppet::Parser::AST::Function.new(
- version = catalog.version
+ :name => "template",
+ :ftype => :rvalue,
- fileobj = catalog.vertices.find { |r| r.title == file }
- assert(fileobj, "File was not in catalog")
+ :arguments => AST::ASTArray.new(
+ :children => [stringobj(template)]
+ )
+ )
+ end
+ ast = varobj("output", func)
+ scope = mkscope
+ scope.setvar("myvar", "this is yayness")
+ assert_raise(Puppet::ParseError) do
+ ast.evaluate(scope)
+ end
+ end
- assert_equal(
- "original text\n", fileobj["content"],
+ def test_template_reparses
+ template = tempfile
- "Template did not work")
+ File.open(template, "w") do |f|
+ f.puts "original text"
+ end
- Puppet[:filetimeout] = -5
- # Have to sleep because one second is the fs's time granularity.
- sleep(1)
+ file = tempfile
- # Now modify the template
- File.open(template, "w") do |f|
- f.puts "new text"
- end
+ Puppet[:code] = %{file { "#{file}": content => template("#{template}") }}
+ Puppet[:environment] = "yay"
+ node = mknode
+ node.stubs(:environment).returns Puppet::Node::Environment.new
- newversion = Puppet::Parser::Compiler.new(node).compile.version
+ Puppet[:environment] = "yay"
- assert(version != newversion, "Parse date did not change")
- end
+ catalog = Puppet::Parser::Compiler.new(node).compile
- def test_template_defined_vars
- template = tempfile
+ version = catalog.version
- File.open(template, "w") do |f|
- f.puts "template <%= @yayness %>"
- end
+ fileobj = catalog.vertices.find { |r| r.title == file }
+ assert(fileobj, "File was not in catalog")
- func = nil
- assert_nothing_raised do
- func = Puppet::Parser::AST::Function.new(
+ assert_equal(
+ "original text\n", fileobj["content"],
- :name => "template",
- :ftype => :rvalue,
+ "Template did not work")
- :arguments => AST::ASTArray.new(
- :children => [stringobj(template)]
- )
- )
- end
- ast = varobj("output", func)
+ Puppet[:filetimeout] = -5
+ # Have to sleep because one second is the fs's time granularity.
+ sleep(1)
- {
- "" => "",
- false => "false",
- }.each do |string, value|
- scope = mkscope
- scope.setvar("yayness", string)
- assert_equal(string, scope.lookupvar("yayness", false))
+ # Now modify the template
+ File.open(template, "w") do |f|
+ f.puts "new text"
+ end
- assert_nothing_raised("An empty string was not a valid variable value") do
- ast.evaluate(scope)
- end
+ newversion = Puppet::Parser::Compiler.new(node).compile.version
+ assert(version != newversion, "Parse date did not change")
+ end
- assert_equal(
- "template #{value}\n", scope.lookupvar("output"),
+ def test_template_defined_vars
+ template = tempfile
- "#{string.inspect} did not get evaluated correctly")
- end
+ File.open(template, "w") do |f|
+ f.puts "template <%= @yayness %>"
end
- def test_autoloading_functions
- #assert_equal(false, Puppet::Parser::Functions.function(:autofunc),
- # "Got told autofunc already exists")
+ func = nil
+ assert_nothing_raised do
- dir = tempfile
- $LOAD_PATH << dir
- newpath = File.join(dir, "puppet", "parser", "functions")
- FileUtils.mkdir_p(newpath)
+ func = Puppet::Parser::AST::Function.new(
- File.open(File.join(newpath, "autofunc.rb"), "w") { |f|
- f.puts %{
- Puppet::Parser::Functions.newfunction(:autofunc, :type => :rvalue) do |vals|
- Puppet.wanring vals.inspect
- end
- }
- }
- Puppet::Node::Environment.stubs(:current).returns nil
- obj = nil
- assert_nothing_raised {
- obj = Puppet::Parser::Functions.function(:autofunc)
- }
+ :name => "template",
+ :ftype => :rvalue,
- assert(obj, "Did not autoload function")
- assert(Puppet::Parser::Functions.environment_module.method_defined?(:function_autofunc), "Did not set function correctly")
+ :arguments => AST::ASTArray.new(
+ :children => [stringobj(template)]
+ )
+ )
end
+ ast = varobj("output", func)
- def test_search
- scope = mkscope
+ {
+ "" => "",
+ false => "false",
+ }.each do |string, value|
+ scope = mkscope
+ scope.setvar("yayness", string)
+ assert_equal(string, scope.lookupvar("yayness", false))
- fun = scope.known_resource_types.add Puppet::Resource::Type.new(:definition, "yay::ness")
- foo = scope.known_resource_types.add Puppet::Resource::Type.new(:definition, "foo::bar")
+ assert_nothing_raised("An empty string was not a valid variable value") do
+ ast.evaluate(scope)
+ end
- search = Puppet::Parser::Functions.function(:search)
- scope.function_search(["foo", "yay"])
- ffun = ffoo = nil
- assert_nothing_raised("Search path change did not work") do
- ffun = scope.find_definition("ness")
- ffoo = scope.find_definition('bar')
- end
+ assert_equal(
+ "template #{value}\n", scope.lookupvar("output"),
- assert(ffun, "Could not find definition in 'fun' namespace")
- assert(ffoo, "Could not find definition in 'foo' namespace")
+ "#{string.inspect} did not get evaluated correctly")
+ end
+ end
+
+ def test_autoloading_functions
+ #assert_equal(false, Puppet::Parser::Functions.function(:autofunc),
+ # "Got told autofunc already exists")
+
+ dir = tempfile
+ $LOAD_PATH << dir
+ newpath = File.join(dir, "puppet", "parser", "functions")
+ FileUtils.mkdir_p(newpath)
+
+ File.open(File.join(newpath, "autofunc.rb"), "w") { |f|
+ f.puts %{
+ Puppet::Parser::Functions.newfunction(:autofunc, :type => :rvalue) do |vals|
+ Puppet.wanring vals.inspect
+ end
+ }
+ }
+ Puppet::Node::Environment.stubs(:current).returns nil
+ obj = nil
+ assert_nothing_raised {
+ obj = Puppet::Parser::Functions.function(:autofunc)
+ }
+
+ assert(obj, "Did not autoload function")
+ assert(Puppet::Parser::Functions.environment_module.method_defined?(:function_autofunc), "Did not set function correctly")
+ end
+
+ def test_search
+ scope = mkscope
+
+ fun = scope.known_resource_types.add Puppet::Resource::Type.new(:definition, "yay::ness")
+ foo = scope.known_resource_types.add Puppet::Resource::Type.new(:definition, "foo::bar")
+
+ search = Puppet::Parser::Functions.function(:search)
+ scope.function_search(["foo", "yay"])
+
+ ffun = ffoo = nil
+ assert_nothing_raised("Search path change did not work") do
+ ffun = scope.find_definition("ness")
+ ffoo = scope.find_definition('bar')
end
- def test_include
- scope = mkscope
- parser = mkparser
+ assert(ffun, "Could not find definition in 'fun' namespace")
+ assert(ffoo, "Could not find definition in 'foo' namespace")
+ end
- include = Puppet::Parser::Functions.function(:include)
+ def test_include
+ scope = mkscope
+ parser = mkparser
- assert_raise(Puppet::ParseError, "did not throw error on missing class") do
- scope.function_include("nosuchclass")
- end
+ include = Puppet::Parser::Functions.function(:include)
+
+ assert_raise(Puppet::ParseError, "did not throw error on missing class") do
+ scope.function_include("nosuchclass")
+ end
- parser.newclass("myclass")
+ parser.newclass("myclass")
- scope.compiler.expects(:evaluate_classes).with(%w{myclass otherclass}, scope, false).returns(%w{myclass otherclass})
+ scope.compiler.expects(:evaluate_classes).with(%w{myclass otherclass}, scope, false).returns(%w{myclass otherclass})
- assert_nothing_raised do
- scope.function_include(["myclass", "otherclass"])
- end
+ assert_nothing_raised do
+ scope.function_include(["myclass", "otherclass"])
end
+ end
- def test_file
- parser = mkparser
- scope = mkscope(:parser => parser)
+ def test_file
+ parser = mkparser
+ scope = mkscope(:parser => parser)
- file = Puppet::Parser::Functions.function(:file)
+ file = Puppet::Parser::Functions.function(:file)
- file1 = tempfile
- file2 = tempfile
- file3 = tempfile
+ file1 = tempfile
+ file2 = tempfile
+ file3 = tempfile
- File.open(file2, "w") { |f| f.puts "yaytest" }
+ File.open(file2, "w") { |f| f.puts "yaytest" }
- val = nil
- assert_nothing_raised("Failed to call file with one arg") do
- val = scope.function_file([file2])
- end
+ val = nil
+ assert_nothing_raised("Failed to call file with one arg") do
+ val = scope.function_file([file2])
+ end
- assert_equal("yaytest\n", val, "file() failed")
+ assert_equal("yaytest\n", val, "file() failed")
- assert_nothing_raised("Failed to call file with two args") do
- val = scope.function_file([file1, file2])
- end
+ assert_nothing_raised("Failed to call file with two args") do
+ val = scope.function_file([file1, file2])
+ end
- assert_equal("yaytest\n", val, "file() failed")
+ assert_equal("yaytest\n", val, "file() failed")
- assert_raise(Puppet::ParseError, "did not fail when files are missing") do
- val = scope.function_file([file1, file3])
- end
+ assert_raise(Puppet::ParseError, "did not fail when files are missing") do
+ val = scope.function_file([file1, file3])
end
+ end
+
+ def test_generate
+ command = tempfile
+ sh = %x{which sh}
+ File.open(command, "w") do |f|
+ f.puts %{#!#{sh}
+ if [ -n "$1" ]; then
+ echo "yay-$1"
+ else
+ echo yay
+ fi
+ }
+ end
+ File.chmod(0755, command)
+ assert_equal("yay\n", %x{#{command}}, "command did not work")
+ assert_equal("yay-foo\n", %x{#{command} foo}, "command did not work")
- def test_generate
- command = tempfile
- sh = %x{which sh}
- File.open(command, "w") do |f|
- f.puts %{#!#{sh}
- if [ -n "$1" ]; then
- echo "yay-$1"
- else
- echo yay
- fi
- }
- end
- File.chmod(0755, command)
- assert_equal("yay\n", %x{#{command}}, "command did not work")
- assert_equal("yay-foo\n", %x{#{command} foo}, "command did not work")
-
- Puppet::Node::Environment.stubs(:current).returns nil
- generate = Puppet::Parser::Functions.function(:generate)
+ Puppet::Node::Environment.stubs(:current).returns nil
+ generate = Puppet::Parser::Functions.function(:generate)
- scope = mkscope
- parser = mkparser
+ scope = mkscope
+ parser = mkparser
- val = nil
- assert_nothing_raised("Could not call generator with no args") do
- val = scope.function_generate([command])
- end
- assert_equal("yay\n", val, "generator returned wrong results")
+ val = nil
+ assert_nothing_raised("Could not call generator with no args") do
+ val = scope.function_generate([command])
+ end
+ assert_equal("yay\n", val, "generator returned wrong results")
- assert_nothing_raised("Could not call generator with args") do
- val = scope.function_generate([command, "foo"])
- end
- assert_equal("yay-foo\n", val, "generator returned wrong results")
+ assert_nothing_raised("Could not call generator with args") do
+ val = scope.function_generate([command, "foo"])
+ end
+ assert_equal("yay-foo\n", val, "generator returned wrong results")
- assert_raise(Puppet::ParseError, "Did not fail with an unqualified path") do
- val = scope.function_generate([File.basename(command), "foo"])
- end
+ assert_raise(Puppet::ParseError, "Did not fail with an unqualified path") do
+ val = scope.function_generate([File.basename(command), "foo"])
+ end
- assert_raise(Puppet::ParseError, "Did not fail when command failed") do
- val = scope.function_generate([%x{which touch}.chomp, "/this/dir/does/not/exist"])
- end
+ assert_raise(Puppet::ParseError, "Did not fail when command failed") do
+ val = scope.function_generate([%x{which touch}.chomp, "/this/dir/does/not/exist"])
+ end
- fake = File.join(File.dirname(command), "..")
- dir = File.dirname(command)
- dirname = File.basename(dir)
- bad = File.join(dir, "..", dirname, File.basename(command))
- assert_raise(Puppet::ParseError, "Did not fail when command failed") do
- val = scope.function_generate([bad])
- end
+ fake = File.join(File.dirname(command), "..")
+ dir = File.dirname(command)
+ dirname = File.basename(dir)
+ bad = File.join(dir, "..", dirname, File.basename(command))
+ assert_raise(Puppet::ParseError, "Did not fail when command failed") do
+ val = scope.function_generate([bad])
end
+ end
end
diff --git a/test/language/parser.rb b/test/language/parser.rb
index 7082763..5a433c7 100755
--- a/test/language/parser.rb
+++ b/test/language/parser.rb
@@ -9,738 +9,738 @@ require 'puppettest'
require 'puppettest/support/utils'
class TestParser < Test::Unit::TestCase
- include PuppetTest
- include PuppetTest::ParserTesting
- include PuppetTest::Support::Utils
- def setup
- super
- Puppet[:parseonly] = true
- #@lexer = Puppet::Parser::Lexer.new
- end
-
- def teardown
- super
- Puppet::Node::Environment.clear
- end
-
- def test_each_file
- textfiles { |file|
- Puppet::Node::Environment.clear
- parser = mkparser
- Puppet.debug("parsing #{file}") if __FILE__ == $0
- assert_nothing_raised {
- parser.file = file
- parser.parse
- }
- }
- end
-
- def test_failers
- failers { |file|
- parser = mkparser
- Puppet.debug("parsing failer #{file}") if __FILE__ == $0
- assert_raise(Puppet::ParseError, "Did not fail while parsing #{file}") {
- parser.file = file
- ast = parser.parse
- config = mkcompiler(parser)
- config.compile
- #ast.hostclass("").evaluate config.topscope
- }
- }
- end
-
- def test_arrayrvalues
- parser = mkparser
- ret = nil
- file = tempfile
- assert_nothing_raised {
- parser.string = "file { \"#{file}\": mode => [755, 640] }"
- }
-
- assert_nothing_raised {
- ret = parser.parse
- }
- end
-
- def test_arrayrvalueswithtrailingcomma
- parser = mkparser
- ret = nil
- file = tempfile
- assert_nothing_raised {
- parser.string = "file { \"#{file}\": mode => [755, 640,] }"
- }
-
- assert_nothing_raised {
- ret = parser.parse
- }
- end
-
- def mkmanifest(file)
- name = File.join(tmpdir, "file#{rand(100)}")
- @@tmpfiles << name
-
- File.open(file, "w") { |f|
- f.puts "file { \"%s\": ensure => file, mode => 755 }\n" % name
- }
- end
-
- def test_importglobbing
- basedir = File.join(tmpdir, "importesting")
- @@tmpfiles << basedir
- Dir.mkdir(basedir)
-
- subdir = "subdir"
- Dir.mkdir(File.join(basedir, subdir))
- manifest = File.join(basedir, "manifest")
- File.open(manifest, "w") { |f|
- f.puts "import \"%s/*\"" % subdir
- }
-
- 4.times { |i|
- path = File.join(basedir, subdir, "subfile#{i}")
- mkmanifest(path)
- }
-
- assert_nothing_raised("Could not parse multiple files") {
- parser = mkparser
- parser.file = manifest
- parser.parse
- }
- end
-
- def test_nonexistent_import
- basedir = File.join(tmpdir, "importesting")
- @@tmpfiles << basedir
- Dir.mkdir(basedir)
- manifest = File.join(basedir, "manifest")
- File.open(manifest, "w") do |f|
- f.puts "import \" no such file \""
- end
- assert_raise(Puppet::ParseError) {
- parser = mkparser
- parser.file = manifest
- parser.parse
- }
- end
-
- def test_trailingcomma
- path = tempfile
- str = %{file { "#{path}": ensure => file, }
- }
-
- parser = mkparser
- parser.string = str
-
- assert_nothing_raised("Could not parse trailing comma") {
- parser.parse
- }
- end
-
- def test_importedclasses
- imported = tempfile
- importer = tempfile
-
- made = tempfile
+ include PuppetTest
+ include PuppetTest::ParserTesting
+ include PuppetTest::Support::Utils
+ def setup
+ super
+ Puppet[:parseonly] = true
+ #@lexer = Puppet::Parser::Lexer.new
+ end
+
+ def teardown
+ super
+ Puppet::Node::Environment.clear
+ end
+
+ def test_each_file
+ textfiles { |file|
+ Puppet::Node::Environment.clear
+ parser = mkparser
+ Puppet.debug("parsing #{file}") if __FILE__ == $0
+ assert_nothing_raised {
+ parser.file = file
+ parser.parse
+ }
+ }
+ end
+
+ def test_failers
+ failers { |file|
+ parser = mkparser
+ Puppet.debug("parsing failer #{file}") if __FILE__ == $0
+ assert_raise(Puppet::ParseError, "Did not fail while parsing #{file}") {
+ parser.file = file
+ ast = parser.parse
+ config = mkcompiler(parser)
+ config.compile
+ #ast.hostclass("").evaluate config.topscope
+ }
+ }
+ end
+
+ def test_arrayrvalues
+ parser = mkparser
+ ret = nil
+ file = tempfile
+ assert_nothing_raised {
+ parser.string = "file { \"#{file}\": mode => [755, 640] }"
+ }
+
+ assert_nothing_raised {
+ ret = parser.parse
+ }
+ end
+
+ def test_arrayrvalueswithtrailingcomma
+ parser = mkparser
+ ret = nil
+ file = tempfile
+ assert_nothing_raised {
+ parser.string = "file { \"#{file}\": mode => [755, 640,] }"
+ }
+
+ assert_nothing_raised {
+ ret = parser.parse
+ }
+ end
+
+ def mkmanifest(file)
+ name = File.join(tmpdir, "file#{rand(100)}")
+ @@tmpfiles << name
+
+ File.open(file, "w") { |f|
+ f.puts "file { \"%s\": ensure => file, mode => 755 }\n" % name
+ }
+ end
+
+ def test_importglobbing
+ basedir = File.join(tmpdir, "importesting")
+ @@tmpfiles << basedir
+ Dir.mkdir(basedir)
+
+ subdir = "subdir"
+ Dir.mkdir(File.join(basedir, subdir))
+ manifest = File.join(basedir, "manifest")
+ File.open(manifest, "w") { |f|
+ f.puts "import \"%s/*\"" % subdir
+ }
+
+ 4.times { |i|
+ path = File.join(basedir, subdir, "subfile#{i}")
+ mkmanifest(path)
+ }
+
+ assert_nothing_raised("Could not parse multiple files") {
+ parser = mkparser
+ parser.file = manifest
+ parser.parse
+ }
+ end
+
+ def test_nonexistent_import
+ basedir = File.join(tmpdir, "importesting")
+ @@tmpfiles << basedir
+ Dir.mkdir(basedir)
+ manifest = File.join(basedir, "manifest")
+ File.open(manifest, "w") do |f|
+ f.puts "import \" no such file \""
+ end
+ assert_raise(Puppet::ParseError) {
+ parser = mkparser
+ parser.file = manifest
+ parser.parse
+ }
+ end
- File.open(imported, "w") do |f|
- f.puts %{class foo { file { "#{made}": ensure => file }}}
- end
+ def test_trailingcomma
+ path = tempfile
+ str = %{file { "#{path}": ensure => file, }
+ }
- File.open(importer, "w") do |f|
- f.puts %{import "#{imported}"\ninclude foo}
- end
+ parser = mkparser
+ parser.string = str
- parser = mkparser
- parser.file = importer
+ assert_nothing_raised("Could not parse trailing comma") {
+ parser.parse
+ }
+ end
+
+ def test_importedclasses
+ imported = tempfile
+ importer = tempfile
+
+ made = tempfile
+
+ File.open(imported, "w") do |f|
+ f.puts %{class foo { file { "#{made}": ensure => file }}}
+ end
- # Make sure it parses fine
- assert_nothing_raised {
- parser.parse
- }
-
- # Now make sure it actually does the work
- assert_creates(importer, made)
+ File.open(importer, "w") do |f|
+ f.puts %{import "#{imported}"\ninclude foo}
end
- # Make sure fully qualified and unqualified files can be imported
- def test_fqfilesandlocalfiles
- dir = tempfile
- Dir.mkdir(dir)
- importer = File.join(dir, "site.pp")
- fullfile = File.join(dir, "full.pp")
- localfile = File.join(dir, "local.pp")
-
- files = []
-
- File.open(importer, "w") do |f|
- f.puts %{import "#{fullfile}"\ninclude full\nimport "local.pp"\ninclude local}
- end
-
- fullmaker = tempfile
- files << fullmaker
-
- File.open(fullfile, "w") do |f|
- f.puts %{class full { file { "#{fullmaker}": ensure => file }}}
- end
+ parser = mkparser
+ parser.file = importer
- localmaker = tempfile
- files << localmaker
+ # Make sure it parses fine
+ assert_nothing_raised {
+ parser.parse
+ }
- File.open(localfile, "w") do |f|
- f.puts %{class local { file { "#{localmaker}": ensure => file }}}
- end
+ # Now make sure it actually does the work
+ assert_creates(importer, made)
+ end
- parser = mkparser
- parser.file = importer
+ # Make sure fully qualified and unqualified files can be imported
+ def test_fqfilesandlocalfiles
+ dir = tempfile
+ Dir.mkdir(dir)
+ importer = File.join(dir, "site.pp")
+ fullfile = File.join(dir, "full.pp")
+ localfile = File.join(dir, "local.pp")
- # Make sure it parses
- assert_nothing_raised {
- parser.parse
- }
+ files = []
- # Now make sure it actually does the work
- assert_creates(importer, *files)
+ File.open(importer, "w") do |f|
+ f.puts %{import "#{fullfile}"\ninclude full\nimport "local.pp"\ninclude local}
end
- # Make sure the parser adds '.pp' when necessary
- def test_addingpp
- dir = tempfile
- Dir.mkdir(dir)
- importer = File.join(dir, "site.pp")
- localfile = File.join(dir, "local.pp")
-
- files = []
-
- File.open(importer, "w") do |f|
- f.puts %{import "local"\ninclude local}
- end
+ fullmaker = tempfile
+ files << fullmaker
- file = tempfile
- files << file
-
- File.open(localfile, "w") do |f|
- f.puts %{class local { file { "#{file}": ensure => file }}}
- end
-
- parser = mkparser
- parser.file = importer
-
- assert_nothing_raised {
- parser.parse
- }
+ File.open(fullfile, "w") do |f|
+ f.puts %{class full { file { "#{fullmaker}": ensure => file }}}
end
- # Make sure that file importing changes file relative names.
- def test_changingrelativenames
- dir = tempfile
- Dir.mkdir(dir)
- Dir.mkdir(File.join(dir, "subdir"))
- top = File.join(dir, "site.pp")
- subone = File.join(dir, "subdir/subone")
- subtwo = File.join(dir, "subdir/subtwo")
-
- files = []
- file = tempfile
- files << file
-
- File.open(subone + ".pp", "w") do |f|
- f.puts %{class one { file { "#{file}": ensure => file }}}
- end
-
- otherfile = tempfile
- files << otherfile
- File.open(subtwo + ".pp", "w") do |f|
- f.puts %{import "subone"\n class two inherits one {
- file { "#{otherfile}": ensure => file }
- }}
- end
-
- File.open(top, "w") do |f|
- f.puts %{import "subdir/subtwo"}
- end
-
- parser = mkparser
- parser.file = top
+ localmaker = tempfile
+ files << localmaker
- assert_nothing_raised {
- parser.parse
- }
+ File.open(localfile, "w") do |f|
+ f.puts %{class local { file { "#{localmaker}": ensure => file }}}
end
- # Defaults are purely syntactical, so it doesn't make sense to be able to
- # collect them.
- def test_uncollectabledefaults
- string = "@Port { protocols => tcp }"
+ parser = mkparser
+ parser.file = importer
- assert_raise(Puppet::ParseError) {
- mkparser.parse(string)
- }
- end
+ # Make sure it parses
+ assert_nothing_raised {
+ parser.parse
+ }
- # Verify that we can parse collections
- def test_collecting
- text = "Port <| |>"
- parser = mkparser
- parser.string = text
+ # Now make sure it actually does the work
+ assert_creates(importer, *files)
+ end
- ret = nil
- assert_nothing_raised {
- ret = parser.parse
- }
+ # Make sure the parser adds '.pp' when necessary
+ def test_addingpp
+ dir = tempfile
+ Dir.mkdir(dir)
+ importer = File.join(dir, "site.pp")
+ localfile = File.join(dir, "local.pp")
- ret.hostclass("").code.each do |obj|
- assert_instance_of(AST::Collection, obj)
- end
- end
+ files = []
- def test_emptyfile
- file = tempfile
- File.open(file, "w") do |f|
- f.puts %{}
- end
- parser = mkparser
- parser.file = file
- assert_nothing_raised {
- parser.parse
- }
+ File.open(importer, "w") do |f|
+ f.puts %{import "local"\ninclude local}
end
- def test_multiple_nodes_named
- file = tempfile
- other = tempfile
-
- File.open(file, "w") do |f|
- f.puts %{
-node nodeA, nodeB {
- file { "#{other}": ensure => file }
-
-}
-}
- end
+ file = tempfile
+ files << file
- parser = mkparser
- parser.file = file
- ast = nil
- assert_nothing_raised {
- ast = parser.parse
- }
+ File.open(localfile, "w") do |f|
+ f.puts %{class local { file { "#{file}": ensure => file }}}
end
- def test_emptyarrays
- str = %{$var = []\n}
+ parser = mkparser
+ parser.file = importer
- parser = mkparser
- parser.string = str
-
- # Make sure it parses fine
- assert_nothing_raised {
- parser.parse
- }
- end
+ assert_nothing_raised {
+ parser.parse
+ }
+ end
- # Make sure function names aren't reserved words.
- def test_functionnamecollision
- str = %{tag yayness
-tag(rahness)
+ # Make sure that file importing changes file relative names.
+ def test_changingrelativenames
+ dir = tempfile
+ Dir.mkdir(dir)
+ Dir.mkdir(File.join(dir, "subdir"))
+ top = File.join(dir, "site.pp")
+ subone = File.join(dir, "subdir/subone")
+ subtwo = File.join(dir, "subdir/subtwo")
-file { "/tmp/yayness":
- tag => "rahness",
- ensure => exists
-}
-}
- parser = mkparser
- parser.string = str
+ files = []
+ file = tempfile
+ files << file
- # Make sure it parses fine
- assert_nothing_raised {
- parser.parse
- }
+ File.open(subone + ".pp", "w") do |f|
+ f.puts %{class one { file { "#{file}": ensure => file }}}
end
- def test_metaparams_in_definition_prototypes
- parser = mkparser
-
-
- assert_raise(Puppet::ParseError) {
- parser.parse %{define mydef($schedule) {}}
- }
-
- assert_nothing_raised {
- parser.parse %{define adef($schedule = false) {}}
- parser.parse %{define mydef($schedule = daily) {}}
- }
+ otherfile = tempfile
+ files << otherfile
+ File.open(subtwo + ".pp", "w") do |f|
+ f.puts %{import "subone"\n class two inherits one {
+ file { "#{otherfile}": ensure => file }
+ }}
end
- def test_parsingif
- parser = mkparser
- exec = proc do |val|
- %{exec { "/bin/echo #{val}": logoutput => true }}
- end
- str1 = %{if true { #{exec.call("true")} }}
- ret = nil
- assert_nothing_raised {
- ret = parser.parse(str1).hostclass("").code[0]
- }
- assert_instance_of(Puppet::Parser::AST::IfStatement, ret)
- parser = mkparser
- str2 = %{if true { #{exec.call("true")} } else { #{exec.call("false")} }}
- ret = parser.parse(str2).hostclass("").code[0]
- assert_instance_of(Puppet::Parser::AST::IfStatement, ret)
- assert_instance_of(Puppet::Parser::AST::Else, ret.else)
- end
-
- def test_hostclass
- parser = mkparser
-
- assert_nothing_raised {
- parser.parse %{class myclass { class other {} }}
- }
- assert(parser.hostclass("myclass"), "Could not find myclass")
- assert(parser.hostclass("myclass::other"), "Could not find myclass::other")
-
- assert_nothing_raised {
- parser.parse "class base {}
- class container {
- class deep::sub inherits base {}
- }"
- }
- sub = parser.hostclass("container::deep::sub")
- assert(sub, "Could not find sub")
-
- # Now try it with a parent class being a fq class
- assert_nothing_raised {
- parser.parse "class container::one inherits container::deep::sub {}"
- }
- sub = parser.hostclass("container::one")
- assert(sub, "Could not find one")
- assert_equal("container::deep::sub", sub.parent)
-
- # Finally, try including a qualified class
- assert_nothing_raised("Could not include fully qualified class") {
- parser.parse "include container::deep::sub"
- }
- end
-
- def test_topnamespace
- parser = mkparser
-
- # Make sure we put the top-level code into a class called "" in
- # the "" namespace
- assert_nothing_raised do
- out = parser.parse ""
-
- assert_instance_of(Puppet::Resource::TypeCollection, out)
- assert_nil(parser.hostclass(""), "Got a 'main' class when we had no code")
- end
-
- # Now try something a touch more complicated
- parser.initvars
- assert_nothing_raised do
- out = parser.parse "Exec { path => '/usr/bin:/usr/sbin' }"
- assert_instance_of(Puppet::Resource::TypeCollection, out)
- assert_equal("", parser.hostclass("").name)
- assert_equal("", parser.hostclass("").namespace)
- end
+ File.open(top, "w") do |f|
+ f.puts %{import "subdir/subtwo"}
end
- # Make sure virtual and exported resources work appropriately.
- def test_virtualresources
- tests = [:virtual]
- if Puppet.features.rails?
- catalog_cache_class = Puppet::Resource::Catalog.indirection.cache_class
- facts_cache_class = Puppet::Node::Facts.indirection.cache_class
- node_cache_class = Puppet::Node.indirection.cache_class
- Puppet[:storeconfigs] = true
- tests << :exported
- end
-
- tests.each do |form|
- parser = mkparser
-
- if form == :virtual
- at = "@"
- else
- at = "@@"
- end
-
- check = proc do |res, msg|
- if res.is_a?(Puppet::Parser::Resource)
- txt = res.ref
- else
- txt = res.class
- end
- # Real resources get marked virtual when exported
- if form == :virtual or res.is_a?(Puppet::Parser::Resource)
- assert(res.virtual, "#{msg} #{at}#{txt} is not virtual")
- end
- if form == :virtual
- assert(! res.exported, "#{msg} #{at}#{txt} is exported")
- else
- assert(res.exported, "#{msg} #{at}#{txt} is not exported")
- end
- end
-
- ret = nil
- assert_nothing_raised do
- ret = parser.parse("#{at}file { '/tmp/testing': owner => root }")
- end
-
- assert_instance_of(AST::ASTArray, ret.hostclass("").code)
- resdef = ret.hostclass("").code[0]
- assert_instance_of(AST::Resource, resdef)
- assert_equal("/tmp/testing", resdef.title.value)
- # We always get an astarray back, so...
- check.call(resdef, "simple resource")
-
- # Now let's try it with multiple resources in the same spec
- assert_nothing_raised do
- ret = parser.parse("#{at}file { ['/tmp/1', '/tmp/2']: owner => root }")
- end
-
- ret.hostclass("").code.each do |res|
- assert_instance_of(AST::Resource, res)
- check.call(res, "multiresource")
- end
- end
-
- ensure
- if Puppet.features.rails?
- Puppet[:storeconfigs] = false
- Puppet::Resource::Catalog.cache_class = catalog_cache_class
- Puppet::Node::Facts.cache_class = facts_cache_class
- Puppet::Node.cache_class = node_cache_class
- end
- end
-
- def test_collections
- tests = [:virtual]
- if Puppet.features.rails?
- catalog_cache_class = Puppet::Resource::Catalog.indirection.cache_class
- facts_cache_class = Puppet::Node::Facts.indirection.cache_class
- node_cache_class = Puppet::Node.indirection.cache_class
- Puppet[:storeconfigs] = true
- tests << :exported
- end
-
- tests.each do |form|
- Puppet::Node::Environment.clear
- parser = mkparser
-
- if form == :virtual
- arrow = "<||>"
- else
- arrow = "<<||>>"
- end
-
- ret = nil
- assert_nothing_raised do
- ret = parser.parse("File #{arrow}")
- end
-
- coll = ret.hostclass("").code[0]
- assert_instance_of(AST::Collection, coll)
- assert_equal(form, coll.form)
- end
-
- ensure
- if Puppet.features.rails?
- Puppet[:storeconfigs] = false
- Puppet::Resource::Catalog.cache_class = catalog_cache_class
- Puppet::Node::Facts.cache_class = facts_cache_class
- Puppet::Node.cache_class = node_cache_class
- end
- end
+ parser = mkparser
+ parser.file = top
- def test_collectionexpressions
- %w{== !=}.each do |oper|
- Puppet::Node::Environment.clear
- str = "File <| title #{oper} '/tmp/testing' |>"
+ assert_nothing_raised {
+ parser.parse
+ }
+ end
- parser = mkparser
+ # Defaults are purely syntactical, so it doesn't make sense to be able to
+ # collect them.
+ def test_uncollectabledefaults
+ string = "@Port { protocols => tcp }"
- res = nil
- assert_nothing_raised do
- res = parser.parse(str).hostclass("").code[0]
- end
+ assert_raise(Puppet::ParseError) {
+ mkparser.parse(string)
+ }
+ end
- assert_instance_of(AST::Collection, res)
+ # Verify that we can parse collections
+ def test_collecting
+ text = "Port <| |>"
+ parser = mkparser
+ parser.string = text
- query = res.query
- assert_instance_of(AST::CollExpr, query)
+ ret = nil
+ assert_nothing_raised {
+ ret = parser.parse
+ }
- assert_equal(:virtual, query.form)
- assert_equal("title", query.test1.value)
- assert_equal("/tmp/testing", query.test2.value)
- assert_equal(oper, query.oper)
- end
+ ret.hostclass("").code.each do |obj|
+ assert_instance_of(AST::Collection, obj)
end
+ end
- def test_collectionstatements
- %w{and or}.each do |joiner|
- str = "File <| title == '/tmp/testing' #{joiner} owner == root |>"
-
- parser = mkparser
-
- res = nil
- assert_nothing_raised do
- res = parser.parse(str).hostclass("").code[0]
- end
-
- assert_instance_of(AST::Collection, res)
-
- query = res.query
- assert_instance_of(AST::CollExpr, query)
-
- assert_equal(joiner, query.oper)
- assert_instance_of(AST::CollExpr, query.test1)
- assert_instance_of(AST::CollExpr, query.test2)
- end
- end
-
- def test_collectionstatements_with_parens
- [
- "(title == '/tmp/testing' and owner == root) or owner == wheel",
- "(title == '/tmp/testing')"
- ].each do |test|
- str = "File <| #{test} |>"
- parser = mkparser
-
- res = nil
- assert_nothing_raised("Could not parse '#{test}'") do
- res = parser.parse(str).hostclass("").code[0]
- end
-
- assert_instance_of(AST::Collection, res)
-
- query = res.query
- assert_instance_of(AST::CollExpr, query)
-
- #assert_equal(joiner, query.oper)
- #assert_instance_of(AST::CollExpr, query.test1)
- #assert_instance_of(AST::CollExpr, query.test2)
- end
+ def test_emptyfile
+ file = tempfile
+ File.open(file, "w") do |f|
+ f.puts %{}
end
+ parser = mkparser
+ parser.file = file
+ assert_nothing_raised {
+ parser.parse
+ }
+ end
- def test_fully_qualified_definitions
- parser = mkparser
+ def test_multiple_nodes_named
+ file = tempfile
+ other = tempfile
- assert_nothing_raised("Could not parse fully-qualified definition") {
- parser.parse %{define one::two { }}
- }
- assert(parser.definition("one::two"), "Could not find one::two with no namespace")
-
- # Now try using the definition
- assert_nothing_raised("Could not parse fully-qualified definition usage") {
- parser.parse %{one::two { yayness: }}
- }
- end
-
- # #524
- def test_functions_with_no_arguments
- parser = mkparser
- assert_nothing_raised("Could not parse statement function with no args") {
- parser.parse %{tag()}
- }
- assert_nothing_raised("Could not parse rvalue function with no args") {
- parser.parse %{$testing = template()}
- }
- end
-
- # #774
- def test_fully_qualified_collection_statement
- parser = mkparser
- assert_nothing_raised("Could not parse fully qualified collection statement") {
- parser.parse %{Foo::Bar <||>}
- }
- end
-
- def test_multiple_imports_on_one_line
- one = tempfile
- two = tempfile
- base = tempfile
- File.open(one, "w") { |f| f.puts "$var = value" }
- File.open(two, "w") { |f| f.puts "$var = value" }
- File.open(base, "w") { |f| f.puts "import '#{one}', '#{two}'" }
-
- parser = mkparser
- parser.file = base
-
- # Importing is logged at debug time.
- Puppet::Util::Log.level = :debug
- assert_nothing_raised("Parser could not import multiple files at once") do
- parser.parse
- end
-
- [one, two].each do |file|
- assert(@logs.detect { |l| l.message =~ /importing '#{file}'/}, "did not import #{file}")
- end
- end
+ File.open(file, "w") do |f|
+ f.puts %{
+node nodeA, nodeB {
+ file { "#{other}": ensure => file }
- def test_cannot_assign_qualified_variables
- parser = mkparser
- assert_raise(Puppet::ParseError, "successfully assigned a qualified variable") do
- parser.parse("$one::two = yay")
- end
+}
+}
end
- # #629 - undef keyword
- def test_undef
- parser = mkparser
- result = nil
- assert_nothing_raised("Could not parse assignment to undef") {
- result = parser.parse %{$variable = undef}
- }
+ parser = mkparser
+ parser.file = file
+ ast = nil
+ assert_nothing_raised {
+ ast = parser.parse
+ }
+ end
- main = result.hostclass("").code
- children = main.children
- assert_instance_of(AST::VarDef, main.children[0])
- assert_instance_of(AST::Undef, main.children[0].value)
- end
+ def test_emptyarrays
+ str = %{$var = []\n}
- # Prompted by #729 -- parsing should not modify the interpreter.
- def test_parse
- parser = mkparser
+ parser = mkparser
+ parser.string = str
- str = "file { '/tmp/yay': ensure => file }\nclass yay {}\nnode foo {}\ndefine bar {}\n"
- result = nil
- assert_nothing_raised("Could not parse") do
- result = parser.parse(str)
- end
- assert_instance_of(Puppet::Resource::TypeCollection, result, "Did not get a ASTSet back from parsing")
+ # Make sure it parses fine
+ assert_nothing_raised {
+ parser.parse
+ }
+ end
- assert_instance_of(Puppet::Resource::Type, result.hostclass("yay"), "Did not create 'yay' class")
- assert_instance_of(Puppet::Resource::Type, result.hostclass(""), "Did not create main class")
- assert_instance_of(Puppet::Resource::Type, result.definition("bar"), "Did not create 'bar' definition")
- assert_instance_of(Puppet::Resource::Type, result.node("foo"), "Did not create 'foo' node")
- end
-
- def test_namesplit
- parser = mkparser
+ # Make sure function names aren't reserved words.
+ def test_functionnamecollision
+ str = %{tag yayness
+tag(rahness)
- assert_nothing_raised do
- {"base::sub" => %w{base sub},
- "main" => ["", "main"],
- "one::two::three::four" => ["one::two::three", "four"],
- }.each do |name, ary|
- result = parser.namesplit(name)
- assert_equal(ary, result, "#{name} split to #{result}")
- end
- end
+file { "/tmp/yayness":
+ tag => "rahness",
+ ensure => exists
+}
+}
+ parser = mkparser
+ parser.string = str
+
+ # Make sure it parses fine
+ assert_nothing_raised {
+ parser.parse
+ }
+ end
+
+ def test_metaparams_in_definition_prototypes
+ parser = mkparser
+
+
+ assert_raise(Puppet::ParseError) {
+ parser.parse %{define mydef($schedule) {}}
+ }
+
+ assert_nothing_raised {
+ parser.parse %{define adef($schedule = false) {}}
+ parser.parse %{define mydef($schedule = daily) {}}
+ }
+ end
+
+ def test_parsingif
+ parser = mkparser
+ exec = proc do |val|
+ %{exec { "/bin/echo #{val}": logoutput => true }}
+ end
+ str1 = %{if true { #{exec.call("true")} }}
+ ret = nil
+ assert_nothing_raised {
+ ret = parser.parse(str1).hostclass("").code[0]
+ }
+ assert_instance_of(Puppet::Parser::AST::IfStatement, ret)
+ parser = mkparser
+ str2 = %{if true { #{exec.call("true")} } else { #{exec.call("false")} }}
+ ret = parser.parse(str2).hostclass("").code[0]
+ assert_instance_of(Puppet::Parser::AST::IfStatement, ret)
+ assert_instance_of(Puppet::Parser::AST::Else, ret.else)
+ end
+
+ def test_hostclass
+ parser = mkparser
+
+ assert_nothing_raised {
+ parser.parse %{class myclass { class other {} }}
+ }
+ assert(parser.hostclass("myclass"), "Could not find myclass")
+ assert(parser.hostclass("myclass::other"), "Could not find myclass::other")
+
+ assert_nothing_raised {
+ parser.parse "class base {}
+ class container {
+ class deep::sub inherits base {}
+ }"
+ }
+ sub = parser.hostclass("container::deep::sub")
+ assert(sub, "Could not find sub")
+
+ # Now try it with a parent class being a fq class
+ assert_nothing_raised {
+ parser.parse "class container::one inherits container::deep::sub {}"
+ }
+ sub = parser.hostclass("container::one")
+ assert(sub, "Could not find one")
+ assert_equal("container::deep::sub", sub.parent)
+
+ # Finally, try including a qualified class
+ assert_nothing_raised("Could not include fully qualified class") {
+ parser.parse "include container::deep::sub"
+ }
+ end
+
+ def test_topnamespace
+ parser = mkparser
+
+ # Make sure we put the top-level code into a class called "" in
+ # the "" namespace
+ assert_nothing_raised do
+ out = parser.parse ""
+
+ assert_instance_of(Puppet::Resource::TypeCollection, out)
+ assert_nil(parser.hostclass(""), "Got a 'main' class when we had no code")
+ end
+
+ # Now try something a touch more complicated
+ parser.initvars
+ assert_nothing_raised do
+ out = parser.parse "Exec { path => '/usr/bin:/usr/sbin' }"
+ assert_instance_of(Puppet::Resource::TypeCollection, out)
+ assert_equal("", parser.hostclass("").name)
+ assert_equal("", parser.hostclass("").namespace)
+ end
+ end
+
+ # Make sure virtual and exported resources work appropriately.
+ def test_virtualresources
+ tests = [:virtual]
+ if Puppet.features.rails?
+ catalog_cache_class = Puppet::Resource::Catalog.indirection.cache_class
+ facts_cache_class = Puppet::Node::Facts.indirection.cache_class
+ node_cache_class = Puppet::Node.indirection.cache_class
+ Puppet[:storeconfigs] = true
+ tests << :exported
+ end
+
+ tests.each do |form|
+ parser = mkparser
+
+ if form == :virtual
+ at = "@"
+ else
+ at = "@@"
+ end
+
+ check = proc do |res, msg|
+ if res.is_a?(Puppet::Parser::Resource)
+ txt = res.ref
+ else
+ txt = res.class
+ end
+ # Real resources get marked virtual when exported
+ if form == :virtual or res.is_a?(Puppet::Parser::Resource)
+ assert(res.virtual, "#{msg} #{at}#{txt} is not virtual")
+ end
+ if form == :virtual
+ assert(! res.exported, "#{msg} #{at}#{txt} is exported")
+ else
+ assert(res.exported, "#{msg} #{at}#{txt} is not exported")
+ end
+ end
+
+ ret = nil
+ assert_nothing_raised do
+ ret = parser.parse("#{at}file { '/tmp/testing': owner => root }")
+ end
+
+ assert_instance_of(AST::ASTArray, ret.hostclass("").code)
+ resdef = ret.hostclass("").code[0]
+ assert_instance_of(AST::Resource, resdef)
+ assert_equal("/tmp/testing", resdef.title.value)
+ # We always get an astarray back, so...
+ check.call(resdef, "simple resource")
+
+ # Now let's try it with multiple resources in the same spec
+ assert_nothing_raised do
+ ret = parser.parse("#{at}file { ['/tmp/1', '/tmp/2']: owner => root }")
+ end
+
+ ret.hostclass("").code.each do |res|
+ assert_instance_of(AST::Resource, res)
+ check.call(res, "multiresource")
+ end
+ end
+
+ ensure
+ if Puppet.features.rails?
+ Puppet[:storeconfigs] = false
+ Puppet::Resource::Catalog.cache_class = catalog_cache_class
+ Puppet::Node::Facts.cache_class = facts_cache_class
+ Puppet::Node.cache_class = node_cache_class
+ end
+ end
+
+ def test_collections
+ tests = [:virtual]
+ if Puppet.features.rails?
+ catalog_cache_class = Puppet::Resource::Catalog.indirection.cache_class
+ facts_cache_class = Puppet::Node::Facts.indirection.cache_class
+ node_cache_class = Puppet::Node.indirection.cache_class
+ Puppet[:storeconfigs] = true
+ tests << :exported
end
- # Make sure class, node, and define methods are case-insensitive
- def test_structure_case_insensitivity
- parser = mkparser
+ tests.each do |form|
+ Puppet::Node::Environment.clear
+ parser = mkparser
- result = nil
- assert_nothing_raised do
- result = parser.newclass "Yayness"
- end
- assert_equal(result, parser.find_hostclass("", "yayNess"))
+ if form == :virtual
+ arrow = "<||>"
+ else
+ arrow = "<<||>>"
+ end
- assert_nothing_raised do
- result = parser.newdefine "FunTest"
- end
- assert_equal(result, parser.find_definition("", "fUntEst"), "#{"fUntEst"} was not matched")
- end
+ ret = nil
+ assert_nothing_raised do
+ ret = parser.parse("File #{arrow}")
+ end
+
+ coll = ret.hostclass("").code[0]
+ assert_instance_of(AST::Collection, coll)
+ assert_equal(form, coll.form)
+ end
+
+ ensure
+ if Puppet.features.rails?
+ Puppet[:storeconfigs] = false
+ Puppet::Resource::Catalog.cache_class = catalog_cache_class
+ Puppet::Node::Facts.cache_class = facts_cache_class
+ Puppet::Node.cache_class = node_cache_class
+ end
+ end
+
+ def test_collectionexpressions
+ %w{== !=}.each do |oper|
+ Puppet::Node::Environment.clear
+ str = "File <| title #{oper} '/tmp/testing' |>"
+
+ parser = mkparser
+
+ res = nil
+ assert_nothing_raised do
+ res = parser.parse(str).hostclass("").code[0]
+ end
+
+ assert_instance_of(AST::Collection, res)
+
+ query = res.query
+ assert_instance_of(AST::CollExpr, query)
+
+ assert_equal(:virtual, query.form)
+ assert_equal("title", query.test1.value)
+ assert_equal("/tmp/testing", query.test2.value)
+ assert_equal(oper, query.oper)
+ end
+ end
+
+ def test_collectionstatements
+ %w{and or}.each do |joiner|
+ str = "File <| title == '/tmp/testing' #{joiner} owner == root |>"
+
+ parser = mkparser
+
+ res = nil
+ assert_nothing_raised do
+ res = parser.parse(str).hostclass("").code[0]
+ end
+
+ assert_instance_of(AST::Collection, res)
+
+ query = res.query
+ assert_instance_of(AST::CollExpr, query)
+
+ assert_equal(joiner, query.oper)
+ assert_instance_of(AST::CollExpr, query.test1)
+ assert_instance_of(AST::CollExpr, query.test2)
+ end
+ end
+
+ def test_collectionstatements_with_parens
+ [
+ "(title == '/tmp/testing' and owner == root) or owner == wheel",
+ "(title == '/tmp/testing')"
+ ].each do |test|
+ str = "File <| #{test} |>"
+ parser = mkparser
+
+ res = nil
+ assert_nothing_raised("Could not parse '#{test}'") do
+ res = parser.parse(str).hostclass("").code[0]
+ end
+
+ assert_instance_of(AST::Collection, res)
+
+ query = res.query
+ assert_instance_of(AST::CollExpr, query)
+
+ #assert_equal(joiner, query.oper)
+ #assert_instance_of(AST::CollExpr, query.test1)
+ #assert_instance_of(AST::CollExpr, query.test2)
+ end
+ end
+
+ def test_fully_qualified_definitions
+ parser = mkparser
+
+ assert_nothing_raised("Could not parse fully-qualified definition") {
+ parser.parse %{define one::two { }}
+ }
+ assert(parser.definition("one::two"), "Could not find one::two with no namespace")
+
+ # Now try using the definition
+ assert_nothing_raised("Could not parse fully-qualified definition usage") {
+ parser.parse %{one::two { yayness: }}
+ }
+ end
+
+ # #524
+ def test_functions_with_no_arguments
+ parser = mkparser
+ assert_nothing_raised("Could not parse statement function with no args") {
+ parser.parse %{tag()}
+ }
+ assert_nothing_raised("Could not parse rvalue function with no args") {
+ parser.parse %{$testing = template()}
+ }
+ end
+
+ # #774
+ def test_fully_qualified_collection_statement
+ parser = mkparser
+ assert_nothing_raised("Could not parse fully qualified collection statement") {
+ parser.parse %{Foo::Bar <||>}
+ }
+ end
+
+ def test_multiple_imports_on_one_line
+ one = tempfile
+ two = tempfile
+ base = tempfile
+ File.open(one, "w") { |f| f.puts "$var = value" }
+ File.open(two, "w") { |f| f.puts "$var = value" }
+ File.open(base, "w") { |f| f.puts "import '#{one}', '#{two}'" }
+
+ parser = mkparser
+ parser.file = base
+
+ # Importing is logged at debug time.
+ Puppet::Util::Log.level = :debug
+ assert_nothing_raised("Parser could not import multiple files at once") do
+ parser.parse
+ end
+
+ [one, two].each do |file|
+ assert(@logs.detect { |l| l.message =~ /importing '#{file}'/}, "did not import #{file}")
+ end
+ end
+
+ def test_cannot_assign_qualified_variables
+ parser = mkparser
+ assert_raise(Puppet::ParseError, "successfully assigned a qualified variable") do
+ parser.parse("$one::two = yay")
+ end
+ end
+
+ # #629 - undef keyword
+ def test_undef
+ parser = mkparser
+ result = nil
+ assert_nothing_raised("Could not parse assignment to undef") {
+ result = parser.parse %{$variable = undef}
+ }
+
+ main = result.hostclass("").code
+ children = main.children
+ assert_instance_of(AST::VarDef, main.children[0])
+ assert_instance_of(AST::Undef, main.children[0].value)
+ end
+
+ # Prompted by #729 -- parsing should not modify the interpreter.
+ def test_parse
+ parser = mkparser
+
+ str = "file { '/tmp/yay': ensure => file }\nclass yay {}\nnode foo {}\ndefine bar {}\n"
+ result = nil
+ assert_nothing_raised("Could not parse") do
+ result = parser.parse(str)
+ end
+ assert_instance_of(Puppet::Resource::TypeCollection, result, "Did not get a ASTSet back from parsing")
+
+ assert_instance_of(Puppet::Resource::Type, result.hostclass("yay"), "Did not create 'yay' class")
+ assert_instance_of(Puppet::Resource::Type, result.hostclass(""), "Did not create main class")
+ assert_instance_of(Puppet::Resource::Type, result.definition("bar"), "Did not create 'bar' definition")
+ assert_instance_of(Puppet::Resource::Type, result.node("foo"), "Did not create 'foo' node")
+ end
+
+ def test_namesplit
+ parser = mkparser
+
+ assert_nothing_raised do
+ {"base::sub" => %w{base sub},
+ "main" => ["", "main"],
+ "one::two::three::four" => ["one::two::three", "four"],
+ }.each do |name, ary|
+ result = parser.namesplit(name)
+ assert_equal(ary, result, "#{name} split to #{result}")
+ end
+ end
+ end
+
+ # Make sure class, node, and define methods are case-insensitive
+ def test_structure_case_insensitivity
+ parser = mkparser
+
+ result = nil
+ assert_nothing_raised do
+ result = parser.newclass "Yayness"
+ end
+ assert_equal(result, parser.find_hostclass("", "yayNess"))
+
+ assert_nothing_raised do
+ result = parser.newdefine "FunTest"
+ end
+ assert_equal(result, parser.find_definition("", "fUntEst"), "#{"fUntEst"} was not matched")
+ end
end
diff --git a/test/language/scope.rb b/test/language/scope.rb
index 0e99aa5..cb5558a 100755
--- a/test/language/scope.rb
+++ b/test/language/scope.rb
@@ -17,261 +17,261 @@ require 'puppettest/resourcetesting'
# and test whether we've got things in the right scopes
class TestScope < Test::Unit::TestCase
- include PuppetTest::ParserTesting
- include PuppetTest::ResourceTesting
+ include PuppetTest::ParserTesting
+ include PuppetTest::ResourceTesting
+
+ def setup
+ Puppet::Node::Environment.clear
+ super
+ end
+
+ def to_ary(hash)
+ hash.collect { |key,value|
+ [key,value]
+ }
+ end
+
+ def test_variables
+ config = mkcompiler
+ topscope = config.topscope
+ midscope = config.newscope(topscope)
+ botscope = config.newscope(midscope)
+
+ scopes = {:top => topscope, :mid => midscope, :bot => botscope}
+
+ # Set a variable in the top and make sure all three can get it
+ topscope.setvar("first", "topval")
+ scopes.each do |name, scope|
+ assert_equal("topval", scope.lookupvar("first", false), "Could not find var in #{name}")
+ end
- def setup
- Puppet::Node::Environment.clear
- super
+ # Now set a var in the midscope and make sure the mid and bottom can see it but not the top
+ midscope.setvar("second", "midval")
+ assert_equal(:undefined, scopes[:top].lookupvar("second", false), "Found child var in top scope")
+ [:mid, :bot].each do |name|
+ assert_equal("midval", scopes[name].lookupvar("second", false), "Could not find var in #{name}")
end
- def to_ary(hash)
- hash.collect { |key,value|
- [key,value]
- }
+ # And set something in the bottom, and make sure we only find it there.
+ botscope.setvar("third", "botval")
+ [:top, :mid].each do |name|
+ assert_equal(:undefined, scopes[name].lookupvar("third", false), "Found child var in top scope")
end
+ assert_equal("botval", scopes[:bot].lookupvar("third", false), "Could not find var in bottom scope")
- def test_variables
- config = mkcompiler
- topscope = config.topscope
- midscope = config.newscope(topscope)
- botscope = config.newscope(midscope)
- scopes = {:top => topscope, :mid => midscope, :bot => botscope}
+ # Test that the scopes convert to hash structures correctly.
+ # For topscope recursive vs non-recursive should be identical
+ assert_equal(topscope.to_hash(false), topscope.to_hash(true),
+ "Recursive and non-recursive hash is identical for topscope")
- # Set a variable in the top and make sure all three can get it
- topscope.setvar("first", "topval")
- scopes.each do |name, scope|
- assert_equal("topval", scope.lookupvar("first", false), "Could not find var in #{name}")
- end
+ # Check the variable we expect is present.
+ assert_equal({"first" => "topval"}, topscope.to_hash, "topscope returns the expected hash of variables")
- # Now set a var in the midscope and make sure the mid and bottom can see it but not the top
- midscope.setvar("second", "midval")
- assert_equal(:undefined, scopes[:top].lookupvar("second", false), "Found child var in top scope")
- [:mid, :bot].each do |name|
- assert_equal("midval", scopes[name].lookupvar("second", false), "Could not find var in #{name}")
- end
+ # Now, check that midscope does the right thing in all cases.
- # And set something in the bottom, and make sure we only find it there.
- botscope.setvar("third", "botval")
- [:top, :mid].each do |name|
- assert_equal(:undefined, scopes[name].lookupvar("third", false), "Found child var in top scope")
- end
- assert_equal("botval", scopes[:bot].lookupvar("third", false), "Could not find var in bottom scope")
+ assert_equal(
+ {"second" => "midval"},
+ midscope.to_hash(false),
+ "midscope non-recursive hash contains only midscope variable")
- # Test that the scopes convert to hash structures correctly.
- # For topscope recursive vs non-recursive should be identical
- assert_equal(topscope.to_hash(false), topscope.to_hash(true),
- "Recursive and non-recursive hash is identical for topscope")
+ assert_equal(
+ {"first" => "topval", "second" => "midval"},
+ midscope.to_hash(true),
- # Check the variable we expect is present.
- assert_equal({"first" => "topval"}, topscope.to_hash, "topscope returns the expected hash of variables")
+ "midscope recursive hash contains topscope variable also")
- # Now, check that midscope does the right thing in all cases.
+ # Finally, check the ability to shadow symbols by adding a shadow to
+ # bottomscope, then checking that we see the right stuff.
+ botscope.setvar("first", "shadowval")
- assert_equal(
- {"second" => "midval"},
- midscope.to_hash(false),
+ assert_equal(
+ {"third" => "botval", "first" => "shadowval"},
+ botscope.to_hash(false),
- "midscope non-recursive hash contains only midscope variable")
+ "botscope has the right non-recursive hash")
- assert_equal(
- {"first" => "topval", "second" => "midval"},
- midscope.to_hash(true),
+ assert_equal(
+ {"third" => "botval", "first" => "shadowval", "second" => "midval"},
+ botscope.to_hash(true),
- "midscope recursive hash contains topscope variable also")
+ "botscope values shadow parent scope values")
+ end
- # Finally, check the ability to shadow symbols by adding a shadow to
- # bottomscope, then checking that we see the right stuff.
- botscope.setvar("first", "shadowval")
+ def test_declarative
+ # set to declarative
+ top = mkscope
+ sub = mkscope(:parent => top)
- assert_equal(
- {"third" => "botval", "first" => "shadowval"},
- botscope.to_hash(false),
+ assert_nothing_raised {
+ top.setvar("test","value")
+ }
+ assert_raise(Puppet::ParseError) {
+ top.setvar("test","other")
+ }
+ assert_nothing_raised {
+ sub.setvar("test","later")
+ }
+ assert_raise(Puppet::ParseError) {
+ top.setvar("test","yeehaw")
+ }
+ end
- "botscope has the right non-recursive hash")
+ def test_parent
+ config = mkcompiler
+ top = config.topscope
- assert_equal(
- {"third" => "botval", "first" => "shadowval", "second" => "midval"},
- botscope.to_hash(true),
+ # Make a subscope
+ sub = config.newscope(top)
- "botscope values shadow parent scope values")
- end
+ assert_equal(top, sub.parent, "Did not find parent scope correctly")
+ assert_equal(top, sub.parent, "Did not find parent scope on second call")
+ end
- def test_declarative
- # set to declarative
- top = mkscope
- sub = mkscope(:parent => top)
-
- assert_nothing_raised {
- top.setvar("test","value")
- }
- assert_raise(Puppet::ParseError) {
- top.setvar("test","other")
- }
- assert_nothing_raised {
- sub.setvar("test","later")
- }
- assert_raise(Puppet::ParseError) {
- top.setvar("test","yeehaw")
- }
- end
+ # Make sure we know what we consider to be truth.
+ def test_truth
- def test_parent
- config = mkcompiler
- top = config.topscope
+ assert_equal(
+ true, Puppet::Parser::Scope.true?("a string"),
- # Make a subscope
- sub = config.newscope(top)
-
- assert_equal(top, sub.parent, "Did not find parent scope correctly")
- assert_equal(top, sub.parent, "Did not find parent scope on second call")
- end
-
- # Make sure we know what we consider to be truth.
- def test_truth
+ "Strings not considered true")
assert_equal(
- true, Puppet::Parser::Scope.true?("a string"),
-
- "Strings not considered true")
+ true, Puppet::Parser::Scope.true?(true),
- assert_equal(
- true, Puppet::Parser::Scope.true?(true),
+ "True considered true")
- "True considered true")
-
- assert_equal(
- false, Puppet::Parser::Scope.true?(""),
+ assert_equal(
+ false, Puppet::Parser::Scope.true?(""),
- "Empty strings considered true")
+ "Empty strings considered true")
- assert_equal(
- false, Puppet::Parser::Scope.true?(false),
+ assert_equal(
+ false, Puppet::Parser::Scope.true?(false),
- "false considered true")
+ "false considered true")
- assert_equal(
- false, Puppet::Parser::Scope.true?(:undef),
+ assert_equal(
+ false, Puppet::Parser::Scope.true?(:undef),
- "undef considered true")
- end
+ "undef considered true")
+ end
- def test_virtual_definitions_do_not_get_evaluated
- parser = mkparser
- config = mkcompiler
+ def test_virtual_definitions_do_not_get_evaluated
+ parser = mkparser
+ config = mkcompiler
- # Create a default source
- parser.newclass("")
- config.topscope.source = parser.known_resource_types.hostclass("")
+ # Create a default source
+ parser.newclass("")
+ config.topscope.source = parser.known_resource_types.hostclass("")
- # And a scope resource
- scope_res = Puppet::Parser::Resource.new(:file, "/file", :scope => config.topscope)
- config.topscope.resource = scope_res
+ # And a scope resource
+ scope_res = Puppet::Parser::Resource.new(:file, "/file", :scope => config.topscope)
+ config.topscope.resource = scope_res
- args = AST::ASTArray.new(
- :children => [nameobj("arg")]
- )
+ args = AST::ASTArray.new(
+ :children => [nameobj("arg")]
+ )
- # Create a top-level define
- parser.newdefine "one", :arguments => [%w{arg}],
- :code => AST::ASTArray.new(
- :children => [
- resourcedef("file", "/tmp", {"owner" => varref("arg")})
- ]
- )
+ # Create a top-level define
+ parser.newdefine "one", :arguments => [%w{arg}],
+ :code => AST::ASTArray.new(
+ :children => [
+ resourcedef("file", "/tmp", {"owner" => varref("arg")})
+ ]
+ )
- # create a resource that calls our third define
- obj = resourcedef("one", "boo", {"arg" => "parentfoo"})
+ # create a resource that calls our third define
+ obj = resourcedef("one", "boo", {"arg" => "parentfoo"})
- # And mark it as virtual
- obj.virtual = true
+ # And mark it as virtual
+ obj.virtual = true
- # And then evaluate it
- obj.evaluate config.topscope
+ # And then evaluate it
+ obj.evaluate config.topscope
- # And run the loop.
- config.send(:evaluate_generators)
+ # And run the loop.
+ config.send(:evaluate_generators)
- %w{File}.each do |type|
- objects = config.resources.find_all { |r| r.type == type and r.virtual }
+ %w{File}.each do |type|
+ objects = config.resources.find_all { |r| r.type == type and r.virtual }
- assert(objects.empty?, "Virtual define got evaluated")
- end
+ assert(objects.empty?, "Virtual define got evaluated")
end
-
- if defined? ::ActiveRecord
- # Verify that we can both store and collect an object in the same
- # run, whether it's in the same scope as a collection or a different
- # scope.
- def test_storeandcollect
- catalog_cache_class = Puppet::Resource::Catalog.indirection.cache_class
- facts_cache_class = Puppet::Node::Facts.indirection.cache_class
- node_cache_class = Puppet::Node.indirection.cache_class
- Puppet[:storeconfigs] = true
- Puppet::Rails.init
- sleep 1
- children = []
- Puppet[:code] = "
+ end
+
+ if defined? ::ActiveRecord
+ # Verify that we can both store and collect an object in the same
+ # run, whether it's in the same scope as a collection or a different
+ # scope.
+ def test_storeandcollect
+ catalog_cache_class = Puppet::Resource::Catalog.indirection.cache_class
+ facts_cache_class = Puppet::Node::Facts.indirection.cache_class
+ node_cache_class = Puppet::Node.indirection.cache_class
+ Puppet[:storeconfigs] = true
+ Puppet::Rails.init
+ sleep 1
+ children = []
+ Puppet[:code] = "
class yay {
- @@host { myhost: ip => \"192.168.0.2\" }
+ @@host { myhost: ip => \"192.168.0.2\" }
}
include yay
@@host { puppet: ip => \"192.168.0.3\" }
Host <<||>>"
- config = nil
- # We run it twice because we want to make sure there's no conflict
- # if we pull it up from the database.
- node = mknode
- node.merge "hostname" => node.name
- 2.times { |i|
- catalog = Puppet::Parser::Compiler.new(node).compile
- assert_instance_of(Puppet::Parser::Resource, catalog.resource(:host, "puppet"))
- assert_instance_of(Puppet::Parser::Resource, catalog.resource(:host, "myhost"))
- }
- ensure
- Puppet[:storeconfigs] = false
- Puppet::Resource::Catalog.cache_class = catalog_cache_class
- Puppet::Node::Facts.cache_class = facts_cache_class
- Puppet::Node.cache_class = node_cache_class
- end
- else
- $stderr.puts "No ActiveRecord -- skipping collection tests"
- end
+ config = nil
+ # We run it twice because we want to make sure there's no conflict
+ # if we pull it up from the database.
+ node = mknode
+ node.merge "hostname" => node.name
+ 2.times { |i|
+ catalog = Puppet::Parser::Compiler.new(node).compile
+ assert_instance_of(Puppet::Parser::Resource, catalog.resource(:host, "puppet"))
+ assert_instance_of(Puppet::Parser::Resource, catalog.resource(:host, "myhost"))
+ }
+ ensure
+ Puppet[:storeconfigs] = false
+ Puppet::Resource::Catalog.cache_class = catalog_cache_class
+ Puppet::Node::Facts.cache_class = facts_cache_class
+ Puppet::Node.cache_class = node_cache_class
+ end
+ else
+ $stderr.puts "No ActiveRecord -- skipping collection tests"
+ end
- def test_namespaces
- scope = mkscope
+ def test_namespaces
+ scope = mkscope
- assert_equal(
- [""], scope.namespaces,
+ assert_equal(
+ [""], scope.namespaces,
- "Started out with incorrect namespaces")
- assert_nothing_raised { scope.add_namespace("fun::test") }
- assert_equal(["fun::test"], scope.namespaces, "Did not add namespace correctly")
- assert_nothing_raised { scope.add_namespace("yay::test") }
- assert_equal(["fun::test", "yay::test"], scope.namespaces, "Did not add extra namespace correctly")
- end
+ "Started out with incorrect namespaces")
+ assert_nothing_raised { scope.add_namespace("fun::test") }
+ assert_equal(["fun::test"], scope.namespaces, "Did not add namespace correctly")
+ assert_nothing_raised { scope.add_namespace("yay::test") }
+ assert_equal(["fun::test", "yay::test"], scope.namespaces, "Did not add extra namespace correctly")
+ end
- # #629 - undef should be "" or :undef
- def test_lookupvar_with_undef
- scope = mkscope
+ # #629 - undef should be "" or :undef
+ def test_lookupvar_with_undef
+ scope = mkscope
- scope.setvar("testing", :undef)
+ scope.setvar("testing", :undef)
- assert_equal(
- :undef, scope.lookupvar("testing", false),
+ assert_equal(
+ :undef, scope.lookupvar("testing", false),
- "undef was not returned as :undef when not string")
+ "undef was not returned as :undef when not string")
- assert_equal(
- "", scope.lookupvar("testing", true),
+ assert_equal(
+ "", scope.lookupvar("testing", true),
- "undef was not returned as '' when string")
- end
+ "undef was not returned as '' when string")
+ end
end
diff --git a/test/language/snippets.rb b/test/language/snippets.rb
index d55b75e..51c5e23 100755
--- a/test/language/snippets.rb
+++ b/test/language/snippets.rb
@@ -9,511 +9,511 @@ require 'puppet/network/handler'
require 'puppettest'
class TestSnippets < Test::Unit::TestCase
- include PuppetTest
+ include PuppetTest
- def setup
- super
- @file = Puppet::Type.type(:file)
- Facter.stubs(:to_hash).returns({})
- Facter.stubs(:value).returns("whatever")
- end
+ def setup
+ super
+ @file = Puppet::Type.type(:file)
+ Facter.stubs(:to_hash).returns({})
+ Facter.stubs(:value).returns("whatever")
+ end
- def self.snippetdir
- PuppetTest.datadir "snippets"
- end
+ def self.snippetdir
+ PuppetTest.datadir "snippets"
+ end
- def assert_file(path, msg = nil)
- unless file = @catalog.resource(:file, path)
- msg ||= "Could not find file #{path}"
- raise msg
- end
+ def assert_file(path, msg = nil)
+ unless file = @catalog.resource(:file, path)
+ msg ||= "Could not find file #{path}"
+ raise msg
end
+ end
- def assert_not_file(path, msg = nil)
- if file = @catalog.resource(:file, path)
- msg ||= "File #{path} exists!"
- raise msg
- end
+ def assert_not_file(path, msg = nil)
+ if file = @catalog.resource(:file, path)
+ msg ||= "File #{path} exists!"
+ raise msg
end
+ end
- def assert_mode_equal(mode, path)
- unless file = @catalog.resource(:file, path)
- raise "Could not find file #{path}"
- end
-
- unless mode == file.should(:mode)
- raise "Mode for %s is incorrect: %o vs %o" % [path, mode, file.should(:mode)]
- end
+ def assert_mode_equal(mode, path)
+ unless file = @catalog.resource(:file, path)
+ raise "Could not find file #{path}"
end
- def snippet(name)
- File.join(self.class.snippetdir, name)
+ unless mode == file.should(:mode)
+ raise "Mode for %s is incorrect: %o vs %o" % [path, mode, file.should(:mode)]
end
+ end
- def file2ast(file)
- parser = Puppet::Parser::Parser.new
- parser.file = file
- ast = parser.parse
+ def snippet(name)
+ File.join(self.class.snippetdir, name)
+ end
- ast
- end
+ def file2ast(file)
+ parser = Puppet::Parser::Parser.new
+ parser.file = file
+ ast = parser.parse
- def snippet2ast(text)
- parser = Puppet::Parser::Parser.new
- parser.string = text
- ast = parser.parse
+ ast
+ end
- ast
- end
+ def snippet2ast(text)
+ parser = Puppet::Parser::Parser.new
+ parser.string = text
+ ast = parser.parse
- def client
- args = {
- :Listen => false
- }
- Puppet::Network::Client.new(args)
- end
+ ast
+ end
- def ast2scope(ast)
- scope = Puppet::Parser::Scope.new
- ast.evaluate(scope)
-
- scope
- end
-
- def scope2objs(scope)
- objs = scope.to_trans
- end
-
- def snippet2scope(snippet)
- ast = snippet2ast(snippet)
- scope = ast2scope(ast)
- end
-
- def snippet2objs(snippet)
- ast = snippet2ast(snippet)
- scope = ast2scope(ast)
- objs = scope2objs(scope)
- end
-
- def properties(type)
- properties = type.validproperties
- end
-
- def metaparams(type)
- mparams = []
- Puppet::Type.eachmetaparam { |param|
- mparams.push param
- }
-
- mparams
- end
-
- def params(type)
- params = []
- type.parameters.each { |name,property|
- params.push name
- }
-
- params
- end
-
- def randthing(thing,type)
- list = self.send(thing,type)
- list[rand(list.length)]
- end
+ def client
+ args = {
+ :Listen => false
+ }
+ Puppet::Network::Client.new(args)
+ end
+
+ def ast2scope(ast)
+ scope = Puppet::Parser::Scope.new
+ ast.evaluate(scope)
+
+ scope
+ end
+
+ def scope2objs(scope)
+ objs = scope.to_trans
+ end
+
+ def snippet2scope(snippet)
+ ast = snippet2ast(snippet)
+ scope = ast2scope(ast)
+ end
+
+ def snippet2objs(snippet)
+ ast = snippet2ast(snippet)
+ scope = ast2scope(ast)
+ objs = scope2objs(scope)
+ end
+
+ def properties(type)
+ properties = type.validproperties
+ end
+
+ def metaparams(type)
+ mparams = []
+ Puppet::Type.eachmetaparam { |param|
+ mparams.push param
+ }
- def randeach(type)
- [:properties, :metaparams, :parameters].collect { |thing|
- randthing(thing,type)
- }
- end
+ mparams
+ end
- @@snippets = {
- true => [
- %{File { mode => 755 }}
- ],
+ def params(type)
+ params = []
+ type.parameters.each { |name,property|
+ params.push name
}
- def disabled_test_defaults
- Puppet::Type.eachtype { |type|
- next if type.name == :puppet or type.name == :component
+ params
+ end
- rands = randeach(type)
+ def randthing(thing,type)
+ list = self.send(thing,type)
+ list[rand(list.length)]
+ end
- name = type.name.to_s.capitalize
-
- [0..1, 0..2].each { |range|
- params = rands[range]
- paramstr = params.collect { |param|
- "#{param} => fake"
- }.join(", ")
+ def randeach(type)
+ [:properties, :metaparams, :parameters].collect { |thing|
+ randthing(thing,type)
+ }
+ end
- str = "#{name} { #{paramstr} }"
+ @@snippets = {
+ true => [
+ %{File { mode => 755 }}
+ ],
+ }
- scope = nil
- assert_nothing_raised {
- scope = snippet2scope(str)
- }
+ def disabled_test_defaults
+ Puppet::Type.eachtype { |type|
+ next if type.name == :puppet or type.name == :component
- defaults = nil
- assert_nothing_raised {
- defaults = scope.lookupdefaults(name)
- }
+ rands = randeach(type)
- p defaults
+ name = type.name.to_s.capitalize
- params.each { |param|
- puts "#{name} => '#{param}'"
- assert(defaults.include?(param))
- }
- }
- }
- end
+ [0..1, 0..2].each { |range|
+ params = rands[range]
+ paramstr = params.collect { |param|
+ "#{param} => fake"
+ }.join(", ")
- # this is here in case no tests get defined; otherwise we get a warning
- def test_nothing
- end
+ str = "#{name} { #{paramstr} }"
- def snippet_filecreate
- %w{a b c d}.each { |letter|
- path = "/tmp/create#{letter}test"
- assert_file(path)
- assert_mode_equal(0755, path) if %w{a b}.include?(letter)
+ scope = nil
+ assert_nothing_raised {
+ scope = snippet2scope(str)
}
- end
- def snippet_simpledefaults
- path = "/tmp/defaulttest"
- assert_file(path)
- assert_mode_equal(0755, path)
- end
-
- def snippet_simpleselector
- files = %w{a b c d}.collect { |letter|
- path = "/tmp/snippetselect#{letter}test"
- assert_file(path)
- assert_mode_equal(0755, path)
+ defaults = nil
+ assert_nothing_raised {
+ defaults = scope.lookupdefaults(name)
}
- end
-
- def snippet_classpathtest
- path = "/tmp/classtest"
-
- file = @catalog.resource(:file, path)
- assert(file, "did not create file #{path}")
- assert_equal( "/Stage[main]/Testing/Mytype[componentname]/File[/tmp/classtest]", file.path)
- end
-
- def snippet_argumentdefaults
- path1 = "/tmp/argumenttest1"
- path2 = "/tmp/argumenttest2"
-
- file1 = @catalog.resource(:file, path1)
- file2 = @catalog.resource(:file, path2)
-
- assert_file(path1)
- assert_mode_equal(0755, path1)
-
- assert_file(path2)
- assert_mode_equal(0644, path2)
- end
-
- def snippet_casestatement
- paths = %w{
- /tmp/existsfile
- /tmp/existsfile2
- /tmp/existsfile3
- /tmp/existsfile4
- /tmp/existsfile5
- /tmp/existsfile6
- }
+ p defaults
- paths.each { |path|
- file = @catalog.resource(:file, path)
- assert(file, "File #{path} is missing")
- assert_mode_equal(0755, path)
+ params.each { |param|
+ puts "#{name} => '#{param}'"
+ assert(defaults.include?(param))
}
- end
+ }
+ }
+ end
- def snippet_implicititeration
- paths = %w{a b c d e f g h}.collect { |l| "/tmp/iteration#{l}test" }
+ # this is here in case no tests get defined; otherwise we get a warning
+ def test_nothing
+ end
- paths.each { |path|
- file = @catalog.resource(:file, path)
- assert_file(path)
- assert_mode_equal(0755, path)
- }
- end
+ def snippet_filecreate
+ %w{a b c d}.each { |letter|
+ path = "/tmp/create#{letter}test"
+ assert_file(path)
+ assert_mode_equal(0755, path) if %w{a b}.include?(letter)
+ }
+ end
+
+ def snippet_simpledefaults
+ path = "/tmp/defaulttest"
+ assert_file(path)
+ assert_mode_equal(0755, path)
+ end
+
+ def snippet_simpleselector
+ files = %w{a b c d}.collect { |letter|
+ path = "/tmp/snippetselect#{letter}test"
+ assert_file(path)
+ assert_mode_equal(0755, path)
+ }
+ end
- def snippet_multipleinstances
- paths = %w{a b c}.collect { |l| "/tmp/multipleinstances#{l}" }
+ def snippet_classpathtest
+ path = "/tmp/classtest"
- paths.each { |path|
- assert_file(path)
- assert_mode_equal(0755, path)
+ file = @catalog.resource(:file, path)
+ assert(file, "did not create file #{path}")
- }
- end
+ assert_equal( "/Stage[main]/Testing/Mytype[componentname]/File[/tmp/classtest]", file.path)
+ end
- def snippet_namevartest
- file = "/tmp/testfiletest"
- dir = "/tmp/testdirtest"
- assert_file(file)
- assert_file(dir)
- assert_equal(:directory, @catalog.resource(:file, dir).should(:ensure), "Directory is not set to be a directory")
- end
+ def snippet_argumentdefaults
+ path1 = "/tmp/argumenttest1"
+ path2 = "/tmp/argumenttest2"
- def snippet_scopetest
- file = "/tmp/scopetest"
- assert_file(file)
- assert_mode_equal(0755, file)
- end
+ file1 = @catalog.resource(:file, path1)
+ file2 = @catalog.resource(:file, path2)
- def snippet_selectorvalues
- nums = %w{1 2 3 4 5 6 7}
- files = nums.collect { |n|
- "/tmp/selectorvalues#{n}"
- }
+ assert_file(path1)
+ assert_mode_equal(0755, path1)
- files.each { |f|
- assert_file(f)
- assert_mode_equal(0755, f)
- }
- end
+ assert_file(path2)
+ assert_mode_equal(0644, path2)
+ end
- def snippet_singleselector
- nums = %w{1 2 3}
- files = nums.collect { |n|
- "/tmp/singleselector#{n}"
- }
+ def snippet_casestatement
+ paths = %w{
+ /tmp/existsfile
+ /tmp/existsfile2
+ /tmp/existsfile3
+ /tmp/existsfile4
+ /tmp/existsfile5
+ /tmp/existsfile6
+ }
- files.each { |f|
- assert_file(f)
- assert_mode_equal(0755, f)
- }
- end
+ paths.each { |path|
+ file = @catalog.resource(:file, path)
+ assert(file, "File #{path} is missing")
+ assert_mode_equal(0755, path)
+ }
+ end
- def snippet_falsevalues
- file = "/tmp/falsevaluesfalse"
- assert_file(file)
- end
+ def snippet_implicititeration
+ paths = %w{a b c d e f g h}.collect { |l| "/tmp/iteration#{l}test" }
- def disabled_snippet_classargtest
- [1,2].each { |num|
- file = "/tmp/classargtest#{num}"
- assert_file(file)
- assert_mode_equal(0755, file)
- }
- end
+ paths.each { |path|
+ file = @catalog.resource(:file, path)
+ assert_file(path)
+ assert_mode_equal(0755, path)
+ }
+ end
- def snippet_classheirarchy
- [1,2,3].each { |num|
- file = "/tmp/classheir#{num}"
- assert_file(file)
- assert_mode_equal(0755, file)
- }
- end
+ def snippet_multipleinstances
+ paths = %w{a b c}.collect { |l| "/tmp/multipleinstances#{l}" }
- def snippet_singleary
- [1,2,3,4].each { |num|
- file = "/tmp/singleary#{num}"
- assert_file(file)
- }
- end
+ paths.each { |path|
+ assert_file(path)
+ assert_mode_equal(0755, path)
- def snippet_classincludes
- [1,2,3].each { |num|
- file = "/tmp/classincludes#{num}"
- assert_file(file)
- assert_mode_equal(0755, file)
- }
- end
+ }
+ end
+
+ def snippet_namevartest
+ file = "/tmp/testfiletest"
+ dir = "/tmp/testdirtest"
+ assert_file(file)
+ assert_file(dir)
+ assert_equal(:directory, @catalog.resource(:file, dir).should(:ensure), "Directory is not set to be a directory")
+ end
+
+ def snippet_scopetest
+ file = "/tmp/scopetest"
+ assert_file(file)
+ assert_mode_equal(0755, file)
+ end
+
+ def snippet_selectorvalues
+ nums = %w{1 2 3 4 5 6 7}
+ files = nums.collect { |n|
+ "/tmp/selectorvalues#{n}"
+ }
- def snippet_componentmetaparams
- ["/tmp/component1", "/tmp/component2"].each { |file|
- assert_file(file)
- }
- end
+ files.each { |f|
+ assert_file(f)
+ assert_mode_equal(0755, f)
+ }
+ end
- def snippet_aliastest
- %w{/tmp/aliastest /tmp/aliastest2 /tmp/aliastest3}.each { |file|
- assert_file(file)
- }
- end
+ def snippet_singleselector
+ nums = %w{1 2 3}
+ files = nums.collect { |n|
+ "/tmp/singleselector#{n}"
+ }
- def snippet_singlequote
- { 1 => 'a $quote',
- 2 => 'some "\yayness\"'
- }.each { |count, str|
- path = "/tmp/singlequote#{count}"
- assert_file(path)
- assert_equal(str, @catalog.resource(:file, path).parameter(:content).actual_content)
- }
- end
+ files.each { |f|
+ assert_file(f)
+ assert_mode_equal(0755, f)
+ }
+ end
+
+ def snippet_falsevalues
+ file = "/tmp/falsevaluesfalse"
+ assert_file(file)
+ end
+
+ def disabled_snippet_classargtest
+ [1,2].each { |num|
+ file = "/tmp/classargtest#{num}"
+ assert_file(file)
+ assert_mode_equal(0755, file)
+ }
+ end
- # There's no way to actually retrieve the list of classes from the
- # transaction.
- def snippet_tag
- end
+ def snippet_classheirarchy
+ [1,2,3].each { |num|
+ file = "/tmp/classheir#{num}"
+ assert_file(file)
+ assert_mode_equal(0755, file)
+ }
+ end
- # Make sure that set tags are correctly in place, yo.
- def snippet_tagged
- tags = {"testing" => true, "yayness" => false,
- "both" => false, "bothtrue" => true, "define" => true}
+ def snippet_singleary
+ [1,2,3,4].each { |num|
+ file = "/tmp/singleary#{num}"
+ assert_file(file)
+ }
+ end
- tags.each do |tag, retval|
- assert_file("/tmp/tagged#{tag}#{retval.to_s}")
- end
- end
+ def snippet_classincludes
+ [1,2,3].each { |num|
+ file = "/tmp/classincludes#{num}"
+ assert_file(file)
+ assert_mode_equal(0755, file)
+ }
+ end
- def snippet_defineoverrides
- file = "/tmp/defineoverrides1"
- assert_file(file)
- assert_mode_equal(0755, file)
- end
+ def snippet_componentmetaparams
+ ["/tmp/component1", "/tmp/component2"].each { |file|
+ assert_file(file)
+ }
+ end
- def snippet_deepclassheirarchy
- 5.times { |i|
- i += 1
- file = "/tmp/deepclassheir#{i}"
- assert_file(file)
- }
- end
+ def snippet_aliastest
+ %w{/tmp/aliastest /tmp/aliastest2 /tmp/aliastest3}.each { |file|
+ assert_file(file)
+ }
+ end
+
+ def snippet_singlequote
+ { 1 => 'a $quote',
+ 2 => 'some "\yayness\"'
+ }.each { |count, str|
+ path = "/tmp/singlequote#{count}"
+ assert_file(path)
+ assert_equal(str, @catalog.resource(:file, path).parameter(:content).actual_content)
+ }
+ end
+
+ # There's no way to actually retrieve the list of classes from the
+ # transaction.
+ def snippet_tag
+ end
+
+ # Make sure that set tags are correctly in place, yo.
+ def snippet_tagged
+ tags = {"testing" => true, "yayness" => false,
+ "both" => false, "bothtrue" => true, "define" => true}
+
+ tags.each do |tag, retval|
+ assert_file("/tmp/tagged#{tag}#{retval.to_s}")
+ end
+ end
+
+ def snippet_defineoverrides
+ file = "/tmp/defineoverrides1"
+ assert_file(file)
+ assert_mode_equal(0755, file)
+ end
+
+ def snippet_deepclassheirarchy
+ 5.times { |i|
+ i += 1
+ file = "/tmp/deepclassheir#{i}"
+ assert_file(file)
+ }
+ end
- def snippet_emptyclass
- # There's nothing to check other than that it works
- end
+ def snippet_emptyclass
+ # There's nothing to check other than that it works
+ end
- def snippet_emptyexec
- assert(@catalog.resource(:exec, "touch /tmp/emptyexectest"), "Did not create exec")
- end
+ def snippet_emptyexec
+ assert(@catalog.resource(:exec, "touch /tmp/emptyexectest"), "Did not create exec")
+ end
- def snippet_multisubs
- path = "/tmp/multisubtest"
- assert_file(path)
- file = @catalog.resource(:file, path)
- assert_equal("{md5}5fbef65269a99bddc2106251dd89b1dc", file.should(:content), "sub2 did not override content")
- assert_mode_equal(0755, path)
- end
+ def snippet_multisubs
+ path = "/tmp/multisubtest"
+ assert_file(path)
+ file = @catalog.resource(:file, path)
+ assert_equal("{md5}5fbef65269a99bddc2106251dd89b1dc", file.should(:content), "sub2 did not override content")
+ assert_mode_equal(0755, path)
+ end
- def snippet_collection
- assert_file("/tmp/colltest1")
- assert_nil(@catalog.resource(:file, "/tmp/colltest2"), "Incorrectly collected file")
- end
+ def snippet_collection
+ assert_file("/tmp/colltest1")
+ assert_nil(@catalog.resource(:file, "/tmp/colltest2"), "Incorrectly collected file")
+ end
- def snippet_virtualresources
- %w{1 2 3 4}.each do |num|
- assert_file("/tmp/virtualtest#{num}")
- end
+ def snippet_virtualresources
+ %w{1 2 3 4}.each do |num|
+ assert_file("/tmp/virtualtest#{num}")
end
+ end
- def snippet_componentrequire
- %w{1 2}.each do |num|
+ def snippet_componentrequire
+ %w{1 2}.each do |num|
- assert_file(
- "/tmp/testing_component_requires#{num}",
+ assert_file(
+ "/tmp/testing_component_requires#{num}",
- "#{num} does not exist")
- end
- end
-
- def snippet_realize_defined_types
- assert_file("/tmp/realize_defined_test1")
- assert_file("/tmp/realize_defined_test2")
- end
-
- def snippet_collection_within_virtual_definitions
- assert_file("/tmp/collection_within_virtual_definitions1_foo.txt")
- assert_file("/tmp/collection_within_virtual_definitions2_foo2.txt")
- end
-
- def snippet_fqparents
- assert_file("/tmp/fqparent1", "Did not make file from parent class")
- assert_file("/tmp/fqparent2", "Did not make file from subclass")
- end
-
- def snippet_fqdefinition
- assert_file("/tmp/fqdefinition", "Did not make file from fully-qualified definition")
- end
-
- def snippet_subclass_name_duplication
- assert_file("/tmp/subclass_name_duplication1", "Did not make first file from duplicate subclass names")
- assert_file("/tmp/subclass_name_duplication2", "Did not make second file from duplicate subclass names")
- end
-
- def snippet_funccomma
- assert_file("/tmp/funccomma1", "Did not make first file from trailing function comma")
- assert_file("/tmp/funccomma2", "Did not make second file from trailing function comma")
- end
-
- def snippet_arraytrailingcomma
- assert_file("/tmp/arraytrailingcomma1", "Did not make first file from array")
- assert_file("/tmp/arraytrailingcomma2", "Did not make second file from array")
- end
-
- def snippet_multipleclass
- assert_file("/tmp/multipleclassone", "one")
- assert_file("/tmp/multipleclasstwo", "two")
- end
+ "#{num} does not exist")
+ end
+ end
+
+ def snippet_realize_defined_types
+ assert_file("/tmp/realize_defined_test1")
+ assert_file("/tmp/realize_defined_test2")
+ end
+
+ def snippet_collection_within_virtual_definitions
+ assert_file("/tmp/collection_within_virtual_definitions1_foo.txt")
+ assert_file("/tmp/collection_within_virtual_definitions2_foo2.txt")
+ end
+
+ def snippet_fqparents
+ assert_file("/tmp/fqparent1", "Did not make file from parent class")
+ assert_file("/tmp/fqparent2", "Did not make file from subclass")
+ end
+
+ def snippet_fqdefinition
+ assert_file("/tmp/fqdefinition", "Did not make file from fully-qualified definition")
+ end
+
+ def snippet_subclass_name_duplication
+ assert_file("/tmp/subclass_name_duplication1", "Did not make first file from duplicate subclass names")
+ assert_file("/tmp/subclass_name_duplication2", "Did not make second file from duplicate subclass names")
+ end
+
+ def snippet_funccomma
+ assert_file("/tmp/funccomma1", "Did not make first file from trailing function comma")
+ assert_file("/tmp/funccomma2", "Did not make second file from trailing function comma")
+ end
+
+ def snippet_arraytrailingcomma
+ assert_file("/tmp/arraytrailingcomma1", "Did not make first file from array")
+ assert_file("/tmp/arraytrailingcomma2", "Did not make second file from array")
+ end
+
+ def snippet_multipleclass
+ assert_file("/tmp/multipleclassone", "one")
+ assert_file("/tmp/multipleclasstwo", "two")
+ end
+
+ def snippet_multilinecomments
+ assert_not_file("/tmp/multilinecomments","Did create a commented resource");
+ end
+
+ def snippet_collection_override
+ path = "/tmp/collection"
+ assert_file(path)
+ assert_mode_equal(0600, path)
+ end
+
+ def snippet_ifexpression
+ assert_file("/tmp/testiftest","if test");
+ end
+
+ def snippet_hash
+ assert_file("/tmp/myhashfile1","hash test 1");
+ assert_file("/tmp/myhashfile2","hash test 2");
+ assert_file("/tmp/myhashfile3","hash test 3");
+ assert_file("/tmp/myhashfile4","hash test 4");
+ end
+
+ # Iterate across each of the snippets and create a test.
+ Dir.entries(snippetdir).sort.each { |file|
+ next if file =~ /^\./
+
+
+ mname = "snippet_" + file.sub(/\.pp$/, '')
+ if self.method_defined?(mname)
+ #eval("alias #{testname} #{mname}")
+ testname = ("test_#{mname}").intern
+ self.send(:define_method, testname) {
+ Puppet[:manifest] = snippet(file)
+ facts = {
+ "hostname" => "testhost",
+ "domain" => "domain.com",
+ "ipaddress" => "127.0.0.1",
+ "fqdn" => "testhost.domain.com"
+ }
- def snippet_multilinecomments
- assert_not_file("/tmp/multilinecomments","Did create a commented resource");
- end
+ node = Puppet::Node.new("testhost")
+ node.merge(facts)
- def snippet_collection_override
- path = "/tmp/collection"
- assert_file(path)
- assert_mode_equal(0600, path)
- end
+ catalog = nil
+ assert_nothing_raised("Could not compile catalog") {
+ catalog = Puppet::Resource::Catalog.find(node)
+ }
- def snippet_ifexpression
- assert_file("/tmp/testiftest","if test");
- end
+ assert_nothing_raised("Could not convert catalog") {
+ catalog = catalog.to_ral
+ }
- def snippet_hash
- assert_file("/tmp/myhashfile1","hash test 1");
- assert_file("/tmp/myhashfile2","hash test 2");
- assert_file("/tmp/myhashfile3","hash test 3");
- assert_file("/tmp/myhashfile4","hash test 4");
+ @catalog = catalog
+ assert_nothing_raised {
+ self.send(mname)
+ }
+ }
+ mname = mname.intern
end
-
- # Iterate across each of the snippets and create a test.
- Dir.entries(snippetdir).sort.each { |file|
- next if file =~ /^\./
-
-
- mname = "snippet_" + file.sub(/\.pp$/, '')
- if self.method_defined?(mname)
- #eval("alias #{testname} #{mname}")
- testname = ("test_#{mname}").intern
- self.send(:define_method, testname) {
- Puppet[:manifest] = snippet(file)
- facts = {
- "hostname" => "testhost",
- "domain" => "domain.com",
- "ipaddress" => "127.0.0.1",
- "fqdn" => "testhost.domain.com"
- }
-
- node = Puppet::Node.new("testhost")
- node.merge(facts)
-
- catalog = nil
- assert_nothing_raised("Could not compile catalog") {
- catalog = Puppet::Resource::Catalog.find(node)
- }
-
- assert_nothing_raised("Could not convert catalog") {
- catalog = catalog.to_ral
- }
-
- @catalog = catalog
- assert_nothing_raised {
- self.send(mname)
- }
- }
- mname = mname.intern
- end
- }
+ }
end
diff --git a/test/language/transportable.rb b/test/language/transportable.rb
index 37c67d6..1e9ae93 100755
--- a/test/language/transportable.rb
+++ b/test/language/transportable.rb
@@ -9,79 +9,79 @@ require 'puppettest/parsertesting'
require 'yaml'
class TestTransportable < Test::Unit::TestCase
- include PuppetTest::ParserTesting
-
- def test_yamldumpobject
- obj = mk_transobject
- obj.to_yaml_properties
- str = nil
- assert_nothing_raised {
- str = YAML.dump(obj)
- }
-
- newobj = nil
- assert_nothing_raised {
- newobj = YAML.load(str)
- }
-
- assert(newobj.name, "Object has no name")
- assert(newobj.type, "Object has no type")
+ include PuppetTest::ParserTesting
+
+ def test_yamldumpobject
+ obj = mk_transobject
+ obj.to_yaml_properties
+ str = nil
+ assert_nothing_raised {
+ str = YAML.dump(obj)
+ }
+
+ newobj = nil
+ assert_nothing_raised {
+ newobj = YAML.load(str)
+ }
+
+ assert(newobj.name, "Object has no name")
+ assert(newobj.type, "Object has no type")
+ end
+
+ def test_yamldumpbucket
+ objects = %w{/etc/passwd /etc /tmp /var /dev}.collect { |d|
+ mk_transobject(d)
+ }
+ bucket = mk_transbucket(*objects)
+ str = nil
+ assert_nothing_raised {
+ str = YAML.dump(bucket)
+ }
+
+ newobj = nil
+ assert_nothing_raised {
+ newobj = YAML.load(str)
+ }
+
+ assert(newobj.name, "Bucket has no name")
+ assert(newobj.type, "Bucket has no type")
+ end
+
+ # Make sure our 'delve' command is working
+ def test_delve
+ top = mk_transtree do |object, depth, width|
+ object.file = :funtest if width % 2 == 1
end
- def test_yamldumpbucket
- objects = %w{/etc/passwd /etc /tmp /var /dev}.collect { |d|
- mk_transobject(d)
- }
- bucket = mk_transbucket(*objects)
- str = nil
- assert_nothing_raised {
- str = YAML.dump(bucket)
- }
-
- newobj = nil
- assert_nothing_raised {
- newobj = YAML.load(str)
- }
-
- assert(newobj.name, "Bucket has no name")
- assert(newobj.type, "Bucket has no type")
- end
-
- # Make sure our 'delve' command is working
- def test_delve
- top = mk_transtree do |object, depth, width|
- object.file = :funtest if width % 2 == 1
+ objects = []
+ buckets = []
+ found = []
+
+ count = 0
+ assert_nothing_raised {
+ top.delve do |object|
+ count += 1
+ if object.is_a? Puppet::TransBucket
+ buckets << object
+ else
+ objects << object
+ if object.file == :funtest
+ found << object
+ end
end
+ end
+ }
- objects = []
- buckets = []
- found = []
-
- count = 0
- assert_nothing_raised {
- top.delve do |object|
- count += 1
- if object.is_a? Puppet::TransBucket
- buckets << object
- else
- objects << object
- if object.file == :funtest
- found << object
- end
- end
- end
- }
-
- top.flatten.each do |obj|
- assert(objects.include?(obj), "Missing obj #{obj.type}[#{obj.name}]")
- end
+ top.flatten.each do |obj|
+ assert(objects.include?(obj), "Missing obj #{obj.type}[#{obj.name}]")
+ end
- assert_equal(
- found.length,
- top.flatten.find_all { |o| o.file == :funtest }.length,
+ assert_equal(
+ found.length,
+ top.flatten.find_all { |o| o.file == :funtest }.length,
- "Found incorrect number of objects")
- end
+ "Found incorrect number of objects")
+ end
end
diff --git a/test/lib/puppettest.rb b/test/lib/puppettest.rb
index c8a7626..e31a319 100755
--- a/test/lib/puppettest.rb
+++ b/test/lib/puppettest.rb
@@ -9,12 +9,12 @@ require 'puppet'
# include any gems in vendor/gems
Dir["#{mainlib}/../vendor/gems/**"].each do |path|
- libpath = File.join(path, "lib")
- if File.directory?(libpath)
- $LOAD_PATH.unshift(libpath)
- else
- $LOAD_PATH.unshift(path)
- end
+ libpath = File.join(path, "lib")
+ if File.directory?(libpath)
+ $LOAD_PATH.unshift(libpath)
+ else
+ $LOAD_PATH.unshift(path)
+ end
end
require 'mocha'
@@ -22,311 +22,311 @@ require 'mocha'
# Only load the test/unit class if we're not in the spec directory.
# Else we get the bogus 'no tests, no failures' message.
unless Dir.getwd =~ /spec/
- require 'test/unit'
+ require 'test/unit'
end
# Yay; hackish but it works
if ARGV.include?("-d")
- ARGV.delete("-d")
- $console = true
+ ARGV.delete("-d")
+ $console = true
end
# 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
+ 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
+ self.class_eval { public(*saved_private_instance_methods) }
+ yield
+ self.class_eval { private(*saved_private_instance_methods) }
+ end
end
module PuppetTest
- # These need to be here for when rspec tests use these
- # support methods.
- @@tmpfiles = []
-
- # Munge cli arguments, so we can enable debugging if we want
- # and so we can run just specific methods.
- def self.munge_argv
- require 'getoptlong'
-
-
- result = GetoptLong.new(
-
- [ "--debug", "-d", GetoptLong::NO_ARGUMENT ],
- [ "--resolve", "-r", GetoptLong::REQUIRED_ARGUMENT ],
- [ "-n", GetoptLong::REQUIRED_ARGUMENT ],
-
- [ "--help", "-h", GetoptLong::NO_ARGUMENT ]
- )
-
- usage = "USAGE: TESTOPTS='[-n <method> -n <method> ...] [-d]' rake [target] [target] ..."
-
- opts = []
-
- dir = method = nil
- result.each { |opt,arg|
- case opt
- when "--resolve"
- dir, method = arg.split(",")
- when "--debug"
- $puppet_debug = true
- Puppet::Util::Log.level = :debug
- Puppet::Util::Log.newdestination(:console)
- when "--help"
- puts usage
- exit
- else
- opts << opt << arg
- end
- }
- suites = nil
-
- args = ARGV.dup
-
- # Reset the options, so the test suite can deal with them (this is
- # what makes things like '-n' work).
- opts.each { |o| ARGV << o }
-
- args
+ # These need to be here for when rspec tests use these
+ # support methods.
+ @@tmpfiles = []
+
+ # Munge cli arguments, so we can enable debugging if we want
+ # and so we can run just specific methods.
+ def self.munge_argv
+ require 'getoptlong'
+
+
+ result = GetoptLong.new(
+
+ [ "--debug", "-d", GetoptLong::NO_ARGUMENT ],
+ [ "--resolve", "-r", GetoptLong::REQUIRED_ARGUMENT ],
+ [ "-n", GetoptLong::REQUIRED_ARGUMENT ],
+
+ [ "--help", "-h", GetoptLong::NO_ARGUMENT ]
+ )
+
+ usage = "USAGE: TESTOPTS='[-n <method> -n <method> ...] [-d]' rake [target] [target] ..."
+
+ opts = []
+
+ dir = method = nil
+ result.each { |opt,arg|
+ case opt
+ when "--resolve"
+ dir, method = arg.split(",")
+ when "--debug"
+ $puppet_debug = true
+ Puppet::Util::Log.level = :debug
+ Puppet::Util::Log.newdestination(:console)
+ when "--help"
+ puts usage
+ exit
+ else
+ opts << opt << arg
+ end
+ }
+ suites = nil
+
+ args = ARGV.dup
+
+ # Reset the options, so the test suite can deal with them (this is
+ # what makes things like '-n' work).
+ opts.each { |o| ARGV << o }
+
+ args
+ end
+
+ # Find the root of the Puppet tree; this is not the test directory, but
+ # the parent of that dir.
+ def basedir(*list)
+ unless defined?(@@basedir)
+ Dir.chdir(File.dirname(__FILE__)) do
+ @@basedir = File.dirname(File.dirname(Dir.getwd))
+ end
end
-
- # Find the root of the Puppet tree; this is not the test directory, but
- # the parent of that dir.
- def basedir(*list)
- unless defined?(@@basedir)
- Dir.chdir(File.dirname(__FILE__)) do
- @@basedir = File.dirname(File.dirname(Dir.getwd))
- end
- end
- if list.empty?
- @@basedir
- else
- File.join(@@basedir, *list)
- end
+ if list.empty?
+ @@basedir
+ else
+ File.join(@@basedir, *list)
end
+ end
- def datadir(*list)
- File.join(basedir, "test", "data", *list)
- end
+ def datadir(*list)
+ File.join(basedir, "test", "data", *list)
+ end
- def exampledir(*args)
- @@exampledir = File.join(basedir, "examples") unless defined?(@@exampledir)
+ def exampledir(*args)
+ @@exampledir = File.join(basedir, "examples") unless defined?(@@exampledir)
- if args.empty?
- return @@exampledir
- else
- return File.join(@@exampledir, *args)
- end
+ if args.empty?
+ return @@exampledir
+ else
+ return File.join(@@exampledir, *args)
end
+ end
- module_function :basedir, :datadir, :exampledir
-
- def cleanup(&block)
- @@cleaners << block
- end
+ module_function :basedir, :datadir, :exampledir
- # Rails clobbers RUBYLIB, thanks
- def libsetup
- curlibs = ENV["RUBYLIB"].split(":")
- $LOAD_PATH.reject do |dir| dir =~ /^\/usr/ end.each do |dir|
- curlibs << dir unless curlibs.include?(dir)
- end
+ def cleanup(&block)
+ @@cleaners << block
+ end
- ENV["RUBYLIB"] = curlibs.join(":")
+ # Rails clobbers RUBYLIB, thanks
+ def libsetup
+ curlibs = ENV["RUBYLIB"].split(":")
+ $LOAD_PATH.reject do |dir| dir =~ /^\/usr/ end.each do |dir|
+ curlibs << dir unless curlibs.include?(dir)
end
- def logcollector
- collector = []
- Puppet::Util::Log.newdestination(collector)
- cleanup do
- Puppet::Util::Log.close(collector)
- end
- collector
- end
+ ENV["RUBYLIB"] = curlibs.join(":")
+ end
- def rake?
- $0 =~ /test_loader/
+ def logcollector
+ collector = []
+ Puppet::Util::Log.newdestination(collector)
+ cleanup do
+ Puppet::Util::Log.close(collector)
+ end
+ collector
+ end
+
+ def rake?
+ $0 =~ /test_loader/
+ end
+
+ # Redirect stdout and stderr
+ def redirect
+ @stderr = tempfile
+ @stdout = tempfile
+ $stderr = File.open(@stderr, "w")
+ $stdout = File.open(@stdout, "w")
+
+ cleanup do
+ $stderr = STDERR
+ $stdout = STDOUT
end
+ end
- # Redirect stdout and stderr
- def redirect
- @stderr = tempfile
- @stdout = tempfile
- $stderr = File.open(@stderr, "w")
- $stdout = File.open(@stdout, "w")
-
- cleanup do
- $stderr = STDERR
- $stdout = STDOUT
- end
+ def setup
+ ENV["PATH"] += File::PATH_SEPARATOR + "/usr/sbin" unless ENV["PATH"].split(File::PATH_SEPARATOR).include?("/usr/sbin")
+ @memoryatstart = Puppet::Util.memory
+ if defined?(@@testcount)
+ @@testcount += 1
+ else
+ @@testcount = 0
end
- def setup
- ENV["PATH"] += File::PATH_SEPARATOR + "/usr/sbin" unless ENV["PATH"].split(File::PATH_SEPARATOR).include?("/usr/sbin")
- @memoryatstart = Puppet::Util.memory
- if defined?(@@testcount)
- @@testcount += 1
- else
- @@testcount = 0
- end
+ @configpath = File.join(
+ tmpdir,
- @configpath = File.join(
- tmpdir,
+ "configdir" + @@testcount.to_s + "/"
+ )
- "configdir" + @@testcount.to_s + "/"
- )
+ unless defined? $user and $group
+ $user = nonrootuser.uid.to_s
+ $group = nonrootgroup.gid.to_s
+ end
- unless defined? $user and $group
- $user = nonrootuser.uid.to_s
- $group = nonrootgroup.gid.to_s
- end
+ Puppet.settings.clear
+ Puppet[:user] = $user
+ Puppet[:group] = $group
- Puppet.settings.clear
- Puppet[:user] = $user
- Puppet[:group] = $group
+ Puppet[:confdir] = @configpath
+ Puppet[:vardir] = @configpath
- Puppet[:confdir] = @configpath
- Puppet[:vardir] = @configpath
+ Dir.mkdir(@configpath) unless File.exists?(@configpath)
- Dir.mkdir(@configpath) unless File.exists?(@configpath)
+ @@tmpfiles << @configpath << tmpdir
+ @@tmppids = []
- @@tmpfiles << @configpath << tmpdir
- @@tmppids = []
+ @@cleaners = []
- @@cleaners = []
+ @logs = []
- @logs = []
+ # If we're running under rake, then disable debugging and such.
+ #if rake? or ! Puppet[:debug]
+ #if defined?($puppet_debug) or ! rake?
+ Puppet[:color] = false if textmate?
+ Puppet::Util::Log.newdestination(@logs)
+ if defined? $console
+ Puppet.info @method_name
+ Puppet::Util::Log.newdestination(:console)
+ Puppet[:trace] = true
+ end
+ Puppet::Util::Log.level = :debug
+ #$VERBOSE = 1
+ #else
+ # Puppet::Util::Log.close
+ # Puppet::Util::Log.newdestination(@logs)
+ # Puppet[:httplog] = tempfile
+ #end
- # If we're running under rake, then disable debugging and such.
- #if rake? or ! Puppet[:debug]
- #if defined?($puppet_debug) or ! rake?
- Puppet[:color] = false if textmate?
- Puppet::Util::Log.newdestination(@logs)
- if defined? $console
- Puppet.info @method_name
- Puppet::Util::Log.newdestination(:console)
- Puppet[:trace] = true
- end
- Puppet::Util::Log.level = :debug
- #$VERBOSE = 1
- #else
- # Puppet::Util::Log.close
- # Puppet::Util::Log.newdestination(@logs)
- # Puppet[:httplog] = tempfile
- #end
+ Puppet[:ignoreschedules] = true
- Puppet[:ignoreschedules] = true
+ #@start = Time.now
- #@start = Time.now
+ #Facter.stubs(:value).returns "stubbed_value"
+ #Facter.stubs(:to_hash).returns({})
+ end
- #Facter.stubs(:value).returns "stubbed_value"
- #Facter.stubs(:to_hash).returns({})
+ def tempfile
+ if defined?(@@tmpfilenum)
+ @@tmpfilenum += 1
+ else
+ @@tmpfilenum = 1
end
- def tempfile
- if defined?(@@tmpfilenum)
- @@tmpfilenum += 1
+ f = File.join(self.tmpdir, "tempfile_" + @@tmpfilenum.to_s)
+ @@tmpfiles ||= []
+ @@tmpfiles << f
+ f
+ end
+
+ def textmate?
+ !!ENV["TM_FILENAME"]
+ end
+
+ def tstdir
+ dir = tempfile
+ Dir.mkdir(dir)
+ dir
+ end
+
+ def tmpdir
+ unless @tmpdir
+ @tmpdir = case Facter["operatingsystem"].value
+ when "Darwin"; "/private/tmp"
+ when "SunOS"; "/var/tmp"
else
- @@tmpfilenum = 1
- end
-
- f = File.join(self.tmpdir, "tempfile_" + @@tmpfilenum.to_s)
- @@tmpfiles ||= []
- @@tmpfiles << f
- f
- end
-
- def textmate?
- !!ENV["TM_FILENAME"]
- end
-
- def tstdir
- dir = tempfile
- Dir.mkdir(dir)
- dir
- end
-
- def tmpdir
- unless @tmpdir
- @tmpdir = case Facter["operatingsystem"].value
- when "Darwin"; "/private/tmp"
- when "SunOS"; "/var/tmp"
- else
- "/tmp"
- end
-
-
- @tmpdir = File.join(@tmpdir, "puppettesting#{Process.pid}")
-
- unless File.exists?(@tmpdir)
- FileUtils.mkdir_p(@tmpdir)
- File.chmod(01777, @tmpdir)
- end
- end
- @tmpdir
- end
-
- def remove_tmp_files
- @@tmpfiles.each { |file|
- unless file =~ /tmp/
- puts "Not deleting tmpfile #{file}"
- next
+ "/tmp"
end
- if FileTest.exists?(file)
- system("chmod -R 755 #{file}")
- system("rm -rf #{file}")
- end
- }
- @@tmpfiles.clear
- end
-
- def teardown
- #@stop = Time.now
- #File.open("/tmp/test_times.log", ::File::WRONLY|::File::CREAT|::File::APPEND) { |f| f.puts "%0.4f %s %s" % [@stop - @start, @method_name, self.class] }
- @@cleaners.each { |cleaner| cleaner.call }
-
- remove_tmp_files
-
- @@tmppids.each { |pid|
- %x{kill -INT #{pid} 2>/dev/null}
- }
-
- @@tmppids.clear
- Puppet::Util::Storage.clear
- Puppet.clear
- Puppet.settings.clear
- Puppet::Util::Cacher.expire
- @memoryatend = Puppet::Util.memory
- diff = @memoryatend - @memoryatstart
+ @tmpdir = File.join(@tmpdir, "puppettesting#{Process.pid}")
- Puppet.info "#{self.class}##{@method_name} memory growth (#{@memoryatstart} to #{@memoryatend}): #{diff}" if diff > 1000
-
- # reset all of the logs
- Puppet::Util::Log.close_all
- @logs.clear
-
- # Just in case there are processes waiting to die...
- require 'timeout'
-
- begin
- Timeout::timeout(5) do
- Process.waitall
- end
- rescue Timeout::Error
- # just move on
- end
+ unless File.exists?(@tmpdir)
+ FileUtils.mkdir_p(@tmpdir)
+ File.chmod(01777, @tmpdir)
+ end
end
-
- def logstore
- @logs = []
- Puppet::Util::Log.newdestination(@logs)
+ @tmpdir
+ end
+
+ def remove_tmp_files
+ @@tmpfiles.each { |file|
+ unless file =~ /tmp/
+ puts "Not deleting tmpfile #{file}"
+ next
+ end
+ if FileTest.exists?(file)
+ system("chmod -R 755 #{file}")
+ system("rm -rf #{file}")
+ end
+ }
+ @@tmpfiles.clear
+ end
+
+ def teardown
+ #@stop = Time.now
+ #File.open("/tmp/test_times.log", ::File::WRONLY|::File::CREAT|::File::APPEND) { |f| f.puts "%0.4f %s %s" % [@stop - @start, @method_name, self.class] }
+ @@cleaners.each { |cleaner| cleaner.call }
+
+ remove_tmp_files
+
+ @@tmppids.each { |pid|
+ %x{kill -INT #{pid} 2>/dev/null}
+ }
+
+ @@tmppids.clear
+
+ Puppet::Util::Storage.clear
+ Puppet.clear
+ Puppet.settings.clear
+ Puppet::Util::Cacher.expire
+
+ @memoryatend = Puppet::Util.memory
+ diff = @memoryatend - @memoryatstart
+
+ Puppet.info "#{self.class}##{@method_name} memory growth (#{@memoryatstart} to #{@memoryatend}): #{diff}" if diff > 1000
+
+ # reset all of the logs
+ Puppet::Util::Log.close_all
+ @logs.clear
+
+ # Just in case there are processes waiting to die...
+ require 'timeout'
+
+ begin
+ Timeout::timeout(5) do
+ Process.waitall
+ end
+ rescue Timeout::Error
+ # just move on
end
+ end
+
+ def logstore
+ @logs = []
+ Puppet::Util::Log.newdestination(@logs)
+ end
end
require 'puppettest/support'
diff --git a/test/lib/puppettest/certificates.rb b/test/lib/puppettest/certificates.rb
index 501e36a..34da6da 100644
--- a/test/lib/puppettest/certificates.rb
+++ b/test/lib/puppettest/certificates.rb
@@ -3,56 +3,56 @@
require 'puppettest'
module PuppetTest::Certificates
- include PuppetTest
-
- def mkPassFile()
- keyfile = File.join(@dir, "tmpkeyfile")
- @@tmpfiles << keyfile
- system("mkdir -p #{@dir}") unless FileTest.exists?(@dir)
- File.open(keyfile, "w", 0600) { |f|
- f.print "as;dklj23rlkjzdflij23wr"
- }
-
- keyfile
- end
-
- def mkCA
- ca = nil
- assert_nothing_raised {
- ca = Puppet::SSLCertificates::CA.new
- }
-
- ca
- end
-
- def mkStore(ca)
- store = OpenSSL::X509::Store.new
- store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
- store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK
- store.add_cert(ca.cert)
- store.add_crl(ca.crl)
- store
- end
-
- def mkcert(hostname)
- cert = nil
- assert_nothing_raised {
- cert = Puppet::SSLCertificates::Certificate.new(:name => hostname)
- cert.mkcsr
- }
-
- cert
- end
-
- def mksignedcert(ca = nil, hostname = nil)
- ca ||= mkCA()
- hostname ||= "ttltest.example.com"
-
- cert = nil
- assert_nothing_raised {
- cert, cacert = ca.sign(mkcert(hostname).mkcsr)
- }
- cert
- end
+ include PuppetTest
+
+ def mkPassFile()
+ keyfile = File.join(@dir, "tmpkeyfile")
+ @@tmpfiles << keyfile
+ system("mkdir -p #{@dir}") unless FileTest.exists?(@dir)
+ File.open(keyfile, "w", 0600) { |f|
+ f.print "as;dklj23rlkjzdflij23wr"
+ }
+
+ keyfile
+ end
+
+ def mkCA
+ ca = nil
+ assert_nothing_raised {
+ ca = Puppet::SSLCertificates::CA.new
+ }
+
+ ca
+ end
+
+ def mkStore(ca)
+ store = OpenSSL::X509::Store.new
+ store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
+ store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK
+ store.add_cert(ca.cert)
+ store.add_crl(ca.crl)
+ store
+ end
+
+ def mkcert(hostname)
+ cert = nil
+ assert_nothing_raised {
+ cert = Puppet::SSLCertificates::Certificate.new(:name => hostname)
+ cert.mkcsr
+ }
+
+ cert
+ end
+
+ def mksignedcert(ca = nil, hostname = nil)
+ ca ||= mkCA()
+ hostname ||= "ttltest.example.com"
+
+ cert = nil
+ assert_nothing_raised {
+ cert, cacert = ca.sign(mkcert(hostname).mkcsr)
+ }
+ cert
+ end
end
diff --git a/test/lib/puppettest/exetest.rb b/test/lib/puppettest/exetest.rb
index 67b4b81..5a2248d 100644
--- a/test/lib/puppettest/exetest.rb
+++ b/test/lib/puppettest/exetest.rb
@@ -1,125 +1,125 @@
require 'puppettest/servertest'
module PuppetTest::ExeTest
- include PuppetTest::ServerTest
-
- def setup
- super
- setbindir
- setlibdir
- end
-
- def bindir
- File.join(basedir, "bin")
+ include PuppetTest::ServerTest
+
+ def setup
+ super
+ setbindir
+ setlibdir
+ end
+
+ def bindir
+ File.join(basedir, "bin")
+ end
+
+ def sbindir
+ File.join(basedir, "sbin")
+ end
+
+ def setbindir
+ ENV["PATH"] = [bindir, ENV["PATH"]].join(":") unless ENV["PATH"].split(":").include?(bindir)
+ ENV["PATH"] = [sbindir, ENV["PATH"]].join(":") unless ENV["PATH"].split(":").include?(sbindir)
+ end
+
+ def setlibdir
+ ENV["RUBYLIB"] = $LOAD_PATH.find_all { |dir|
+ dir =~ /puppet/ or dir =~ /\.\./
+ }.join(":")
+ end
+
+ # Run a ruby command. This explicitly uses ruby to run stuff, since we
+ # don't necessarily know where our ruby binary is, dernit.
+ # Currently unused, because I couldn't get it to work.
+ def rundaemon(*cmd)
+ @ruby ||= %x{which ruby}.chomp
+ cmd = cmd.unshift(@ruby).join(" ")
+
+ out = nil
+ Dir.chdir(bindir) {
+ out = %x{#{@ruby} #{cmd}}
+ }
+ out
+ end
+
+ def startmasterd(args = "")
+ output = nil
+
+ manifest = mktestmanifest
+ args += " --manifest #{manifest}"
+ args += " --confdir #{Puppet[:confdir]}"
+ args += " --rundir #{File.join(Puppet[:vardir], "run")}"
+ args += " --vardir #{Puppet[:vardir]}"
+ args += " --certdnsnames #{Puppet[:certdnsnames]}"
+ args += " --masterport #{@@port}"
+ args += " --user #{Puppet::Util::SUIDManager.uid}"
+ args += " --group #{Puppet::Util::SUIDManager.gid}"
+ args += " --autosign true"
+
+ #if Puppet[:debug]
+ # args += " --debug"
+ #end
+
+ cmd = "puppetmasterd #{args}"
+
+
+ assert_nothing_raised {
+ output = %x{#{cmd}}.chomp
+ }
+ assert_equal("", output, "Puppetmasterd produced output #{output}")
+ assert($CHILD_STATUS == 0, "Puppetmasterd exit status was #{$CHILD_STATUS}")
+ sleep(1)
+
+ cleanup do
+ stopmasterd
+ sleep(1)
end
- def sbindir
- File.join(basedir, "sbin")
- end
+ manifest
+ end
- def setbindir
- ENV["PATH"] = [bindir, ENV["PATH"]].join(":") unless ENV["PATH"].split(":").include?(bindir)
- ENV["PATH"] = [sbindir, ENV["PATH"]].join(":") unless ENV["PATH"].split(":").include?(sbindir)
- end
+ def stopmasterd(running = true)
+ ps = Facter["ps"].value || "ps -ef"
- def setlibdir
- ENV["RUBYLIB"] = $LOAD_PATH.find_all { |dir|
- dir =~ /puppet/ or dir =~ /\.\./
- }.join(":")
- end
+ pidfile = File.join(Puppet[:vardir], "run", "puppetmasterd.pid")
- # Run a ruby command. This explicitly uses ruby to run stuff, since we
- # don't necessarily know where our ruby binary is, dernit.
- # Currently unused, because I couldn't get it to work.
- def rundaemon(*cmd)
- @ruby ||= %x{which ruby}.chomp
- cmd = cmd.unshift(@ruby).join(" ")
-
- out = nil
- Dir.chdir(bindir) {
- out = %x{#{@ruby} #{cmd}}
- }
- out
+ pid = nil
+ if FileTest.exists?(pidfile)
+ pid = File.read(pidfile).chomp.to_i
+ File.unlink(pidfile)
end
- def startmasterd(args = "")
- output = nil
-
- manifest = mktestmanifest
- args += " --manifest #{manifest}"
- args += " --confdir #{Puppet[:confdir]}"
- args += " --rundir #{File.join(Puppet[:vardir], "run")}"
- args += " --vardir #{Puppet[:vardir]}"
- args += " --certdnsnames #{Puppet[:certdnsnames]}"
- args += " --masterport #{@@port}"
- args += " --user #{Puppet::Util::SUIDManager.uid}"
- args += " --group #{Puppet::Util::SUIDManager.gid}"
- args += " --autosign true"
-
- #if Puppet[:debug]
- # args += " --debug"
- #end
-
- cmd = "puppetmasterd #{args}"
-
-
- assert_nothing_raised {
- output = %x{#{cmd}}.chomp
- }
- assert_equal("", output, "Puppetmasterd produced output #{output}")
- assert($CHILD_STATUS == 0, "Puppetmasterd exit status was #{$CHILD_STATUS}")
- sleep(1)
-
- cleanup do
- stopmasterd
- sleep(1)
+ return unless running
+ if running or pid
+ runningpid = nil
+ %x{#{ps}}.chomp.split(/\n/).each { |line|
+ if line =~ /ruby.+puppetmasterd/
+ next if line =~ /\.rb/ # skip the test script itself
+ next if line =~ /^puppet/ # skip masters running as 'puppet'
+ ary = line.sub(/^\s+/, '').split(/\s+/)
+ pid = ary[1].to_i
end
+ }
- manifest
end
- def stopmasterd(running = true)
- ps = Facter["ps"].value || "ps -ef"
-
- pidfile = File.join(Puppet[:vardir], "run", "puppetmasterd.pid")
-
- pid = nil
- if FileTest.exists?(pidfile)
- pid = File.read(pidfile).chomp.to_i
- File.unlink(pidfile)
- end
-
- return unless running
- if running or pid
- runningpid = nil
- %x{#{ps}}.chomp.split(/\n/).each { |line|
- if line =~ /ruby.+puppetmasterd/
- next if line =~ /\.rb/ # skip the test script itself
- next if line =~ /^puppet/ # skip masters running as 'puppet'
- ary = line.sub(/^\s+/, '').split(/\s+/)
- pid = ary[1].to_i
- end
- }
-
- end
-
- # we default to mandating that it's running, but teardown
- # doesn't require that
- if pid
- if pid == $PID
- raise Puppet::Error, "Tried to kill own pid"
- end
- begin
- Process.kill(:INT, pid)
- rescue
- # ignore it
- end
- end
+ # we default to mandating that it's running, but teardown
+ # doesn't require that
+ if pid
+ if pid == $PID
+ raise Puppet::Error, "Tried to kill own pid"
+ end
+ begin
+ Process.kill(:INT, pid)
+ rescue
+ # ignore it
+ end
end
+ end
- def teardown
- stopmasterd(false)
- super
- end
+ def teardown
+ stopmasterd(false)
+ super
+ end
end
diff --git a/test/lib/puppettest/fakes.rb b/test/lib/puppettest/fakes.rb
index a05d0f5..aaa7110 100644
--- a/test/lib/puppettest/fakes.rb
+++ b/test/lib/puppettest/fakes.rb
@@ -1,199 +1,199 @@
require 'puppettest'
module PuppetTest
- # A baseclass for the faketypes.
- class FakeModel
- include Puppet::Util
- class << self
- attr_accessor :name, :realresource
- @name = :fakeresource
- end
-
- def self.key_attributes
- @realresource.key_attributes
- end
+ # A baseclass for the faketypes.
+ class FakeModel
+ include Puppet::Util
+ class << self
+ attr_accessor :name, :realresource
+ @name = :fakeresource
+ end
- def self.validproperties
- Puppet::Type.type(@name).validproperties
- end
+ def self.key_attributes
+ @realresource.key_attributes
+ end
- def self.validproperty?(name)
- Puppet::Type.type(@name).validproperty?(name)
- end
+ def self.validproperties
+ Puppet::Type.type(@name).validproperties
+ end
- def self.to_s
- "Fake#{@name.to_s.capitalize}"
- end
+ def self.validproperty?(name)
+ Puppet::Type.type(@name).validproperty?(name)
+ end
- def [](param)
- if @realresource.attrtype(param) == :property
- @is[param]
- else
- @params[param]
- end
- end
+ def self.to_s
+ "Fake#{@name.to_s.capitalize}"
+ end
- def []=(param, value)
- param = symbolize(param)
- raise Puppet::DevError, "Invalid attribute #{param} for #{@realresource.name}" unless @realresource.valid_parameter?(param)
- if @realresource.attrtype(param) == :property
- @should[param] = value
- else
- @params[param] = value
- end
- end
+ def [](param)
+ if @realresource.attrtype(param) == :property
+ @is[param]
+ else
+ @params[param]
+ end
+ end
- def initialize(name)
- @realresource = Puppet::Type.type(self.class.name)
- raise "Could not find type #{self.class.name}" unless @realresource
- @is = {}
- @should = {}
- @params = {}
- self[@realresource.key_attributes.first] = name
- end
+ def []=(param, value)
+ param = symbolize(param)
+ raise Puppet::DevError, "Invalid attribute #{param} for #{@realresource.name}" unless @realresource.valid_parameter?(param)
+ if @realresource.attrtype(param) == :property
+ @should[param] = value
+ else
+ @params[param] = value
+ end
+ end
- def inspect
- "#{self.class.to_s.sub(/.+::/, '')}(#{super()})"
- end
+ def initialize(name)
+ @realresource = Puppet::Type.type(self.class.name)
+ raise "Could not find type #{self.class.name}" unless @realresource
+ @is = {}
+ @should = {}
+ @params = {}
+ self[@realresource.key_attributes.first] = name
+ end
- def is(param)
- @is[param]
- end
+ def inspect
+ "#{self.class.to_s.sub(/.+::/, '')}(#{super()})"
+ end
- def should(param)
- @should[param]
- end
+ def is(param)
+ @is[param]
+ end
- def to_hash
- hash = @params.dup
- [@is, @should].each do |h|
- h.each do |p, v|
- hash[p] = v
- end
- end
- hash
- end
+ def should(param)
+ @should[param]
+ end
- def name
- self[:name]
+ def to_hash
+ hash = @params.dup
+ [@is, @should].each do |h|
+ h.each do |p, v|
+ hash[p] = v
end
+ end
+ hash
end
- class FakeProvider
- attr_accessor :resource
- class << self
- attr_accessor :name, :resource_type, :methods
- end
+ def name
+ self[:name]
+ end
+ end
- # A very low number, so these never show up as defaults via the standard
- # algorithms.
- def self.defaultnum
- -50
- end
+ class FakeProvider
+ attr_accessor :resource
+ class << self
+ attr_accessor :name, :resource_type, :methods
+ end
- # Set up methods to fake things
- def self.apimethods(*ary)
- @resource_type.validproperties.each do |property|
- ary << property unless ary.include? property
- end
- attr_accessor(*ary)
+ # A very low number, so these never show up as defaults via the standard
+ # algorithms.
+ def self.defaultnum
+ -50
+ end
- @methods = ary
- end
+ # Set up methods to fake things
+ def self.apimethods(*ary)
+ @resource_type.validproperties.each do |property|
+ ary << property unless ary.include? property
+ end
+ attr_accessor(*ary)
- def self.default?
- false
- end
+ @methods = ary
+ end
- def self.initvars
- @calls = Hash.new do |hash, key|
- hash[key] = 0
- end
- end
+ def self.default?
+ false
+ end
- def self.source
- self.name
- end
+ def self.initvars
+ @calls = Hash.new do |hash, key|
+ hash[key] = 0
+ end
+ end
- def self.supports_parameter?(param)
- true
- end
+ def self.source
+ self.name
+ end
- def self.suitable?
- true
- end
+ def self.supports_parameter?(param)
+ true
+ end
- def clear
- @resource = nil
- end
+ def self.suitable?
+ true
+ end
- def initialize(resource)
- @resource = resource
- end
+ def clear
+ @resource = nil
+ end
- def properties
- self.class.resource_type.validproperties.inject({}) do |props, name|
- props[name] = self.send(name) || :absent
- props
- end
- end
+ def initialize(resource)
+ @resource = resource
end
- class FakeParsedProvider < FakeProvider
- def hash
- ret = {}
- instance_variables.each do |v|
- v = v.sub("@", '')
- if val = self.send(v)
- ret[v.intern] = val
- end
- end
+ def properties
+ self.class.resource_type.validproperties.inject({}) do |props, name|
+ props[name] = self.send(name) || :absent
+ props
+ end
+ end
+ end
- ret
+ class FakeParsedProvider < FakeProvider
+ def hash
+ ret = {}
+ instance_variables.each do |v|
+ v = v.sub("@", '')
+ if val = self.send(v)
+ ret[v.intern] = val
end
+ end
- def store(hash)
- hash.each do |n, v|
- method = n.to_s + "="
- send(method, v) if respond_to? method
- end
- end
+ ret
end
- @@fakeresources = {}
- @@fakeproviders = {}
+ def store(hash)
+ hash.each do |n, v|
+ method = n.to_s + "="
+ send(method, v) if respond_to? method
+ end
+ end
+ end
- def fakeresource(type, name, options = {})
- type = type.intern if type.is_a? String
- unless @@fakeresources.include? type
- @@fakeresources[type] = Class.new(FakeModel)
- @@fakeresources[type].name = type
+ @@fakeresources = {}
+ @@fakeproviders = {}
- resource = Puppet::Type.type(type)
- raise("Could not find type #{type}") unless resource
- @@fakeresources[type].realresource = resource
- end
+ def fakeresource(type, name, options = {})
+ type = type.intern if type.is_a? String
+ unless @@fakeresources.include? type
+ @@fakeresources[type] = Class.new(FakeModel)
+ @@fakeresources[type].name = type
- obj = @@fakeresources[type].new(name)
- options.each do |name, val|
- obj[name] = val
- end
- obj
+ resource = Puppet::Type.type(type)
+ raise("Could not find type #{type}") unless resource
+ @@fakeresources[type].realresource = resource
end
- module_function :fakeresource
+ obj = @@fakeresources[type].new(name)
+ options.each do |name, val|
+ obj[name] = val
+ end
+ obj
+ end
- def fakeprovider(type, resource)
- type = type.intern if type.is_a? String
- unless @@fakeproviders.include? type
- @@fakeproviders[type] = Class.new(FakeModel) do
- @name = type
- end
- end
+ module_function :fakeresource
- @@fakeproviders[type].new(resource)
+ def fakeprovider(type, resource)
+ type = type.intern if type.is_a? String
+ unless @@fakeproviders.include? type
+ @@fakeproviders[type] = Class.new(FakeModel) do
+ @name = type
+ end
end
- module_function :fakeprovider
+ @@fakeproviders[type].new(resource)
+ end
+
+ module_function :fakeprovider
end
diff --git a/test/lib/puppettest/fileparsing.rb b/test/lib/puppettest/fileparsing.rb
index 11de002..914c4bc 100644
--- a/test/lib/puppettest/fileparsing.rb
+++ b/test/lib/puppettest/fileparsing.rb
@@ -1,26 +1,26 @@
module PuppetTest::FileParsing
- # Run an isomorphism test on our parsing process.
- def fakedataparse(*files)
- files.each do |file|
- @provider.stubs(:default_target).returns(file)
+ # Run an isomorphism test on our parsing process.
+ def fakedataparse(*files)
+ files.each do |file|
+ @provider.stubs(:default_target).returns(file)
- @provider.prefetch
+ @provider.prefetch
- text = @provider.to_file(@provider.target_records(file))
- text.gsub!(/^# HEADER.+\n/, '')
+ text = @provider.to_file(@provider.target_records(file))
+ text.gsub!(/^# HEADER.+\n/, '')
- yield if block_given?
+ yield if block_given?
- oldlines = File.readlines(file)
- newlines = text.chomp.split "\n"
- oldlines.zip(newlines).each do |old, new|
- if self.is_a?(Test::Unit::TestCase)
- assert_equal(old.chomp.gsub(/\s+/, ''), new.gsub(/\s+/, ''), "File was not written back out correctly")
- else
- new.gsub(/\s+/, '').should == old.chomp.gsub(/\s+/, '')
- end
- end
+ oldlines = File.readlines(file)
+ newlines = text.chomp.split "\n"
+ oldlines.zip(newlines).each do |old, new|
+ if self.is_a?(Test::Unit::TestCase)
+ assert_equal(old.chomp.gsub(/\s+/, ''), new.gsub(/\s+/, ''), "File was not written back out correctly")
+ else
+ new.gsub(/\s+/, '').should == old.chomp.gsub(/\s+/, '')
end
+ end
end
+ end
end
diff --git a/test/lib/puppettest/filetesting.rb b/test/lib/puppettest/filetesting.rb
index 79981ce..08babfe 100644
--- a/test/lib/puppettest/filetesting.rb
+++ b/test/lib/puppettest/filetesting.rb
@@ -1,221 +1,221 @@
require 'puppettest'
module PuppetTest::FileTesting
- include PuppetTest
- def cycle(comp)
- trans = nil
- assert_nothing_raised {
- trans = comp.evaluate
- }
- assert_nothing_raised {
- trans.evaluate
- }
+ include PuppetTest
+ def cycle(comp)
+ trans = nil
+ assert_nothing_raised {
+ trans = comp.evaluate
+ }
+ assert_nothing_raised {
+ trans.evaluate
+ }
+ end
+
+ def randlist(list)
+ num = rand(4)
+ if num == 0
+ num = 1
end
+ set = []
- def randlist(list)
- num = rand(4)
- if num == 0
- num = 1
- end
- set = []
-
- ret = []
- num.times { |index|
- item = list[rand(list.length)]
- redo if set.include?(item)
-
- ret.push item
- }
- ret
- end
+ ret = []
+ num.times { |index|
+ item = list[rand(list.length)]
+ redo if set.include?(item)
- def mkranddirsandfiles(dirs = nil,files = nil,depth = 3)
- return if depth < 0
+ ret.push item
+ }
+ ret
+ end
- dirs ||= %w{This Is A Set Of Directories}
+ def mkranddirsandfiles(dirs = nil,files = nil,depth = 3)
+ return if depth < 0
- files ||= %w{and this is a set of files}
+ dirs ||= %w{This Is A Set Of Directories}
- tfiles = randlist(files)
- tdirs = randlist(dirs)
+ files ||= %w{and this is a set of files}
- tfiles.each { |file|
- File.open(file, "w") { |of|
- 4.times {
- of.puts rand(100)
- }
- }
- }
+ tfiles = randlist(files)
+ tdirs = randlist(dirs)
- tdirs.each { |dir|
- # it shouldn't already exist, but...
- unless FileTest.exists?(dir)
- Dir.mkdir(dir)
- FileUtils.cd(dir) {
- mkranddirsandfiles(dirs,files,depth - 1)
- }
- end
+ tfiles.each { |file|
+ File.open(file, "w") { |of|
+ 4.times {
+ of.puts rand(100)
}
- end
+ }
+ }
- def file_list(dir)
- list = nil
+ tdirs.each { |dir|
+ # it shouldn't already exist, but...
+ unless FileTest.exists?(dir)
+ Dir.mkdir(dir)
FileUtils.cd(dir) {
- list = %x{find . 2>/dev/null}.chomp.split(/\n/)
- }
- list
- end
-
- def assert_trees_equal(fromdir,todir)
- assert(FileTest.directory?(fromdir))
- assert(FileTest.directory?(todir))
-
- # verify the file list is the same
- fromlist = nil
- FileUtils.cd(fromdir) {
- fromlist = %x{find . 2>/dev/null}.chomp.split(/\n/).reject { |file|
- ! FileTest.readable?(file)
- }.sort
- }
- tolist = file_list(todir).sort
-
- fromlist.sort.zip(tolist.sort).each { |a,b|
- assert_equal(a, b, "Fromfile #{a} with length #{fromlist.length} does not match tofile #{b} with length #{tolist.length}")
+ mkranddirsandfiles(dirs,files,depth - 1)
}
- #assert_equal(fromlist,tolist)
-
- # and then do some verification that the files are actually set up
- # the same
- checked = 0
- fromlist.each_with_index { |file,i|
- fromfile = File.join(fromdir,file)
- tofile = File.join(todir,file)
- fromstat = File.stat(fromfile)
- tostat = File.stat(tofile)
- [:ftype,:gid,:mode,:uid].each { |method|
-
- assert_equal(
-
- fromstat.send(method),
-
- tostat.send(method)
- )
-
- next if fromstat.ftype == "directory"
- if checked < 10 and i % 3 == 0
- from = File.open(fromfile) { |f| f.read }
- to = File.open(tofile) { |f| f.read }
-
- assert_equal(from,to)
- checked += 1
- end
- }
- }
- end
-
- def random_files(dir)
- checked = 0
- list = file_list(dir)
- list.reverse.each_with_index { |file,i|
- path = File.join(dir,file)
- stat = File.stat(dir)
- if checked < 10 and (i % 3) == 2
- next unless yield path
- checked += 1
- end
- }
- end
-
- def delete_random_files(dir)
- deleted = []
- random_files(dir) { |file|
- stat = File.stat(file)
- begin
- if stat.ftype == "directory"
- false
- else
- deleted << file
- File.unlink(file)
- true
- end
- rescue => detail
- # we probably won't be able to open our own secured files
- puts detail
- false
- end
- }
-
- deleted
- end
-
- def add_random_files(dir)
- added = []
- random_files(dir) { |file|
- stat = File.stat(file)
- begin
- if stat.ftype == "directory"
- name = File.join(file,"file" + rand(100).to_s)
- File.open(name, "w") { |f|
- f.puts rand(10)
- }
- added << name
- else
- false
- end
- rescue => detail
- # we probably won't be able to open our own secured files
- puts detail
- false
- end
- }
- added
- end
-
- def modify_random_files(dir)
- modded = []
- random_files(dir) { |file|
- stat = File.stat(file)
- begin
- if stat.ftype == "directory"
- false
- else
- File.open(file, "w") { |f|
- f.puts rand(10)
- }
- modded << name
- true
- end
- rescue => detail
- # we probably won't be able to open our own secured files
- puts detail
- false
- end
- }
- modded
- end
-
- def readonly_random_files(dir)
- modded = []
- random_files(dir) { |file|
- stat = File.stat(file)
- begin
- if stat.ftype == "directory"
- File.new(file).chmod(0111)
- else
- File.new(file).chmod(0000)
- end
- modded << file
- rescue => detail
- # we probably won't be able to open our own secured files
- puts detail
- false
- end
- }
- modded
- end
-
- def conffile
- exampledir("root/etc/configfile")
- end
+ end
+ }
+ end
+
+ def file_list(dir)
+ list = nil
+ FileUtils.cd(dir) {
+ list = %x{find . 2>/dev/null}.chomp.split(/\n/)
+ }
+ list
+ end
+
+ def assert_trees_equal(fromdir,todir)
+ assert(FileTest.directory?(fromdir))
+ assert(FileTest.directory?(todir))
+
+ # verify the file list is the same
+ fromlist = nil
+ FileUtils.cd(fromdir) {
+ fromlist = %x{find . 2>/dev/null}.chomp.split(/\n/).reject { |file|
+ ! FileTest.readable?(file)
+ }.sort
+ }
+ tolist = file_list(todir).sort
+
+ fromlist.sort.zip(tolist.sort).each { |a,b|
+ assert_equal(a, b, "Fromfile #{a} with length #{fromlist.length} does not match tofile #{b} with length #{tolist.length}")
+ }
+ #assert_equal(fromlist,tolist)
+
+ # and then do some verification that the files are actually set up
+ # the same
+ checked = 0
+ fromlist.each_with_index { |file,i|
+ fromfile = File.join(fromdir,file)
+ tofile = File.join(todir,file)
+ fromstat = File.stat(fromfile)
+ tostat = File.stat(tofile)
+ [:ftype,:gid,:mode,:uid].each { |method|
+
+ assert_equal(
+
+ fromstat.send(method),
+
+ tostat.send(method)
+ )
+
+ next if fromstat.ftype == "directory"
+ if checked < 10 and i % 3 == 0
+ from = File.open(fromfile) { |f| f.read }
+ to = File.open(tofile) { |f| f.read }
+
+ assert_equal(from,to)
+ checked += 1
+ end
+ }
+ }
+ end
+
+ def random_files(dir)
+ checked = 0
+ list = file_list(dir)
+ list.reverse.each_with_index { |file,i|
+ path = File.join(dir,file)
+ stat = File.stat(dir)
+ if checked < 10 and (i % 3) == 2
+ next unless yield path
+ checked += 1
+ end
+ }
+ end
+
+ def delete_random_files(dir)
+ deleted = []
+ random_files(dir) { |file|
+ stat = File.stat(file)
+ begin
+ if stat.ftype == "directory"
+ false
+ else
+ deleted << file
+ File.unlink(file)
+ true
+ end
+ rescue => detail
+ # we probably won't be able to open our own secured files
+ puts detail
+ false
+ end
+ }
+
+ deleted
+ end
+
+ def add_random_files(dir)
+ added = []
+ random_files(dir) { |file|
+ stat = File.stat(file)
+ begin
+ if stat.ftype == "directory"
+ name = File.join(file,"file" + rand(100).to_s)
+ File.open(name, "w") { |f|
+ f.puts rand(10)
+ }
+ added << name
+ else
+ false
+ end
+ rescue => detail
+ # we probably won't be able to open our own secured files
+ puts detail
+ false
+ end
+ }
+ added
+ end
+
+ def modify_random_files(dir)
+ modded = []
+ random_files(dir) { |file|
+ stat = File.stat(file)
+ begin
+ if stat.ftype == "directory"
+ false
+ else
+ File.open(file, "w") { |f|
+ f.puts rand(10)
+ }
+ modded << name
+ true
+ end
+ rescue => detail
+ # we probably won't be able to open our own secured files
+ puts detail
+ false
+ end
+ }
+ modded
+ end
+
+ def readonly_random_files(dir)
+ modded = []
+ random_files(dir) { |file|
+ stat = File.stat(file)
+ begin
+ if stat.ftype == "directory"
+ File.new(file).chmod(0111)
+ else
+ File.new(file).chmod(0000)
+ end
+ modded << file
+ rescue => detail
+ # we probably won't be able to open our own secured files
+ puts detail
+ false
+ end
+ }
+ modded
+ end
+
+ def conffile
+ exampledir("root/etc/configfile")
+ end
end
diff --git a/test/lib/puppettest/parsertesting.rb b/test/lib/puppettest/parsertesting.rb
index fe85fe9..bd04c1e 100644
--- a/test/lib/puppettest/parsertesting.rb
+++ b/test/lib/puppettest/parsertesting.rb
@@ -2,427 +2,427 @@ require 'puppettest'
require 'puppet/rails'
module PuppetTest::ParserTesting
- include PuppetTest
- AST = Puppet::Parser::AST
+ include PuppetTest
+ AST = Puppet::Parser::AST
- Compiler = Puppet::Parser::Compiler
+ Compiler = Puppet::Parser::Compiler
- # A fake class that we can use for testing evaluation.
- class FakeAST
- attr_writer :evaluate
+ # A fake class that we can use for testing evaluation.
+ class FakeAST
+ attr_writer :evaluate
- def evaluated?
- @evaluated
- end
-
- def evaluate(*args)
- @evaluated = true
- @evaluate
- end
-
- def initialize(val = nil)
- @evaluate = val if val
- end
-
- def reset
- @evaluated = nil
- end
-
- def safeevaluate(*args)
- evaluate
- end
-
- def evaluate_match(othervalue, scope, options={})
- value = evaluate
- othervalue == value
- end
+ def evaluated?
+ @evaluated
end
- def astarray(*args)
- AST::ASTArray.new(
- :children => args
- )
+ def evaluate(*args)
+ @evaluated = true
+ @evaluate
end
- def mkcompiler(parser = nil)
- node = mknode
- Compiler.new(node)
+ def initialize(val = nil)
+ @evaluate = val if val
end
- def mknode(name = nil)
- require 'puppet/node'
- Puppet::Node.new(name || "nodename")
+ def reset
+ @evaluated = nil
end
- def mkparser
- Puppet::Node::Environment.clear
- Puppet::Parser::Parser.new(Puppet::Node::Environment.new)
+ def safeevaluate(*args)
+ evaluate
end
- def mkscope(hash = {})
- parser ||= mkparser
- compiler ||= mkcompiler
- compiler.topscope.source = (parser.find_hostclass("", "") || parser.newclass(""))
-
- raise "Could not find source for scope" unless compiler.topscope.source
- # Make the 'main' stuff
- compiler.send(:evaluate_main)
- compiler.topscope
+ def evaluate_match(othervalue, scope, options={})
+ value = evaluate
+ othervalue == value
end
-
- def classobj(name, hash = {})
- hash[:file] ||= __FILE__
- hash[:line] ||= __LINE__
- hash[:type] ||= name
- AST::HostClass.new(hash)
+ end
+
+ def astarray(*args)
+ AST::ASTArray.new(
+ :children => args
+ )
+ end
+
+ def mkcompiler(parser = nil)
+ node = mknode
+ Compiler.new(node)
+ end
+
+ def mknode(name = nil)
+ require 'puppet/node'
+ Puppet::Node.new(name || "nodename")
+ end
+
+ def mkparser
+ Puppet::Node::Environment.clear
+ Puppet::Parser::Parser.new(Puppet::Node::Environment.new)
+ end
+
+ def mkscope(hash = {})
+ parser ||= mkparser
+ compiler ||= mkcompiler
+ compiler.topscope.source = (parser.find_hostclass("", "") || parser.newclass(""))
+
+ raise "Could not find source for scope" unless compiler.topscope.source
+ # Make the 'main' stuff
+ compiler.send(:evaluate_main)
+ compiler.topscope
+ end
+
+ def classobj(name, hash = {})
+ hash[:file] ||= __FILE__
+ hash[:line] ||= __LINE__
+ hash[:type] ||= name
+ AST::HostClass.new(hash)
+ end
+
+ def tagobj(*names)
+ args = {}
+ newnames = names.collect do |name|
+ if name.is_a? AST
+ name
+ else
+ nameobj(name)
+ end
end
+ args[:type] = astarray(*newnames)
+ assert_nothing_raised("Could not create tag #{names.inspect}") {
+ return AST::Tag.new(args)
+ }
+ end
- def tagobj(*names)
- args = {}
- newnames = names.collect do |name|
- if name.is_a? AST
- name
- else
- nameobj(name)
- end
- end
- args[:type] = astarray(*newnames)
- assert_nothing_raised("Could not create tag #{names.inspect}") {
- return AST::Tag.new(args)
- }
- end
+ def resourcedef(type, title, params)
+ title = stringobj(title) unless title.is_a?(AST)
+ assert_nothing_raised("Could not create #{type} #{title}") {
- def resourcedef(type, title, params)
- title = stringobj(title) unless title.is_a?(AST)
- assert_nothing_raised("Could not create #{type} #{title}") {
+ return AST::Resource.new(
- return AST::Resource.new(
+ :file => __FILE__,
+ :line => __LINE__,
+ :title => title,
+ :type => type,
- :file => __FILE__,
- :line => __LINE__,
- :title => title,
- :type => type,
+ :parameters => resourceinst(params)
+ )
+ }
+ end
- :parameters => resourceinst(params)
- )
- }
- end
+ def virt_resourcedef(*args)
+ res = resourcedef(*args)
+ res.virtual = true
+ res
+ end
- def virt_resourcedef(*args)
- res = resourcedef(*args)
- res.virtual = true
- res
- end
+ def resourceoverride(type, title, params)
+ assert_nothing_raised("Could not create #{type} #{name}") {
- def resourceoverride(type, title, params)
- assert_nothing_raised("Could not create #{type} #{name}") {
+ return AST::ResourceOverride.new(
- return AST::ResourceOverride.new(
+ :file => __FILE__,
+ :line => __LINE__,
+ :object => resourceref(type, title),
- :file => __FILE__,
- :line => __LINE__,
- :object => resourceref(type, title),
+ :type => type,
+ :parameters => resourceinst(params)
+ )
+ }
+ end
- :type => type,
- :parameters => resourceinst(params)
- )
- }
- end
+ def resourceref(type, title)
+ assert_nothing_raised("Could not create #{type} #{title}") {
- def resourceref(type, title)
- assert_nothing_raised("Could not create #{type} #{title}") {
+ return AST::ResourceReference.new(
- return AST::ResourceReference.new(
+ :file => __FILE__,
+ :line => __LINE__,
+ :type => type,
- :file => __FILE__,
- :line => __LINE__,
- :type => type,
+ :title => stringobj(title)
+ )
+ }
+ end
- :title => stringobj(title)
- )
- }
- end
-
- def fileobj(path, hash = {"owner" => "root"})
- assert_nothing_raised("Could not create file #{path}") {
- return resourcedef("file", path, hash)
- }
- end
+ def fileobj(path, hash = {"owner" => "root"})
+ assert_nothing_raised("Could not create file #{path}") {
+ return resourcedef("file", path, hash)
+ }
+ end
- def nameobj(name)
- assert_nothing_raised("Could not create name #{name}") {
+ def nameobj(name)
+ assert_nothing_raised("Could not create name #{name}") {
- return AST::Name.new(
+ return AST::Name.new(
- :file => tempfile,
+ :file => tempfile,
- :line => rand(100),
- :value => name
- )
- }
- end
+ :line => rand(100),
+ :value => name
+ )
+ }
+ end
- def typeobj(name)
- assert_nothing_raised("Could not create type #{name}") {
+ def typeobj(name)
+ assert_nothing_raised("Could not create type #{name}") {
- return AST::Type.new(
+ return AST::Type.new(
- :file => tempfile,
+ :file => tempfile,
- :line => rand(100),
- :value => name
- )
- }
- end
+ :line => rand(100),
+ :value => name
+ )
+ }
+ end
- def nodedef(name)
- assert_nothing_raised("Could not create node #{name}") {
+ def nodedef(name)
+ assert_nothing_raised("Could not create node #{name}") {
- return AST::NodeDef.new(
+ return AST::NodeDef.new(
- :file => tempfile,
+ :file => tempfile,
- :line => rand(100),
- :names => nameobj(name),
+ :line => rand(100),
+ :names => nameobj(name),
- :code => AST::ASTArray.new(
+ :code => AST::ASTArray.new(
- :children => [
- varobj("#{name}var", "#{name}value"),
+ :children => [
+ varobj("#{name}var", "#{name}value"),
- fileobj("/#{name}")
- ]
- )
- )
- }
- end
-
- def resourceinst(hash)
- assert_nothing_raised("Could not create resource instance") {
- params = hash.collect { |param, value|
- resourceparam(param, value)
- }
-
- return AST::ResourceInstance.new(
-
- :file => tempfile,
-
- :line => rand(100),
- :children => params
- )
- }
- end
+ fileobj("/#{name}")
+ ]
+ )
+ )
+ }
+ end
- def resourceparam(param, value)
- # Allow them to pass non-strings in
- value = stringobj(value) if value.is_a?(String)
- assert_nothing_raised("Could not create param #{param}") {
+ def resourceinst(hash)
+ assert_nothing_raised("Could not create resource instance") {
+ params = hash.collect { |param, value|
+ resourceparam(param, value)
+ }
- return AST::ResourceParam.new(
+ return AST::ResourceInstance.new(
- :file => tempfile,
+ :file => tempfile,
- :line => rand(100),
- :param => param,
- :value => value
- )
- }
- end
+ :line => rand(100),
+ :children => params
+ )
+ }
+ end
- def stringobj(value)
+ def resourceparam(param, value)
+ # Allow them to pass non-strings in
+ value = stringobj(value) if value.is_a?(String)
+ assert_nothing_raised("Could not create param #{param}") {
- AST::String.new(
+ return AST::ResourceParam.new(
- :file => tempfile,
+ :file => tempfile,
- :line => rand(100),
- :value => value
- )
- end
+ :line => rand(100),
+ :param => param,
+ :value => value
+ )
+ }
+ end
- def varobj(name, value)
- value = stringobj(value) unless value.is_a? AST
- assert_nothing_raised("Could not create #{name} code") {
+ def stringobj(value)
- return AST::VarDef.new(
+ AST::String.new(
- :file => tempfile,
+ :file => tempfile,
- :line => rand(100),
- :name => nameobj(name),
- :value => value
- )
- }
- end
+ :line => rand(100),
+ :value => value
+ )
+ end
- def varref(name)
- assert_nothing_raised("Could not create #{name} variable") {
+ def varobj(name, value)
+ value = stringobj(value) unless value.is_a? AST
+ assert_nothing_raised("Could not create #{name} code") {
- return AST::Variable.new(
+ return AST::VarDef.new(
- :file => __FILE__,
- :line => __LINE__,
+ :file => tempfile,
- :value => name
- )
- }
- end
+ :line => rand(100),
+ :name => nameobj(name),
+ :value => value
+ )
+ }
+ end
- def argobj(name, value)
- assert_nothing_raised("Could not create #{name} compargument") {
- return AST::CompArgument.new(
- :children => [nameobj(name), stringobj(value)]
- )
- }
- end
+ def varref(name)
+ assert_nothing_raised("Could not create #{name} variable") {
- def defaultobj(type, params)
- pary = []
- params.each { |p,v|
+ return AST::Variable.new(
- pary << AST::ResourceParam.new(
+ :file => __FILE__,
+ :line => __LINE__,
- :file => __FILE__,
- :line => __LINE__,
- :param => p,
+ :value => name
+ )
+ }
+ end
- :value => stringobj(v)
- )
- }
+ def argobj(name, value)
+ assert_nothing_raised("Could not create #{name} compargument") {
+ return AST::CompArgument.new(
+ :children => [nameobj(name), stringobj(value)]
+ )
+ }
+ end
- past = AST::ASTArray.new(
+ def defaultobj(type, params)
+ pary = []
+ params.each { |p,v|
- :file => __FILE__,
- :line => __LINE__,
+ pary << AST::ResourceParam.new(
- :children => pary
- )
+ :file => __FILE__,
+ :line => __LINE__,
+ :param => p,
- assert_nothing_raised("Could not create defaults for #{type}") {
+ :value => stringobj(v)
+ )
+ }
- return AST::ResourceDefaults.new(
+ past = AST::ASTArray.new(
- :file => __FILE__,
- :line => __LINE__,
- :type => type,
+ :file => __FILE__,
+ :line => __LINE__,
- :parameters => past
- )
- }
- end
+ :children => pary
+ )
- def taggedobj(name, ftype = :statement)
- functionobj("tagged", name, ftype)
- end
+ assert_nothing_raised("Could not create defaults for #{type}") {
- def functionobj(function, name, ftype = :statement)
- func = nil
- assert_nothing_raised do
+ return AST::ResourceDefaults.new(
- func = Puppet::Parser::AST::Function.new(
+ :file => __FILE__,
+ :line => __LINE__,
+ :type => type,
- :name => function,
- :ftype => ftype,
+ :parameters => past
+ )
+ }
+ end
- :arguments => AST::ASTArray.new(
- :children => [nameobj(name)]
- )
- )
- end
+ def taggedobj(name, ftype = :statement)
+ functionobj("tagged", name, ftype)
+ end
- func
- end
+ def functionobj(function, name, ftype = :statement)
+ func = nil
+ assert_nothing_raised do
- # This assumes no nodes
- def assert_creates(manifest, *files)
- oldmanifest = Puppet[:manifest]
- Puppet[:manifest] = manifest
+ func = Puppet::Parser::AST::Function.new(
- catalog = Puppet::Parser::Compiler.new(mknode).compile.to_ral
- catalog.apply
+ :name => function,
+ :ftype => ftype,
- files.each do |file|
- assert(FileTest.exists?(file), "Did not create #{file}")
- end
- ensure
- Puppet[:manifest] = oldmanifest
+ :arguments => AST::ASTArray.new(
+ :children => [nameobj(name)]
+ )
+ )
end
- def mk_transobject(file = "/etc/passwd")
- obj = nil
- assert_nothing_raised {
- obj = Puppet::TransObject.new("file", file)
- obj["owner"] = "root"
- obj["mode"] = "644"
- }
+ func
+ end
- obj
- end
-
- def mk_transbucket(*resources)
- bucket = nil
- assert_nothing_raised {
- bucket = Puppet::TransBucket.new
- bucket.name = "yayname"
- bucket.type = "yaytype"
- }
+ # This assumes no nodes
+ def assert_creates(manifest, *files)
+ oldmanifest = Puppet[:manifest]
+ Puppet[:manifest] = manifest
- resources.each { |o| bucket << o }
+ catalog = Puppet::Parser::Compiler.new(mknode).compile.to_ral
+ catalog.apply
- bucket
+ files.each do |file|
+ assert(FileTest.exists?(file), "Did not create #{file}")
end
-
- # Make a tree of resources, yielding if desired
- def mk_transtree(depth = 4, width = 2)
- top = nil
- assert_nothing_raised {
- top = Puppet::TransBucket.new
- top.name = "top"
- top.type = "bucket"
- }
-
- bucket = top
-
- file = tempfile
- depth.times do |i|
- resources = []
- width.times do |j|
- path = tempfile + i.to_s
- obj = Puppet::TransObject.new("file", path)
- obj["owner"] = "root"
- obj["mode"] = "644"
-
- # Yield, if they want
- yield(obj, i, j) if block_given?
-
- resources << obj
- end
-
- newbucket = mk_transbucket(*resources)
-
- bucket.push newbucket
- bucket = newbucket
- end
-
- top
+ ensure
+ Puppet[:manifest] = oldmanifest
+ end
+
+ def mk_transobject(file = "/etc/passwd")
+ obj = nil
+ assert_nothing_raised {
+ obj = Puppet::TransObject.new("file", file)
+ obj["owner"] = "root"
+ obj["mode"] = "644"
+ }
+
+ obj
+ end
+
+ def mk_transbucket(*resources)
+ bucket = nil
+ assert_nothing_raised {
+ bucket = Puppet::TransBucket.new
+ bucket.name = "yayname"
+ bucket.type = "yaytype"
+ }
+
+ resources.each { |o| bucket << o }
+
+ bucket
+ end
+
+ # Make a tree of resources, yielding if desired
+ def mk_transtree(depth = 4, width = 2)
+ top = nil
+ assert_nothing_raised {
+ top = Puppet::TransBucket.new
+ top.name = "top"
+ top.type = "bucket"
+ }
+
+ bucket = top
+
+ file = tempfile
+ depth.times do |i|
+ resources = []
+ width.times do |j|
+ path = tempfile + i.to_s
+ obj = Puppet::TransObject.new("file", path)
+ obj["owner"] = "root"
+ obj["mode"] = "644"
+
+ # Yield, if they want
+ yield(obj, i, j) if block_given?
+
+ resources << obj
+ end
+
+ newbucket = mk_transbucket(*resources)
+
+ bucket.push newbucket
+ bucket = newbucket
end
- # Take a list of AST resources, evaluate them, and return the results
- def assert_evaluate(children)
- top = nil
- assert_nothing_raised("Could not create top object") {
- top = AST::ASTArray.new(
- :children => children
- )
- }
-
- trans = nil
- scope = nil
- assert_nothing_raised {
- scope = Puppet::Parser::Scope.new
- trans = scope.evaluate(:ast => top)
- }
-
- trans
- end
+ top
+ end
+
+ # Take a list of AST resources, evaluate them, and return the results
+ def assert_evaluate(children)
+ top = nil
+ assert_nothing_raised("Could not create top object") {
+ top = AST::ASTArray.new(
+ :children => children
+ )
+ }
+
+ trans = nil
+ scope = nil
+ assert_nothing_raised {
+ scope = Puppet::Parser::Scope.new
+ trans = scope.evaluate(:ast => top)
+ }
+
+ trans
+ end
end
diff --git a/test/lib/puppettest/railstesting.rb b/test/lib/puppettest/railstesting.rb
index 2240c73..e05511e 100644
--- a/test/lib/puppettest/railstesting.rb
+++ b/test/lib/puppettest/railstesting.rb
@@ -1,52 +1,52 @@
module PuppetTest::RailsTesting
- Parser = Puppet::Parser
- AST = Puppet::Parser::AST
- include PuppetTest::ParserTesting
+ Parser = Puppet::Parser
+ AST = Puppet::Parser::AST
+ include PuppetTest::ParserTesting
- def teardown
- super
+ def teardown
+ super
- # If we don't clean up the connection list, then the rails
- # lib will still think it's connected.
- ActiveRecord::Base.clear_active_connections! if Puppet.features.rails?
- end
+ # If we don't clean up the connection list, then the rails
+ # lib will still think it's connected.
+ ActiveRecord::Base.clear_active_connections! if Puppet.features.rails?
+ end
- def railsinit
- Puppet::Rails.init
- end
+ def railsinit
+ Puppet::Rails.init
+ end
- def railsteardown
- Puppet::Rails.teardown if Puppet[:dbadapter] != "sqlite3"
- end
+ def railsteardown
+ Puppet::Rails.teardown if Puppet[:dbadapter] != "sqlite3"
+ end
- def railsresource(type = "file", title = "/tmp/testing", params = {})
- railsteardown
- railsinit
+ def railsresource(type = "file", title = "/tmp/testing", params = {})
+ railsteardown
+ railsinit
- # We need a host for resources
- #host = Puppet::Rails::Host.new(:name => Facter.value("hostname"))
+ # We need a host for resources
+ #host = Puppet::Rails::Host.new(:name => Facter.value("hostname"))
- # Now build a resource
- resources = []
+ # Now build a resource
+ resources = []
- resources << mkresource(
- :type => type, :title => title, :exported => true,
+ resources << mkresource(
+ :type => type, :title => title, :exported => true,
- :parameters => params)
+ :parameters => params)
- # Now collect our facts
- facts = Facter.to_hash
+ # Now collect our facts
+ facts = Facter.to_hash
- # Now try storing our crap
- host = nil
- node = mknode(facts["hostname"])
- node.parameters = facts
- assert_nothing_raised {
- host = Puppet::Rails::Host.store(node, resources)
- }
+ # Now try storing our crap
+ host = nil
+ node = mknode(facts["hostname"])
+ node.parameters = facts
+ assert_nothing_raised {
+ host = Puppet::Rails::Host.store(node, resources)
+ }
- # Now save the whole thing
- host.save
- end
+ # Now save the whole thing
+ host.save
+ end
end
diff --git a/test/lib/puppettest/reporttesting.rb b/test/lib/puppettest/reporttesting.rb
index b0cb0f2..448a6a9 100644
--- a/test/lib/puppettest/reporttesting.rb
+++ b/test/lib/puppettest/reporttesting.rb
@@ -1,16 +1,16 @@
module PuppetTest::Reporttesting
- def fakereport
- # Create a bunch of log messages in an array.
- report = Puppet::Transaction::Report.new
+ def fakereport
+ # Create a bunch of log messages in an array.
+ report = Puppet::Transaction::Report.new
- 3.times { |i|
- # We have to use warning so that the logs always happen
- log = Puppet.warning("Report test message #{i}")
+ 3.times { |i|
+ # We have to use warning so that the logs always happen
+ log = Puppet.warning("Report test message #{i}")
- report << log
- }
+ report << log
+ }
- report
- end
+ report
+ end
end
diff --git a/test/lib/puppettest/resourcetesting.rb b/test/lib/puppettest/resourcetesting.rb
index 0949dff..ea8bec0 100644
--- a/test/lib/puppettest/resourcetesting.rb
+++ b/test/lib/puppettest/resourcetesting.rb
@@ -1,54 +1,54 @@
module PuppetTest::ResourceTesting
- Parser = Puppet::Parser
- AST = Puppet::Parser::AST
+ Parser = Puppet::Parser
+ AST = Puppet::Parser::AST
- def mkevaltest(parser = nil)
- parser ||= mkparser
+ def mkevaltest(parser = nil)
+ parser ||= mkparser
- @parser.newdefine(
- "evaltest",
+ @parser.newdefine(
+ "evaltest",
- :arguments => [%w{one}, ["two", stringobj("755")]],
+ :arguments => [%w{one}, ["two", stringobj("755")]],
- :code => resourcedef(
- "file", "/tmp",
+ :code => resourcedef(
+ "file", "/tmp",
- "owner" => varref("one"), "mode" => varref("two"))
- )
+ "owner" => varref("one"), "mode" => varref("two"))
+ )
+ end
+
+ def mkresource(args = {})
+ args[:source] ||= "source"
+ args[:scope] ||= mkscope
+
+ type = args[:type] || "resource"
+ title = args[:title] || "testing"
+ args.delete(:type)
+ args.delete(:title)
+ {:source => "source", :scope => "scope"}.each do |param, value|
+ args[param] ||= value
end
- def mkresource(args = {})
- args[:source] ||= "source"
- args[:scope] ||= mkscope
-
- type = args[:type] || "resource"
- title = args[:title] || "testing"
- args.delete(:type)
- args.delete(:title)
- {:source => "source", :scope => "scope"}.each do |param, value|
- args[param] ||= value
- end
-
- params = args[:parameters] || {:one => "yay", :three => "rah"}
- if args[:parameters] == :none
- args.delete(:parameters)
- else
- args[:parameters] = paramify args[:source], params
- end
-
- Parser::Resource.new(type, title, args)
+ params = args[:parameters] || {:one => "yay", :three => "rah"}
+ if args[:parameters] == :none
+ args.delete(:parameters)
+ else
+ args[:parameters] = paramify args[:source], params
end
- def param(name, value, source)
- Parser::Resource::Param.new(:name => name, :value => value, :source => source)
- end
+ Parser::Resource.new(type, title, args)
+ end
+
+ def param(name, value, source)
+ Parser::Resource::Param.new(:name => name, :value => value, :source => source)
+ end
- def paramify(source, hash)
- hash.collect do |name, value|
- Parser::Resource::Param.new(
- :name => name, :value => value, :source => source
- )
- end
+ def paramify(source, hash)
+ hash.collect do |name, value|
+ Parser::Resource::Param.new(
+ :name => name, :value => value, :source => source
+ )
end
+ end
end
diff --git a/test/lib/puppettest/runnable_test.rb b/test/lib/puppettest/runnable_test.rb
index ac2fb7b..bb8d89e 100644
--- a/test/lib/puppettest/runnable_test.rb
+++ b/test/lib/puppettest/runnable_test.rb
@@ -1,43 +1,43 @@
# Manage whether a test is runnable.
module PuppetTest
- module RunnableTest
- # Confine this example group based on specified criteria. This can be
- # a message and its related test either as a hash or as a single
- # message argument and a block to be evaluated at the time the confine
- # is checked.
- #
- # Examples:
- #
- # confine "Rails is not available" => Puppet.features.rails?
- #
- # confine("ActiveRecord 2.1.x") { ::ActiveRecord::VERSION::MAJOR == 2 and ::ActiveRecord::VERSION::MINOR <= 1 }
- #
- def confine(hash_or_message, &block)
- hash = block_given? ? {hash_or_message => block} : hash_or_message
- confines.update hash
- end
+ module RunnableTest
+ # Confine this example group based on specified criteria. This can be
+ # a message and its related test either as a hash or as a single
+ # message argument and a block to be evaluated at the time the confine
+ # is checked.
+ #
+ # Examples:
+ #
+ # confine "Rails is not available" => Puppet.features.rails?
+ #
+ # confine("ActiveRecord 2.1.x") { ::ActiveRecord::VERSION::MAJOR == 2 and ::ActiveRecord::VERSION::MINOR <= 1 }
+ #
+ def confine(hash_or_message, &block)
+ hash = block_given? ? {hash_or_message => block} : hash_or_message
+ confines.update hash
+ end
- # Check all confines for a given example group, starting with any
- # specified in the parent example group. If any confine test is false,
- # the example group is not runnable (and will be skipped). Note: This
- # is used directly by Rspec and is not intended for develper use.
- #
- def runnable?
- return false if superclass.respond_to?(:runnable?) and not superclass.runnable?
+ # Check all confines for a given example group, starting with any
+ # specified in the parent example group. If any confine test is false,
+ # the example group is not runnable (and will be skipped). Note: This
+ # is used directly by Rspec and is not intended for develper use.
+ #
+ def runnable?
+ return false if superclass.respond_to?(:runnable?) and not superclass.runnable?
- confines.each do |message, is_runnable|
- is_runnable = is_runnable.call if is_runnable.respond_to?(:call)
- messages << message unless is_runnable
- end
+ confines.each do |message, is_runnable|
+ is_runnable = is_runnable.call if is_runnable.respond_to?(:call)
+ messages << message unless is_runnable
+ end
- messages.empty?
- end
+ messages.empty?
+ end
- def messages; @messages ||= [] end
+ def messages; @messages ||= [] end
- private
+ private
- def confines; @confines ||= {} end
- end
+ def confines; @confines ||= {} end
+ end
end
diff --git a/test/lib/puppettest/servertest.rb b/test/lib/puppettest/servertest.rb
index 4efcedd..4174c1a 100644
--- a/test/lib/puppettest/servertest.rb
+++ b/test/lib/puppettest/servertest.rb
@@ -2,73 +2,73 @@ require 'puppettest'
require 'puppet/network/http_server/webrick'
module PuppetTest::ServerTest
- include PuppetTest
- def setup
- super
+ include PuppetTest
+ def setup
+ super
- if defined?(@@port)
- @@port += 1
- else
- @@port = 20000
- end
+ if defined?(@@port)
+ @@port += 1
+ else
+ @@port = 20000
end
+ end
- # create a simple manifest that just creates a file
- def mktestmanifest
- file = File.join(Puppet[:confdir], "#{(self.class.to_s + "test")}site.pp")
- #@createdfile = File.join(tmpdir, self.class.to_s + "manifesttesting" +
- # "_#{@method_name}")
- @createdfile = tempfile
+ # create a simple manifest that just creates a file
+ def mktestmanifest
+ file = File.join(Puppet[:confdir], "#{(self.class.to_s + "test")}site.pp")
+ #@createdfile = File.join(tmpdir, self.class.to_s + "manifesttesting" +
+ # "_#{@method_name}")
+ @createdfile = tempfile
- File.open(file, "w") { |f|
- f.puts "file { \"%s\": ensure => file, mode => 755 }\n" % @createdfile
- }
+ File.open(file, "w") { |f|
+ f.puts "file { \"%s\": ensure => file, mode => 755 }\n" % @createdfile
+ }
- @@tmpfiles << @createdfile
- @@tmpfiles << file
+ @@tmpfiles << @createdfile
+ @@tmpfiles << file
- file
- end
+ file
+ end
- # create a server, forked into the background
- def mkserver(handlers = nil)
- Puppet[:name] = "puppetmasterd"
- # our default handlers
- unless handlers
- handlers = {
- :CA => {}, # so that certs autogenerate
- :Master => {
- :Manifest => mktestmanifest,
- :UseNodes => false
- },
- }
- end
+ # create a server, forked into the background
+ def mkserver(handlers = nil)
+ Puppet[:name] = "puppetmasterd"
+ # our default handlers
+ unless handlers
+ handlers = {
+ :CA => {}, # so that certs autogenerate
+ :Master => {
+ :Manifest => mktestmanifest,
+ :UseNodes => false
+ },
+ }
+ end
- # then create the actual server
- server = nil
- assert_nothing_raised {
+ # then create the actual server
+ server = nil
+ assert_nothing_raised {
- server = Puppet::Network::HTTPServer::WEBrick.new(
+ server = Puppet::Network::HTTPServer::WEBrick.new(
- :Port => @@port,
+ :Port => @@port,
- :Handlers => handlers
- )
- }
+ :Handlers => handlers
+ )
+ }
- # fork it
- spid = fork {
- trap(:INT) { server.shutdown }
- server.start
- }
+ # fork it
+ spid = fork {
+ trap(:INT) { server.shutdown }
+ server.start
+ }
- # and store its pid for killing
- @@tmppids << spid
+ # and store its pid for killing
+ @@tmppids << spid
- # give the server a chance to do its thing
- sleep 1
- spid
- end
+ # give the server a chance to do its thing
+ sleep 1
+ spid
+ end
end
diff --git a/test/lib/puppettest/support/assertions.rb b/test/lib/puppettest/support/assertions.rb
index 8426869..7f326b1 100644
--- a/test/lib/puppettest/support/assertions.rb
+++ b/test/lib/puppettest/support/assertions.rb
@@ -4,63 +4,63 @@ require 'fileutils'
module PuppetTest
- include PuppetTest::Support::Utils
- def assert_logged(level, regex, msg = nil)
- # Skip verifying logs that we're not supposed to send.
- return unless Puppet::Util::Log.sendlevel?(level)
- r = @logs.detect { |l| l.level == level and l.message =~ regex }
- @logs.clear
- assert(r, msg)
- end
+ include PuppetTest::Support::Utils
+ def assert_logged(level, regex, msg = nil)
+ # Skip verifying logs that we're not supposed to send.
+ return unless Puppet::Util::Log.sendlevel?(level)
+ r = @logs.detect { |l| l.level == level and l.message =~ regex }
+ @logs.clear
+ assert(r, msg)
+ end
- def assert_uid_gid(uid, gid, filename)
- flunk "Must be uid 0 to run these tests" unless Process.uid == 0
+ def assert_uid_gid(uid, gid, filename)
+ flunk "Must be uid 0 to run these tests" unless Process.uid == 0
- fork do
- Puppet::Util::SUIDManager.gid = gid
- Puppet::Util::SUIDManager.uid = uid
- # FIXME: use the tempfile method from puppettest.rb
- system("mkfifo #{filename}")
- f = File.open(filename, "w")
- f << "#{Puppet::Util::SUIDManager.uid}\n#{Puppet::Util::SUIDManager.gid}\n"
- yield if block_given?
- end
+ fork do
+ Puppet::Util::SUIDManager.gid = gid
+ Puppet::Util::SUIDManager.uid = uid
+ # FIXME: use the tempfile method from puppettest.rb
+ system("mkfifo #{filename}")
+ f = File.open(filename, "w")
+ f << "#{Puppet::Util::SUIDManager.uid}\n#{Puppet::Util::SUIDManager.gid}\n"
+ yield if block_given?
+ end
- # avoid a race.
- true while !File.exists? filename
+ # avoid a race.
+ true while !File.exists? filename
- f = File.open(filename, "r")
+ f = File.open(filename, "r")
- a = f.readlines
- assert_equal(uid, a[0].chomp.to_i, "UID was incorrect")
- assert_equal(gid, a[1].chomp.to_i, "GID was incorrect")
- FileUtils.rm(filename)
- end
+ a = f.readlines
+ assert_equal(uid, a[0].chomp.to_i, "UID was incorrect")
+ assert_equal(gid, a[1].chomp.to_i, "GID was incorrect")
+ FileUtils.rm(filename)
+ end
- def assert_events(events, *resources)
- trans = nil
- comp = nil
- msg = nil
+ def assert_events(events, *resources)
+ trans = nil
+ comp = nil
+ msg = nil
- raise Puppet::DevError, "Incorrect call of assert_events" unless events.is_a? Array
- msg = resources.pop if resources[-1].is_a? String
+ raise Puppet::DevError, "Incorrect call of assert_events" unless events.is_a? Array
+ msg = resources.pop if resources[-1].is_a? String
- config = resources2catalog(*resources)
- transaction = Puppet::Transaction.new(config)
+ config = resources2catalog(*resources)
+ transaction = Puppet::Transaction.new(config)
- run_events(:evaluate, transaction, events, msg)
+ run_events(:evaluate, transaction, events, msg)
- transaction
- end
+ transaction
+ end
- # A simpler method that just applies what we have.
- def assert_apply(*resources)
- config = resources2catalog(*resources)
+ # A simpler method that just applies what we have.
+ def assert_apply(*resources)
+ config = resources2catalog(*resources)
- events = nil
- assert_nothing_raised("Failed to evaluate") {
- events = config.apply.events
- }
- events
- end
+ events = nil
+ assert_nothing_raised("Failed to evaluate") {
+ events = config.apply.events
+ }
+ events
+ end
end
diff --git a/test/lib/puppettest/support/helpers.rb b/test/lib/puppettest/support/helpers.rb
index 4a3a530..75c699f 100644
--- a/test/lib/puppettest/support/helpers.rb
+++ b/test/lib/puppettest/support/helpers.rb
@@ -1,18 +1,18 @@
require 'puppettest'
module PuppetTest
- # NOTE: currently both of these will produce bogus results on Darwin due to the wonderful
- # UID of nobody.
- def nonrootuser
- Etc.passwd { |user|
- return user if user.uid != Puppet::Util::SUIDManager.uid and user.uid > 0 and user.uid < 255
- }
- end
+ # NOTE: currently both of these will produce bogus results on Darwin due to the wonderful
+ # UID of nobody.
+ def nonrootuser
+ Etc.passwd { |user|
+ return user if user.uid != Puppet::Util::SUIDManager.uid and user.uid > 0 and user.uid < 255
+ }
+ end
- def nonrootgroup
- Etc.group { |group|
- return group if group.gid != Puppet::Util::SUIDManager.gid and group.gid > 0 and group.gid < 255
- }
- end
+ def nonrootgroup
+ Etc.group { |group|
+ return group if group.gid != Puppet::Util::SUIDManager.gid and group.gid > 0 and group.gid < 255
+ }
+ end
end
diff --git a/test/lib/puppettest/support/resources.rb b/test/lib/puppettest/support/resources.rb
index 0eec20a..2b922bb 100755
--- a/test/lib/puppettest/support/resources.rb
+++ b/test/lib/puppettest/support/resources.rb
@@ -4,32 +4,32 @@
# Copyright (c) 2006. All rights reserved.
module PuppetTest::Support::Resources
- def tree_resource(name)
- Puppet::Type.type(:file).new :title => name, :path => "/tmp/#{name}", :mode => 0755
- end
+ def tree_resource(name)
+ Puppet::Type.type(:file).new :title => name, :path => "/tmp/#{name}", :mode => 0755
+ end
- def tree_container(name)
- Puppet::Type::Component.create :name => name, :type => "yay"
- end
+ def tree_container(name)
+ Puppet::Type::Component.create :name => name, :type => "yay"
+ end
- def treenode(config, name, *resources)
- comp = tree_container name
- resources.each do |resource|
- resource = tree_resource(resource) if resource.is_a?(String)
- config.add_edge(comp, resource)
- config.add_resource resource unless config.resource(resource.ref)
- end
- comp
+ def treenode(config, name, *resources)
+ comp = tree_container name
+ resources.each do |resource|
+ resource = tree_resource(resource) if resource.is_a?(String)
+ config.add_edge(comp, resource)
+ config.add_resource resource unless config.resource(resource.ref)
end
+ comp
+ end
- def mktree
- catalog = Puppet::Resource::Catalog.new do |config|
- one = treenode(config, "one", "a", "b")
- two = treenode(config, "two", "c", "d")
- middle = treenode(config, "middle", "e", "f", two)
- top = treenode(config, "top", "g", "h", middle, one)
- end
-
- catalog
+ def mktree
+ catalog = Puppet::Resource::Catalog.new do |config|
+ one = treenode(config, "one", "a", "b")
+ two = treenode(config, "two", "c", "d")
+ middle = treenode(config, "middle", "e", "f", two)
+ top = treenode(config, "top", "g", "h", middle, one)
end
+
+ catalog
+ end
end
diff --git a/test/lib/puppettest/support/utils.rb b/test/lib/puppettest/support/utils.rb
index 466798a..edc81d3 100644
--- a/test/lib/puppettest/support/utils.rb
+++ b/test/lib/puppettest/support/utils.rb
@@ -3,153 +3,153 @@ require 'puppettest'
module PuppetTest::Support
end
module PuppetTest::Support::Utils
- def gcdebug(type)
- Puppet.warning "#{type}: #{ObjectSpace.each_object(type) { |o| }}"
+ def gcdebug(type)
+ Puppet.warning "#{type}: #{ObjectSpace.each_object(type) { |o| }}"
+ end
+
+ #
+ # TODO: I think this method needs to be renamed to something a little more
+ # explanatory.
+ #
+
+ def newobj(type, name, hash)
+ transport = Puppet::TransObject.new(name, "file")
+ transport[:path] = path
+ transport[:ensure] = "file"
+ assert_nothing_raised {
+ file = transport.to_ral
+ }
+ end
+
+ # Turn a list of resources, or possibly a catalog and some resources,
+ # into a catalog object.
+ def resources2catalog(*resources)
+ if resources[0].is_a?(Puppet::Resource::Catalog)
+ config = resources.shift
+ resources.each { |r| config.add_resource r } unless resources.empty?
+ elsif resources[0].is_a?(Puppet::Type.type(:component))
+ raise ArgumentError, "resource2config() no longer accpts components"
+ comp = resources.shift
+ comp.delve
+ else
+ config = Puppet::Resource::Catalog.new
+ resources.each { |res| config.add_resource res }
end
-
- #
- # TODO: I think this method needs to be renamed to something a little more
- # explanatory.
- #
-
- def newobj(type, name, hash)
- transport = Puppet::TransObject.new(name, "file")
- transport[:path] = path
- transport[:ensure] = "file"
- assert_nothing_raised {
- file = transport.to_ral
- }
- end
-
- # Turn a list of resources, or possibly a catalog and some resources,
- # into a catalog object.
- def resources2catalog(*resources)
- if resources[0].is_a?(Puppet::Resource::Catalog)
- config = resources.shift
- resources.each { |r| config.add_resource r } unless resources.empty?
- elsif resources[0].is_a?(Puppet::Type.type(:component))
- raise ArgumentError, "resource2config() no longer accpts components"
- comp = resources.shift
- comp.delve
- else
- config = Puppet::Resource::Catalog.new
- resources.each { |res| config.add_resource res }
- end
- config
- end
-
- # stop any services that might be hanging around
- def stopservices
- end
-
- # TODO: rewrite this to use the 'etc' module.
-
- # Define a variable that contains the name of my user.
- def setme
- # retrieve the user name
- id = %x{id}.chomp
- if id =~ /uid=\d+\(([^\)]+)\)/
- @me = $1
- else
- puts id
- end
- raise "Could not retrieve user name; 'id' did not work" unless defined?(@me)
- end
-
- # Define a variable that contains a group I'm in.
- def set_mygroup
- # retrieve the user name
- group = %x{groups}.chomp.split(/ /)[0]
- raise "Could not find group to set in @mygroup" unless group
- @mygroup = group
- end
-
- def run_events(type, trans, events, msg)
- case type
- when :evaluate, :rollback # things are hunky-dory
- else
- raise Puppet::DevError, "Incorrect run_events type"
- end
-
- method = type
-
- trans.send(method)
- newevents = trans.events.reject { |e| e.status == 'failure' }.collect { |e|
- e.name
- }
-
- assert_equal(events, newevents, "Incorrect #{type} #{msg} events")
-
- trans
- end
-
- def fakefile(name)
- ary = [PuppetTest.basedir, "test"]
- ary += name.split("/")
- file = File.join(ary)
- raise Puppet::DevError, "No fakedata file #{file}" unless FileTest.exists?(file)
- file
- end
-
- # wrap how to retrieve the masked mode
- def filemode(file)
- File.stat(file).mode & 007777
+ config
+ end
+
+ # stop any services that might be hanging around
+ def stopservices
+ end
+
+ # TODO: rewrite this to use the 'etc' module.
+
+ # Define a variable that contains the name of my user.
+ def setme
+ # retrieve the user name
+ id = %x{id}.chomp
+ if id =~ /uid=\d+\(([^\)]+)\)/
+ @me = $1
+ else
+ puts id
end
-
- def memory
- Puppet::Util.memory
+ raise "Could not retrieve user name; 'id' did not work" unless defined?(@me)
+ end
+
+ # Define a variable that contains a group I'm in.
+ def set_mygroup
+ # retrieve the user name
+ group = %x{groups}.chomp.split(/ /)[0]
+ raise "Could not find group to set in @mygroup" unless group
+ @mygroup = group
+ end
+
+ def run_events(type, trans, events, msg)
+ case type
+ when :evaluate, :rollback # things are hunky-dory
+ else
+ raise Puppet::DevError, "Incorrect run_events type"
end
- # a list of files that we can parse for testing
- def textfiles
- textdir = datadir "snippets"
- Dir.entries(textdir).reject { |f|
- f =~ /^\./ or f =~ /fail/
- }.each { |f|
- yield File.join(textdir, f)
- }
+ method = type
+
+ trans.send(method)
+ newevents = trans.events.reject { |e| e.status == 'failure' }.collect { |e|
+ e.name
+ }
+
+ assert_equal(events, newevents, "Incorrect #{type} #{msg} events")
+
+ trans
+ end
+
+ def fakefile(name)
+ ary = [PuppetTest.basedir, "test"]
+ ary += name.split("/")
+ file = File.join(ary)
+ raise Puppet::DevError, "No fakedata file #{file}" unless FileTest.exists?(file)
+ file
+ end
+
+ # wrap how to retrieve the masked mode
+ def filemode(file)
+ File.stat(file).mode & 007777
+ end
+
+ def memory
+ Puppet::Util.memory
+ end
+
+ # a list of files that we can parse for testing
+ def textfiles
+ textdir = datadir "snippets"
+ Dir.entries(textdir).reject { |f|
+ f =~ /^\./ or f =~ /fail/
+ }.each { |f|
+ yield File.join(textdir, f)
+ }
+ end
+
+ def failers
+ textdir = datadir "failers"
+ # only parse this one file now
+ files = Dir.entries(textdir).reject { |file|
+ file =~ %r{\.swp}
+ }.reject { |file|
+ file =~ %r{\.disabled}
+ }.collect { |file|
+ File.join(textdir,file)
+ }.find_all { |file|
+ FileTest.file?(file)
+ }.sort.each { |file|
+ Puppet.debug "Processing #{file}"
+ yield file
+ }
+ end
+
+ def mk_catalog(*resources)
+ if resources[0].is_a?(String)
+ name = resources.shift
+ else
+ name = :testing
end
-
- def failers
- textdir = datadir "failers"
- # only parse this one file now
- files = Dir.entries(textdir).reject { |file|
- file =~ %r{\.swp}
- }.reject { |file|
- file =~ %r{\.disabled}
- }.collect { |file|
- File.join(textdir,file)
- }.find_all { |file|
- FileTest.file?(file)
- }.sort.each { |file|
- Puppet.debug "Processing #{file}"
- yield file
- }
+ config = Puppet::Resource::Catalog.new :testing do |conf|
+ resources.each { |resource| conf.add_resource resource }
end
- def mk_catalog(*resources)
- if resources[0].is_a?(String)
- name = resources.shift
- else
- name = :testing
- end
- config = Puppet::Resource::Catalog.new :testing do |conf|
- resources.each { |resource| conf.add_resource resource }
- end
-
- config
- end
+ config
+ end
end
module PuppetTest
- include PuppetTest::Support::Utils
-
- def fakedata(dir,pat='*')
- glob = "#{basedir}/test/#{dir}/#{pat}"
- files = Dir.glob(glob,File::FNM_PATHNAME)
- raise Puppet::DevError, "No fakedata matching #{glob}" if files.empty?
- files
- end
- module_function :fakedata
+ include PuppetTest::Support::Utils
+
+ def fakedata(dir,pat='*')
+ glob = "#{basedir}/test/#{dir}/#{pat}"
+ files = Dir.glob(glob,File::FNM_PATHNAME)
+ raise Puppet::DevError, "No fakedata matching #{glob}" if files.empty?
+ files
+ end
+ module_function :fakedata
end
diff --git a/test/lib/puppettest/testcase.rb b/test/lib/puppettest/testcase.rb
index de088a4..b1b22e5 100644
--- a/test/lib/puppettest/testcase.rb
+++ b/test/lib/puppettest/testcase.rb
@@ -8,21 +8,21 @@ require 'puppettest/runnable_test'
require 'test/unit'
class PuppetTest::TestCase < Test::Unit::TestCase
- include PuppetTest
- extend PuppetTest::RunnableTest
+ include PuppetTest
+ extend PuppetTest::RunnableTest
- def self.suite
- # Always skip this parent class. It'd be nice if there were a
- # "supported" way to do this.
- if self == PuppetTest::TestCase
- suite = Test::Unit::TestSuite.new(name)
- return suite
- elsif self.runnable?
- return super
- else
- puts "Skipping #{name}: #{@messages.join(", ")}" if defined? $console
- suite = Test::Unit::TestSuite.new(name)
- return suite
- end
+ def self.suite
+ # Always skip this parent class. It'd be nice if there were a
+ # "supported" way to do this.
+ if self == PuppetTest::TestCase
+ suite = Test::Unit::TestSuite.new(name)
+ return suite
+ elsif self.runnable?
+ return super
+ else
+ puts "Skipping #{name}: #{@messages.join(", ")}" if defined? $console
+ suite = Test::Unit::TestSuite.new(name)
+ return suite
end
+ end
end
diff --git a/test/lib/rake/puppet_testtask.rb b/test/lib/rake/puppet_testtask.rb
index dfdf723..c490e57 100644
--- a/test/lib/rake/puppet_testtask.rb
+++ b/test/lib/rake/puppet_testtask.rb
@@ -4,16 +4,16 @@ require 'rake'
require 'rake/testtask'
module Rake
- class PuppetTestTask < Rake::TestTask
- def rake_loader
- if Integer(RUBY_VERSION.split(/\./)[2]) < 4
- file = super
- else
- file = find_file('rake/puppet_test_loader') or
- fail "unable to find rake test loader"
- end
- file
- end
+ class PuppetTestTask < Rake::TestTask
+ def rake_loader
+ if Integer(RUBY_VERSION.split(/\./)[2]) < 4
+ file = super
+ else
+ file = find_file('rake/puppet_test_loader') or
+ fail "unable to find rake test loader"
+ end
+ file
end
+ end
end
diff --git a/test/network/authconfig.rb b/test/network/authconfig.rb
index 18445bc..f53238d 100755
--- a/test/network/authconfig.rb
+++ b/test/network/authconfig.rb
@@ -7,63 +7,63 @@ require 'puppettest'
require 'puppet/network/authconfig'
class TestAuthConfig < Test::Unit::TestCase
- include PuppetTest
+ include PuppetTest
- def request(call, client, ip)
- r = Puppet::Network::ClientRequest.new(client, ip, false)
- h, m = call.split(".")
- r.handler = h
- r.method = m
- r
- end
+ def request(call, client, ip)
+ r = Puppet::Network::ClientRequest.new(client, ip, false)
+ h, m = call.split(".")
+ r.handler = h
+ r.method = m
+ r
+ end
- def test_parsingconfigfile
- file = tempfile
- assert(Puppet[:authconfig], "No config path")
+ def test_parsingconfigfile
+ file = tempfile
+ assert(Puppet[:authconfig], "No config path")
- Puppet[:authconfig] = file
+ Puppet[:authconfig] = file
- File.open(file, "w") { |f|
- f.puts "[pelementserver.describe]
- allow *.madstop.com
- deny 10.10.1.1
+ File.open(file, "w") { |f|
+ f.puts "[pelementserver.describe]
+ allow *.madstop.com
+ deny 10.10.1.1
[fileserver]
- allow *.madstop.com
- deny 10.10.1.1
+ allow *.madstop.com
+ deny 10.10.1.1
[fileserver.list]
- allow 10.10.1.1
+ allow 10.10.1.1
"
- }
-
- config = nil
- assert_nothing_raised {
- config = Puppet::Network::AuthConfig.new(file)
- }
-
- assert_nothing_raised {
- assert(config.allowed?(request("pelementserver.describe", "culain.madstop.com", "1.1.1.1")), "Did not allow host")
- assert(! config.allowed?(request("pelementserver.describe", "culain.madstop.com", "10.10.1.1")), "Allowed host")
- assert(config.allowed?(request("fileserver.yay", "culain.madstop.com", "10.1.1.1")), "Did not allow host to fs")
- assert(! config.allowed?(request("fileserver.yay", "culain.madstop.com", "10.10.1.1")), "Allowed host to fs")
- assert(config.allowed?(request("fileserver.list", "culain.madstop.com", "10.10.1.1")), "Did not allow host to fs.list")
- }
- end
-
- def test_singleton
- auth = nil
- assert_nothing_raised { auth = Puppet::Network::AuthConfig.main }
- assert(auth, "did not get main authconfig")
-
- other = nil
- assert_nothing_raised { other = Puppet::Network::AuthConfig.main }
-
- assert_equal(
- auth.object_id, other.object_id,
+ }
+
+ config = nil
+ assert_nothing_raised {
+ config = Puppet::Network::AuthConfig.new(file)
+ }
+
+ assert_nothing_raised {
+ assert(config.allowed?(request("pelementserver.describe", "culain.madstop.com", "1.1.1.1")), "Did not allow host")
+ assert(! config.allowed?(request("pelementserver.describe", "culain.madstop.com", "10.10.1.1")), "Allowed host")
+ assert(config.allowed?(request("fileserver.yay", "culain.madstop.com", "10.1.1.1")), "Did not allow host to fs")
+ assert(! config.allowed?(request("fileserver.yay", "culain.madstop.com", "10.10.1.1")), "Allowed host to fs")
+ assert(config.allowed?(request("fileserver.list", "culain.madstop.com", "10.10.1.1")), "Did not allow host to fs.list")
+ }
+ end
+
+ def test_singleton
+ auth = nil
+ assert_nothing_raised { auth = Puppet::Network::AuthConfig.main }
+ assert(auth, "did not get main authconfig")
+
+ other = nil
+ assert_nothing_raised { other = Puppet::Network::AuthConfig.main }
+
+ assert_equal(
+ auth.object_id, other.object_id,
- "did not get same authconfig from class")
- end
+ "did not get same authconfig from class")
+ end
end
diff --git a/test/network/authorization.rb b/test/network/authorization.rb
index cecc1fd..f29fe25 100755
--- a/test/network/authorization.rb
+++ b/test/network/authorization.rb
@@ -7,132 +7,132 @@ require 'puppet/network/authorization'
require 'mocha'
class TestAuthConfig < Test::Unit::TestCase
- include PuppetTest
-
- # A mock class for authconfig
- class FakeAuth
- class << self
- attr_accessor :allow, :exists
- end
- def allowed?(req)
- self.class.allow
- end
- def exists?
- self.class.exists
- end
- end
-
- class AuthTest
- include Puppet::Network::Authorization
-
- def clear
- @loaded.clear
- end
-
- def load(name)
- @loaded ||= []
- @loaded << name
- end
+ include PuppetTest
- def handler_loaded?(name)
- @loaded ||= []
- @loaded.include?(name)
- end
+ # A mock class for authconfig
+ class FakeAuth
+ class << self
+ attr_accessor :allow, :exists
end
-
- def setup
- super
- @obj = AuthTest.new
-
- # Override the authconfig to make life easier
- class << @obj
- def authconfig
- @authconfig ||= FakeAuth.new
- end
- end
- @request = Puppet::Network::ClientRequest.new("host", "ip", false)
- @request.handler = "foo"
- @request.method = "bar"
+ def allowed?(req)
+ self.class.allow
end
-
- def test_authconfig
- obj = AuthTest.new
- auth = nil
- assert_nothing_raised { auth = obj.send(:authconfig) }
- assert(auth, "did not get auth")
- assert_equal(Puppet::Network::AuthConfig.main.object_id, auth.object_id, "did not get main authconfig")
+ def exists?
+ self.class.exists
end
+ end
- def test_authorize
- # Make sure that unauthenticated clients can do puppetca stuff, but
- # nothing else.
- @request.handler = "puppetca"
- @request.method = "yay"
- assert(@obj.authorized?(@request), "Did not allow unauthenticated ca call")
- assert_logged(:notice, /Allowing/, "did not log call")
- @request.handler = "other"
- assert(! @obj.authorized?(@request), "Allowed unauthencated other call")
- assert_logged(:notice, /Denying/, "did not log call")
-
- @request.authenticated = true
- # We start without the namespace auth file, so everything should
- # start out denied
- assert(! @obj.authorized?(@request), "Allowed call with no config file")
- assert_logged(:notice, /Denying/, "did not log call")
-
- # Now set our run_mode to master, so calls are allowed
- Puppet.run_mode.stubs(:master?).returns true
-
- assert(
- @obj.authorized?(@request),
-
- "Denied call with no config file and master")
- assert_logged(:debug, /Allowing/, "did not log call")
+ class AuthTest
+ include Puppet::Network::Authorization
- # Now "create" the file, so we do real tests
- FakeAuth.exists = true
+ def clear
+ @loaded.clear
+ end
- # We start out denying
- assert(! @obj.authorized?(@request), "Allowed call when denying")
- assert_logged(:notice, /Denying/, "did not log call")
+ def load(name)
+ @loaded ||= []
+ @loaded << name
+ end
- FakeAuth.allow = true
- assert(@obj.authorized?(@request), "Denied call when allowing")
- assert_logged(:debug, /Allowing/, "did not log call")
+ def handler_loaded?(name)
+ @loaded ||= []
+ @loaded.include?(name)
end
+ end
- def test_available?
- # Start out false
- assert(! @obj.available?(@request), "Defaulted to true")
- assert_logged(:warning, /requested unavailable/, "did not log call")
+ def setup
+ super
+ @obj = AuthTest.new
- @obj.load(@request.handler)
- assert(@obj.available?(@request), "did not see it loaded")
+ # Override the authconfig to make life easier
+ class << @obj
+ def authconfig
+ @authconfig ||= FakeAuth.new
+ end
end
-
- # Make sure we raise things appropriately
- def test_verify
- # Start out unavailabl
- assert_raise(Puppet::Network::InvalidClientRequest) do
- @obj.verify(@request)
- end
- class << @obj
- def available?(req)
- true
- end
- end
- assert_raise(Puppet::Network::InvalidClientRequest) do
- @obj.verify(@request)
- end
- class << @obj
- def authorized?(req)
- true
- end
- end
- assert_nothing_raised do
- @obj.verify(@request)
- end
+ @request = Puppet::Network::ClientRequest.new("host", "ip", false)
+ @request.handler = "foo"
+ @request.method = "bar"
+ end
+
+ def test_authconfig
+ obj = AuthTest.new
+ auth = nil
+ assert_nothing_raised { auth = obj.send(:authconfig) }
+ assert(auth, "did not get auth")
+ assert_equal(Puppet::Network::AuthConfig.main.object_id, auth.object_id, "did not get main authconfig")
+ end
+
+ def test_authorize
+ # Make sure that unauthenticated clients can do puppetca stuff, but
+ # nothing else.
+ @request.handler = "puppetca"
+ @request.method = "yay"
+ assert(@obj.authorized?(@request), "Did not allow unauthenticated ca call")
+ assert_logged(:notice, /Allowing/, "did not log call")
+ @request.handler = "other"
+ assert(! @obj.authorized?(@request), "Allowed unauthencated other call")
+ assert_logged(:notice, /Denying/, "did not log call")
+
+ @request.authenticated = true
+ # We start without the namespace auth file, so everything should
+ # start out denied
+ assert(! @obj.authorized?(@request), "Allowed call with no config file")
+ assert_logged(:notice, /Denying/, "did not log call")
+
+ # Now set our run_mode to master, so calls are allowed
+ Puppet.run_mode.stubs(:master?).returns true
+
+ assert(
+ @obj.authorized?(@request),
+
+ "Denied call with no config file and master")
+ assert_logged(:debug, /Allowing/, "did not log call")
+
+ # Now "create" the file, so we do real tests
+ FakeAuth.exists = true
+
+ # We start out denying
+ assert(! @obj.authorized?(@request), "Allowed call when denying")
+ assert_logged(:notice, /Denying/, "did not log call")
+
+ FakeAuth.allow = true
+ assert(@obj.authorized?(@request), "Denied call when allowing")
+ assert_logged(:debug, /Allowing/, "did not log call")
+ end
+
+ def test_available?
+ # Start out false
+ assert(! @obj.available?(@request), "Defaulted to true")
+ assert_logged(:warning, /requested unavailable/, "did not log call")
+
+ @obj.load(@request.handler)
+ assert(@obj.available?(@request), "did not see it loaded")
+ end
+
+ # Make sure we raise things appropriately
+ def test_verify
+ # Start out unavailabl
+ assert_raise(Puppet::Network::InvalidClientRequest) do
+ @obj.verify(@request)
+ end
+ class << @obj
+ def available?(req)
+ true
+ end
+ end
+ assert_raise(Puppet::Network::InvalidClientRequest) do
+ @obj.verify(@request)
+ end
+ class << @obj
+ def authorized?(req)
+ true
+ end
+ end
+ assert_nothing_raised do
+ @obj.verify(@request)
end
+ end
end
diff --git a/test/network/authstore.rb b/test/network/authstore.rb
index 9837a46..e608423 100755
--- a/test/network/authstore.rb
+++ b/test/network/authstore.rb
@@ -7,534 +7,534 @@ require 'mocha'
require 'puppet/network/authstore'
class TestAuthStore < Test::Unit::TestCase
- include PuppetTest
- Declaration = Puppet::Network::AuthStore::Declaration
- def mkstore
- store = nil
- assert_nothing_raised {
- store = Puppet::Network::AuthStore.new
- }
-
- store
+ include PuppetTest
+ Declaration = Puppet::Network::AuthStore::Declaration
+ def mkstore
+ store = nil
+ assert_nothing_raised {
+ store = Puppet::Network::AuthStore.new
+ }
+
+ store
+ end
+
+ def setup
+ super
+ @store = mkstore
+ end
+
+ def test_localallow
+ Puppet[:trace] = false
+ assert_nothing_raised {
+ assert(@store.allowed?(nil, nil), "Store disallowed local access")
+ }
+
+ assert_raise(Puppet::DevError) {
+ @store.allowed?("kirby.madstop.com", nil)
+ }
+
+ assert_raise(Puppet::DevError) {
+ @store.allowed?(nil, "192.168.0.1")
+ }
+ end
+
+ def test_simpleips
+ %w{
+ 192.168.0.5
+ 7.0.48.7
+ }.each { |ip|
+ assert_nothing_raised("Failed to @store IP address #{ip}") {
+ @store.allow(ip)
+ }
+
+ assert(@store.allowed?("hosttest.com", ip), "IP #{ip} not allowed")
+ }
+
+ #assert_raise(Puppet::AuthStoreError) {
+ # @store.allow("192.168.674.0")
+ #}
+ end
+
+ def test_ipranges
+ %w{
+ 192.168.0.*
+ 192.168.1.0/24
+ 192.178.*
+ 193.179.0.0/8
+ }.each { |range|
+ assert_nothing_raised("Failed to @store IP range #{range}") {
+ @store.allow(range)
+ }
+ }
+
+ %w{
+ 192.168.0.1
+ 192.168.1.5
+ 192.178.0.5
+ 193.0.0.1
+ }.each { |ip|
+ assert(@store.allowed?("fakename.com", ip), "IP #{ip} is not allowed")
+ }
+ end
+
+ def test_iprangedenials
+ assert_nothing_raised("Failed to @store overlapping IP ranges") {
+ @store.allow("192.168.0.0/16")
+ @store.deny("192.168.0.0/24")
+ }
+
+ assert(@store.allowed?("fake.name", "192.168.1.50"), "/16 ip not allowed")
+ assert(! @store.allowed?("fake.name", "192.168.0.50"), "/24 ip allowed")
+ end
+
+ def test_subdomaindenails
+ assert_nothing_raised("Failed to @store overlapping IP ranges") {
+ @store.allow("*.madstop.com")
+ @store.deny("*.sub.madstop.com")
+ }
+
+
+ assert(
+ @store.allowed?("hostname.madstop.com", "192.168.1.50"),
+
+ "hostname not allowed")
+
+ assert(
+ ! @store.allowed?("name.sub.madstop.com", "192.168.0.50"),
+
+ "subname name allowed")
+ end
+
+ def test_orderingstuff
+ assert_nothing_raised("Failed to @store overlapping IP ranges") {
+ @store.allow("*.madstop.com")
+ @store.deny("192.168.0.0/24")
+ }
+
+
+ assert(
+ @store.allowed?("hostname.madstop.com", "192.168.1.50"),
+
+ "hostname not allowed")
+
+ assert(
+ ! @store.allowed?("hostname.madstop.com", "192.168.0.50"),
+
+ "Host allowed over IP")
+ end
+
+ def test_globalallow
+ assert_nothing_raised("Failed to add global allow") {
+ @store.allow("*")
+ }
+
+ [
+ %w{hostname.com 192.168.0.4},
+ %w{localhost 192.168.0.1},
+ %w{localhost 127.0.0.1}
+
+ ].each { |ary|
+ assert(@store.allowed?(*ary), "Failed to allow #{ary.join(",")}")
+ }
+ end
+
+ def test_store
+ assert_nothing_raised do
+
+ assert_nil(
+ @store.send(:store, :allow, "*.host.com"),
+
+ "store did not return nil")
end
+ assert_equal([Declaration.new(:allow, "*.host.com")],
+ @store.send(:instance_variable_get, "@declarations"),
+ "Did not store declaration")
- def setup
- super
- @store = mkstore
- end
-
- def test_localallow
- Puppet[:trace] = false
- assert_nothing_raised {
- assert(@store.allowed?(nil, nil), "Store disallowed local access")
- }
-
- assert_raise(Puppet::DevError) {
- @store.allowed?("kirby.madstop.com", nil)
- }
-
- assert_raise(Puppet::DevError) {
- @store.allowed?(nil, "192.168.0.1")
- }
- end
-
- def test_simpleips
- %w{
- 192.168.0.5
- 7.0.48.7
- }.each { |ip|
- assert_nothing_raised("Failed to @store IP address #{ip}") {
- @store.allow(ip)
- }
-
- assert(@store.allowed?("hosttest.com", ip), "IP #{ip} not allowed")
- }
-
- #assert_raise(Puppet::AuthStoreError) {
- # @store.allow("192.168.674.0")
- #}
- end
+ # Now add another one and make sure it gets sorted appropriately
+ assert_nothing_raised do
- def test_ipranges
- %w{
- 192.168.0.*
- 192.168.1.0/24
- 192.178.*
- 193.179.0.0/8
- }.each { |range|
- assert_nothing_raised("Failed to @store IP range #{range}") {
- @store.allow(range)
- }
- }
-
- %w{
- 192.168.0.1
- 192.168.1.5
- 192.178.0.5
- 193.0.0.1
- }.each { |ip|
- assert(@store.allowed?("fakename.com", ip), "IP #{ip} is not allowed")
- }
- end
-
- def test_iprangedenials
- assert_nothing_raised("Failed to @store overlapping IP ranges") {
- @store.allow("192.168.0.0/16")
- @store.deny("192.168.0.0/24")
- }
+ assert_nil(
+ @store.send(:store, :allow, "me.host.com"),
- assert(@store.allowed?("fake.name", "192.168.1.50"), "/16 ip not allowed")
- assert(! @store.allowed?("fake.name", "192.168.0.50"), "/24 ip allowed")
+ "store did not return nil")
end
- def test_subdomaindenails
- assert_nothing_raised("Failed to @store overlapping IP ranges") {
- @store.allow("*.madstop.com")
- @store.deny("*.sub.madstop.com")
- }
-
-
- assert(
- @store.allowed?("hostname.madstop.com", "192.168.1.50"),
-
- "hostname not allowed")
-
- assert(
- ! @store.allowed?("name.sub.madstop.com", "192.168.0.50"),
-
- "subname name allowed")
- end
-
- def test_orderingstuff
- assert_nothing_raised("Failed to @store overlapping IP ranges") {
- @store.allow("*.madstop.com")
- @store.deny("192.168.0.0/24")
- }
-
-
- assert(
- @store.allowed?("hostname.madstop.com", "192.168.1.50"),
-
- "hostname not allowed")
-
- assert(
- ! @store.allowed?("hostname.madstop.com", "192.168.0.50"),
-
- "Host allowed over IP")
- end
-
- def test_globalallow
- assert_nothing_raised("Failed to add global allow") {
- @store.allow("*")
- }
+ assert_equal(
[
- %w{hostname.com 192.168.0.4},
- %w{localhost 192.168.0.1},
- %w{localhost 127.0.0.1}
-
- ].each { |ary|
- assert(@store.allowed?(*ary), "Failed to allow #{ary.join(",")}")
- }
- end
-
- def test_store
- assert_nothing_raised do
-
- assert_nil(
- @store.send(:store, :allow, "*.host.com"),
+ Declaration.new(:allow, "me.host.com"),
- "store did not return nil")
- end
- assert_equal([Declaration.new(:allow, "*.host.com")],
- @store.send(:instance_variable_get, "@declarations"),
- "Did not store declaration")
+ Declaration.new(:allow, "*.host.com")
+ ],
+ @store.send(:instance_variable_get, "@declarations"),
+ "Did not sort declarations")
+ end
- # Now add another one and make sure it gets sorted appropriately
- assert_nothing_raised do
+ def test_allow_and_deny
+ store = Puppet::Network::AuthStore.new
+ store.expects(:store).with(:allow, "host.com")
+ store.allow("host.com")
- assert_nil(
- @store.send(:store, :allow, "me.host.com"),
+ store = Puppet::Network::AuthStore.new
+ store.expects(:store).with(:deny, "host.com")
+ store.deny("host.com")
- "store did not return nil")
- end
+ store = Puppet::Network::AuthStore.new
+ assert_nothing_raised do
+ assert_nil(
+ store.allow("*"),
- assert_equal(
- [
- Declaration.new(:allow, "me.host.com"),
-
- Declaration.new(:allow, "*.host.com")
- ],
- @store.send(:instance_variable_get, "@declarations"),
- "Did not sort declarations")
+ "allow did not return nil")
end
- def test_allow_and_deny
- store = Puppet::Network::AuthStore.new
- store.expects(:store).with(:allow, "host.com")
- store.allow("host.com")
-
- store = Puppet::Network::AuthStore.new
- store.expects(:store).with(:deny, "host.com")
- store.deny("host.com")
-
- store = Puppet::Network::AuthStore.new
- assert_nothing_raised do
-
- assert_nil(
- store.allow("*"),
-
- "allow did not return nil")
- end
+ assert(
+ store.globalallow?,
+
+ "did not enable global allow")
+ end
+
+ def test_hostnames
+ Puppet[:trace] = false
+ %w{
+ kirby.madstop.com
+ luke.madstop.net
+ name-other.madstop.net
+ }.each { |name|
+ assert_nothing_raised("Failed to @store simple name #{name}") {
+ @store.allow(name)
+ }
+ assert(@store.allowed?(name, "192.168.0.1"), "Name #{name} not allowed")
+ }
+
+ %w{
+ ^invalid!
+ inval$id
+
+ }.each { |pat|
+
+ assert_raise(
+ Puppet::AuthStoreError,
+
+ "name '#{pat}' was allowed") {
+ @store.allow(pat)
+ }
+ }
+ end
+
+ def test_domains
+ assert_nothing_raised("Failed to @store domains") {
+ @store.allow("*.a.very.long.domain.name.com")
+ @store.allow("*.madstop.com")
+ @store.allow("*.some-other.net")
+ @store.allow("*.much.longer.more-other.net")
+ }
+
+ %w{
+ madstop.com
+ culain.madstop.com
+ kirby.madstop.com
+ funtest.some-other.net
+ ya-test.madstop.com
+ some.much.much.longer.more-other.net
+ }.each { |name|
+ assert(@store.allowed?(name, "192.168.0.1"), "Host #{name} not allowed")
+ }
+
+ assert_raise(Puppet::AuthStoreError) {
+ @store.allow("domain.*.com")
+ }
+
+
+ assert(
+ !@store.allowed?("very.long.domain.name.com", "1.2.3.4"),
+
+ "Long hostname allowed")
+
+ assert_raise(Puppet::AuthStoreError) {
+ @store.allow("domain.*.other.com")
+ }
+ end
+
+ # #531
+ def test_case_insensitivity
+ @store.allow("hostname.com")
+
+ %w{hostname.com Hostname.COM hostname.Com HOSTNAME.COM}.each do |name|
+ assert(@store.allowed?(name, "127.0.0.1"), "did not allow #{name}")
+ end
+ end
- assert(
- store.globalallow?,
+ def test_allowed?
+ Puppet[:trace] = false
- "did not enable global allow")
- end
+ assert(
+ @store.allowed?(nil, nil),
- def test_hostnames
- Puppet[:trace] = false
- %w{
- kirby.madstop.com
- luke.madstop.net
- name-other.madstop.net
- }.each { |name|
- assert_nothing_raised("Failed to @store simple name #{name}") {
- @store.allow(name)
- }
- assert(@store.allowed?(name, "192.168.0.1"), "Name #{name} not allowed")
- }
-
- %w{
- ^invalid!
- inval$id
-
- }.each { |pat|
-
- assert_raise(
- Puppet::AuthStoreError,
-
- "name '#{pat}' was allowed") {
- @store.allow(pat)
- }
- }
+ "Did not default to true for local checks")
+ assert_raise(Puppet::DevError, "did not fail on one input") do
+ @store.allowed?("host.com", nil)
end
-
- def test_domains
- assert_nothing_raised("Failed to @store domains") {
- @store.allow("*.a.very.long.domain.name.com")
- @store.allow("*.madstop.com")
- @store.allow("*.some-other.net")
- @store.allow("*.much.longer.more-other.net")
- }
-
- %w{
- madstop.com
- culain.madstop.com
- kirby.madstop.com
- funtest.some-other.net
- ya-test.madstop.com
- some.much.much.longer.more-other.net
- }.each { |name|
- assert(@store.allowed?(name, "192.168.0.1"), "Host #{name} not allowed")
- }
-
- assert_raise(Puppet::AuthStoreError) {
- @store.allow("domain.*.com")
- }
-
-
- assert(
- !@store.allowed?("very.long.domain.name.com", "1.2.3.4"),
-
- "Long hostname allowed")
-
- assert_raise(Puppet::AuthStoreError) {
- @store.allow("domain.*.other.com")
- }
+ assert_raise(Puppet::DevError, "did not fail on one input") do
+ @store.allowed?(nil, "192.168.0.1")
end
- # #531
- def test_case_insensitivity
- @store.allow("hostname.com")
+ end
- %w{hostname.com Hostname.COM hostname.Com HOSTNAME.COM}.each do |name|
- assert(@store.allowed?(name, "127.0.0.1"), "did not allow #{name}")
- end
- end
+ # Make sure more specific allows and denies win over generalities
+ def test_specific_overrides
+ @store.allow("host.madstop.com")
+ @store.deny("*.madstop.com")
- def test_allowed?
- Puppet[:trace] = false
- assert(
- @store.allowed?(nil, nil),
+ assert(
+ @store.allowed?("host.madstop.com", "192.168.0.1"),
- "Did not default to true for local checks")
- assert_raise(Puppet::DevError, "did not fail on one input") do
- @store.allowed?("host.com", nil)
- end
- assert_raise(Puppet::DevError, "did not fail on one input") do
- @store.allowed?(nil, "192.168.0.1")
- end
+ "More specific allowal by name failed")
- end
+ @store.allow("192.168.0.1")
+ @store.deny("192.168.0.0/24")
- # Make sure more specific allows and denies win over generalities
- def test_specific_overrides
- @store.allow("host.madstop.com")
- @store.deny("*.madstop.com")
+ assert(
+ @store.allowed?("host.madstop.com", "192.168.0.1"),
- assert(
- @store.allowed?("host.madstop.com", "192.168.0.1"),
+ "More specific allowal by ip failed")
+ end
- "More specific allowal by name failed")
+ def test_dynamic_backreferences
+ @store.allow("$1.madstop.com")
- @store.allow("192.168.0.1")
- @store.deny("192.168.0.0/24")
+ assert_nothing_raised { @store.interpolate([nil, "host"]) }
+ assert(@store.allowed?("host.madstop.com", "192.168.0.1"), "interpolation failed")
+ assert_nothing_raised { @store.reset_interpolation }
+ end
+ def test_dynamic_ip
+ @store.allow("192.168.0.$1")
- assert(
- @store.allowed?("host.madstop.com", "192.168.0.1"),
+ assert_nothing_raised { @store.interpolate([nil, "12"]) }
+ assert(@store.allowed?("host.madstop.com", "192.168.0.12"), "interpolation failed")
+ assert_nothing_raised { @store.reset_interpolation }
+ end
- "More specific allowal by ip failed")
- end
+ def test_multiple_dynamic_backreferences
+ @store.allow("$1.$2")
- def test_dynamic_backreferences
- @store.allow("$1.madstop.com")
+ assert_nothing_raised { @store.interpolate([nil, "host", "madstop.com"]) }
+ assert(@store.allowed?("host.madstop.com", "192.168.0.1"), "interpolation failed")
+ assert_nothing_raised { @store.reset_interpolation }
+ end
- assert_nothing_raised { @store.interpolate([nil, "host"]) }
- assert(@store.allowed?("host.madstop.com", "192.168.0.1"), "interpolation failed")
- assert_nothing_raised { @store.reset_interpolation }
- end
-
- def test_dynamic_ip
- @store.allow("192.168.0.$1")
+ def test_multithreaded_allow_with_dynamic_backreferences
+ @store.allow("$1.madstop.com")
- assert_nothing_raised { @store.interpolate([nil, "12"]) }
- assert(@store.allowed?("host.madstop.com", "192.168.0.12"), "interpolation failed")
- assert_nothing_raised { @store.reset_interpolation }
- end
-
- def test_multiple_dynamic_backreferences
- @store.allow("$1.$2")
-
- assert_nothing_raised { @store.interpolate([nil, "host", "madstop.com"]) }
- assert(@store.allowed?("host.madstop.com", "192.168.0.1"), "interpolation failed")
- assert_nothing_raised { @store.reset_interpolation }
- end
-
- def test_multithreaded_allow_with_dynamic_backreferences
- @store.allow("$1.madstop.com")
-
- threads = []
- 9.times { |a|
- threads << Thread.new {
- 9.times { |b|
- Thread.pass
- @store.interpolate([nil, "a#{b}", "madstop.com"])
- Thread.pass
- assert( @store.allowed?("a#{b}.madstop.com", "192.168.0.1") )
- Thread.pass
- @store.reset_interpolation
- Thread.pass
- }
- }
- }
- threads.each { |th| th.join }
- end
+ threads = []
+ 9.times { |a|
+ threads << Thread.new {
+ 9.times { |b|
+ Thread.pass
+ @store.interpolate([nil, "a#{b}", "madstop.com"])
+ Thread.pass
+ assert( @store.allowed?("a#{b}.madstop.com", "192.168.0.1") )
+ Thread.pass
+ @store.reset_interpolation
+ Thread.pass
+ }
+ }
+ }
+ threads.each { |th| th.join }
+ end
end
class TestAuthStoreDeclaration < PuppetTest::TestCase
- include PuppetTest
- Declaration = Puppet::Network::AuthStore::Declaration
-
- def setup
- super
- @decl = Declaration.new(:allow, "hostname.com")
+ include PuppetTest
+ Declaration = Puppet::Network::AuthStore::Declaration
+
+ def setup
+ super
+ @decl = Declaration.new(:allow, "hostname.com")
+ end
+
+ def test_parse
+ {
+ "192.168.0.1" => [:ip, IPAddr.new("192.168.0.1"), nil],
+ "2001:700:300:1800::" => [:ip, IPAddr.new("2001:700:300:1800::"), nil],
+ "2001:700:300:1800::/64" => [:ip, IPAddr.new("2001:700:300:1800::/64"), 64],
+ "192.168.0.1/32" => [:ip, IPAddr.new("192.168.0.1/32"), 32],
+ "192.168.0.1/24" => [:ip, IPAddr.new("192.168.0.1/24"), 24],
+ "192.*" => [:ip, IPAddr.new("192.0.0.0/8"), 8],
+ "192.168.*" => [:ip, IPAddr.new("192.168.0.0/16"), 16],
+ "192.168.0.*" => [:ip, IPAddr.new("192.168.0.0/24"), 24],
+ "hostname.com" => [:domain, %w{com hostname}, nil],
+ "Hostname.COM" => [:domain, %w{com hostname}, nil],
+ "billy.Hostname.COM" => [:domain, %w{com hostname billy}, nil],
+ "billy-jean.Hostname.COM" => [:domain, %w{com hostname billy-jean}, nil],
+ "*.hostname.COM" => [:domain, %w{com hostname}, 2],
+ "*.hostname.COM" => [:domain, %w{com hostname}, 2],
+ "$1.hostname.COM" => [:dynamic, %w{com hostname $1}, nil],
+ "192.168.$1.$2" => [:dynamic, %w{$2 $1 168 192}, nil],
+ "8A5BC90C-B8FD-4CBC-81DA-BAD84D551791" => [:opaque, %w{8A5BC90C-B8FD-4CBC-81DA-BAD84D551791}, nil]
+ }.each do |input, output|
+
+ # Create a new decl each time, so values aren't cached.
+ assert_nothing_raised do
+ @decl = Declaration.new(:allow, input)
+ end
+
+ [:name, :pattern, :length].zip(output).each do |method, value|
+ assert_equal(value, @decl.send(method), "Got incorrect value for #{method} from #{input}")
+ end
end
- def test_parse
- {
- "192.168.0.1" => [:ip, IPAddr.new("192.168.0.1"), nil],
- "2001:700:300:1800::" => [:ip, IPAddr.new("2001:700:300:1800::"), nil],
- "2001:700:300:1800::/64" => [:ip, IPAddr.new("2001:700:300:1800::/64"), 64],
- "192.168.0.1/32" => [:ip, IPAddr.new("192.168.0.1/32"), 32],
- "192.168.0.1/24" => [:ip, IPAddr.new("192.168.0.1/24"), 24],
- "192.*" => [:ip, IPAddr.new("192.0.0.0/8"), 8],
- "192.168.*" => [:ip, IPAddr.new("192.168.0.0/16"), 16],
- "192.168.0.*" => [:ip, IPAddr.new("192.168.0.0/24"), 24],
- "hostname.com" => [:domain, %w{com hostname}, nil],
- "Hostname.COM" => [:domain, %w{com hostname}, nil],
- "billy.Hostname.COM" => [:domain, %w{com hostname billy}, nil],
- "billy-jean.Hostname.COM" => [:domain, %w{com hostname billy-jean}, nil],
- "*.hostname.COM" => [:domain, %w{com hostname}, 2],
- "*.hostname.COM" => [:domain, %w{com hostname}, 2],
- "$1.hostname.COM" => [:dynamic, %w{com hostname $1}, nil],
- "192.168.$1.$2" => [:dynamic, %w{$2 $1 168 192}, nil],
- "8A5BC90C-B8FD-4CBC-81DA-BAD84D551791" => [:opaque, %w{8A5BC90C-B8FD-4CBC-81DA-BAD84D551791}, nil]
- }.each do |input, output|
-
- # Create a new decl each time, so values aren't cached.
- assert_nothing_raised do
- @decl = Declaration.new(:allow, input)
- end
-
- [:name, :pattern, :length].zip(output).each do |method, value|
- assert_equal(value, @decl.send(method), "Got incorrect value for #{method} from #{input}")
- end
- end
-
- %w{-hostname.com hostname.*}.each do |input|
- assert_raise(Puppet::AuthStoreError, "Did not fail on #{input}") do
- @decl.pattern = input
- end
- end
-
- ["hostname .com", "192.168 .0.1"].each do |input|
- assert_raise(Puppet::AuthStoreError, "Did not fail on #{input}") do
- @decl.pattern = input
- end
- end
+ %w{-hostname.com hostname.*}.each do |input|
+ assert_raise(Puppet::AuthStoreError, "Did not fail on #{input}") do
+ @decl.pattern = input
+ end
end
- def test_result
- ["allow", :allow].each do |val|
- assert_nothing_raised { @decl.type = val }
- assert_equal(true, @decl.result, "did not result to true with #{val.inspect}")
- end
+ ["hostname .com", "192.168 .0.1"].each do |input|
+ assert_raise(Puppet::AuthStoreError, "Did not fail on #{input}") do
+ @decl.pattern = input
+ end
+ end
+ end
- [:deny, "deny"].each do |val|
- assert_nothing_raised { @decl.type = val }
+ def test_result
+ ["allow", :allow].each do |val|
+ assert_nothing_raised { @decl.type = val }
+ assert_equal(true, @decl.result, "did not result to true with #{val.inspect}")
+ end
- assert_equal(
- false, @decl.result,
+ [:deny, "deny"].each do |val|
+ assert_nothing_raised { @decl.type = val }
- "did not result to false with #{val.inspect}")
- end
+ assert_equal(
+ false, @decl.result,
- ["yay", 1, nil, false, true].each do |val|
- assert_raise(ArgumentError, "Did not fail on #{val.inspect}") do
- @decl.type = val
- end
- end
+ "did not result to false with #{val.inspect}")
end
- def test_munge_name
- {
- "hostname.com" => %w{com hostname},
- "alley.hostname.com" => %w{com hostname alley},
- "*.hostname.com" => %w{com hostname *},
- "*.HOSTNAME.Com" => %w{com hostname *},
- "*.HOSTNAME.Com" => %w{com hostname *},
-
- }.each do |input, output|
- assert_equal(output, @decl.send(:munge_name, input), "munged #{input} incorrectly")
- end
+ ["yay", 1, nil, false, true].each do |val|
+ assert_raise(ArgumentError, "Did not fail on #{val.inspect}") do
+ @decl.type = val
+ end
end
-
- # Make sure people can specify TLDs
- def test_match_tlds
- assert_nothing_raised {
- @decl.pattern = "*.tld"
- }
-
- assert_equal(%w{tld}, @decl.pattern, "Failed to allow custom tld")
+ end
+
+ def test_munge_name
+ {
+ "hostname.com" => %w{com hostname},
+ "alley.hostname.com" => %w{com hostname alley},
+ "*.hostname.com" => %w{com hostname *},
+ "*.HOSTNAME.Com" => %w{com hostname *},
+ "*.HOSTNAME.Com" => %w{com hostname *},
+
+ }.each do |input, output|
+ assert_equal(output, @decl.send(:munge_name, input), "munged #{input} incorrectly")
end
+ end
- # Make sure we sort correctly.
- def test_sorting
- # Make sure declarations with no length sort first.
- host_exact = Declaration.new(:allow, "host.com")
- host_range = Declaration.new(:allow, "*.host.com")
+ # Make sure people can specify TLDs
+ def test_match_tlds
+ assert_nothing_raised {
+ @decl.pattern = "*.tld"
+ }
- ip_exact = Declaration.new(:allow, "192.168.0.1")
- ip_range = Declaration.new(:allow, "192.168.0.*")
+ assert_equal(%w{tld}, @decl.pattern, "Failed to allow custom tld")
+ end
+ # Make sure we sort correctly.
+ def test_sorting
+ # Make sure declarations with no length sort first.
+ host_exact = Declaration.new(:allow, "host.com")
+ host_range = Declaration.new(:allow, "*.host.com")
- assert_equal(
- -1, host_exact <=> host_range,
+ ip_exact = Declaration.new(:allow, "192.168.0.1")
+ ip_range = Declaration.new(:allow, "192.168.0.*")
- "exact name match did not sort first")
+ assert_equal(
+ -1, host_exact <=> host_range,
- assert_equal(
- -1, ip_exact <=> ip_range,
+ "exact name match did not sort first")
- "exact ip match did not sort first")
- # Next make sure we sort by length
- ip_long = Declaration.new(:allow, "192.168.*")
- assert_equal(-1, ip_range <=> ip_long, "/16 sorted before /24 in ip")
+ assert_equal(
+ -1, ip_exact <=> ip_range,
- # Now try it using masks
- ip24 = Declaration.new(:allow, "192.168.0.0/24")
- ip16 = Declaration.new(:allow, "192.168.0.0/16")
+ "exact ip match did not sort first")
- assert_equal(-1, ip24 <=> ip16, "/16 sorted before /24 in ip with masks")
+ # Next make sure we sort by length
+ ip_long = Declaration.new(:allow, "192.168.*")
+ assert_equal(-1, ip_range <=> ip_long, "/16 sorted before /24 in ip")
- # Make sure ip checks sort before host checks
- assert_equal(-1, ip_exact <=> host_exact, "IP exact did not sort before host exact")
+ # Now try it using masks
+ ip24 = Declaration.new(:allow, "192.168.0.0/24")
+ ip16 = Declaration.new(:allow, "192.168.0.0/16")
+ assert_equal(-1, ip24 <=> ip16, "/16 sorted before /24 in ip with masks")
- assert_equal(
- -1, ip_range <=> host_range,
+ # Make sure ip checks sort before host checks
+ assert_equal(-1, ip_exact <=> host_exact, "IP exact did not sort before host exact")
- "IP range did not sort before host range")
- host_long = Declaration.new(:allow, "*.domain.host.com")
+ assert_equal(
+ -1, ip_range <=> host_range,
- assert_equal(-1, host_long <=> host_range, "did not sort by domain length")
+ "IP range did not sort before host range")
- # Now make sure denies sort before allows, for equivalent
- # declarations.
- host_deny = Declaration.new(:deny, "host.com")
- assert_equal(-1, host_deny <=> host_exact, "deny did not sort before allow when exact")
+ host_long = Declaration.new(:allow, "*.domain.host.com")
- host_range_deny = Declaration.new(:deny, "*.host.com")
- assert_equal(-1, host_range_deny <=> host_range, "deny did not sort before allow when ranged")
+ assert_equal(-1, host_long <=> host_range, "did not sort by domain length")
- ip_allow = Declaration.new(:allow, "192.168.0.0/16")
- ip_deny = Declaration.new(:deny, "192.168.0.0/16")
+ # Now make sure denies sort before allows, for equivalent
+ # declarations.
+ host_deny = Declaration.new(:deny, "host.com")
+ assert_equal(-1, host_deny <=> host_exact, "deny did not sort before allow when exact")
+ host_range_deny = Declaration.new(:deny, "*.host.com")
+ assert_equal(-1, host_range_deny <=> host_range, "deny did not sort before allow when ranged")
- assert_equal(
- -1, ip_deny <=> ip_allow,
+ ip_allow = Declaration.new(:allow, "192.168.0.0/16")
+ ip_deny = Declaration.new(:deny, "192.168.0.0/16")
- "deny did not sort before allow in ip range")
- %w{host.com *.domain.com 192.168.0.1 192.168.0.1/24}.each do |decl|
- assert_equal(0, Declaration.new(:allow, decl) <=>
- Declaration.new(:allow, decl),
- "Equivalent declarations for #{decl} were considered different"
- )
- end
- end
+ assert_equal(
+ -1, ip_deny <=> ip_allow,
- def test_match?
- host = Declaration.new(:allow, "host.com")
- host.expects(:matchname?).with("host.com")
- host.match?("host.com", "192.168.0.1")
+ "deny did not sort before allow in ip range")
- ip = Declaration.new(:allow, "192.168.0.1")
- ip.pattern.expects(:include?)
- ip.match?("host.com", "192.168.0.1")
+ %w{host.com *.domain.com 192.168.0.1 192.168.0.1/24}.each do |decl|
+ assert_equal(0, Declaration.new(:allow, decl) <=>
+ Declaration.new(:allow, decl),
+ "Equivalent declarations for #{decl} were considered different"
+ )
end
-
- def test_matchname?
- host = Declaration.new(:allow, "host.com")
- assert(host.send(:matchname?, "host.com"), "exact did not match")
- assert(! host.send(:matchname?, "yay.com"), "incorrect match")
-
- domain = Declaration.new(:allow, "*.domain.com")
- %w{host.domain.com domain.com very.long.domain.com very-long.domain.com }.each do |name|
- assert(domain.send(:matchname?, name), "Did not match #{name}")
- end
+ end
+
+ def test_match?
+ host = Declaration.new(:allow, "host.com")
+ host.expects(:matchname?).with("host.com")
+ host.match?("host.com", "192.168.0.1")
+
+ ip = Declaration.new(:allow, "192.168.0.1")
+ ip.pattern.expects(:include?)
+ ip.match?("host.com", "192.168.0.1")
+ end
+
+ def test_matchname?
+ host = Declaration.new(:allow, "host.com")
+ assert(host.send(:matchname?, "host.com"), "exact did not match")
+ assert(! host.send(:matchname?, "yay.com"), "incorrect match")
+
+ domain = Declaration.new(:allow, "*.domain.com")
+ %w{host.domain.com domain.com very.long.domain.com very-long.domain.com }.each do |name|
+ assert(domain.send(:matchname?, name), "Did not match #{name}")
end
+ end
end
diff --git a/test/network/client/ca.rb b/test/network/client/ca.rb
index 2735083..5037fe4 100755
--- a/test/network/client/ca.rb
+++ b/test/network/client/ca.rb
@@ -8,62 +8,62 @@ require 'puppet/network/client/ca'
require 'puppet/sslcertificates/support'
class TestClientCA < Test::Unit::TestCase
- include PuppetTest::ServerTest
+ include PuppetTest::ServerTest
- def setup
- Puppet::Util::SUIDManager.stubs(:asuser).yields
- super
- @ca = Puppet::Network::Handler.ca.new
- @client = Puppet::Network::Client.ca.new :CA => @ca
- end
-
- def test_request_cert
- assert_nothing_raised("Could not request cert") do
- @client.request_cert
- end
+ def setup
+ Puppet::Util::SUIDManager.stubs(:asuser).yields
+ super
+ @ca = Puppet::Network::Handler.ca.new
+ @client = Puppet::Network::Client.ca.new :CA => @ca
+ end
- [:hostprivkey, :hostcert, :localcacert].each do |name|
- assert(FileTest.exists?(Puppet.settings[name]), "Did not create cert #{name}")
- end
+ def test_request_cert
+ assert_nothing_raised("Could not request cert") do
+ @client.request_cert
end
- # Make sure the ca defaults to specific ports and names
- def test_ca_server
- Puppet.settings.stubs(:value).returns "eh"
- Puppet.settings.expects(:value).with(:ca_server).returns("myca")
- Puppet.settings.expects(:value).with(:ca_port).returns(321)
- Puppet.settings.stubs(:value).with(:http_proxy_host).returns(nil)
- Puppet.settings.stubs(:value).with(:http_proxy_port).returns(nil)
- Puppet.settings.stubs(:value).with(:http_keepalive).returns(false)
- Puppet.settings.stubs(:value).with(:configtimeout).returns(180)
-
- # Just throw an error; the important thing is the values, not what happens next.
- Net::HTTP.stubs(:new).with("myca", 321, nil, nil).raises(ArgumentError)
- assert_raise(ArgumentError) { Puppet::Network::Client.ca.new }
+ [:hostprivkey, :hostcert, :localcacert].each do |name|
+ assert(FileTest.exists?(Puppet.settings[name]), "Did not create cert #{name}")
end
+ end
- # #578
- def test_invalid_certs_are_not_written
- # Run the get once, which should be valid
+ # Make sure the ca defaults to specific ports and names
+ def test_ca_server
+ Puppet.settings.stubs(:value).returns "eh"
+ Puppet.settings.expects(:value).with(:ca_server).returns("myca")
+ Puppet.settings.expects(:value).with(:ca_port).returns(321)
+ Puppet.settings.stubs(:value).with(:http_proxy_host).returns(nil)
+ Puppet.settings.stubs(:value).with(:http_proxy_port).returns(nil)
+ Puppet.settings.stubs(:value).with(:http_keepalive).returns(false)
+ Puppet.settings.stubs(:value).with(:configtimeout).returns(180)
- assert_nothing_raised("Could not get a certificate") do
- @client.request_cert
- end
+ # Just throw an error; the important thing is the values, not what happens next.
+ Net::HTTP.stubs(:new).with("myca", 321, nil, nil).raises(ArgumentError)
+ assert_raise(ArgumentError) { Puppet::Network::Client.ca.new }
+ end
- # Now remove the cert and keys, so we get a broken cert
- File.unlink(Puppet[:hostcert])
- File.unlink(Puppet[:localcacert])
- File.unlink(Puppet[:hostprivkey])
+ # #578
+ def test_invalid_certs_are_not_written
+ # Run the get once, which should be valid
- @client = Puppet::Network::Client.ca.new :CA => @ca
- @ca.expects(:getcert).returns("yay") # not a valid cert
- # Now make sure it fails, since we'll get the old cert but have new keys
- assert_raise(Puppet::Network::Client::CA::InvalidCertificate, "Did not fail on invalid cert") do
- @client.request_cert
- end
+ assert_nothing_raised("Could not get a certificate") do
+ @client.request_cert
+ end
+
+ # Now remove the cert and keys, so we get a broken cert
+ File.unlink(Puppet[:hostcert])
+ File.unlink(Puppet[:localcacert])
+ File.unlink(Puppet[:hostprivkey])
- # And then make sure the cert isn't written to disk
- assert(! FileTest.exists?(Puppet[:hostcert]), "Invalid cert got written to disk")
+ @client = Puppet::Network::Client.ca.new :CA => @ca
+ @ca.expects(:getcert).returns("yay") # not a valid cert
+ # Now make sure it fails, since we'll get the old cert but have new keys
+ assert_raise(Puppet::Network::Client::CA::InvalidCertificate, "Did not fail on invalid cert") do
+ @client.request_cert
end
+
+ # And then make sure the cert isn't written to disk
+ assert(! FileTest.exists?(Puppet[:hostcert]), "Invalid cert got written to disk")
+ end
end
diff --git a/test/network/client/dipper.rb b/test/network/client/dipper.rb
index 17298c4..d4f7846 100755
--- a/test/network/client/dipper.rb
+++ b/test/network/client/dipper.rb
@@ -6,29 +6,29 @@ require 'puppettest'
require 'puppet/file_bucket/dipper'
class TestDipperClient < Test::Unit::TestCase
- include PuppetTest::ServerTest
-
- def setup
- super
- @dipper = Puppet::FileBucket::Dipper.new(:Path => tempfile)
+ include PuppetTest::ServerTest
+
+ def setup
+ super
+ @dipper = Puppet::FileBucket::Dipper.new(:Path => tempfile)
+ end
+
+ # Make sure we can create a new file with 'restore'.
+ def test_restore_to_new_file
+ file = tempfile
+ text = "asdf;lkajseofiqwekj"
+ File.open(file, "w") { |f| f.puts text }
+ md5 = nil
+ assert_nothing_raised("Could not send file") do
+ md5 = @dipper.backup(file)
end
- # Make sure we can create a new file with 'restore'.
- def test_restore_to_new_file
- file = tempfile
- text = "asdf;lkajseofiqwekj"
- File.open(file, "w") { |f| f.puts text }
- md5 = nil
- assert_nothing_raised("Could not send file") do
- md5 = @dipper.backup(file)
- end
-
- newfile = tempfile
- assert_nothing_raised("could not restore to new path") do
- @dipper.restore(newfile, md5)
- end
-
- assert_equal(File.read(file), File.read(newfile), "did not restore correctly")
+ newfile = tempfile
+ assert_nothing_raised("could not restore to new path") do
+ @dipper.restore(newfile, md5)
end
+
+ assert_equal(File.read(file), File.read(newfile), "did not restore correctly")
+ end
end
diff --git a/test/network/client_request.rb b/test/network/client_request.rb
index 3a35706..25fc57f 100755
--- a/test/network/client_request.rb
+++ b/test/network/client_request.rb
@@ -7,32 +7,32 @@ require 'puppettest'
require 'puppet/network/client_request'
class TestClientRequest < Test::Unit::TestCase
- include PuppetTest
+ include PuppetTest
- def test_initialize
- req = nil
- assert_nothing_raised do
- req = Puppet::Network::ClientRequest.new("name", "ip", false)
- end
+ def test_initialize
+ req = nil
+ assert_nothing_raised do
+ req = Puppet::Network::ClientRequest.new("name", "ip", false)
+ end
- assert_equal("name", req.name, "host name was not set correctly")
- assert_equal("ip", req.ip, "host ip was not set correctly")
- assert_equal(false, req.authenticated, "host auth was not set correctly")
- assert(! req.authenticated, "host was incorrectly considered authenticated")
+ assert_equal("name", req.name, "host name was not set correctly")
+ assert_equal("ip", req.ip, "host ip was not set correctly")
+ assert_equal(false, req.authenticated, "host auth was not set correctly")
+ assert(! req.authenticated, "host was incorrectly considered authenticated")
- req.authenticated = true
- assert(req.authenticated, "host was not considered authenticated")
+ req.authenticated = true
+ assert(req.authenticated, "host was not considered authenticated")
- assert_raise(ArgumentError) do
- req.call
- end
+ assert_raise(ArgumentError) do
+ req.call
+ end
- req.handler = "yay"
- req.method = "foo"
- assert_equal("yay.foo", req.call, "call was not built correctly")
+ req.handler = "yay"
+ req.method = "foo"
+ assert_equal("yay.foo", req.call, "call was not built correctly")
- assert_equal("name(ip)", req.to_s, "request string not correct")
- end
+ assert_equal("name(ip)", req.to_s, "request string not correct")
+ end
end
diff --git a/test/network/handler/ca.rb b/test/network/handler/ca.rb
index 401b8d5..79a1b15 100755
--- a/test/network/handler/ca.rb
+++ b/test/network/handler/ca.rb
@@ -9,265 +9,265 @@ require 'mocha'
$short = (ARGV.length > 0 and ARGV[0] == "short")
class TestCA < Test::Unit::TestCase
- include PuppetTest::ServerTest
-
- def setup
- Puppet::Util::SUIDManager.stubs(:asuser).yields
- super
- end
-
- # Verify that we're autosigning. We have to autosign a "different" machine,
- # since we always autosign the CA server's certificate.
- def test_autocertgeneration
- ca = nil
-
- # create our ca
- assert_nothing_raised {
- ca = Puppet::Network::Handler.ca.new(:autosign => true)
- }
-
- # create a cert with a fake name
- key = nil
- csr = nil
- cert = nil
- hostname = "test.domain.com"
- assert_nothing_raised {
- cert = Puppet::SSLCertificates::Certificate.new(
- :name => "test.domain.com"
- )
- }
-
- # make the request
- assert_nothing_raised {
- cert.mkcsr
- }
-
- # and get it signed
- certtext = nil
- cacerttext = nil
- assert_nothing_raised {
- certtext, cacerttext = ca.getcert(cert.csr.to_s)
- }
-
- # they should both be strings
- assert_instance_of(String, certtext)
- assert_instance_of(String, cacerttext)
-
- # and they should both be valid certs
- assert_nothing_raised {
- OpenSSL::X509::Certificate.new(certtext)
- }
- assert_nothing_raised {
- OpenSSL::X509::Certificate.new(cacerttext)
- }
-
- # and pull it again, just to make sure we're getting the same thing
- newtext = nil
- assert_nothing_raised {
- newtext, cacerttext = ca.getcert(
- cert.csr.to_s, "test.reductivelabs.com", "127.0.0.1"
- )
- }
-
- assert_equal(certtext,newtext)
- end
-
- # this time don't use autosign
- def test_storeAndSign
- ca = nil
- caserv = nil
-
- # make our CA server
- assert_nothing_raised {
- caserv = Puppet::Network::Handler.ca.new(:autosign => false)
- }
-
- # retrieve the actual ca object
- assert_nothing_raised {
- ca = caserv.ca
- }
-
- # make our test cert again
- key = nil
- csr = nil
- cert = nil
- hostname = "test.domain.com"
- assert_nothing_raised {
- cert = Puppet::SSLCertificates::Certificate.new(
- :name => "anothertest.domain.com"
- )
- }
- # and the CSR
- assert_nothing_raised {
- cert.mkcsr
- }
-
- # retrieve them
- certtext = nil
- assert_nothing_raised {
- certtext, cacerttext = caserv.getcert(
- cert.csr.to_s, "test.reductivelabs.com", "127.0.0.1"
- )
- }
-
- # verify we got nothing back, since autosign is off
- assert_equal("", certtext)
-
- # now sign it manually, with the CA object
- x509 = nil
- assert_nothing_raised {
- x509, cacert = ca.sign(cert.csr)
- }
-
- # and write it out
- cert.cert = x509
- assert_nothing_raised {
- cert.write
- }
-
- assert(File.exists?(cert.certfile))
-
- # now get them again, and verify that we actually get them
- newtext = nil
- assert_nothing_raised {
- newtext, cacerttext = caserv.getcert(cert.csr.to_s)
- }
-
- assert(newtext)
- assert_nothing_raised {
- OpenSSL::X509::Certificate.new(newtext)
- }
-
- # Now verify that we can clean a given host's certs
- assert_nothing_raised {
- ca.clean("anothertest.domain.com")
- }
-
- assert(!File.exists?(cert.certfile), "Cert still exists after clean")
- end
-
- # and now test the autosign file
- def test_autosign
- autosign = File.join(tmpdir, "autosigntesting")
- @@tmpfiles << autosign
- File.open(autosign, "w") { |f|
- f.puts "hostmatch.domain.com"
- f.puts "*.other.com"
- }
-
- caserv = nil
- assert_nothing_raised {
- caserv = Puppet::Network::Handler.ca.new(:autosign => autosign)
- }
-
- # make sure we know what's going on
- assert(caserv.autosign?("hostmatch.domain.com"))
- assert(caserv.autosign?("fakehost.other.com"))
- assert(!caserv.autosign?("kirby.reductivelabs.com"))
- assert(!caserv.autosign?("culain.domain.com"))
- end
-
- # verify that things aren't autosigned by default
- def test_nodefaultautosign
- caserv = nil
- assert_nothing_raised {
- caserv = Puppet::Network::Handler.ca.new
- }
-
- # make sure we know what's going on
- assert(!caserv.autosign?("hostmatch.domain.com"))
- assert(!caserv.autosign?("fakehost.other.com"))
- assert(!caserv.autosign?("kirby.reductivelabs.com"))
- assert(!caserv.autosign?("culain.domain.com"))
- end
-
- # We want the CA to autosign its own certificate, because otherwise
- # the puppetmasterd CA does not autostart.
- def test_caautosign
- server = nil
- Puppet.stubs(:master?).returns true
- assert_nothing_raised {
-
- server = Puppet::Network::HTTPServer::WEBrick.new(
+ include PuppetTest::ServerTest
+
+ def setup
+ Puppet::Util::SUIDManager.stubs(:asuser).yields
+ super
+ end
+
+ # Verify that we're autosigning. We have to autosign a "different" machine,
+ # since we always autosign the CA server's certificate.
+ def test_autocertgeneration
+ ca = nil
+
+ # create our ca
+ assert_nothing_raised {
+ ca = Puppet::Network::Handler.ca.new(:autosign => true)
+ }
+
+ # create a cert with a fake name
+ key = nil
+ csr = nil
+ cert = nil
+ hostname = "test.domain.com"
+ assert_nothing_raised {
+ cert = Puppet::SSLCertificates::Certificate.new(
+ :name => "test.domain.com"
+ )
+ }
+
+ # make the request
+ assert_nothing_raised {
+ cert.mkcsr
+ }
+
+ # and get it signed
+ certtext = nil
+ cacerttext = nil
+ assert_nothing_raised {
+ certtext, cacerttext = ca.getcert(cert.csr.to_s)
+ }
+
+ # they should both be strings
+ assert_instance_of(String, certtext)
+ assert_instance_of(String, cacerttext)
+
+ # and they should both be valid certs
+ assert_nothing_raised {
+ OpenSSL::X509::Certificate.new(certtext)
+ }
+ assert_nothing_raised {
+ OpenSSL::X509::Certificate.new(cacerttext)
+ }
+
+ # and pull it again, just to make sure we're getting the same thing
+ newtext = nil
+ assert_nothing_raised {
+ newtext, cacerttext = ca.getcert(
+ cert.csr.to_s, "test.reductivelabs.com", "127.0.0.1"
+ )
+ }
+
+ assert_equal(certtext,newtext)
+ end
+
+ # this time don't use autosign
+ def test_storeAndSign
+ ca = nil
+ caserv = nil
+
+ # make our CA server
+ assert_nothing_raised {
+ caserv = Puppet::Network::Handler.ca.new(:autosign => false)
+ }
+
+ # retrieve the actual ca object
+ assert_nothing_raised {
+ ca = caserv.ca
+ }
+
+ # make our test cert again
+ key = nil
+ csr = nil
+ cert = nil
+ hostname = "test.domain.com"
+ assert_nothing_raised {
+ cert = Puppet::SSLCertificates::Certificate.new(
+ :name => "anothertest.domain.com"
+ )
+ }
+ # and the CSR
+ assert_nothing_raised {
+ cert.mkcsr
+ }
+
+ # retrieve them
+ certtext = nil
+ assert_nothing_raised {
+ certtext, cacerttext = caserv.getcert(
+ cert.csr.to_s, "test.reductivelabs.com", "127.0.0.1"
+ )
+ }
+
+ # verify we got nothing back, since autosign is off
+ assert_equal("", certtext)
+
+ # now sign it manually, with the CA object
+ x509 = nil
+ assert_nothing_raised {
+ x509, cacert = ca.sign(cert.csr)
+ }
+
+ # and write it out
+ cert.cert = x509
+ assert_nothing_raised {
+ cert.write
+ }
+
+ assert(File.exists?(cert.certfile))
+
+ # now get them again, and verify that we actually get them
+ newtext = nil
+ assert_nothing_raised {
+ newtext, cacerttext = caserv.getcert(cert.csr.to_s)
+ }
+
+ assert(newtext)
+ assert_nothing_raised {
+ OpenSSL::X509::Certificate.new(newtext)
+ }
+
+ # Now verify that we can clean a given host's certs
+ assert_nothing_raised {
+ ca.clean("anothertest.domain.com")
+ }
+
+ assert(!File.exists?(cert.certfile), "Cert still exists after clean")
+ end
+
+ # and now test the autosign file
+ def test_autosign
+ autosign = File.join(tmpdir, "autosigntesting")
+ @@tmpfiles << autosign
+ File.open(autosign, "w") { |f|
+ f.puts "hostmatch.domain.com"
+ f.puts "*.other.com"
+ }
+
+ caserv = nil
+ assert_nothing_raised {
+ caserv = Puppet::Network::Handler.ca.new(:autosign => autosign)
+ }
+
+ # make sure we know what's going on
+ assert(caserv.autosign?("hostmatch.domain.com"))
+ assert(caserv.autosign?("fakehost.other.com"))
+ assert(!caserv.autosign?("kirby.reductivelabs.com"))
+ assert(!caserv.autosign?("culain.domain.com"))
+ end
+
+ # verify that things aren't autosigned by default
+ def test_nodefaultautosign
+ caserv = nil
+ assert_nothing_raised {
+ caserv = Puppet::Network::Handler.ca.new
+ }
+
+ # make sure we know what's going on
+ assert(!caserv.autosign?("hostmatch.domain.com"))
+ assert(!caserv.autosign?("fakehost.other.com"))
+ assert(!caserv.autosign?("kirby.reductivelabs.com"))
+ assert(!caserv.autosign?("culain.domain.com"))
+ end
+
+ # We want the CA to autosign its own certificate, because otherwise
+ # the puppetmasterd CA does not autostart.
+ def test_caautosign
+ server = nil
+ Puppet.stubs(:master?).returns true
+ assert_nothing_raised {
+
+ server = Puppet::Network::HTTPServer::WEBrick.new(
- :Port => @@port,
+ :Port => @@port,
- :Handlers => {
- :CA => {}, # so that certs autogenerate
- :Status => nil
- }
- )
+ :Handlers => {
+ :CA => {}, # so that certs autogenerate
+ :Status => nil
}
+ )
+ }
+ end
+
+ # Make sure true/false causes the file to be ignored.
+ def test_autosign_true_beats_file
+ caserv = nil
+ assert_nothing_raised {
+ caserv = Puppet::Network::Handler.ca.new
+ }
+
+ host = "hostname.domain.com"
+
+ # Create an autosign file
+ file = tempfile
+ Puppet[:autosign] = file
+
+ File.open(file, "w") { |f|
+ f.puts host
+ }
+
+ # Start with "false"
+ Puppet[:autosign] = false
+
+ assert(! caserv.autosign?(host), "Host was incorrectly autosigned")
+
+ # Then set it to true
+ Puppet[:autosign] = true
+ assert(caserv.autosign?(host), "Host was not autosigned")
+ # And try a different host
+ assert(caserv.autosign?("other.yay.com"), "Host was not autosigned")
+
+ # And lastly the file
+ Puppet[:autosign] = file
+ assert(caserv.autosign?(host), "Host was not autosigned")
+
+ # And try a different host
+ assert(! caserv.autosign?("other.yay.com"), "Host was autosigned")
+ end
+
+ # Make sure that a CSR created with keys that don't match the existing
+ # cert throws an exception on the server.
+ def test_mismatched_public_keys_throws_exception
+ ca = Puppet::Network::Handler.ca.new
+
+ # First initialize the server
+ client = Puppet::Network::Client.ca.new :CA => ca
+ client.request_cert
+ File.unlink(Puppet[:hostcsr])
+
+ # Now use a different cert name
+ Puppet[:certname] = "my.host.com"
+ client = Puppet::Network::Client.ca.new :CA => ca
+ firstcsr = client.csr
+ File.unlink(Puppet[:hostcsr]) if FileTest.exists?(Puppet[:hostcsr])
+
+ assert_nothing_raised("Could not get cert") do
+ ca.getcert(firstcsr.to_s)
end
- # Make sure true/false causes the file to be ignored.
- def test_autosign_true_beats_file
- caserv = nil
- assert_nothing_raised {
- caserv = Puppet::Network::Handler.ca.new
- }
-
- host = "hostname.domain.com"
-
- # Create an autosign file
- file = tempfile
- Puppet[:autosign] = file
-
- File.open(file, "w") { |f|
- f.puts host
- }
-
- # Start with "false"
- Puppet[:autosign] = false
-
- assert(! caserv.autosign?(host), "Host was incorrectly autosigned")
-
- # Then set it to true
- Puppet[:autosign] = true
- assert(caserv.autosign?(host), "Host was not autosigned")
- # And try a different host
- assert(caserv.autosign?("other.yay.com"), "Host was not autosigned")
-
- # And lastly the file
- Puppet[:autosign] = file
- assert(caserv.autosign?(host), "Host was not autosigned")
-
- # And try a different host
- assert(! caserv.autosign?("other.yay.com"), "Host was autosigned")
- end
-
- # Make sure that a CSR created with keys that don't match the existing
- # cert throws an exception on the server.
- def test_mismatched_public_keys_throws_exception
- ca = Puppet::Network::Handler.ca.new
-
- # First initialize the server
- client = Puppet::Network::Client.ca.new :CA => ca
- client.request_cert
- File.unlink(Puppet[:hostcsr])
-
- # Now use a different cert name
- Puppet[:certname] = "my.host.com"
- client = Puppet::Network::Client.ca.new :CA => ca
- firstcsr = client.csr
- File.unlink(Puppet[:hostcsr]) if FileTest.exists?(Puppet[:hostcsr])
-
- assert_nothing_raised("Could not get cert") do
- ca.getcert(firstcsr.to_s)
- end
-
- # Now get rid of the public key, forcing a new csr
- File.unlink(Puppet[:hostprivkey])
+ # Now get rid of the public key, forcing a new csr
+ File.unlink(Puppet[:hostprivkey])
- client = Puppet::Network::Client.ca.new :CA => ca
+ client = Puppet::Network::Client.ca.new :CA => ca
- second_csr = client.csr
+ second_csr = client.csr
- assert(firstcsr.to_s != second_csr.to_s, "CSR did not change")
+ assert(firstcsr.to_s != second_csr.to_s, "CSR did not change")
- assert_raise(Puppet::Error, "CA allowed mismatched keys") do
- ca.getcert(second_csr.to_s)
- end
+ assert_raise(Puppet::Error, "CA allowed mismatched keys") do
+ ca.getcert(second_csr.to_s)
end
+ end
end
diff --git a/test/network/handler/fileserver.rb b/test/network/handler/fileserver.rb
index bfe76d0..d979821 100755
--- a/test/network/handler/fileserver.rb
+++ b/test/network/handler/fileserver.rb
@@ -6,833 +6,833 @@ require 'puppettest'
require 'puppet/network/handler/fileserver'
class TestFileServer < Test::Unit::TestCase
- include PuppetTest
-
- def mkmount(path = nil)
- mount = nil
- name = "yaytest"
- base = path || tempfile
- Dir.mkdir(base) unless FileTest.exists?(base)
- # Create a test file
- File.open(File.join(base, "file"), "w") { |f| f.puts "bazoo" }
- assert_nothing_raised {
- mount = Puppet::Network::Handler.fileserver::Mount.new(name, base)
- }
+ include PuppetTest
+
+ def mkmount(path = nil)
+ mount = nil
+ name = "yaytest"
+ base = path || tempfile
+ Dir.mkdir(base) unless FileTest.exists?(base)
+ # Create a test file
+ File.open(File.join(base, "file"), "w") { |f| f.puts "bazoo" }
+ assert_nothing_raised {
+ mount = Puppet::Network::Handler.fileserver::Mount.new(name, base)
+ }
- mount
- end
- # make a simple file source
- def mktestdir
- testdir = File.join(tmpdir, "remotefilecopytesting")
- @@tmpfiles << testdir
-
- # create a tmpfile
- pattern = "tmpfile"
- tmpfile = File.join(testdir, pattern)
- assert_nothing_raised {
- Dir.mkdir(testdir)
- File.open(tmpfile, "w") { |f|
- 3.times { f.puts rand(100) }
- }
- }
+ mount
+ end
+ # make a simple file source
+ def mktestdir
+ testdir = File.join(tmpdir, "remotefilecopytesting")
+ @@tmpfiles << testdir
- [testdir, %r{#{pattern}}, tmpfile]
- end
+ # create a tmpfile
+ pattern = "tmpfile"
+ tmpfile = File.join(testdir, pattern)
+ assert_nothing_raised {
+ Dir.mkdir(testdir)
+ File.open(tmpfile, "w") { |f|
+ 3.times { f.puts rand(100) }
+ }
+ }
- # make a bunch of random test files
- def mktestfiles(testdir)
- @@tmpfiles << testdir
- assert_nothing_raised {
- files = %w{a b c d e}.collect { |l|
- name = File.join(testdir, "file#{l}")
- File.open(name, "w") { |f|
- f.puts rand(100)
- }
-
- name
- }
+ [testdir, %r{#{pattern}}, tmpfile]
+ end
- return files
+ # make a bunch of random test files
+ def mktestfiles(testdir)
+ @@tmpfiles << testdir
+ assert_nothing_raised {
+ files = %w{a b c d e}.collect { |l|
+ name = File.join(testdir, "file#{l}")
+ File.open(name, "w") { |f|
+ f.puts rand(100)
}
- end
- def assert_describe(base, file, server)
- file = File.basename(file)
- assert_nothing_raised {
- desc = server.describe(base + file)
- assert(desc, "Got no description for #{file}")
- assert(desc != "", "Got no description for #{file}")
- assert_match(/^\d+/, desc, "Got invalid description #{desc}")
- }
- end
+ name
+ }
- # test for invalid names
- def test_namefailures
- server = nil
- assert_nothing_raised {
+ return files
+ }
+ end
- server = Puppet::Network::Handler.fileserver.new(
+ def assert_describe(base, file, server)
+ file = File.basename(file)
+ assert_nothing_raised {
+ desc = server.describe(base + file)
+ assert(desc, "Got no description for #{file}")
+ assert(desc != "", "Got no description for #{file}")
+ assert_match(/^\d+/, desc, "Got invalid description #{desc}")
+ }
+ end
- :Local => true,
+ # test for invalid names
+ def test_namefailures
+ server = nil
+ assert_nothing_raised {
- :Config => false
- )
- }
+ server = Puppet::Network::Handler.fileserver.new(
- [" ", "=" "+", "&", "#", "*"].each do |char|
- assert_raise(Puppet::Network::Handler::FileServerError, "'#{char}' did not throw a failure in fileserver module names") {
- server.mount("/tmp", "invalid#{char}name")
- }
- end
- end
+ :Local => true,
- # verify that listing the root behaves as expected
- def test_listroot
- server = nil
- testdir, pattern, tmpfile = mktestdir
+ :Config => false
+ )
+ }
- file = nil
- checks = Puppet::Network::Handler.fileserver::CHECKPARAMS
+ [" ", "=" "+", "&", "#", "*"].each do |char|
+ assert_raise(Puppet::Network::Handler::FileServerError, "'#{char}' did not throw a failure in fileserver module names") {
+ server.mount("/tmp", "invalid#{char}name")
+ }
+ end
+ end
- # and make our fileserver
- assert_nothing_raised {
+ # verify that listing the root behaves as expected
+ def test_listroot
+ server = nil
+ testdir, pattern, tmpfile = mktestdir
- server = Puppet::Network::Handler.fileserver.new(
+ file = nil
+ checks = Puppet::Network::Handler.fileserver::CHECKPARAMS
- :Local => true,
+ # and make our fileserver
+ assert_nothing_raised {
- :Config => false
- )
- }
+ server = Puppet::Network::Handler.fileserver.new(
- # mount the testdir
- assert_nothing_raised {
- server.mount(testdir, "test")
- }
+ :Local => true,
- # and verify different iterations of 'root' return the same value
- list = nil
- assert_nothing_raised {
- list = server.list("/test/", :manage, true, false)
- }
+ :Config => false
+ )
+ }
- assert(list =~ pattern)
+ # mount the testdir
+ assert_nothing_raised {
+ server.mount(testdir, "test")
+ }
- assert_nothing_raised {
- list = server.list("/test", :manage, true, false)
- }
- assert(list =~ pattern)
+ # and verify different iterations of 'root' return the same value
+ list = nil
+ assert_nothing_raised {
+ list = server.list("/test/", :manage, true, false)
+ }
- end
+ assert(list =~ pattern)
- # test listing individual files
- def test_getfilelist
- server = nil
- testdir, pattern, tmpfile = mktestdir
+ assert_nothing_raised {
+ list = server.list("/test", :manage, true, false)
+ }
+ assert(list =~ pattern)
- file = nil
+ end
- assert_nothing_raised {
+ # test listing individual files
+ def test_getfilelist
+ server = nil
+ testdir, pattern, tmpfile = mktestdir
- server = Puppet::Network::Handler.fileserver.new(
+ file = nil
- :Local => true,
+ assert_nothing_raised {
- :Config => false
- )
- }
+ server = Puppet::Network::Handler.fileserver.new(
- assert_nothing_raised {
- server.mount(testdir, "test")
- }
+ :Local => true,
- # get our listing
- list = nil
- sfile = "/test/tmpfile"
- assert_nothing_raised {
- list = server.list(sfile, :manage, true, false)
- }
+ :Config => false
+ )
+ }
- output = "/\tfile"
+ assert_nothing_raised {
+ server.mount(testdir, "test")
+ }
- # verify it got listed as a file
- assert_equal(output, list)
+ # get our listing
+ list = nil
+ sfile = "/test/tmpfile"
+ assert_nothing_raised {
+ list = server.list(sfile, :manage, true, false)
+ }
- # verify we got all fields
- assert(list !~ /\t\t/)
+ output = "/\tfile"
- # verify that we didn't get the directory itself
- list.split("\n").each { |line|
- assert(line !~ %r{remotefile})
- }
+ # verify it got listed as a file
+ assert_equal(output, list)
- # and then verify that the contents match
- contents = File.read(tmpfile)
+ # verify we got all fields
+ assert(list !~ /\t\t/)
- ret = nil
- assert_nothing_raised {
- ret = server.retrieve(sfile)
- }
+ # verify that we didn't get the directory itself
+ list.split("\n").each { |line|
+ assert(line !~ %r{remotefile})
+ }
- assert_equal(contents, ret)
- end
+ # and then verify that the contents match
+ contents = File.read(tmpfile)
- # check that the fileserver is seeing newly created files
- def test_seenewfiles
- server = nil
- testdir, pattern, tmpfile = mktestdir
+ ret = nil
+ assert_nothing_raised {
+ ret = server.retrieve(sfile)
+ }
+ assert_equal(contents, ret)
+ end
- newfile = File.join(testdir, "newfile")
+ # check that the fileserver is seeing newly created files
+ def test_seenewfiles
+ server = nil
+ testdir, pattern, tmpfile = mktestdir
- # go through the whole schtick again...
- file = nil
- checks = Puppet::Network::Handler.fileserver::CHECKPARAMS
- assert_nothing_raised {
+ newfile = File.join(testdir, "newfile")
- server = Puppet::Network::Handler.fileserver.new(
+ # go through the whole schtick again...
+ file = nil
+ checks = Puppet::Network::Handler.fileserver::CHECKPARAMS
- :Local => true,
+ assert_nothing_raised {
- :Config => false
- )
- }
+ server = Puppet::Network::Handler.fileserver.new(
- assert_nothing_raised {
- server.mount(testdir, "test")
- }
+ :Local => true,
- list = nil
- sfile = "/test/"
- assert_nothing_raised {
- list = server.list(sfile, :manage, true, false)
- }
+ :Config => false
+ )
+ }
- # create the new file
- File.open(newfile, "w") { |f|
- 3.times { f.puts rand(100) }
- }
+ assert_nothing_raised {
+ server.mount(testdir, "test")
+ }
- newlist = nil
- assert_nothing_raised {
- newlist = server.list(sfile, :manage, true, false)
- }
+ list = nil
+ sfile = "/test/"
+ assert_nothing_raised {
+ list = server.list(sfile, :manage, true, false)
+ }
- # verify the list has changed
- assert(list != newlist)
+ # create the new file
+ File.open(newfile, "w") { |f|
+ 3.times { f.puts rand(100) }
+ }
- # and verify that we are specifically seeing the new file
- assert(newlist =~ /newfile/)
- end
+ newlist = nil
+ assert_nothing_raised {
+ newlist = server.list(sfile, :manage, true, false)
+ }
- # verify we can mount /, which is what local file servers will
- # normally do
- def test_mountroot
- server = nil
- assert_nothing_raised {
+ # verify the list has changed
+ assert(list != newlist)
- server = Puppet::Network::Handler.fileserver.new(
+ # and verify that we are specifically seeing the new file
+ assert(newlist =~ /newfile/)
+ end
- :Local => true,
+ # verify we can mount /, which is what local file servers will
+ # normally do
+ def test_mountroot
+ server = nil
+ assert_nothing_raised {
- :Config => false
- )
- }
+ server = Puppet::Network::Handler.fileserver.new(
- assert_nothing_raised {
- server.mount("/", "root")
- }
+ :Local => true,
- testdir, pattern, tmpfile = mktestdir
+ :Config => false
+ )
+ }
- list = nil
- assert_nothing_raised {
- list = server.list("/root/#{testdir}", :manage, true, false)
- }
+ assert_nothing_raised {
+ server.mount("/", "root")
+ }
- assert(list =~ pattern)
- assert_nothing_raised {
- list = server.list("/root#{testdir}", :manage, true, false)
- }
+ testdir, pattern, tmpfile = mktestdir
- assert(list =~ pattern)
- end
+ list = nil
+ assert_nothing_raised {
+ list = server.list("/root/#{testdir}", :manage, true, false)
+ }
- # verify that we're correctly recursing the right number of levels
- def test_recursionlevels
- server = nil
- assert_nothing_raised {
+ assert(list =~ pattern)
+ assert_nothing_raised {
+ list = server.list("/root#{testdir}", :manage, true, false)
+ }
- server = Puppet::Network::Handler.fileserver.new(
+ assert(list =~ pattern)
+ end
- :Local => true,
+ # verify that we're correctly recursing the right number of levels
+ def test_recursionlevels
+ server = nil
+ assert_nothing_raised {
- :Config => false
- )
- }
+ server = Puppet::Network::Handler.fileserver.new(
- # make our deep recursion
- basedir = File.join(tmpdir, "recurseremotetesting")
- testdir = "#{basedir}/with/some/sub/directories/for/the/purposes/of/testing"
- oldfile = File.join(testdir, "oldfile")
- assert_nothing_raised {
- system("mkdir -p #{testdir}")
- File.open(oldfile, "w") { |f|
- 3.times { f.puts rand(100) }
- }
- @@tmpfiles << basedir
- }
+ :Local => true,
- assert_nothing_raised {
- server.mount(basedir, "test")
- }
+ :Config => false
+ )
+ }
- # get our list
- list = nil
- assert_nothing_raised {
- list = server.list("/test/with", :manage, false, false)
- }
+ # make our deep recursion
+ basedir = File.join(tmpdir, "recurseremotetesting")
+ testdir = "#{basedir}/with/some/sub/directories/for/the/purposes/of/testing"
+ oldfile = File.join(testdir, "oldfile")
+ assert_nothing_raised {
+ system("mkdir -p #{testdir}")
+ File.open(oldfile, "w") { |f|
+ 3.times { f.puts rand(100) }
+ }
+ @@tmpfiles << basedir
+ }
- # make sure we only got one line, since we're not recursing
- assert(list !~ /\n/)
+ assert_nothing_raised {
+ server.mount(basedir, "test")
+ }
- # for each level of recursion, make sure we get the right list
- [0, 1, 2].each { |num|
- assert_nothing_raised {
- list = server.list("/test/with", :manage, num, false)
- }
+ # get our list
+ list = nil
+ assert_nothing_raised {
+ list = server.list("/test/with", :manage, false, false)
+ }
- count = 0
- while list =~ /\n/
- list.sub!(/\n/, '')
- count += 1
- end
- assert_equal(num, count)
- }
- end
+ # make sure we only got one line, since we're not recursing
+ assert(list !~ /\n/)
+
+ # for each level of recursion, make sure we get the right list
+ [0, 1, 2].each { |num|
+ assert_nothing_raised {
+ list = server.list("/test/with", :manage, num, false)
+ }
+
+ count = 0
+ while list =~ /\n/
+ list.sub!(/\n/, '')
+ count += 1
+ end
+ assert_equal(num, count)
+ }
+ end
- # verify that we're not seeing the dir we ask for; i.e., that our
- # list is relative to that dir, not it's parent dir
- def test_listedpath
- server = nil
- assert_nothing_raised {
+ # verify that we're not seeing the dir we ask for; i.e., that our
+ # list is relative to that dir, not it's parent dir
+ def test_listedpath
+ server = nil
+ assert_nothing_raised {
- server = Puppet::Network::Handler.fileserver.new(
+ server = Puppet::Network::Handler.fileserver.new(
- :Local => true,
+ :Local => true,
- :Config => false
- )
- }
+ :Config => false
+ )
+ }
- # create a deep dir
- basedir = tempfile
- testdir = "#{basedir}/with/some/sub/directories/for/testing"
- oldfile = File.join(testdir, "oldfile")
- assert_nothing_raised {
- system("mkdir -p #{testdir}")
- File.open(oldfile, "w") { |f|
- 3.times { f.puts rand(100) }
- }
- @@tmpfiles << basedir
- }
+ # create a deep dir
+ basedir = tempfile
+ testdir = "#{basedir}/with/some/sub/directories/for/testing"
+ oldfile = File.join(testdir, "oldfile")
+ assert_nothing_raised {
+ system("mkdir -p #{testdir}")
+ File.open(oldfile, "w") { |f|
+ 3.times { f.puts rand(100) }
+ }
+ @@tmpfiles << basedir
+ }
- # mounty mounty
- assert_nothing_raised {
- server.mount(basedir, "localhost")
- }
+ # mounty mounty
+ assert_nothing_raised {
+ server.mount(basedir, "localhost")
+ }
- list = nil
- # and then check a few dirs
- assert_nothing_raised {
- list = server.list("/localhost/with", :manage, false, false)
- }
+ list = nil
+ # and then check a few dirs
+ assert_nothing_raised {
+ list = server.list("/localhost/with", :manage, false, false)
+ }
- assert(list !~ /with/)
+ assert(list !~ /with/)
- assert_nothing_raised {
- list = server.list("/localhost/with/some/sub", :manage, true, false)
- }
+ assert_nothing_raised {
+ list = server.list("/localhost/with/some/sub", :manage, true, false)
+ }
- assert(list !~ /sub/)
- end
+ assert(list !~ /sub/)
+ end
- # test many dirs, not necessarily very deep
- def test_widelists
- server = nil
- assert_nothing_raised {
+ # test many dirs, not necessarily very deep
+ def test_widelists
+ server = nil
+ assert_nothing_raised {
- server = Puppet::Network::Handler.fileserver.new(
+ server = Puppet::Network::Handler.fileserver.new(
- :Local => true,
+ :Local => true,
- :Config => false
- )
- }
+ :Config => false
+ )
+ }
- basedir = tempfile
- dirs = %w{a set of directories}
- assert_nothing_raised {
- Dir.mkdir(basedir)
- dirs.each { |dir|
- Dir.mkdir(File.join(basedir, dir))
- }
- @@tmpfiles << basedir
- }
+ basedir = tempfile
+ dirs = %w{a set of directories}
+ assert_nothing_raised {
+ Dir.mkdir(basedir)
+ dirs.each { |dir|
+ Dir.mkdir(File.join(basedir, dir))
+ }
+ @@tmpfiles << basedir
+ }
- assert_nothing_raised {
- server.mount(basedir, "localhost")
- }
+ assert_nothing_raised {
+ server.mount(basedir, "localhost")
+ }
- list = nil
- assert_nothing_raised {
- list = server.list("/localhost/", :manage, 1, false)
- }
- assert_instance_of(String, list, "Server returned %s instead of string")
- list = list.split("\n")
+ list = nil
+ assert_nothing_raised {
+ list = server.list("/localhost/", :manage, 1, false)
+ }
+ assert_instance_of(String, list, "Server returned %s instead of string")
+ list = list.split("\n")
- assert_equal(dirs.length + 1, list.length)
- end
+ assert_equal(dirs.length + 1, list.length)
+ end
- # verify that 'describe' works as advertised
- def test_describe
- server = nil
- testdir = tstdir
- files = mktestfiles(testdir)
+ # verify that 'describe' works as advertised
+ def test_describe
+ server = nil
+ testdir = tstdir
+ files = mktestfiles(testdir)
- file = nil
- checks = Puppet::Network::Handler.fileserver::CHECKPARAMS
+ file = nil
+ checks = Puppet::Network::Handler.fileserver::CHECKPARAMS
- assert_nothing_raised {
+ assert_nothing_raised {
- server = Puppet::Network::Handler.fileserver.new(
+ server = Puppet::Network::Handler.fileserver.new(
- :Local => true,
+ :Local => true,
- :Config => false
- )
- }
+ :Config => false
+ )
+ }
- assert_nothing_raised {
- server.mount(testdir, "test")
- }
+ assert_nothing_raised {
+ server.mount(testdir, "test")
+ }
- # get our list
- list = nil
- sfile = "/test/"
- assert_nothing_raised {
- list = server.list(sfile, :manage, true, false)
- }
+ # get our list
+ list = nil
+ sfile = "/test/"
+ assert_nothing_raised {
+ list = server.list(sfile, :manage, true, false)
+ }
- # and describe each file in the list
- assert_nothing_raised {
- list.split("\n").each { |line|
- file, type = line.split("\t")
+ # and describe each file in the list
+ assert_nothing_raised {
+ list.split("\n").each { |line|
+ file, type = line.split("\t")
- desc = server.describe(sfile + file)
- }
- }
+ desc = server.describe(sfile + file)
+ }
+ }
- # and then make sure we can describe everything that we know is there
- files.each { |file|
- assert_describe(sfile, file, server)
- }
+ # and then make sure we can describe everything that we know is there
+ files.each { |file|
+ assert_describe(sfile, file, server)
+ }
- # And then describe some files that we know aren't there
- retval = nil
- assert_nothing_raised("Describing non-existent files raised an error") {
- retval = server.describe(sfile + "noexisties")
- }
+ # And then describe some files that we know aren't there
+ retval = nil
+ assert_nothing_raised("Describing non-existent files raised an error") {
+ retval = server.describe(sfile + "noexisties")
+ }
- assert_equal("", retval, "Description of non-existent files returned a value")
+ assert_equal("", retval, "Description of non-existent files returned a value")
- # Now try to describe some sources that don't even exist
- retval = nil
+ # Now try to describe some sources that don't even exist
+ retval = nil
- assert_raise(
- Puppet::Network::Handler::FileServerError,
+ assert_raise(
+ Puppet::Network::Handler::FileServerError,
- "Describing non-existent mount did not raise an error") {
- retval = server.describe("/notmounted/noexisties")
- }
+ "Describing non-existent mount did not raise an error") {
+ retval = server.describe("/notmounted/noexisties")
+ }
- assert_nil(retval, "Description of non-existent mounts returned a value")
- end
+ assert_nil(retval, "Description of non-existent mounts returned a value")
+ end
- def test_describe_does_not_fail_when_mount_does_not_find_file
- server = Puppet::Network::Handler.fileserver.new(:Local => true, :Config => false)
+ def test_describe_does_not_fail_when_mount_does_not_find_file
+ server = Puppet::Network::Handler.fileserver.new(:Local => true, :Config => false)
- assert_nothing_raised("Failed when describing missing plugins") do
- server.describe "/plugins"
- end
+ assert_nothing_raised("Failed when describing missing plugins") do
+ server.describe "/plugins"
end
+ end
- # test that our config file is parsing and working as planned
- def test_configfile
- server = nil
- basedir = File.join(tmpdir, "fileserverconfigfiletesting")
- @@tmpfiles << basedir
+ # test that our config file is parsing and working as planned
+ def test_configfile
+ server = nil
+ basedir = File.join(tmpdir, "fileserverconfigfiletesting")
+ @@tmpfiles << basedir
- # make some dirs for mounting
- Dir.mkdir(basedir)
- mounts = {}
- %w{thing thus the-se those}.each { |dir|
- path = File.join(basedir, dir)
- Dir.mkdir(path)
- mounts[dir] = mktestfiles(path)
+ # make some dirs for mounting
+ Dir.mkdir(basedir)
+ mounts = {}
+ %w{thing thus the-se those}.each { |dir|
+ path = File.join(basedir, dir)
+ Dir.mkdir(path)
+ mounts[dir] = mktestfiles(path)
- }
+ }
- # create an example file with each of them
- conffile = tempfile
- @@tmpfiles << conffile
+ # create an example file with each of them
+ conffile = tempfile
+ @@tmpfiles << conffile
- File.open(conffile, "w") { |f|
- f.print "# a test config file
+ File.open(conffile, "w") { |f|
+ f.print "# a test config file
[thing]
- path #{basedir}/thing
- allow 192.168.0.*
+ path #{basedir}/thing
+ allow 192.168.0.*
[thus]
- path #{basedir}/thus
- allow *.madstop.com, *.kanies.com
- deny *.sub.madstop.com
+ path #{basedir}/thus
+ allow *.madstop.com, *.kanies.com
+ deny *.sub.madstop.com
[the-se]
- path #{basedir}/the-se
+ path #{basedir}/the-se
[those]
- path #{basedir}/those
+ path #{basedir}/those
"
- }
+ }
- # create a server with the file
- assert_nothing_raised {
+ # create a server with the file
+ assert_nothing_raised {
- server = Puppet::Network::Handler.fileserver.new(
+ server = Puppet::Network::Handler.fileserver.new(
- :Local => false,
+ :Local => false,
- :Config => conffile
- )
- }
-
- list = nil
- # run through once with no host/ip info, to verify everything is working
- mounts.each { |mount, files|
- mount = "/#{mount}/"
- assert_nothing_raised {
- list = server.list(mount, :manage, true, false)
- }
+ :Config => conffile
+ )
+ }
- assert_nothing_raised {
- list.split("\n").each { |line|
- file, type = line.split("\t")
+ list = nil
+ # run through once with no host/ip info, to verify everything is working
+ mounts.each { |mount, files|
+ mount = "/#{mount}/"
+ assert_nothing_raised {
+ list = server.list(mount, :manage, true, false)
+ }
- desc = server.describe(mount + file)
- }
- }
+ assert_nothing_raised {
+ list.split("\n").each { |line|
+ file, type = line.split("\t")
- files.each { |f|
- assert_describe(mount, f, server)
- }
+ desc = server.describe(mount + file)
}
+ }
- # now let's check that things are being correctly forbidden
- # this is just a map of names and expected results
- {
- "thing" => {
- :deny => [
- ["hostname.com", "192.168.1.0"],
- ["hostname.com", "192.158.0.0"]
- ],
- :allow => [
- ["hostname.com", "192.168.0.0"],
- ["hostname.com", "192.168.0.245"],
- ]
- },
- "thus" => {
- :deny => [
- ["hostname.com", "192.168.1.0"],
- ["name.sub.madstop.com", "192.158.0.0"]
- ],
- :allow => [
- ["luke.kanies.com", "192.168.0.0"],
- ["luke.madstop.com", "192.168.0.245"],
- ]
+ files.each { |f|
+ assert_describe(mount, f, server)
+ }
+ }
+
+ # now let's check that things are being correctly forbidden
+ # this is just a map of names and expected results
+ {
+ "thing" => {
+ :deny => [
+ ["hostname.com", "192.168.1.0"],
+ ["hostname.com", "192.158.0.0"]
+ ],
+ :allow => [
+ ["hostname.com", "192.168.0.0"],
+ ["hostname.com", "192.168.0.245"],
+ ]
+ },
+ "thus" => {
+ :deny => [
+ ["hostname.com", "192.168.1.0"],
+ ["name.sub.madstop.com", "192.158.0.0"]
+ ],
+ :allow => [
+ ["luke.kanies.com", "192.168.0.0"],
+ ["luke.madstop.com", "192.168.0.245"],
+ ]
+ }
+ }.each { |mount, hash|
+ mount = "/#{mount}/"
+
+ # run through the map
+ hash.each { |type, ary|
+ ary.each { |sub|
+ host, ip = sub
+
+ case type
+ when :deny
+
+ assert_raise(
+ Puppet::AuthorizationError,
+
+ "Host #{host}, ip #{ip}, allowed #{mount}") {
+ list = server.list(mount, :manage, true, false, host, ip)
}
- }.each { |mount, hash|
- mount = "/#{mount}/"
-
- # run through the map
- hash.each { |type, ary|
- ary.each { |sub|
- host, ip = sub
-
- case type
- when :deny
-
- assert_raise(
- Puppet::AuthorizationError,
-
- "Host #{host}, ip #{ip}, allowed #{mount}") {
- list = server.list(mount, :manage, true, false, host, ip)
- }
- when :allow
- assert_nothing_raised("Host #{host}, ip #{ip}, denied #{mount}") {
- list = server.list(mount, :manage, true, false, host, ip)
- }
- end
- }
+ when :allow
+ assert_nothing_raised("Host #{host}, ip #{ip}, denied #{mount}") {
+ list = server.list(mount, :manage, true, false, host, ip)
}
+ end
}
+ }
+ }
- end
+ end
- # Test that we smoothly handle invalid config files
- def test_configfailures
- # create an example file with each of them
- conffile = tempfile
+ # Test that we smoothly handle invalid config files
+ def test_configfailures
+ # create an example file with each of them
+ conffile = tempfile
- invalidmounts = {
- "noexist" => "[noexist]
- path /this/path/does/not/exist
- allow 192.168.0.*
+ invalidmounts = {
+ "noexist" => "[noexist]
+ path /this/path/does/not/exist
+ allow 192.168.0.*
"
}
- invalidconfigs = [
- "[not valid]
- path /this/path/does/not/exist
- allow 192.168.0.*
+ invalidconfigs = [
+ "[not valid]
+ path /this/path/does/not/exist
+ allow 192.168.0.*
",
"[valid]
- invalidstatement
- path /etc
- allow 192.168.0.*
+ invalidstatement
+ path /etc
+ allow 192.168.0.*
",
"[valid]
- allow 192.168.0.*
+ allow 192.168.0.*
"
]
- invalidmounts.each { |mount, text|
- File.open(conffile, "w") { |f|
- f.print text
- }
+ invalidmounts.each { |mount, text|
+ File.open(conffile, "w") { |f|
+ f.print text
+ }
- # create a server with the file
- server = nil
- assert_nothing_raised {
+ # create a server with the file
+ server = nil
+ assert_nothing_raised {
- server = Puppet::Network::Handler.fileserver.new(
+ server = Puppet::Network::Handler.fileserver.new(
- :Local => true,
+ :Local => true,
- :Config => conffile
- )
- }
+ :Config => conffile
+ )
+ }
- assert_raise(
- Puppet::Network::Handler::FileServerError,
+ assert_raise(
+ Puppet::Network::Handler::FileServerError,
- "Invalid mount was mounted") {
- server.list(mount, :manage)
- }
- }
+ "Invalid mount was mounted") {
+ server.list(mount, :manage)
+ }
+ }
- invalidconfigs.each_with_index { |text, i|
- File.open(conffile, "w") { |f|
- f.print text
- }
+ invalidconfigs.each_with_index { |text, i|
+ File.open(conffile, "w") { |f|
+ f.print text
+ }
- # create a server with the file
- server = nil
+ # create a server with the file
+ server = nil
- assert_raise(
- Puppet::Network::Handler::FileServerError,
+ assert_raise(
+ Puppet::Network::Handler::FileServerError,
- "Invalid config #{i} did not raise error") {
+ "Invalid config #{i} did not raise error") {
- server = Puppet::Network::Handler.fileserver.new(
+ server = Puppet::Network::Handler.fileserver.new(
- :Local => true,
+ :Local => true,
- :Config => conffile
- )
- }
- }
- end
+ :Config => conffile
+ )
+ }
+ }
+ end
- # verify we reread the config file when it changes
- def test_filereread
- server = nil
+ # verify we reread the config file when it changes
+ def test_filereread
+ server = nil
- conffile = tempfile
- dir = tstdir
+ conffile = tempfile
+ dir = tstdir
- files = mktestfiles(dir)
- File.open(conffile, "w") { |f|
- f.print "# a test config file
+ files = mktestfiles(dir)
+ File.open(conffile, "w") { |f|
+ f.print "# a test config file
[thing]
- path #{dir}
- allow test1.domain.com
+ path #{dir}
+ allow test1.domain.com
"
- }
+ }
- # Reset the timeout, so we reload faster
- Puppet[:filetimeout] = 0.5
+ # Reset the timeout, so we reload faster
+ Puppet[:filetimeout] = 0.5
- # start our server with a fast timeout
- assert_nothing_raised {
+ # start our server with a fast timeout
+ assert_nothing_raised {
- server = Puppet::Network::Handler.fileserver.new(
+ server = Puppet::Network::Handler.fileserver.new(
- :Local => false,
+ :Local => false,
- :Config => conffile
- )
- }
+ :Config => conffile
+ )
+ }
- list = nil
- assert_nothing_raised {
+ list = nil
+ assert_nothing_raised {
- list = server.list(
- "/thing/", :manage, false, false,
+ list = server.list(
+ "/thing/", :manage, false, false,
- "test1.domain.com", "127.0.0.1")
- }
- assert(list != "", "List returned nothing in rereard test")
+ "test1.domain.com", "127.0.0.1")
+ }
+ assert(list != "", "List returned nothing in rereard test")
- assert_raise(Puppet::AuthorizationError, "List allowed invalid host") {
- list = server.list("/thing/", :manage, false, false, "test2.domain.com", "127.0.0.1")
- }
+ assert_raise(Puppet::AuthorizationError, "List allowed invalid host") {
+ list = server.list("/thing/", :manage, false, false, "test2.domain.com", "127.0.0.1")
+ }
- sleep 1
- File.open(conffile, "w") { |f|
- f.print "# a test config file
+ sleep 1
+ File.open(conffile, "w") { |f|
+ f.print "# a test config file
[thing]
- path #{dir}
- allow test2.domain.com
+ path #{dir}
+ allow test2.domain.com
"
+ }
+
+ assert_raise(Puppet::AuthorizationError, "List allowed invalid host") {
+ list = server.list("/thing/", :manage, false, false, "test1.domain.com", "127.0.0.1")
}
- assert_raise(Puppet::AuthorizationError, "List allowed invalid host") {
- list = server.list("/thing/", :manage, false, false, "test1.domain.com", "127.0.0.1")
- }
+ assert_nothing_raised {
+ list = server.list("/thing/", :manage, false, false, "test2.domain.com", "127.0.0.1")
+ }
- assert_nothing_raised {
- list = server.list("/thing/", :manage, false, false, "test2.domain.com", "127.0.0.1")
- }
+ assert(list != "", "List returned nothing in rereard test")
- assert(list != "", "List returned nothing in rereard test")
+ list = nil
+ end
- list = nil
- end
+ # Verify that we get converted to the right kind of string
+ def test_mountstring
+ mount = nil
+ name = "yaytest"
+ path = tmpdir
+ assert_nothing_raised {
+ mount = Puppet::Network::Handler.fileserver::Mount.new(name, path)
+ }
- # Verify that we get converted to the right kind of string
- def test_mountstring
- mount = nil
- name = "yaytest"
- path = tmpdir
- assert_nothing_raised {
- mount = Puppet::Network::Handler.fileserver::Mount.new(name, path)
- }
+ assert_equal("mount[#{name}]", mount.to_s)
+ end
- assert_equal("mount[#{name}]", mount.to_s)
- end
+ def test_servinglinks
+ # Disable the checking, so changes propagate immediately.
+ Puppet[:filetimeout] = -5
+ server = nil
+ source = tempfile
+ file = File.join(source, "file")
+ link = File.join(source, "link")
+ Dir.mkdir(source)
+ File.open(file, "w") { |f| f.puts "yay" }
+ File.symlink(file, link)
+ assert_nothing_raised {
- def test_servinglinks
- # Disable the checking, so changes propagate immediately.
- Puppet[:filetimeout] = -5
- server = nil
- source = tempfile
- file = File.join(source, "file")
- link = File.join(source, "link")
- Dir.mkdir(source)
- File.open(file, "w") { |f| f.puts "yay" }
- File.symlink(file, link)
- assert_nothing_raised {
+ server = Puppet::Network::Handler.fileserver.new(
- server = Puppet::Network::Handler.fileserver.new(
+ :Local => true,
- :Local => true,
+ :Config => false
+ )
+ }
- :Config => false
- )
- }
+ assert_nothing_raised {
+ server.mount(source, "mount")
+ }
- assert_nothing_raised {
- server.mount(source, "mount")
- }
+ # First describe the link when following
+ results = {}
+ assert_nothing_raised {
+ server.describe("/mount/link", :follow).split("\t").zip(
+ Puppet::Network::Handler.fileserver::CHECKPARAMS
+ ).each { |v,p| results[p] = v }
+ }
- # First describe the link when following
- results = {}
- assert_nothing_raised {
- server.describe("/mount/link", :follow).split("\t").zip(
- Puppet::Network::Handler.fileserver::CHECKPARAMS
- ).each { |v,p| results[p] = v }
- }
+ assert_equal("file", results[:type])
- assert_equal("file", results[:type])
+ # Then not
+ results = {}
+ assert_nothing_raised {
+ server.describe("/mount/link", :manage).split("\t").zip(
+ Puppet::Network::Handler.fileserver::CHECKPARAMS
+ ).each { |v,p| results[p] = v }
+ }
- # Then not
- results = {}
- assert_nothing_raised {
- server.describe("/mount/link", :manage).split("\t").zip(
- Puppet::Network::Handler.fileserver::CHECKPARAMS
- ).each { |v,p| results[p] = v }
- }
+ assert_equal("link", results[:type])
- assert_equal("link", results[:type])
+ results.each { |p,v|
+ assert(v, "#{p} has no value")
+ assert(v != "", "#{p} has no value")
+ }
+ end
+
+ # Test that substitution patterns in the path are exapanded
+ # properly. Disabled, because it was testing too much of the process
+ # and in a non-portable way. This is a thorough enough test that it should
+ # be kept, but it should be done in a way that is clearly portable (e.g.,
+ # no md5 sums of file paths).
+ def test_host_specific
+ client1 = "client1.example.com"
+ client2 = "client2.example.com"
+ ip = "127.0.0.1"
+
+ # Setup a directory hierarchy for the tests
+ fsdir = File.join(tmpdir, "host-specific")
+ @@tmpfiles << fsdir
+ hostdir = File.join(fsdir, "host")
+ fqdndir = File.join(fsdir, "fqdn")
+ client1_hostdir = File.join(hostdir, "client1")
+ client2_fqdndir = File.join(fqdndir, client2)
+ contents = {
+ client1_hostdir => "client1\n",
+ client2_fqdndir => client2 + "\n"
+ }
+ [fsdir, hostdir, fqdndir, client1_hostdir, client2_fqdndir].each { |d| Dir.mkdir(d) }
- results.each { |p,v|
- assert(v, "#{p} has no value")
- assert(v != "", "#{p} has no value")
- }
+ [client1_hostdir, client2_fqdndir].each do |d|
+ File.open(File.join(d, "file.txt"), "w") do |f|
+ f.print contents[d]
+ end
end
-
- # Test that substitution patterns in the path are exapanded
- # properly. Disabled, because it was testing too much of the process
- # and in a non-portable way. This is a thorough enough test that it should
- # be kept, but it should be done in a way that is clearly portable (e.g.,
- # no md5 sums of file paths).
- def test_host_specific
- client1 = "client1.example.com"
- client2 = "client2.example.com"
- ip = "127.0.0.1"
-
- # Setup a directory hierarchy for the tests
- fsdir = File.join(tmpdir, "host-specific")
- @@tmpfiles << fsdir
- hostdir = File.join(fsdir, "host")
- fqdndir = File.join(fsdir, "fqdn")
- client1_hostdir = File.join(hostdir, "client1")
- client2_fqdndir = File.join(fqdndir, client2)
- contents = {
- client1_hostdir => "client1\n",
- client2_fqdndir => client2 + "\n"
- }
- [fsdir, hostdir, fqdndir, client1_hostdir, client2_fqdndir].each { |d| Dir.mkdir(d) }
-
- [client1_hostdir, client2_fqdndir].each do |d|
- File.open(File.join(d, "file.txt"), "w") do |f|
- f.print contents[d]
- end
- end
- conffile = tempfile
- File.open(conffile, "w") do |f|
- f.print("
+ conffile = tempfile
+ File.open(conffile, "w") do |f|
+ f.print("
[host]
path #{hostdir}/%h
allow *
@@ -840,421 +840,421 @@ allow *
path #{fqdndir}/%H
allow *
")
- end
+ end
- server = nil
- assert_nothing_raised {
+ server = nil
+ assert_nothing_raised {
- server = Puppet::Network::Handler.fileserver.new(
+ server = Puppet::Network::Handler.fileserver.new(
- :Local => true,
+ :Local => true,
- :Config => conffile
- )
- }
+ :Config => conffile
+ )
+ }
- # check that list returns the correct thing for the two clients
- list = nil
- sfile = "/host/file.txt"
- assert_nothing_raised {
- list = server.list(sfile, :manage, true, false, client1, ip)
- }
- assert_equal("/\tfile", list)
- assert_nothing_raised {
- list = server.list(sfile, :manage, true, false, client2, ip)
- }
- assert_equal("", list)
+ # check that list returns the correct thing for the two clients
+ list = nil
+ sfile = "/host/file.txt"
+ assert_nothing_raised {
+ list = server.list(sfile, :manage, true, false, client1, ip)
+ }
+ assert_equal("/\tfile", list)
+ assert_nothing_raised {
+ list = server.list(sfile, :manage, true, false, client2, ip)
+ }
+ assert_equal("", list)
- sfile = "/fqdn/file.txt"
- assert_nothing_raised {
- list = server.list(sfile, :manage, true, false, client1, ip)
- }
- assert_equal("", list)
- assert_nothing_raised {
- list = server.list(sfile, :manage, true, false, client2, ip)
- }
- assert_equal("/\tfile", list)
+ sfile = "/fqdn/file.txt"
+ assert_nothing_raised {
+ list = server.list(sfile, :manage, true, false, client1, ip)
+ }
+ assert_equal("", list)
+ assert_nothing_raised {
+ list = server.list(sfile, :manage, true, false, client2, ip)
+ }
+ assert_equal("/\tfile", list)
- # check describe
- sfile = "/host/file.txt"
- assert_nothing_raised {
- list = server.describe(sfile, :manage, client1, ip).split("\t")
- }
- assert_equal(5, list.size)
- assert_equal("file", list[1])
- md5 = Digest::MD5.hexdigest(contents[client1_hostdir])
- assert_equal("{md5}#{md5}", list[4])
+ # check describe
+ sfile = "/host/file.txt"
+ assert_nothing_raised {
+ list = server.describe(sfile, :manage, client1, ip).split("\t")
+ }
+ assert_equal(5, list.size)
+ assert_equal("file", list[1])
+ md5 = Digest::MD5.hexdigest(contents[client1_hostdir])
+ assert_equal("{md5}#{md5}", list[4])
- assert_nothing_raised {
- list = server.describe(sfile, :manage, client2, ip).split("\t")
- }
- assert_equal([], list)
+ assert_nothing_raised {
+ list = server.describe(sfile, :manage, client2, ip).split("\t")
+ }
+ assert_equal([], list)
- sfile = "/fqdn/file.txt"
- assert_nothing_raised {
- list = server.describe(sfile, :manage, client1, ip).split("\t")
- }
- assert_equal([], list)
+ sfile = "/fqdn/file.txt"
+ assert_nothing_raised {
+ list = server.describe(sfile, :manage, client1, ip).split("\t")
+ }
+ assert_equal([], list)
- assert_nothing_raised {
- list = server.describe(sfile, :manage, client2, ip).split("\t")
- }
- assert_equal(5, list.size)
- assert_equal("file", list[1])
- md5 = Digest::MD5.hexdigest(contents[client2_fqdndir])
- assert_equal("{md5}#{md5}", list[4])
-
- # Check retrieve
- sfile = "/host/file.txt"
- assert_nothing_raised {
- list = server.retrieve(sfile, :manage, client1, ip).chomp
- }
- assert_equal(contents[client1_hostdir].chomp, list)
+ assert_nothing_raised {
+ list = server.describe(sfile, :manage, client2, ip).split("\t")
+ }
+ assert_equal(5, list.size)
+ assert_equal("file", list[1])
+ md5 = Digest::MD5.hexdigest(contents[client2_fqdndir])
+ assert_equal("{md5}#{md5}", list[4])
- assert_nothing_raised {
- list = server.retrieve(sfile, :manage, client2, ip).chomp
- }
- assert_equal("", list)
+ # Check retrieve
+ sfile = "/host/file.txt"
+ assert_nothing_raised {
+ list = server.retrieve(sfile, :manage, client1, ip).chomp
+ }
+ assert_equal(contents[client1_hostdir].chomp, list)
- sfile = "/fqdn/file.txt"
- assert_nothing_raised {
- list = server.retrieve(sfile, :manage, client1, ip).chomp
- }
- assert_equal("", list)
+ assert_nothing_raised {
+ list = server.retrieve(sfile, :manage, client2, ip).chomp
+ }
+ assert_equal("", list)
- assert_nothing_raised {
- list = server.retrieve(sfile, :manage, client2, ip).chomp
- }
- assert_equal(contents[client2_fqdndir].chomp, list)
- end
+ sfile = "/fqdn/file.txt"
+ assert_nothing_raised {
+ list = server.retrieve(sfile, :manage, client1, ip).chomp
+ }
+ assert_equal("", list)
- # Make sure the 'subdir' method in Mount works.
- def test_mount_subdir
- mount = nil
- base = tempfile
- Dir.mkdir(base)
- subdir = File.join(base, "subdir")
- Dir.mkdir(subdir)
- [base, subdir].each do |d|
- File.open(File.join(d, "file"), "w") { |f| f.puts "bazoo" }
- end
- mount = mkmount(base)
-
- assert_equal(base, mount.subdir, "Did not default to base path")
- assert_equal(subdir, mount.subdir("subdir"), "Did not default to base path")
+ assert_nothing_raised {
+ list = server.retrieve(sfile, :manage, client2, ip).chomp
+ }
+ assert_equal(contents[client2_fqdndir].chomp, list)
+ end
+
+ # Make sure the 'subdir' method in Mount works.
+ def test_mount_subdir
+ mount = nil
+ base = tempfile
+ Dir.mkdir(base)
+ subdir = File.join(base, "subdir")
+ Dir.mkdir(subdir)
+ [base, subdir].each do |d|
+ File.open(File.join(d, "file"), "w") { |f| f.puts "bazoo" }
end
+ mount = mkmount(base)
- # Make sure mounts get correctly marked expandable or not, depending on
- # the path.
- def test_expandable
- name = "yaytest"
- dir = tempfile
- Dir.mkdir(dir)
+ assert_equal(base, mount.subdir, "Did not default to base path")
+ assert_equal(subdir, mount.subdir("subdir"), "Did not default to base path")
+ end
- mount = mkmount
- assert_nothing_raised {
- mount.path = dir
- }
+ # Make sure mounts get correctly marked expandable or not, depending on
+ # the path.
+ def test_expandable
+ name = "yaytest"
+ dir = tempfile
+ Dir.mkdir(dir)
- assert(! mount.expandable?, "Mount incorrectly called expandable")
+ mount = mkmount
+ assert_nothing_raised {
+ mount.path = dir
+ }
- assert_nothing_raised {
- mount.path = "/dir/a%a"
- }
- assert(mount.expandable?, "Mount not called expandable")
+ assert(! mount.expandable?, "Mount incorrectly called expandable")
- # This isn't a valid replacement pattern, so it should throw an error
- # because the dir doesn't exist
- assert_raise(Puppet::Network::Handler::FileServerError) {
- mount.path = "/dir/a%"
- }
+ assert_nothing_raised {
+ mount.path = "/dir/a%a"
+ }
+ assert(mount.expandable?, "Mount not called expandable")
- # Now send it back to a normal path
- assert_nothing_raised {
- mount.path = dir
- }
- # Make sure it got reverted
- assert(! mount.expandable?, "Mount incorrectly called expandable")
+ # This isn't a valid replacement pattern, so it should throw an error
+ # because the dir doesn't exist
+ assert_raise(Puppet::Network::Handler::FileServerError) {
+ mount.path = "/dir/a%"
+ }
+ # Now send it back to a normal path
+ assert_nothing_raised {
+ mount.path = dir
+ }
+ # Make sure it got reverted
+ assert(! mount.expandable?, "Mount incorrectly called expandable")
- end
- def test_mount_expand
- mount = mkmount
-
- check = proc do |client, pattern, repl|
- path = "/my/#{pattern}/file"
- assert_equal("/my/#{repl}/file", mount.expand(path, client))
- end
-
- # Do a round of checks with a fake client
- client = "host.domain.com"
- {"%h" => "host", # Short name
- "%H" => client, # Full name
- "%d" => "domain.com", # domain
- "%%" => "%", # escape
- "%o" => "%o" # other
- }.each do |pat, repl|
- result = check.call(client, pat, repl)
- end
-
- # Now, check that they use Facter info
- client = nil
- Facter.stubs(:value).with { |v| v.to_s == "hostname" }.returns("myhost")
- Facter.stubs(:value).with { |v| v.to_s == "domain" }.returns("mydomain.com")
-
-
- Facter.stubs(:to_hash).returns(
- {
- :ipaddress => "127.0.0.1",
- :hostname => "myhost",
- :domain => "mydomain.com",
-
- })
-
-
- {"%h" => "myhost", # Short name
- "%H" => "myhost.mydomain.com", # Full name
- "%d" => "mydomain.com", # domain
- "%%" => "%", # escape
- "%o" => "%o" # other
- }.each do |pat, repl|
- check.call(client, pat, repl)
- end
+ end
- end
+ def test_mount_expand
+ mount = mkmount
- # Test that the fileserver expands the %h and %d things.
- def test_fileserver_expansion
- server = nil
- assert_nothing_raised {
+ check = proc do |client, pattern, repl|
+ path = "/my/#{pattern}/file"
+ assert_equal("/my/#{repl}/file", mount.expand(path, client))
+ end
- server = Puppet::Network::Handler.fileserver.new(
+ # Do a round of checks with a fake client
+ client = "host.domain.com"
+ {"%h" => "host", # Short name
+ "%H" => client, # Full name
+ "%d" => "domain.com", # domain
+ "%%" => "%", # escape
+ "%o" => "%o" # other
+ }.each do |pat, repl|
+ result = check.call(client, pat, repl)
+ end
- :Local => true,
+ # Now, check that they use Facter info
+ client = nil
+ Facter.stubs(:value).with { |v| v.to_s == "hostname" }.returns("myhost")
+ Facter.stubs(:value).with { |v| v.to_s == "domain" }.returns("mydomain.com")
- :Config => false
- )
- }
- dir = tempfile
+ Facter.stubs(:to_hash).returns(
+ {
+ :ipaddress => "127.0.0.1",
+ :hostname => "myhost",
+ :domain => "mydomain.com",
- # When mocks attack, part 2
- kernel_fact = Facter.value(:kernel)
+ })
- ip = '127.0.0.1'
+ {"%h" => "myhost", # Short name
+ "%H" => "myhost.mydomain.com", # Full name
+ "%d" => "mydomain.com", # domain
+ "%%" => "%", # escape
+ "%o" => "%o" # other
+ }.each do |pat, repl|
+ check.call(client, pat, repl)
+ end
- Facter.stubs(:to_hash).returns(
- {
- :kernel => kernel_fact,
- :ipaddress => "127.0.0.1",
- :hostname => "myhost",
- :domain => "mydomain.com",
+ end
- })
+ # Test that the fileserver expands the %h and %d things.
+ def test_fileserver_expansion
+ server = nil
+ assert_nothing_raised {
- Dir.mkdir(dir)
- host = "myhost.mydomain.com"
- {
- "%H" => "myhost.mydomain.com", "%h" => "myhost", "%d" => "mydomain.com"
- }.each do |pattern, string|
- file = File.join(dir, string)
- mount = File.join(dir, pattern)
- File.open(file, "w") do |f| f.puts "yayness: #{string}" end
- name = "name"
- obj = nil
- assert_nothing_raised {
- obj = server.mount(mount, name)
- }
- obj.allow "*"
+ server = Puppet::Network::Handler.fileserver.new(
- ret = nil
- assert_nothing_raised do
- ret = server.list("/name", :manage, false, false, host, ip)
- end
+ :Local => true,
- assert_equal("/\tfile", ret)
+ :Config => false
+ )
+ }
- assert_nothing_raised do
- ret = server.describe("/name", :manage, host, ip)
- end
- assert(ret =~ /\tfile\t/, "Did not get valid a description (#{ret.inspect})")
+ dir = tempfile
- assert_nothing_raised do
- ret = server.retrieve("/name", :manage, host, ip)
- end
+ # When mocks attack, part 2
+ kernel_fact = Facter.value(:kernel)
- assert_equal(ret, File.read(file))
+ ip = '127.0.0.1'
- server.umount(name)
- File.unlink(file)
- end
+ Facter.stubs(:to_hash).returns(
+ {
+ :kernel => kernel_fact,
+ :ipaddress => "127.0.0.1",
+ :hostname => "myhost",
+ :domain => "mydomain.com",
+
+ })
+
+ Dir.mkdir(dir)
+ host = "myhost.mydomain.com"
+ {
+ "%H" => "myhost.mydomain.com", "%h" => "myhost", "%d" => "mydomain.com"
+ }.each do |pattern, string|
+ file = File.join(dir, string)
+ mount = File.join(dir, pattern)
+ File.open(file, "w") do |f| f.puts "yayness: #{string}" end
+ name = "name"
+ obj = nil
+ assert_nothing_raised {
+ obj = server.mount(mount, name)
+ }
+ obj.allow "*"
+
+ ret = nil
+ assert_nothing_raised do
+ ret = server.list("/name", :manage, false, false, host, ip)
+ end
+
+ assert_equal("/\tfile", ret)
+
+ assert_nothing_raised do
+ ret = server.describe("/name", :manage, host, ip)
+ end
+ assert(ret =~ /\tfile\t/, "Did not get valid a description (#{ret.inspect})")
+
+ assert_nothing_raised do
+ ret = server.retrieve("/name", :manage, host, ip)
+ end
+
+ assert_equal(ret, File.read(file))
+
+ server.umount(name)
+
+ File.unlink(file)
end
+ end
+
+ # Test the default modules fileserving
+ def test_modules_default
+ moddir = tempfile
+ Dir.mkdir(moddir)
+ mounts = {}
+ Puppet[:modulepath] = moddir
+
+ mods = %w{green red}.collect do |name|
+ path = File::join(moddir, name, Puppet::Module::FILES)
+ FileUtils::mkdir_p(path)
+ if name == "green"
+ file = File::join(path, "test.txt")
+ File::open(file, "w") { |f| f.print name }
+ end
- # Test the default modules fileserving
- def test_modules_default
- moddir = tempfile
- Dir.mkdir(moddir)
- mounts = {}
- Puppet[:modulepath] = moddir
-
- mods = %w{green red}.collect do |name|
- path = File::join(moddir, name, Puppet::Module::FILES)
- FileUtils::mkdir_p(path)
- if name == "green"
- file = File::join(path, "test.txt")
- File::open(file, "w") { |f| f.print name }
- end
-
- Puppet::Module::find(name)
- end
+ Puppet::Module::find(name)
+ end
- conffile = tempfile
+ conffile = tempfile
- File.open(conffile, "w") { |f| f.puts "# a test config file" }
+ File.open(conffile, "w") { |f| f.puts "# a test config file" }
- # create a server with the file
- server = nil
- assert_nothing_raised {
+ # create a server with the file
+ server = nil
+ assert_nothing_raised {
- server = Puppet::Network::Handler::FileServer.new(
+ server = Puppet::Network::Handler::FileServer.new(
- :Local => false ,
+ :Local => false ,
- :Config => conffile
- )
- }
+ :Config => conffile
+ )
+ }
- mods.each do |mod|
- mount = "/#{mod.name}/"
- list = nil
- assert_nothing_raised {
- list = server.list(mount, :manage, true, false)
- }
- list = list.split("\n")
- if mod.name == "green"
- assert_equal(2, list.size)
- assert_equal("/\tdirectory", list[0])
- assert_equal("/test.txt\tfile", list[1])
- else
- assert_equal(1, list.size)
- assert_equal("/\tdirectory", list[0])
- end
-
- assert_nothing_raised("Host 'allow' denied #{mount}") {
- server.list(mount, :manage, true, false, 'allow.example.com', "192.168.0.1")
- }
- end
+ mods.each do |mod|
+ mount = "/#{mod.name}/"
+ list = nil
+ assert_nothing_raised {
+ list = server.list(mount, :manage, true, false)
+ }
+ list = list.split("\n")
+ if mod.name == "green"
+ assert_equal(2, list.size)
+ assert_equal("/\tdirectory", list[0])
+ assert_equal("/test.txt\tfile", list[1])
+ else
+ assert_equal(1, list.size)
+ assert_equal("/\tdirectory", list[0])
+ end
+
+ assert_nothing_raised("Host 'allow' denied #{mount}") {
+ server.list(mount, :manage, true, false, 'allow.example.com', "192.168.0.1")
+ }
end
+ end
- # Test that configuring deny/allow for modules works
- def test_modules_config
- moddir = tempfile
- Dir.mkdir(moddir)
- mounts = {}
- Puppet[:modulepath] = moddir
+ # Test that configuring deny/allow for modules works
+ def test_modules_config
+ moddir = tempfile
+ Dir.mkdir(moddir)
+ mounts = {}
+ Puppet[:modulepath] = moddir
- path = File::join(moddir, "amod", Puppet::Module::FILES)
- file = File::join(path, "test.txt")
- FileUtils::mkdir_p(path)
- File::open(file, "w") { |f| f.print "Howdy" }
+ path = File::join(moddir, "amod", Puppet::Module::FILES)
+ file = File::join(path, "test.txt")
+ FileUtils::mkdir_p(path)
+ File::open(file, "w") { |f| f.print "Howdy" }
- mod = Puppet::Module::find("amod")
+ mod = Puppet::Module::find("amod")
- conffile = tempfile
- @@tmpfiles << conffile
+ conffile = tempfile
+ @@tmpfiles << conffile
- File.open(conffile, "w") { |f|
- f.print "# a test config file
+ File.open(conffile, "w") { |f|
+ f.print "# a test config file
[modules]
- path #{basedir}/thing
- allow 192.168.0.*
+ path #{basedir}/thing
+ allow 192.168.0.*
"
- }
+ }
- # create a server with the file
- server = nil
- assert_nothing_raised {
+ # create a server with the file
+ server = nil
+ assert_nothing_raised {
- server = Puppet::Network::Handler::FileServer.new(
+ server = Puppet::Network::Handler::FileServer.new(
- :Local => false,
+ :Local => false,
- :Config => conffile
- )
- }
+ :Config => conffile
+ )
+ }
- list = nil
- mount = "/#{mod.name}/"
- assert_nothing_raised {
- list = server.list(mount, :manage, true, false)
- }
+ list = nil
+ mount = "/#{mod.name}/"
+ assert_nothing_raised {
+ list = server.list(mount, :manage, true, false)
+ }
- assert_nothing_raised {
- list.split("\n").each { |line|
- file, type = line.split("\t")
- server.describe(mount + file)
- }
- }
+ assert_nothing_raised {
+ list.split("\n").each { |line|
+ file, type = line.split("\t")
+ server.describe(mount + file)
+ }
+ }
- assert_describe(mount, file, server)
+ assert_describe(mount, file, server)
- # now let's check that things are being correctly forbidden
+ # now let's check that things are being correctly forbidden
- assert_raise(
- Puppet::AuthorizationError,
+ assert_raise(
+ Puppet::AuthorizationError,
- "Host 'deny' allowed #{mount}") {
- server.list(mount, :manage, true, false, 'deny.example.com', "192.168.1.1")
- }
- assert_nothing_raised("Host 'allow' denied #{mount}") {
- server.list(mount, :manage, true, false, 'allow.example.com', "192.168.0.1")
- }
- end
+ "Host 'deny' allowed #{mount}") {
+ server.list(mount, :manage, true, false, 'deny.example.com', "192.168.1.1")
+ }
+ assert_nothing_raised("Host 'allow' denied #{mount}") {
+ server.list(mount, :manage, true, false, 'allow.example.com', "192.168.0.1")
+ }
+ end
- # Make sure we successfully throw errors -- someone ran into this with
- # 0.22.4.
- def test_failures
- # create a server with the file
- server = nil
+ # Make sure we successfully throw errors -- someone ran into this with
+ # 0.22.4.
+ def test_failures
+ # create a server with the file
+ server = nil
- config = tempfile
- [
- "[this is invalid]\nallow one.two.com", # invalid name
- "[valid]\nallow *.testing something.com", # invalid allow
- "[valid]\nallow one.two.com\ndeny *.testing something.com", # invalid deny
- ].each do |failer|
- File.open(config, "w") { |f| f.puts failer }
- assert_raise(Puppet::Network::Handler::FileServerError, "Did not fail on #{failer.inspect}") {
+ config = tempfile
+ [
+ "[this is invalid]\nallow one.two.com", # invalid name
+ "[valid]\nallow *.testing something.com", # invalid allow
+ "[valid]\nallow one.two.com\ndeny *.testing something.com", # invalid deny
+ ].each do |failer|
+ File.open(config, "w") { |f| f.puts failer }
+ assert_raise(Puppet::Network::Handler::FileServerError, "Did not fail on #{failer.inspect}") {
- server = Puppet::Network::Handler::FileServer.new(
+ server = Puppet::Network::Handler::FileServer.new(
- :Local => false,
+ :Local => false,
- :Config => config
- )
- }
- end
+ :Config => config
+ )
+ }
end
-
- def test_can_start_without_configuration
- Puppet[:fileserverconfig] = tempfile
- assert_nothing_raised("Could not create fileserver when configuration is absent") do
- server = Puppet::Network::Handler::FileServer.new(
- :Local => false
- )
- end
+ end
+
+ def test_can_start_without_configuration
+ Puppet[:fileserverconfig] = tempfile
+ assert_nothing_raised("Could not create fileserver when configuration is absent") do
+ server = Puppet::Network::Handler::FileServer.new(
+ :Local => false
+ )
end
+ end
- def test_creates_default_mounts_when_no_configuration_is_available
- Puppet[:fileserverconfig] = tempfile
- server = Puppet::Network::Handler::FileServer.new(:Local => false)
+ def test_creates_default_mounts_when_no_configuration_is_available
+ Puppet[:fileserverconfig] = tempfile
+ server = Puppet::Network::Handler::FileServer.new(:Local => false)
- assert(server.mounted?("plugins"), "Did not create default plugins mount when missing configuration file")
- assert(server.mounted?("modules"), "Did not create default modules mount when missing configuration file")
- end
+ assert(server.mounted?("plugins"), "Did not create default plugins mount when missing configuration file")
+ assert(server.mounted?("modules"), "Did not create default modules mount when missing configuration file")
+ end
end
diff --git a/test/network/handler/master.rb b/test/network/handler/master.rb
index a802b0a..81869ac 100755
--- a/test/network/handler/master.rb
+++ b/test/network/handler/master.rb
@@ -6,89 +6,89 @@ require 'puppettest'
require 'puppet/network/handler/master'
class TestMaster < Test::Unit::TestCase
- include PuppetTest::ServerTest
+ include PuppetTest::ServerTest
- def setup
- super
- @master = Puppet::Network::Handler.master.new(:Manifest => tempfile)
+ def setup
+ super
+ @master = Puppet::Network::Handler.master.new(:Manifest => tempfile)
- @catalog = stub 'catalog', :extract => ""
- Puppet::Resource::Catalog.stubs(:find).returns(@catalog)
- end
+ @catalog = stub 'catalog', :extract => ""
+ Puppet::Resource::Catalog.stubs(:find).returns(@catalog)
+ end
- def teardown
- super
- Puppet::Util::Cacher.expire
- end
+ def teardown
+ super
+ Puppet::Util::Cacher.expire
+ end
- def test_freshness_is_always_now
- now1 = mock 'now1'
- Time.stubs(:now).returns(now1)
+ def test_freshness_is_always_now
+ now1 = mock 'now1'
+ Time.stubs(:now).returns(now1)
- now1.expects(:to_i).returns 10
+ now1.expects(:to_i).returns 10
- assert_equal(@master.freshness, 10, "Did not return current time as freshness")
- end
+ assert_equal(@master.freshness, 10, "Did not return current time as freshness")
+ end
- def test_hostname_is_used_if_client_is_missing
- @master.expects(:decode_facts).returns("hostname" => "yay")
- Puppet::Node::Facts.expects(:new).with { |name, facts| name == "yay" }.returns(stub('facts', :save => nil))
+ def test_hostname_is_used_if_client_is_missing
+ @master.expects(:decode_facts).returns("hostname" => "yay")
+ Puppet::Node::Facts.expects(:new).with { |name, facts| name == "yay" }.returns(stub('facts', :save => nil))
- @master.getconfig("facts")
- end
+ @master.getconfig("facts")
+ end
- def test_facts_are_saved
- facts = mock('facts')
- Puppet::Node::Facts.expects(:new).returns(facts)
- facts.expects(:save)
+ def test_facts_are_saved
+ facts = mock('facts')
+ Puppet::Node::Facts.expects(:new).returns(facts)
+ facts.expects(:save)
- @master.stubs(:decode_facts)
+ @master.stubs(:decode_facts)
- @master.getconfig("facts", "yaml", "foo.com")
- end
+ @master.getconfig("facts", "yaml", "foo.com")
+ end
- def test_catalog_is_used_for_compiling
- facts = stub('facts', :save => nil)
- Puppet::Node::Facts.stubs(:new).returns(facts)
+ def test_catalog_is_used_for_compiling
+ facts = stub('facts', :save => nil)
+ Puppet::Node::Facts.stubs(:new).returns(facts)
- @master.stubs(:decode_facts)
+ @master.stubs(:decode_facts)
- Puppet::Resource::Catalog.expects(:find).with("foo.com").returns(@catalog)
+ Puppet::Resource::Catalog.expects(:find).with("foo.com").returns(@catalog)
- @master.getconfig("facts", "yaml", "foo.com")
- end
+ @master.getconfig("facts", "yaml", "foo.com")
+ end
end
class TestMasterFormats < Test::Unit::TestCase
- def setup
- @facts = stub('facts', :save => nil)
- Puppet::Node::Facts.stubs(:new).returns(@facts)
+ def setup
+ @facts = stub('facts', :save => nil)
+ Puppet::Node::Facts.stubs(:new).returns(@facts)
- @master = Puppet::Network::Handler.master.new(:Code => "")
- @master.stubs(:decode_facts)
+ @master = Puppet::Network::Handler.master.new(:Code => "")
+ @master.stubs(:decode_facts)
- @catalog = stub 'catalog', :extract => ""
- Puppet::Resource::Catalog.stubs(:find).returns(@catalog)
- end
+ @catalog = stub 'catalog', :extract => ""
+ Puppet::Resource::Catalog.stubs(:find).returns(@catalog)
+ end
- def test_marshal_can_be_used
- @catalog.expects(:extract).returns "myextract"
+ def test_marshal_can_be_used
+ @catalog.expects(:extract).returns "myextract"
- Marshal.expects(:dump).with("myextract").returns "eh"
+ Marshal.expects(:dump).with("myextract").returns "eh"
- @master.getconfig("facts", "marshal", "foo.com")
- end
+ @master.getconfig("facts", "marshal", "foo.com")
+ end
- def test_yaml_can_be_used
- extract = mock 'extract'
- @catalog.expects(:extract).returns extract
+ def test_yaml_can_be_used
+ extract = mock 'extract'
+ @catalog.expects(:extract).returns extract
- extract.expects(:to_yaml).returns "myaml"
+ extract.expects(:to_yaml).returns "myaml"
- @master.getconfig("facts", "yaml", "foo.com")
- end
+ @master.getconfig("facts", "yaml", "foo.com")
+ end
- def test_failure_when_non_yaml_or_marshal_is_used
- assert_raise(RuntimeError) { @master.getconfig("facts", "blah", "foo.com") }
- end
+ def test_failure_when_non_yaml_or_marshal_is_used
+ assert_raise(RuntimeError) { @master.getconfig("facts", "blah", "foo.com") }
+ end
end
diff --git a/test/network/handler/report.rb b/test/network/handler/report.rb
index ed7a96f..590dcdb 100755
--- a/test/network/handler/report.rb
+++ b/test/network/handler/report.rb
@@ -7,77 +7,77 @@ require 'puppet/network/handler/report'
require 'puppettest/reporttesting'
class TestReportServer < Test::Unit::TestCase
- include PuppetTest
- include PuppetTest::Reporttesting
-
- Report = Puppet::Network::Handler.report
- Puppet::Util.logmethods(self)
-
- def mkserver
- server = nil
- assert_nothing_raised {
- server = Puppet::Network::Handler.report.new
- }
- server
- end
-
- def mkclient(server = nil)
- server ||= mkserver
- client = nil
- assert_nothing_raised {
- client = Puppet::Network::Client.report.new(:Report => server)
- }
-
- client
- end
-
- def test_process
- server = Puppet::Network::Handler.report.new
-
- # We have to run multiple reports to make sure there's no conflict
- reports = []
- $run = []
- 2.times do |i|
- name = "processtest#{i}"
- reports << name
-
- Report.newreport(name) do
- def process
- $run << self.report_name
- end
- end
+ include PuppetTest
+ include PuppetTest::Reporttesting
+
+ Report = Puppet::Network::Handler.report
+ Puppet::Util.logmethods(self)
+
+ def mkserver
+ server = nil
+ assert_nothing_raised {
+ server = Puppet::Network::Handler.report.new
+ }
+ server
+ end
+
+ def mkclient(server = nil)
+ server ||= mkserver
+ client = nil
+ assert_nothing_raised {
+ client = Puppet::Network::Client.report.new(:Report => server)
+ }
+
+ client
+ end
+
+ def test_process
+ server = Puppet::Network::Handler.report.new
+
+ # We have to run multiple reports to make sure there's no conflict
+ reports = []
+ $run = []
+ 2.times do |i|
+ name = "processtest#{i}"
+ reports << name
+
+ Report.newreport(name) do
+ def process
+ $run << self.report_name
end
- Puppet[:reports] = reports.collect { |r| r.to_s }.join(",")
-
- report = fakereport
+ end
+ end
+ Puppet[:reports] = reports.collect { |r| r.to_s }.join(",")
- retval = nil
- assert_nothing_raised {
- retval = server.send(:process, YAML.dump(report))
- }
+ report = fakereport
- reports.each do |name|
- assert($run.include?(name.intern), "Did not run #{name}")
- end
+ retval = nil
+ assert_nothing_raised {
+ retval = server.send(:process, YAML.dump(report))
+ }
- # Now make sure our server doesn't die on missing reports
- Puppet[:reports] = "fakereport"
- assert_nothing_raised {
- retval = server.send(:process, YAML.dump(report))
- }
+ reports.each do |name|
+ assert($run.include?(name.intern), "Did not run #{name}")
end
- def test_reports
- Puppet[:reports] = "myreport"
+ # Now make sure our server doesn't die on missing reports
+ Puppet[:reports] = "fakereport"
+ assert_nothing_raised {
+ retval = server.send(:process, YAML.dump(report))
+ }
+ end
- # Create a server
- server = Puppet::Network::Handler.report.new
+ def test_reports
+ Puppet[:reports] = "myreport"
- {"myreport" => ["myreport"],
- " fake, another, yay " => ["fake", "another", "yay"]
- }.each do |str, ary|
- Puppet[:reports] = str
- assert_equal(ary, server.send(:reports))
- end
+ # Create a server
+ server = Puppet::Network::Handler.report.new
+
+ {"myreport" => ["myreport"],
+ " fake, another, yay " => ["fake", "another", "yay"]
+ }.each do |str, ary|
+ Puppet[:reports] = str
+ assert_equal(ary, server.send(:reports))
end
+ end
end
diff --git a/test/network/handler/runner.rb b/test/network/handler/runner.rb
index 6bf783b..396568b 100755
--- a/test/network/handler/runner.rb
+++ b/test/network/handler/runner.rb
@@ -6,15 +6,15 @@ require 'puppettest'
require 'puppet/network/handler/runner'
class TestHandlerRunner < Test::Unit::TestCase
- include PuppetTest
+ include PuppetTest
- def test_it_calls_agent_runner
- runner = mock 'runner'
- Puppet::Run.expects(:new).with(:tags => "mytags", :ignoreschedules => true, :background => false).returns runner
- runner.expects(:run)
- runner.expects(:status).returns "yay"
+ def test_it_calls_agent_runner
+ runner = mock 'runner'
+ Puppet::Run.expects(:new).with(:tags => "mytags", :ignoreschedules => true, :background => false).returns runner
+ runner.expects(:run)
+ runner.expects(:status).returns "yay"
- assert_equal("yay", Puppet::Network::Handler.runner.new.run("mytags", true, true))
- end
+ assert_equal("yay", Puppet::Network::Handler.runner.new.run("mytags", true, true))
+ end
end
diff --git a/test/network/rights.rb b/test/network/rights.rb
index 80d6cea..df032b5 100755
--- a/test/network/rights.rb
+++ b/test/network/rights.rb
@@ -6,35 +6,35 @@ require 'puppettest'
require 'puppet/network/rights'
class TestRights < Test::Unit::TestCase
- include PuppetTest
+ include PuppetTest
- def setup
- super
- @store = Puppet::Network::Rights.new
- end
+ def setup
+ super
+ @store = Puppet::Network::Rights.new
+ end
- def test_rights
- assert_raise(ArgumentError, "Did not fail on unknown right") {
- @store.allowed?(:write, "host.madstop.com", "0.0.0.0")
- }
+ def test_rights
+ assert_raise(ArgumentError, "Did not fail on unknown right") {
+ @store.allowed?(:write, "host.madstop.com", "0.0.0.0")
+ }
- assert_nothing_raised {
- @store.newright(:write)
- }
+ assert_nothing_raised {
+ @store.newright(:write)
+ }
- assert(
- ! @store.allowed?(:write, "host.madstop.com", "0.0.0.0"),
+ assert(
+ ! @store.allowed?(:write, "host.madstop.com", "0.0.0.0"),
- "Defaulted to allowing access")
+ "Defaulted to allowing access")
- assert_nothing_raised {
- @store[:write].info "This is a log message"
- }
+ assert_nothing_raised {
+ @store[:write].info "This is a log message"
+ }
- assert_logged(:info, /This is a log message/, "did not log from Rights")
- end
+ assert_logged(:info, /This is a log message/, "did not log from Rights")
+ end
end
diff --git a/test/network/server/mongrel_test.rb b/test/network/server/mongrel_test.rb
index 4414097..7bb2df1 100755
--- a/test/network/server/mongrel_test.rb
+++ b/test/network/server/mongrel_test.rb
@@ -6,100 +6,100 @@ require 'puppettest'
require 'mocha'
class TestMongrelServer < PuppetTest::TestCase
- confine "Missing mongrel" => Puppet.features.mongrel?
+ confine "Missing mongrel" => Puppet.features.mongrel?
+
+ include PuppetTest::ServerTest
+
+ def mkserver(handlers = nil)
+ handlers ||= { :Status => nil }
+ mongrel = Puppet::Network::HTTPServer::Mongrel.new(handlers)
+ end
+
+ # Make sure client info is correctly extracted.
+ def test_client_info
+ obj = Object.new
+ obj.singleton_class.send(:attr_accessor, :params)
+ params = {}
+ obj.params = params
+
+ mongrel = mkserver
+
+ ip = Facter.value(:ipaddress)
+ params["REMOTE_ADDR"] = ip
+ params[Puppet[:ssl_client_header]] = ""
+ params[Puppet[:ssl_client_verify_header]] = "failure"
+ info = nil
+ Resolv.expects(:getname).with(ip).returns("host.domain.com").times(4)
+ assert_nothing_raised("Could not call client_info") do
+ info = mongrel.send(:client_info, obj)
+ end
+ assert(! info.authenticated?, "Client info object was marked valid even though headers were missing")
+ assert_equal(ip, info.ip, "Did not copy over ip correctly")
+
+ assert_equal("host.domain.com", info.name, "Did not copy over hostname correctly")
+
+ # Now pass the X-Forwarded-For header and check it is preferred over REMOTE_ADDR
+ params["REMOTE_ADDR"] = '127.0.0.1'
+ params["HTTP_X_FORWARDED_FOR"] = ip
+ info = nil
+ assert_nothing_raised("Could not call client_info") do
+ info = mongrel.send(:client_info, obj)
+ end
+ assert(! info.authenticated?, "Client info object was marked valid even though headers were missing")
+ assert_equal(ip, info.ip, "Did not copy over ip correctly")
- include PuppetTest::ServerTest
+ assert_equal("host.domain.com", info.name, "Did not copy over hostname correctly")
- def mkserver(handlers = nil)
- handlers ||= { :Status => nil }
- mongrel = Puppet::Network::HTTPServer::Mongrel.new(handlers)
+ # Now add a valid auth header.
+ params["REMOTE_ADDR"] = ip
+ params["HTTP_X_FORWARDED_FOR"] = nil
+ params[Puppet[:ssl_client_header]] = "/CN=host.domain.com"
+ assert_nothing_raised("Could not call client_info") do
+ info = mongrel.send(:client_info, obj)
+ end
+ assert(! info.authenticated?, "Client info object was marked valid even though the verify header was fals")
+ assert_equal(ip, info.ip, "Did not copy over ip correctly")
+ assert_equal("host.domain.com", info.name, "Did not copy over hostname correctly")
+
+ # Now change the verify header to be true
+ params[Puppet[:ssl_client_verify_header]] = "SUCCESS"
+ assert_nothing_raised("Could not call client_info") do
+ info = mongrel.send(:client_info, obj)
end
- # Make sure client info is correctly extracted.
- def test_client_info
- obj = Object.new
- obj.singleton_class.send(:attr_accessor, :params)
- params = {}
- obj.params = params
-
- mongrel = mkserver
-
- ip = Facter.value(:ipaddress)
- params["REMOTE_ADDR"] = ip
- params[Puppet[:ssl_client_header]] = ""
- params[Puppet[:ssl_client_verify_header]] = "failure"
- info = nil
- Resolv.expects(:getname).with(ip).returns("host.domain.com").times(4)
- assert_nothing_raised("Could not call client_info") do
- info = mongrel.send(:client_info, obj)
- end
- assert(! info.authenticated?, "Client info object was marked valid even though headers were missing")
- assert_equal(ip, info.ip, "Did not copy over ip correctly")
-
- assert_equal("host.domain.com", info.name, "Did not copy over hostname correctly")
-
- # Now pass the X-Forwarded-For header and check it is preferred over REMOTE_ADDR
- params["REMOTE_ADDR"] = '127.0.0.1'
- params["HTTP_X_FORWARDED_FOR"] = ip
- info = nil
- assert_nothing_raised("Could not call client_info") do
- info = mongrel.send(:client_info, obj)
- end
- assert(! info.authenticated?, "Client info object was marked valid even though headers were missing")
- assert_equal(ip, info.ip, "Did not copy over ip correctly")
-
- assert_equal("host.domain.com", info.name, "Did not copy over hostname correctly")
-
- # Now add a valid auth header.
- params["REMOTE_ADDR"] = ip
- params["HTTP_X_FORWARDED_FOR"] = nil
- params[Puppet[:ssl_client_header]] = "/CN=host.domain.com"
- assert_nothing_raised("Could not call client_info") do
- info = mongrel.send(:client_info, obj)
- end
- assert(! info.authenticated?, "Client info object was marked valid even though the verify header was fals")
- assert_equal(ip, info.ip, "Did not copy over ip correctly")
- assert_equal("host.domain.com", info.name, "Did not copy over hostname correctly")
-
- # Now change the verify header to be true
- params[Puppet[:ssl_client_verify_header]] = "SUCCESS"
- assert_nothing_raised("Could not call client_info") do
- info = mongrel.send(:client_info, obj)
- end
-
- assert(info.authenticated?, "Client info object was not marked valid even though all headers were correct")
- assert_equal(ip, info.ip, "Did not copy over ip correctly")
- assert_equal("host.domain.com", info.name, "Did not copy over hostname correctly")
-
- # Now try it with a different header name
- params.delete(Puppet[:ssl_client_header])
- Puppet[:ssl_client_header] = "header_testing"
- params["header_testing"] = "/CN=other.domain.com"
- info = nil
- assert_nothing_raised("Could not call client_info with other header") do
- info = mongrel.send(:client_info, obj)
- end
-
- assert(info.authenticated?, "Client info object was not marked valid even though the header was present")
- assert_equal(ip, info.ip, "Did not copy over ip correctly")
- assert_equal("other.domain.com", info.name, "Did not copy over hostname correctly")
-
- # Now make sure it's considered invalid without that header
- params.delete("header_testing")
- info = nil
- assert_nothing_raised("Could not call client_info with no header") do
- info = mongrel.send(:client_info, obj)
- end
-
- assert(! info.authenticated?, "Client info object was marked valid without header")
- assert_equal(ip, info.ip, "Did not copy over ip correctly")
- assert_equal(Resolv.getname(ip), info.name, "Did not look up hostname correctly")
+ assert(info.authenticated?, "Client info object was not marked valid even though all headers were correct")
+ assert_equal(ip, info.ip, "Did not copy over ip correctly")
+ assert_equal("host.domain.com", info.name, "Did not copy over hostname correctly")
+
+ # Now try it with a different header name
+ params.delete(Puppet[:ssl_client_header])
+ Puppet[:ssl_client_header] = "header_testing"
+ params["header_testing"] = "/CN=other.domain.com"
+ info = nil
+ assert_nothing_raised("Could not call client_info with other header") do
+ info = mongrel.send(:client_info, obj)
end
- def test_daemonize
- mongrel = mkserver
+ assert(info.authenticated?, "Client info object was not marked valid even though the header was present")
+ assert_equal(ip, info.ip, "Did not copy over ip correctly")
+ assert_equal("other.domain.com", info.name, "Did not copy over hostname correctly")
- assert(mongrel.respond_to?(:daemonize), "Mongrel server does not respond to daemonize")
+ # Now make sure it's considered invalid without that header
+ params.delete("header_testing")
+ info = nil
+ assert_nothing_raised("Could not call client_info with no header") do
+ info = mongrel.send(:client_info, obj)
end
+
+ assert(! info.authenticated?, "Client info object was marked valid without header")
+ assert_equal(ip, info.ip, "Did not copy over ip correctly")
+ assert_equal(Resolv.getname(ip), info.name, "Did not look up hostname correctly")
+ end
+
+ def test_daemonize
+ mongrel = mkserver
+
+ assert(mongrel.respond_to?(:daemonize), "Mongrel server does not respond to daemonize")
+ end
end
diff --git a/test/network/server/webrick.rb b/test/network/server/webrick.rb
index cdc6820..e203894 100755
--- a/test/network/server/webrick.rb
+++ b/test/network/server/webrick.rb
@@ -7,122 +7,122 @@ require 'puppet/network/http_server/webrick'
require 'mocha'
class TestWebrickServer < Test::Unit::TestCase
- include PuppetTest::ServerTest
+ include PuppetTest::ServerTest
- def setup
- Puppet::Util::SUIDManager.stubs(:asuser).yields
- super
- end
+ def setup
+ Puppet::Util::SUIDManager.stubs(:asuser).yields
+ super
+ end
- def teardown
- super
- Puppet::Network::HttpPool.clear_http_instances
- end
+ def teardown
+ super
+ Puppet::Network::HttpPool.clear_http_instances
+ end
- # Make sure we can create a server, and that it knows how to create its
- # certs by default.
- def test_basics
- server = nil
- assert_raise(Puppet::Error, "server succeeded with no cert") do
+ # Make sure we can create a server, and that it knows how to create its
+ # certs by default.
+ def test_basics
+ server = nil
+ assert_raise(Puppet::Error, "server succeeded with no cert") do
- server = Puppet::Network::HTTPServer::WEBrick.new(
+ server = Puppet::Network::HTTPServer::WEBrick.new(
- :Port => @@port,
+ :Port => @@port,
- :Handlers => {
- :Status => nil
- }
- )
- end
+ :Handlers => {
+ :Status => nil
+ }
+ )
+ end
- assert_nothing_raised("Could not create simple server") do
+ assert_nothing_raised("Could not create simple server") do
- server = Puppet::Network::HTTPServer::WEBrick.new(
+ server = Puppet::Network::HTTPServer::WEBrick.new(
- :Port => @@port,
+ :Port => @@port,
- :Handlers => {
- :CA => {}, # so that certs autogenerate
- :Status => nil
- }
- )
- end
+ :Handlers => {
+ :CA => {}, # so that certs autogenerate
+ :Status => nil
+ }
+ )
+ end
- assert(server, "did not create server")
+ assert(server, "did not create server")
- assert(server.cert, "did not retrieve cert")
- end
+ assert(server.cert, "did not retrieve cert")
+ end
- # test that we can connect to the server
- # we have to use fork here, because we apparently can't use threads
- # to talk to other threads
- def test_connect_with_fork
- Puppet[:autosign] = true
- serverpid, server = mk_status_server
+ # test that we can connect to the server
+ # we have to use fork here, because we apparently can't use threads
+ # to talk to other threads
+ def test_connect_with_fork
+ Puppet[:autosign] = true
+ serverpid, server = mk_status_server
- # create a status client, and verify it can talk
- client = mk_status_client
+ # create a status client, and verify it can talk
+ client = mk_status_client
- assert(client.cert, "did not get cert for client")
+ assert(client.cert, "did not get cert for client")
- retval = nil
- assert_nothing_raised("Could not connect to server") {
- retval = client.status
- }
- assert_equal(1, retval)
- end
+ retval = nil
+ assert_nothing_raised("Could not connect to server") {
+ retval = client.status
+ }
+ assert_equal(1, retval)
+ end
- def mk_status_client
- client = nil
+ def mk_status_client
+ client = nil
- assert_nothing_raised {
+ assert_nothing_raised {
- client = Puppet::Network::Client.status.new(
+ client = Puppet::Network::Client.status.new(
- :Server => "localhost",
+ :Server => "localhost",
- :Port => @@port
- )
- }
- client
- end
-
- def mk_status_server
- server = nil
- Puppet[:certdnsnames] = "localhost"
- assert_nothing_raised {
-
- server = Puppet::Network::HTTPServer::WEBrick.new(
+ :Port => @@port
+ )
+ }
+ client
+ end
+
+ def mk_status_server
+ server = nil
+ Puppet[:certdnsnames] = "localhost"
+ assert_nothing_raised {
+
+ server = Puppet::Network::HTTPServer::WEBrick.new(
- :Port => @@port,
+ :Port => @@port,
- :Handlers => {
- :CA => {}, # so that certs autogenerate
- :Status => nil
- }
- )
-
+ :Handlers => {
+ :CA => {}, # so that certs autogenerate
+ :Status => nil
}
-
- pid = fork {
- Puppet.run_mode.stubs(:master?).returns true
- assert_nothing_raised {
- trap(:INT) { server.shutdown }
- server.start
- }
- }
- @@tmppids << pid
- [pid, server]
- end
-
- def kill_and_wait(pid, file)
- %x{kill -INT #{pid} 2>/dev/null}
- count = 0
- while count < 30 && File::exist?(file)
- count += 1
- sleep(1)
- end
- assert(count < 30, "Killing server #{pid} failed")
+ )
+
+ }
+
+ pid = fork {
+ Puppet.run_mode.stubs(:master?).returns true
+ assert_nothing_raised {
+ trap(:INT) { server.shutdown }
+ server.start
+ }
+ }
+ @@tmppids << pid
+ [pid, server]
+ end
+
+ def kill_and_wait(pid, file)
+ %x{kill -INT #{pid} 2>/dev/null}
+ count = 0
+ while count < 30 && File::exist?(file)
+ count += 1
+ sleep(1)
end
+ assert(count < 30, "Killing server #{pid} failed")
+ end
end
diff --git a/test/network/xmlrpc/client.rb b/test/network/xmlrpc/client.rb
index 53be5ca..7e7f369 100755
--- a/test/network/xmlrpc/client.rb
+++ b/test/network/xmlrpc/client.rb
@@ -7,39 +7,39 @@ require 'puppet/network/xmlrpc/client'
require 'mocha'
class TestXMLRPCClient < Test::Unit::TestCase
- include PuppetTest
+ include PuppetTest
- def setup
- Puppet::Util::SUIDManager.stubs(:asuser).yields
- super
- end
+ def setup
+ Puppet::Util::SUIDManager.stubs(:asuser).yields
+ super
+ end
- def test_set_backtrace
- error = Puppet::Network::XMLRPCClientError.new("An error")
- assert_nothing_raised do
- error.set_backtrace ["caller"]
- end
- assert_equal(["caller"], error.backtrace)
+ def test_set_backtrace
+ error = Puppet::Network::XMLRPCClientError.new("An error")
+ assert_nothing_raised do
+ error.set_backtrace ["caller"]
+ end
+ assert_equal(["caller"], error.backtrace)
+ end
+
+ # Make sure we correctly generate a netclient
+ def test_handler_class
+ # Create a test handler
+ klass = Puppet::Network::XMLRPCClient
+ yay = Class.new(Puppet::Network::Handler) do
+ @interface = XMLRPC::Service::Interface.new("yay") { |iface|
+ iface.add_method("array getcert(csr)")
+ }
+
+ @name = :Yay
end
+ Object.const_set("Yay", yay)
- # Make sure we correctly generate a netclient
- def test_handler_class
- # Create a test handler
- klass = Puppet::Network::XMLRPCClient
- yay = Class.new(Puppet::Network::Handler) do
- @interface = XMLRPC::Service::Interface.new("yay") { |iface|
- iface.add_method("array getcert(csr)")
- }
-
- @name = :Yay
- end
- Object.const_set("Yay", yay)
-
- net = nil
- assert_nothing_raised("Failed when retrieving client for handler") do
- net = klass.handler_class(yay)
- end
-
- assert(net, "did not get net client")
+ net = nil
+ assert_nothing_raised("Failed when retrieving client for handler") do
+ net = klass.handler_class(yay)
end
+
+ assert(net, "did not get net client")
+ end
end
diff --git a/test/network/xmlrpc/processor.rb b/test/network/xmlrpc/processor.rb
index 3bf7b7f..0c990c9 100755
--- a/test/network/xmlrpc/processor.rb
+++ b/test/network/xmlrpc/processor.rb
@@ -7,73 +7,73 @@ require 'puppet/network/xmlrpc/processor'
require 'mocha'
class TestXMLRPCProcessor < Test::Unit::TestCase
- include PuppetTest
- class BaseProcessor
- def add_handler(interface, handler)
- @handlers ||= {}
- @handlers[interface] = handler
- end
+ include PuppetTest
+ class BaseProcessor
+ def add_handler(interface, handler)
+ @handlers ||= {}
+ @handlers[interface] = handler
end
+ end
- # We use a base class just so super() works with add_handler.
- class Processor < BaseProcessor
- include Puppet::Network::XMLRPCProcessor
+ # We use a base class just so super() works with add_handler.
+ class Processor < BaseProcessor
+ include Puppet::Network::XMLRPCProcessor
- def set_service_hook(&block)
- meta_def(:service, &block)
- end
+ def set_service_hook(&block)
+ meta_def(:service, &block)
end
-
- def setup
- super
- Puppet::Util::SUIDManager.stubs(:asuser).yields
- @processor = Processor.new
+ end
+
+ def setup
+ super
+ Puppet::Util::SUIDManager.stubs(:asuser).yields
+ @processor = Processor.new
+ end
+
+ def test_handlers
+ ca = Puppet::Network::Handler.ca
+ @processor.send(:setup_processor)
+ assert(! @processor.handler_loaded?(:ca), "already have ca handler loaded")
+ assert_nothing_raised do
+ @processor.add_handler(ca.interface, ca.new)
end
- def test_handlers
- ca = Puppet::Network::Handler.ca
- @processor.send(:setup_processor)
- assert(! @processor.handler_loaded?(:ca), "already have ca handler loaded")
- assert_nothing_raised do
- @processor.add_handler(ca.interface, ca.new)
- end
+ assert(@processor.handler_loaded?(:puppetca), "ca handler not loaded by symbol")
+ assert(@processor.handler_loaded?("puppetca"), "ca handler not loaded by string")
+ end
- assert(@processor.handler_loaded?(:puppetca), "ca handler not loaded by symbol")
- assert(@processor.handler_loaded?("puppetca"), "ca handler not loaded by string")
+ def test_process
+ ca = Puppet::Network::Handler.ca
+ @processor.send(:setup_processor)
+ assert_nothing_raised do
+ @processor.add_handler(ca.interface, ca.new)
end
- def test_process
- ca = Puppet::Network::Handler.ca
- @processor.send(:setup_processor)
- assert_nothing_raised do
- @processor.add_handler(ca.interface, ca.new)
- end
+ fakeparser = Class.new do
+ def parseMethodCall(data)
+ data
+ end
+ end
- fakeparser = Class.new do
- def parseMethodCall(data)
- data
- end
- end
+ request = Puppet::Network::ClientRequest.new("fake", "192.168.0.1", false)
+ request.handler = "myhandler"
+ request.method = "mymethod"
- request = Puppet::Network::ClientRequest.new("fake", "192.168.0.1", false)
- request.handler = "myhandler"
- request.method = "mymethod"
+ @processor.expects(:parser).returns(fakeparser.new)
- @processor.expects(:parser).returns(fakeparser.new)
+ request.expects(:handler=).with("myhandler")
+ request.expects(:method=).with("mymethod")
- request.expects(:handler=).with("myhandler")
- request.expects(:method=).with("mymethod")
+ @processor.stubs(:verify)
+ @processor.expects(:handle).with(request.call, "params", request.name, request.ip)
- @processor.stubs(:verify)
- @processor.expects(:handle).with(request.call, "params", request.name, request.ip)
+ @processor.send(:process, ["myhandler.mymethod", ["params"]], request)
+ end
- @processor.send(:process, ["myhandler.mymethod", ["params"]], request)
- end
-
- def test_setup_processor
- @processor.expects(:set_service_hook)
- @processor.send(:setup_processor)
- end
+ def test_setup_processor
+ @processor.expects(:set_service_hook)
+ @processor.send(:setup_processor)
+ end
end
diff --git a/test/network/xmlrpc/server.rb b/test/network/xmlrpc/server.rb
index 88652a2..a5474b0 100755
--- a/test/network/xmlrpc/server.rb
+++ b/test/network/xmlrpc/server.rb
@@ -7,20 +7,20 @@ require 'puppet/network/xmlrpc/server'
require 'mocha'
class TestXMLRPCServer < Test::Unit::TestCase
- def setup
- super
- assert_nothing_raised do
- @server = Puppet::Network::XMLRPCServer.new
- end
+ def setup
+ super
+ assert_nothing_raised do
+ @server = Puppet::Network::XMLRPCServer.new
end
+ end
- def test_initialize
- assert(@server.get_service_hook, "no service hook defined")
+ def test_initialize
+ assert(@server.get_service_hook, "no service hook defined")
- assert_nothing_raised("Did not init @loadedhandlers") do
- assert(! @server.handler_loaded?(:puppetca), "server thinks handlers are loaded")
- end
+ assert_nothing_raised("Did not init @loadedhandlers") do
+ assert(! @server.handler_loaded?(:puppetca), "server thinks handlers are loaded")
end
+ end
end
diff --git a/test/network/xmlrpc/webrick_servlet.rb b/test/network/xmlrpc/webrick_servlet.rb
index d3daa4c..47bad27 100755
--- a/test/network/xmlrpc/webrick_servlet.rb
+++ b/test/network/xmlrpc/webrick_servlet.rb
@@ -8,28 +8,28 @@ require 'puppet/network/xmlrpc/webrick_servlet'
require 'mocha'
class TestXMLRPCWEBrickServlet < Test::Unit::TestCase
- include PuppetTest
- def test_basics
- # Make sure we're doing things as our user info, rather than puppet/puppet
- setme
- set_mygroup
- Puppet[:user] = @me
- Puppet[:group] = @mygroup
- servlet = nil
- ca = Puppet::Network::Handler.ca.new
-
- assert_nothing_raised("Could not create servlet") do
- servlet = Puppet::Network::XMLRPC::WEBrickServlet.new([ca])
- end
+ include PuppetTest
+ def test_basics
+ # Make sure we're doing things as our user info, rather than puppet/puppet
+ setme
+ set_mygroup
+ Puppet[:user] = @me
+ Puppet[:group] = @mygroup
+ servlet = nil
+ ca = Puppet::Network::Handler.ca.new
+
+ assert_nothing_raised("Could not create servlet") do
+ servlet = Puppet::Network::XMLRPC::WEBrickServlet.new([ca])
+ end
- assert(servlet.get_service_hook, "service hook was not set up")
+ assert(servlet.get_service_hook, "service hook was not set up")
- assert(
- servlet.handler_loaded?(:puppetca),
+ assert(
+ servlet.handler_loaded?(:puppetca),
- "Did not load handler")
- end
+ "Did not load handler")
+ end
end
diff --git a/test/other/provider.rb b/test/other/provider.rb
index 341c364..052d7a0 100755
--- a/test/other/provider.rb
+++ b/test/other/provider.rb
@@ -7,95 +7,95 @@ require 'puppet/provider'
require 'puppettest'
class TestImpl < Test::Unit::TestCase
- include PuppetTest
-
- def setup
- super
- @type = newtype(@method_name.to_s + "type")
-
- # But create a new provider for every method.
- @provider = newprovider(@method_name.to_s + "provider")
+ include PuppetTest
+
+ def setup
+ super
+ @type = newtype(@method_name.to_s + "type")
+
+ # But create a new provider for every method.
+ @provider = newprovider(@method_name.to_s + "provider")
+ end
+
+ def newtype(name)
+ # First create a fake type
+ return Puppet::Type.newtype(name) {
+ newparam(:name) { isnamevar }
+ }
+ end
+
+ def newprovider(name, type = nil)
+ type ||= @type
+ provider = nil
+ assert_nothing_raised("Could not create provider") do
+ provider = type.provide(name) {}
end
+ provider
+ end
- def newtype(name)
- # First create a fake type
- return Puppet::Type.newtype(name) {
- newparam(:name) { isnamevar }
- }
- end
+ def test_provider_default
+ nondef = nil
+ assert_nothing_raised {
+ nondef = newprovider(:nondefault)
+ }
- def newprovider(name, type = nil)
- type ||= @type
- provider = nil
- assert_nothing_raised("Could not create provider") do
- provider = type.provide(name) {}
- end
- provider
+ assert_nothing_raised do
+ @provider.defaultfor :operatingsystem => Facter["operatingsystem"].value
end
- def test_provider_default
- nondef = nil
- assert_nothing_raised {
- nondef = newprovider(:nondefault)
- }
+ assert_equal(@provider.name, @type.defaultprovider.name, "Did not get right provider")
- assert_nothing_raised do
- @provider.defaultfor :operatingsystem => Facter["operatingsystem"].value
- end
+ @type.suitableprovider
+ end
- assert_equal(@provider.name, @type.defaultprovider.name, "Did not get right provider")
+ def test_subclassconfines
+ parent = newprovider("parentprovider")
- @type.suitableprovider
- end
+ # Now make a bad confine on the parent
+ parent.confine :exists => "/this/file/definitely/does/not/exist"
- def test_subclassconfines
- parent = newprovider("parentprovider")
+ child = nil
+ assert_nothing_raised {
+ child = @type.provide("child", :parent => parent.name) {}
+ }
- # Now make a bad confine on the parent
- parent.confine :exists => "/this/file/definitely/does/not/exist"
+ assert(child.suitable?, "Parent ruled out child")
+ end
- child = nil
- assert_nothing_raised {
- child = @type.provide("child", :parent => parent.name) {}
- }
+ def test_commands
+ parent = newprovider("parentprovider")
- assert(child.suitable?, "Parent ruled out child")
- end
+ child = nil
+ assert_nothing_raised {
+ child = @type.provide("child", :parent => parent.name) {}
+ }
- def test_commands
- parent = newprovider("parentprovider")
+ assert_nothing_raised {
+ child.commands :which => "which"
+ }
- child = nil
- assert_nothing_raised {
- child = @type.provide("child", :parent => parent.name) {}
- }
+ assert(child.command(:which), "Did not find 'which' command")
- assert_nothing_raised {
- child.commands :which => "which"
- }
+ assert(child.command(:which) =~ /^\//,
+ "Command did not become fully qualified")
+ assert(FileTest.exists?(child.command(:which)),
+ "Did not find actual 'which' binary")
- assert(child.command(:which), "Did not find 'which' command")
-
- assert(child.command(:which) =~ /^\//,
- "Command did not become fully qualified")
- assert(FileTest.exists?(child.command(:which)),
- "Did not find actual 'which' binary")
-
- assert_raise(Puppet::DevError) do
- child.command(:nosuchcommand)
- end
+ assert_raise(Puppet::DevError) do
+ child.command(:nosuchcommand)
+ end
- # Now create a parent command
- assert_nothing_raised {
- parent.commands :sh => Puppet::Util.binary('sh')
- }
+ # Now create a parent command
+ assert_nothing_raised {
+ parent.commands :sh => Puppet::Util.binary('sh')
+ }
- assert(parent.command(:sh), "Did not find 'sh' command")
+ assert(parent.command(:sh), "Did not find 'sh' command")
- assert(child.command(:sh), "Did not find parent's 'sh' command")
+ assert(child.command(:sh), "Did not find parent's 'sh' command")
- assert(FileTest.exists?(child.command(:sh)),
- "Somehow broke path to sh")
- end
+ assert(FileTest.exists?(child.command(:sh)),
+ "Somehow broke path to sh")
+ end
end
diff --git a/test/other/puppet.rb b/test/other/puppet.rb
index 7caba89..657bdef 100755
--- a/test/other/puppet.rb
+++ b/test/other/puppet.rb
@@ -7,80 +7,80 @@ require 'puppettest'
# Test the different features of the main puppet module
class TestPuppetModule < Test::Unit::TestCase
- include PuppetTest
- include SignalObserver
-
- def mkfakeclient
- Class.new(Puppet::Network::Client) do
- def initialize
- end
-
- def runnow
- Puppet.info "fake client has run"
- end
- end
+ include PuppetTest
+ include SignalObserver
+
+ def mkfakeclient
+ Class.new(Puppet::Network::Client) do
+ def initialize
+ end
+
+ def runnow
+ Puppet.info "fake client has run"
+ end
end
+ end
- def mktestclass
- Class.new do
- def initialize(file)
- @file = file
- end
+ def mktestclass
+ Class.new do
+ def initialize(file)
+ @file = file
+ end
- def started?
- FileTest.exists?(@file)
- end
+ def started?
+ FileTest.exists?(@file)
+ end
- def start
- File.open(@file, "w") do |f| f.puts "" end
- end
+ def start
+ File.open(@file, "w") do |f| f.puts "" end
+ end
- def shutdown
- File.unlink(@file)
- end
- end
+ def shutdown
+ File.unlink(@file)
+ end
end
+ end
- def test_path
- oldpath = ENV["PATH"]
- cleanup do
- ENV["PATH"] = oldpath
- end
- newpath = oldpath + ":/something/else"
- assert_nothing_raised do
- Puppet[:path] = newpath
- end
-
- assert_equal(newpath, ENV["PATH"])
+ def test_path
+ oldpath = ENV["PATH"]
+ cleanup do
+ ENV["PATH"] = oldpath
+ end
+ newpath = oldpath + ":/something/else"
+ assert_nothing_raised do
+ Puppet[:path] = newpath
end
- def test_libdir
- oldlibs = $LOAD_PATH.dup
- cleanup do
- $LOAD_PATH.each do |dir|
- $LOAD_PATH.delete(dir) unless oldlibs.include?(dir)
- end
- end
- one = tempfile
- two = tempfile
- Dir.mkdir(one)
- Dir.mkdir(two)
-
- # Make sure setting the libdir gets the dir added to $LOAD_PATH
- assert_nothing_raised do
- Puppet[:libdir] = one
- end
-
- assert($LOAD_PATH.include?(one), "libdir was not added")
-
- # Now change it, make sure it gets added and the old one gets
- # removed
- assert_nothing_raised do
- Puppet[:libdir] = two
- end
-
- assert($LOAD_PATH.include?(two), "libdir was not added")
- assert(! $LOAD_PATH.include?(one), "old libdir was not removed")
+ assert_equal(newpath, ENV["PATH"])
+ end
+
+ def test_libdir
+ oldlibs = $LOAD_PATH.dup
+ cleanup do
+ $LOAD_PATH.each do |dir|
+ $LOAD_PATH.delete(dir) unless oldlibs.include?(dir)
+ end
+ end
+ one = tempfile
+ two = tempfile
+ Dir.mkdir(one)
+ Dir.mkdir(two)
+
+ # Make sure setting the libdir gets the dir added to $LOAD_PATH
+ assert_nothing_raised do
+ Puppet[:libdir] = one
end
+
+ assert($LOAD_PATH.include?(one), "libdir was not added")
+
+ # Now change it, make sure it gets added and the old one gets
+ # removed
+ assert_nothing_raised do
+ Puppet[:libdir] = two
+ end
+
+ assert($LOAD_PATH.include?(two), "libdir was not added")
+ assert(! $LOAD_PATH.include?(one), "old libdir was not removed")
+ end
end
diff --git a/test/other/relationships.rb b/test/other/relationships.rb
index c270be7..df4d3a9 100755
--- a/test/other/relationships.rb
+++ b/test/other/relationships.rb
@@ -6,93 +6,93 @@ require 'puppet'
require 'puppettest'
class TestRelationships < Test::Unit::TestCase
- include PuppetTest
- def setup
- super
- Puppet::Type.type(:exec)
- end
+ include PuppetTest
+ def setup
+ super
+ Puppet::Type.type(:exec)
+ end
- def newfile
- assert_nothing_raised {
+ def newfile
+ assert_nothing_raised {
- return Puppet::Type.type(:file).new(
+ return Puppet::Type.type(:file).new(
- :path => tempfile,
+ :path => tempfile,
- :check => [:mode, :owner, :group]
- )
- }
+ :check => [:mode, :owner, :group]
+ )
+ }
+ end
+
+ def check_relationship(sources, targets, out, refresher)
+ if out
+ deps = sources.builddepends
+ sources = [sources]
+ else
+ deps = targets.builddepends
+ targets = [targets]
end
+ assert_instance_of(Array, deps)
+ assert(! deps.empty?, "Did not receive any relationships")
- def check_relationship(sources, targets, out, refresher)
- if out
- deps = sources.builddepends
- sources = [sources]
- else
- deps = targets.builddepends
- targets = [targets]
- end
- assert_instance_of(Array, deps)
- assert(! deps.empty?, "Did not receive any relationships")
+ deps.each do |edge|
+ assert_instance_of(Puppet::Relationship, edge)
+ end
- deps.each do |edge|
- assert_instance_of(Puppet::Relationship, edge)
- end
+ sources.each do |source|
+ targets.each do |target|
+ edge = deps.find { |e| e.source == source and e.target == target }
+ assert(edge, "Could not find edge for #{source.ref} => #{target.ref}")
- sources.each do |source|
- targets.each do |target|
- edge = deps.find { |e| e.source == source and e.target == target }
- assert(edge, "Could not find edge for #{source.ref} => #{target.ref}")
-
- if refresher
- assert_equal(:ALL_EVENTS, edge.event)
- assert_equal(:refresh, edge.callback)
- else
- assert_nil(edge.event)
- assert_nil(edge.callback, "Got a callback with no events")
- end
- end
+ if refresher
+ assert_equal(:ALL_EVENTS, edge.event)
+ assert_equal(:refresh, edge.callback)
+ else
+ assert_nil(edge.event)
+ assert_nil(edge.callback, "Got a callback with no events")
end
+ end
end
+ end
- def test_autorequire
- # We know that execs autorequire their cwd, so we'll use that
- path = tempfile
+ def test_autorequire
+ # We know that execs autorequire their cwd, so we'll use that
+ path = tempfile
- file = Puppet::Type.type(:file).new(
- :title => "myfile", :path => path,
+ file = Puppet::Type.type(:file).new(
+ :title => "myfile", :path => path,
- :ensure => :directory)
+ :ensure => :directory)
- exec = Puppet::Type.newexec(
- :title => "myexec", :cwd => path,
+ exec = Puppet::Type.newexec(
+ :title => "myexec", :cwd => path,
- :command => "/bin/echo")
+ :command => "/bin/echo")
- catalog = mk_catalog(file, exec)
- reqs = nil
- assert_nothing_raised do
- reqs = exec.autorequire
- end
- assert_instance_of(Puppet::Relationship, reqs[0], "Did not return a relationship edge")
- assert_equal(file, reqs[0].source, "Did not set the autorequire source correctly")
- assert_equal(exec, reqs[0].target, "Did not set the autorequire target correctly")
-
- # Now make sure that these relationships are added to the
- # relationship graph
- catalog.apply do |trans|
- assert(catalog.relationship_graph.edge?(file, exec), "autorequire edge was not created")
- end
+ catalog = mk_catalog(file, exec)
+ reqs = nil
+ assert_nothing_raised do
+ reqs = exec.autorequire
end
+ assert_instance_of(Puppet::Relationship, reqs[0], "Did not return a relationship edge")
+ assert_equal(file, reqs[0].source, "Did not set the autorequire source correctly")
+ assert_equal(exec, reqs[0].target, "Did not set the autorequire target correctly")
+
+ # Now make sure that these relationships are added to the
+ # relationship graph
+ catalog.apply do |trans|
+ assert(catalog.relationship_graph.edge?(file, exec), "autorequire edge was not created")
+ end
+ end
- # Testing #411. It was a problem with builddepends.
- def test_missing_deps
- file = Puppet::Type.type(:file).new :path => tempfile, :require => Puppet::Resource.new("file", "/no/such/file")
+ # Testing #411. It was a problem with builddepends.
+ def test_missing_deps
+ file = Puppet::Type.type(:file).new :path => tempfile, :require => Puppet::Resource.new("file", "/no/such/file")
- assert_raise(Puppet::Error) do
- file.builddepends
- end
+ assert_raise(Puppet::Error) do
+ file.builddepends
end
+ end
end
diff --git a/test/other/report.rb b/test/other/report.rb
index 862e506..b3b41da 100755
--- a/test/other/report.rb
+++ b/test/other/report.rb
@@ -9,130 +9,130 @@ require 'puppettest'
require 'puppettest/reporttesting'
class TestReports < Test::Unit::TestCase
- include PuppetTest
- include PuppetTest::Reporttesting
+ include PuppetTest
+ include PuppetTest::Reporttesting
- def mkreport
- # First do some work
- objects = []
- 6.times do |i|
- file = tempfile
+ def mkreport
+ # First do some work
+ objects = []
+ 6.times do |i|
+ file = tempfile
- # Make every third file
- File.open(file, "w") { |f| f.puts "" } if i % 3 == 0
+ # Make every third file
+ File.open(file, "w") { |f| f.puts "" } if i % 3 == 0
- objects << Puppet::Type.type(:file).new(
+ objects << Puppet::Type.type(:file).new(
- :path => file,
+ :path => file,
- :ensure => "file"
- )
- end
-
- config = mk_catalog(*objects)
- # So the report works out.
- config.retrieval_duration = 0.001
- trans = config.apply
-
- report = Puppet::Transaction::Report.new
- trans.add_metrics_to_report(report)
-
- report
+ :ensure => "file"
+ )
end
- # Make sure we can use reports as log destinations.
- def test_reports_as_log_destinations
- report = fakereport
+ config = mk_catalog(*objects)
+ # So the report works out.
+ config.retrieval_duration = 0.001
+ trans = config.apply
- assert_nothing_raised {
- Puppet::Util::Log.newdestination(report)
- }
+ report = Puppet::Transaction::Report.new
+ trans.add_metrics_to_report(report)
- # Now make a file for testing logging
- file = Puppet::Type.type(:file).new(:path => tempfile, :ensure => "file")
- file.finish
+ report
+ end
- log = nil
- assert_nothing_raised {
- log = file.log "This is a message, yo"
- }
+ # Make sure we can use reports as log destinations.
+ def test_reports_as_log_destinations
+ report = fakereport
- assert(report.logs.include?(log), "Report did not get log message")
+ assert_nothing_raised {
+ Puppet::Util::Log.newdestination(report)
+ }
- assert_nothing_raised {
- Puppet::Util::Log.close(report)
- }
+ # Now make a file for testing logging
+ file = Puppet::Type.type(:file).new(:path => tempfile, :ensure => "file")
+ file.finish
- log = file.log "This is another message, yo"
+ log = nil
+ assert_nothing_raised {
+ log = file.log "This is a message, yo"
+ }
- assert(! report.logs.include?(log), "Report got log message after close")
- end
+ assert(report.logs.include?(log), "Report did not get log message")
- def test_store_report
- # Create a bunch of log messages in an array.
- report = Puppet::Transaction::Report.new
+ assert_nothing_raised {
+ Puppet::Util::Log.close(report)
+ }
- # We have to reuse reporting here because of something going on in the
- # server/report.rb file
- Puppet.settings.use(:main, :master)
+ log = file.log "This is another message, yo"
- 3.times { |i|
- log = Puppet.warning("Report test message #{i}")
+ assert(! report.logs.include?(log), "Report got log message after close")
+ end
- report << log
- }
+ def test_store_report
+ # Create a bunch of log messages in an array.
+ report = Puppet::Transaction::Report.new
- assert_nothing_raised do
- report.extend(Puppet::Reports.report(:store))
- end
+ # We have to reuse reporting here because of something going on in the
+ # server/report.rb file
+ Puppet.settings.use(:main, :master)
- yaml = YAML.dump(report)
+ 3.times { |i|
+ log = Puppet.warning("Report test message #{i}")
- file = report.process
+ report << log
+ }
- assert(FileTest.exists?(file), "report file did not get created")
- assert_equal(yaml, File.read(file), "File did not get written")
+ assert_nothing_raised do
+ report.extend(Puppet::Reports.report(:store))
end
- if Puppet.features.rrd?
- def test_rrdgraph_report
- Puppet.settings.use(:main, :metrics)
- report = mkreport
+ yaml = YAML.dump(report)
+
+ file = report.process
- assert(! report.metrics.empty?, "Did not receive any metrics")
+ assert(FileTest.exists?(file), "report file did not get created")
+ assert_equal(yaml, File.read(file), "File did not get written")
+ end
- assert_nothing_raised do
- report.extend(Puppet::Reports.report(:rrdgraph))
- end
+ if Puppet.features.rrd?
+ def test_rrdgraph_report
+ Puppet.settings.use(:main, :metrics)
+ report = mkreport
- assert_nothing_raised {
- report.process
- }
+ assert(! report.metrics.empty?, "Did not receive any metrics")
- hostdir = nil
- assert_nothing_raised do
- hostdir = report.hostdir
- end
+ assert_nothing_raised do
+ report.extend(Puppet::Reports.report(:rrdgraph))
+ end
- assert(hostdir, "Did not get hostdir back")
+ assert_nothing_raised {
+ report.process
+ }
- assert(FileTest.directory?(hostdir), "Host rrd dir did not get created")
- index = File.join(hostdir, "index.html")
- assert(FileTest.exists?(index), "index file was not created")
+ hostdir = nil
+ assert_nothing_raised do
+ hostdir = report.hostdir
+ end
- # Now make sure it creaets each of the rrd files
- %w{changes resources time}.each do |type|
- file = File.join(hostdir, "#{type}.rrd")
- assert(FileTest.exists?(file), "Did not create rrd file for #{type}")
+ assert(hostdir, "Did not get hostdir back")
- daily = file.sub ".rrd", "-daily.png"
- assert(FileTest.exists?(daily), "Did not make daily graph for #{type}")
- end
+ assert(FileTest.directory?(hostdir), "Host rrd dir did not get created")
+ index = File.join(hostdir, "index.html")
+ assert(FileTest.exists?(index), "index file was not created")
+ # Now make sure it creaets each of the rrd files
+ %w{changes resources time}.each do |type|
+ file = File.join(hostdir, "#{type}.rrd")
+ assert(FileTest.exists?(file), "Did not create rrd file for #{type}")
+
+ daily = file.sub ".rrd", "-daily.png"
+ assert(FileTest.exists?(daily), "Did not make daily graph for #{type}")
end
- else
- $stderr.puts "Install RRD for metric reporting tests"
- end
+
+ end
+ else
+ $stderr.puts "Install RRD for metric reporting tests"
+ end
end
diff --git a/test/other/transactions.rb b/test/other/transactions.rb
index 26fc0b6..6655d86 100755
--- a/test/other/transactions.rb
+++ b/test/other/transactions.rb
@@ -9,426 +9,426 @@ require 'puppettest/support/resources'
require 'puppettest/support/utils'
class TestTransactions < Test::Unit::TestCase
- include PuppetTest::FileTesting
- include PuppetTest::Support::Resources
- include PuppetTest::Support::Utils
- class Fakeprop <Puppet::Property
- initvars
-
- attr_accessor :path, :is, :should, :name
- def should_to_s(value)
- value.to_s
- end
- def insync?(foo)
- true
- end
- def info(*args)
- false
- end
-
- def set(value)
- # eh
- end
-
- def log(msg)
- end
+ include PuppetTest::FileTesting
+ include PuppetTest::Support::Resources
+ include PuppetTest::Support::Utils
+ class Fakeprop <Puppet::Property
+ initvars
+
+ attr_accessor :path, :is, :should, :name
+ def should_to_s(value)
+ value.to_s
+ end
+ def insync?(foo)
+ true
+ end
+ def info(*args)
+ false
end
+ def set(value)
+ # eh
+ end
- def mkgenerator(&block)
- $finished = []
- cleanup { $finished = nil }
-
- # Create a bogus type that generates new instances with shorter
- type = Puppet::Type.newtype(:generator) do
- newparam(:name, :namevar => true)
- def finish
- $finished << self.name
- end
- end
- type.class_eval(&block) if block
- cleanup do
- Puppet::Type.rmtype(:generator)
- end
-
- type
+ def log(msg)
end
+ end
- # Create a new type that generates instances with shorter names.
- def mkreducer(&block)
- type = mkgenerator do
- def eval_generate
- ret = []
- if title.length > 1
- ret << self.class.new(:title => title[0..-2])
- else
- return nil
- end
- ret
- end
- end
- type.class_eval(&block) if block
+ def mkgenerator(&block)
+ $finished = []
+ cleanup { $finished = nil }
- type
+ # Create a bogus type that generates new instances with shorter
+ type = Puppet::Type.newtype(:generator) do
+ newparam(:name, :namevar => true)
+ def finish
+ $finished << self.name
+ end
+ end
+ type.class_eval(&block) if block
+ cleanup do
+ Puppet::Type.rmtype(:generator)
end
- def test_prefetch
- # Create a type just for testing prefetch
- name = :prefetchtesting
- $prefetched = false
- type = Puppet::Type.newtype(name) do
- newparam(:name) {}
+ type
+ end
+
+ # Create a new type that generates instances with shorter names.
+ def mkreducer(&block)
+ type = mkgenerator do
+ def eval_generate
+ ret = []
+ if title.length > 1
+ ret << self.class.new(:title => title[0..-2])
+ else
+ return nil
end
+ ret
+ end
+ end
- cleanup do
- Puppet::Type.rmtype(name)
- end
+ type.class_eval(&block) if block
- # Now create a provider
- type.provide(:prefetch) do
- def self.prefetch(resources)
- $prefetched = resources
- end
- end
+ type
+ end
- # Now create an instance
- inst = type.new :name => "yay"
+ def test_prefetch
+ # Create a type just for testing prefetch
+ name = :prefetchtesting
+ $prefetched = false
+ type = Puppet::Type.newtype(name) do
+ newparam(:name) {}
+ end
- # Create a transaction
- trans = Puppet::Transaction.new(mk_catalog(inst))
+ cleanup do
+ Puppet::Type.rmtype(name)
+ end
- # Make sure prefetch works
- assert_nothing_raised do
- trans.prefetch
- end
+ # Now create a provider
+ type.provide(:prefetch) do
+ def self.prefetch(resources)
+ $prefetched = resources
+ end
+ end
- assert_equal({inst.title => inst}, $prefetched, "type prefetch was not called")
+ # Now create an instance
+ inst = type.new :name => "yay"
- # Now make sure it gets called from within evaluate
- $prefetched = false
- assert_nothing_raised do
- trans.evaluate
- end
+ # Create a transaction
+ trans = Puppet::Transaction.new(mk_catalog(inst))
- assert_equal({inst.title => inst}, $prefetched, "evaluate did not call prefetch")
+ # Make sure prefetch works
+ assert_nothing_raised do
+ trans.prefetch
end
- # We need to generate resources before we prefetch them, else generated
- # resources that require prefetching don't work.
- def test_generate_before_prefetch
- config = mk_catalog
- trans = Puppet::Transaction.new(config)
+ assert_equal({inst.title => inst}, $prefetched, "type prefetch was not called")
- generate = nil
- prefetch = nil
- trans.expects(:generate).with { |*args| generate = Time.now; true }
- trans.expects(:prefetch).with { |*args| ! generate.nil? }
- trans.prepare
- return
-
- resource = Puppet::Type.type(:file).new :ensure => :present, :path => tempfile
- other_resource = mock 'generated'
- def resource.generate
- [other_resource]
- end
+ # Now make sure it gets called from within evaluate
+ $prefetched = false
+ assert_nothing_raised do
+ trans.evaluate
+ end
+ assert_equal({inst.title => inst}, $prefetched, "evaluate did not call prefetch")
+ end
+
+ # We need to generate resources before we prefetch them, else generated
+ # resources that require prefetching don't work.
+ def test_generate_before_prefetch
+ config = mk_catalog
+ trans = Puppet::Transaction.new(config)
+
+ generate = nil
+ prefetch = nil
+ trans.expects(:generate).with { |*args| generate = Time.now; true }
+ trans.expects(:prefetch).with { |*args| ! generate.nil? }
+ trans.prepare
+ return
+
+ resource = Puppet::Type.type(:file).new :ensure => :present, :path => tempfile
+ other_resource = mock 'generated'
+ def resource.generate
+ [other_resource]
+ end
- config = mk_catalog(yay, rah)
- trans = Puppet::Transaction.new(config)
- assert_nothing_raised do
- trans.generate
- end
+ config = mk_catalog(yay, rah)
+ trans = Puppet::Transaction.new(config)
- %w{ya ra y r}.each do |name|
- assert(trans.catalog.vertex?(Puppet::Type.type(:generator)[name]), "Generated #{name} was not a vertex")
- assert($finished.include?(name), "#{name} was not finished")
- end
+ assert_nothing_raised do
+ trans.generate
end
- def test_ignore_tags?
- config = Puppet::Resource::Catalog.new
- config.host_config = true
- transaction = Puppet::Transaction.new(config)
- assert(! transaction.ignore_tags?, "Ignoring tags when applying a host catalog")
-
- config.host_config = false
- transaction = Puppet::Transaction.new(config)
- assert(transaction.ignore_tags?, "Not ignoring tags when applying a non-host catalog")
+ %w{ya ra y r}.each do |name|
+ assert(trans.catalog.vertex?(Puppet::Type.type(:generator)[name]), "Generated #{name} was not a vertex")
+ assert($finished.include?(name), "#{name} was not finished")
end
-
- def test_missing_tags?
- resource = Puppet::Type.type(:notify).new :title => "foo"
- resource.stubs(:tagged?).returns true
- config = Puppet::Resource::Catalog.new
-
- # Mark it as a host config so we don't care which test is first
- config.host_config = true
- transaction = Puppet::Transaction.new(config)
- assert(! transaction.missing_tags?(resource), "Considered a resource to be missing tags when none are set")
-
- # host catalogs pay attention to tags, no one else does.
- Puppet[:tags] = "three,four"
- config.host_config = false
- transaction = Puppet::Transaction.new(config)
- assert(! transaction.missing_tags?(resource), "Considered a resource to be missing tags when not running a host catalog")
-
- #
- config.host_config = true
- transaction = Puppet::Transaction.new(config)
- assert(! transaction.missing_tags?(resource), "Considered a resource to be missing tags when running a host catalog and all tags are present")
-
- transaction = Puppet::Transaction.new(config)
- resource.stubs :tagged? => false
- assert(transaction.missing_tags?(resource), "Considered a resource not to be missing tags when running a host catalog and tags are missing")
+ end
+
+ def test_ignore_tags?
+ config = Puppet::Resource::Catalog.new
+ config.host_config = true
+ transaction = Puppet::Transaction.new(config)
+ assert(! transaction.ignore_tags?, "Ignoring tags when applying a host catalog")
+
+ config.host_config = false
+ transaction = Puppet::Transaction.new(config)
+ assert(transaction.ignore_tags?, "Not ignoring tags when applying a non-host catalog")
+ end
+
+ def test_missing_tags?
+ resource = Puppet::Type.type(:notify).new :title => "foo"
+ resource.stubs(:tagged?).returns true
+ config = Puppet::Resource::Catalog.new
+
+ # Mark it as a host config so we don't care which test is first
+ config.host_config = true
+ transaction = Puppet::Transaction.new(config)
+ assert(! transaction.missing_tags?(resource), "Considered a resource to be missing tags when none are set")
+
+ # host catalogs pay attention to tags, no one else does.
+ Puppet[:tags] = "three,four"
+ config.host_config = false
+ transaction = Puppet::Transaction.new(config)
+ assert(! transaction.missing_tags?(resource), "Considered a resource to be missing tags when not running a host catalog")
+
+ #
+ config.host_config = true
+ transaction = Puppet::Transaction.new(config)
+ assert(! transaction.missing_tags?(resource), "Considered a resource to be missing tags when running a host catalog and all tags are present")
+
+ transaction = Puppet::Transaction.new(config)
+ resource.stubs :tagged? => false
+ assert(transaction.missing_tags?(resource), "Considered a resource not to be missing tags when running a host catalog and tags are missing")
+ end
+
+ # Make sure changes in contained files still generate callback events.
+ def test_generated_callbacks
+ dir = tempfile
+ maker = tempfile
+ Dir.mkdir(dir)
+ file = File.join(dir, "file")
+ File.open(file, "w") { |f| f.puts "" }
+ File.chmod(0644, file)
+ File.chmod(0755, dir) # So only the child file causes a change
+
+ dirobj = Puppet::Type.type(:file).new :mode => "755", :recurse => true, :path => dir
+ exec = Puppet::Type.type(:exec).new :title => "make",
+ :command => "touch #{maker}", :path => ENV['PATH'], :refreshonly => true,
+ :subscribe => dirobj
+
+ assert_apply(dirobj, exec)
+ assert(FileTest.exists?(maker), "Did not make callback file")
+ end
+
+ # Testing #401 -- transactions are calling refresh on classes that don't support it.
+ def test_callback_availability
+ $called = []
+ klass = Puppet::Type.newtype(:norefresh) do
+ newparam(:name, :namevar => true) {}
+ def method_missing(method, *args)
+ $called << method
+ end
end
-
- # Make sure changes in contained files still generate callback events.
- def test_generated_callbacks
- dir = tempfile
- maker = tempfile
- Dir.mkdir(dir)
- file = File.join(dir, "file")
- File.open(file, "w") { |f| f.puts "" }
- File.chmod(0644, file)
- File.chmod(0755, dir) # So only the child file causes a change
-
- dirobj = Puppet::Type.type(:file).new :mode => "755", :recurse => true, :path => dir
- exec = Puppet::Type.type(:exec).new :title => "make",
- :command => "touch #{maker}", :path => ENV['PATH'], :refreshonly => true,
- :subscribe => dirobj
-
- assert_apply(dirobj, exec)
- assert(FileTest.exists?(maker), "Did not make callback file")
+ cleanup do
+ $called = nil
+ Puppet::Type.rmtype(:norefresh)
end
- # Testing #401 -- transactions are calling refresh on classes that don't support it.
- def test_callback_availability
- $called = []
- klass = Puppet::Type.newtype(:norefresh) do
- newparam(:name, :namevar => true) {}
- def method_missing(method, *args)
- $called << method
- end
- end
- cleanup do
- $called = nil
- Puppet::Type.rmtype(:norefresh)
- end
+ file = Puppet::Type.type(:file).new :path => tempfile, :content => "yay"
+ one = klass.new :name => "one", :subscribe => file
- file = Puppet::Type.type(:file).new :path => tempfile, :content => "yay"
- one = klass.new :name => "one", :subscribe => file
+ assert_apply(file, one)
- assert_apply(file, one)
+ assert(! $called.include?(:refresh), "Called refresh when it wasn't set as a method")
+ end
- assert(! $called.include?(:refresh), "Called refresh when it wasn't set as a method")
- end
+ # Testing #437 - cyclic graphs should throw failures.
+ def test_fail_on_cycle
+ one = Puppet::Type.type(:exec).new(:name => "/bin/echo one")
+ two = Puppet::Type.type(:exec).new(:name => "/bin/echo two")
+ one[:require] = two
+ two[:require] = one
- # Testing #437 - cyclic graphs should throw failures.
- def test_fail_on_cycle
- one = Puppet::Type.type(:exec).new(:name => "/bin/echo one")
- two = Puppet::Type.type(:exec).new(:name => "/bin/echo two")
- one[:require] = two
- two[:require] = one
-
- config = mk_catalog(one, two)
- trans = Puppet::Transaction.new(config)
- assert_raise(Puppet::Error) do
- trans.prepare
- end
+ config = mk_catalog(one, two)
+ trans = Puppet::Transaction.new(config)
+ assert_raise(Puppet::Error) do
+ trans.prepare
end
-
- def test_errors_during_generation
- type = Puppet::Type.newtype(:failer) do
- newparam(:name) {}
- def eval_generate
- raise ArgumentError, "Invalid value"
- end
- def generate
- raise ArgumentError, "Invalid value"
- end
- end
- cleanup { Puppet::Type.rmtype(:failer) }
-
- obj = type.new(:name => "testing")
-
- assert_apply(obj)
+ end
+
+ def test_errors_during_generation
+ type = Puppet::Type.newtype(:failer) do
+ newparam(:name) {}
+ def eval_generate
+ raise ArgumentError, "Invalid value"
+ end
+ def generate
+ raise ArgumentError, "Invalid value"
+ end
end
+ cleanup { Puppet::Type.rmtype(:failer) }
- def test_self_refresh_causes_triggering
- type = Puppet::Type.newtype(:refresher, :self_refresh => true) do
- attr_accessor :refreshed, :testing
- newparam(:name) {}
- newproperty(:testing) do
- def retrieve
- :eh
- end
-
- def sync
- # noop
- :ran_testing
- end
- end
- def refresh
- @refreshed = true
- end
- end
- cleanup { Puppet::Type.rmtype(:refresher)}
+ obj = type.new(:name => "testing")
- obj = type.new(:name => "yay", :testing => "cool")
+ assert_apply(obj)
+ end
- assert(! obj.insync?(obj.retrieve), "fake object is already in sync")
+ def test_self_refresh_causes_triggering
+ type = Puppet::Type.newtype(:refresher, :self_refresh => true) do
+ attr_accessor :refreshed, :testing
+ newparam(:name) {}
+ newproperty(:testing) do
+ def retrieve
+ :eh
+ end
- # Now make sure it gets refreshed when the change happens
- assert_apply(obj)
- assert(obj.refreshed, "object was not refreshed during transaction")
+ def sync
+ # noop
+ :ran_testing
+ end
+ end
+ def refresh
+ @refreshed = true
+ end
end
+ cleanup { Puppet::Type.rmtype(:refresher)}
+
+ obj = type.new(:name => "yay", :testing => "cool")
+
+ assert(! obj.insync?(obj.retrieve), "fake object is already in sync")
+
+ # Now make sure it gets refreshed when the change happens
+ assert_apply(obj)
+ assert(obj.refreshed, "object was not refreshed during transaction")
+ end
+
+ # Testing #433
+ def test_explicit_dependencies_beat_automatic
+ # Create a couple of different resource sets that have automatic relationships and make sure the manual relationships win
+ rels = {}
+ # Now add the explicit relationship
+ # Now files
+ d = tempfile
+ f = File.join(d, "file")
+ file = Puppet::Type.type(:file).new(:path => f, :content => "yay")
+ dir = Puppet::Type.type(:file).new(:path => d, :ensure => :directory, :require => file)
+
+ rels[dir] = file
+ rels.each do |after, before|
+ config = mk_catalog(before, after)
+ trans = Puppet::Transaction.new(config)
+ str = "from #{before} to #{after}"
+
+ assert_nothing_raised("Failed to create graph #{str}") do
+ trans.prepare
+ end
- # Testing #433
- def test_explicit_dependencies_beat_automatic
- # Create a couple of different resource sets that have automatic relationships and make sure the manual relationships win
- rels = {}
- # Now add the explicit relationship
- # Now files
- d = tempfile
- f = File.join(d, "file")
- file = Puppet::Type.type(:file).new(:path => f, :content => "yay")
- dir = Puppet::Type.type(:file).new(:path => d, :ensure => :directory, :require => file)
-
- rels[dir] = file
- rels.each do |after, before|
- config = mk_catalog(before, after)
- trans = Puppet::Transaction.new(config)
- str = "from #{before} to #{after}"
-
- assert_nothing_raised("Failed to create graph #{str}") do
- trans.prepare
- end
-
- graph = trans.relationship_graph
- assert(graph.edge?(before, after), "did not create manual relationship #{str}")
- assert(! graph.edge?(after, before), "created automatic relationship #{str}")
- end
+ graph = trans.relationship_graph
+ assert(graph.edge?(before, after), "did not create manual relationship #{str}")
+ assert(! graph.edge?(after, before), "created automatic relationship #{str}")
end
+ end
- # #542 - make sure resources in noop mode still notify their resources,
- # so that users know if a service will get restarted.
- def test_noop_with_notify
- path = tempfile
- epath = tempfile
- spath = tempfile
+ # #542 - make sure resources in noop mode still notify their resources,
+ # so that users know if a service will get restarted.
+ def test_noop_with_notify
+ path = tempfile
+ epath = tempfile
+ spath = tempfile
- file = Puppet::Type.type(:file).new(
- :path => path, :ensure => :file,
+ file = Puppet::Type.type(:file).new(
+ :path => path, :ensure => :file,
- :title => "file")
+ :title => "file")
- exec = Puppet::Type.type(:exec).new(
- :command => "touch #{epath}",
- :path => ENV["PATH"], :subscribe => file, :refreshonly => true,
+ exec = Puppet::Type.type(:exec).new(
+ :command => "touch #{epath}",
+ :path => ENV["PATH"], :subscribe => file, :refreshonly => true,
- :title => 'exec1')
+ :title => 'exec1')
- exec2 = Puppet::Type.type(:exec).new(
- :command => "touch #{spath}",
- :path => ENV["PATH"], :subscribe => exec, :refreshonly => true,
+ exec2 = Puppet::Type.type(:exec).new(
+ :command => "touch #{spath}",
+ :path => ENV["PATH"], :subscribe => exec, :refreshonly => true,
- :title => 'exec2')
+ :title => 'exec2')
- Puppet[:noop] = true
+ Puppet[:noop] = true
- assert(file.noop, "file not in noop")
- assert(exec.noop, "exec not in noop")
+ assert(file.noop, "file not in noop")
+ assert(exec.noop, "exec not in noop")
- @logs.clear
- assert_apply(file, exec, exec2)
+ @logs.clear
+ assert_apply(file, exec, exec2)
- assert(! FileTest.exists?(path), "Created file in noop")
- assert(! FileTest.exists?(epath), "Executed exec in noop")
- assert(! FileTest.exists?(spath), "Executed second exec in noop")
+ assert(! FileTest.exists?(path), "Created file in noop")
+ assert(! FileTest.exists?(epath), "Executed exec in noop")
+ assert(! FileTest.exists?(spath), "Executed second exec in noop")
- assert(@logs.detect { |l|
- l.message =~ /should be/ and l.source == file.property(:ensure).path},
- "did not log file change")
+ assert(@logs.detect { |l|
+ l.message =~ /should be/ and l.source == file.property(:ensure).path},
+ "did not log file change")
- assert(
- @logs.detect { |l|
- l.message =~ /Would have/ and l.source == exec.path },
+ assert(
+ @logs.detect { |l|
+ l.message =~ /Would have/ and l.source == exec.path },
- "did not log first exec trigger")
+ "did not log first exec trigger")
- assert(
- @logs.detect { |l|
- l.message =~ /Would have/ and l.source == exec2.path },
+ assert(
+ @logs.detect { |l|
+ l.message =~ /Would have/ and l.source == exec2.path },
+
+ "did not log second exec trigger")
+ end
+
+ def test_only_stop_purging_with_relations
+ files = []
+ paths = []
+ 3.times do |i|
+ path = tempfile
+ paths << path
+
+ file = Puppet::Type.type(:file).new(
+ :path => path, :ensure => :absent,
- "did not log second exec trigger")
+ :backup => false, :title => "file#{i}")
+ File.open(path, "w") { |f| f.puts "" }
+ files << file
end
- def test_only_stop_purging_with_relations
- files = []
- paths = []
- 3.times do |i|
- path = tempfile
- paths << path
+ files[0][:ensure] = :file
+ files[0][:require] = files[1..2]
- file = Puppet::Type.type(:file).new(
- :path => path, :ensure => :absent,
-
- :backup => false, :title => "file#{i}")
- File.open(path, "w") { |f| f.puts "" }
- files << file
- end
+ # Mark the second as purging
+ files[1].purging
- files[0][:ensure] = :file
- files[0][:require] = files[1..2]
+ assert_apply(*files)
- # Mark the second as purging
- files[1].purging
+ assert(FileTest.exists?(paths[1]), "Deleted required purging file")
+ assert(! FileTest.exists?(paths[2]), "Did not delete non-purged file")
+ end
- assert_apply(*files)
+ def test_flush
+ $state = :absent
+ $flushed = 0
+ type = Puppet::Type.newtype(:flushtest) do
+ newparam(:name)
+ newproperty(:ensure) do
+ newvalues :absent, :present, :other
+ def retrieve
+ $state
+ end
+ def set(value)
+ $state = value
+ :thing_changed
+ end
+ end
- assert(FileTest.exists?(paths[1]), "Deleted required purging file")
- assert(! FileTest.exists?(paths[2]), "Did not delete non-purged file")
+ def flush
+ $flushed += 1
+ end
end
- def test_flush
- $state = :absent
- $flushed = 0
- type = Puppet::Type.newtype(:flushtest) do
- newparam(:name)
- newproperty(:ensure) do
- newvalues :absent, :present, :other
- def retrieve
- $state
- end
- def set(value)
- $state = value
- :thing_changed
- end
- end
-
- def flush
- $flushed += 1
- end
- end
-
- cleanup { Puppet::Type.rmtype(:flushtest) }
+ cleanup { Puppet::Type.rmtype(:flushtest) }
- obj = type.new(:name => "test", :ensure => :present)
+ obj = type.new(:name => "test", :ensure => :present)
- # first make sure it runs through and flushes
- assert_apply(obj)
+ # first make sure it runs through and flushes
+ assert_apply(obj)
- assert_equal(:present, $state, "Object did not make a change")
- assert_equal(1, $flushed, "object was not flushed")
+ assert_equal(:present, $state, "Object did not make a change")
+ assert_equal(1, $flushed, "object was not flushed")
- # Now run a noop and make sure we don't flush
- obj[:ensure] = "other"
- obj[:noop] = true
+ # Now run a noop and make sure we don't flush
+ obj[:ensure] = "other"
+ obj[:noop] = true
- assert_apply(obj)
- assert_equal(:present, $state, "Object made a change in noop")
- assert_equal(1, $flushed, "object was flushed in noop")
- end
+ assert_apply(obj)
+ assert_equal(:present, $state, "Object made a change in noop")
+ assert_equal(1, $flushed, "object was flushed in noop")
+ end
end
diff --git a/test/puppet/defaults.rb b/test/puppet/defaults.rb
index 2338e03..d290cef 100755
--- a/test/puppet/defaults.rb
+++ b/test/puppet/defaults.rb
@@ -7,63 +7,63 @@ require 'puppettest'
class TestPuppetDefaults < Test::Unit::TestCase
- include PuppetTest
- @@dirs = %w{rrddir confdir vardir logdir statedir}
- @@files = %w{statefile manifest masterlog}
- @@normals = %w{puppetport masterport server}
- @@booleans = %w{noop}
+ include PuppetTest
+ @@dirs = %w{rrddir confdir vardir logdir statedir}
+ @@files = %w{statefile manifest masterlog}
+ @@normals = %w{puppetport masterport server}
+ @@booleans = %w{noop}
- def testVersion
- assert( Puppet.version =~ /^[0-9]+(\.[0-9]+)*/, "got invalid version number #{Puppet.version}")
- end
+ def testVersion
+ assert( Puppet.version =~ /^[0-9]+(\.[0-9]+)*/, "got invalid version number #{Puppet.version}")
+ end
- def testStringOrParam
- [@@dirs,@@files,@@booleans].flatten.each { |param|
- assert_nothing_raised { Puppet[param] }
- assert_nothing_raised { Puppet[param.intern] }
- }
- end
+ def testStringOrParam
+ [@@dirs,@@files,@@booleans].flatten.each { |param|
+ assert_nothing_raised { Puppet[param] }
+ assert_nothing_raised { Puppet[param.intern] }
+ }
+ end
- def test_valuesForEach
- [@@dirs,@@files,@@booleans].flatten.each { |param|
- param = param.intern
- assert_nothing_raised { Puppet[param] }
- }
- end
+ def test_valuesForEach
+ [@@dirs,@@files,@@booleans].flatten.each { |param|
+ param = param.intern
+ assert_nothing_raised { Puppet[param] }
+ }
+ end
- def testValuesForEach
- [@@dirs,@@files,@@booleans].flatten.each { |param|
- assert_nothing_raised { Puppet[param] }
- }
- end
+ def testValuesForEach
+ [@@dirs,@@files,@@booleans].flatten.each { |param|
+ assert_nothing_raised { Puppet[param] }
+ }
+ end
- # we don't want user defaults in /, or root defaults in ~
- def testDefaultsInCorrectRoots
- notval = nil
- if Puppet.features.root?
- notval = Regexp.new(File.expand_path("~"))
- else
- notval = /^\/var|^\/etc/
- end
- [@@dirs,@@files].flatten.each { |param|
- value = Puppet[param]
-
- assert_nothing_raised { raise "#{param} is incorrectly set to #{value}" } unless value !~ notval
- }
+ # we don't want user defaults in /, or root defaults in ~
+ def testDefaultsInCorrectRoots
+ notval = nil
+ if Puppet.features.root?
+ notval = Regexp.new(File.expand_path("~"))
+ else
+ notval = /^\/var|^\/etc/
end
+ [@@dirs,@@files].flatten.each { |param|
+ value = Puppet[param]
- def test_settingdefaults
- testvals = {
- :fakeparam => "$confdir/yaytest",
- :anotherparam => "$vardir/goodtest",
- :string => "a yay string",
- :boolean => true
- }
+ assert_nothing_raised { raise "#{param} is incorrectly set to #{value}" } unless value !~ notval
+ }
+ end
- testvals.each { |param, default|
- assert_nothing_raised {
- Puppet.setdefaults("testing", param => [default, "a value"])
- }
- }
- end
+ def test_settingdefaults
+ testvals = {
+ :fakeparam => "$confdir/yaytest",
+ :anotherparam => "$vardir/goodtest",
+ :string => "a yay string",
+ :boolean => true
+ }
+
+ testvals.each { |param, default|
+ assert_nothing_raised {
+ Puppet.setdefaults("testing", param => [default, "a value"])
+ }
+ }
+ end
end
diff --git a/test/puppet/errortest.rb b/test/puppet/errortest.rb
index d998438..bb81b0d 100755
--- a/test/puppet/errortest.rb
+++ b/test/puppet/errortest.rb
@@ -6,14 +6,14 @@ require 'puppet'
require 'puppettest'
class TestError < Test::Unit::TestCase
- include PuppetTest
+ include PuppetTest
- def test_errorisstring
- error = nil
- assert_nothing_raised {
- error = Puppet::ParseError.new("This is an error")
- }
- assert_instance_of(String, error.to_s)
- end
+ def test_errorisstring
+ error = nil
+ assert_nothing_raised {
+ error = Puppet::ParseError.new("This is an error")
+ }
+ assert_instance_of(String, error.to_s)
+ end
end
diff --git a/test/puppet/tc_suidmanager.rb b/test/puppet/tc_suidmanager.rb
index ddf6a0e..449f2ae 100755
--- a/test/puppet/tc_suidmanager.rb
+++ b/test/puppet/tc_suidmanager.rb
@@ -8,122 +8,122 @@ require 'test/unit'
require 'mocha'
class TestSUIDManager < Test::Unit::TestCase
- include PuppetTest
-
- def setup
- the_id = 42
- Puppet::Util::SUIDManager.stubs(:convert_xid).returns(the_id)
- Puppet::Util::SUIDManager.stubs(:initgroups)
- @user = stub('user', :uid => the_id, :gid => the_id, :name => 'name')
- super
+ include PuppetTest
+
+ def setup
+ the_id = 42
+ Puppet::Util::SUIDManager.stubs(:convert_xid).returns(the_id)
+ Puppet::Util::SUIDManager.stubs(:initgroups)
+ @user = stub('user', :uid => the_id, :gid => the_id, :name => 'name')
+ super
+ end
+
+ def test_metaprogramming_function_additions
+ # NOTE: the way that we are dynamically generating the methods in
+ # SUIDManager for the UID/GID calls was causing problems due to the
+ # modification of a closure. Should the bug rear itself again, this
+ # test will fail.
+ Process.expects(:uid).times(2)
+
+ assert_nothing_raised do
+ Puppet::Util::SUIDManager.uid
+ Puppet::Util::SUIDManager.uid
end
+ end
- def test_metaprogramming_function_additions
- # NOTE: the way that we are dynamically generating the methods in
- # SUIDManager for the UID/GID calls was causing problems due to the
- # modification of a closure. Should the bug rear itself again, this
- # test will fail.
- Process.expects(:uid).times(2)
-
- assert_nothing_raised do
- Puppet::Util::SUIDManager.uid
- Puppet::Util::SUIDManager.uid
- end
- end
-
- def test_id_set
- Process.expects(:euid=).with(@user.uid)
- Process.expects(:egid=).with(@user.gid)
-
- assert_nothing_raised do
- Puppet::Util::SUIDManager.egid = @user.gid
- Puppet::Util::SUIDManager.euid = @user.uid
- end
- end
-
- def test_utiluid
- assert_not_equal(nil, Puppet::Util.uid(nonrootuser.name))
- end
+ def test_id_set
+ Process.expects(:euid=).with(@user.uid)
+ Process.expects(:egid=).with(@user.gid)
- def test_asuser_as_root
- Process.stubs(:uid).returns(0)
- expects_id_set_and_revert @user.uid, @user.gid
- Puppet::Util::SUIDManager.asuser @user.uid, @user.gid do end
- rescue Errno::EPERM
+ assert_nothing_raised do
+ Puppet::Util::SUIDManager.egid = @user.gid
+ Puppet::Util::SUIDManager.euid = @user.uid
end
-
- def test_asuser_as_nonroot
- Process.stubs(:uid).returns(1)
- expects_no_id_set
- Puppet::Util::SUIDManager.asuser @user.uid, @user.gid do end
- end
-
-
- def test_system_as_root
- Process.stubs(:uid).returns(0)
- set_exit_status!
- expects_id_set_and_revert @user.uid, @user.gid
- Kernel.expects(:system).with('blah')
- Puppet::Util::SUIDManager.system('blah', @user.uid, @user.gid)
- end
-
- def test_system_as_nonroot
- Process.stubs(:uid).returns(1)
- set_exit_status!
- expects_no_id_set
- Kernel.expects(:system).with('blah')
- Puppet::Util::SUIDManager.system('blah', @user.uid, @user.gid)
+ end
+
+ def test_utiluid
+ assert_not_equal(nil, Puppet::Util.uid(nonrootuser.name))
+ end
+
+ def test_asuser_as_root
+ Process.stubs(:uid).returns(0)
+ expects_id_set_and_revert @user.uid, @user.gid
+ Puppet::Util::SUIDManager.asuser @user.uid, @user.gid do end
+ rescue Errno::EPERM
+ end
+
+ def test_asuser_as_nonroot
+ Process.stubs(:uid).returns(1)
+ expects_no_id_set
+ Puppet::Util::SUIDManager.asuser @user.uid, @user.gid do end
+ end
+
+
+ def test_system_as_root
+ Process.stubs(:uid).returns(0)
+ set_exit_status!
+ expects_id_set_and_revert @user.uid, @user.gid
+ Kernel.expects(:system).with('blah')
+ Puppet::Util::SUIDManager.system('blah', @user.uid, @user.gid)
+ end
+
+ def test_system_as_nonroot
+ Process.stubs(:uid).returns(1)
+ set_exit_status!
+ expects_no_id_set
+ Kernel.expects(:system).with('blah')
+ Puppet::Util::SUIDManager.system('blah', @user.uid, @user.gid)
+ end
+
+ def test_run_and_capture
+ if (RUBY_VERSION <=> "1.8.4") < 0
+ warn "Cannot run this test on ruby < 1.8.4"
+ else
+ set_exit_status!
+
+
+ Puppet::Util.expects(:execute).with(
+ 'yay',
+ { :failonfail => false,
+ :uid => @user.uid,
+
+ :gid => @user.gid }
+ ).returns('output')
+
+
+ output = Puppet::Util::SUIDManager.run_and_capture 'yay',
+ @user.uid,
+ @user.gid
+
+ assert_equal 'output', output.first
+ assert_kind_of Process::Status, output.last
end
+ end
- def test_run_and_capture
- if (RUBY_VERSION <=> "1.8.4") < 0
- warn "Cannot run this test on ruby < 1.8.4"
- else
- set_exit_status!
+ private
+ def expects_id_set_and_revert(uid, gid)
+ Process.stubs(:groups=)
+ Process.expects(:euid).returns(99997)
+ Process.expects(:egid).returns(99996)
- Puppet::Util.expects(:execute).with(
- 'yay',
- { :failonfail => false,
- :uid => @user.uid,
+ Process.expects(:euid=).with(uid)
+ Process.expects(:egid=).with(gid)
- :gid => @user.gid }
- ).returns('output')
+ Process.expects(:euid=).with(99997)
+ Process.expects(:egid=).with(99996)
+ end
+ def expects_no_id_set
+ Process.expects(:egid).never
+ Process.expects(:euid).never
+ Process.expects(:egid=).never
+ Process.expects(:euid=).never
+ end
- output = Puppet::Util::SUIDManager.run_and_capture 'yay',
- @user.uid,
- @user.gid
-
- assert_equal 'output', output.first
- assert_kind_of Process::Status, output.last
- end
- end
-
- private
-
- def expects_id_set_and_revert(uid, gid)
- Process.stubs(:groups=)
- Process.expects(:euid).returns(99997)
- Process.expects(:egid).returns(99996)
-
- Process.expects(:euid=).with(uid)
- Process.expects(:egid=).with(gid)
-
- Process.expects(:euid=).with(99997)
- Process.expects(:egid=).with(99996)
- end
-
- def expects_no_id_set
- Process.expects(:egid).never
- Process.expects(:euid).never
- Process.expects(:egid=).never
- Process.expects(:euid=).never
- end
-
- def set_exit_status!
- # We want to make sure $CHILD_STATUS is set, this is the only way I know how.
- Kernel.system '' if $CHILD_STATUS.nil?
- end
+ def set_exit_status!
+ # We want to make sure $CHILD_STATUS is set, this is the only way I know how.
+ Kernel.system '' if $CHILD_STATUS.nil?
+ end
end
diff --git a/test/rails/rails.rb b/test/rails/rails.rb
index 7f4b366..6a5bd7b 100755
--- a/test/rails/rails.rb
+++ b/test/rails/rails.rb
@@ -12,14 +12,14 @@ require 'puppettest/resourcetesting'
require 'puppettest/railstesting'
class TestRails < Test::Unit::TestCase
- include PuppetTest::ParserTesting
- include PuppetTest::ResourceTesting
- include PuppetTest::RailsTesting
+ include PuppetTest::ParserTesting
+ include PuppetTest::ResourceTesting
+ include PuppetTest::RailsTesting
- def test_includerails
- assert_nothing_raised {
- require 'puppet/rails'
- }
- end
+ def test_includerails
+ assert_nothing_raised {
+ require 'puppet/rails'
+ }
+ end
end
diff --git a/test/rails/railsparameter.rb b/test/rails/railsparameter.rb
index ca7d207..9f6fc1c 100755
--- a/test/rails/railsparameter.rb
+++ b/test/rails/railsparameter.rb
@@ -10,71 +10,71 @@ require 'puppettest/railstesting'
# Don't do any tests w/out this class
if defined? ::ActiveRecord::Base
class TestRailsParameter < Test::Unit::TestCase
- include PuppetTest::RailsTesting
+ include PuppetTest::RailsTesting
- def params
- {"myname" => "myval", "multiple" => %w{one two three}}
- end
+ def params
+ {"myname" => "myval", "multiple" => %w{one two three}}
+ end
- # Create a resource param from a rails parameter
- def test_to_resourceparam
- railsinit
+ # Create a resource param from a rails parameter
+ def test_to_resourceparam
+ railsinit
- # Now create a source
- parser = mkparser
- source = parser.newclass "myclass"
+ # Now create a source
+ parser = mkparser
+ source = parser.newclass "myclass"
- host = Puppet::Rails::Host.new(:name => "myhost")
+ host = Puppet::Rails::Host.new(:name => "myhost")
- host.save
+ host.save
- resource = host.resources.create(
+ resource = host.resources.create(
- :title => "/tmp/to_resource",
- :restype => "file",
+ :title => "/tmp/to_resource",
+ :restype => "file",
- :exported => true)
+ :exported => true)
- # Use array and non-array values, to make sure we get things back in
- # the same form.
- params.each do |name, value|
- param = Puppet::Rails::ParamName.find_or_create_by_name(name)
- if value.is_a? Array
- values = value
- else
- values = [value]
- end
- valueobjects = values.collect do |v|
+ # Use array and non-array values, to make sure we get things back in
+ # the same form.
+ params.each do |name, value|
+ param = Puppet::Rails::ParamName.find_or_create_by_name(name)
+ if value.is_a? Array
+ values = value
+ else
+ values = [value]
+ end
+ valueobjects = values.collect do |v|
- resource.param_values.create(
- :value => v,
+ resource.param_values.create(
+ :value => v,
- :param_name => param)
- end
+ :param_name => param)
+ end
- assert(param, "Did not create rails parameter")
+ assert(param, "Did not create rails parameter")
- # The id doesn't get assigned until we save
- end
+ # The id doesn't get assigned until we save
+ end
- resource.save
+ resource.save
- # And try to convert our parameter
- params.each do |name, value|
- param = Puppet::Rails::ParamName.find_by_name(name)
- pp = nil
- assert_nothing_raised do
- pp = param.to_resourceparam(resource, source)
- end
+ # And try to convert our parameter
+ params.each do |name, value|
+ param = Puppet::Rails::ParamName.find_by_name(name)
+ pp = nil
+ assert_nothing_raised do
+ pp = param.to_resourceparam(resource, source)
+ end
- assert_instance_of(Puppet::Parser::Resource::Param, pp)
- assert_equal(name.to_sym, pp.name, "parameter name was not equal")
- assert_equal(value, pp.value, "value was not equal for #{value.inspect}")
- end
+ assert_instance_of(Puppet::Parser::Resource::Param, pp)
+ assert_equal(name.to_sym, pp.name, "parameter name was not equal")
+ assert_equal(value, pp.value, "value was not equal for #{value.inspect}")
end
+ end
end
else
- $stderr.puts "Install Rails for Rails and Caching tests"
+ $stderr.puts "Install Rails for Rails and Caching tests"
end
diff --git a/test/ral/manager/attributes.rb b/test/ral/manager/attributes.rb
index 24edf37..74a4d07 100755
--- a/test/ral/manager/attributes.rb
+++ b/test/ral/manager/attributes.rb
@@ -9,289 +9,289 @@ require 'puppettest'
require 'mocha'
class TestTypeAttributes < Test::Unit::TestCase
- include PuppetTest
+ include PuppetTest
- def mktype
- type = Puppet::Type.newtype(:faketype) {}
- cleanup { Puppet::Type.rmtype(:faketype) }
- type
- end
+ def mktype
+ type = Puppet::Type.newtype(:faketype) {}
+ cleanup { Puppet::Type.rmtype(:faketype) }
+ type
+ end
- def test_bracket_methods
- type = mktype
+ def test_bracket_methods
+ type = mktype
- # make a namevar
- type.newparam(:name) {}
+ # make a namevar
+ type.newparam(:name) {}
- # make a property
- type.newproperty(:property) {}
+ # make a property
+ type.newproperty(:property) {}
- # and a param
- type.newparam(:param)
+ # and a param
+ type.newparam(:param)
- inst = type.new(:name => "yay")
+ inst = type.new(:name => "yay")
- # Make sure we can set each of them, including a metaparam
- [:param, :property, :noop].each do |param|
- assert_nothing_raised("Failed to set symbol") do
- inst[param] = true
- end
+ # Make sure we can set each of them, including a metaparam
+ [:param, :property, :noop].each do |param|
+ assert_nothing_raised("Failed to set symbol") do
+ inst[param] = true
+ end
- assert_nothing_raised("Failed to set string") do
- inst[param.to_s] = true
- end
+ assert_nothing_raised("Failed to set string") do
+ inst[param.to_s] = true
+ end
- if param == :property
- assert(inst.property(param), "did not get obj for #{param}")
+ if param == :property
+ assert(inst.property(param), "did not get obj for #{param}")
- assert_equal(
- true, inst.should(param),
+ assert_equal(
+ true, inst.should(param),
- "should value did not get set")
- else
- assert_equal(true, inst[param], "did not get correct value for #{param} from symbol")
- assert_equal(true, inst[param.to_s], "did not get correct value for #{param} from string")
- end
- end
+ "should value did not get set")
+ else
+ assert_equal(true, inst[param], "did not get correct value for #{param} from symbol")
+ assert_equal(true, inst[param.to_s], "did not get correct value for #{param} from string")
+ end
end
+ end
- def test_properties
- type = mktype
-
- # make a namevar
- type.newparam(:name) {}
+ def test_properties
+ type = mktype
- # make a couple of properties
- props = [:one, :two, :three]
- props.each do |prop|
- type.newproperty(prop) {}
- end
+ # make a namevar
+ type.newparam(:name) {}
- inst = type.new(:name => "yay")
+ # make a couple of properties
+ props = [:one, :two, :three]
+ props.each do |prop|
+ type.newproperty(prop) {}
+ end
- inst[:one] = "boo"
- one = inst.property(:one)
- assert(one, "did not get obj for one")
- assert_equal([one], inst.send(:properties), "got wrong properties")
+ inst = type.new(:name => "yay")
+
+ inst[:one] = "boo"
+ one = inst.property(:one)
+ assert(one, "did not get obj for one")
+ assert_equal([one], inst.send(:properties), "got wrong properties")
+
+ inst[:three] = "rah"
+ three = inst.property(:three)
+ assert(three, "did not get obj for three")
+ assert_equal([one, three], inst.send(:properties), "got wrong properties")
+
+ inst[:two] = "whee"
+ two = inst.property(:two)
+ assert(two, "did not get obj for two")
+ assert_equal([one, two, three], inst.send(:properties), "got wrong properties")
+ end
+
+ def attr_check(type)
+ @num ||= 0
+ @num += 1
+ name = "name#{@num}"
+ inst = type.new(:name => name)
+ [:meta, :param, :prop].each do |name|
+ klass = type.attrclass(name)
+ assert(klass, "did not get class for #{name}")
+ obj = yield inst, klass
+ assert_instance_of(klass, obj, "did not get object back")
+
+ assert_equal(
+ "value", inst.value(klass.name),
+
+ "value was not correct from value method")
+ assert_equal("value", obj.value, "value was not correct")
+ end
+ end
+
+ def test_newattr
+ type = mktype
+ type.newparam(:name) {}
+
+ # Make one of each param type
+ {
+ :meta => :newmetaparam, :param => :newparam, :prop => :newproperty
+ }.each do |name, method|
+ assert_nothing_raised("Could not make #{name} of type #{method}") do
+ type.send(method, name) {}
+ end
+ end
- inst[:three] = "rah"
- three = inst.property(:three)
- assert(three, "did not get obj for three")
- assert_equal([one, three], inst.send(:properties), "got wrong properties")
+ # Now set each of them
+ attr_check(type) do |inst, klass|
+ property = inst.newattr(klass.name)
+ property.value = "value"
+ property
+ end
- inst[:two] = "whee"
- two = inst.property(:two)
- assert(two, "did not get obj for two")
- assert_equal([one, two, three], inst.send(:properties), "got wrong properties")
+ # Now try it passing the class in
+ attr_check(type) do |inst, klass|
+ property = inst.newattr(klass)
+ property.value = "value"
+ property
end
- def attr_check(type)
- @num ||= 0
- @num += 1
- name = "name#{@num}"
- inst = type.new(:name => name)
- [:meta, :param, :prop].each do |name|
- klass = type.attrclass(name)
- assert(klass, "did not get class for #{name}")
- obj = yield inst, klass
- assert_instance_of(klass, obj, "did not get object back")
-
- assert_equal(
- "value", inst.value(klass.name),
-
- "value was not correct from value method")
- assert_equal("value", obj.value, "value was not correct")
- end
+ # Lastly, make sure we can create and then set, separately
+ attr_check(type) do |inst, klass|
+ obj = inst.newattr(klass.name)
+ assert_nothing_raised("Could not set value after creation") do
+ obj.value = "value"
+ end
+
+ # Make sure we can't create a new param object
+ new_attr = inst.newattr(klass.name)
+ assert_equal(new_attr, obj, "newattr should return the same object if called a second time")
+
+ obj
+ end
+ end
+
+ def test_alias_parameter
+ type = mktype
+ type.newparam(:name) {}
+ type.newparam(:one) {}
+ type.newproperty(:two) {}
+
+ aliases = {
+ :three => :one,
+ :four => :two
+ }
+ aliases.each do |new, old|
+ assert_nothing_raised("Could not create alias parameter #{new}") do
+ type.set_attr_alias new => old
+ end
end
- def test_newattr
- type = mktype
- type.newparam(:name) {}
-
- # Make one of each param type
- {
- :meta => :newmetaparam, :param => :newparam, :prop => :newproperty
- }.each do |name, method|
- assert_nothing_raised("Could not make #{name} of type #{method}") do
- type.send(method, name) {}
- end
- end
-
- # Now set each of them
- attr_check(type) do |inst, klass|
- property = inst.newattr(klass.name)
- property.value = "value"
- property
- end
-
- # Now try it passing the class in
- attr_check(type) do |inst, klass|
- property = inst.newattr(klass)
- property.value = "value"
- property
- end
-
- # Lastly, make sure we can create and then set, separately
- attr_check(type) do |inst, klass|
- obj = inst.newattr(klass.name)
- assert_nothing_raised("Could not set value after creation") do
- obj.value = "value"
- end
-
- # Make sure we can't create a new param object
- new_attr = inst.newattr(klass.name)
- assert_equal(new_attr, obj, "newattr should return the same object if called a second time")
-
- obj
- end
+ aliases.each do |new, old|
+ assert_equal(old, type.attr_alias(new), "did not return alias info for #{new}")
end
- def test_alias_parameter
- type = mktype
- type.newparam(:name) {}
- type.newparam(:one) {}
- type.newproperty(:two) {}
-
- aliases = {
- :three => :one,
- :four => :two
- }
- aliases.each do |new, old|
- assert_nothing_raised("Could not create alias parameter #{new}") do
- type.set_attr_alias new => old
- end
- end
-
- aliases.each do |new, old|
- assert_equal(old, type.attr_alias(new), "did not return alias info for #{new}")
- end
-
- assert_nil(type.attr_alias(:name), "got invalid alias info for name")
-
- inst = type.new(:name => "my name")
- assert(inst, "could not create instance")
-
- aliases.each do |new, old|
- val = "value #{new}"
- assert_nothing_raised do
- inst[new] = val
- end
-
- case old
- when :one # param
-
- assert_equal(
- val, inst[new],
+ assert_nil(type.attr_alias(:name), "got invalid alias info for name")
+
+ inst = type.new(:name => "my name")
+ assert(inst, "could not create instance")
+
+ aliases.each do |new, old|
+ val = "value #{new}"
+ assert_nothing_raised do
+ inst[new] = val
+ end
+
+ case old
+ when :one # param
+
+ assert_equal(
+ val, inst[new],
- "Incorrect alias value for #{new} in []")
- else
- assert_equal(val, inst.should(new), "Incorrect alias value for #{new} in should")
- end
- assert_equal(val, inst.value(new), "Incorrect alias value for #{new}")
- assert_equal(val, inst.value(old), "Incorrect orig value for #{old}")
- end
+ "Incorrect alias value for #{new} in []")
+ else
+ assert_equal(val, inst.should(new), "Incorrect alias value for #{new} in should")
+ end
+ assert_equal(val, inst.value(new), "Incorrect alias value for #{new}")
+ assert_equal(val, inst.value(old), "Incorrect orig value for #{old}")
end
-
- # Make sure newattr handles required features correctly.
- def test_newattr_and_required_features
- # Make a type with some features
- type = mktype
- type.feature :fone, "Something"
- type.feature :ftwo, "Something else"
- type.newparam(:name) {}
-
- # Make three properties: one with no requirements, one with one, and one with two
- none = type.newproperty(:none) {}
- one = type.newproperty(:one, :required_features => :fone) {}
- two = type.newproperty(:two, :required_features => [:fone, :ftwo]) {}
-
- # Now make similar providers
- nope = type.provide(:nope) {}
- maybe = type.provide(:maybe) { has_feature :fone}
- yep = type.provide(:yep) { has_features :fone, :ftwo}
-
- attrs = [:none, :one, :two]
-
- # Now make sure that we get warnings and no properties in those cases where our providers do not support the features requested
- [nope, maybe, yep].each_with_index do |prov, i|
- resource = type.new(:provider => prov.name, :name => "test#{i}", :none => "a", :one => "b", :two => "c")
-
- case prov.name
- when :nope
- yes = [:none]
- no = [:one, :two]
- when :maybe
- yes = [:none, :one]
- no = [:two]
- when :yep
- yes = [:none, :one, :two]
- no = []
- end
- yes.each { |a| assert(resource.should(a), "Did not get value for #{a} in #{prov.name}") }
- no.each do |a|
- # These may or may not get passed to the provider. We shouldn't care.
- end
-
- @logs.clear
- end
+ end
+
+ # Make sure newattr handles required features correctly.
+ def test_newattr_and_required_features
+ # Make a type with some features
+ type = mktype
+ type.feature :fone, "Something"
+ type.feature :ftwo, "Something else"
+ type.newparam(:name) {}
+
+ # Make three properties: one with no requirements, one with one, and one with two
+ none = type.newproperty(:none) {}
+ one = type.newproperty(:one, :required_features => :fone) {}
+ two = type.newproperty(:two, :required_features => [:fone, :ftwo]) {}
+
+ # Now make similar providers
+ nope = type.provide(:nope) {}
+ maybe = type.provide(:maybe) { has_feature :fone}
+ yep = type.provide(:yep) { has_features :fone, :ftwo}
+
+ attrs = [:none, :one, :two]
+
+ # Now make sure that we get warnings and no properties in those cases where our providers do not support the features requested
+ [nope, maybe, yep].each_with_index do |prov, i|
+ resource = type.new(:provider => prov.name, :name => "test#{i}", :none => "a", :one => "b", :two => "c")
+
+ case prov.name
+ when :nope
+ yes = [:none]
+ no = [:one, :two]
+ when :maybe
+ yes = [:none, :one]
+ no = [:two]
+ when :yep
+ yes = [:none, :one, :two]
+ no = []
+ end
+ yes.each { |a| assert(resource.should(a), "Did not get value for #{a} in #{prov.name}") }
+ no.each do |a|
+ # These may or may not get passed to the provider. We shouldn't care.
+ end
+
+ @logs.clear
end
-
- # Make sure the 'check' metaparam just ignores non-properties, rather than failing.
- def test_check_allows_parameters
- file = Puppet::Type.type(:file)
- klass = file.attrclass(:check)
-
- resource = file.new(:path => tempfile)
- inst = klass.new(:resource => resource)
-
- {:property => [:owner, :group], :parameter => [:ignore, :recurse], :metaparam => [:require, :subscribe]}.each do |attrtype, attrs|
- assert_nothing_raised("Could not set check to a single #{attrtype} value") do
- inst.value = attrs[0]
- end
-
- if attrtype == :property
- assert(resource.property(attrs[0]), "Check did not create property instance during single check")
- end
- assert_nothing_raised("Could not set check to multiple #{attrtype} values") do
- inst.value = attrs
- end
- if attrtype == :property
- assert(resource.property(attrs[1]), "Check did not create property instance during multiple check")
- end
- end
-
- # But make sure actually invalid attributes fail
- assert_raise(Puppet::Error, ":check did not fail on invalid attribute") do
- inst.value = :nosuchattr
- end
+ end
+
+ # Make sure the 'check' metaparam just ignores non-properties, rather than failing.
+ def test_check_allows_parameters
+ file = Puppet::Type.type(:file)
+ klass = file.attrclass(:check)
+
+ resource = file.new(:path => tempfile)
+ inst = klass.new(:resource => resource)
+
+ {:property => [:owner, :group], :parameter => [:ignore, :recurse], :metaparam => [:require, :subscribe]}.each do |attrtype, attrs|
+ assert_nothing_raised("Could not set check to a single #{attrtype} value") do
+ inst.value = attrs[0]
+ end
+
+ if attrtype == :property
+ assert(resource.property(attrs[0]), "Check did not create property instance during single check")
+ end
+ assert_nothing_raised("Could not set check to multiple #{attrtype} values") do
+ inst.value = attrs
+ end
+ if attrtype == :property
+ assert(resource.property(attrs[1]), "Check did not create property instance during multiple check")
+ end
end
- def test_check_ignores_unsupported_params
- type = Puppet::Type.newtype(:unsupported) do
- feature :nosuchfeat, "testing"
- newparam(:name) {}
- newproperty(:yep) {}
- newproperty(:nope, :required_features => :nosuchfeat) {}
- end
- $yep = :absent
- type.provide(:only) do
- def self.supports_parameter?(param)
- param.name != :nope
- end
-
- def yep
- $yep
- end
- def yep=(v)
- $yep = v
- end
- end
- cleanup { Puppet::Type.rmtype(:unsupported) }
-
- obj = type.new(:name => "test", :check => :yep)
- obj.stubs(:newattr).returns(stub_everything("newattr"))
- obj.expects(:newattr).with(:nope).never
- obj[:check] = :all
+ # But make sure actually invalid attributes fail
+ assert_raise(Puppet::Error, ":check did not fail on invalid attribute") do
+ inst.value = :nosuchattr
+ end
+ end
+
+ def test_check_ignores_unsupported_params
+ type = Puppet::Type.newtype(:unsupported) do
+ feature :nosuchfeat, "testing"
+ newparam(:name) {}
+ newproperty(:yep) {}
+ newproperty(:nope, :required_features => :nosuchfeat) {}
end
+ $yep = :absent
+ type.provide(:only) do
+ def self.supports_parameter?(param)
+ param.name != :nope
+ end
+
+ def yep
+ $yep
+ end
+ def yep=(v)
+ $yep = v
+ end
+ end
+ cleanup { Puppet::Type.rmtype(:unsupported) }
+
+ obj = type.new(:name => "test", :check => :yep)
+ obj.stubs(:newattr).returns(stub_everything("newattr"))
+ obj.expects(:newattr).with(:nope).never
+ obj[:check] = :all
+ end
end
diff --git a/test/ral/manager/instances.rb b/test/ral/manager/instances.rb
index 7daa105..dd1cf05 100755
--- a/test/ral/manager/instances.rb
+++ b/test/ral/manager/instances.rb
@@ -8,85 +8,85 @@ require File.dirname(__FILE__) + '/../../lib/puppettest'
require 'puppettest'
class TestTypeInstances < Test::Unit::TestCase
- include PuppetTest
-
- def setup
- super
- @type = Puppet::Type.newtype(:instance_test) do
- newparam(:name) {}
- ensurable
- end
- cleanup { Puppet::Type.rmtype(:instance_test) }
+ include PuppetTest
+
+ def setup
+ super
+ @type = Puppet::Type.newtype(:instance_test) do
+ newparam(:name) {}
+ ensurable
+ end
+ cleanup { Puppet::Type.rmtype(:instance_test) }
+ end
+
+ # Make sure the instances class method works as expected.
+ def test_instances
+ # First make sure it throws an error when there are no providers
+ assert_raise(Puppet::DevError, "Did not fail when no providers are present") do
+ @type.instances
end
- # Make sure the instances class method works as expected.
- def test_instances
- # First make sure it throws an error when there are no providers
- assert_raise(Puppet::DevError, "Did not fail when no providers are present") do
- @type.instances
- end
-
- # Now add a couple of providers
-
- # The default
- @type.provide(:default) do
- defaultfor :operatingsystem => Facter.value(:operatingsystem)
- mk_resource_methods
- class << self
- attr_accessor :names
- end
- def self.instance(name)
- new(:name => name, :ensure => :present)
- end
- def self.instances
- @instances ||= names.collect { |name| instance(name) }
- end
-
- @names = [:one, :five, :six]
- end
-
- # A provider with the same source
- @type.provide(:sub, :source => :default, :parent => :default) do
- @names = [:two, :seven, :eight]
- end
-
- # An unsuitable provider
- @type.provide(:nope, :parent => :default) do
- confine :exists => "/no/such/file"
- @names = [:three, :nine, :ten]
- end
-
- # Another suitable, non-default provider
- @type.provide(:yep, :parent => :default) do
- @names = [:four, :seven, :ten]
- end
-
- # Now make a couple of instances, so we know we correctly match instead of always
- # trying to create new ones.
- one = @type.new(:name => :one, :ensure => :present)
- three = @type.new(:name => :three, :ensure => :present, :provider => :sub)
- five = @type.new(:name => :five, :ensure => :present, :provider => :yep)
-
- result = nil
- assert_nothing_raised("Could not get instance list") do
- result = @type.instances
- end
-
- result.each do |resource|
- assert_instance_of(@type, resource, "Returned non-resource")
- end
-
- assert_equal(:one, result[0].name, "Did not get default instances first")
-
- resources = result.inject({}) { |hash, res| hash[res.name] = res; hash }
- assert(resources.include?(:four), "Did not get resources from other suitable providers")
- assert(! resources.include?(:three), "Got resources from unsuitable providers")
-
- # Now make sure we didn't change the provider type for :five
- assert_equal(:yep, five.provider.class.name, "Changed provider type when listing resources")
-
- # Now make sure the resources have an 'ensure' property to go with the value in the provider
- assert(resources[:one].send(:instance_variable_get, "@parameters").include?(:ensure), "Did not create ensure property")
+ # Now add a couple of providers
+
+ # The default
+ @type.provide(:default) do
+ defaultfor :operatingsystem => Facter.value(:operatingsystem)
+ mk_resource_methods
+ class << self
+ attr_accessor :names
+ end
+ def self.instance(name)
+ new(:name => name, :ensure => :present)
+ end
+ def self.instances
+ @instances ||= names.collect { |name| instance(name) }
+ end
+
+ @names = [:one, :five, :six]
end
+
+ # A provider with the same source
+ @type.provide(:sub, :source => :default, :parent => :default) do
+ @names = [:two, :seven, :eight]
+ end
+
+ # An unsuitable provider
+ @type.provide(:nope, :parent => :default) do
+ confine :exists => "/no/such/file"
+ @names = [:three, :nine, :ten]
+ end
+
+ # Another suitable, non-default provider
+ @type.provide(:yep, :parent => :default) do
+ @names = [:four, :seven, :ten]
+ end
+
+ # Now make a couple of instances, so we know we correctly match instead of always
+ # trying to create new ones.
+ one = @type.new(:name => :one, :ensure => :present)
+ three = @type.new(:name => :three, :ensure => :present, :provider => :sub)
+ five = @type.new(:name => :five, :ensure => :present, :provider => :yep)
+
+ result = nil
+ assert_nothing_raised("Could not get instance list") do
+ result = @type.instances
+ end
+
+ result.each do |resource|
+ assert_instance_of(@type, resource, "Returned non-resource")
+ end
+
+ assert_equal(:one, result[0].name, "Did not get default instances first")
+
+ resources = result.inject({}) { |hash, res| hash[res.name] = res; hash }
+ assert(resources.include?(:four), "Did not get resources from other suitable providers")
+ assert(! resources.include?(:three), "Got resources from unsuitable providers")
+
+ # Now make sure we didn't change the provider type for :five
+ assert_equal(:yep, five.provider.class.name, "Changed provider type when listing resources")
+
+ # Now make sure the resources have an 'ensure' property to go with the value in the provider
+ assert(resources[:one].send(:instance_variable_get, "@parameters").include?(:ensure), "Did not create ensure property")
+ end
end
diff --git a/test/ral/manager/manager.rb b/test/ral/manager/manager.rb
index 8efea12..76b1d97 100755
--- a/test/ral/manager/manager.rb
+++ b/test/ral/manager/manager.rb
@@ -8,47 +8,47 @@ require File.dirname(__FILE__) + '/../../lib/puppettest'
require 'puppettest'
class TestTypeManager < Test::Unit::TestCase
- include PuppetTest
+ include PuppetTest
- class FakeManager
- extend Puppet::MetaType::Manager
- def self.clear
- @types = {}
- end
+ class FakeManager
+ extend Puppet::MetaType::Manager
+ def self.clear
+ @types = {}
end
-
- def teardown
- super
- FakeManager.clear
- end
-
- # Make sure we can remove defined types
- def test_rmtype
- assert_nothing_raised {
- FakeManager.newtype :testing do
- newparam(:name, :namevar => true)
- end
- }
- assert(FakeManager.type(:testing), "Did not get fake type")
-
- assert_nothing_raised do
- FakeManager.rmtype(:testing)
- end
-
- assert_nil(FakeManager.type(:testing), "Type was not removed")
- assert(! defined?(FakeManager::Testing), "Constant was not removed")
+ end
+
+ def teardown
+ super
+ FakeManager.clear
+ end
+
+ # Make sure we can remove defined types
+ def test_rmtype
+ assert_nothing_raised {
+ FakeManager.newtype :testing do
+ newparam(:name, :namevar => true)
+ end
+ }
+ assert(FakeManager.type(:testing), "Did not get fake type")
+
+ assert_nothing_raised do
+ FakeManager.rmtype(:testing)
end
- def test_newtype
- assert_nothing_raised do
- FakeManager.newtype(:testing, :self_refresh => true) do
- newparam(:name, :namevar => true)
- end
- end
+ assert_nil(FakeManager.type(:testing), "Type was not removed")
+ assert(! defined?(FakeManager::Testing), "Constant was not removed")
+ end
- test = FakeManager.type(:testing)
- assert(test, "did not get type")
- assert(test.self_refresh, "did not set attribute")
+ def test_newtype
+ assert_nothing_raised do
+ FakeManager.newtype(:testing, :self_refresh => true) do
+ newparam(:name, :namevar => true)
+ end
end
+
+ test = FakeManager.type(:testing)
+ assert(test, "did not get type")
+ assert(test.self_refresh, "did not set attribute")
+ end
end
diff --git a/test/ral/manager/provider.rb b/test/ral/manager/provider.rb
index 82c27b6..d4c8a34 100755
--- a/test/ral/manager/provider.rb
+++ b/test/ral/manager/provider.rb
@@ -6,79 +6,79 @@ require 'puppettest'
require 'mocha'
class TestTypeProviders < Test::Unit::TestCase
- include PuppetTest
-
- def setup
- super
- @type = Puppet::Type.newtype(:provider_test) do
- newparam(:name) {}
- ensurable
- end
- cleanup { Puppet::Type.rmtype(:provider_test) }
- end
-
- # Make sure default providers behave correctly
- def test_defaultproviders
- basic = @type.provide(:basic) do
- defaultfor :operatingsystem => :somethingelse,
- :operatingsystemrelease => :yayness
- end
+ include PuppetTest
- assert_equal(basic, @type.defaultprovider)
- @type.defaultprovider = nil
+ def setup
+ super
+ @type = Puppet::Type.newtype(:provider_test) do
+ newparam(:name) {}
+ ensurable
+ end
+ cleanup { Puppet::Type.rmtype(:provider_test) }
+ end
+
+ # Make sure default providers behave correctly
+ def test_defaultproviders
+ basic = @type.provide(:basic) do
+ defaultfor :operatingsystem => :somethingelse,
+ :operatingsystemrelease => :yayness
+ end
- greater = @type.provide(:greater) do
- defaultfor :operatingsystem => Facter.value("operatingsystem")
- end
+ assert_equal(basic, @type.defaultprovider)
+ @type.defaultprovider = nil
- assert_equal(greater, @type.defaultprovider)
+ greater = @type.provide(:greater) do
+ defaultfor :operatingsystem => Facter.value("operatingsystem")
end
- # Make sure the provider is always the first parameter created.
- def test_provider_sorting
- should = [:name, :ensure]
- assert_equal(should, @type.allattrs.reject { |p| ! should.include?(p) }, "Got wrong order of parameters")
+ assert_equal(greater, @type.defaultprovider)
+ end
- @type.provide(:yay) { }
- should = [:name, :provider, :ensure]
- assert_equal(should, @type.allattrs.reject { |p| ! should.include?(p) },
- "Providify did not reorder parameters")
- end
+ # Make sure the provider is always the first parameter created.
+ def test_provider_sorting
+ should = [:name, :ensure]
+ assert_equal(should, @type.allattrs.reject { |p| ! should.include?(p) }, "Got wrong order of parameters")
- # Make sure that provider instances can be passed in directly.
- def test_name_or_provider
- provider = @type.provide(:testing) do
- end
+ @type.provide(:yay) { }
+ should = [:name, :provider, :ensure]
+ assert_equal(should, @type.allattrs.reject { |p| ! should.include?(p) },
+ "Providify did not reorder parameters")
+ end
- # first make sure we can pass the name in
- resource = nil
- assert_nothing_raised("Could not create provider instance by name") do
- resource = @type.new :name => "yay", :provider => :testing
- end
+ # Make sure that provider instances can be passed in directly.
+ def test_name_or_provider
+ provider = @type.provide(:testing) do
+ end
- assert_instance_of(provider, resource.provider, "Did not create provider instance")
+ # first make sure we can pass the name in
+ resource = nil
+ assert_nothing_raised("Could not create provider instance by name") do
+ resource = @type.new :name => "yay", :provider => :testing
+ end
- # Now make sure we can pass in an instance
- provinst = provider.new(:name => "foo")
- assert_nothing_raised("Could not pass in provider instance") do
- resource = @type.new :name => "foo", :provider => provinst
- end
+ assert_instance_of(provider, resource.provider, "Did not create provider instance")
- assert_equal(provinst, resource.provider, "Did not retain provider instance")
- assert_equal(provider.name, resource[:provider], "Provider value was set to the provider instead of its name")
+ # Now make sure we can pass in an instance
+ provinst = provider.new(:name => "foo")
+ assert_nothing_raised("Could not pass in provider instance") do
+ resource = @type.new :name => "foo", :provider => provinst
+ end
- # Now make sure unsuitable provider instances still throw errors
- provider = @type.provide(:badprov) do
- confine :exists => "/no/such/file"
- end
+ assert_equal(provinst, resource.provider, "Did not retain provider instance")
+ assert_equal(provider.name, resource[:provider], "Provider value was set to the provider instead of its name")
- # And make sure the provider must be a valid provider type for this resource
- pkgprov = Puppet::Type.type(:package).new(:name => "yayness").provider
- assert(provider, "did not get package provider")
+ # Now make sure unsuitable provider instances still throw errors
+ provider = @type.provide(:badprov) do
+ confine :exists => "/no/such/file"
+ end
- assert_raise(Puppet::Error, "Did not fail on invalid provider instance") do
- resource = @type.new :name => "bar", :provider => pkgprov
- end
+ # And make sure the provider must be a valid provider type for this resource
+ pkgprov = Puppet::Type.type(:package).new(:name => "yayness").provider
+ assert(provider, "did not get package provider")
+ assert_raise(Puppet::Error, "Did not fail on invalid provider instance") do
+ resource = @type.new :name => "bar", :provider => pkgprov
end
+
+ end
end
diff --git a/test/ral/manager/type.rb b/test/ral/manager/type.rb
index 5fd4fd6..7df6430 100755
--- a/test/ral/manager/type.rb
+++ b/test/ral/manager/type.rb
@@ -6,356 +6,356 @@ require 'mocha'
require 'puppettest'
class TestType < Test::Unit::TestCase
- include PuppetTest
- def test_typemethods
- Puppet::Type.eachtype { |type|
- name = nil
- assert_nothing_raised("Searching for name for #{type} caused failure") {
- name = type.name
- }
+ include PuppetTest
+ def test_typemethods
+ Puppet::Type.eachtype { |type|
+ name = nil
+ assert_nothing_raised("Searching for name for #{type} caused failure") {
+ name = type.name
+ }
- assert(name, "Could not find name for #{type}")
+ assert(name, "Could not find name for #{type}")
- assert_equal(
+ assert_equal(
- type,
- Puppet::Type.type(name),
+ type,
+ Puppet::Type.type(name),
- "Failed to retrieve #{name} by name"
- )
+ "Failed to retrieve #{name} by name"
+ )
- # Skip types with no parameters or valid properties
- #unless ! type.parameters.empty? or ! type.validproperties.empty?
- # next
- #end
+ # Skip types with no parameters or valid properties
+ #unless ! type.parameters.empty? or ! type.validproperties.empty?
+ # next
+ #end
- assert_nothing_raised {
+ assert_nothing_raised {
- assert_not_nil(
+ assert_not_nil(
- type.properties,
+ type.properties,
- "Properties for #{name} are nil"
- )
+ "Properties for #{name} are nil"
+ )
- assert_not_nil(
+ assert_not_nil(
- type.validproperties,
+ type.validproperties,
- "Valid properties for #{name} are nil"
- )
- }
- }
- end
+ "Valid properties for #{name} are nil"
+ )
+ }
+ }
+ end
- def test_aliases_are_added_to_catalog
+ def test_aliases_are_added_to_catalog
- resource = Puppet::Type.type(:file).new(
+ resource = Puppet::Type.type(:file).new(
- :name => "/path/to/some/missing/file",
+ :name => "/path/to/some/missing/file",
- :ensure => "file"
- )
- resource.stubs(:path).returns("")
+ :ensure => "file"
+ )
+ resource.stubs(:path).returns("")
- catalog = stubs 'catalog'
- catalog.stubs(:resource).returns(nil)
- catalog.expects(:alias).with(resource, "funtest")
- resource.catalog = catalog
+ catalog = stubs 'catalog'
+ catalog.stubs(:resource).returns(nil)
+ catalog.expects(:alias).with(resource, "funtest")
+ resource.catalog = catalog
- assert_nothing_raised("Could not add alias") {
- resource[:alias] = "funtest"
- }
- end
+ assert_nothing_raised("Could not add alias") {
+ resource[:alias] = "funtest"
+ }
+ end
- def test_aliasing_fails_without_a_catalog
+ def test_aliasing_fails_without_a_catalog
- resource = Puppet::Type.type(:file).new(
+ resource = Puppet::Type.type(:file).new(
- :name => "/no/such/file",
+ :name => "/no/such/file",
- :ensure => "file"
- )
+ :ensure => "file"
+ )
- assert_raise(Puppet::Error, "It should fail to alias when no catalog was available") {
- resource[:alias] = "funtest"
- }
- end
+ assert_raise(Puppet::Error, "It should fail to alias when no catalog was available") {
+ resource[:alias] = "funtest"
+ }
+ end
- def test_ensuredefault
- user = nil
- assert_nothing_raised {
+ def test_ensuredefault
+ user = nil
+ assert_nothing_raised {
- user = Puppet::Type.type(:user).new(
+ user = Puppet::Type.type(:user).new(
- :name => "pptestAA",
+ :name => "pptestAA",
- :check => [:uid]
- )
- }
+ :check => [:uid]
+ )
+ }
- # make sure we don't get :ensure for unmanaged files
- assert(! user.property(:ensure), "User got an ensure property")
+ # make sure we don't get :ensure for unmanaged files
+ assert(! user.property(:ensure), "User got an ensure property")
- assert_nothing_raised {
+ assert_nothing_raised {
- user = Puppet::Type.type(:user).new(
+ user = Puppet::Type.type(:user).new(
- :name => "pptestAB",
+ :name => "pptestAB",
- :comment => "Testingness"
- )
- }
- # but make sure it gets added once we manage them
- assert(user.property(:ensure), "User did not add ensure property")
+ :comment => "Testingness"
+ )
+ }
+ # but make sure it gets added once we manage them
+ assert(user.property(:ensure), "User did not add ensure property")
- assert_nothing_raised {
+ assert_nothing_raised {
- user = Puppet::Type.type(:user).new(
+ user = Puppet::Type.type(:user).new(
- :name => "pptestBC",
+ :name => "pptestBC",
- :comment => "A fake user"
- )
- }
-
- # and make sure managed objects start with them
- assert(user.property(:ensure), "User did not get an ensure property")
+ :comment => "A fake user"
+ )
+ }
+
+ # and make sure managed objects start with them
+ assert(user.property(:ensure), "User did not get an ensure property")
+ end
+ def test_newtype_methods
+ assert_nothing_raised {
+ Puppet::Type.newtype(:mytype) do
+ newparam(:wow) do isnamevar end
+ end
+ }
+
+
+ assert(
+ Puppet::Type.respond_to?(:newmytype),
+
+ "new<type> method did not get created")
+
+ obj = nil
+ assert_nothing_raised {
+ obj = Puppet::Type.newmytype(:wow => "yay")
+ }
+
+ assert(obj.is_a?(Puppet::Type.type(:mytype)),
+ "Obj is not the correct type")
+
+ # Now make the type again, just to make sure it works on refreshing.
+ assert_nothing_raised {
+ Puppet::Type.newtype(:mytype) do
+ newparam(:yay) do isnamevar end
+ end
+ }
+
+ obj = nil
+ # Make sure the old class was thrown away and only the new one is sitting
+ # around.
+ assert_raise(Puppet::Error) {
+ obj = Puppet::Type.newmytype(:wow => "yay")
+ }
+ assert_nothing_raised {
+ obj = Puppet::Type.newmytype(:yay => "yay")
+ }
+
+ # Now make sure that we don't replace existing, non-type methods
+ parammethod = Puppet::Type.method(:newparam)
+
+ assert_nothing_raised {
+ Puppet::Type.newtype(:param) do
+ newparam(:rah) do isnamevar end
+ end
+ }
+ assert_equal(parammethod, Puppet::Type.method(:newparam), "newparam method got replaced by newtype")
+ end
+
+ def test_newproperty_options
+ # Create a type with a fake provider
+ providerclass = Class.new do
+ def self.supports_parameter?(prop)
+ true
+ end
+ def method_missing(method, *args)
+ method
+ end
end
- def test_newtype_methods
- assert_nothing_raised {
- Puppet::Type.newtype(:mytype) do
- newparam(:wow) do isnamevar end
- end
- }
+ self.class.const_set("ProviderClass", providerclass)
+ type = Puppet::Type.newtype(:mytype) do
+ newparam(:name) do
+ isnamevar
+ end
+ def provider
+ @provider ||= ProviderClass.new
- assert(
- Puppet::Type.respond_to?(:newmytype),
-
- "new<type> method did not get created")
-
- obj = nil
- assert_nothing_raised {
- obj = Puppet::Type.newmytype(:wow => "yay")
- }
-
- assert(obj.is_a?(Puppet::Type.type(:mytype)),
- "Obj is not the correct type")
-
- # Now make the type again, just to make sure it works on refreshing.
- assert_nothing_raised {
- Puppet::Type.newtype(:mytype) do
- newparam(:yay) do isnamevar end
- end
- }
-
- obj = nil
- # Make sure the old class was thrown away and only the new one is sitting
- # around.
- assert_raise(Puppet::Error) {
- obj = Puppet::Type.newmytype(:wow => "yay")
- }
- assert_nothing_raised {
- obj = Puppet::Type.newmytype(:yay => "yay")
- }
-
- # Now make sure that we don't replace existing, non-type methods
- parammethod = Puppet::Type.method(:newparam)
-
- assert_nothing_raised {
- Puppet::Type.newtype(:param) do
- newparam(:rah) do isnamevar end
- end
- }
- assert_equal(parammethod, Puppet::Type.method(:newparam), "newparam method got replaced by newtype")
+ @provider
+ end
+ end
+
+ # Now make a property with no options.
+ property = nil
+ assert_nothing_raised do
+ property = type.newproperty(:noopts) do
+ end
end
- def test_newproperty_options
- # Create a type with a fake provider
- providerclass = Class.new do
- def self.supports_parameter?(prop)
- true
- end
- def method_missing(method, *args)
- method
- end
- end
- self.class.const_set("ProviderClass", providerclass)
-
- type = Puppet::Type.newtype(:mytype) do
- newparam(:name) do
- isnamevar
- end
- def provider
- @provider ||= ProviderClass.new
-
- @provider
- end
- end
-
- # Now make a property with no options.
- property = nil
- assert_nothing_raised do
- property = type.newproperty(:noopts) do
- end
- end
-
- # Now create an instance
- obj = type.create(:name => :myobj)
-
- inst = property.new(:resource => obj)
-
- # And make sure it's correctly setting @is
- ret = nil
- assert_nothing_raised {
- ret = inst.retrieve
- }
-
- assert_equal(:noopts, inst.retrieve)
-
- # Now create a property with a different way of doing it
- property = nil
- assert_nothing_raised do
- property = type.newproperty(:setretrieve, :retrieve => :yayness)
- end
-
- inst = property.new(:resource => obj)
-
- # And make sure it's correctly setting @is
- ret = nil
- assert_nothing_raised {
- ret = inst.retrieve
- }
-
- assert_equal(:yayness, ret)
+ # Now create an instance
+ obj = type.create(:name => :myobj)
+
+ inst = property.new(:resource => obj)
+
+ # And make sure it's correctly setting @is
+ ret = nil
+ assert_nothing_raised {
+ ret = inst.retrieve
+ }
+
+ assert_equal(:noopts, inst.retrieve)
+
+ # Now create a property with a different way of doing it
+ property = nil
+ assert_nothing_raised do
+ property = type.newproperty(:setretrieve, :retrieve => :yayness)
end
- # Make sure the title is sufficiently differentiated from the namevar.
- def test_title_at_creation_with_hash
- file = nil
- fileclass = Puppet::Type.type(:file)
+ inst = property.new(:resource => obj)
+
+ # And make sure it's correctly setting @is
+ ret = nil
+ assert_nothing_raised {
+ ret = inst.retrieve
+ }
+
+ assert_equal(:yayness, ret)
+ end
+
+ # Make sure the title is sufficiently differentiated from the namevar.
+ def test_title_at_creation_with_hash
+ file = nil
+ fileclass = Puppet::Type.type(:file)
- path = tempfile
- assert_nothing_raised do
+ path = tempfile
+ assert_nothing_raised do
- file = fileclass.create(
+ file = fileclass.create(
- :title => "Myfile",
+ :title => "Myfile",
- :path => path
- )
- end
+ :path => path
+ )
+ end
- assert_equal("Myfile", file.title, "Did not get correct title")
- assert_equal(path, file[:name], "Did not get correct name")
+ assert_equal("Myfile", file.title, "Did not get correct title")
+ assert_equal(path, file[:name], "Did not get correct name")
- file = nil
+ file = nil
- # Now make sure we can specify both and still get the right answers
- assert_nothing_raised do
+ # Now make sure we can specify both and still get the right answers
+ assert_nothing_raised do
- file = fileclass.create(
+ file = fileclass.create(
- :title => "Myfile",
+ :title => "Myfile",
- :name => path
- )
- end
+ :name => path
+ )
+ end
- assert_instance_of(fileclass, file)
+ assert_instance_of(fileclass, file)
- assert_equal("Myfile", file.title, "Did not get correct title")
- assert_equal(path, file[:name], "Did not get correct name")
- end
+ assert_equal("Myfile", file.title, "Did not get correct title")
+ assert_equal(path, file[:name], "Did not get correct name")
+ end
- # Make sure that we can have multiple non-isomorphic objects with the same name,
- # but not with isomorphic objects.
- def test_isomorphic_names
- catalog = mk_catalog
- # First do execs, since they're not isomorphic.
- echo = Puppet::Util.binary "echo"
- exec1 = exec2 = nil
- assert_nothing_raised do
+ # Make sure that we can have multiple non-isomorphic objects with the same name,
+ # but not with isomorphic objects.
+ def test_isomorphic_names
+ catalog = mk_catalog
+ # First do execs, since they're not isomorphic.
+ echo = Puppet::Util.binary "echo"
+ exec1 = exec2 = nil
+ assert_nothing_raised do
- exec1 = Puppet::Type.type(:exec).new(
+ exec1 = Puppet::Type.type(:exec).new(
- :title => "exec1",
+ :title => "exec1",
- :command => "#{echo} funtest"
- )
- end
- catalog.add_resource(exec1)
- assert_nothing_raised do
+ :command => "#{echo} funtest"
+ )
+ end
+ catalog.add_resource(exec1)
+ assert_nothing_raised do
- exec2 = Puppet::Type.type(:exec).new(
+ exec2 = Puppet::Type.type(:exec).new(
- :title => "exec2",
+ :title => "exec2",
- :command => "#{echo} funtest"
- )
- end
- catalog.add_resource(exec2)
+ :command => "#{echo} funtest"
+ )
+ end
+ catalog.add_resource(exec2)
- # Now do files, since they are. This should fail.
- file1 = file2 = nil
- path = tempfile
+ # Now do files, since they are. This should fail.
+ file1 = file2 = nil
+ path = tempfile
- file1 = Puppet::Type.type(:file).new(
+ file1 = Puppet::Type.type(:file).new(
- :title => "file1",
- :path => path,
+ :title => "file1",
+ :path => path,
- :content => "yayness"
- )
- catalog.add_resource(file1)
+ :content => "yayness"
+ )
+ catalog.add_resource(file1)
- file2 = Puppet::Type.type(:file).new(
+ file2 = Puppet::Type.type(:file).new(
- :title => "file2",
- :path => path,
+ :title => "file2",
+ :path => path,
- :content => "rahness"
- )
- assert_raise(ArgumentError) { catalog.add_resource(file2) }
- end
+ :content => "rahness"
+ )
+ assert_raise(ArgumentError) { catalog.add_resource(file2) }
+ end
- def test_tags
- obj = Puppet::Type.type(:file).new(:path => tempfile)
+ def test_tags
+ obj = Puppet::Type.type(:file).new(:path => tempfile)
- tags = ["some", "test", "tags"]
+ tags = ["some", "test", "tags"]
- obj.tags = tags
+ obj.tags = tags
- # tags can be stored in an unordered set, so we sort
- # them for the assert_equal to work
- assert_equal((tags << "file").sort, obj.tags.sort)
- end
+ # tags can be stored in an unordered set, so we sort
+ # them for the assert_equal to work
+ assert_equal((tags << "file").sort, obj.tags.sort)
+ end
- def test_to_hash
- file = Puppet::Type.newfile :path => tempfile, :owner => "luke",
- :recurse => true, :loglevel => "warning"
+ def test_to_hash
+ file = Puppet::Type.newfile :path => tempfile, :owner => "luke",
+ :recurse => true, :loglevel => "warning"
- hash = nil
- assert_nothing_raised do
- hash = file.to_hash
- end
+ hash = nil
+ assert_nothing_raised do
+ hash = file.to_hash
+ end
- [:path, :owner, :recurse, :loglevel].each do |param|
- assert(hash[param], "Hash did not include #{param}")
- end
+ [:path, :owner, :recurse, :loglevel].each do |param|
+ assert(hash[param], "Hash did not include #{param}")
end
+ end
- def test_ref
- path = tempfile
- Puppet::Type.type(:exec) # uggh, the methods need to load the types
- file = Puppet::Type.newfile(:path => path)
- assert_equal("File[#{path}]", file.ref)
+ def test_ref
+ path = tempfile
+ Puppet::Type.type(:exec) # uggh, the methods need to load the types
+ file = Puppet::Type.newfile(:path => path)
+ assert_equal("File[#{path}]", file.ref)
- exec = Puppet::Type.newexec(:title => "yay", :command => "/bin/echo yay")
- assert_equal("Exec[yay]", exec.ref)
- end
+ exec = Puppet::Type.newexec(:title => "yay", :command => "/bin/echo yay")
+ assert_equal("Exec[yay]", exec.ref)
+ end
end
diff --git a/test/ral/providers/cron/crontab.rb b/test/ral/providers/cron/crontab.rb
index 3a996cb..0c87a5b 100755
--- a/test/ral/providers/cron/crontab.rb
+++ b/test/ral/providers/cron/crontab.rb
@@ -7,642 +7,642 @@ require 'mocha'
require 'puppettest/fileparsing'
class TestCronParsedProvider < Test::Unit::TestCase
- include PuppetTest
- include PuppetTest::FileParsing
-
-
- FIELDS = {
- :crontab => %w{command minute hour month monthday weekday}.collect { |o| o.intern },
- :freebsd_special => %w{special command}.collect { |o| o.intern },
- :environment => [:line],
- :blank => [:line],
- :comment => [:line],
- }
-
- # These are potentially multi-line records; there's no one-to-one map, but they model
- # a full cron job. These tests assume individual record types will always be correctly
- # parsed, so all they
- def sample_crons
- @sample_crons ||= YAML.load(File.read(File.join(@crondir, "crontab_collections.yaml")))
+ include PuppetTest
+ include PuppetTest::FileParsing
+
+
+ FIELDS = {
+ :crontab => %w{command minute hour month monthday weekday}.collect { |o| o.intern },
+ :freebsd_special => %w{special command}.collect { |o| o.intern },
+ :environment => [:line],
+ :blank => [:line],
+ :comment => [:line],
+ }
+
+ # These are potentially multi-line records; there's no one-to-one map, but they model
+ # a full cron job. These tests assume individual record types will always be correctly
+ # parsed, so all they
+ def sample_crons
+ @sample_crons ||= YAML.load(File.read(File.join(@crondir, "crontab_collections.yaml")))
+ end
+
+ # These are simple lines that can appear in the files; there is a one to one
+ # mapping between records and lines. We have plenty of redundancy here because
+ # we use these records to build up our complex, multi-line cron jobs below.
+ def sample_records
+ @sample_records ||= YAML.load(File.read(File.join(@crondir, "crontab_sample_records.yaml")))
+ end
+
+ def setup
+ super
+ @type = Puppet::Type.type(:cron)
+ @provider = @type.provider(:crontab)
+ @provider.initvars
+ @crondir = datadir(File.join(%w{providers cron}))
+
+ @oldfiletype = @provider.filetype
+ end
+
+ def teardown
+ Puppet::Util::FileType.filetype(:ram).clear
+ @provider.clear
+ super
+ end
+
+ # Make sure a cron job matches up. Any non-passed fields are considered absent.
+ def assert_cron_equal(msg, cron, options)
+ assert_instance_of(@provider, cron, "not an instance of provider in #{msg}")
+ options.each do |param, value|
+ assert_equal(value, cron.send(param), "#{param} was not equal in #{msg}")
end
-
- # These are simple lines that can appear in the files; there is a one to one
- # mapping between records and lines. We have plenty of redundancy here because
- # we use these records to build up our complex, multi-line cron jobs below.
- def sample_records
- @sample_records ||= YAML.load(File.read(File.join(@crondir, "crontab_sample_records.yaml")))
+ %w{command environment minute hour month monthday weekday}.each do |var|
+ assert_equal(:absent, cron.send(var), "#{var} was not parsed absent in #{msg}") unless options.include?(var.intern)
end
+ end
+
+ # Make sure a cron record matches. This only works for crontab records.
+ def assert_record_equal(msg, record, options)
+ raise ArgumentError, "You must pass the required record type" unless options.include?(:record_type)
+ assert_instance_of(Hash, record, "not an instance of a hash in #{msg}")
+ options.each do |param, value|
+ assert_equal(value, record[param], "#{param} was not equal in #{msg}")
+ end
+ FIELDS[record[:record_type]].each do |var|
+ assert_equal(:absent, record[var], "#{var} was not parsed absent in #{msg}") unless options.include?(var)
+ end
+ end
- def setup
- super
- @type = Puppet::Type.type(:cron)
- @provider = @type.provider(:crontab)
- @provider.initvars
- @crondir = datadir(File.join(%w{providers cron}))
+ def assert_header(file)
+ header = []
+ file.gsub! /^(# HEADER: .+$)\n/ do
+ header << $1
+ ''
+ end
+ assert_equal(4, header.length, "Did not get four header lines")
+ end
+
+ # This handles parsing every possible iteration of cron records. Note that this is only
+ # single-line stuff and doesn't include multi-line values (e.g., with names and/or envs).
+ # Those have separate tests.
+ def test_parse_line
+ # First just do each sample record one by one
+ sample_records.each do |name, options|
+ result = nil
+ assert_nothing_raised("Could not parse #{name}: '#{options[:text]}'") do
+ result = @provider.parse_line(options[:text])
+ end
+ assert_record_equal("record for #{name}", result, options[:record])
+ end
- @oldfiletype = @provider.filetype
+ # Then do them all at once.
+ records = []
+ text = ""
+ sample_records.each do |name, options|
+ records << options[:record]
+ text += options[:text] + "\n"
end
- def teardown
- Puppet::Util::FileType.filetype(:ram).clear
- @provider.clear
- super
+ result = nil
+ assert_nothing_raised("Could not match all records in one file") do
+ result = @provider.parse(text)
end
- # Make sure a cron job matches up. Any non-passed fields are considered absent.
- def assert_cron_equal(msg, cron, options)
- assert_instance_of(@provider, cron, "not an instance of provider in #{msg}")
- options.each do |param, value|
- assert_equal(value, cron.send(param), "#{param} was not equal in #{msg}")
- end
- %w{command environment minute hour month monthday weekday}.each do |var|
- assert_equal(:absent, cron.send(var), "#{var} was not parsed absent in #{msg}") unless options.include?(var.intern)
- end
+ records.zip(result).each do |should, record|
+ assert_record_equal("record for #{should.inspect} in full match", record, should)
+ end
+ end
+
+ # Here we test that each record generates to the correct text.
+ def test_generate_line
+ # First just do each sample record one by one
+ sample_records.each do |name, options|
+ result = nil
+ assert_nothing_raised("Could not generate #{name}: '#{options[:record]}'") do
+ result = @provider.to_line(options[:record])
+ end
+ assert_equal(options[:text], result, "Did not generate correct text for #{name}")
end
- # Make sure a cron record matches. This only works for crontab records.
- def assert_record_equal(msg, record, options)
- raise ArgumentError, "You must pass the required record type" unless options.include?(:record_type)
- assert_instance_of(Hash, record, "not an instance of a hash in #{msg}")
- options.each do |param, value|
- assert_equal(value, record[param], "#{param} was not equal in #{msg}")
- end
- FIELDS[record[:record_type]].each do |var|
- assert_equal(:absent, record[var], "#{var} was not parsed absent in #{msg}") unless options.include?(var)
- end
+ # Then do them all at once.
+ records = []
+ text = ""
+ sample_records.each do |name, options|
+ records << options[:record]
+ text += options[:text] + "\n"
end
- def assert_header(file)
- header = []
- file.gsub! /^(# HEADER: .+$)\n/ do
- header << $1
- ''
- end
- assert_equal(4, header.length, "Did not get four header lines")
+ result = nil
+ assert_nothing_raised("Could not match all records in one file") do
+ result = @provider.to_file(records)
end
- # This handles parsing every possible iteration of cron records. Note that this is only
- # single-line stuff and doesn't include multi-line values (e.g., with names and/or envs).
- # Those have separate tests.
- def test_parse_line
- # First just do each sample record one by one
- sample_records.each do |name, options|
- result = nil
- assert_nothing_raised("Could not parse #{name}: '#{options[:text]}'") do
- result = @provider.parse_line(options[:text])
- end
- assert_record_equal("record for #{name}", result, options[:record])
- end
+ assert_header(result)
- # Then do them all at once.
- records = []
- text = ""
- sample_records.each do |name, options|
- records << options[:record]
- text += options[:text] + "\n"
- end
+ assert_equal(text, result, "Did not generate correct full crontab")
+ end
- result = nil
- assert_nothing_raised("Could not match all records in one file") do
- result = @provider.parse(text)
+ # Test cronjobs that are made up from multiple records.
+ def test_multi_line_cronjobs
+ fulltext = ""
+ all_records = []
+ sample_crons.each do |name, record_names|
+ records = record_names.collect do |record_name|
+ unless record = sample_records[record_name]
+ raise "Could not find sample record #{record_name}"
end
+ record
+ end
+
+ text = records.collect { |r| r[:text] }.join("\n") + "\n"
+ record_list = records.collect { |r| r[:record] }
+
+ # Add it to our full collection
+ all_records += record_list
+ fulltext += text
+
+ # First make sure we generate each one correctly
+ result = nil
+ assert_nothing_raised("Could not generate multi-line cronjob #{name}") do
+ result = @provider.to_file(record_list)
+ end
+ assert_header(result)
+ assert_equal(text, result, "Did not generate correct text for multi-line cronjob #{name}")
+
+ # Now make sure we parse each one correctly
+ assert_nothing_raised("Could not parse multi-line cronjob #{name}") do
+ result = @provider.parse(text)
+ end
+ record_list.zip(result).each do |should, record|
+ assert_record_equal("multiline cronjob #{name}", record, should)
+ end
+ end
- records.zip(result).each do |should, record|
- assert_record_equal("record for #{should.inspect} in full match", record, should)
- end
+ # Make sure we can generate it all correctly
+ result = nil
+ assert_nothing_raised("Could not generate all multi-line cronjobs") do
+ result = @provider.to_file(all_records)
end
+ assert_header(result)
+ assert_equal(fulltext, result, "Did not generate correct text for all multi-line cronjobs")
- # Here we test that each record generates to the correct text.
- def test_generate_line
- # First just do each sample record one by one
- sample_records.each do |name, options|
- result = nil
- assert_nothing_raised("Could not generate #{name}: '#{options[:record]}'") do
- result = @provider.to_line(options[:record])
- end
- assert_equal(options[:text], result, "Did not generate correct text for #{name}")
+ # Now make sure we parse them all correctly
+ assert_nothing_raised("Could not parse multi-line cronjobs") do
+ result = @provider.parse(fulltext)
+ end
+ all_records.zip(result).each do |should, record|
+ assert_record_equal("multiline cronjob %s", record, should)
+ end
+ end
+
+ # Take our sample files, and make sure we can entirely parse them,
+ # then that we can generate them again and we get the same data.
+ def test_parse_and_generate_sample_files
+ @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
+ crondir = datadir(File.join(%w{providers cron}))
+ files = Dir.glob("#{crondir}/crontab.*")
+
+ setme
+ @provider.default_target = @me
+ target = @provider.target_object(@me)
+ files.each do |file|
+ str = args = nil
+ assert_nothing_raised("could not load #{file}") do
+ str, args = YAML.load(File.read(file))
+ end
+
+ # Stupid old yaml
+ args.each do |hash|
+ hash.each do |param, value|
+ if param.is_a?(String) and param =~ /^:/
+ hash.delete(param)
+ param = param.sub(/^:/,'').intern
+ hash[param] = value
+ end
+
+ if value.is_a?(String) and value =~ /^:/
+ value = value.sub(/^:/,'').intern
+ hash[param] = value
+ end
end
-
- # Then do them all at once.
- records = []
- text = ""
- sample_records.each do |name, options|
- records << options[:record]
- text += options[:text] + "\n"
+ end
+ target.write(str)
+ assert_nothing_raised("could not parse #{file}") do
+ @provider.prefetch
+ end
+ records = @provider.send(:instance_variable_get, "@records")
+
+ args.zip(records) do |should, sis|
+ # Make the values a bit more equal.
+ should[:target] = @me
+ should[:ensure] = :present
+ #should[:environment] ||= []
+ should[:on_disk] = true
+ is = sis.dup
+ sis.dup.each do |p,v|
+ is.delete(p) if v == :absent
end
- result = nil
- assert_nothing_raised("Could not match all records in one file") do
- result = @provider.to_file(records)
- end
+ assert_equal(
+ should, is,
+
+ "Did not parse #{file} correctly")
+ end
- assert_header(result)
+ assert_nothing_raised("could not generate #{file}") do
+ @provider.flush_target(@me)
+ end
- assert_equal(text, result, "Did not generate correct full crontab")
+ assert_equal(str, target.read, "#{file} changed")
+ @provider.clear
end
+ end
+
+ # A simple test to see if we can load the cron from disk.
+ def test_load
+ setme
+ records = nil
+ assert_nothing_raised {
+ records = @provider.retrieve(@me)
+ }
+ assert_instance_of(Array, records, "did not get correct response")
+ end
+
+ # Test that a cron job turns out as expected, by creating one and generating
+ # it directly
+ def test_simple_to_cron
+ # make the cron
+ setme
+
+ name = "yaytest"
+ args = {:name => name,
+ :command => "date > /dev/null",
+ :minute => "30",
+ :user => @me,
+ :record_type => :crontab
+ }
+ # generate the text
+ str = nil
+ assert_nothing_raised {
+ str = @provider.to_line(args)
+ }
- # Test cronjobs that are made up from multiple records.
- def test_multi_line_cronjobs
- fulltext = ""
- all_records = []
- sample_crons.each do |name, record_names|
- records = record_names.collect do |record_name|
- unless record = sample_records[record_name]
- raise "Could not find sample record #{record_name}"
- end
- record
- end
-
- text = records.collect { |r| r[:text] }.join("\n") + "\n"
- record_list = records.collect { |r| r[:record] }
-
- # Add it to our full collection
- all_records += record_list
- fulltext += text
-
- # First make sure we generate each one correctly
- result = nil
- assert_nothing_raised("Could not generate multi-line cronjob #{name}") do
- result = @provider.to_file(record_list)
- end
- assert_header(result)
- assert_equal(text, result, "Did not generate correct text for multi-line cronjob #{name}")
-
- # Now make sure we parse each one correctly
- assert_nothing_raised("Could not parse multi-line cronjob #{name}") do
- result = @provider.parse(text)
- end
- record_list.zip(result).each do |should, record|
- assert_record_equal("multiline cronjob #{name}", record, should)
- end
- end
-
- # Make sure we can generate it all correctly
- result = nil
- assert_nothing_raised("Could not generate all multi-line cronjobs") do
- result = @provider.to_file(all_records)
- end
- assert_header(result)
- assert_equal(fulltext, result, "Did not generate correct text for all multi-line cronjobs")
-
- # Now make sure we parse them all correctly
- assert_nothing_raised("Could not parse multi-line cronjobs") do
- result = @provider.parse(fulltext)
- end
- all_records.zip(result).each do |should, record|
- assert_record_equal("multiline cronjob %s", record, should)
- end
- end
- # Take our sample files, and make sure we can entirely parse them,
- # then that we can generate them again and we get the same data.
- def test_parse_and_generate_sample_files
- @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
- crondir = datadir(File.join(%w{providers cron}))
- files = Dir.glob("#{crondir}/crontab.*")
-
- setme
- @provider.default_target = @me
- target = @provider.target_object(@me)
- files.each do |file|
- str = args = nil
- assert_nothing_raised("could not load #{file}") do
- str, args = YAML.load(File.read(file))
- end
-
- # Stupid old yaml
- args.each do |hash|
- hash.each do |param, value|
- if param.is_a?(String) and param =~ /^:/
- hash.delete(param)
- param = param.sub(/^:/,'').intern
- hash[param] = value
- end
-
- if value.is_a?(String) and value =~ /^:/
- value = value.sub(/^:/,'').intern
- hash[param] = value
- end
- end
- end
- target.write(str)
- assert_nothing_raised("could not parse #{file}") do
- @provider.prefetch
- end
- records = @provider.send(:instance_variable_get, "@records")
-
- args.zip(records) do |should, sis|
- # Make the values a bit more equal.
- should[:target] = @me
- should[:ensure] = :present
- #should[:environment] ||= []
- should[:on_disk] = true
- is = sis.dup
- sis.dup.each do |p,v|
- is.delete(p) if v == :absent
- end
-
- assert_equal(
- should, is,
+ assert_equal(
+ "# Puppet Name: #{name}\n30 * * * * date > /dev/null", str,
- "Did not parse #{file} correctly")
- end
+ "Cron did not generate correctly")
+ end
+
+ # Test that comments are correctly retained
+ def test_retain_comments
+ str = "# this is a comment\n#and another comment\n"
+ user = "fakeuser"
+ records = nil
+ @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
+ target = @provider.target_object(user)
+ target.write(str)
+ assert_nothing_raised {
+ @provider.prefetch
+ }
- assert_nothing_raised("could not generate #{file}") do
- @provider.flush_target(@me)
- end
+ assert_nothing_raised {
+ newstr = @provider.flush_target(user)
+ assert(target.read.include?(str), "Comments were lost")
+ }
+ end
- assert_equal(str, target.read, "#{file} changed")
- @provider.clear
- end
- end
+ def test_simpleparsing
+ @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
+ text = "5 1,2 * 1 0 /bin/echo funtest"
- # A simple test to see if we can load the cron from disk.
- def test_load
- setme
- records = nil
- assert_nothing_raised {
- records = @provider.retrieve(@me)
- }
- assert_instance_of(Array, records, "did not get correct response")
- end
+ records = nil
+ assert_nothing_raised {
+ records = @provider.parse(text)
+ }
- # Test that a cron job turns out as expected, by creating one and generating
- # it directly
- def test_simple_to_cron
- # make the cron
- setme
-
- name = "yaytest"
- args = {:name => name,
- :command => "date > /dev/null",
- :minute => "30",
- :user => @me,
- :record_type => :crontab
- }
- # generate the text
- str = nil
- assert_nothing_raised {
- str = @provider.to_line(args)
- }
-
-
- assert_equal(
- "# Puppet Name: #{name}\n30 * * * * date > /dev/null", str,
-
- "Cron did not generate correctly")
- end
+ should = {
+ :minute => %w{5},
+ :hour => %w{1 2},
+ :monthday => :absent,
+ :month => %w{1},
+ :weekday => %w{0},
+ :command => "/bin/echo funtest"
+ }
- # Test that comments are correctly retained
- def test_retain_comments
- str = "# this is a comment\n#and another comment\n"
- user = "fakeuser"
- records = nil
- @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
- target = @provider.target_object(user)
- target.write(str)
- assert_nothing_raised {
- @provider.prefetch
- }
-
- assert_nothing_raised {
- newstr = @provider.flush_target(user)
- assert(target.read.include?(str), "Comments were lost")
- }
- end
+ is = records.shift
+ assert(is, "Did not get record")
- def test_simpleparsing
- @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
- text = "5 1,2 * 1 0 /bin/echo funtest"
-
- records = nil
- assert_nothing_raised {
- records = @provider.parse(text)
- }
-
- should = {
- :minute => %w{5},
- :hour => %w{1 2},
- :monthday => :absent,
- :month => %w{1},
- :weekday => %w{0},
- :command => "/bin/echo funtest"
- }
-
- is = records.shift
- assert(is, "Did not get record")
-
- should.each do |p, v|
- assert_equal(v, is[p], "did not parse #{p} correctly")
- end
+ should.each do |p, v|
+ assert_equal(v, is[p], "did not parse #{p} correctly")
end
+ end
- # Make sure we can create a cron in an empty tab.
- # LAK:FIXME This actually modifies the user's crontab,
- # which is pretty heinous.
- def test_mkcron_if_empty
- setme
- @provider.filetype = @oldfiletype
-
- records = @provider.retrieve(@me)
+ # Make sure we can create a cron in an empty tab.
+ # LAK:FIXME This actually modifies the user's crontab,
+ # which is pretty heinous.
+ def test_mkcron_if_empty
+ setme
+ @provider.filetype = @oldfiletype
- target = @provider.target_object(@me)
+ records = @provider.retrieve(@me)
- cleanup do
- if records.length == 0
- target.remove
- else
- target.write(@provider.to_file(records))
- end
- end
+ target = @provider.target_object(@me)
- # Now get rid of it
- assert_nothing_raised("Could not remove cron tab") do
- target.remove
- end
+ cleanup do
+ if records.length == 0
+ target.remove
+ else
+ target.write(@provider.to_file(records))
+ end
+ end
- @provider.flush :target => @me, :command => "/do/something",
- :record_type => :crontab
- created = @provider.retrieve(@me)
- assert(created.detect { |r| r[:command] == "/do/something" }, "Did not create cron tab")
+ # Now get rid of it
+ assert_nothing_raised("Could not remove cron tab") do
+ target.remove
end
- # Make sure we correctly bidirectionally parse things.
- def test_records_and_strings
- @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
- setme
-
- target = @provider.target_object(@me)
-
- [
- "* * * * * /some/command",
- "0,30 * * * * /some/command",
- "0-30 * * * * /some/command",
- "# Puppet Name: name\n0-30 * * * * /some/command",
- "# Puppet Name: name\nVAR=VALUE\n0-30 * * * * /some/command",
- "# Puppet Name: name\nVAR=VALUE\nC=D\n0-30 * * * * /some/command",
- "0 * * * * /some/command"
- ].each do |str|
- @provider.initvars
- str += "\n"
- target.write(str)
-
- assert_equal(
- str, target.read,
+ @provider.flush :target => @me, :command => "/do/something",
+ :record_type => :crontab
+ created = @provider.retrieve(@me)
+ assert(created.detect { |r| r[:command] == "/do/something" }, "Did not create cron tab")
+ end
+
+ # Make sure we correctly bidirectionally parse things.
+ def test_records_and_strings
+ @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
+ setme
+
+ target = @provider.target_object(@me)
+
+ [
+ "* * * * * /some/command",
+ "0,30 * * * * /some/command",
+ "0-30 * * * * /some/command",
+ "# Puppet Name: name\n0-30 * * * * /some/command",
+ "# Puppet Name: name\nVAR=VALUE\n0-30 * * * * /some/command",
+ "# Puppet Name: name\nVAR=VALUE\nC=D\n0-30 * * * * /some/command",
+ "0 * * * * /some/command"
+ ].each do |str|
+ @provider.initvars
+ str += "\n"
+ target.write(str)
+
+ assert_equal(
+ str, target.read,
- "Did not write correctly")
- assert_nothing_raised("Could not prefetch with #{str.inspect}") do
- @provider.prefetch
- end
- assert_nothing_raised("Could not flush with #{str.inspect}") do
- @provider.flush_target(@me)
- end
+ "Did not write correctly")
+ assert_nothing_raised("Could not prefetch with #{str.inspect}") do
+ @provider.prefetch
+ end
+ assert_nothing_raised("Could not flush with #{str.inspect}") do
+ @provider.flush_target(@me)
+ end
- assert_equal(
- str, target.read,
+ assert_equal(
+ str, target.read,
- "Changed in read/write")
+ "Changed in read/write")
- @provider.clear
- end
+ @provider.clear
end
+ end
- # Test that a specified cron job will be matched against an existing job
- # with no name, as long as all fields match
- def test_matchcron
- mecron = "0,30 * * * * date
+ # Test that a specified cron job will be matched against an existing job
+ # with no name, as long as all fields match
+ def test_matchcron
+ mecron = "0,30 * * * * date
- * * * * * funtest
- # a comment
- 0,30 * * 1 * date
- "
+ * * * * * funtest
+ # a comment
+ 0,30 * * 1 * date
+ "
- youcron = "0,30 * * * * date
+ youcron = "0,30 * * * * date
- * * * * * yaytest
- # a comment
- 0,30 * * 1 * fooness
- "
- setme
- @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
- you = "you"
+ * * * * * yaytest
+ # a comment
+ 0,30 * * 1 * fooness
+ "
+ setme
+ @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
+ you = "you"
- # Write the same tab to multiple targets
- @provider.target_object(@me).write(mecron.gsub(/^\s+/, ''))
- @provider.target_object(you).write(youcron.gsub(/^\s+/, ''))
+ # Write the same tab to multiple targets
+ @provider.target_object(@me).write(mecron.gsub(/^\s+/, ''))
+ @provider.target_object(you).write(youcron.gsub(/^\s+/, ''))
- # Now make some crons that should match
- matchers = [
+ # Now make some crons that should match
+ matchers = [
- @type.new(
+ @type.new(
- :name => "yaycron",
- :minute => [0, 30],
- :command => "date",
+ :name => "yaycron",
+ :minute => [0, 30],
+ :command => "date",
- :user => @me
- ),
+ :user => @me
+ ),
- @type.new(
+ @type.new(
- :name => "youtest",
- :command => "yaytest",
+ :name => "youtest",
+ :command => "yaytest",
- :user => you
- )
- ]
+ :user => you
+ )
+ ]
- nonmatchers = [
+ nonmatchers = [
- @type.new(
+ @type.new(
- :name => "footest",
- :minute => [0, 30],
- :hour => 1,
- :command => "fooness",
+ :name => "footest",
+ :minute => [0, 30],
+ :hour => 1,
+ :command => "fooness",
- :user => @me # wrong target
- ),
+ :user => @me # wrong target
+ ),
- @type.new(
+ @type.new(
- :name => "funtest2",
- :command => "funtest",
+ :name => "funtest2",
+ :command => "funtest",
- :user => you # wrong target for this cron
- )
- ]
-
- # Create another cron so we prefetch two of them
- @type.new(:name => "testing", :minute => 30, :command => "whatever", :user => "you")
-
- assert_nothing_raised("Could not prefetch cron") do
- @provider.prefetch([matchers, nonmatchers].flatten.inject({}) { |crons, cron| crons[cron.name] = cron; crons })
- end
+ :user => you # wrong target for this cron
+ )
+ ]
- matchers.each do |cron|
- assert_equal(:present, cron.provider.ensure, "Cron #{cron.name} was not matched")
- if value = cron.value(:minute) and value == "*"
- value = :absent
- end
- assert_equal(value, cron.provider.minute, "Minutes were not retrieved, so cron was not matched")
- assert_equal(cron.value(:target), cron.provider.target, "Cron #{cron.name} was matched from the wrong target")
- end
+ # Create another cron so we prefetch two of them
+ @type.new(:name => "testing", :minute => 30, :command => "whatever", :user => "you")
- nonmatchers.each do |cron|
- assert_equal(:absent, cron.provider.ensure, "Cron #{cron.name} was incorrectly matched")
- end
+ assert_nothing_raised("Could not prefetch cron") do
+ @provider.prefetch([matchers, nonmatchers].flatten.inject({}) { |crons, cron| crons[cron.name] = cron; crons })
end
- def test_data
- setme
- @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
- target = @provider.target_object(@me)
- fakedata("data/providers/cron/examples").each do |file|
- text = File.read(file)
- target.write(text)
-
- assert_nothing_raised("Could not parse #{file}") do
- @provider.prefetch
- end
- # mark the provider modified
- @provider.modified(@me)
-
- # and zero the text
- target.write("")
-
- result = nil
- assert_nothing_raised("Could not generate #{file}") do
- @provider.flush_target(@me)
- end
-
- # Ignore whitespace differences, since those don't affect function.
- modtext = text.gsub(/[ \t]+/, " ")
- modtarget = target.read.gsub(/[ \t]+/, " ")
- assert_equal(modtext, modtarget, "File was not rewritten the same")
-
- @provider.clear
- end
+ matchers.each do |cron|
+ assert_equal(:present, cron.provider.ensure, "Cron #{cron.name} was not matched")
+ if value = cron.value(:minute) and value == "*"
+ value = :absent
+ end
+ assert_equal(value, cron.provider.minute, "Minutes were not retrieved, so cron was not matched")
+ assert_equal(cron.value(:target), cron.provider.target, "Cron #{cron.name} was matched from the wrong target")
end
- # Match freebsd's annoying @daily stuff.
- def test_match_freebsd_special
- @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
- setme
-
- target = @provider.target_object(@me)
-
- [
- "@daily /some/command",
- "@daily /some/command more"
- ].each do |str|
- @provider.initvars
- str += "\n"
- target.write(str)
- assert_nothing_raised("Could not prefetch with #{str.inspect}") do
- @provider.prefetch
- end
- records = @provider.send(:instance_variable_get, "@records")
- records.each do |r|
-
- assert_equal(
- :freebsd_special, r[:record_type],
+ nonmatchers.each do |cron|
+ assert_equal(:absent, cron.provider.ensure, "Cron #{cron.name} was incorrectly matched")
+ end
+ end
+
+ def test_data
+ setme
+ @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
+ target = @provider.target_object(@me)
+ fakedata("data/providers/cron/examples").each do |file|
+ text = File.read(file)
+ target.write(text)
+
+ assert_nothing_raised("Could not parse #{file}") do
+ @provider.prefetch
+ end
+ # mark the provider modified
+ @provider.modified(@me)
+
+ # and zero the text
+ target.write("")
+
+ result = nil
+ assert_nothing_raised("Could not generate #{file}") do
+ @provider.flush_target(@me)
+ end
+
+ # Ignore whitespace differences, since those don't affect function.
+ modtext = text.gsub(/[ \t]+/, " ")
+ modtarget = target.read.gsub(/[ \t]+/, " ")
+ assert_equal(modtext, modtarget, "File was not rewritten the same")
+
+ @provider.clear
+ end
+ end
+
+ # Match freebsd's annoying @daily stuff.
+ def test_match_freebsd_special
+ @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
+ setme
+
+ target = @provider.target_object(@me)
+
+ [
+ "@daily /some/command",
+ "@daily /some/command more"
+ ].each do |str|
+ @provider.initvars
+ str += "\n"
+ target.write(str)
+ assert_nothing_raised("Could not prefetch with #{str.inspect}") do
+ @provider.prefetch
+ end
+ records = @provider.send(:instance_variable_get, "@records")
+ records.each do |r|
+
+ assert_equal(
+ :freebsd_special, r[:record_type],
- "Did not create lines as freebsd lines")
- end
- assert_nothing_raised("Could not flush with #{str.inspect}") do
- @provider.flush_target(@me)
- end
+ "Did not create lines as freebsd lines")
+ end
+ assert_nothing_raised("Could not flush with #{str.inspect}") do
+ @provider.flush_target(@me)
+ end
- assert_equal(
- str, target.read,
+ assert_equal(
+ str, target.read,
- "Changed in read/write")
+ "Changed in read/write")
- @provider.clear
- end
+ @provider.clear
end
+ end
- # #707
- def test_write_freebsd_special
- assert_equal(@provider.to_line(:record_type => :crontab, :ensure => :present, :special => "reboot", :command => "/bin/echo something"), "@reboot /bin/echo something")
- end
+ # #707
+ def test_write_freebsd_special
+ assert_equal(@provider.to_line(:record_type => :crontab, :ensure => :present, :special => "reboot", :command => "/bin/echo something"), "@reboot /bin/echo something")
+ end
- def test_prefetch
- cron = @type.new :command => "/bin/echo yay", :name => "test", :hour => 4
+ def test_prefetch
+ cron = @type.new :command => "/bin/echo yay", :name => "test", :hour => 4
- assert_nothing_raised("Could not prefetch cron") do
- cron.provider.class.prefetch("test" => cron)
- end
+ assert_nothing_raised("Could not prefetch cron") do
+ cron.provider.class.prefetch("test" => cron)
end
+ end
- # Testing #669.
- def test_environment_settings
- @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
- setme
+ # Testing #669.
+ def test_environment_settings
+ @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
+ setme
- target = @provider.target_object(@me)
+ target = @provider.target_object(@me)
- # First with no env settings
- resource = @type.new :command => "/bin/echo yay", :name => "test", :hour => 4
- cron = resource.provider
+ # First with no env settings
+ resource = @type.new :command => "/bin/echo yay", :name => "test", :hour => 4
+ cron = resource.provider
- cron.ensure = :present
- cron.command = "/bin/echo yay"
- cron.hour = %w{4}
- cron.flush
+ cron.ensure = :present
+ cron.command = "/bin/echo yay"
+ cron.hour = %w{4}
+ cron.flush
- result = target.read
- assert_equal("# Puppet Name: test\n* 4 * * * /bin/echo yay\n", result, "Did not write cron out correctly")
+ result = target.read
+ assert_equal("# Puppet Name: test\n* 4 * * * /bin/echo yay\n", result, "Did not write cron out correctly")
- # Now set the env
- cron.environment = "TEST=foo"
- cron.flush
+ # Now set the env
+ cron.environment = "TEST=foo"
+ cron.flush
- result = target.read
- assert_equal("# Puppet Name: test\nTEST=foo\n* 4 * * * /bin/echo yay\n", result, "Did not write out environment setting")
+ result = target.read
+ assert_equal("# Puppet Name: test\nTEST=foo\n* 4 * * * /bin/echo yay\n", result, "Did not write out environment setting")
- # Modify it
- cron.environment = ["TEST=foo", "BLAH=yay"]
- cron.flush
+ # Modify it
+ cron.environment = ["TEST=foo", "BLAH=yay"]
+ cron.flush
- result = target.read
- assert_equal("# Puppet Name: test\nTEST=foo\nBLAH=yay\n* 4 * * * /bin/echo yay\n", result, "Did not write out environment setting")
+ result = target.read
+ assert_equal("# Puppet Name: test\nTEST=foo\nBLAH=yay\n* 4 * * * /bin/echo yay\n", result, "Did not write out environment setting")
- # And remove it
- cron.environment = :absent
- cron.flush
+ # And remove it
+ cron.environment = :absent
+ cron.flush
- result = target.read
- assert_equal("# Puppet Name: test\n* 4 * * * /bin/echo yay\n", result, "Did not write out environment setting")
- end
+ result = target.read
+ assert_equal("# Puppet Name: test\n* 4 * * * /bin/echo yay\n", result, "Did not write out environment setting")
+ end
- # Testing #1216
- def test_strange_lines
- @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
- text = " 5 \t\t 1,2 * 1 0 /bin/echo funtest"
-
- records = nil
- assert_nothing_raised {
- records = @provider.parse(text)
- }
-
- should = {
- :minute => %w{5},
- :hour => %w{1 2},
- :monthday => :absent,
- :month => %w{1},
- :weekday => %w{0},
- :command => "/bin/echo funtest"
- }
-
- is = records.shift
- assert(is, "Did not get record")
-
- should.each do |p, v|
- assert_equal(v, is[p], "did not parse #{p} correctly")
- end
+ # Testing #1216
+ def test_strange_lines
+ @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
+ text = " 5 \t\t 1,2 * 1 0 /bin/echo funtest"
+
+ records = nil
+ assert_nothing_raised {
+ records = @provider.parse(text)
+ }
+
+ should = {
+ :minute => %w{5},
+ :hour => %w{1 2},
+ :monthday => :absent,
+ :month => %w{1},
+ :weekday => %w{0},
+ :command => "/bin/echo funtest"
+ }
+
+ is = records.shift
+ assert(is, "Did not get record")
+
+ should.each do |p, v|
+ assert_equal(v, is[p], "did not parse #{p} correctly")
end
+ end
end
diff --git a/test/ral/providers/group.rb b/test/ral/providers/group.rb
index 829e7df..8a08605 100755
--- a/test/ral/providers/group.rb
+++ b/test/ral/providers/group.rb
@@ -6,237 +6,237 @@ require 'puppettest'
require 'etc'
class TestGroupProvider < Test::Unit::TestCase
- include PuppetTest
- def setup
- super
- @@tmpgroups = []
- @provider = nil
- assert_nothing_raised {
- @provider = Puppet::Type.type(:group).defaultprovider
- }
-
- assert(@provider, "Could not find default group provider")
- assert(@provider.name != :fake, "Got a fake provider")
+ include PuppetTest
+ def setup
+ super
+ @@tmpgroups = []
+ @provider = nil
+ assert_nothing_raised {
+ @provider = Puppet::Type.type(:group).defaultprovider
+ }
+
+ assert(@provider, "Could not find default group provider")
+ assert(@provider.name != :fake, "Got a fake provider")
+ end
+
+ def teardown
+ super
+ @@tmpgroups.each { |group|
+ remove(group) unless missing?(group)
+ }
+ end
+
+ def mkgroup(name, hash = {})
+ fakeresource = stub 'group', :allowdupe? => false, :name => name
+ fakeresource.stubs(:[]).returns nil
+ fakeresource.stubs(:should).returns nil
+ fakeresource.stubs(:[]).with(:name).returns name
+ hash.each do |name, val|
+ fakeresource.stubs(:should).with(name).returns val
+ fakeresource.stubs(:[]).with(name).returns val
end
+ group = nil
+ assert_nothing_raised {
+ group = @provider.new(fakeresource)
+ }
+ assert(group, "Could not create provider group")
- def teardown
- super
- @@tmpgroups.each { |group|
- remove(group) unless missing?(group)
- }
- end
-
- def mkgroup(name, hash = {})
- fakeresource = stub 'group', :allowdupe? => false, :name => name
- fakeresource.stubs(:[]).returns nil
- fakeresource.stubs(:should).returns nil
- fakeresource.stubs(:[]).with(:name).returns name
- hash.each do |name, val|
- fakeresource.stubs(:should).with(name).returns val
- fakeresource.stubs(:[]).with(name).returns val
- end
- group = nil
- assert_nothing_raised {
- group = @provider.new(fakeresource)
- }
- assert(group, "Could not create provider group")
+ group
+ end
- group
- end
+ case Facter["operatingsystem"].value
+ when "Darwin"
+ def missing?(group)
+ output = %x{nidump -r /groups/#{group} / 2>/dev/null}.chomp
- case Facter["operatingsystem"].value
- when "Darwin"
- def missing?(group)
- output = %x{nidump -r /groups/#{group} / 2>/dev/null}.chomp
-
- return output == ""
-
- assert_equal("", output, "Group #{group} is present:\n#{output}")
- end
-
- def gid(name)
- %x{nireport / /groups name gid}.split("\n").each { |line|
- group, id = line.chomp.split(/\s+/)
- assert(id =~ /^-?\d+$/, "Group id #{id.inspect} for #{group} is not a number")
- if group == name
- return Integer(id)
- end
- }
-
- nil
- end
-
- def remove(group)
- system("niutil -destroy / /groups/#{group}")
- end
- else
- def missing?(group)
- obj = Etc.getgrnam(group)
- return false
- rescue ArgumentError
- return true
- end
+ return output == ""
- def gid(name)
- assert_nothing_raised {
- obj = Etc.getgrnam(name)
- return obj.gid
- }
+ assert_equal("", output, "Group #{group} is present:\n#{output}")
+ end
- nil
+ def gid(name)
+ %x{nireport / /groups name gid}.split("\n").each { |line|
+ group, id = line.chomp.split(/\s+/)
+ assert(id =~ /^-?\d+$/, "Group id #{id.inspect} for #{group} is not a number")
+ if group == name
+ return Integer(id)
end
+ }
- def remove(group)
- system("groupdel #{group}")
- end
+ nil
end
- def groupnames
- %x{groups}.chomp.split(/ /)
+ def remove(group)
+ system("niutil -destroy / /groups/#{group}")
end
-
- def groupids
- Process.groups
+ else
+ def missing?(group)
+ obj = Etc.getgrnam(group)
+ return false
+ rescue ArgumentError
+ return true
end
- def attrtest_ensure(group)
- old = group.ensure
- assert_nothing_raised {
- group.delete
- }
-
- assert(!group.exists?, "Group was not deleted")
+ def gid(name)
+ assert_nothing_raised {
+ obj = Etc.getgrnam(name)
+ return obj.gid
+ }
- assert_nothing_raised {
- group.create
- }
- assert(group.exists?, "Group was not created")
+ nil
+ end
- unless old == :present
- assert_nothing_raised {
- group.delete
- }
- end
+ def remove(group)
+ system("groupdel #{group}")
end
+ end
- def attrtest_gid(group)
- old = gid(group.name)
-
- newgid = old
- while true
- newgid += 1
-
- if newgid - old > 1000
- $stderr.puts "Could not find extra test UID"
- return
- end
- begin
- Etc.getgrgid(newgid)
- rescue ArgumentError => detail
- break
- end
- end
+ def groupnames
+ %x{groups}.chomp.split(/ /)
+ end
- assert_nothing_raised("Failed to change group id") {
- group.gid = newgid
- }
+ def groupids
+ Process.groups
+ end
- curgid = nil
- assert_nothing_raised {
- curgid = gid(group.name)
- }
+ def attrtest_ensure(group)
+ old = group.ensure
+ assert_nothing_raised {
+ group.delete
+ }
- assert_equal(newgid, curgid, "GID was not changed")
- # Refresh
- group.getinfo(true)
- assert_equal(newgid, group.gid, "Object got wrong gid")
+ assert(!group.exists?, "Group was not deleted")
- assert_nothing_raised("Failed to change group id") {
- group.gid = old
- }
- end
+ assert_nothing_raised {
+ group.create
+ }
+ assert(group.exists?, "Group was not created")
- # Iterate over each of our groups and try to grab the gid.
- def test_ownprovidergroups
- groupnames.each { |group|
- gobj = nil
- comp = nil
- fakeresource = fakeresource(:group, group)
- assert_nothing_raised {
- gobj = @provider.new(fakeresource)
- }
-
- assert(gobj.gid, "Failed to retrieve gid")
- }
+ unless old == :present
+ assert_nothing_raised {
+ group.delete
+ }
+ end
+ end
+
+ def attrtest_gid(group)
+ old = gid(group.name)
+
+ newgid = old
+ while true
+ newgid += 1
+
+ if newgid - old > 1000
+ $stderr.puts "Could not find extra test UID"
+ return
+ end
+ begin
+ Etc.getgrgid(newgid)
+ rescue ArgumentError => detail
+ break
+ end
end
- if Puppet.features.root?
- def test_mkgroup
- gobj = nil
- comp = nil
- name = "pptestgr"
- assert(missing?(name), "Group #{name} is still present")
- group = mkgroup(name)
-
- @@tmpgroups << name
-
- assert(group.respond_to?(:addcmd), "no respondo?")
- assert_nothing_raised {
- group.create
- }
- assert(!missing?(name), "Group #{name} is missing")
-
- tests = Puppet::Type.type(:group).validproperties
-
- tests.each { |test|
- if self.respond_to?("attrtest_#{test}")
- self.send("attrtest_#{test}", group)
- else
- $stderr.puts "Not testing attr #{test} of group"
- end
- }
-
- assert_nothing_raised {
- group.delete
- }
+ assert_nothing_raised("Failed to change group id") {
+ group.gid = newgid
+ }
+
+ curgid = nil
+ assert_nothing_raised {
+ curgid = gid(group.name)
+ }
+
+ assert_equal(newgid, curgid, "GID was not changed")
+ # Refresh
+ group.getinfo(true)
+ assert_equal(newgid, group.gid, "Object got wrong gid")
+
+ assert_nothing_raised("Failed to change group id") {
+ group.gid = old
+ }
+ end
+
+ # Iterate over each of our groups and try to grab the gid.
+ def test_ownprovidergroups
+ groupnames.each { |group|
+ gobj = nil
+ comp = nil
+ fakeresource = fakeresource(:group, group)
+ assert_nothing_raised {
+ gobj = @provider.new(fakeresource)
+ }
+
+ assert(gobj.gid, "Failed to retrieve gid")
+ }
+ end
+
+ if Puppet.features.root?
+ def test_mkgroup
+ gobj = nil
+ comp = nil
+ name = "pptestgr"
+ assert(missing?(name), "Group #{name} is still present")
+ group = mkgroup(name)
+
+ @@tmpgroups << name
+
+ assert(group.respond_to?(:addcmd), "no respondo?")
+ assert_nothing_raised {
+ group.create
+ }
+ assert(!missing?(name), "Group #{name} is missing")
+
+ tests = Puppet::Type.type(:group).validproperties
+
+ tests.each { |test|
+ if self.respond_to?("attrtest_#{test}")
+ self.send("attrtest_#{test}", group)
+ else
+ $stderr.puts "Not testing attr #{test} of group"
end
+ }
- # groupadd -o is broken in FreeBSD.
- unless Facter["operatingsystem"].value == "FreeBSD"
- def test_duplicateIDs
- group1 = mkgroup("group1", :gid => 125)
-
- @@tmpgroups << "group1"
- @@tmpgroups << "group2"
- # Create the first group
- assert_nothing_raised {
- group1.create
- }
-
- # Not all OSes fail here, so we can't test that it doesn't work with
- # it off, only that it does work with it on.
- group2 = mkgroup("group2", :gid => 125)
- group2.resource.stubs(:allowdupe?).returns true
-
- # Now create the second group
- assert_nothing_raised {
- group2.create
- }
- assert_equal(:present, group2.ensure, "Group did not get created")
- end
- end
- else
- $stderr.puts "Not running as root; skipping group creation tests."
+ assert_nothing_raised {
+ group.delete
+ }
end
- def test_autogen
- provider = nil
- group = Puppet::Type.type(:group).new(:name => nonrootgroup.name)
- provider = group.provider
- assert(provider, "did not get provider")
-
- # Everyone should be able to autogenerate a uid
- assert_instance_of(Fixnum, provider.autogen(:gid))
+ # groupadd -o is broken in FreeBSD.
+ unless Facter["operatingsystem"].value == "FreeBSD"
+ def test_duplicateIDs
+ group1 = mkgroup("group1", :gid => 125)
+
+ @@tmpgroups << "group1"
+ @@tmpgroups << "group2"
+ # Create the first group
+ assert_nothing_raised {
+ group1.create
+ }
+
+ # Not all OSes fail here, so we can't test that it doesn't work with
+ # it off, only that it does work with it on.
+ group2 = mkgroup("group2", :gid => 125)
+ group2.resource.stubs(:allowdupe?).returns true
+
+ # Now create the second group
+ assert_nothing_raised {
+ group2.create
+ }
+ assert_equal(:present, group2.ensure, "Group did not get created")
+ end
end
+ else
+ $stderr.puts "Not running as root; skipping group creation tests."
+ end
+
+ def test_autogen
+ provider = nil
+ group = Puppet::Type.type(:group).new(:name => nonrootgroup.name)
+ provider = group.provider
+ assert(provider, "did not get provider")
+
+ # Everyone should be able to autogenerate a uid
+ assert_instance_of(Fixnum, provider.autogen(:gid))
+ end
end
diff --git a/test/ral/providers/host/parsed.rb b/test/ral/providers/host/parsed.rb
index 5b21abc..c2367d5 100755
--- a/test/ral/providers/host/parsed.rb
+++ b/test/ral/providers/host/parsed.rb
@@ -8,86 +8,86 @@ require 'puppettest/fileparsing'
require 'test/unit'
class TestParsedHostProvider < Test::Unit::TestCase
- include PuppetTest
- include PuppetTest::FileParsing
-
- def setup
- super
- @provider = Puppet::Type.type(:host).provider(:parsed)
-
- @oldfiletype = @provider.filetype
+ include PuppetTest
+ include PuppetTest::FileParsing
+
+ def setup
+ super
+ @provider = Puppet::Type.type(:host).provider(:parsed)
+
+ @oldfiletype = @provider.filetype
+ end
+
+ def teardown
+ Puppet::Util::FileType.filetype(:ram).clear
+ @provider.filetype = @oldfiletype
+ @provider.clear
+ super
+ end
+
+ def test_provider_existence
+ assert(@provider, "Could not retrieve provider")
+ end
+
+ # Here we just create a fake host type that answers to all of the methods
+ # but does not modify our actual system.
+ def mkfaketype
+ @provider.filetype = Puppet::Util::FileType.filetype(:ram)
+ end
+
+ def mkhosthash
+ if defined?(@hcount)
+ @hcount += 1
+ else
+ @hcount = 1
end
- def teardown
- Puppet::Util::FileType.filetype(:ram).clear
- @provider.filetype = @oldfiletype
- @provider.clear
- super
- end
+ return {
+ :name => "fakehost#{@hcount}",
+ :ip => "192.168.27.#{@hcount}",
+ :host_aliases => ["alias#{@hcount}"],
+ :ensure => :present
+ }
+ end
- def test_provider_existence
- assert(@provider, "Could not retrieve provider")
- end
+ def mkhost
+ hash = mkhosthash
- # Here we just create a fake host type that answers to all of the methods
- # but does not modify our actual system.
- def mkfaketype
- @provider.filetype = Puppet::Util::FileType.filetype(:ram)
- end
+ fakeresource = fakeresource(:host, hash[:name])
- def mkhosthash
- if defined?(@hcount)
- @hcount += 1
- else
- @hcount = 1
- end
-
- return {
- :name => "fakehost#{@hcount}",
- :ip => "192.168.27.#{@hcount}",
- :host_aliases => ["alias#{@hcount}"],
- :ensure => :present
- }
- end
+ host = @provider.new(fakeresource)
- def mkhost
- hash = mkhosthash
-
- fakeresource = fakeresource(:host, hash[:name])
-
- host = @provider.new(fakeresource)
-
- assert(host, "Could not create provider host")
- hash.each do |name, val|
- host.send(name.to_s + "=", val)
- end
-
- host
+ assert(host, "Could not create provider host")
+ hash.each do |name, val|
+ host.send(name.to_s + "=", val)
end
- # Make sure we convert both directlys correctly using a simple host.
- def test_basic_isomorphism
- hash = {:record_type => :parsed, :name => "myhost", :ip => "192.168.43.56", :host_aliases => %w{another host}}
+ host
+ end
- str = nil
- assert_nothing_raised do
- str = @provider.to_line(hash)
- end
+ # Make sure we convert both directlys correctly using a simple host.
+ def test_basic_isomorphism
+ hash = {:record_type => :parsed, :name => "myhost", :ip => "192.168.43.56", :host_aliases => %w{another host}}
- assert_equal("192.168.43.56\tmyhost\tanother\thost", str)
+ str = nil
+ assert_nothing_raised do
+ str = @provider.to_line(hash)
+ end
- newhash = nil
- assert_nothing_raised do
- newhash = @provider.parse(str).shift
- end
+ assert_equal("192.168.43.56\tmyhost\tanother\thost", str)
- assert_equal(hash, newhash)
+ newhash = nil
+ assert_nothing_raised do
+ newhash = @provider.parse(str).shift
end
- # Make sure parsing gets comments, blanks, and hosts
- def test_blanks_and_comments
- mkfaketype
- text = %{# comment one
+ assert_equal(hash, newhash)
+ end
+
+ # Make sure parsing gets comments, blanks, and hosts
+ def test_blanks_and_comments
+ mkfaketype
+ text = %{# comment one
192.168.43.56\tmyhost\tanother\thost
@@ -95,140 +95,140 @@ class TestParsedHostProvider < Test::Unit::TestCase
192.168.43.57\tanotherhost
}
- instances = nil
- assert_nothing_raised do
- instances = @provider.parse(text)
- end
+ instances = nil
+ assert_nothing_raised do
+ instances = @provider.parse(text)
+ end
- assert_equal(
- [
- {:record_type => :comment, :line => "# comment one"},
- {:record_type => :blank, :line => ""},
- {:record_type => :parsed, :name => "myhost", :ip => "192.168.43.56", :host_aliases => %w{another host}},
- {:record_type => :blank, :line => " "},
- {:record_type => :comment, :line => "# another comment"},
+ assert_equal(
+ [
+ {:record_type => :comment, :line => "# comment one"},
+ {:record_type => :blank, :line => ""},
+ {:record_type => :parsed, :name => "myhost", :ip => "192.168.43.56", :host_aliases => %w{another host}},
+ {:record_type => :blank, :line => " "},
+ {:record_type => :comment, :line => "# another comment"},
- {:record_type => :parsed, :name => "anotherhost", :ip => "192.168.43.57", :host_aliases => []}
- ], instances)
+ {:record_type => :parsed, :name => "anotherhost", :ip => "192.168.43.57", :host_aliases => []}
+ ], instances)
- newtext = nil
- assert_nothing_raised do
- newtext = @provider.to_file(instances).gsub(/^# HEADER.+\n/, '')
- end
+ newtext = nil
+ assert_nothing_raised do
+ newtext = @provider.to_file(instances).gsub(/^# HEADER.+\n/, '')
+ end
- assert_equal(text, newtext)
+ assert_equal(text, newtext)
+ end
+
+ def test_simplehost
+ mkfaketype
+ @provider.default_target = :yayness
+ file = @provider.target_object(:yayness)
+
+ # Start out with no content.
+ assert_nothing_raised {
+ assert_equal([], @provider.parse(file.read))
+ }
+
+ # Now create a provider
+ host = nil
+ assert_nothing_raised {
+ host = mkhost
+ }
+
+ # Make sure we're still empty
+ assert_nothing_raised {
+ assert_equal([], @provider.parse(file.read))
+ }
+
+ # Try storing it
+ assert_nothing_raised do
+ host.flush
end
- def test_simplehost
- mkfaketype
- @provider.default_target = :yayness
- file = @provider.target_object(:yayness)
-
- # Start out with no content.
- assert_nothing_raised {
- assert_equal([], @provider.parse(file.read))
- }
-
- # Now create a provider
- host = nil
- assert_nothing_raised {
- host = mkhost
- }
-
- # Make sure we're still empty
- assert_nothing_raised {
- assert_equal([], @provider.parse(file.read))
- }
-
- # Try storing it
- assert_nothing_raised do
- host.flush
- end
-
- # Make sure we get the host back
- assert_nothing_raised {
-
- assert(
- file.read.include?(host.name),
+ # Make sure we get the host back
+ assert_nothing_raised {
+
+ assert(
+ file.read.include?(host.name),
- "Did not flush host to disk")
- }
+ "Did not flush host to disk")
+ }
- # Remove a single field and make sure it gets tossed
- name = host.host_aliases
- host.host_aliases = [:absent]
+ # Remove a single field and make sure it gets tossed
+ name = host.host_aliases
+ host.host_aliases = [:absent]
- assert_nothing_raised {
- host.flush
+ assert_nothing_raised {
+ host.flush
- assert(
- ! file.read.include?(name[0]),
+ assert(
+ ! file.read.include?(name[0]),
- "Did not remove host_aliases from disk")
- }
-
- # Make sure it throws up if we remove a required field
- host.ip = :absent
-
- assert_raise(ArgumentError) {
- host.flush
- }
-
- # Now remove the whole object
- host.ensure = :absent
- assert_nothing_raised {
- host.flush
- assert_equal([], @provider.parse(file.read))
- }
- end
-
- # Parse our sample data and make sure we regenerate it correctly.
- def test_hostsparse
- fakedata("data/types/hosts").each do |file| fakedataparse(file) end
+ "Did not remove host_aliases from disk")
+ }
+
+ # Make sure it throws up if we remove a required field
+ host.ip = :absent
+
+ assert_raise(ArgumentError) {
+ host.flush
+ }
+
+ # Now remove the whole object
+ host.ensure = :absent
+ assert_nothing_raised {
+ host.flush
+ assert_equal([], @provider.parse(file.read))
+ }
+ end
+
+ # Parse our sample data and make sure we regenerate it correctly.
+ def test_hostsparse
+ fakedata("data/types/hosts").each do |file| fakedataparse(file) end
+ end
+
+ # Make sure we can modify the file elsewhere and those modifications will
+ # get taken into account.
+ def test_modifyingfile
+ hostfile = tempfile
+ @provider.default_target = hostfile
+
+ file = @provider.target_object(hostfile)
+
+ hosts = []
+ 3.times {
+ h = mkhost
+ hosts << h
+ }
+
+ hosts.each do |host|
+ host.flush
end
- # Make sure we can modify the file elsewhere and those modifications will
- # get taken into account.
- def test_modifyingfile
- hostfile = tempfile
- @provider.default_target = hostfile
+ newhost = mkhost
+ hosts << newhost
- file = @provider.target_object(hostfile)
+ # Now store our new host
+ newhost.flush
- hosts = []
- 3.times {
- h = mkhost
- hosts << h
- }
+ # Verify we can retrieve that info
+ assert_nothing_raised("Could not retrieve after second write") {
+ @provider.prefetch
+ }
- hosts.each do |host|
- host.flush
- end
+ text = file.read
- newhost = mkhost
- hosts << newhost
+ instances = @provider.parse(text)
- # Now store our new host
- newhost.flush
-
- # Verify we can retrieve that info
- assert_nothing_raised("Could not retrieve after second write") {
- @provider.prefetch
- }
-
- text = file.read
-
- instances = @provider.parse(text)
-
- # And verify that we have data for everything
- hosts.each { |host|
- name = host.resource[:name]
- assert(text.include?(name), "Host #{name} is not in file")
- hash = host.property_hash
- assert(! hash.empty?, "Could not find host #{name}")
- assert(hash[:ip], "Could not find ip for host #{name}")
- }
- end
+ # And verify that we have data for everything
+ hosts.each { |host|
+ name = host.resource[:name]
+ assert(text.include?(name), "Host #{name} is not in file")
+ hash = host.property_hash
+ assert(! hash.empty?, "Could not find host #{name}")
+ assert(hash[:ip], "Could not find ip for host #{name}")
+ }
+ end
end
diff --git a/test/ral/providers/mailalias/aliases.rb b/test/ral/providers/mailalias/aliases.rb
index 8c2626e..0497528 100755
--- a/test/ral/providers/mailalias/aliases.rb
+++ b/test/ral/providers/mailalias/aliases.rb
@@ -6,50 +6,50 @@ require 'puppettest'
require 'puppettest/fileparsing'
class TestMailaliasAliasesProvider < Test::Unit::TestCase
- include PuppetTest
- include PuppetTest::FileParsing
-
- def setup
- super
- @provider = Puppet::Type.type(:mailalias).provider(:aliases)
-
- @oldfiletype = @provider.filetype
-
- @alias = mkalias
+ include PuppetTest
+ include PuppetTest::FileParsing
+
+ def setup
+ super
+ @provider = Puppet::Type.type(:mailalias).provider(:aliases)
+
+ @oldfiletype = @provider.filetype
+
+ @alias = mkalias
+ end
+
+ def teardown
+ Puppet::Util::FileType.filetype(:ram).clear
+ @provider.filetype = @oldfiletype
+ @provider.clear
+ super
+ end
+
+ def mkalias(name = "me")
+ if defined?(@pcount)
+ @pcount += 1
+ else
+ @pcount = 1
end
+ args = {
+ :name => name,
+ :recipient => %w{here there}
+ }
- def teardown
- Puppet::Util::FileType.filetype(:ram).clear
- @provider.filetype = @oldfiletype
- @provider.clear
- super
- end
+ fakeresource = fakeresource(:mailalias, args[:name])
- def mkalias(name = "me")
- if defined?(@pcount)
- @pcount += 1
- else
- @pcount = 1
- end
- args = {
- :name => name,
- :recipient => %w{here there}
- }
-
- fakeresource = fakeresource(:mailalias, args[:name])
-
- key = @provider.new(fakeresource)
- args.each do |p,v|
- key.send(p.to_s + "=", v)
- end
-
- key
+ key = @provider.new(fakeresource)
+ args.each do |p,v|
+ key.send(p.to_s + "=", v)
end
- def test_data_parsing_and_generating
- fakedata("data/types/mailalias").each { |file|
- fakedataparse(file)
- }
- end
+ key
+ end
+
+ def test_data_parsing_and_generating
+ fakedata("data/types/mailalias").each { |file|
+ fakedataparse(file)
+ }
+ end
end
diff --git a/test/ral/providers/nameservice.rb b/test/ral/providers/nameservice.rb
index 7b37cc5..967c59f 100755
--- a/test/ral/providers/nameservice.rb
+++ b/test/ral/providers/nameservice.rb
@@ -7,26 +7,26 @@ require 'puppet/provider/nameservice'
require 'facter'
class TestNameServiceProvider < Test::Unit::TestCase
- include PuppetTest::FileTesting
-
- def test_option
- klass = Class.new(Puppet::Provider::NameService)
- klass.resource_type = Puppet::Type.type(:user)
-
- val = nil
- assert_nothing_raised {
- val = klass.option(:home, :flag)
- }
-
- assert_nil(val, "Got an option")
-
- assert_nothing_raised {
- klass.options :home, :flag => "-d"
- }
- assert_nothing_raised {
- val = klass.option(:home, :flag)
- }
- assert_equal("-d", val, "Got incorrect option")
- end
+ include PuppetTest::FileTesting
+
+ def test_option
+ klass = Class.new(Puppet::Provider::NameService)
+ klass.resource_type = Puppet::Type.type(:user)
+
+ val = nil
+ assert_nothing_raised {
+ val = klass.option(:home, :flag)
+ }
+
+ assert_nil(val, "Got an option")
+
+ assert_nothing_raised {
+ klass.options :home, :flag => "-d"
+ }
+ assert_nothing_raised {
+ val = klass.option(:home, :flag)
+ }
+ assert_equal("-d", val, "Got incorrect option")
+ end
end
diff --git a/test/ral/providers/package.rb b/test/ral/providers/package.rb
index 6a8489c..9c5e0df 100755
--- a/test/ral/providers/package.rb
+++ b/test/ral/providers/package.rb
@@ -6,240 +6,240 @@ require 'puppettest'
require 'etc'
class TestPackageProvider < Test::Unit::TestCase
- include PuppetTest
-
- def setup
- super
- Puppet.info @method_name
- end
-
- # Load the testpackages hash.
- def self.load_test_packages
- require 'yaml'
- file = File.join(PuppetTest.datadir, "providers", "package", "testpackages.yaml")
- raise "Could not find file #{file}" unless FileTest.exists?(file)
- array = YAML::load(File.read(file)).collect { |hash|
- # Stupid ruby 1.8.1. YAML is sometimes broken such that
- # symbols end up being strings with the : in them.
- hash.each do |name, value|
- if name.is_a?(String) and name =~ /^:/
- hash.delete(name)
- name = name.sub(/^:/, '').intern
- hash[name] = value
- end
- if value.is_a?(String) and value =~ /^:/
- hash[name] = value.sub(/^:/, '').intern
- end
- end
- }
-
- array
- end
-
- def self.suitable_test_packages
- list = load_test_packages
- providers = {}
- Puppet::Type.type(:package).suitableprovider.each do |provider|
- providers[provider.name] = provider
- end
- facts = {}
- Facter.to_hash.each do |fact, value|
- facts[fact.to_s.downcase.intern] = value.to_s.downcase.intern
- end
- list.find_all { |hash| # First find the matching providers
- hash.include?(:provider) and providers.include?(hash[:provider])
- }.reject { |hash| # Then find matching fact sets
- facts.detect do |fact, value|
- # We're detecting unmatched facts, but we also want to
- # delete the facts so they don't show up later.
- if fval = hash[fact]
- hash.delete(fact)
- fval = [fval] unless fval.is_a?(Array)
- fval = fval.collect { |v| v.downcase.intern }
- ! fval.include?(value)
- end
- end
- }
- end
-
- def assert_absent(provider, msg = "package not absent")
- result = nil
- assert_nothing_raised("Could not query provider") do
- result = provider.query
- end
- if result.nil?
- assert_nil(result)
- elsif result.is_a?(Hash)
- assert (result[:ensure] == :absent or result[:ensure] == :purged), msg
- else
- raise "dunno how to handle #{result.inspect}"
- end
+ include PuppetTest
+
+ def setup
+ super
+ Puppet.info @method_name
+ end
+
+ # Load the testpackages hash.
+ def self.load_test_packages
+ require 'yaml'
+ file = File.join(PuppetTest.datadir, "providers", "package", "testpackages.yaml")
+ raise "Could not find file #{file}" unless FileTest.exists?(file)
+ array = YAML::load(File.read(file)).collect { |hash|
+ # Stupid ruby 1.8.1. YAML is sometimes broken such that
+ # symbols end up being strings with the : in them.
+ hash.each do |name, value|
+ if name.is_a?(String) and name =~ /^:/
+ hash.delete(name)
+ name = name.sub(/^:/, '').intern
+ hash[name] = value
+ end
+ if value.is_a?(String) and value =~ /^:/
+ hash[name] = value.sub(/^:/, '').intern
+ end
+ end
+ }
+
+ array
+ end
+
+ def self.suitable_test_packages
+ list = load_test_packages
+ providers = {}
+ Puppet::Type.type(:package).suitableprovider.each do |provider|
+ providers[provider.name] = provider
end
-
- def assert_not_absent(provider, msg = "package not installed")
- result = nil
- assert_nothing_raised("Could not query provider") do
- result = provider.query
- end
- assert((result == :listed or result.is_a?(Hash)), "query did not return hash or :listed")
- if result == :listed
- assert(provider.resource.is(:ensure) != :absent, msg)
- else
- assert(result[:ensure] != :absent, msg)
- end
+ facts = {}
+ Facter.to_hash.each do |fact, value|
+ facts[fact.to_s.downcase.intern] = value.to_s.downcase.intern
end
+ list.find_all { |hash| # First find the matching providers
+ hash.include?(:provider) and providers.include?(hash[:provider])
+ }.reject { |hash| # Then find matching fact sets
+ facts.detect do |fact, value|
+ # We're detecting unmatched facts, but we also want to
+ # delete the facts so they don't show up later.
+ if fval = hash[fact]
+ hash.delete(fact)
+ fval = [fval] unless fval.is_a?(Array)
+ fval = fval.collect { |v| v.downcase.intern }
+ ! fval.include?(value)
+ end
+ end
+ }
+ end
+
+ def assert_absent(provider, msg = "package not absent")
+ result = nil
+ assert_nothing_raised("Could not query provider") do
+ result = provider.query
+ end
+ if result.nil?
+ assert_nil(result)
+ elsif result.is_a?(Hash)
+ assert (result[:ensure] == :absent or result[:ensure] == :purged), msg
+ else
+ raise "dunno how to handle #{result.inspect}"
+ end
+ end
- # Run a package through all of its paces. FIXME This should use the
- # provider, not the package, duh.
- def run_package_installation_test(hash)
- # Turn the hash into a package
- if files = hash[:files]
- hash.delete(:files)
- if files.is_a?(Array)
- hash[:source] = files.shift
- else
- hash[:source] = files
- files = []
- end
- else
- files = []
- end
-
- if versions = hash[:versions]
- hash.delete(:versions)
- else
- versions = []
- end
-
- # Start out by just making sure it's installed
- if versions.empty?
- hash[:ensure] = :present
- else
- hash[:ensure] = versions.shift
- end
+ def assert_not_absent(provider, msg = "package not installed")
+ result = nil
+ assert_nothing_raised("Could not query provider") do
+ result = provider.query
+ end
+ assert((result == :listed or result.is_a?(Hash)), "query did not return hash or :listed")
+ if result == :listed
+ assert(provider.resource.is(:ensure) != :absent, msg)
+ else
+ assert(result[:ensure] != :absent, msg)
+ end
+ end
+
+ # Run a package through all of its paces. FIXME This should use the
+ # provider, not the package, duh.
+ def run_package_installation_test(hash)
+ # Turn the hash into a package
+ if files = hash[:files]
+ hash.delete(:files)
+ if files.is_a?(Array)
+ hash[:source] = files.shift
+ else
+ hash[:source] = files
+ files = []
+ end
+ else
+ files = []
+ end
- if hash[:source]
- unless FileTest.exists?(hash[:source])
- $stderr.puts "Create a package at #{hash[:source]} for testing"
- return
- end
- end
+ if versions = hash[:versions]
+ hash.delete(:versions)
+ else
+ versions = []
+ end
- if cleancmd = hash[:cleanup]
- hash.delete(:cleanup)
- end
+ # Start out by just making sure it's installed
+ if versions.empty?
+ hash[:ensure] = :present
+ else
+ hash[:ensure] = versions.shift
+ end
- pkg = nil
- assert_nothing_raised(
- "Could not turn #{hash.inspect} into a package"
- ) do
- pkg = Puppet::Type.newpackage(hash)
- end
+ if hash[:source]
+ unless FileTest.exists?(hash[:source])
+ $stderr.puts "Create a package at #{hash[:source]} for testing"
+ return
+ end
+ end
- # Make any necessary modifications.
- modpkg(pkg)
+ if cleancmd = hash[:cleanup]
+ hash.delete(:cleanup)
+ end
- provider = pkg.provider
+ pkg = nil
+ assert_nothing_raised(
+ "Could not turn #{hash.inspect} into a package"
+ ) do
+ pkg = Puppet::Type.newpackage(hash)
+ end
- assert(provider, "Could not retrieve provider")
+ # Make any necessary modifications.
+ modpkg(pkg)
- return if result = provider.query and ! [:absent, :purged].include?(result[:ensure])
+ provider = pkg.provider
- assert_absent(provider)
+ assert(provider, "Could not retrieve provider")
- if Process.uid != 0
- Puppet.info "Run as root for full package tests"
- return
- end
+ return if result = provider.query and ! [:absent, :purged].include?(result[:ensure])
- cleanup do
- if pkg.provider.respond_to?(:uninstall)
- pkg.provider.flush
- if pkg.provider.properties[:ensure] != :absent
- assert_nothing_raised("Could not clean up package") do
- pkg.provider.uninstall
- end
- end
- else
- system(cleancmd) if cleancmd
- end
- end
+ assert_absent(provider)
- # Now call 'latest' after the package is installed
- if provider.respond_to?(:latest)
- assert_nothing_raised("Could not call 'latest'") do
- provider.latest
- end
- end
+ if Process.uid != 0
+ Puppet.info "Run as root for full package tests"
+ return
+ end
- assert_nothing_raised("Could not install package") do
- provider.install
- end
+ cleanup do
+ if pkg.provider.respond_to?(:uninstall)
+ pkg.provider.flush
+ if pkg.provider.properties[:ensure] != :absent
+ assert_nothing_raised("Could not clean up package") do
+ pkg.provider.uninstall
+ end
+ end
+ else
+ system(cleancmd) if cleancmd
+ end
+ end
- assert_not_absent(provider, "package did not install")
-
- # If there are any remaining files, then test upgrading from there
- unless files.empty?
- pkg[:source] = files.shift
- current = provider.properties
- assert_nothing_raised("Could not upgrade") do
- provider.update
- end
- provider.flush
- new = provider.properties
- assert(current != new, "package was not upgraded: #{current.inspect} did not change")
- end
+ # Now call 'latest' after the package is installed
+ if provider.respond_to?(:latest)
+ assert_nothing_raised("Could not call 'latest'") do
+ provider.latest
+ end
+ end
- unless versions.empty?
- pkg[:ensure] = versions.shift
- current = provider.properties
- assert_nothing_raised("Could not upgrade") do
- provider.update
- end
- provider.flush
- new = provider.properties
- assert(current != new, "package was not upgraded: #{current.inspect} did not change")
- end
+ assert_nothing_raised("Could not install package") do
+ provider.install
+ end
- # Now call 'latest' after the package is installed
- if provider.respond_to?(:latest)
- assert_nothing_raised("Could not call 'latest'") do
- provider.latest
- end
- end
+ assert_not_absent(provider, "package did not install")
+
+ # If there are any remaining files, then test upgrading from there
+ unless files.empty?
+ pkg[:source] = files.shift
+ current = provider.properties
+ assert_nothing_raised("Could not upgrade") do
+ provider.update
+ end
+ provider.flush
+ new = provider.properties
+ assert(current != new, "package was not upgraded: #{current.inspect} did not change")
+ end
- # Now remove the package
- if provider.respond_to?(:uninstall)
- assert_nothing_raised do
- provider.uninstall
- end
+ unless versions.empty?
+ pkg[:ensure] = versions.shift
+ current = provider.properties
+ assert_nothing_raised("Could not upgrade") do
+ provider.update
+ end
+ provider.flush
+ new = provider.properties
+ assert(current != new, "package was not upgraded: #{current.inspect} did not change")
+ end
- assert_absent(provider)
- end
+ # Now call 'latest' after the package is installed
+ if provider.respond_to?(:latest)
+ assert_nothing_raised("Could not call 'latest'") do
+ provider.latest
+ end
end
- # Now create a separate test method for each package
- suitable_test_packages.each do |hash|
- mname = ["test", hash[:name].to_s, hash[:provider].to_s].join("_").intern
+ # Now remove the package
+ if provider.respond_to?(:uninstall)
+ assert_nothing_raised do
+ provider.uninstall
+ end
- if method_defined?(mname)
- warn "Already a test method defined for #{mname}"
- else
- define_method(mname) do
- run_package_installation_test(hash)
- end
- end
+ assert_absent(provider)
end
-
- def test_dont_complain_if_theres_nothing_to_test
- assert("sometimes the above metaprogramming fails to find anything to test and the runner complains")
+ end
+
+ # Now create a separate test method for each package
+ suitable_test_packages.each do |hash|
+ mname = ["test", hash[:name].to_s, hash[:provider].to_s].join("_").intern
+
+ if method_defined?(mname)
+ warn "Already a test method defined for #{mname}"
+ else
+ define_method(mname) do
+ run_package_installation_test(hash)
+ end
end
+ end
- def modpkg(pkg)
- case pkg[:provider]
- when :sun
- pkg[:adminfile] = "/usr/local/pkg/admin_file"
- end
+ def test_dont_complain_if_theres_nothing_to_test
+ assert("sometimes the above metaprogramming fails to find anything to test and the runner complains")
+ end
+
+ def modpkg(pkg)
+ case pkg[:provider]
+ when :sun
+ pkg[:adminfile] = "/usr/local/pkg/admin_file"
end
+ end
end
diff --git a/test/ral/providers/package/aptitude.rb b/test/ral/providers/package/aptitude.rb
index ba736f9..34eba10 100755
--- a/test/ral/providers/package/aptitude.rb
+++ b/test/ral/providers/package/aptitude.rb
@@ -5,79 +5,79 @@ require File.dirname(__FILE__) + '/../../../lib/puppettest'
require 'mocha'
class AptitudePackageProviderTest < PuppetTest::TestCase
- include PuppetTest
+ include PuppetTest
- confine "Aptitude package provider missing" =>
- Puppet::Type.type(:package).provider(:aptitude).suitable?
+ confine "Aptitude package provider missing" =>
+ Puppet::Type.type(:package).provider(:aptitude).suitable?
- def setup
- super
- @type = Puppet::Type.type(:package)
- end
+ def setup
+ super
+ @type = Puppet::Type.type(:package)
+ end
- def test_install
- pkg = @type.new :name => 'faff',
- :provider => :aptitude,
- :ensure => :present,
- :source => "/tmp/faff.deb"
+ def test_install
+ pkg = @type.new :name => 'faff',
+ :provider => :aptitude,
+ :ensure => :present,
+ :source => "/tmp/faff.deb"
- pkg.provider.expects(
- :dpkgquery
+ pkg.provider.expects(
+ :dpkgquery
- ).with(
+ ).with(
- '-W',
- '--showformat',
- '${Status} ${Package} ${Version}\n',
+ '-W',
+ '--showformat',
+ '${Status} ${Package} ${Version}\n',
- 'faff'
- ).returns(
- "deinstall ok config-files faff 1.2.3-1\n"
- ).times(1)
+ 'faff'
+ ).returns(
+ "deinstall ok config-files faff 1.2.3-1\n"
+ ).times(1)
- pkg.provider.expects(
- :aptitude
+ pkg.provider.expects(
+ :aptitude
- ).with(
+ ).with(
- '-y',
- '-o',
- 'DPkg::Options::=--force-confold',
- :install,
+ '-y',
+ '-o',
+ 'DPkg::Options::=--force-confold',
+ :install,
- 'faff'
- ).returns(0)
+ 'faff'
+ ).returns(0)
- assert_apply( pkg )
- end
+ assert_apply( pkg )
+ end
- def test_purge
- pkg = @type.new :name => 'faff', :provider => :aptitude, :ensure => :purged
+ def test_purge
+ pkg = @type.new :name => 'faff', :provider => :aptitude, :ensure => :purged
- pkg.provider.expects(
- :dpkgquery
+ pkg.provider.expects(
+ :dpkgquery
- ).with(
+ ).with(
- '-W',
- '--showformat',
- '${Status} ${Package} ${Version}\n',
+ '-W',
+ '--showformat',
+ '${Status} ${Package} ${Version}\n',
- 'faff'
- ).returns(
- "install ok installed faff 1.2.3-1\n"
- ).times(1)
- pkg.provider.expects(
- :aptitude
+ 'faff'
+ ).returns(
+ "install ok installed faff 1.2.3-1\n"
+ ).times(1)
+ pkg.provider.expects(
+ :aptitude
- ).with(
+ ).with(
- '-y',
- 'purge',
+ '-y',
+ 'purge',
- 'faff'
- ).returns(0)
+ 'faff'
+ ).returns(0)
- assert_apply( pkg )
- end
+ assert_apply( pkg )
+ end
end
diff --git a/test/ral/providers/package/aptrpm.rb b/test/ral/providers/package/aptrpm.rb
index dbb6a00..5f2a0d2 100755
--- a/test/ral/providers/package/aptrpm.rb
+++ b/test/ral/providers/package/aptrpm.rb
@@ -5,96 +5,96 @@ require File.dirname(__FILE__) + '/../../../lib/puppettest'
require 'mocha'
class AptrpmPackageProviderTest < PuppetTest::TestCase
- confine "Apt package provider missing" =>
- Puppet::Type.type(:package).provider(:aptrpm).suitable?
+ confine "Apt package provider missing" =>
+ Puppet::Type.type(:package).provider(:aptrpm).suitable?
- def setup
- super
- @type = Puppet::Type.type(:package)
- end
+ def setup
+ super
+ @type = Puppet::Type.type(:package)
+ end
- def test_install
- pkg = @type.new :name => 'faff',
- :provider => :aptrpm,
- :ensure => :present,
- :source => "/tmp/faff.rpm"
+ def test_install
+ pkg = @type.new :name => 'faff',
+ :provider => :aptrpm,
+ :ensure => :present,
+ :source => "/tmp/faff.rpm"
- pkg.provider.expects(
- :rpm
+ pkg.provider.expects(
+ :rpm
- ).with(
+ ).with(
- '-q',
- 'faff',
- '--nosignature',
- '--nodigest',
- '--qf',
+ '-q',
+ 'faff',
+ '--nosignature',
+ '--nodigest',
+ '--qf',
- "%{NAME}-%{VERSION}-%{RELEASE} %{VERSION}-%{RELEASE}\n"
- ).raises(Puppet::ExecutionFailure, "couldn't find rpm").times(1)
+ "%{NAME}-%{VERSION}-%{RELEASE} %{VERSION}-%{RELEASE}\n"
+ ).raises(Puppet::ExecutionFailure, "couldn't find rpm").times(1)
- pkg.provider.expects(
- :aptget
+ pkg.provider.expects(
+ :aptget
- ).with(
+ ).with(
- '-q',
- '-y',
- "install",
+ '-q',
+ '-y',
+ "install",
- 'faff'
- ).returns(0)
+ 'faff'
+ ).returns(0)
- pkg.evaluate.each { |state| state.forward }
- end
+ pkg.evaluate.each { |state| state.forward }
+ end
- def test_uninstall
- pkg = @type.new :name => 'faff', :provider => :aptrpm, :ensure => :absent
+ def test_uninstall
+ pkg = @type.new :name => 'faff', :provider => :aptrpm, :ensure => :absent
- pkg.provider.expects(
- :rpm
+ pkg.provider.expects(
+ :rpm
- ).with(
+ ).with(
- '-q',
- 'faff',
- '--nosignature',
- '--nodigest',
- '--qf',
+ '-q',
+ 'faff',
+ '--nosignature',
+ '--nodigest',
+ '--qf',
- "%{NAME}-%{VERSION}-%{RELEASE} %{VERSION}-%{RELEASE}\n"
- ).returns(
- "faff-1.2.3-1 1.2.3-1\n"
- ).times(1)
- pkg.provider.expects(
- :aptget
+ "%{NAME}-%{VERSION}-%{RELEASE} %{VERSION}-%{RELEASE}\n"
+ ).returns(
+ "faff-1.2.3-1 1.2.3-1\n"
+ ).times(1)
+ pkg.provider.expects(
+ :aptget
- ).with(
+ ).with(
- '-y',
- '-q',
- 'remove',
+ '-y',
+ '-q',
+ 'remove',
- 'faff'
- ).returns(0)
+ 'faff'
+ ).returns(0)
- pkg.evaluate.each { |state| state.forward }
- end
+ pkg.evaluate.each { |state| state.forward }
+ end
- # LAK: I don't know where this test will ever return true..
- def disabled_test_latest
- pkg = @type.new :name => 'ssh', :provider => :aptrpm
+ # LAK: I don't know where this test will ever return true..
+ def disabled_test_latest
+ pkg = @type.new :name => 'ssh', :provider => :aptrpm
- assert(pkg, "did not create pkg")
- status = pkg.provider.query
- assert(status, "ssh is not installed")
- assert(status[:ensure] != :absent, "ssh is not installed")
+ assert(pkg, "did not create pkg")
+ status = pkg.provider.query
+ assert(status, "ssh is not installed")
+ assert(status[:ensure] != :absent, "ssh is not installed")
- latest = nil
- assert_nothing_raised("Could not call latest") do
- latest = pkg.provider.latest
- end
- assert(latest, "Could not get latest value from apt")
+ latest = nil
+ assert_nothing_raised("Could not call latest") do
+ latest = pkg.provider.latest
end
+ assert(latest, "Could not get latest value from apt")
+ end
end
diff --git a/test/ral/providers/parsedfile.rb b/test/ral/providers/parsedfile.rb
index 53a37cf..c7e5d9b 100755
--- a/test/ral/providers/parsedfile.rb
+++ b/test/ral/providers/parsedfile.rb
@@ -10,686 +10,686 @@ require 'puppet/provider/parsedfile'
require 'facter'
class TestParsedFile < Test::Unit::TestCase
- include PuppetTest
- include PuppetTest::FileParsing
-
- Puppet::Type.newtype(:testparsedfiletype) do
- ensurable
- newproperty(:one) do
- newvalue(:a)
- newvalue(:b)
- end
- newproperty(:two) do
- newvalue(:c)
- newvalue(:d)
- end
+ include PuppetTest
+ include PuppetTest::FileParsing
+
+ Puppet::Type.newtype(:testparsedfiletype) do
+ ensurable
+ newproperty(:one) do
+ newvalue(:a)
+ newvalue(:b)
+ end
+ newproperty(:two) do
+ newvalue(:c)
+ newvalue(:d)
+ end
- newparam(:name) do
- end
+ newparam(:name) do
+ end
- # The target should always be a property, not a parameter.
- newproperty(:target) do
- defaultto { @resource.class.defaultprovider.default_target }
- end
+ # The target should always be a property, not a parameter.
+ newproperty(:target) do
+ defaultto { @resource.class.defaultprovider.default_target }
end
+ end
- # A simple block to skip the complexity of a full transaction.
- def apply(resource)
- [:one, :two, :ensure, :target].each do |st|
- Puppet.info "Setting #{resource[:name]}: #{st} => #{resource.should(st)}"
- resource.provider.send(st.to_s + "=", resource.should(st))
- end
+ # A simple block to skip the complexity of a full transaction.
+ def apply(resource)
+ [:one, :two, :ensure, :target].each do |st|
+ Puppet.info "Setting #{resource[:name]}: #{st} => #{resource.should(st)}"
+ resource.provider.send(st.to_s + "=", resource.should(st))
end
+ end
- def mkresource(name, options = {})
- options[:one] ||= "a"
- options[:two] ||= "c"
- options[:name] ||= name
+ def mkresource(name, options = {})
+ options[:one] ||= "a"
+ options[:two] ||= "c"
+ options[:name] ||= name
- resource = @type.new(options)
- end
+ resource = @type.new(options)
+ end
- def mkprovider(name = :parsed)
- @provider = @type.provide(name, :parent => Puppet::Provider::ParsedFile, :filetype => :ram, :default_target => "yayness") do
- record_line name, :fields => %w{name one two}
- end
+ def mkprovider(name = :parsed)
+ @provider = @type.provide(name, :parent => Puppet::Provider::ParsedFile, :filetype => :ram, :default_target => "yayness") do
+ record_line name, :fields => %w{name one two}
end
+ end
- def setup
- super
- @type = Puppet::Type.type(:testparsedfiletype)
- end
+ def setup
+ super
+ @type = Puppet::Type.type(:testparsedfiletype)
+ end
- def teardown
- if defined?(@provider)
- @type.unprovide(@provider.name)
- @provider = nil
- end
- super
+ def teardown
+ if defined?(@provider)
+ @type.unprovide(@provider.name)
+ @provider = nil
end
+ super
+ end
- def test_create_provider
- assert_nothing_raised do
- mkprovider
- end
+ def test_create_provider
+ assert_nothing_raised do
+ mkprovider
end
+ end
- def test_resource_attributes
- prov = nil
- assert_nothing_raised do
- prov = mkprovider
- end
-
- [:one, :two, :name].each do |attr|
- assert(prov.method_defined?(attr), "Did not define #{attr}")
- end
+ def test_resource_attributes
+ prov = nil
+ assert_nothing_raised do
+ prov = mkprovider
+ end
- # Now make sure they stay around
- fakeresource = fakeresource(:testparsedfiletype, "yay")
+ [:one, :two, :name].each do |attr|
+ assert(prov.method_defined?(attr), "Did not define #{attr}")
+ end
- file = prov.new(fakeresource)
- assert(file, "Could not make provider")
+ # Now make sure they stay around
+ fakeresource = fakeresource(:testparsedfiletype, "yay")
- assert_nothing_raised("Could not set provider name") do
- file.name = :yayness
- end
+ file = prov.new(fakeresource)
+ assert(file, "Could not make provider")
- # The provider converts to strings
- assert_equal(:yayness, file.name)
+ assert_nothing_raised("Could not set provider name") do
+ file.name = :yayness
end
- def test_filetype
- prov = mkprovider
+ # The provider converts to strings
+ assert_equal(:yayness, file.name)
+ end
- flat = Puppet::Util::FileType.filetype(:flat)
- ram = Puppet::Util::FileType.filetype(:ram)
- assert_nothing_raised do
- prov.filetype = :flat
- end
+ def test_filetype
+ prov = mkprovider
- assert_equal(flat, prov.filetype)
-
- assert_nothing_raised do
- prov.filetype = ram
- end
- assert_equal(ram, prov.filetype)
+ flat = Puppet::Util::FileType.filetype(:flat)
+ ram = Puppet::Util::FileType.filetype(:ram)
+ assert_nothing_raised do
+ prov.filetype = :flat
end
- # Make sure we correctly create a new filetype object, but only when
- # necessary.
- def test_fileobject
- prov = mkprovider
-
- path = tempfile
- obj = nil
- assert_nothing_raised do
- obj = prov.target_object(path)
- end
+ assert_equal(flat, prov.filetype)
- # The default filetype is 'ram'
- assert_instance_of(Puppet::Util::FileType.filetype(:ram), obj)
+ assert_nothing_raised do
+ prov.filetype = ram
+ end
+ assert_equal(ram, prov.filetype)
+ end
+
+ # Make sure we correctly create a new filetype object, but only when
+ # necessary.
+ def test_fileobject
+ prov = mkprovider
+
+ path = tempfile
+ obj = nil
+ assert_nothing_raised do
+ obj = prov.target_object(path)
+ end
- newobj = nil
- assert_nothing_raised do
- newobj = prov.target_object(path)
- end
+ # The default filetype is 'ram'
+ assert_instance_of(Puppet::Util::FileType.filetype(:ram), obj)
- assert_equal(obj, newobj, "did not reuse file object")
+ newobj = nil
+ assert_nothing_raised do
+ newobj = prov.target_object(path)
+ end
- # now make sure clear does the right thing
- assert_nothing_raised do
- prov.clear
- end
- assert_nothing_raised do
- newobj = prov.target_object(path)
- end
+ assert_equal(obj, newobj, "did not reuse file object")
- assert(obj != newobj, "did not reuse file object")
+ # now make sure clear does the right thing
+ assert_nothing_raised do
+ prov.clear
+ end
+ assert_nothing_raised do
+ newobj = prov.target_object(path)
end
- def test_retrieve
- prov = mkprovider
+ assert(obj != newobj, "did not reuse file object")
+ end
- prov.filetype = :ram
+ def test_retrieve
+ prov = mkprovider
- # Override the parse method with our own
- prov.meta_def(:parse) do |text|
- return [text]
- end
+ prov.filetype = :ram
- path = :yayness
- file = prov.target_object(path)
- text = "a test"
- file.write(text)
+ # Override the parse method with our own
+ prov.meta_def(:parse) do |text|
+ return [text]
+ end
- ret = nil
- assert_nothing_raised do
- ret = prov.retrieve(path)
- end
+ path = :yayness
+ file = prov.target_object(path)
+ text = "a test"
+ file.write(text)
- assert_equal([text], ret)
+ ret = nil
+ assert_nothing_raised do
+ ret = prov.retrieve(path)
+ end
- # Now set the text to nil and make sure we get an empty array
- file.write(nil)
- assert_nothing_raised do
- ret = prov.retrieve(path)
- end
+ assert_equal([text], ret)
- assert_equal([], ret)
+ # Now set the text to nil and make sure we get an empty array
+ file.write(nil)
+ assert_nothing_raised do
+ ret = prov.retrieve(path)
+ end
- # And the empty string should return an empty array
- file.write("")
- assert_nothing_raised do
- ret = prov.retrieve(path)
- end
+ assert_equal([], ret)
- assert_equal([], ret)
+ # And the empty string should return an empty array
+ file.write("")
+ assert_nothing_raised do
+ ret = prov.retrieve(path)
end
- # Verify that prefetch will parse the file, create any necessary instances,
- # and set the 'is' values appropriately.
- def test_prefetch
- prov = mkprovider
+ assert_equal([], ret)
+ end
- prov.filetype = :ram
- prov.default_target = :default
+ # Verify that prefetch will parse the file, create any necessary instances,
+ # and set the 'is' values appropriately.
+ def test_prefetch
+ prov = mkprovider
- # Create a couple of demo files
- prov.target_object(:file1).write "bill b c\njill b d"
+ prov.filetype = :ram
+ prov.default_target = :default
- prov.target_object(:default).write "will b d\n"
+ # Create a couple of demo files
+ prov.target_object(:file1).write "bill b c\njill b d"
- # Create some resources for some of those demo files
- bill = mkresource "bill", :target => :file1, :one => "b", :two => "c"
- will = mkresource "will", :target => :default, :one => "b", :two => "d"
+ prov.target_object(:default).write "will b d\n"
- resources = {"bill" => bill, "will" => will}
- prov_ids = {"bill" => bill.provider.object_id, "will" => will.provider.object_id}
+ # Create some resources for some of those demo files
+ bill = mkresource "bill", :target => :file1, :one => "b", :two => "c"
+ will = mkresource "will", :target => :default, :one => "b", :two => "d"
- assert_nothing_raised do
- prov.prefetch(resources)
- end
+ resources = {"bill" => bill, "will" => will}
+ prov_ids = {"bill" => bill.provider.object_id, "will" => will.provider.object_id}
- assert(bill.provider.object_id != prov_ids["bill"], "provider was not replaced in resource")
- assert(will.provider.object_id != prov_ids["will"], "provider was not replaced in resource")
+ assert_nothing_raised do
+ prov.prefetch(resources)
+ end
- # Make sure we prefetched our resources.
- assert_equal("b", bill.provider.one, "did not prefetch resource from file1")
- assert_equal("c", bill.provider.two, "did not prefetch resource from file1")
- assert_equal("b", will.provider.one, "did not prefetch resource from default")
- assert_equal("d", will.provider.two, "did not prefetch resource from default")
+ assert(bill.provider.object_id != prov_ids["bill"], "provider was not replaced in resource")
+ assert(will.provider.object_id != prov_ids["will"], "provider was not replaced in resource")
- # Now modify our resources and write them out, making sure that prefetching
- # hasn't somehow destroyed this ability
- bill[:one] = "a"
- will[:one] = "a"
+ # Make sure we prefetched our resources.
+ assert_equal("b", bill.provider.one, "did not prefetch resource from file1")
+ assert_equal("c", bill.provider.two, "did not prefetch resource from file1")
+ assert_equal("b", will.provider.one, "did not prefetch resource from default")
+ assert_equal("d", will.provider.two, "did not prefetch resource from default")
- assert_apply(bill)
- assert_apply(will)
+ # Now modify our resources and write them out, making sure that prefetching
+ # hasn't somehow destroyed this ability
+ bill[:one] = "a"
+ will[:one] = "a"
- prov.prefetch(resources)
- assert_equal("a", bill.provider.one, "did not prefetch resource from file1")
- assert_equal("a", will.provider.one, "did not prefetch resource from default")
+ assert_apply(bill)
+ assert_apply(will)
- assert_equal("bill a c\njill b d\n", prov.target_object(:file1).read,
- "Did not write changed resource correctly")
- assert_equal("will a d\n", prov.target_object(:default).read,
- "Did not write changed default resource correctly")
- end
+ prov.prefetch(resources)
+ assert_equal("a", bill.provider.one, "did not prefetch resource from file1")
+ assert_equal("a", will.provider.one, "did not prefetch resource from default")
- # Make sure we can correctly prefetch on a target.
- def test_prefetch_target
- prov = mkprovider
+ assert_equal("bill a c\njill b d\n", prov.target_object(:file1).read,
+ "Did not write changed resource correctly")
+ assert_equal("will a d\n", prov.target_object(:default).read,
+ "Did not write changed default resource correctly")
+ end
- prov.filetype = :ram
- target = :yayness
- prov.target_object(target).write "yay b d"
+ # Make sure we can correctly prefetch on a target.
+ def test_prefetch_target
+ prov = mkprovider
- records = nil
- assert_nothing_raised do
- records = prov.prefetch_target(:yayness)
- end
+ prov.filetype = :ram
+ target = :yayness
+ prov.target_object(target).write "yay b d"
- # Now make sure we correctly got the hash
- record = records.find { |r| r[:name] == "yay" }
- assert(record, "Did not get record in prefetch_target")
- assert_equal("b", record[:one])
- assert_equal("d", record[:two])
+ records = nil
+ assert_nothing_raised do
+ records = prov.prefetch_target(:yayness)
end
- def test_prefetch_match
- prov = mkprovider
-
- prov.meta_def(:match) do |record, resources|
- # Look for matches on :one
- if res = resources.find { |name, resource| resource.should(:one).to_s == record[:one].to_s }
- res[1]
- else
- nil
- end
- end
-
- prov.filetype = :ram
- target = :yayness
- prov.target_object(target).write "foo b d"
+ # Now make sure we correctly got the hash
+ record = records.find { |r| r[:name] == "yay" }
+ assert(record, "Did not get record in prefetch_target")
+ assert_equal("b", record[:one])
+ assert_equal("d", record[:two])
+ end
+
+ def test_prefetch_match
+ prov = mkprovider
+
+ prov.meta_def(:match) do |record, resources|
+ # Look for matches on :one
+ if res = resources.find { |name, resource| resource.should(:one).to_s == record[:one].to_s }
+ res[1]
+ else
+ nil
+ end
+ end
- resource = mkresource "yay", :target => :yayness, :one => "b"
+ prov.filetype = :ram
+ target = :yayness
+ prov.target_object(target).write "foo b d"
- assert_nothing_raised do
- prov.prefetch("yay" => resource)
- end
+ resource = mkresource "yay", :target => :yayness, :one => "b"
- # Now make sure we correctly got the hash
- mprov = resource.provider
- assert_equal("yay", resource[:name])
- assert_equal("b", mprov.one)
- assert_equal("d", mprov.two)
+ assert_nothing_raised do
+ prov.prefetch("yay" => resource)
end
- # We need to test that we're retrieving files from all three locations:
- # from any existing target_objects, from the default file location, and
- # from any existing resource instances.
- def test_targets
- prov = mkprovider
+ # Now make sure we correctly got the hash
+ mprov = resource.provider
+ assert_equal("yay", resource[:name])
+ assert_equal("b", mprov.one)
+ assert_equal("d", mprov.two)
+ end
- files = {}
+ # We need to test that we're retrieving files from all three locations:
+ # from any existing target_objects, from the default file location, and
+ # from any existing resource instances.
+ def test_targets
+ prov = mkprovider
- # Set the default target
- default = tempfile
- files[:default] = default
- prov.default_target = default
+ files = {}
- # Create a file object
- inmem = tempfile
- files[:inmemory] = inmem
- prov.target_object(inmem).write("inmem yay ness")
+ # Set the default target
+ default = tempfile
+ files[:default] = default
+ prov.default_target = default
- # Lastly, create a resource with separate is and should values
- mtarget = tempfile
- files[:resources] = mtarget
- resource = mkresource "yay", :target => mtarget
+ # Create a file object
+ inmem = tempfile
+ files[:inmemory] = inmem
+ prov.target_object(inmem).write("inmem yay ness")
- assert(resource.should(:target), "Did not get a value for target")
+ # Lastly, create a resource with separate is and should values
+ mtarget = tempfile
+ files[:resources] = mtarget
+ resource = mkresource "yay", :target => mtarget
- list = nil
+ assert(resource.should(:target), "Did not get a value for target")
- # First run it without the resource
- assert_nothing_raised do
- list = prov.targets
- end
+ list = nil
- # Make sure it got the first two, but not the resources file
- files.each do |name, file|
- if name == :resources
- assert(! list.include?(file), "Provider somehow found resource target when no resource was passed")
- else
- assert(list.include?(file), "Provider did not find #{name} file")
- end
- end
+ # First run it without the resource
+ assert_nothing_raised do
+ list = prov.targets
+ end
- # Now list with the resource passed
- assert_nothing_raised do
- list = prov.targets("yay" => resource)
- end
+ # Make sure it got the first two, but not the resources file
+ files.each do |name, file|
+ if name == :resources
+ assert(! list.include?(file), "Provider somehow found resource target when no resource was passed")
+ else
+ assert(list.include?(file), "Provider did not find #{name} file")
+ end
+ end
- # And make sure we get all three files
- files.each do |name, file|
- assert(list.include?(file), "Provider did not find #{name} file when resource was passed")
- end
+ # Now list with the resource passed
+ assert_nothing_raised do
+ list = prov.targets("yay" => resource)
end
- # Make sure that flushing behaves correctly. This is what actually writes
- # the data out to disk.
- def test_flush
- prov = mkprovider
+ # And make sure we get all three files
+ files.each do |name, file|
+ assert(list.include?(file), "Provider did not find #{name} file when resource was passed")
+ end
+ end
- prov.filetype = :ram
- prov.default_target = :yayness
+ # Make sure that flushing behaves correctly. This is what actually writes
+ # the data out to disk.
+ def test_flush
+ prov = mkprovider
- # Create some resources.
- one = mkresource "one", :one => "a", :two => "c", :target => :yayness
- two = mkresource "two", :one => "b", :two => "d", :target => :yayness
- resources = {"one" => one, "two" => two}
+ prov.filetype = :ram
+ prov.default_target = :yayness
- # Write out a file with different data.
- prov.target_object(:yayness).write "one b d\ntwo a c"
+ # Create some resources.
+ one = mkresource "one", :one => "a", :two => "c", :target => :yayness
+ two = mkresource "two", :one => "b", :two => "d", :target => :yayness
+ resources = {"one" => one, "two" => two}
- prov.prefetch(resources)
+ # Write out a file with different data.
+ prov.target_object(:yayness).write "one b d\ntwo a c"
- # Apply and flush the first resource.
- assert_nothing_raised do
- apply(one)
- end
- assert_nothing_raised { one.flush }
+ prov.prefetch(resources)
- # Make sure it didn't clear out our property hash
- assert_equal(:a, one.provider.one)
- assert_equal(:c, one.provider.two)
+ # Apply and flush the first resource.
+ assert_nothing_raised do
+ apply(one)
+ end
+ assert_nothing_raised { one.flush }
- # And make sure it's right on disk
- assert(prov.target_object(:yayness).read.include?("one a c"), "Did not write out correct data")
+ # Make sure it didn't clear out our property hash
+ assert_equal(:a, one.provider.one)
+ assert_equal(:c, one.provider.two)
- # Make sure the second resource has not been modified
- assert_equal("a", two.provider.one, "Two was flushed early")
- assert_equal("c", two.provider.two, "Two was flushed early")
+ # And make sure it's right on disk
+ assert(prov.target_object(:yayness).read.include?("one a c"), "Did not write out correct data")
- # And on disk
- assert(prov.target_object(:yayness).read.include?("two a c"), "Wrote out other resource")
+ # Make sure the second resource has not been modified
+ assert_equal("a", two.provider.one, "Two was flushed early")
+ assert_equal("c", two.provider.two, "Two was flushed early")
- # Now fetch the data again and make sure we're still right
- assert_nothing_raised { prov.prefetch(resources) }
- assert_equal("a", one.provider.one)
- assert_equal("a", two.provider.one)
+ # And on disk
+ assert(prov.target_object(:yayness).read.include?("two a c"), "Wrote out other resource")
- # Now flush the second resource and make sure it goes well
- assert_nothing_raised { apply(two) }
- assert_nothing_raised { two.flush }
+ # Now fetch the data again and make sure we're still right
+ assert_nothing_raised { prov.prefetch(resources) }
+ assert_equal("a", one.provider.one)
+ assert_equal("a", two.provider.one)
- # And make sure it didn't clear our hash
- assert_equal(:b, two.provider.one)
- end
+ # Now flush the second resource and make sure it goes well
+ assert_nothing_raised { apply(two) }
+ assert_nothing_raised { two.flush }
- # Make sure it works even if the file does not currently exist
- def test_creating_file
- prov = mkprovider
- prov.clear
+ # And make sure it didn't clear our hash
+ assert_equal(:b, two.provider.one)
+ end
- prov.default_target = :basic
+ # Make sure it works even if the file does not currently exist
+ def test_creating_file
+ prov = mkprovider
+ prov.clear
- resource = mkresource "yay", :target => :basic, :one => "a", :two => "c"
+ prov.default_target = :basic
- assert_equal(:present, resource.should(:ensure))
+ resource = mkresource "yay", :target => :basic, :one => "a", :two => "c"
- apply(resource)
+ assert_equal(:present, resource.should(:ensure))
- assert_nothing_raised do
- resource.flush
- end
+ apply(resource)
- assert_equal("yay a c\n", prov.target_object(:basic).read,
- "Did not create file")
+ assert_nothing_raised do
+ resource.flush
+ end
- # Make a change
- resource.provider.one = "b"
+ assert_equal("yay a c\n", prov.target_object(:basic).read,
+ "Did not create file")
- # Flush it
- assert_nothing_raised do
- resource.flush
- end
+ # Make a change
+ resource.provider.one = "b"
- # And make sure our resource doesn't appear twice in the file.
- assert_equal("yay b c\n", prov.target_object(:basic).read, "Wrote record to file twice")
+ # Flush it
+ assert_nothing_raised do
+ resource.flush
end
- # Make sure a record can switch targets.
- def test_switching_targets
- prov = mkprovider
-
- prov.filetype = :ram
- prov.default_target = :first
+ # And make sure our resource doesn't appear twice in the file.
+ assert_equal("yay b c\n", prov.target_object(:basic).read, "Wrote record to file twice")
+ end
- # Make three resources, one for each target and one to switch
- first = mkresource "first", :target => :first
- second = mkresource "second", :target => :second
- mover = mkresource "mover", :target => :first
+ # Make sure a record can switch targets.
+ def test_switching_targets
+ prov = mkprovider
- [first, second, mover].each do |m|
- assert_nothing_raised("Could not apply #{m[:name]}") do
- apply(m)
- end
- end
+ prov.filetype = :ram
+ prov.default_target = :first
- # Flush.
- [first, second, mover].each do |m|
- assert_nothing_raised do
- m.flush
- end
- end
+ # Make three resources, one for each target and one to switch
+ first = mkresource "first", :target => :first
+ second = mkresource "second", :target => :second
+ mover = mkresource "mover", :target => :first
- check = proc do |target, name|
- assert(prov.target_object(target).read.include?("#{name} a c"), "Did not sync #{name}")
- end
- # Make sure the data is there
- check.call(:first, :first)
- check.call(:second, :second)
- check.call(:first, :mover)
+ [first, second, mover].each do |m|
+ assert_nothing_raised("Could not apply #{m[:name]}") do
+ apply(m)
+ end
+ end
- # Now change the target for the mover
- mover[:target] = :second
+ # Flush.
+ [first, second, mover].each do |m|
+ assert_nothing_raised do
+ m.flush
+ end
+ end
- # Apply it
- assert_nothing_raised do
- apply(mover)
- end
+ check = proc do |target, name|
+ assert(prov.target_object(target).read.include?("#{name} a c"), "Did not sync #{name}")
+ end
+ # Make sure the data is there
+ check.call(:first, :first)
+ check.call(:second, :second)
+ check.call(:first, :mover)
- # Flush
- assert_nothing_raised do
- mover.flush
- end
+ # Now change the target for the mover
+ mover[:target] = :second
- # Make sure the data is there
- check.call(:first, :first)
- check.call(:second, :second)
- check.call(:second, :mover)
+ # Apply it
+ assert_nothing_raised do
+ apply(mover)
+ end
- # And make sure the mover is no longer in the first file
- assert(prov.target_object(:first) !~ /mover/, "Mover was not removed from first file")
+ # Flush
+ assert_nothing_raised do
+ mover.flush
end
- # Make sure that 'ensure' correctly calls 'sync' on all properties.
- def test_ensure
- prov = mkprovider
+ # Make sure the data is there
+ check.call(:first, :first)
+ check.call(:second, :second)
+ check.call(:second, :mover)
+
+ # And make sure the mover is no longer in the first file
+ assert(prov.target_object(:first) !~ /mover/, "Mover was not removed from first file")
+ end
- prov.filetype = :ram
- prov.default_target = :first
+ # Make sure that 'ensure' correctly calls 'sync' on all properties.
+ def test_ensure
+ prov = mkprovider
- # Make two resources, one that starts on disk and one that doesn't
- ondisk = mkresource "ondisk", :target => :first
- notdisk = mkresource "notdisk", :target => :first
+ prov.filetype = :ram
+ prov.default_target = :first
- prov.target_object(:first).write "ondisk a c\n"
- prov.prefetch("ondisk" => ondisk, "notdisk" => notdisk)
+ # Make two resources, one that starts on disk and one that doesn't
+ ondisk = mkresource "ondisk", :target => :first
+ notdisk = mkresource "notdisk", :target => :first
+ prov.target_object(:first).write "ondisk a c\n"
+ prov.prefetch("ondisk" => ondisk, "notdisk" => notdisk)
- assert_equal(
- :present, notdisk.should(:ensure),
- "Did not get default ensure value")
+ assert_equal(
+ :present, notdisk.should(:ensure),
- # Try creating the object
- assert_nothing_raised { notdisk.provider.create }
+ "Did not get default ensure value")
- # Now make sure all of the data is copied over correctly.
- notdisk.class.validproperties.each do |property|
- assert_equal(notdisk.should(property), notdisk.provider.property_hash[property],
- "#{property} was not copied over during creation")
- end
+ # Try creating the object
+ assert_nothing_raised { notdisk.provider.create }
- # Flush it to disk and make sure it got copied down
- assert_nothing_raised do
- notdisk.flush
- end
+ # Now make sure all of the data is copied over correctly.
+ notdisk.class.validproperties.each do |property|
+ assert_equal(notdisk.should(property), notdisk.provider.property_hash[property],
+ "#{property} was not copied over during creation")
+ end
- assert(prov.target_object(:first).read =~ /^notdisk/,
- "Did not write out object to disk")
- assert(prov.target_object(:first).read =~ /^ondisk/,
- "Lost object on disk")
+ # Flush it to disk and make sure it got copied down
+ assert_nothing_raised do
+ notdisk.flush
+ end
- # Make sure our on-disk resource behaves appropriately.
- assert_equal(:present, ondisk.provider.ensure)
+ assert(prov.target_object(:first).read =~ /^notdisk/,
+ "Did not write out object to disk")
+ assert(prov.target_object(:first).read =~ /^ondisk/,
+ "Lost object on disk")
- # Now destroy the object
- assert_nothing_raised { notdisk.provider.destroy }
+ # Make sure our on-disk resource behaves appropriately.
+ assert_equal(:present, ondisk.provider.ensure)
- assert_nothing_raised { notdisk.flush }
+ # Now destroy the object
+ assert_nothing_raised { notdisk.provider.destroy }
- # And make sure it's no longer present
- assert(prov.target_object(:first).read !~ /^notdisk/, "Did not remove thing from disk")
- assert(prov.target_object(:first).read =~ /^ondisk/, "Lost object on disk")
- assert_equal(:present, ondisk.provider.ensure)
- end
+ assert_nothing_raised { notdisk.flush }
- def test_absent_fields
- prov = @type.provide(:record, :parent => Puppet::Provider::ParsedFile) do
- record_line :record, :fields => %w{name one two},
- :separator => "\s"
- end
- cleanup { @type.unprovide(:record) }
+ # And make sure it's no longer present
+ assert(prov.target_object(:first).read !~ /^notdisk/, "Did not remove thing from disk")
+ assert(prov.target_object(:first).read =~ /^ondisk/, "Lost object on disk")
+ assert_equal(:present, ondisk.provider.ensure)
+ end
- line = prov.parse_line("a d")
+ def test_absent_fields
+ prov = @type.provide(:record, :parent => Puppet::Provider::ParsedFile) do
+ record_line :record, :fields => %w{name one two},
+ :separator => "\s"
+ end
+ cleanup { @type.unprovide(:record) }
- assert_equal("a", line[:name], "field name was not set")
- assert_equal(:absent, line[:one], "field one was not set to absent")
+ line = prov.parse_line("a d")
- # Now use a different provider with a non-blank "absent"
- prov = @type.provide(:cronstyle, :parent => Puppet::Provider::ParsedFile) do
- record_line :cronstyle, :fields => %w{name one two},
- :separator => "\s", :absent => "*"
- end
- cleanup { @type.unprovide(:cronstyle) }
- line = prov.parse_line("a * d")
+ assert_equal("a", line[:name], "field name was not set")
+ assert_equal(:absent, line[:one], "field one was not set to absent")
- assert_equal("a", line[:name], "field name was not set")
- assert_equal(:absent, line[:one], "field one was not set to absent")
+ # Now use a different provider with a non-blank "absent"
+ prov = @type.provide(:cronstyle, :parent => Puppet::Provider::ParsedFile) do
+ record_line :cronstyle, :fields => %w{name one two},
+ :separator => "\s", :absent => "*"
end
+ cleanup { @type.unprovide(:cronstyle) }
+ line = prov.parse_line("a * d")
- # This test is because in x2puppet I was having problems where multiple
- # retrievals somehow destroyed the 'is' values.
- def test_value_retrieval
- prov = mkprovider
- prov.default_target = :yayness
+ assert_equal("a", line[:name], "field name was not set")
+ assert_equal(:absent, line[:one], "field one was not set to absent")
+ end
- prov.target_object(:yayness).write "bill a c\njill b d"
+ # This test is because in x2puppet I was having problems where multiple
+ # retrievals somehow destroyed the 'is' values.
+ def test_value_retrieval
+ prov = mkprovider
+ prov.default_target = :yayness
- list = @type.instances
+ prov.target_object(:yayness).write "bill a c\njill b d"
- bill = list.find { |r| r[:name] == "bill" }
- jill = list.find { |r| r[:name] == "jill" }
- assert(bill, "Could not find bill")
- assert(jill, "Could not find jill")
+ list = @type.instances
- prov = bill.provider
+ bill = list.find { |r| r[:name] == "bill" }
+ jill = list.find { |r| r[:name] == "jill" }
+ assert(bill, "Could not find bill")
+ assert(jill, "Could not find jill")
- 4.times do |i|
- assert(prov.one, "Did not get a value for 'one' on try #{(i + 1)}")
- end
+ prov = bill.provider
- # First make sure we can retrieve values multiple times from the
- # provider
- bills_values = nil
- assert_nothing_raised do
- bills_values = bill.retrieve
- end
+ 4.times do |i|
+ assert(prov.one, "Did not get a value for 'one' on try #{(i + 1)}")
+ end
- assert(bills_values[bill.property(:one)],
- "Bill does not have a value for 'one'")
- assert(bills_values[bill.property(:one)],
- "Bill does not have a value for 'one' on second try")
- assert_nothing_raised do
- bill.retrieve
- end
- assert(bills_values[bill.property(:one)],
- "bill's value for 'one' disappeared")
+ # First make sure we can retrieve values multiple times from the
+ # provider
+ bills_values = nil
+ assert_nothing_raised do
+ bills_values = bill.retrieve
end
- # Make sure that creating a new resource finds existing records in memory
- def test_initialize_finds_records
- prov = mkprovider
- prov.default_target = :yayness
+ assert(bills_values[bill.property(:one)],
+ "Bill does not have a value for 'one'")
+ assert(bills_values[bill.property(:one)],
+ "Bill does not have a value for 'one' on second try")
+ assert_nothing_raised do
+ bill.retrieve
+ end
+ assert(bills_values[bill.property(:one)],
+ "bill's value for 'one' disappeared")
+ end
- prov.target_object(:yayness).write "bill a c\njill b d"
+ # Make sure that creating a new resource finds existing records in memory
+ def test_initialize_finds_records
+ prov = mkprovider
+ prov.default_target = :yayness
- prov.prefetch
+ prov.target_object(:yayness).write "bill a c\njill b d"
- # Now make a resource
- bill = @type.new :name => "bill"
+ prov.prefetch
- assert_equal("a", bill.provider.one, "Record was not found in memory")
- end
+ # Now make a resource
+ bill = @type.new :name => "bill"
- # Make sure invalid fields always show up as insync
- def test_invalid_fields
+ assert_equal("a", bill.provider.one, "Record was not found in memory")
+ end
- prov = @type.provide(
- :test, :parent => Puppet::Provider::ParsedFile,
+ # Make sure invalid fields always show up as insync
+ def test_invalid_fields
- :filetype => :ram, :default_target => :yayness) do
- record_line :test, :fields => %w{name two}
- end
- cleanup do @type.unprovide(:test) end
+ prov = @type.provide(
+ :test, :parent => Puppet::Provider::ParsedFile,
- bill = nil
- assert_nothing_raised do
- bill = @type.new :name => "bill",
- :one => "a", :two => "c"
- end
+ :filetype => :ram, :default_target => :yayness) do
+ record_line :test, :fields => %w{name two}
+ end
+ cleanup do @type.unprovide(:test) end
- assert_apply(bill)
+ bill = nil
+ assert_nothing_raised do
+ bill = @type.new :name => "bill",
+ :one => "a", :two => "c"
+ end
- prov.prefetch
- current_value = nil
- assert_nothing_raised do
- current_value = bill.retrieve
- end
+ assert_apply(bill)
- assert_events([], bill)
+ prov.prefetch
+ current_value = nil
+ assert_nothing_raised do
+ current_value = bill.retrieve
end
- # Make sure we call the prefetch hook at the right place.
- def test_prefetch_hook
+ assert_events([], bill)
+ end
+
+ # Make sure we call the prefetch hook at the right place.
+ def test_prefetch_hook
- prov = @type.provide(
- :test, :parent => Puppet::Provider::ParsedFile,
+ prov = @type.provide(
+ :test, :parent => Puppet::Provider::ParsedFile,
- :filetype => :ram, :default_target => :yayness) do
+ :filetype => :ram, :default_target => :yayness) do
- def self.prefetch_hook(records)
- records
- end
+ def self.prefetch_hook(records)
+ records
+ end
- record_line :test, :fields => %w{name two}
- end
- cleanup do @type.unprovide(:test) end
+ record_line :test, :fields => %w{name two}
+ end
+ cleanup do @type.unprovide(:test) end
- target = "target"
+ target = "target"
- records = [{:target => "nope"}]
- targeted = {:target => "target"}
- prov.send(:instance_variable_set, "@records", records)
- prov.expects(:retrieve).with(target).returns([targeted])
+ records = [{:target => "nope"}]
+ targeted = {:target => "target"}
+ prov.send(:instance_variable_set, "@records", records)
+ prov.expects(:retrieve).with(target).returns([targeted])
- prov.expects(:prefetch_hook).with([targeted]).returns([targeted])
+ prov.expects(:prefetch_hook).with([targeted]).returns([targeted])
- prov.prefetch_target(target)
- end
+ prov.prefetch_target(target)
+ end
- # #529
- def test_keep_content_with_target
- mkprovider
- @provider.filetype = :flat
- dpath = tempfile
- opath = tempfile
- @provider.default_target = dpath
+ # #529
+ def test_keep_content_with_target
+ mkprovider
+ @provider.filetype = :flat
+ dpath = tempfile
+ opath = tempfile
+ @provider.default_target = dpath
- dtarget = @provider.target_object(dpath)
- otarget = @provider.target_object(opath)
+ dtarget = @provider.target_object(dpath)
+ otarget = @provider.target_object(opath)
- dtarget.write("dname a c\n")
- otarget.write("oname b d\n")
+ dtarget.write("dname a c\n")
+ otarget.write("oname b d\n")
- # Now make a resource that targets elsewhat.
- res = @type.new(:name => "test", :one => "a", :two => "c", :target => opath)
+ # Now make a resource that targets elsewhat.
+ res = @type.new(:name => "test", :one => "a", :two => "c", :target => opath)
- assert(res.property(:target), "Target is a parameter, not a property")
+ assert(res.property(:target), "Target is a parameter, not a property")
- assert_apply(res)
+ assert_apply(res)
- assert_equal(
- "oname b d\ntest a c\n", otarget.read,
+ assert_equal(
+ "oname b d\ntest a c\n", otarget.read,
- "did not get correct results in specified target")
- end
+ "did not get correct results in specified target")
+ end
end
diff --git a/test/ral/providers/provider.rb b/test/ral/providers/provider.rb
index 2ea08e0..cb0b2a1 100755
--- a/test/ral/providers/provider.rb
+++ b/test/ral/providers/provider.rb
@@ -6,524 +6,524 @@ require 'puppettest'
require 'facter'
class TestProvider < Test::Unit::TestCase
- include PuppetTest
+ include PuppetTest
- def echo
- echo = Puppet::Util.binary("echo")
+ def echo
+ echo = Puppet::Util.binary("echo")
- raise "Could not find 'echo' binary; cannot complete test" unless echo
+ raise "Could not find 'echo' binary; cannot complete test" unless echo
- echo
+ echo
+ end
+
+ def newprovider
+ # Create our provider
+ provider = Class.new(Puppet::Provider) do
+ @name = :fakeprovider
end
+ provider.initvars
- def newprovider
- # Create our provider
- provider = Class.new(Puppet::Provider) do
- @name = :fakeprovider
- end
- provider.initvars
+ provider
+ end
- provider
+ def setup
+ super
+ @type = Puppet::Type.newtype(:provider_test) do
+ newparam(:name) {}
+ ensurable
end
-
- def setup
- super
- @type = Puppet::Type.newtype(:provider_test) do
- newparam(:name) {}
- ensurable
+ cleanup { Puppet::Type.rmtype(:provider_test) }
+ end
+
+ def test_confine_defaults_to_suitable
+
+ provider = newprovider
+ assert(provider.suitable?, "Marked unsuitable with no confines")
+ end
+
+ def test_confine_results
+ {
+ {:true => true} => true,
+ {:true => false} => false,
+ {:false => false} => true,
+ {:false => true} => false,
+ {:operatingsystem => Facter.value(:operatingsystem)} => true,
+ {:operatingsystem => :yayness} => false,
+ {:nothing => :yayness} => false,
+ {:exists => echo} => true,
+ {:exists => "/this/file/does/not/exist"} => false,
+ }.each do |hash, result|
+ provider = newprovider
+
+ # First test :true
+ hash.each do |test, val|
+ assert_nothing_raised do
+ provider.confine test => val
end
- cleanup { Puppet::Type.rmtype(:provider_test) }
- end
+ end
- def test_confine_defaults_to_suitable
+ assert_equal(result, provider.suitable?, "Failed for #{hash.inspect}")
- provider = newprovider
- assert(provider.suitable?, "Marked unsuitable with no confines")
+ provider.initvars
end
-
- def test_confine_results
- {
- {:true => true} => true,
- {:true => false} => false,
- {:false => false} => true,
- {:false => true} => false,
- {:operatingsystem => Facter.value(:operatingsystem)} => true,
- {:operatingsystem => :yayness} => false,
- {:nothing => :yayness} => false,
- {:exists => echo} => true,
- {:exists => "/this/file/does/not/exist"} => false,
- }.each do |hash, result|
- provider = newprovider
-
- # First test :true
- hash.each do |test, val|
- assert_nothing_raised do
- provider.confine test => val
- end
- end
-
- assert_equal(result, provider.suitable?, "Failed for #{hash.inspect}")
-
- provider.initvars
+ end
+
+ def test_multiple_confines_do_not_override
+ provider = newprovider
+
+ # Make sure multiple confines don't overwrite each other
+ provider.confine :true => false
+ assert(! provider.suitable?)
+ provider.confine :true => true
+ assert(! provider.suitable?)
+ end
+
+ def test_one_failed_confine_is_sufficient
+
+ provider = newprovider
+
+ # Make sure we test multiple of them, and that a single false wins
+ provider.confine :true => true, :false => false
+ assert(provider.suitable?)
+ provider.confine :true => false
+ assert(! provider.suitable?)
+ end
+
+ # #1197 - the binary should not be
+ def test_command_checks_for_binaries_each_time
+ provider = newprovider
+
+ provider.commands :testing => "/no/such/path"
+
+ provider.stubs(:binary).returns "/no/such/path"
+
+ provider.command(:testing)
+ assert_equal("/no/such/path", provider.command(:testing), "Did not return correct binary path")
+ end
+
+ def test_command
+ {:echo => "echo", :echo_with_path => echo, :missing => "nosuchcommand", :missing_qualified => "/path/to/nosuchcommand"}.each do |name, command|
+ provider = newprovider
+ assert_nothing_raised("Could not define command #{name} with argument #{command} for provider") do
+ provider.commands(name => command)
+ end
+
+ if name.to_s =~ /missing/
+ assert_nil(provider.command(name), "Somehow got a response for missing commands")
+ assert(! provider.suitable?, "Provider was considered suitable with missing command")
+ next # skip, since we don't do any validity checking here.
+ end
+
+ assert_equal(echo, provider.command(name), "Did not get correct path for echo")
+ assert(provider.suitable?, "Provider was not considered suitable with 'echo'")
+
+ # Now make sure they both work
+ inst = provider.new(nil)
+ [provider, inst].each do |thing|
+ assert_nothing_raised("Could not call #{command} on #{thing}") do
+ out = thing.send(name, "some", "text")
+ assert_equal("some text\n", out)
end
- end
+ end
- def test_multiple_confines_do_not_override
- provider = newprovider
+ assert(provider.suitable?, "Provider considered unsuitable")
- # Make sure multiple confines don't overwrite each other
- provider.confine :true => false
- assert(! provider.suitable?)
- provider.confine :true => true
- assert(! provider.suitable?)
- end
+ # Now add an invalid command
+ assert_nothing_raised do
+ provider.commands :fake => "nosuchcommanddefinitely"
+ end
+ assert(! provider.suitable?, "Provider considered suitable")
- def test_one_failed_confine_is_sufficient
+ assert_nil(provider.command(:fake), "Got a value for missing command")
+ assert_raise(Puppet::Error) do
+ provider.fake
+ end
- provider = newprovider
+ Puppet[:trace] = false
+ assert_raise(Puppet::DevError) do
+ provider.command(:nosuchcmd)
+ end
- # Make sure we test multiple of them, and that a single false wins
- provider.confine :true => true, :false => false
- assert(provider.suitable?)
- provider.confine :true => false
- assert(! provider.suitable?)
- end
+ # Lastly, verify that we can find our superclass commands
+ newprov = Class.new(provider)
+ newprov.initvars
- # #1197 - the binary should not be
- def test_command_checks_for_binaries_each_time
- provider = newprovider
+ assert_equal(echo, newprov.command(name))
+ end
+ end
- provider.commands :testing => "/no/such/path"
+ def test_default?
+ provider = newprovider
- provider.stubs(:binary).returns "/no/such/path"
+ assert(! provider.default?, "Was considered default with no settings")
- provider.command(:testing)
- assert_equal("/no/such/path", provider.command(:testing), "Did not return correct binary path")
+ assert_nothing_raised do
+ provider.defaultfor :operatingsystem => Facter.value(:operatingsystem)
end
- def test_command
- {:echo => "echo", :echo_with_path => echo, :missing => "nosuchcommand", :missing_qualified => "/path/to/nosuchcommand"}.each do |name, command|
- provider = newprovider
- assert_nothing_raised("Could not define command #{name} with argument #{command} for provider") do
- provider.commands(name => command)
- end
-
- if name.to_s =~ /missing/
- assert_nil(provider.command(name), "Somehow got a response for missing commands")
- assert(! provider.suitable?, "Provider was considered suitable with missing command")
- next # skip, since we don't do any validity checking here.
- end
-
- assert_equal(echo, provider.command(name), "Did not get correct path for echo")
- assert(provider.suitable?, "Provider was not considered suitable with 'echo'")
-
- # Now make sure they both work
- inst = provider.new(nil)
- [provider, inst].each do |thing|
- assert_nothing_raised("Could not call #{command} on #{thing}") do
- out = thing.send(name, "some", "text")
- assert_equal("some text\n", out)
- end
- end
-
- assert(provider.suitable?, "Provider considered unsuitable")
-
- # Now add an invalid command
- assert_nothing_raised do
- provider.commands :fake => "nosuchcommanddefinitely"
- end
- assert(! provider.suitable?, "Provider considered suitable")
-
- assert_nil(provider.command(:fake), "Got a value for missing command")
- assert_raise(Puppet::Error) do
- provider.fake
- end
-
- Puppet[:trace] = false
- assert_raise(Puppet::DevError) do
- provider.command(:nosuchcmd)
- end
-
- # Lastly, verify that we can find our superclass commands
- newprov = Class.new(provider)
- newprov.initvars
-
- assert_equal(echo, newprov.command(name))
- end
+ assert(provider.default?, "Was not considered default")
+
+ # Make sure any true value is sufficient.
+ assert_nothing_raised do
+ provider.defaultfor :operatingsystem => [
+ :yayness, :rahness,
+ Facter.value(:operatingsystem)
+ ]
end
- def test_default?
- provider = newprovider
+ assert(provider.default?, "Was not considered default")
- assert(! provider.default?, "Was considered default with no settings")
+ # Now make sure that a random setting returns false.
+ assert_nothing_raised do
+ provider.defaultfor :operatingsystem => :yayness
+ end
- assert_nothing_raised do
- provider.defaultfor :operatingsystem => Facter.value(:operatingsystem)
- end
+ assert(! provider.default?, "Was considered default")
+ end
- assert(provider.default?, "Was not considered default")
+ # Make sure that failed commands get their output in the error.
+ def test_outputonfailure
+ provider = newprovider
- # Make sure any true value is sufficient.
- assert_nothing_raised do
- provider.defaultfor :operatingsystem => [
- :yayness, :rahness,
- Facter.value(:operatingsystem)
- ]
- end
+ dir = tstdir
+ file = File.join(dir, "mycmd")
+ sh = Puppet::Util.binary("sh")
+ File.open(file, "w") { |f|
+ f.puts %{#!#{sh}
+ echo A Failure >&2
+ exit 2
+ }
+ }
+ File.chmod(0755, file)
- assert(provider.default?, "Was not considered default")
+ provider.commands :cmd => file
- # Now make sure that a random setting returns false.
- assert_nothing_raised do
- provider.defaultfor :operatingsystem => :yayness
- end
+ inst = provider.new(nil)
- assert(! provider.default?, "Was considered default")
+ assert_raise(Puppet::ExecutionFailure) do
+ inst.cmd "some", "arguments"
end
- # Make sure that failed commands get their output in the error.
- def test_outputonfailure
- provider = newprovider
-
- dir = tstdir
- file = File.join(dir, "mycmd")
- sh = Puppet::Util.binary("sh")
- File.open(file, "w") { |f|
- f.puts %{#!#{sh}
- echo A Failure >&2
- exit 2
- }
- }
- File.chmod(0755, file)
-
- provider.commands :cmd => file
+ out = nil
+ begin
+ inst.cmd "some", "arguments"
+ rescue Puppet::ExecutionFailure => detail
+ out = detail.to_s
+ end
- inst = provider.new(nil)
- assert_raise(Puppet::ExecutionFailure) do
- inst.cmd "some", "arguments"
- end
+ assert(
+ out =~ /A Failure/,
- out = nil
- begin
- inst.cmd "some", "arguments"
- rescue Puppet::ExecutionFailure => detail
- out = detail.to_s
- end
+ "Did not receive command output on failure")
- assert(
- out =~ /A Failure/,
+ assert(
+ out =~ /Execution of/,
- "Did not receive command output on failure")
+ "Did not receive info wrapper on failure")
+ end
+ def test_mk_resource_methods
+ prov = newprovider
+ resourcetype = Struct.new(:validproperties, :parameters)
+ m = resourcetype.new([:prop1, :prop2], [:param1, :param2])
+ prov.resource_type = m
- assert(
- out =~ /Execution of/,
-
- "Did not receive info wrapper on failure")
+ assert_nothing_raised("could not call mk_resource_methods") do
+ prov.mk_resource_methods
end
- def test_mk_resource_methods
- prov = newprovider
- resourcetype = Struct.new(:validproperties, :parameters)
- m = resourcetype.new([:prop1, :prop2], [:param1, :param2])
- prov.resource_type = m
-
- assert_nothing_raised("could not call mk_resource_methods") do
- prov.mk_resource_methods
- end
-
- obj = prov.new(nil)
+ obj = prov.new(nil)
- %w{prop1 prop2 param1 param2}.each do |param|
- assert(prov.public_method_defined?(param), "no getter for #{param}")
- assert(prov.public_method_defined?(param + "="), "no setter for #{param}")
+ %w{prop1 prop2 param1 param2}.each do |param|
+ assert(prov.public_method_defined?(param), "no getter for #{param}")
+ assert(prov.public_method_defined?(param + "="), "no setter for #{param}")
- assert_equal(
- :absent, obj.send(param),
+ assert_equal(
+ :absent, obj.send(param),
- "%s did not default to :absent")
- val = "testing #{param}"
- assert_nothing_raised("Could not call setter for #{param}") do
- obj.send(param + "=", val)
- end
+ "%s did not default to :absent")
+ val = "testing #{param}"
+ assert_nothing_raised("Could not call setter for #{param}") do
+ obj.send(param + "=", val)
+ end
- assert_equal(
- val, obj.send(param),
+ assert_equal(
+ val, obj.send(param),
- "did not get correct value for #{param}")
- end
+ "did not get correct value for #{param}")
end
+ end
- # Make sure optional commands get looked up but don't affect suitability.
- def test_optional_commands
- type = Puppet::Type.newtype(:optional_commands) {}
+ # Make sure optional commands get looked up but don't affect suitability.
+ def test_optional_commands
+ type = Puppet::Type.newtype(:optional_commands) {}
- cleanup { Puppet::Type.rmtype(:optional_commands) }
+ cleanup { Puppet::Type.rmtype(:optional_commands) }
- # Define a provider with mandatory commands
- required = type.provide(:required) {
- commands :missing => "/no/such/binary/definitely"
- }
+ # Define a provider with mandatory commands
+ required = type.provide(:required) {
+ commands :missing => "/no/such/binary/definitely"
+ }
- # And another with optional commands
- optional = type.provide(:optional) {
- optional_commands :missing => "/no/such/binary/definitely"
- }
+ # And another with optional commands
+ optional = type.provide(:optional) {
+ optional_commands :missing => "/no/such/binary/definitely"
+ }
- assert(! required.suitable?, "Provider with missing commands considered suitable")
- assert_nil(required.command(:missing), "Provider returned non-nil from missing command")
+ assert(! required.suitable?, "Provider with missing commands considered suitable")
+ assert_nil(required.command(:missing), "Provider returned non-nil from missing command")
- assert(optional.suitable?, "Provider with optional commands considered unsuitable")
- assert_nil(optional.command(:missing), "Provider returned non-nil from missing command")
+ assert(optional.suitable?, "Provider with optional commands considered unsuitable")
+ assert_nil(optional.command(:missing), "Provider returned non-nil from missing command")
- assert_raise(Puppet::Error, "Provider did not fail when missing command was called") do
- optional.missing
- end
+ assert_raise(Puppet::Error, "Provider did not fail when missing command was called") do
+ optional.missing
end
+ end
- # Disabling, since I might not keep this interface
- def disabled_test_read_and_each
- # Create a new provider
- provider = @type.provide(:testing)
+ # Disabling, since I might not keep this interface
+ def disabled_test_read_and_each
+ # Create a new provider
+ provider = @type.provide(:testing)
- assert_raise(Puppet::DevError, "Did not fail when :read was not overridden") do
- provider.read
- end
+ assert_raise(Puppet::DevError, "Did not fail when :read was not overridden") do
+ provider.read
+ end
- children = [:one, :two]
- provider.meta_def(:read) do
- children
- end
+ children = [:one, :two]
+ provider.meta_def(:read) do
+ children
+ end
- result = []
- assert_nothing_raised("could not call 'each' on provider class") do
- provider.each { |i| result << i }
- end
+ result = []
+ assert_nothing_raised("could not call 'each' on provider class") do
+ provider.each { |i| result << i }
+ end
- assert_equal(children, result, "did not get correct list from each")
+ assert_equal(children, result, "did not get correct list from each")
- assert_equal(children, provider.collect { |i| i }, "provider does not include enumerable")
- end
+ assert_equal(children, provider.collect { |i| i }, "provider does not include enumerable")
+ end
- def test_source
- base = @type.provide(:base)
+ def test_source
+ base = @type.provide(:base)
- assert_equal(:base, base.source, "source did not default correctly")
- assert_equal(:base, base.source, "source did not default correctly")
+ assert_equal(:base, base.source, "source did not default correctly")
+ assert_equal(:base, base.source, "source did not default correctly")
- sub = @type.provide(:sub, :parent => :base)
+ sub = @type.provide(:sub, :parent => :base)
- assert_equal(:sub, sub.source, "source did not default correctly for sub class")
- assert_equal(:sub, sub.source, "source did not default correctly for sub class")
+ assert_equal(:sub, sub.source, "source did not default correctly for sub class")
+ assert_equal(:sub, sub.source, "source did not default correctly for sub class")
- other = @type.provide(:other, :parent => :base, :source => :base)
+ other = @type.provide(:other, :parent => :base, :source => :base)
- assert_equal(:base, other.source, "source did not override")
- assert_equal(:base, other.source, "source did not override")
- end
+ assert_equal(:base, other.source, "source did not override")
+ assert_equal(:base, other.source, "source did not override")
+ end
- # Make sure we can initialize with either a resource or a hash, or none at all.
- def test_initialize
- test = @type.provide(:test)
+ # Make sure we can initialize with either a resource or a hash, or none at all.
+ def test_initialize
+ test = @type.provide(:test)
- inst = @type.new :name => "boo"
- prov = nil
- assert_nothing_raised("Could not init with a resource") do
- prov = test.new(inst)
- end
- assert_equal(prov.resource, inst, "did not set resource correctly")
- assert_equal(inst.name, prov.name, "did not get resource name")
+ inst = @type.new :name => "boo"
+ prov = nil
+ assert_nothing_raised("Could not init with a resource") do
+ prov = test.new(inst)
+ end
+ assert_equal(prov.resource, inst, "did not set resource correctly")
+ assert_equal(inst.name, prov.name, "did not get resource name")
- params = {:name => :one, :ensure => :present}
- assert_nothing_raised("Could not init with a hash") do
- prov = test.new(params)
- end
- assert_equal(params, prov.send(:instance_variable_get, "@property_hash"), "did not set resource correctly")
- assert_equal(:one, prov.name, "did not get name from hash")
+ params = {:name => :one, :ensure => :present}
+ assert_nothing_raised("Could not init with a hash") do
+ prov = test.new(params)
+ end
+ assert_equal(params, prov.send(:instance_variable_get, "@property_hash"), "did not set resource correctly")
+ assert_equal(:one, prov.name, "did not get name from hash")
- assert_nothing_raised("Could not init with no argument") do
- prov = test.new
- end
+ assert_nothing_raised("Could not init with no argument") do
+ prov = test.new
+ end
- assert_raise(Puppet::DevError, "did not fail when no name is present") do
- prov.name
- end
+ assert_raise(Puppet::DevError, "did not fail when no name is present") do
+ prov.name
end
+ end
end
class TestProviderFeatures < Test::Unit::TestCase
- include PuppetTest
+ include PuppetTest
- def setup
- super
- @type = Puppet::Type.newtype(:feature_test) do
- newparam(:name) {}
- ensurable
- end
- cleanup { Puppet::Type.rmtype(:feature_test) }
+ def setup
+ super
+ @type = Puppet::Type.newtype(:feature_test) do
+ newparam(:name) {}
+ ensurable
+ end
+ cleanup { Puppet::Type.rmtype(:feature_test) }
- @features = {:numeric => [:one, :two], :alpha => [:a, :b]}
+ @features = {:numeric => [:one, :two], :alpha => [:a, :b]}
- @features.each do |name, methods|
- assert_nothing_raised("Could not define features") do
- @type.feature(name, "boo", :methods => methods)
- end
+ @features.each do |name, methods|
+ assert_nothing_raised("Could not define features") do
+ @type.feature(name, "boo", :methods => methods)
+ end
+ end
+ end
+
+ # Give them the basic run-through.
+ def test_method_features
+ @providers = {:numbers => @features[:numeric], :letters => @features[:alpha]}
+ @providers[:both] = @features[:numeric] + @features[:alpha]
+ @providers[:mixed] = [:one, :b]
+ @providers[:neither] = [:something, :else]
+
+ @providers.each do |name, methods|
+ assert_nothing_raised("Could not create provider #{name}") do
+ @type.provide(name) do
+ methods.each do |name|
+ define_method(name) {}
+ end
end
+ end
end
- # Give them the basic run-through.
- def test_method_features
- @providers = {:numbers => @features[:numeric], :letters => @features[:alpha]}
- @providers[:both] = @features[:numeric] + @features[:alpha]
- @providers[:mixed] = [:one, :b]
- @providers[:neither] = [:something, :else]
-
- @providers.each do |name, methods|
- assert_nothing_raised("Could not create provider #{name}") do
- @type.provide(name) do
- methods.each do |name|
- define_method(name) {}
- end
- end
- end
+ resource = @type.new(:name => "foo")
+ {:numbers => [:numeric], :letters => [:alpha], :both => [:numeric, :alpha], :mixed => [], :neither => []}.each do |name, should|
+ should.sort! { |a,b| a.to_s <=> b.to_s }
+ provider = @type.provider(name)
+ assert(provider, "Could not find provider #{name}")
+ assert_equal(should, provider.features, "Provider #{name} has incorrect features")
+
+ inst = provider.new(resource)
+ # Make sure the boolean methods work on both the provider and
+ # instance.
+ @features.keys.each do |feature|
+ method = feature.to_s + "?"
+ assert(inst.respond_to?(method), "No boolean instance method for #{name} on #{feature}")
+ assert(provider.respond_to?(method), "No boolean class method for #{name} on #{feature}")
+
+ if should.include?(feature)
+ assert(provider.feature?(feature), "class missing feature? #{feature}")
+ assert(inst.feature?(feature), "instance missing feature? #{feature}")
+ assert(provider.send(method), "class missing feature #{feature}")
+ assert(inst.send(method), "instance missing feature #{feature}")
+ assert(inst.satisfies?(feature), "instance.satisfy #{feature} returned false")
+ else
+ assert(! provider.feature?(feature), "class has feature? #{feature}")
+ assert(! inst.feature?(feature), "instance has feature? #{feature}")
+ assert(! provider.send(method), "class has feature #{feature}")
+ assert(! inst.send(method), "instance has feature #{feature}")
+ assert(! inst.satisfies?(feature), "instance.satisfy #{feature} returned true")
+ end
end
- resource = @type.new(:name => "foo")
- {:numbers => [:numeric], :letters => [:alpha], :both => [:numeric, :alpha], :mixed => [], :neither => []}.each do |name, should|
- should.sort! { |a,b| a.to_s <=> b.to_s }
- provider = @type.provider(name)
- assert(provider, "Could not find provider #{name}")
- assert_equal(should, provider.features, "Provider #{name} has incorrect features")
-
- inst = provider.new(resource)
- # Make sure the boolean methods work on both the provider and
- # instance.
- @features.keys.each do |feature|
- method = feature.to_s + "?"
- assert(inst.respond_to?(method), "No boolean instance method for #{name} on #{feature}")
- assert(provider.respond_to?(method), "No boolean class method for #{name} on #{feature}")
-
- if should.include?(feature)
- assert(provider.feature?(feature), "class missing feature? #{feature}")
- assert(inst.feature?(feature), "instance missing feature? #{feature}")
- assert(provider.send(method), "class missing feature #{feature}")
- assert(inst.send(method), "instance missing feature #{feature}")
- assert(inst.satisfies?(feature), "instance.satisfy #{feature} returned false")
- else
- assert(! provider.feature?(feature), "class has feature? #{feature}")
- assert(! inst.feature?(feature), "instance has feature? #{feature}")
- assert(! provider.send(method), "class has feature #{feature}")
- assert(! inst.send(method), "instance has feature #{feature}")
- assert(! inst.satisfies?(feature), "instance.satisfy #{feature} returned true")
- end
- end
-
- end
-
- Puppet[:trace] = true
- Puppet::Type.loadall
- Puppet::Type.eachtype do |type|
- assert(type.respond_to?(:feature), "No features method defined for #{type.name}")
- end
- end
+ end
- def test_has_feature
- # Define a new feature that has no methods
- @type.feature(:nomeths, "desc")
+ Puppet[:trace] = true
+ Puppet::Type.loadall
+ Puppet::Type.eachtype do |type|
+ assert(type.respond_to?(:feature), "No features method defined for #{type.name}")
+ end
+ end
- # Define a provider with nothing
- provider = @type.provide(:nothing) {}
+ def test_has_feature
+ # Define a new feature that has no methods
+ @type.feature(:nomeths, "desc")
+ # Define a provider with nothing
+ provider = @type.provide(:nothing) {}
- assert(
- provider.respond_to?(:has_features),
- "Provider did not get 'has_features' method added")
+ assert(
+ provider.respond_to?(:has_features),
- assert(
- provider.respond_to?(:has_feature),
+ "Provider did not get 'has_features' method added")
- "Provider did not get the 'has_feature' alias method")
+ assert(
+ provider.respond_to?(:has_feature),
- # One with the numeric methods and nothing else
- @type.provide(:numbers) do
- define_method(:one) {}
- define_method(:two) {}
- end
+ "Provider did not get the 'has_feature' alias method")
- # Another with the numbers and a declaration
- @type.provide(:both) do
- define_method(:one) {}
- define_method(:two) {}
+ # One with the numeric methods and nothing else
+ @type.provide(:numbers) do
+ define_method(:one) {}
+ define_method(:two) {}
+ end
- has_feature :alpha
- end
+ # Another with the numbers and a declaration
+ @type.provide(:both) do
+ define_method(:one) {}
+ define_method(:two) {}
- # And just the declaration
- @type.provide(:letters) do
- has_feature :alpha
- end
+ has_feature :alpha
+ end
- # And a provider that declares it has our methodless feature.
- @type.provide(:none) do
- has_feature :nomeths
- end
+ # And just the declaration
+ @type.provide(:letters) do
+ has_feature :alpha
+ end
- should = {:nothing => [], :both => [:numeric, :alpha],
- :letters => [:alpha], :numbers => [:numeric],
- :none => [:nomeths]}
-
- should.each do |name, features|
- provider_class = @type.provider(name)
- provider = provider_class.new({})
-
- assert(provider, "did not get provider named #{name}")
- features.sort! { |a,b| a.to_s <=> b.to_s }
- assert_equal(features, provider.features, "Got incorrect feature list for provider instance #{name}")
- assert_equal(features, provider_class.features, "Got incorrect feature list for provider class #{name}")
- features.each do |feat|
- assert(provider.feature?(feat), "Provider instance #{name} did not have feature #{feat}")
- assert(provider_class.feature?(feat), "Provider class #{name} did not have feature #{feat}")
- end
- end
+ # And a provider that declares it has our methodless feature.
+ @type.provide(:none) do
+ has_feature :nomeths
end
- def test_supports_parameter?
- # Make some parameters for each setting
- @type.newparam(:neither) {}
- @type.newparam(:some, :required_features => :alpha)
- @type.newparam(:both, :required_features => [:alpha, :numeric])
-
- # and appropriate providers
- nope = @type.provide(:nope) {}
- maybe = @type.provide(:maybe) { has_feature(:alpha) }
- yep = @type.provide(:yep) { has_features(:alpha, :numeric) }
-
- # Now make sure our providers answer correctly.
- [nope, maybe, yep].each do |prov|
- assert(prov.respond_to?(:supports_parameter?), "#{prov.name} does not respond to :supports_parameter?")
- case prov.name
- when :nope
- supported = [:neither]
- un = [:some, :both]
- when :maybe
- supported = [:neither, :some]
- un = [:both]
- when :yep
- supported = [:neither, :some, :both]
- un = []
- end
-
- supported.each do |param|
- assert(prov.supports_parameter?(param), "#{param} was not supported by #{prov.name}")
- end
- un.each do |param|
- assert(! prov.supports_parameter?(param), "#{param} was incorrectly supported by #{prov.name}")
- end
- end
+ should = {:nothing => [], :both => [:numeric, :alpha],
+ :letters => [:alpha], :numbers => [:numeric],
+ :none => [:nomeths]}
+
+ should.each do |name, features|
+ provider_class = @type.provider(name)
+ provider = provider_class.new({})
+
+ assert(provider, "did not get provider named #{name}")
+ features.sort! { |a,b| a.to_s <=> b.to_s }
+ assert_equal(features, provider.features, "Got incorrect feature list for provider instance #{name}")
+ assert_equal(features, provider_class.features, "Got incorrect feature list for provider class #{name}")
+ features.each do |feat|
+ assert(provider.feature?(feat), "Provider instance #{name} did not have feature #{feat}")
+ assert(provider_class.feature?(feat), "Provider class #{name} did not have feature #{feat}")
+ end
+ end
+ end
+
+ def test_supports_parameter?
+ # Make some parameters for each setting
+ @type.newparam(:neither) {}
+ @type.newparam(:some, :required_features => :alpha)
+ @type.newparam(:both, :required_features => [:alpha, :numeric])
+
+ # and appropriate providers
+ nope = @type.provide(:nope) {}
+ maybe = @type.provide(:maybe) { has_feature(:alpha) }
+ yep = @type.provide(:yep) { has_features(:alpha, :numeric) }
+
+ # Now make sure our providers answer correctly.
+ [nope, maybe, yep].each do |prov|
+ assert(prov.respond_to?(:supports_parameter?), "#{prov.name} does not respond to :supports_parameter?")
+ case prov.name
+ when :nope
+ supported = [:neither]
+ un = [:some, :both]
+ when :maybe
+ supported = [:neither, :some]
+ un = [:both]
+ when :yep
+ supported = [:neither, :some, :both]
+ un = []
+ end
+
+ supported.each do |param|
+ assert(prov.supports_parameter?(param), "#{param} was not supported by #{prov.name}")
+ end
+ un.each do |param|
+ assert(! prov.supports_parameter?(param), "#{param} was incorrectly supported by #{prov.name}")
+ end
end
+ end
end
diff --git a/test/ral/providers/service/base.rb b/test/ral/providers/service/base.rb
index ffaf598..82d36ab 100755
--- a/test/ral/providers/service/base.rb
+++ b/test/ral/providers/service/base.rb
@@ -8,73 +8,73 @@ require File.dirname(__FILE__) + '/../../../lib/puppettest'
require 'puppettest'
class TestBaseServiceProvider < Test::Unit::TestCase
- include PuppetTest
+ include PuppetTest
- def test_base
- running = tempfile
+ def test_base
+ running = tempfile
- commands = {}
- %w{touch rm test}.each do |c|
- path = %x{which #{c}}.chomp
- if path == ""
- $stderr.puts "Cannot find '#{c}'; cannot test base service provider"
- return
- end
- commands[c.to_sym] = path
- end
+ commands = {}
+ %w{touch rm test}.each do |c|
+ path = %x{which #{c}}.chomp
+ if path == ""
+ $stderr.puts "Cannot find '#{c}'; cannot test base service provider"
+ return
+ end
+ commands[c.to_sym] = path
+ end
- service = Puppet::Type.type(:service).new(
+ service = Puppet::Type.type(:service).new(
- :name => "yaytest", :provider => :base,
- :start => "#{commands[:touch]} #{running}",
- :status => "#{commands[:test]} -f #{running}",
+ :name => "yaytest", :provider => :base,
+ :start => "#{commands[:touch]} #{running}",
+ :status => "#{commands[:test]} -f #{running}",
- :stop => "#{commands[:rm]} #{running}"
- )
+ :stop => "#{commands[:rm]} #{running}"
+ )
- provider = service.provider
- assert(provider, "did not get base provider")
+ provider = service.provider
+ assert(provider, "did not get base provider")
- assert_nothing_raised do
- provider.start
- end
- assert(FileTest.exists?(running), "start was not called correctly")
- assert_nothing_raised do
- assert_equal(:running, provider.status, "status was not returned correctly")
- end
- assert_nothing_raised do
- provider.stop
- end
- assert(! FileTest.exists?(running), "stop was not called correctly")
- assert_nothing_raised do
- assert_equal(:stopped, provider.status, "status was not returned correctly")
- end
+ assert_nothing_raised do
+ provider.start
+ end
+ assert(FileTest.exists?(running), "start was not called correctly")
+ assert_nothing_raised do
+ assert_equal(:running, provider.status, "status was not returned correctly")
+ end
+ assert_nothing_raised do
+ provider.stop
+ end
+ assert(! FileTest.exists?(running), "stop was not called correctly")
+ assert_nothing_raised do
+ assert_equal(:stopped, provider.status, "status was not returned correctly")
end
+ end
- # Testing #454
- def test_that_failures_propagate
- nope = "/no/such/command"
+ # Testing #454
+ def test_that_failures_propagate
+ nope = "/no/such/command"
- service = Puppet::Type.type(:service).new(
+ service = Puppet::Type.type(:service).new(
- :name => "yaytest", :provider => :base,
- :start => nope,
- :status => nope,
- :stop => nope,
+ :name => "yaytest", :provider => :base,
+ :start => nope,
+ :status => nope,
+ :stop => nope,
- :restart => nope
- )
+ :restart => nope
+ )
- provider = service.provider
- assert(provider, "did not get base provider")
+ provider = service.provider
+ assert(provider, "did not get base provider")
- # We can't fail well when status is messed up, because we depend on the return code
- # of the command for data.
- %w{start stop restart}.each do |command|
- assert_raise(Puppet::Error, "did not throw error when #{command} failed") do
- provider.send(command)
- end
- end
+ # We can't fail well when status is messed up, because we depend on the return code
+ # of the command for data.
+ %w{start stop restart}.each do |command|
+ assert_raise(Puppet::Error, "did not throw error when #{command} failed") do
+ provider.send(command)
+ end
end
+ end
end
diff --git a/test/ral/providers/sshkey/parsed.rb b/test/ral/providers/sshkey/parsed.rb
index 2b4d3a6..f21158f 100755
--- a/test/ral/providers/sshkey/parsed.rb
+++ b/test/ral/providers/sshkey/parsed.rb
@@ -6,107 +6,107 @@ require 'puppettest'
require 'puppettest/fileparsing'
class TestParsedSSHKey < Test::Unit::TestCase
- include PuppetTest
- include PuppetTest::FileParsing
-
- def setup
- super
- @provider = Puppet::Type.type(:sshkey).provider(:parsed)
-
- @oldfiletype = @provider.filetype
+ include PuppetTest
+ include PuppetTest::FileParsing
+
+ def setup
+ super
+ @provider = Puppet::Type.type(:sshkey).provider(:parsed)
+
+ @oldfiletype = @provider.filetype
+ end
+
+ def teardown
+ Puppet::Util::FileType.filetype(:ram).clear
+ @provider.filetype = @oldfiletype
+ @provider.clear
+ super
+ end
+
+ def mkkey(name = "host.domain.com")
+ if defined?(@pcount)
+ @pcount += 1
+ else
+ @pcount = 1
end
-
- def teardown
- Puppet::Util::FileType.filetype(:ram).clear
- @provider.filetype = @oldfiletype
- @provider.clear
- super
+ args = {
+ :name => name || "/fspuppet#{@pcount}",
+ :key => "thisismykey#{@pcount}",
+ :host_aliases => ["host1.domain.com","192.168.0.1"],
+ :type => "dss",
+ :ensure => :present
+ }
+
+ fakeresource = fakeresource(:sshkey, args[:name])
+
+ key = @provider.new(fakeresource)
+ args.each do |p,v|
+ key.send(p.to_s + "=", v)
end
- def mkkey(name = "host.domain.com")
- if defined?(@pcount)
- @pcount += 1
- else
- @pcount = 1
- end
- args = {
- :name => name || "/fspuppet#{@pcount}",
- :key => "thisismykey#{@pcount}",
- :host_aliases => ["host1.domain.com","192.168.0.1"],
- :type => "dss",
- :ensure => :present
- }
-
- fakeresource = fakeresource(:sshkey, args[:name])
-
- key = @provider.new(fakeresource)
- args.each do |p,v|
- key.send(p.to_s + "=", v)
- end
-
- key
- end
+ key
+ end
- def test_keysparse
- fakedata("data/types/sshkey").each { |file|
- fakedataparse(file)
- }
- end
+ def test_keysparse
+ fakedata("data/types/sshkey").each { |file|
+ fakedataparse(file)
+ }
+ end
+
+ def test_simplekey
+ @provider.filetype = :ram
+ file = @provider.default_target
- def test_simplekey
- @provider.filetype = :ram
- file = @provider.default_target
+ key = nil
+ assert_nothing_raised do
+ key = mkkey
+ end
- key = nil
- assert_nothing_raised do
- key = mkkey
- end
+ assert(key, "did not create key")
- assert(key, "did not create key")
+ assert_nothing_raised do
+ key.flush
+ end
- assert_nothing_raised do
- key.flush
- end
+ assert(key.host_aliases, "No host_aliases set for key")
- assert(key.host_aliases, "No host_aliases set for key")
+ hash = key.property_hash.dup
+ text = @provider.target_object(file).read
+ names = [key.name, key.host_aliases].flatten.join(",")
- hash = key.property_hash.dup
- text = @provider.target_object(file).read
- names = [key.name, key.host_aliases].flatten.join(",")
+ assert_equal("#{names} #{key.type} #{key.key}\n", text)
- assert_equal("#{names} #{key.type} #{key.key}\n", text)
+ assert_nothing_raised do
+ @provider.prefetch
+ end
- assert_nothing_raised do
- @provider.prefetch
- end
+ hash.each do |p, v|
+ next unless key.respond_to?(p)
+ assert_equal(v, key.send(p), "#{p} did not match")
+ end
- hash.each do |p, v|
- next unless key.respond_to?(p)
- assert_equal(v, key.send(p), "#{p} did not match")
- end
+ assert(key.name !~ /,/, "Aliases were not split out during parsing")
+ end
- assert(key.name !~ /,/, "Aliases were not split out during parsing")
+ def test_hooks
+ result = nil
+ assert_nothing_raised("Could not call post hook") do
+ result = @provider.parse_line("one,two type key")
end
+ assert_equal("one", result[:name], "Did not call post hook")
+ assert_equal(%w{two}, result[:host_aliases], "Did not call post hook")
+
- def test_hooks
- result = nil
- assert_nothing_raised("Could not call post hook") do
- result = @provider.parse_line("one,two type key")
- end
- assert_equal("one", result[:name], "Did not call post hook")
- assert_equal(%w{two}, result[:host_aliases], "Did not call post hook")
-
-
- assert_equal(
- "one,two type key",
- @provider.to_line(:record_type => :parsed,
- :name => "one",
- :host_aliases => %w{two},
- :type => "type",
+ assert_equal(
+ "one,two type key",
+ @provider.to_line(:record_type => :parsed,
+ :name => "one",
+ :host_aliases => %w{two},
+ :type => "type",
- :key => "key"),
- "Did not use pre-hook when generating line"
- )
- end
+ :key => "key"),
+ "Did not use pre-hook when generating line"
+ )
+ end
end
diff --git a/test/ral/providers/user.rb b/test/ral/providers/user.rb
index 628d88a..64f833f 100755
--- a/test/ral/providers/user.rb
+++ b/test/ral/providers/user.rb
@@ -6,581 +6,581 @@ require 'puppettest'
require 'puppettest/support/utils'
class TestUserProvider < Test::Unit::TestCase
- include PuppetTest::Support::Utils
- include PuppetTest::FileTesting
+ include PuppetTest::Support::Utils
+ include PuppetTest::FileTesting
- def setup
- super
- setme
- @@tmpusers = []
- @provider = nil
- assert_nothing_raised {
- @provider = Puppet::Type.type(:user).defaultprovider
- }
+ def setup
+ super
+ setme
+ @@tmpusers = []
+ @provider = nil
+ assert_nothing_raised {
+ @provider = Puppet::Type.type(:user).defaultprovider
+ }
- assert(@provider, "Could not find default user provider")
+ assert(@provider, "Could not find default user provider")
- end
+ end
- def teardown
- @@tmpusers.each { |user|
- remove(user) unless missing?(user)
- }
- super
- end
+ def teardown
+ @@tmpusers.each { |user|
+ remove(user) unless missing?(user)
+ }
+ super
+ end
- case Facter["operatingsystem"].value
- when "Darwin"
- def missing?(user)
- output = %x{nidump -r /users/#{user} / 2>/dev/null}.chomp
+ case Facter["operatingsystem"].value
+ when "Darwin"
+ def missing?(user)
+ output = %x{nidump -r /users/#{user} / 2>/dev/null}.chomp
- return output == ""
+ return output == ""
- assert_equal("", output, "User #{user} is present:\n#{output}")
- end
+ assert_equal("", output, "User #{user} is present:\n#{output}")
+ end
- def current?(param, user)
- property = Puppet::Type.type(:user).properties.find { |st|
- st.name == param
- }
-
- prov = Puppet::Type.type(:user).defaultprovider
- output = prov.report(param)
- output.each { |hash|
- if hash[:name] == user.name
- val = hash[param]
- if val =~ /^[-0-9]+$/
- return Integer(val)
- else
- return val
- end
- end
- }
-
- nil
+ def current?(param, user)
+ property = Puppet::Type.type(:user).properties.find { |st|
+ st.name == param
+ }
+
+ prov = Puppet::Type.type(:user).defaultprovider
+ output = prov.report(param)
+ output.each { |hash|
+ if hash[:name] == user.name
+ val = hash[param]
+ if val =~ /^[-0-9]+$/
+ return Integer(val)
+ else
+ return val
+ end
end
+ }
- def remove(user)
- system("niutil -destroy / /users/#{user}")
- end
- else
- def missing?(user)
- obj = Etc.getpwnam(user)
- return false
- rescue ArgumentError
- return true
- end
+ nil
+ end
- def current?(param, user)
- property = Puppet::Type.type(:user).properties.find { |st|
- st.name == param
- }
+ def remove(user)
+ system("niutil -destroy / /users/#{user}")
+ end
+ else
+ def missing?(user)
+ obj = Etc.getpwnam(user)
+ return false
+ rescue ArgumentError
+ return true
+ end
- assert_nothing_raised {
- obj = Etc.getpwnam(user.name)
- return obj.send(user.posixmethod(param))
- }
+ def current?(param, user)
+ property = Puppet::Type.type(:user).properties.find { |st|
+ st.name == param
+ }
- nil
- end
+ assert_nothing_raised {
+ obj = Etc.getpwnam(user.name)
+ return obj.send(user.posixmethod(param))
+ }
- def remove(user)
- system("userdel #{user}")
- end
+ nil
end
-
- def eachproperty
- Puppet::Type.type(:user).validproperties.each do |property|
- yield property
- end
+ def remove(user)
+ system("userdel #{user}")
end
+ end
- def findshell(old = nil)
- %w{/bin/sh /bin/bash /sbin/sh /bin/ksh /bin/zsh /bin/csh /bin/tcsh
- /usr/bin/sh /usr/bin/bash /usr/bin/ksh /usr/bin/zsh /usr/bin/csh
- /usr/bin/tcsh}.find { |shell|
- if old
- FileTest.exists?(shell) and shell != old
- else
- FileTest.exists?(shell)
- end
- }
- end
- def fakedata(name, param)
- case param
- when :name; name
- when :ensure; :present
- when :comment; "Puppet's Testing User #{name}" # use a single quote a la #375
- when :gid; nonrootgroup.gid
- when :shell; findshell
- when :home; "/home/#{name}"
+ def eachproperty
+ Puppet::Type.type(:user).validproperties.each do |property|
+ yield property
+ end
+ end
+
+ def findshell(old = nil)
+ %w{/bin/sh /bin/bash /sbin/sh /bin/ksh /bin/zsh /bin/csh /bin/tcsh
+ /usr/bin/sh /usr/bin/bash /usr/bin/ksh /usr/bin/zsh /usr/bin/csh
+ /usr/bin/tcsh}.find { |shell|
+ if old
+ FileTest.exists?(shell) and shell != old
else
- return nil
+ FileTest.exists?(shell)
end
+ }
+ end
+
+ def fakedata(name, param)
+ case param
+ when :name; name
+ when :ensure; :present
+ when :comment; "Puppet's Testing User #{name}" # use a single quote a la #375
+ when :gid; nonrootgroup.gid
+ when :shell; findshell
+ when :home; "/home/#{name}"
+ else
+ return nil
end
-
- def fakeresource(*args)
- resource = super
-
- # Set boolean methods as necessary.
- class << resource
- def allowdupe?
- self[:allowdupe]
- end
- def managehome?
- self[:managehome]
- end
- end
- resource
+ end
+
+ def fakeresource(*args)
+ resource = super
+
+ # Set boolean methods as necessary.
+ class << resource
+ def allowdupe?
+ self[:allowdupe]
+ end
+ def managehome?
+ self[:managehome]
+ end
end
-
- def mkuser(name)
- fakeresource = fakeresource(:user, name)
- user = nil
- assert_nothing_raised {
- user = @provider.new(fakeresource)
- }
- assert(user, "Could not create provider user")
-
- user
+ resource
+ end
+
+ def mkuser(name)
+ fakeresource = fakeresource(:user, name)
+ user = nil
+ assert_nothing_raised {
+ user = @provider.new(fakeresource)
+ }
+ assert(user, "Could not create provider user")
+
+ user
+ end
+
+ def test_list
+ names = nil
+ assert_nothing_raised {
+ names = @provider.listbyname
+ }
+
+ assert(names.length > 0, "Listed no users")
+
+ # Now try it by object
+ assert_nothing_raised {
+ names = @provider.instances
+ }
+ assert(names.length > 0, "Listed no users as objects")
+
+ names.each do |obj|
+ assert_instance_of(@provider, obj)
end
+ end
- def test_list
- names = nil
- assert_nothing_raised {
- names = @provider.listbyname
- }
+ def test_infocollection
+ fakeresource = fakeresource(:user, @me)
- assert(names.length > 0, "Listed no users")
+ user = nil
+ assert_nothing_raised {
+ user = @provider.new(fakeresource)
+ }
+ assert(user, "Could not create user provider")
- # Now try it by object
- assert_nothing_raised {
- names = @provider.instances
- }
- assert(names.length > 0, "Listed no users as objects")
+ Puppet::Type.type(:user).validproperties.each do |property|
+ next if property == :ensure
+ # This is mostly in place for the 'password' stuff.
+ next unless user.class.supports_parameter?(property) and Puppet.features.root?
+ val = nil
+ assert_nothing_raised {
+ val = user.send(property)
+ }
- names.each do |obj|
- assert_instance_of(@provider, obj)
- end
- end
- def test_infocollection
- fakeresource = fakeresource(:user, @me)
+ assert(
+ val != :absent,
- user = nil
- assert_nothing_raised {
- user = @provider.new(fakeresource)
- }
- assert(user, "Could not create user provider")
+ "Property #{property} is missing")
- Puppet::Type.type(:user).validproperties.each do |property|
- next if property == :ensure
- # This is mostly in place for the 'password' stuff.
- next unless user.class.supports_parameter?(property) and Puppet.features.root?
- val = nil
- assert_nothing_raised {
- val = user.send(property)
- }
+ assert(val, "Did not get value for #{property}")
+ end
+ end
+ def test_exists
+ user = mkuser("nosuchuserok")
- assert(
- val != :absent,
- "Property #{property} is missing")
+ assert(
+ ! user.exists?,
- assert(val, "Did not get value for #{property}")
- end
- end
+ "Fake user exists?")
- def test_exists
- user = mkuser("nosuchuserok")
+ user = mkuser(@me)
+ assert(
+ user.exists?,
- assert(
- ! user.exists?,
+ "I don't exist?")
+ end
- "Fake user exists?")
+ def attrtest_ensure(user)
+ old = user.ensure
+ assert_nothing_raised {
+ user.delete
+ }
- user = mkuser(@me)
+ assert(missing?(user.name), "User is still present")
+ assert_nothing_raised {
+ user.create
+ }
+ assert(!missing?(user.name), "User is absent")
+ assert_nothing_raised {
+ user.delete
+ }
- assert(
- user.exists?,
-
- "I don't exist?")
+ unless old == :absent
+ user.create
end
+ end
- def attrtest_ensure(user)
- old = user.ensure
- assert_nothing_raised {
- user.delete
- }
-
- assert(missing?(user.name), "User is still present")
- assert_nothing_raised {
- user.create
- }
- assert(!missing?(user.name), "User is absent")
- assert_nothing_raised {
- user.delete
- }
-
- unless old == :absent
- user.create
- end
- end
+ def attrtest_comment(user)
+ old = user.comment
- def attrtest_comment(user)
- old = user.comment
+ newname = "Billy O'Neal" # use a single quote, a la #372
+ assert_nothing_raised {
+ user.comment = newname
+ }
- newname = "Billy O'Neal" # use a single quote, a la #372
- assert_nothing_raised {
- user.comment = newname
- }
+ assert_equal(
+ newname, current?(:comment, user),
- assert_equal(
- newname, current?(:comment, user),
+ "Comment was not changed")
- "Comment was not changed")
+ assert_nothing_raised {
+ user.comment = old
+ }
- assert_nothing_raised {
- user.comment = old
- }
+ assert_equal(
+ old, current?(:comment, user),
- assert_equal(
- old, current?(:comment, user),
+ "Comment was not reverted")
+ end
- "Comment was not reverted")
- end
+ def attrtest_home(user)
+ old = current?(:home, user)
- def attrtest_home(user)
- old = current?(:home, user)
+ assert_nothing_raised {
+ user.home = "/tmp"
+ }
- assert_nothing_raised {
- user.home = "/tmp"
- }
+ assert_equal("/tmp", current?(:home, user), "Home was not changed")
+ assert_nothing_raised {
+ user.home = old
+ }
- assert_equal("/tmp", current?(:home, user), "Home was not changed")
- assert_nothing_raised {
- user.home = old
- }
+ assert_equal(old, current?(:home, user), "Home was not reverted")
+ end
- assert_equal(old, current?(:home, user), "Home was not reverted")
- end
+ def attrtest_shell(user)
+ old = current?(:shell, user)
- def attrtest_shell(user)
- old = current?(:shell, user)
+ newshell = findshell(old)
- newshell = findshell(old)
+ unless newshell
+ $stderr.puts "Cannot find alternate shell; skipping shell test"
+ return
+ end
- unless newshell
- $stderr.puts "Cannot find alternate shell; skipping shell test"
- return
- end
+ assert_nothing_raised {
+ user.shell = newshell
+ }
- assert_nothing_raised {
- user.shell = newshell
- }
+ assert_equal(
+ newshell, current?(:shell, user),
- assert_equal(
- newshell, current?(:shell, user),
+ "Shell was not changed")
- "Shell was not changed")
+ assert_nothing_raised {
+ user.shell = old
+ }
- assert_nothing_raised {
- user.shell = old
- }
+ assert_equal(old, current?(:shell, user), "Shell was not reverted")
+ end
- assert_equal(old, current?(:shell, user), "Shell was not reverted")
- end
+ def attrtest_gid(user)
+ old = current?(:gid, user)
- def attrtest_gid(user)
- old = current?(:gid, user)
-
- newgroup = %w{nogroup nobody staff users daemon}.find { |gid|
- begin
- group = Etc.getgrnam(gid)
- rescue ArgumentError => detail
- next
- end
- old != group.gid
- }
- group = Etc.getgrnam(newgroup)
-
- unless newgroup
- $stderr.puts "Cannot find alternate group; skipping gid test"
- return
+ newgroup = %w{nogroup nobody staff users daemon}.find { |gid|
+ begin
+ group = Etc.getgrnam(gid)
+ rescue ArgumentError => detail
+ next
end
+ old != group.gid
+ }
+ group = Etc.getgrnam(newgroup)
- # Stupid DirectoryServices
- if Facter.value(:operatingsystem) == "Darwin"
- assert_raise(ArgumentError, "gid allowed a non-integer value") do
- user.gid = group.name
- end
- end
-
- assert_nothing_raised("Failed to specify group by id") {
- user.gid = group.gid
- }
-
- assert_equal(group.gid, current?(:gid,user), "GID was not changed")
-
- assert_nothing_raised("Failed to change back to old gid") {
- user.gid = old
- }
+ unless newgroup
+ $stderr.puts "Cannot find alternate group; skipping gid test"
+ return
end
- def attrtest_uid(user)
- old = current?(:uid, user)
-
- newuid = old
- while true
- newuid += 1
-
- if newuid - old > 1000
- $stderr.puts "Could not find extra test UID"
- return
- end
- begin
- newuser = Etc.getpwuid(newuid)
- rescue ArgumentError => detail
- break
- end
- end
-
- assert_nothing_raised("Failed to change user id") {
- user.uid = newuid
- }
-
- assert_equal(newuid, current?(:uid, user), "UID was not changed")
-
- assert_nothing_raised("Failed to change user id") {
- user.uid = old
- }
- assert_equal(old, current?(:uid, user), "UID was not changed back")
+ # Stupid DirectoryServices
+ if Facter.value(:operatingsystem) == "Darwin"
+ assert_raise(ArgumentError, "gid allowed a non-integer value") do
+ user.gid = group.name
+ end
end
- def attrtest_groups(user)
- Etc.setgrent
- max = 0
- while group = Etc.getgrent
- max = group.gid if group.gid > max and group.gid < 5000
- end
-
- groups = []
- main = []
- extra = []
- 5.times do |i|
- i += 1
- name = "pptstgr#{i}"
+ assert_nothing_raised("Failed to specify group by id") {
+ user.gid = group.gid
+ }
+
+ assert_equal(group.gid, current?(:gid,user), "GID was not changed")
+
+ assert_nothing_raised("Failed to change back to old gid") {
+ user.gid = old
+ }
+ end
+
+ def attrtest_uid(user)
+ old = current?(:uid, user)
+
+ newuid = old
+ while true
+ newuid += 1
+
+ if newuid - old > 1000
+ $stderr.puts "Could not find extra test UID"
+ return
+ end
+ begin
+ newuser = Etc.getpwuid(newuid)
+ rescue ArgumentError => detail
+ break
+ end
+ end
- tmpgroup = Puppet::Type.type(:group).new(
+ assert_nothing_raised("Failed to change user id") {
+ user.uid = newuid
+ }
- :name => name,
+ assert_equal(newuid, current?(:uid, user), "UID was not changed")
- :gid => max + i
- )
+ assert_nothing_raised("Failed to change user id") {
+ user.uid = old
+ }
+ assert_equal(old, current?(:uid, user), "UID was not changed back")
+ end
- groups << tmpgroup
+ def attrtest_groups(user)
+ Etc.setgrent
+ max = 0
+ while group = Etc.getgrent
+ max = group.gid if group.gid > max and group.gid < 5000
+ end
- cleanup do
- tmpgroup.provider.delete if tmpgroup.provider.exists?
- end
+ groups = []
+ main = []
+ extra = []
+ 5.times do |i|
+ i += 1
+ name = "pptstgr#{i}"
- if i < 3
- main << name
- else
- extra << name
- end
- end
+ tmpgroup = Puppet::Type.type(:group).new(
- # Create our test groups
- assert_apply(*groups)
+ :name => name,
- # Now add some of them to our user
- assert_nothing_raised {
- user.resource[:groups] = extra.join(",")
- }
+ :gid => max + i
+ )
- # Some tests to verify that groups work correctly startig from nothing
- # Remove our user
- user.delete
+ groups << tmpgroup
- # And add it again
- user.create
+ cleanup do
+ tmpgroup.provider.delete if tmpgroup.provider.exists?
+ end
- # Make sure that the group list is added at creation time.
- # This is necessary because we don't have default fakedata for groups.
- assert(user.groups, "Did not retrieve group list")
+ if i < 3
+ main << name
+ else
+ extra << name
+ end
+ end
- list = user.groups.split(",")
- assert_equal(extra.sort, list.sort, "Group list was not set at creation time")
+ # Create our test groups
+ assert_apply(*groups)
- # Now set to our main list of groups
- assert_nothing_raised {
- user.groups = main.join(",")
- }
+ # Now add some of them to our user
+ assert_nothing_raised {
+ user.resource[:groups] = extra.join(",")
+ }
- list = user.groups.split(",")
- assert_equal(main.sort, list.sort, "Group list is not equal")
- end
+ # Some tests to verify that groups work correctly startig from nothing
+ # Remove our user
+ user.delete
- if Puppet.features.root?
- def test_simpleuser
- name = "pptest"
+ # And add it again
+ user.create
- assert(missing?(name), "User #{name} is present")
+ # Make sure that the group list is added at creation time.
+ # This is necessary because we don't have default fakedata for groups.
+ assert(user.groups, "Did not retrieve group list")
- user = mkuser(name)
+ list = user.groups.split(",")
+ assert_equal(extra.sort, list.sort, "Group list was not set at creation time")
- eachproperty do |property|
- if val = fakedata(user.name, property)
- user.resource[property] = val
- end
- end
+ # Now set to our main list of groups
+ assert_nothing_raised {
+ user.groups = main.join(",")
+ }
- @@tmpusers << name
+ list = user.groups.split(",")
+ assert_equal(main.sort, list.sort, "Group list is not equal")
+ end
- assert_nothing_raised {
- user.create
- }
+ if Puppet.features.root?
+ def test_simpleuser
+ name = "pptest"
- assert_equal("Puppet's Testing User pptest",
- user.comment,
- "Comment was not set")
+ assert(missing?(name), "User #{name} is present")
- assert_nothing_raised {
- user.delete
- }
+ user = mkuser(name)
- assert(missing?(user.name), "User was not deleted")
+ eachproperty do |property|
+ if val = fakedata(user.name, property)
+ user.resource[property] = val
end
+ end
- def test_alluserproperties
- user = nil
- name = "pptest"
+ @@tmpusers << name
- assert(missing?(name), "User #{name} is present")
-
- user = mkuser(name)
+ assert_nothing_raised {
+ user.create
+ }
- eachproperty do |property|
- if val = fakedata(user.name, property)
- user.resource[property] = val
- end
- end
+ assert_equal("Puppet's Testing User pptest",
+ user.comment,
+ "Comment was not set")
- @@tmpusers << name
+ assert_nothing_raised {
+ user.delete
+ }
- assert_nothing_raised {
- user.create
- }
- assert_equal("Puppet's Testing User pptest", user.comment,
- "Comment was not set")
+ assert(missing?(user.name), "User was not deleted")
+ end
- tests = Puppet::Type.type(:user).validproperties
+ def test_alluserproperties
+ user = nil
+ name = "pptest"
- just = nil
- tests.each { |test|
- if self.respond_to?("attrtest_#{test}")
- self.send("attrtest_#{test}", user)
- else
- Puppet.err "Not testing attr #{test} of user"
- end
- }
+ assert(missing?(name), "User #{name} is present")
- assert_nothing_raised {
- user.delete
- }
- end
+ user = mkuser(name)
- # This is a weird method that shows how annoying the interface between
- # types and providers is. Grr.
- def test_duplicateIDs
- user1 = mkuser("user1")
- user1.create
- user1.uid = 125
- user2 = mkuser("user2")
- user2.resource[:uid] = 125
-
- cleanup do
- user1.delete
- user2.delete
- end
-
- # Not all OSes fail here, so we can't test that it doesn't work with
- # it off, only that it does work with it on.
- assert_nothing_raised {
- user2.resource[:allowdupe] = :true
- }
- assert_nothing_raised { user2.create }
-
- assert_equal(
- :present, user2.ensure,
-
- "User did not get created")
+ eachproperty do |property|
+ if val = fakedata(user.name, property)
+ user.resource[property] = val
end
- else
- $stderr.puts "Not root; skipping user creation/modification tests"
- end
-
- # Here is where we test individual providers
- def test_useradd_flags
- useradd = nil
- assert_nothing_raised {
- useradd = Puppet::Type.type(:user).provider(:useradd)
- }
- assert(useradd, "Did not retrieve useradd provider")
+ end
- user = nil
- assert_nothing_raised {
- fakeresource = fakeresource(:user, @me)
- user = useradd.new(fakeresource)
- }
+ @@tmpusers << name
+ assert_nothing_raised {
+ user.create
+ }
+ assert_equal("Puppet's Testing User pptest", user.comment,
+ "Comment was not set")
- assert_equal(
- "-d", user.send(:flag, :home),
-
- "Incorrect home flag")
-
+ tests = Puppet::Type.type(:user).validproperties
- assert_equal(
- "-s", user.send(:flag, :shell),
+ just = nil
+ tests.each { |test|
+ if self.respond_to?("attrtest_#{test}")
+ self.send("attrtest_#{test}", user)
+ else
+ Puppet.err "Not testing attr #{test} of user"
+ end
+ }
- "Incorrect shell flag")
+ assert_nothing_raised {
+ user.delete
+ }
end
- def test_autogen
- provider = nil
- user = Puppet::Type.type(:user).new(:name => nonrootuser.name)
- provider = user.provider
- assert(provider, "did not get provider")
-
- # Everyone should be able to autogenerate a uid
- assert_instance_of(Fixnum, provider.autogen(:uid))
-
- # If we're Darwin, then we should get results, but everyone else should
- # get nil
- darwin = (Facter.value(:operatingsystem) == "Darwin")
-
- should = {
- :comment => user[:name].capitalize,
- :home => "/var/empty",
- :shell => "/usr/bin/false"
- }
-
- should.each do |param, value|
- if darwin
- assert_equal(value, provider.autogen(param), "did not autogen #{param} for darwin correctly")
- else
- assert_nil(provider.autogen(param), "autogenned #{param} for non-darwin os")
- end
- end
+ # This is a weird method that shows how annoying the interface between
+ # types and providers is. Grr.
+ def test_duplicateIDs
+ user1 = mkuser("user1")
+ user1.create
+ user1.uid = 125
+ user2 = mkuser("user2")
+ user2.resource[:uid] = 125
+
+ cleanup do
+ user1.delete
+ user2.delete
+ end
+
+ # Not all OSes fail here, so we can't test that it doesn't work with
+ # it off, only that it does work with it on.
+ assert_nothing_raised {
+ user2.resource[:allowdupe] = :true
+ }
+ assert_nothing_raised { user2.create }
+
+ assert_equal(
+ :present, user2.ensure,
+
+ "User did not get created")
+ end
+ else
+ $stderr.puts "Not root; skipping user creation/modification tests"
+ end
+
+ # Here is where we test individual providers
+ def test_useradd_flags
+ useradd = nil
+ assert_nothing_raised {
+ useradd = Puppet::Type.type(:user).provider(:useradd)
+ }
+ assert(useradd, "Did not retrieve useradd provider")
+
+ user = nil
+ assert_nothing_raised {
+ fakeresource = fakeresource(:user, @me)
+ user = useradd.new(fakeresource)
+ }
+
+
+ assert_equal(
+ "-d", user.send(:flag, :home),
+
+ "Incorrect home flag")
+
+
+ assert_equal(
+ "-s", user.send(:flag, :shell),
+
+ "Incorrect shell flag")
+ end
+
+ def test_autogen
+ provider = nil
+ user = Puppet::Type.type(:user).new(:name => nonrootuser.name)
+ provider = user.provider
+ assert(provider, "did not get provider")
+
+ # Everyone should be able to autogenerate a uid
+ assert_instance_of(Fixnum, provider.autogen(:uid))
+
+ # If we're Darwin, then we should get results, but everyone else should
+ # get nil
+ darwin = (Facter.value(:operatingsystem) == "Darwin")
+
+ should = {
+ :comment => user[:name].capitalize,
+ :home => "/var/empty",
+ :shell => "/usr/bin/false"
+ }
+
+ should.each do |param, value|
+ if darwin
+ assert_equal(value, provider.autogen(param), "did not autogen #{param} for darwin correctly")
+ else
+ assert_nil(provider.autogen(param), "autogenned #{param} for non-darwin os")
+ end
end
+ end
end
diff --git a/test/ral/providers/user/useradd.rb b/test/ral/providers/user/useradd.rb
index 52d933f..12e1f7f 100755
--- a/test/ral/providers/user/useradd.rb
+++ b/test/ral/providers/user/useradd.rb
@@ -5,229 +5,229 @@ require File.dirname(__FILE__) + '/../../../lib/puppettest'
require 'mocha'
class UserAddProviderTest < PuppetTest::TestCase
- confine "useradd user provider missing" =>
- Puppet::Type.type(:user).provider(:useradd).suitable?
-
- def setup
- super
- @type = Puppet::Type.type(:user)
- @provider = Puppet::Type.type(:user).provider(:useradd)
- @home = tempfile
- @vals = {:name => 'faff',
- :provider => :useradd,
- :ensure => :present,
- :uid => 5000,
- :gid => 5000,
- :home => @home,
- :comment => "yayness",
- :groups => %w{one two}
- }
+ confine "useradd user provider missing" =>
+ Puppet::Type.type(:user).provider(:useradd).suitable?
+
+ def setup
+ super
+ @type = Puppet::Type.type(:user)
+ @provider = Puppet::Type.type(:user).provider(:useradd)
+ @home = tempfile
+ @vals = {:name => 'faff',
+ :provider => :useradd,
+ :ensure => :present,
+ :uid => 5000,
+ :gid => 5000,
+ :home => @home,
+ :comment => "yayness",
+ :groups => %w{one two}
+ }
+ end
+
+ def setup_user
+ @user = @type.new(@vals)
+
+ @vals.each do |name, val|
+ next unless @user.class.validproperty?(name)
end
+ @user
+ end
- def setup_user
- @user = @type.new(@vals)
+ def test_features
+ [:manages_homedir].each do |feature|
- @vals.each do |name, val|
- next unless @user.class.validproperty?(name)
- end
- @user
- end
-
- def test_features
- [:manages_homedir].each do |feature|
-
- assert(
- @provider.feature?(feature),
+ assert(
+ @provider.feature?(feature),
- "useradd provider is missing #{feature}")
- end
+ "useradd provider is missing #{feature}")
end
+ end
- def test_create
- user = setup_user
-
- @vals.each do |name, val|
- next unless user.class.validproperty?(name)
- end
+ def test_create
+ user = setup_user
- user.expects(:allowdupe?).returns(false)
- user.expects(:managehome?).returns(false)
+ @vals.each do |name, val|
+ next unless user.class.validproperty?(name)
+ end
- user.provider.expects(:execute).with do |params|
- command = params.shift
- assert_equal(@provider.command(:add), command,
- "Got incorrect command")
+ user.expects(:allowdupe?).returns(false)
+ user.expects(:managehome?).returns(false)
- if %w{Fedora RedHat}.include?(Facter.value(:operatingsystem))
- assert(params.include?("-M"), "Did not disable homedir creation on red hat")
- params.delete("-M")
- end
+ user.provider.expects(:execute).with do |params|
+ command = params.shift
+ assert_equal(@provider.command(:add), command,
+ "Got incorrect command")
- options = {}
- options[params.shift] = params.shift while params.length > 0
+ if %w{Fedora RedHat}.include?(Facter.value(:operatingsystem))
+ assert(params.include?("-M"), "Did not disable homedir creation on red hat")
+ params.delete("-M")
+ end
- @vals[:groups] = @vals[:groups].join(",")
+ options = {}
+ options[params.shift] = params.shift while params.length > 0
- flags = {:home => "-d", :groups => "-G", :gid => "-g",
- :uid => "-u", :comment => "-c"}
+ @vals[:groups] = @vals[:groups].join(",")
- flags.each do |param, flag|
- assert_equal(@vals[param], options[flag], "Got incorrect value for #{param}")
- end
+ flags = {:home => "-d", :groups => "-G", :gid => "-g",
+ :uid => "-u", :comment => "-c"}
- true
- end
+ flags.each do |param, flag|
+ assert_equal(@vals[param], options[flag], "Got incorrect value for #{param}")
+ end
- user.provider.create
+ true
end
- # Make sure we add the right flags when managing home
- def test_managehome
- @vals[:managehome] = true
- setup_user
+ user.provider.create
+ end
+
+ # Make sure we add the right flags when managing home
+ def test_managehome
+ @vals[:managehome] = true
+ setup_user
- assert(
- @user.provider.respond_to?(:manages_homedir?),
+ assert(
+ @user.provider.respond_to?(:manages_homedir?),
- "provider did not get managehome test set")
+ "provider did not get managehome test set")
- assert(@user.managehome?, "provider did not get managehome")
+ assert(@user.managehome?, "provider did not get managehome")
- # First run
- @user.expects(:managehome?).returns(true)
+ # First run
+ @user.expects(:managehome?).returns(true)
- @user.provider.expects(:execute).with do |params|
- assert_equal(params[0], @provider.command(:add), "useradd was not called")
- assert(params.include?("-m"), "Did not add -m when managehome was in affect")
- assert(! params.include?("-M"), "Added -M when managehome was in affect")
+ @user.provider.expects(:execute).with do |params|
+ assert_equal(params[0], @provider.command(:add), "useradd was not called")
+ assert(params.include?("-m"), "Did not add -m when managehome was in affect")
+ assert(! params.include?("-M"), "Added -M when managehome was in affect")
- true
- end
+ true
+ end
- @user.provider.create
+ @user.provider.create
- # Start again, this time with manages_home off
- @vals[:managehome] = false
- setup_user
+ # Start again, this time with manages_home off
+ @vals[:managehome] = false
+ setup_user
- # First run
- @user.expects(:managehome?).returns(false)
+ # First run
+ @user.expects(:managehome?).returns(false)
- @user.provider.expects(:execute).with do |params|
- assert_equal(params[0], @provider.command(:add), "useradd was not called")
- assert(params.include?("-M"), "Did not add -M on Red Hat") if %w{Fedora RedHat}.include?(Facter.value(:operatingsystem))
- assert(! params.include?("-m"), "Added -m when managehome was disabled")
+ @user.provider.expects(:execute).with do |params|
+ assert_equal(params[0], @provider.command(:add), "useradd was not called")
+ assert(params.include?("-M"), "Did not add -M on Red Hat") if %w{Fedora RedHat}.include?(Facter.value(:operatingsystem))
+ assert(! params.include?("-m"), "Added -m when managehome was disabled")
- true
- end
-
- @user.provider.create
+ true
end
- def test_allowdupe
- @vals[:allowdupe] = true
- setup_user
+ @user.provider.create
+ end
+ def test_allowdupe
+ @vals[:allowdupe] = true
+ setup_user
- assert(
- @user.provider.respond_to?(:allows_duplicates?),
-
- "provider did not get allowdupe test set")
- assert(@user.allowdupe?, "provider did not get allowdupe")
+ assert(
+ @user.provider.respond_to?(:allows_duplicates?),
+
+ "provider did not get allowdupe test set")
- # First run
- @user.expects(:allowdupe?).returns(true)
+ assert(@user.allowdupe?, "provider did not get allowdupe")
- @user.provider.expects(:execute).with do |params|
- assert_equal(params[0], @provider.command(:add), "useradd was not called")
- assert(params.include?("-o"), "Did not add -o when allowdupe was in affect")
+ # First run
+ @user.expects(:allowdupe?).returns(true)
- true
- end
+ @user.provider.expects(:execute).with do |params|
+ assert_equal(params[0], @provider.command(:add), "useradd was not called")
+ assert(params.include?("-o"), "Did not add -o when allowdupe was in affect")
- @user.provider.create
+ true
+ end
- # Start again, this time with manages_home off
- @vals[:allowdupe] = false
- setup_user
+ @user.provider.create
- # First run
- @user.expects(:allowdupe?).returns(false)
+ # Start again, this time with manages_home off
+ @vals[:allowdupe] = false
+ setup_user
- @user.provider.expects(:execute).with do |params|
- assert_equal(params[0], @provider.command(:add), "useradd was not called")
- assert(! params.include?("-o"), "Added -o when allowdupe was disabled")
+ # First run
+ @user.expects(:allowdupe?).returns(false)
- true
- end
+ @user.provider.expects(:execute).with do |params|
+ assert_equal(params[0], @provider.command(:add), "useradd was not called")
+ assert(! params.include?("-o"), "Added -o when allowdupe was disabled")
- @user.provider.create
+ true
end
- def test_manages_password
- return unless @provider.feature?(:manages_passwords)
- @vals[:password] = "somethingorother"
- setup_user
-
- @user.provider.expects(:execute).with do |params|
- assert_equal(params[0], @provider.command(:add), "useradd was not called")
- params.shift
- options = {}
- params.each_with_index do |p, i|
- if p =~ /^-/ and p != "-M"
- options[p] = params[i + 1]
- end
- end
- assert_equal(options["-p"], @vals[:password], "Did not set password in useradd call")
- true
+ @user.provider.create
+ end
+
+ def test_manages_password
+ return unless @provider.feature?(:manages_passwords)
+ @vals[:password] = "somethingorother"
+ setup_user
+
+ @user.provider.expects(:execute).with do |params|
+ assert_equal(params[0], @provider.command(:add), "useradd was not called")
+ params.shift
+ options = {}
+ params.each_with_index do |p, i|
+ if p =~ /^-/ and p != "-M"
+ options[p] = params[i + 1]
end
+ end
+ assert_equal(options["-p"], @vals[:password], "Did not set password in useradd call")
+ true
+ end
- @user.provider.create
-
- # Now mark the user made, and make sure the right command is called
- setup_user
- @vals[:password] = "somethingelse"
+ @user.provider.create
- @user.provider.expects(:execute).with do |params|
- assert_equal(params[0], @provider.command(:modify), "usermod was not called")
+ # Now mark the user made, and make sure the right command is called
+ setup_user
+ @vals[:password] = "somethingelse"
- options = {}
- params.each_with_index do |p, i|
- if p =~ /^-/ and p != "-M"
- options[p] = params[i + 1]
- end
- end
+ @user.provider.expects(:execute).with do |params|
+ assert_equal(params[0], @provider.command(:modify), "usermod was not called")
- assert_equal(
- options["-p"], @vals[:password],
-
- "Did not set password in useradd call")
- true
+ options = {}
+ params.each_with_index do |p, i|
+ if p =~ /^-/ and p != "-M"
+ options[p] = params[i + 1]
end
+ end
- @user.provider.password = @vals[:password]
+ assert_equal(
+ options["-p"], @vals[:password],
+
+ "Did not set password in useradd call")
+ true
end
+ @user.provider.password = @vals[:password]
+ end
+
end
class UserRootAddProviderTest < PuppetTest::TestCase
- confine "useradd user provider missing" => Puppet::Type.type(:user).provider(:useradd).suitable?
- confine "useradd does not manage passwords" => Puppet::Type.type(:user).provider(:useradd).manages_passwords?
- confine "not running as root" => (Process.uid == 0)
+ confine "useradd user provider missing" => Puppet::Type.type(:user).provider(:useradd).suitable?
+ confine "useradd does not manage passwords" => Puppet::Type.type(:user).provider(:useradd).manages_passwords?
+ confine "not running as root" => (Process.uid == 0)
- def test_password
- user = Puppet::Type.type(:user).new(:name => "root", :check => [:password], :provider => :useradd)
+ def test_password
+ user = Puppet::Type.type(:user).new(:name => "root", :check => [:password], :provider => :useradd)
- provider = user.provider
+ provider = user.provider
- assert_nothing_raised("Could not check password") do
- pass = provider.password
- assert(pass, "Did not get password for root")
- assert(pass!= "x", "Password was retrieved from /etc/passwd instead of /etc/shadow")
- end
+ assert_nothing_raised("Could not check password") do
+ pass = provider.password
+ assert(pass, "Did not get password for root")
+ assert(pass!= "x", "Password was retrieved from /etc/passwd instead of /etc/shadow")
end
+ end
end
diff --git a/test/ral/type/cron.rb b/test/ral/type/cron.rb
index 1bf8baf..a941cae 100755
--- a/test/ral/type/cron.rb
+++ b/test/ral/type/cron.rb
@@ -7,499 +7,499 @@ require 'puppettest'
# Test cron job creation, modification, and destruction
class TestCron < Test::Unit::TestCase
- include PuppetTest
+ include PuppetTest
- def setup
- super
+ def setup
+ super
- setme
+ setme
- @crontype = Puppet::Type.type(:cron)
- @provider = @crontype.defaultprovider
- if @provider.respond_to?(:filetype=)
- @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
- end
- @crontype = Puppet::Type.type(:cron)
+ @crontype = Puppet::Type.type(:cron)
+ @provider = @crontype.defaultprovider
+ if @provider.respond_to?(:filetype=)
+ @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
end
+ @crontype = Puppet::Type.type(:cron)
+ end
- def teardown
- super
- @crontype.defaultprovider = nil
- end
-
- def eachprovider
- @crontype.suitableprovider.each do |provider|
- yield provider
- end
- end
+ def teardown
+ super
+ @crontype.defaultprovider = nil
+ end
- # Back up the user's existing cron tab if they have one.
- def cronback
- tab = nil
- assert_nothing_raised {
- tab = Puppet::Type.type(:cron).filetype.read(@me)
- }
-
- @currenttab = $CHILD_STATUS == 0 ? tab : nil
+ def eachprovider
+ @crontype.suitableprovider.each do |provider|
+ yield provider
end
-
- # Restore the cron tab to its original form.
- def cronrestore
- assert_nothing_raised {
- if @currenttab
- @crontype.filetype.new(@me).write(@currenttab)
- else
- @crontype.filetype.new(@me).remove
- end
- }
+ end
+
+ # Back up the user's existing cron tab if they have one.
+ def cronback
+ tab = nil
+ assert_nothing_raised {
+ tab = Puppet::Type.type(:cron).filetype.read(@me)
+ }
+
+ @currenttab = $CHILD_STATUS == 0 ? tab : nil
+ end
+
+ # Restore the cron tab to its original form.
+ def cronrestore
+ assert_nothing_raised {
+ if @currenttab
+ @crontype.filetype.new(@me).write(@currenttab)
+ else
+ @crontype.filetype.new(@me).remove
+ end
+ }
+ end
+
+ # Create a cron job with all fields filled in.
+ def mkcron(name, addargs = true)
+ cron = nil
+ command = "date > #{tmpdir()}/crontest#{name}"
+ args = nil
+ if addargs
+ args = {
+ :command => command,
+ :name => name,
+ :user => @me,
+ :minute => rand(59),
+ :month => "1",
+ :monthday => "1",
+ :hour => "1"
+ }
+ else
+ args = {:command => command, :name => name}
end
+ assert_nothing_raised {
+ cron = @crontype.new(args)
+ }
- # Create a cron job with all fields filled in.
- def mkcron(name, addargs = true)
- cron = nil
- command = "date > #{tmpdir()}/crontest#{name}"
- args = nil
- if addargs
- args = {
- :command => command,
- :name => name,
- :user => @me,
- :minute => rand(59),
- :month => "1",
- :monthday => "1",
- :hour => "1"
- }
- else
- args = {:command => command, :name => name}
- end
- assert_nothing_raised {
- cron = @crontype.new(args)
- }
-
- cron
- end
+ cron
+ end
- # Run the cron through its paces -- install it then remove it.
- def cyclecron(cron)
- obj = Puppet::Type::Cron.cronobj(@me)
+ # Run the cron through its paces -- install it then remove it.
+ def cyclecron(cron)
+ obj = Puppet::Type::Cron.cronobj(@me)
- text = obj.read
- name = cron.name
- comp = mk_catalog(name, cron)
+ text = obj.read
+ name = cron.name
+ comp = mk_catalog(name, cron)
- assert_events([:cron_created], comp)
- cron.provider.class.prefetch
- currentvalue = cron.retrieve
+ assert_events([:cron_created], comp)
+ cron.provider.class.prefetch
+ currentvalue = cron.retrieve
- assert(cron.insync?(currentvalue), "Cron is not in sync")
+ assert(cron.insync?(currentvalue), "Cron is not in sync")
- assert_events([], comp)
+ assert_events([], comp)
- curtext = obj.read
- text.split("\n").each do |line|
- assert(curtext.include?(line), "Missing '#{line}'")
- end
- obj = Puppet::Type::Cron.cronobj(@me)
+ curtext = obj.read
+ text.split("\n").each do |line|
+ assert(curtext.include?(line), "Missing '#{line}'")
+ end
+ obj = Puppet::Type::Cron.cronobj(@me)
- cron[:ensure] = :absent
+ cron[:ensure] = :absent
- assert_events([:cron_removed], comp)
+ assert_events([:cron_removed], comp)
- cron.provider.class.prefetch
- currentvalue = cron.retrieve
+ cron.provider.class.prefetch
+ currentvalue = cron.retrieve
- assert(cron.insync?(currentvalue), "Cron is not in sync")
- assert_events([], comp)
- end
+ assert(cron.insync?(currentvalue), "Cron is not in sync")
+ assert_events([], comp)
+ end
- # Test that a cron job with spaces at the end doesn't get rewritten
- def test_trailingspaces
- eachprovider do |provider|
- cron = nil
- # make the cron
- name = "yaytest"
- command = "date > /dev/null "
- assert_nothing_raised {
+ # Test that a cron job with spaces at the end doesn't get rewritten
+ def test_trailingspaces
+ eachprovider do |provider|
+ cron = nil
+ # make the cron
+ name = "yaytest"
+ command = "date > /dev/null "
+ assert_nothing_raised {
- cron = @crontype.new(
+ cron = @crontype.new(
- :name => name,
- :command => "date > /dev/null ",
- :month => "May",
+ :name => name,
+ :command => "date > /dev/null ",
+ :month => "May",
- :user => @me
- )
- }
- property = cron.send(:property, :command)
- cron.provider.command = command
- cron.provider.ensure = :present
- cron.provider.user = @me
- cron.provider.month = ["4"]
- cron.provider.class.prefetch
- currentvalue = cron.retrieve
- assert(cron.parameter(:command).insync?(currentvalue[:command]), "Property :command is not considered in sync with value #{currentvalue[:command]}")
- end
+ :user => @me
+ )
+ }
+ property = cron.send(:property, :command)
+ cron.provider.command = command
+ cron.provider.ensure = :present
+ cron.provider.user = @me
+ cron.provider.month = ["4"]
+ cron.provider.class.prefetch
+ currentvalue = cron.retrieve
+ assert(cron.parameter(:command).insync?(currentvalue[:command]), "Property :command is not considered in sync with value #{currentvalue[:command]}")
end
+ end
- def test_makeandretrievecron
- %w{storeandretrieve a-name another-name more_naming SomeName}.each do |name|
- cron = mkcron(name)
- catalog = mk_catalog(name, cron)
- trans = assert_events([:cron_created], catalog, name)
+ def test_makeandretrievecron
+ %w{storeandretrieve a-name another-name more_naming SomeName}.each do |name|
+ cron = mkcron(name)
+ catalog = mk_catalog(name, cron)
+ trans = assert_events([:cron_created], catalog, name)
- cron.provider.class.prefetch
- cron = nil
+ cron.provider.class.prefetch
+ cron = nil
- assert(cron = catalog.resource(:cron, name), "Could not retrieve named cron")
- assert_instance_of(Puppet::Type.type(:cron), cron)
- end
+ assert(cron = catalog.resource(:cron, name), "Could not retrieve named cron")
+ assert_instance_of(Puppet::Type.type(:cron), cron)
end
-
- # Do input validation testing on all of the parameters.
- def test_arguments
- values = {
- :monthday => {
- :valid => [ 1, 13, "1" ],
- :invalid => [ -1, 0, 32 ]
- },
- :weekday => {
- :valid => [ 0, 3, 6, "1", "tue", "wed",
- "Wed", "MOnday", "SaTurday" ],
- :invalid => [ -1, 8, "13", "tues", "teusday", "thurs" ]
- },
- :hour => {
- :valid => [ 0, 21, 23 ],
- :invalid => [ -1, 24 ]
- },
- :minute => {
- :valid => [ 0, 34, 59 ],
- :invalid => [ -1, 60 ]
- },
- :month => {
- :valid => [ 1, 11, 12, "mar", "March", "apr", "October", "DeCeMbEr" ],
- :invalid => [ -1, 0, 13, "marc", "sept" ]
+ end
+
+ # Do input validation testing on all of the parameters.
+ def test_arguments
+ values = {
+ :monthday => {
+ :valid => [ 1, 13, "1" ],
+ :invalid => [ -1, 0, 32 ]
+ },
+ :weekday => {
+ :valid => [ 0, 3, 6, "1", "tue", "wed",
+ "Wed", "MOnday", "SaTurday" ],
+ :invalid => [ -1, 8, "13", "tues", "teusday", "thurs" ]
+ },
+ :hour => {
+ :valid => [ 0, 21, 23 ],
+ :invalid => [ -1, 24 ]
+ },
+ :minute => {
+ :valid => [ 0, 34, 59 ],
+ :invalid => [ -1, 60 ]
+ },
+ :month => {
+ :valid => [ 1, 11, 12, "mar", "March", "apr", "October", "DeCeMbEr" ],
+ :invalid => [ -1, 0, 13, "marc", "sept" ]
+ }
+ }
+
+ cron = mkcron("valtesting")
+ values.each { |param, hash|
+ # We have to test the valid ones first, because otherwise the
+ # property will fail to create at all.
+ [:valid, :invalid].each { |type|
+ hash[type].each { |value|
+ case type
+ when :valid
+ assert_nothing_raised {
+ cron[param] = value
}
- }
- cron = mkcron("valtesting")
- values.each { |param, hash|
- # We have to test the valid ones first, because otherwise the
- # property will fail to create at all.
- [:valid, :invalid].each { |type|
- hash[type].each { |value|
- case type
- when :valid
- assert_nothing_raised {
- cron[param] = value
- }
-
- assert_equal([value.to_s], cron.should(param), "Cron value was not set correctly") if value.is_a?(Integer)
- when :invalid
- assert_raise(Puppet::Error, "#{value} is incorrectly a valid #{param}") {
- cron[param] = value
- }
- end
-
- if value.is_a?(Integer)
- value = value.to_s
- redo
- end
- }
+ assert_equal([value.to_s], cron.should(param), "Cron value was not set correctly") if value.is_a?(Integer)
+ when :invalid
+ assert_raise(Puppet::Error, "#{value} is incorrectly a valid #{param}") {
+ cron[param] = value
}
+ end
+
+ if value.is_a?(Integer)
+ value = value.to_s
+ redo
+ end
}
- end
+ }
+ }
+ end
- # Verify that comma-separated numbers are not resulting in rewrites
- def test_comma_separated_vals_work
- eachprovider do |provider|
- cron = nil
- assert_nothing_raised {
+ # Verify that comma-separated numbers are not resulting in rewrites
+ def test_comma_separated_vals_work
+ eachprovider do |provider|
+ cron = nil
+ assert_nothing_raised {
- cron = @crontype.new(
+ cron = @crontype.new(
- :command => "/bin/date > /dev/null",
- :minute => [0, 30],
- :name => "crontest",
+ :command => "/bin/date > /dev/null",
+ :minute => [0, 30],
+ :name => "crontest",
- :provider => provider.name
- )
- }
+ :provider => provider.name
+ )
+ }
- cron.provider.ensure = :present
- cron.provider.command = '/bin/date > /dev/null'
- cron.provider.minute = %w{0 30}
- cron.provider.class.prefetch
- currentvalue = cron.retrieve
+ cron.provider.ensure = :present
+ cron.provider.command = '/bin/date > /dev/null'
+ cron.provider.minute = %w{0 30}
+ cron.provider.class.prefetch
+ currentvalue = cron.retrieve
- currentvalue.each do |name, value|
- # We're only interested in comparing minutes.
- next unless name.to_s == "minute"
- assert(cron.parameter(name).insync?(value), "Property #{name} is not considered in sync with value #{value.inspect}")
- end
- end
+ currentvalue.each do |name, value|
+ # We're only interested in comparing minutes.
+ next unless name.to_s == "minute"
+ assert(cron.parameter(name).insync?(value), "Property #{name} is not considered in sync with value #{value.inspect}")
+ end
end
+ end
- def test_fieldremoval
- cron = nil
- assert_nothing_raised {
+ def test_fieldremoval
+ cron = nil
+ assert_nothing_raised {
- cron = @crontype.new(
+ cron = @crontype.new(
- :command => "/bin/date > /dev/null",
- :minute => [0, 30],
- :name => "crontest",
+ :command => "/bin/date > /dev/null",
+ :minute => [0, 30],
+ :name => "crontest",
- :provider => :crontab
- )
- }
+ :provider => :crontab
+ )
+ }
- assert_events([:cron_created], cron)
- cron.provider.class.prefetch
+ assert_events([:cron_created], cron)
+ cron.provider.class.prefetch
- cron[:minute] = :absent
- assert_events([:minute_changed], cron)
+ cron[:minute] = :absent
+ assert_events([:minute_changed], cron)
- current_values = nil
- assert_nothing_raised {
- cron.provider.class.prefetch
- current_values = cron.retrieve
- }
- assert_equal(:absent, current_values[cron.property(:minute)])
- end
+ current_values = nil
+ assert_nothing_raised {
+ cron.provider.class.prefetch
+ current_values = cron.retrieve
+ }
+ assert_equal(:absent, current_values[cron.property(:minute)])
+ end
- def test_listing
- # Make a crontab cron for testing
- provider = @crontype.provider(:crontab)
- return unless provider.suitable?
+ def test_listing
+ # Make a crontab cron for testing
+ provider = @crontype.provider(:crontab)
+ return unless provider.suitable?
- ft = provider.filetype
- provider.filetype = :ram
- cleanup { provider.filetype = ft }
+ ft = provider.filetype
+ provider.filetype = :ram
+ cleanup { provider.filetype = ft }
- setme
+ setme
- cron = @crontype.new(
- :name => "testing",
- :minute => [0, 30],
- :command => "/bin/testing",
+ cron = @crontype.new(
+ :name => "testing",
+ :minute => [0, 30],
+ :command => "/bin/testing",
- :user => @me
- )
- # Write it to our file
- assert_apply(cron)
-
- crons = []
- assert_nothing_raised {
- @crontype.instances.each do |cron|
- crons << cron
- end
- }
+ :user => @me
+ )
+ # Write it to our file
+ assert_apply(cron)
- crons.each do |cron|
- assert_instance_of(@crontype, cron, "Did not receive a real cron object")
+ crons = []
+ assert_nothing_raised {
+ @crontype.instances.each do |cron|
+ crons << cron
+ end
+ }
- assert_instance_of(
- String, cron.value(:user),
+ crons.each do |cron|
+ assert_instance_of(@crontype, cron, "Did not receive a real cron object")
- "Cron user is not a string")
- end
- end
+ assert_instance_of(
+ String, cron.value(:user),
- def verify_failonnouser
- assert_raise(Puppet::Error) do
- @crontype.retrieve("nosuchuser")
- end
+ "Cron user is not a string")
end
+ end
- def test_divisionnumbers
- cron = mkcron("divtest")
- cron[:minute] = "*/5"
+ def verify_failonnouser
+ assert_raise(Puppet::Error) do
+ @crontype.retrieve("nosuchuser")
+ end
+ end
- assert_apply(cron)
+ def test_divisionnumbers
+ cron = mkcron("divtest")
+ cron[:minute] = "*/5"
- cron.provider.class.prefetch
- currentvalue = cron.retrieve
+ assert_apply(cron)
- assert_equal(["*/5"], currentvalue[cron.property(:minute)])
- end
+ cron.provider.class.prefetch
+ currentvalue = cron.retrieve
- def test_ranges
- cron = mkcron("rangetest")
- cron[:minute] = "2-4"
+ assert_equal(["*/5"], currentvalue[cron.property(:minute)])
+ end
- assert_apply(cron)
+ def test_ranges
+ cron = mkcron("rangetest")
+ cron[:minute] = "2-4"
- current_values = nil
- assert_nothing_raised {
- cron.provider.class.prefetch
- current_values = cron.retrieve
- }
+ assert_apply(cron)
- assert_equal(["2-4"], current_values[cron.property(:minute)])
- end
+ current_values = nil
+ assert_nothing_raised {
+ cron.provider.class.prefetch
+ current_values = cron.retrieve
+ }
+ assert_equal(["2-4"], current_values[cron.property(:minute)])
+ end
- def provider_set(cron, param, value)
- unless param =~ /=$/
- param = "#{param}="
- end
- cron.provider.send(param, value)
+ def provider_set(cron, param, value)
+ unless param =~ /=$/
+ param = "#{param}="
end
- def test_value
- cron = mkcron("valuetesting", false)
+ cron.provider.send(param, value)
+ end
- # First, test the normal properties
- [:minute, :hour, :month].each do |param|
- cron.newattr(param)
- property = cron.property(param)
+ def test_value
+ cron = mkcron("valuetesting", false)
- assert(property, "Did not get #{param} property")
+ # First, test the normal properties
+ [:minute, :hour, :month].each do |param|
+ cron.newattr(param)
+ property = cron.property(param)
- assert_nothing_raised {
- # property.is = :absent
- provider_set(cron, param, :absent)
- }
+ assert(property, "Did not get #{param} property")
- val = "*"
- assert_equal(val, cron.value(param))
-
- # Make sure arrays work, too
- provider_set(cron, param, ["1"])
- assert_equal(%w{1}, cron.value(param))
+ assert_nothing_raised {
+ # property.is = :absent
+ provider_set(cron, param, :absent)
+ }
- # Make sure values get comma-joined
- provider_set(cron, param, %w{2 3})
- assert_equal(%w{2 3}, cron.value(param))
+ val = "*"
+ assert_equal(val, cron.value(param))
- # Make sure "should" values work, too
- cron[param] = "4"
- assert_equal(%w{4}, cron.value(param))
+ # Make sure arrays work, too
+ provider_set(cron, param, ["1"])
+ assert_equal(%w{1}, cron.value(param))
- cron[param] = ["4"]
- assert_equal(%w{4}, cron.value(param))
+ # Make sure values get comma-joined
+ provider_set(cron, param, %w{2 3})
+ assert_equal(%w{2 3}, cron.value(param))
- cron[param] = ["4", "5"]
- assert_equal(%w{4 5}, cron.value(param))
+ # Make sure "should" values work, too
+ cron[param] = "4"
+ assert_equal(%w{4}, cron.value(param))
- provider_set(cron, param, :absent)
- assert_equal(%w{4 5}, cron.value(param))
- end
+ cron[param] = ["4"]
+ assert_equal(%w{4}, cron.value(param))
- Puppet[:trace] = false
+ cron[param] = ["4", "5"]
+ assert_equal(%w{4 5}, cron.value(param))
- # Now make sure that :command works correctly
- cron.delete(:command)
- cron.newattr(:command)
- property = cron.property(:command)
+ provider_set(cron, param, :absent)
+ assert_equal(%w{4 5}, cron.value(param))
+ end
- assert_nothing_raised {
- provider_set(cron, :command, :absent)
- }
+ Puppet[:trace] = false
- param = :command
- # Make sure arrays work, too
- provider_set(cron, param, ["/bin/echo"])
- assert_equal("/bin/echo", cron.value(param))
+ # Now make sure that :command works correctly
+ cron.delete(:command)
+ cron.newattr(:command)
+ property = cron.property(:command)
- # Make sure values are not comma-joined
- provider_set(cron, param, %w{/bin/echo /bin/test})
- assert_equal("/bin/echo", cron.value(param))
+ assert_nothing_raised {
+ provider_set(cron, :command, :absent)
+ }
- # Make sure "should" values work, too
- cron[param] = "/bin/echo"
- assert_equal("/bin/echo", cron.value(param))
+ param = :command
+ # Make sure arrays work, too
+ provider_set(cron, param, ["/bin/echo"])
+ assert_equal("/bin/echo", cron.value(param))
- cron[param] = ["/bin/echo"]
- assert_equal("/bin/echo", cron.value(param))
+ # Make sure values are not comma-joined
+ provider_set(cron, param, %w{/bin/echo /bin/test})
+ assert_equal("/bin/echo", cron.value(param))
- cron[param] = %w{/bin/echo /bin/test}
- assert_equal("/bin/echo", cron.value(param))
+ # Make sure "should" values work, too
+ cron[param] = "/bin/echo"
+ assert_equal("/bin/echo", cron.value(param))
- provider_set(cron, param, :absent)
- assert_equal("/bin/echo", cron.value(param))
- end
+ cron[param] = ["/bin/echo"]
+ assert_equal("/bin/echo", cron.value(param))
- def test_multiple_users
- crons = []
- users = ["root", nonrootuser.name]
- users.each do |user|
+ cron[param] = %w{/bin/echo /bin/test}
+ assert_equal("/bin/echo", cron.value(param))
- cron = Puppet::Type.type(:cron).new(
+ provider_set(cron, param, :absent)
+ assert_equal("/bin/echo", cron.value(param))
+ end
- :name => "testcron-#{user}",
- :user => user,
- :command => "/bin/echo",
+ def test_multiple_users
+ crons = []
+ users = ["root", nonrootuser.name]
+ users.each do |user|
- :minute => [0,30]
- )
- crons << cron
+ cron = Puppet::Type.type(:cron).new(
- assert_equal(cron.should(:user), cron.should(:target),
- "Target was not set correctly for #{user}")
- end
- provider = crons[0].provider.class
+ :name => "testcron-#{user}",
+ :user => user,
+ :command => "/bin/echo",
- assert_apply(*crons)
-
- users.each do |user|
- users.each do |other|
- next if user == other
- text = provider.target_object(other).read
+ :minute => [0,30]
+ )
+ crons << cron
+ assert_equal(cron.should(:user), cron.should(:target),
+ "Target was not set correctly for #{user}")
+ end
+ provider = crons[0].provider.class
- assert(
- text !~ /testcron-#{user}/,
+ assert_apply(*crons)
- "#{user}'s cron job is in #{other}'s tab")
- end
- end
- end
+ users.each do |user|
+ users.each do |other|
+ next if user == other
+ text = provider.target_object(other).read
- # Make sure the user stuff defaults correctly.
- def test_default_user
- crontab = @crontype.provider(:crontab)
- if crontab.suitable?
- inst = @crontype.new(
+ assert(
+ text !~ /testcron-#{user}/,
- :name => "something", :command => "/some/thing",
+ "#{user}'s cron job is in #{other}'s tab")
+ end
+ end
+ end
- :provider => :crontab)
- assert_equal(Etc.getpwuid(Process.uid).name, inst.should(:user), "user did not default to current user with crontab")
- assert_equal(Etc.getpwuid(Process.uid).name, inst.should(:target), "target did not default to current user with crontab")
+ # Make sure the user stuff defaults correctly.
+ def test_default_user
+ crontab = @crontype.provider(:crontab)
+ if crontab.suitable?
- # Now make a new cron with a user, and make sure it gets copied
- # over
+ inst = @crontype.new(
- inst = @crontype.new(
- :name => "yay", :command => "/some/thing",
+ :name => "something", :command => "/some/thing",
- :user => "bin", :provider => :crontab)
+ :provider => :crontab)
+ assert_equal(Etc.getpwuid(Process.uid).name, inst.should(:user), "user did not default to current user with crontab")
+ assert_equal(Etc.getpwuid(Process.uid).name, inst.should(:target), "target did not default to current user with crontab")
- assert_equal(
- "bin", inst.should(:target),
+ # Now make a new cron with a user, and make sure it gets copied
+ # over
- "target did not default to user with crontab")
- end
- end
+ inst = @crontype.new(
+ :name => "yay", :command => "/some/thing",
- # #705 - make sure extra spaces don't screw things up
- def test_spaces_in_command
- string = "echo multiple spaces"
- cron = @crontype.new(:name => "space testing", :command => string)
- assert_apply(cron)
+ :user => "bin", :provider => :crontab)
- cron = @crontype.new(:name => "space testing", :command => string)
+ assert_equal(
+ "bin", inst.should(:target),
- # Now make sure that it's correctly in sync
- cron.provider.class.prefetch("testing" => cron)
- properties = cron.retrieve
- assert_equal(string, properties[:command], "Cron did not pick up extra spaces in command")
- assert(cron.parameter(:command).insync?(properties[:command]), "Command changed with multiple spaces")
+ "target did not default to user with crontab")
end
+ end
+
+ # #705 - make sure extra spaces don't screw things up
+ def test_spaces_in_command
+ string = "echo multiple spaces"
+ cron = @crontype.new(:name => "space testing", :command => string)
+ assert_apply(cron)
+
+ cron = @crontype.new(:name => "space testing", :command => string)
+
+ # Now make sure that it's correctly in sync
+ cron.provider.class.prefetch("testing" => cron)
+ properties = cron.retrieve
+ assert_equal(string, properties[:command], "Cron did not pick up extra spaces in command")
+ assert(cron.parameter(:command).insync?(properties[:command]), "Command changed with multiple spaces")
+ end
end
diff --git a/test/ral/type/exec.rb b/test/ral/type/exec.rb
index eacb12a..5b26a98 100755
--- a/test/ral/type/exec.rb
+++ b/test/ral/type/exec.rb
@@ -5,843 +5,843 @@ require File.dirname(__FILE__) + '/../../lib/puppettest'
require 'puppettest'
class TestExec < Test::Unit::TestCase
- include PuppetTest
- def test_numvsstring
- [0, "0"].each { |val|
- command = nil
- output = nil
- assert_nothing_raised {
+ include PuppetTest
+ def test_numvsstring
+ [0, "0"].each { |val|
+ command = nil
+ output = nil
+ assert_nothing_raised {
- command = Puppet::Type.type(:exec).new(
+ command = Puppet::Type.type(:exec).new(
- :command => "/bin/echo",
+ :command => "/bin/echo",
- :returns => val
- )
- }
- assert_events([:executed_command], command)
- }
- end
+ :returns => val
+ )
+ }
+ assert_events([:executed_command], command)
+ }
+ end
+
+ def test_path_or_qualified
+ command = nil
+ output = nil
+ assert_raise(Puppet::Error) {
+ command = Puppet::Type.type(:exec).new(
+ :command => "echo"
+ )
+ }
+ assert_nothing_raised {
- def test_path_or_qualified
- command = nil
- output = nil
- assert_raise(Puppet::Error) {
- command = Puppet::Type.type(:exec).new(
- :command => "echo"
- )
- }
- assert_nothing_raised {
+ command = Puppet::Type.type(:exec).new(
- command = Puppet::Type.type(:exec).new(
+ :command => "echo",
- :command => "echo",
+ :path => "/usr/bin:/bin:/usr/sbin:/sbin"
+ )
+ }
+ assert_nothing_raised {
+ command = Puppet::Type.type(:exec).new(
+ :command => "/bin/echo"
+ )
+ }
+ assert_nothing_raised {
- :path => "/usr/bin:/bin:/usr/sbin:/sbin"
- )
- }
- assert_nothing_raised {
- command = Puppet::Type.type(:exec).new(
- :command => "/bin/echo"
- )
- }
- assert_nothing_raised {
+ command = Puppet::Type.type(:exec).new(
- command = Puppet::Type.type(:exec).new(
+ :command => "/bin/echo",
- :command => "/bin/echo",
+ :path => "/usr/bin:/bin:/usr/sbin:/sbin"
+ )
+ }
+ end
- :path => "/usr/bin:/bin:/usr/sbin:/sbin"
- )
- }
- end
-
- def test_nonzero_returns
- assert_nothing_raised {
+ def test_nonzero_returns
+ assert_nothing_raised {
- command = Puppet::Type.type(:exec).new(
+ command = Puppet::Type.type(:exec).new(
- :command => "mkdir /this/directory/does/not/exist",
- :path => "/usr/bin:/bin:/usr/sbin:/sbin",
+ :command => "mkdir /this/directory/does/not/exist",
+ :path => "/usr/bin:/bin:/usr/sbin:/sbin",
- :returns => 1
- )
- }
- assert_nothing_raised {
+ :returns => 1
+ )
+ }
+ assert_nothing_raised {
- command = Puppet::Type.type(:exec).new(
+ command = Puppet::Type.type(:exec).new(
- :command => "touch /etc",
- :path => "/usr/bin:/bin:/usr/sbin:/sbin",
+ :command => "touch /etc",
+ :path => "/usr/bin:/bin:/usr/sbin:/sbin",
- :returns => 1
- )
- }
- assert_nothing_raised {
+ :returns => 1
+ )
+ }
+ assert_nothing_raised {
- command = Puppet::Type.type(:exec).new(
+ command = Puppet::Type.type(:exec).new(
- :command => "thiscommanddoesnotexist",
- :path => "/usr/bin:/bin:/usr/sbin:/sbin",
+ :command => "thiscommanddoesnotexist",
+ :path => "/usr/bin:/bin:/usr/sbin:/sbin",
- :returns => 127
- )
- }
- end
+ :returns => 127
+ )
+ }
+ end
- def test_cwdsettings
- command = nil
- dir = "/tmp"
- wd = Dir.chdir(dir) {
- Dir.getwd
- }
- assert_nothing_raised {
+ def test_cwdsettings
+ command = nil
+ dir = "/tmp"
+ wd = Dir.chdir(dir) {
+ Dir.getwd
+ }
+ assert_nothing_raised {
- command = Puppet::Type.type(:exec).new(
+ command = Puppet::Type.type(:exec).new(
- :command => "pwd",
- :cwd => dir,
- :path => "/usr/bin:/bin:/usr/sbin:/sbin",
+ :command => "pwd",
+ :cwd => dir,
+ :path => "/usr/bin:/bin:/usr/sbin:/sbin",
- :returns => 0
- )
- }
- assert_events([:executed_command], command)
- assert_equal(wd,command.output.chomp)
- end
+ :returns => 0
+ )
+ }
+ assert_events([:executed_command], command)
+ assert_equal(wd,command.output.chomp)
+ end
- def test_refreshonly_functional
- file = nil
- cmd = nil
- tmpfile = tempfile
- @@tmpfiles.push tmpfile
- trans = nil
+ def test_refreshonly_functional
+ file = nil
+ cmd = nil
+ tmpfile = tempfile
+ @@tmpfiles.push tmpfile
+ trans = nil
- file = Puppet::Type.type(:file).new(
+ file = Puppet::Type.type(:file).new(
- :path => tmpfile,
+ :path => tmpfile,
- :content => "yay"
- )
- # Get the file in sync
- assert_apply(file)
+ :content => "yay"
+ )
+ # Get the file in sync
+ assert_apply(file)
- # Now make an exec
- maker = tempfile
- assert_nothing_raised {
+ # Now make an exec
+ maker = tempfile
+ assert_nothing_raised {
- cmd = Puppet::Type.type(:exec).new(
+ cmd = Puppet::Type.type(:exec).new(
- :command => "touch #{maker}",
- :path => "/usr/bin:/bin:/usr/sbin:/sbin",
- :subscribe => file,
+ :command => "touch #{maker}",
+ :path => "/usr/bin:/bin:/usr/sbin:/sbin",
+ :subscribe => file,
- :refreshonly => true
- )
- }
+ :refreshonly => true
+ )
+ }
- assert(cmd, "did not make exec")
+ assert(cmd, "did not make exec")
- assert_nothing_raised do
- assert(! cmd.check, "Check passed when refreshonly is set")
- end
+ assert_nothing_raised do
+ assert(! cmd.check, "Check passed when refreshonly is set")
+ end
- assert_events([], file, cmd)
- assert(! FileTest.exists?(maker), "made file without refreshing")
+ assert_events([], file, cmd)
+ assert(! FileTest.exists?(maker), "made file without refreshing")
- # Now change our content, so we throw a refresh
- file[:content] = "yayness"
- assert_events([:content_changed, :restarted], file, cmd)
- assert(FileTest.exists?(maker), "file was not made in refresh")
- end
+ # Now change our content, so we throw a refresh
+ file[:content] = "yayness"
+ assert_events([:content_changed, :restarted], file, cmd)
+ assert(FileTest.exists?(maker), "file was not made in refresh")
+ end
- def test_refreshonly
- cmd = true
- assert_nothing_raised {
+ def test_refreshonly
+ cmd = true
+ assert_nothing_raised {
- cmd = Puppet::Type.type(:exec).new(
+ cmd = Puppet::Type.type(:exec).new(
- :command => "pwd",
- :path => "/usr/bin:/bin:/usr/sbin:/sbin",
+ :command => "pwd",
+ :path => "/usr/bin:/bin:/usr/sbin:/sbin",
- :refreshonly => true
- )
- }
+ :refreshonly => true
+ )
+ }
- # Checks should always fail when refreshonly is enabled
- assert(!cmd.check, "Check passed with refreshonly true")
+ # Checks should always fail when refreshonly is enabled
+ assert(!cmd.check, "Check passed with refreshonly true")
- # Now make sure it passes if we pass in "true"
- assert(cmd.check(true), "Check failed with refreshonly true while refreshing")
+ # Now make sure it passes if we pass in "true"
+ assert(cmd.check(true), "Check failed with refreshonly true while refreshing")
- # Now set it to false
- cmd[:refreshonly] = false
- assert(cmd.check, "Check failed with refreshonly false")
- end
+ # Now set it to false
+ cmd[:refreshonly] = false
+ assert(cmd.check, "Check failed with refreshonly false")
+ end
- def test_creates
- file = tempfile
- exec = nil
- assert(! FileTest.exists?(file), "File already exists")
- assert_nothing_raised {
+ def test_creates
+ file = tempfile
+ exec = nil
+ assert(! FileTest.exists?(file), "File already exists")
+ assert_nothing_raised {
- exec = Puppet::Type.type(:exec).new(
+ exec = Puppet::Type.type(:exec).new(
- :command => "touch #{file}",
- :path => "/usr/bin:/bin:/usr/sbin:/sbin",
+ :command => "touch #{file}",
+ :path => "/usr/bin:/bin:/usr/sbin:/sbin",
- :creates => file
- )
- }
+ :creates => file
+ )
+ }
- comp = mk_catalog("createstest", exec)
- assert_events([:executed_command], comp, "creates")
- assert_events([], comp, "creates")
- end
+ comp = mk_catalog("createstest", exec)
+ assert_events([:executed_command], comp, "creates")
+ assert_events([], comp, "creates")
+ end
- # Verify that we can download the file that we're going to execute.
- def test_retrievethenmkexe
- exe = tempfile
- oexe = tempfile
- sh = %x{which sh}
- File.open(exe, "w") { |f| f.puts "#!#{sh}\necho yup" }
+ # Verify that we can download the file that we're going to execute.
+ def test_retrievethenmkexe
+ exe = tempfile
+ oexe = tempfile
+ sh = %x{which sh}
+ File.open(exe, "w") { |f| f.puts "#!#{sh}\necho yup" }
- file = Puppet::Type.type(:file).new(
+ file = Puppet::Type.type(:file).new(
- :path => oexe,
- :source => exe,
+ :path => oexe,
+ :source => exe,
- :mode => 0755
- )
+ :mode => 0755
+ )
- exec = Puppet::Type.type(:exec).new(
+ exec = Puppet::Type.type(:exec).new(
- :command => oexe,
+ :command => oexe,
- :require => Puppet::Resource.new(:file, oexe)
- )
+ :require => Puppet::Resource.new(:file, oexe)
+ )
- comp = mk_catalog("Testing", file, exec)
+ comp = mk_catalog("Testing", file, exec)
- assert_events([:file_created, :executed_command], comp)
- end
+ assert_events([:file_created, :executed_command], comp)
+ end
- # Verify that we auto-require any managed scripts.
- def test_autorequire_files
- exe = tempfile
- oexe = tempfile
- sh = %x{which sh}
- File.open(exe, "w") { |f| f.puts "#!#{sh}\necho yup" }
+ # Verify that we auto-require any managed scripts.
+ def test_autorequire_files
+ exe = tempfile
+ oexe = tempfile
+ sh = %x{which sh}
+ File.open(exe, "w") { |f| f.puts "#!#{sh}\necho yup" }
- file = Puppet::Type.type(:file).new(
+ file = Puppet::Type.type(:file).new(
- :path => oexe,
- :source => exe,
+ :path => oexe,
+ :source => exe,
- :mode => 755
- )
+ :mode => 755
+ )
- basedir = File.dirname(oexe)
+ basedir = File.dirname(oexe)
- baseobj = Puppet::Type.type(:file).new(
+ baseobj = Puppet::Type.type(:file).new(
- :path => basedir,
- :source => exe,
+ :path => basedir,
+ :source => exe,
- :mode => 755
- )
+ :mode => 755
+ )
- ofile = Puppet::Type.type(:file).new(
+ ofile = Puppet::Type.type(:file).new(
- :path => exe,
+ :path => exe,
- :mode => 755
- )
+ :mode => 755
+ )
- exec = Puppet::Type.type(:exec).new(
+ exec = Puppet::Type.type(:exec).new(
- :command => oexe,
- :path => ENV["PATH"],
+ :command => oexe,
+ :path => ENV["PATH"],
- :cwd => basedir
- )
+ :cwd => basedir
+ )
- cat = Puppet::Type.type(:exec).new(
+ cat = Puppet::Type.type(:exec).new(
- :command => "cat #{exe} #{oexe}",
+ :command => "cat #{exe} #{oexe}",
- :path => ENV["PATH"]
- )
+ :path => ENV["PATH"]
+ )
- catalog = mk_catalog(file, baseobj, ofile, exec, cat)
+ catalog = mk_catalog(file, baseobj, ofile, exec, cat)
- rels = nil
- assert_nothing_raised do
- rels = exec.autorequire
- end
+ rels = nil
+ assert_nothing_raised do
+ rels = exec.autorequire
+ end
- # Verify we get the script itself
- assert(rels.detect { |r| r.source == file }, "Exec did not autorequire its command")
+ # Verify we get the script itself
+ assert(rels.detect { |r| r.source == file }, "Exec did not autorequire its command")
- # Verify we catch the cwd
- assert(rels.detect { |r| r.source == baseobj }, "Exec did not autorequire its cwd")
+ # Verify we catch the cwd
+ assert(rels.detect { |r| r.source == baseobj }, "Exec did not autorequire its cwd")
- # Verify we don't require ourselves
- assert(! rels.detect { |r| r.source == ofile }, "Exec incorrectly required mentioned file")
+ # Verify we don't require ourselves
+ assert(! rels.detect { |r| r.source == ofile }, "Exec incorrectly required mentioned file")
- # We not longer autorequire inline files
- assert_nothing_raised do
- rels = cat.autorequire
- end
- assert(! rels.detect { |r| r.source == ofile }, "Exec required second inline file")
- assert(! rels.detect { |r| r.source == file }, "Exec required inline file")
+ # We not longer autorequire inline files
+ assert_nothing_raised do
+ rels = cat.autorequire
end
+ assert(! rels.detect { |r| r.source == ofile }, "Exec required second inline file")
+ assert(! rels.detect { |r| r.source == file }, "Exec required inline file")
+ end
- def test_ifonly
- afile = tempfile
- bfile = tempfile
-
- exec = nil
- assert_nothing_raised {
+ def test_ifonly
+ afile = tempfile
+ bfile = tempfile
- exec = Puppet::Type.type(:exec).new(
+ exec = nil
+ assert_nothing_raised {
- :command => "touch #{bfile}",
- :onlyif => "test -f #{afile}",
+ exec = Puppet::Type.type(:exec).new(
- :path => ENV['PATH']
- )
- }
+ :command => "touch #{bfile}",
+ :onlyif => "test -f #{afile}",
- assert_events([], exec)
- system("touch #{afile}")
- assert_events([:executed_command], exec)
- assert_events([:executed_command], exec)
- system("rm #{afile}")
- assert_events([], exec)
- end
+ :path => ENV['PATH']
+ )
+ }
- def test_unless
- afile = tempfile
- bfile = tempfile
+ assert_events([], exec)
+ system("touch #{afile}")
+ assert_events([:executed_command], exec)
+ assert_events([:executed_command], exec)
+ system("rm #{afile}")
+ assert_events([], exec)
+ end
- exec = nil
- assert_nothing_raised {
+ def test_unless
+ afile = tempfile
+ bfile = tempfile
- exec = Puppet::Type.type(:exec).new(
+ exec = nil
+ assert_nothing_raised {
- :command => "touch #{bfile}",
- :unless => "test -f #{afile}",
+ exec = Puppet::Type.type(:exec).new(
+
+ :command => "touch #{bfile}",
+ :unless => "test -f #{afile}",
+
+ :path => ENV['PATH']
+ )
+ }
+ comp = mk_catalog(exec)
+
+ assert_events([:executed_command], comp)
+ assert_events([:executed_command], comp)
+ system("touch #{afile}")
+ assert_events([], comp)
+ assert_events([], comp)
+ system("rm #{afile}")
+ assert_events([:executed_command], comp)
+ assert_events([:executed_command], comp)
+ end
+
+ if Puppet.features.root?
+ # Verify that we can execute commands as a special user
+ def mknverify(file, user, group = nil, id = true)
+ File.umask(0022)
+
+ args = {
+ :command => "touch #{file}",
+ :path => "/usr/bin:/bin:/usr/sbin:/sbin",
+ }
+
+ if user
+ #Puppet.warning "Using user #{user.name}"
+ if id
+ # convert to a string, because that's what the object expects
+ args[:user] = user.uid.to_s
+ else
+ args[:user] = user.name
+ end
+ end
+
+ if group
+ #Puppet.warning "Using group #{group.name}"
+ if id
+ args[:group] = group.gid.to_s
+ else
+ args[:group] = group.name
+ end
+ end
+ exec = nil
+ assert_nothing_raised {
+ exec = Puppet::Type.type(:exec).new(args)
+ }
- :path => ENV['PATH']
- )
- }
- comp = mk_catalog(exec)
-
- assert_events([:executed_command], comp)
- assert_events([:executed_command], comp)
- system("touch #{afile}")
- assert_events([], comp)
- assert_events([], comp)
- system("rm #{afile}")
- assert_events([:executed_command], comp)
- assert_events([:executed_command], comp)
- end
+ comp = mk_catalog("usertest", exec)
+ assert_events([:executed_command], comp, "usertest")
- if Puppet.features.root?
- # Verify that we can execute commands as a special user
- def mknverify(file, user, group = nil, id = true)
- File.umask(0022)
-
- args = {
- :command => "touch #{file}",
- :path => "/usr/bin:/bin:/usr/sbin:/sbin",
- }
-
- if user
- #Puppet.warning "Using user #{user.name}"
- if id
- # convert to a string, because that's what the object expects
- args[:user] = user.uid.to_s
- else
- args[:user] = user.name
- end
- end
-
- if group
- #Puppet.warning "Using group #{group.name}"
- if id
- args[:group] = group.gid.to_s
- else
- args[:group] = group.name
- end
- end
- exec = nil
- assert_nothing_raised {
- exec = Puppet::Type.type(:exec).new(args)
- }
-
- comp = mk_catalog("usertest", exec)
- assert_events([:executed_command], comp, "usertest")
-
- assert(FileTest.exists?(file), "File does not exist")
- assert_equal(user.uid, File.stat(file).uid, "File UIDs do not match") if user
-
- # We can't actually test group ownership, unfortunately, because
- # behaviour changes wildlly based on platform.
- Puppet::Type.allclear
- end
+ assert(FileTest.exists?(file), "File does not exist")
+ assert_equal(user.uid, File.stat(file).uid, "File UIDs do not match") if user
- def test_userngroup
- file = tempfile
- [
- [nonrootuser], # just user, by name
- [nonrootuser, nil, true], # user, by uid
- [nil, nonrootgroup], # just group
- [nil, nonrootgroup, true], # just group, by id
- [nonrootuser, nonrootgroup], # user and group, by name
- [nonrootuser, nonrootgroup, true], # user and group, by id
- ].each { |ary|
- mknverify(file, *ary) {
- }
- }
- end
+ # We can't actually test group ownership, unfortunately, because
+ # behaviour changes wildlly based on platform.
+ Puppet::Type.allclear
end
- def test_logoutput
- exec = nil
- assert_nothing_raised {
+ def test_userngroup
+ file = tempfile
+ [
+ [nonrootuser], # just user, by name
+ [nonrootuser, nil, true], # user, by uid
+ [nil, nonrootgroup], # just group
+ [nil, nonrootgroup, true], # just group, by id
+ [nonrootuser, nonrootgroup], # user and group, by name
+ [nonrootuser, nonrootgroup, true], # user and group, by id
+ ].each { |ary|
+ mknverify(file, *ary) {
+ }
+ }
+ end
+ end
- exec = Puppet::Type.type(:exec).new(
+ def test_logoutput
+ exec = nil
+ assert_nothing_raised {
- :title => "logoutputesting",
- :path => "/usr/bin:/bin",
- :command => "echo logoutput is false",
+ exec = Puppet::Type.type(:exec).new(
- :logoutput => false
- )
- }
+ :title => "logoutputesting",
+ :path => "/usr/bin:/bin",
+ :command => "echo logoutput is false",
- assert_apply(exec)
+ :logoutput => false
+ )
+ }
- assert_nothing_raised {
- exec[:command] = "echo logoutput is true"
- exec[:logoutput] = true
- }
+ assert_apply(exec)
- assert_apply(exec)
+ assert_nothing_raised {
+ exec[:command] = "echo logoutput is true"
+ exec[:logoutput] = true
+ }
- assert_nothing_raised {
- exec[:command] = "echo logoutput is on_failure"
- exec[:logoutput] = "on_failure"
- }
+ assert_apply(exec)
- assert_apply(exec)
- end
+ assert_nothing_raised {
+ exec[:command] = "echo logoutput is on_failure"
+ exec[:logoutput] = "on_failure"
+ }
+
+ assert_apply(exec)
+ end
+
+ def test_execthenfile
+ exec = nil
+ file = nil
+ basedir = tempfile
+ path = File.join(basedir, "subfile")
+ assert_nothing_raised {
- def test_execthenfile
- exec = nil
- file = nil
- basedir = tempfile
- path = File.join(basedir, "subfile")
- assert_nothing_raised {
+ exec = Puppet::Type.type(:exec).new(
- exec = Puppet::Type.type(:exec).new(
+ :title => "mkdir",
+ :path => "/usr/bin:/bin",
+ :creates => basedir,
- :title => "mkdir",
- :path => "/usr/bin:/bin",
- :creates => basedir,
+ :command => "mkdir #{basedir}; touch #{path}"
- :command => "mkdir #{basedir}; touch #{path}"
+ )
+ }
- )
- }
+ assert_nothing_raised {
- assert_nothing_raised {
+ file = Puppet::Type.type(:file).new(
- file = Puppet::Type.type(:file).new(
+ :path => basedir,
+ :recurse => true,
+ :mode => "755",
- :path => basedir,
- :recurse => true,
- :mode => "755",
+ :require => Puppet::Resource.new("exec", "mkdir")
+ )
+ }
- :require => Puppet::Resource.new("exec", "mkdir")
- )
- }
+ comp = mk_catalog(file, exec)
+ comp.finalize
+ assert_events([:executed_command, :mode_changed], comp)
- comp = mk_catalog(file, exec)
- comp.finalize
- assert_events([:executed_command, :mode_changed], comp)
+ assert(FileTest.exists?(path), "Exec ran first")
+ assert(File.stat(path).mode & 007777 == 0755)
+ end
- assert(FileTest.exists?(path), "Exec ran first")
- assert(File.stat(path).mode & 007777 == 0755)
+ # Make sure all checks need to be fully qualified.
+ def test_falsevals
+ exec = nil
+ assert_nothing_raised do
+ exec = Puppet::Type.type(:exec).new(
+ :command => "/bin/touch yayness"
+ )
end
- # Make sure all checks need to be fully qualified.
- def test_falsevals
- exec = nil
- assert_nothing_raised do
- exec = Puppet::Type.type(:exec).new(
- :command => "/bin/touch yayness"
- )
- end
-
- Puppet::Type.type(:exec).checks.each do |check|
- klass = Puppet::Type.type(:exec).paramclass(check)
- next if klass.value_collection.values.include? :false
- assert_raise(Puppet::Error, "Check '#{check}' did not fail on false") do
- exec[check] = false
- end
- end
+ Puppet::Type.type(:exec).checks.each do |check|
+ klass = Puppet::Type.type(:exec).paramclass(check)
+ next if klass.value_collection.values.include? :false
+ assert_raise(Puppet::Error, "Check '#{check}' did not fail on false") do
+ exec[check] = false
+ end
end
+ end
- def test_createcwdandexe
- exec1 = exec2 = nil
- dir = tempfile
- file = tempfile
+ def test_createcwdandexe
+ exec1 = exec2 = nil
+ dir = tempfile
+ file = tempfile
- assert_nothing_raised {
+ assert_nothing_raised {
- exec1 = Puppet::Type.type(:exec).new(
+ exec1 = Puppet::Type.type(:exec).new(
- :title => "one",
- :path => ENV["PATH"],
+ :title => "one",
+ :path => ENV["PATH"],
- :command => "mkdir #{dir}"
- )
- }
+ :command => "mkdir #{dir}"
+ )
+ }
- assert_nothing_raised("Could not create exec w/out existing cwd") {
+ assert_nothing_raised("Could not create exec w/out existing cwd") {
- exec2 = Puppet::Type.type(:exec).new(
+ exec2 = Puppet::Type.type(:exec).new(
- :title => "two",
- :path => ENV["PATH"],
- :command => "touch #{file}",
+ :title => "two",
+ :path => ENV["PATH"],
+ :command => "touch #{file}",
- :cwd => dir
- )
- }
+ :cwd => dir
+ )
+ }
- # Throw a check in there with our cwd and make sure it works
- assert_nothing_raised("Could not check with a missing cwd") do
- exec2[:unless] = "test -f /this/file/does/not/exist"
- exec2.retrieve
- end
+ # Throw a check in there with our cwd and make sure it works
+ assert_nothing_raised("Could not check with a missing cwd") do
+ exec2[:unless] = "test -f /this/file/does/not/exist"
+ exec2.retrieve
+ end
- assert_raise(Puppet::Error) do
- exec2.property(:returns).sync
- end
+ assert_raise(Puppet::Error) do
+ exec2.property(:returns).sync
+ end
- assert_nothing_raised do
- exec2[:require] = exec1
- end
+ assert_nothing_raised do
+ exec2[:require] = exec1
+ end
- assert_apply(exec1, exec2)
+ assert_apply(exec1, exec2)
- assert(FileTest.exists?(file))
- end
+ assert(FileTest.exists?(file))
+ end
- def test_checkarrays
- exec = nil
- file = tempfile
+ def test_checkarrays
+ exec = nil
+ file = tempfile
- test = "test -f #{file}"
+ test = "test -f #{file}"
- assert_nothing_raised {
+ assert_nothing_raised {
- exec = Puppet::Type.type(:exec).new(
+ exec = Puppet::Type.type(:exec).new(
- :path => ENV["PATH"],
+ :path => ENV["PATH"],
- :command => "touch #{file}"
- )
- }
+ :command => "touch #{file}"
+ )
+ }
- assert_nothing_raised {
- exec[:unless] = test
- }
+ assert_nothing_raised {
+ exec[:unless] = test
+ }
- assert_nothing_raised {
- assert(exec.check, "Check did not pass")
- }
+ assert_nothing_raised {
+ assert(exec.check, "Check did not pass")
+ }
- assert_nothing_raised {
- exec[:unless] = [test, test]
- }
+ assert_nothing_raised {
+ exec[:unless] = [test, test]
+ }
- assert_nothing_raised {
- exec.finish
- }
+ assert_nothing_raised {
+ exec.finish
+ }
- assert_nothing_raised {
- assert(exec.check, "Check did not pass")
- }
+ assert_nothing_raised {
+ assert(exec.check, "Check did not pass")
+ }
- assert_apply(exec)
+ assert_apply(exec)
- assert_nothing_raised {
- assert(! exec.check, "Check passed")
- }
- end
+ assert_nothing_raised {
+ assert(! exec.check, "Check passed")
+ }
+ end
- def test_missing_checks_cause_failures
- # Solaris's sh exits with 1 here instead of 127
- return if Facter.value(:operatingsystem) == "Solaris"
+ def test_missing_checks_cause_failures
+ # Solaris's sh exits with 1 here instead of 127
+ return if Facter.value(:operatingsystem) == "Solaris"
- exec = Puppet::Type.type(:exec).new(
+ exec = Puppet::Type.type(:exec).new(
- :command => "echo true",
- :path => ENV["PATH"],
+ :command => "echo true",
+ :path => ENV["PATH"],
- :onlyif => "/bin/nosuchthingexists"
- )
+ :onlyif => "/bin/nosuchthingexists"
+ )
- assert_raise(ArgumentError, "Missing command did not raise error") {
- exec.run("/bin/nosuchthingexists")
- }
- end
+ assert_raise(ArgumentError, "Missing command did not raise error") {
+ exec.run("/bin/nosuchthingexists")
+ }
+ end
- def test_envparam
+ def test_envparam
- exec = Puppet::Type.newexec(
+ exec = Puppet::Type.newexec(
- :command => "echo $envtest",
- :path => ENV["PATH"],
+ :command => "echo $envtest",
+ :path => ENV["PATH"],
- :env => "envtest=yayness"
- )
+ :env => "envtest=yayness"
+ )
- assert(exec, "Could not make exec")
+ assert(exec, "Could not make exec")
- output = status = nil
- assert_nothing_raised {
- output, status = exec.run("echo $envtest")
- }
+ output = status = nil
+ assert_nothing_raised {
+ output, status = exec.run("echo $envtest")
+ }
- assert_equal("yayness\n", output)
+ assert_equal("yayness\n", output)
- # Now check whether we can do multiline settings
- assert_nothing_raised do
- exec[:env] = "envtest=a list of things
+ # Now check whether we can do multiline settings
+ assert_nothing_raised do
+ exec[:env] = "envtest=a list of things
and stuff"
+ end
+
+ output = status = nil
+ assert_nothing_raised {
+ output, status = exec.run('echo "$envtest"')
+ }
+ assert_equal("a list of things\nand stuff\n", output)
+
+ # Now test arrays
+ assert_nothing_raised do
+ exec[:env] = ["funtest=A", "yaytest=B"]
end
output = status = nil
assert_nothing_raised {
- output, status = exec.run('echo "$envtest"')
- }
- assert_equal("a list of things\nand stuff\n", output)
+ output, status = exec.run('echo "$funtest" "$yaytest"')
+ }
+ assert_equal("A B\n", output)
+ end
- # Now test arrays
- assert_nothing_raised do
- exec[:env] = ["funtest=A", "yaytest=B"]
- end
+ def test_environmentparam
- output = status = nil
- assert_nothing_raised {
- output, status = exec.run('echo "$funtest" "$yaytest"')
- }
- assert_equal("A B\n", output)
- end
+ exec = Puppet::Type.newexec(
- def test_environmentparam
+ :command => "echo $environmenttest",
+ :path => ENV["PATH"],
- exec = Puppet::Type.newexec(
+ :environment => "environmenttest=yayness"
+ )
- :command => "echo $environmenttest",
- :path => ENV["PATH"],
+ assert(exec, "Could not make exec")
- :environment => "environmenttest=yayness"
- )
+ output = status = nil
+ assert_nothing_raised {
+ output, status = exec.run("echo $environmenttest")
+ }
- assert(exec, "Could not make exec")
+ assert_equal("yayness\n", output)
- output = status = nil
- assert_nothing_raised {
- output, status = exec.run("echo $environmenttest")
- }
+ # Now check whether we can do multiline settings
+ assert_nothing_raised do
+ exec[:environment] = "environmenttest=a list of things
+and stuff"
+ end
- assert_equal("yayness\n", output)
+ output = status = nil
+ assert_nothing_raised {
+ output, status = exec.run('echo "$environmenttest"')
+ }
+ assert_equal("a list of things\nand stuff\n", output)
- # Now check whether we can do multiline settings
- assert_nothing_raised do
- exec[:environment] = "environmenttest=a list of things
-and stuff"
+ # Now test arrays
+ assert_nothing_raised do
+ exec[:environment] = ["funtest=A", "yaytest=B"]
end
output = status = nil
assert_nothing_raised {
- output, status = exec.run('echo "$environmenttest"')
- }
- assert_equal("a list of things\nand stuff\n", output)
+ output, status = exec.run('echo "$funtest" "$yaytest"')
+ }
+ assert_equal("A B\n", output)
+ end
- # Now test arrays
- assert_nothing_raised do
- exec[:environment] = ["funtest=A", "yaytest=B"]
- end
+ def test_timeout
+ exec = Puppet::Type.type(:exec).new(:command => "sleep 1", :path => ENV["PATH"], :timeout => "0.2")
+ time = Time.now
- output = status = nil
- assert_nothing_raised {
- output, status = exec.run('echo "$funtest" "$yaytest"')
- }
- assert_equal("A B\n", output)
- end
+ assert_raise(Timeout::Error) {
+ exec.run("sleep 1")
+ }
+ Puppet.info "#{Time.now.to_f - time.to_f} seconds, vs a timeout of #{exec[:timeout]}"
- def test_timeout
- exec = Puppet::Type.type(:exec).new(:command => "sleep 1", :path => ENV["PATH"], :timeout => "0.2")
- time = Time.now
- assert_raise(Timeout::Error) {
- exec.run("sleep 1")
- }
- Puppet.info "#{Time.now.to_f - time.to_f} seconds, vs a timeout of #{exec[:timeout]}"
+ assert_apply(exec)
+ end
+ # Testing #470
+ def test_run_as_created_user
+ exec = nil
+ if Process.uid == 0
+ user = "nosuchuser"
+ assert_nothing_raised("Could not create exec with non-existent user") do
- assert_apply(exec)
- end
+ exec = Puppet::Type.type(:exec).new(
- # Testing #470
- def test_run_as_created_user
- exec = nil
- if Process.uid == 0
- user = "nosuchuser"
- assert_nothing_raised("Could not create exec with non-existent user") do
+ :command => "/bin/echo yay",
- exec = Puppet::Type.type(:exec).new(
-
- :command => "/bin/echo yay",
-
- :user => user
- )
- end
- end
+ :user => user
+ )
+ end
+ end
- # Now try the group
- group = "nosuchgroup"
- assert_nothing_raised("Could not create exec with non-existent user") do
+ # Now try the group
+ group = "nosuchgroup"
+ assert_nothing_raised("Could not create exec with non-existent user") do
- exec = Puppet::Type.type(:exec).new(
+ exec = Puppet::Type.type(:exec).new(
- :command => "/bin/echo yay",
+ :command => "/bin/echo yay",
- :group => group
- )
- end
+ :group => group
+ )
end
-
- # make sure paths work both as arrays and strings
- def test_paths_as_arrays
- path = %w{/usr/bin /usr/sbin /sbin}
- exec = nil
- assert_nothing_raised("Could not use an array for the path") do
- exec = Puppet::Type.type(:exec).new(:command => "echo yay", :path => path)
- end
- assert_equal(path, exec[:path], "array-based path did not match")
- assert_nothing_raised("Could not use a string for the path") do
- exec = Puppet::Type.type(:exec).new(:command => "echo yay", :path => path.join(":"))
- end
- assert_equal(path, exec[:path], "string-based path did not match")
- assert_nothing_raised("Could not use a colon-separated strings in an array for the path") do
- exec = Puppet::Type.type(:exec).new(:command => "echo yay", :path => ["/usr/bin", "/usr/sbin:/sbin"])
- end
- assert_equal(path, exec[:path], "colon-separated array path did not match")
+ end
+
+ # make sure paths work both as arrays and strings
+ def test_paths_as_arrays
+ path = %w{/usr/bin /usr/sbin /sbin}
+ exec = nil
+ assert_nothing_raised("Could not use an array for the path") do
+ exec = Puppet::Type.type(:exec).new(:command => "echo yay", :path => path)
+ end
+ assert_equal(path, exec[:path], "array-based path did not match")
+ assert_nothing_raised("Could not use a string for the path") do
+ exec = Puppet::Type.type(:exec).new(:command => "echo yay", :path => path.join(":"))
+ end
+ assert_equal(path, exec[:path], "string-based path did not match")
+ assert_nothing_raised("Could not use a colon-separated strings in an array for the path") do
+ exec = Puppet::Type.type(:exec).new(:command => "echo yay", :path => ["/usr/bin", "/usr/sbin:/sbin"])
end
+ assert_equal(path, exec[:path], "colon-separated array path did not match")
+ end
- def test_checks_apply_to_refresh
- file = tempfile
- maker = tempfile
+ def test_checks_apply_to_refresh
+ file = tempfile
+ maker = tempfile
- exec = Puppet::Type.type(:exec).new(
+ exec = Puppet::Type.type(:exec).new(
- :title => "maker",
- :command => "touch #{maker}",
+ :title => "maker",
+ :command => "touch #{maker}",
- :path => ENV["PATH"]
- )
+ :path => ENV["PATH"]
+ )
- # Make sure it runs normally
- assert_apply(exec)
- assert(FileTest.exists?(maker), "exec did not run")
- File.unlink(maker)
+ # Make sure it runs normally
+ assert_apply(exec)
+ assert(FileTest.exists?(maker), "exec did not run")
+ File.unlink(maker)
- # Now make sure it refreshes
- assert_nothing_raised("Failed to refresh exec") do
- exec.refresh
- end
- assert(FileTest.exists?(maker), "exec did not run refresh")
- File.unlink(maker)
-
- # Now add the checks
- exec[:creates] = file
+ # Now make sure it refreshes
+ assert_nothing_raised("Failed to refresh exec") do
+ exec.refresh
+ end
+ assert(FileTest.exists?(maker), "exec did not run refresh")
+ File.unlink(maker)
- # Make sure it runs when the file doesn't exist
- assert_nothing_raised("Failed to refresh exec") do
- exec.refresh
- end
- assert(FileTest.exists?(maker), "exec did not refresh when checks passed")
- File.unlink(maker)
+ # Now add the checks
+ exec[:creates] = file
- # Now create the file and make sure it doesn't refresh
- File.open(file, "w") { |f| f.puts "" }
- assert_nothing_raised("Failed to refresh exec") do
- exec.refresh
- end
- assert(! FileTest.exists?(maker), "exec refreshed with failing checks")
+ # Make sure it runs when the file doesn't exist
+ assert_nothing_raised("Failed to refresh exec") do
+ exec.refresh
end
+ assert(FileTest.exists?(maker), "exec did not refresh when checks passed")
+ File.unlink(maker)
- def test_explicit_refresh
- refresher = tempfile
- maker = tempfile
+ # Now create the file and make sure it doesn't refresh
+ File.open(file, "w") { |f| f.puts "" }
+ assert_nothing_raised("Failed to refresh exec") do
+ exec.refresh
+ end
+ assert(! FileTest.exists?(maker), "exec refreshed with failing checks")
+ end
- exec = Puppet::Type.type(:exec).new(
+ def test_explicit_refresh
+ refresher = tempfile
+ maker = tempfile
- :title => "maker",
- :command => "touch #{maker}",
+ exec = Puppet::Type.type(:exec).new(
- :path => ENV["PATH"]
- )
+ :title => "maker",
+ :command => "touch #{maker}",
- # Call refresh normally
- assert_nothing_raised do
- exec.refresh
- end
+ :path => ENV["PATH"]
+ )
- # Make sure it created the normal file
- assert(FileTest.exists?(maker), "normal refresh did not work")
- File.unlink(maker)
+ # Call refresh normally
+ assert_nothing_raised do
+ exec.refresh
+ end
- # Now reset refresh, and make sure it wins
- assert_nothing_raised("Could not set refresh parameter") do
- exec[:refresh] = "touch #{refresher}"
- end
- assert_nothing_raised do
- exec.refresh
- end
+ # Make sure it created the normal file
+ assert(FileTest.exists?(maker), "normal refresh did not work")
+ File.unlink(maker)
- # Make sure it created the normal file
- assert(FileTest.exists?(refresher), "refresh param was ignored")
- assert(! FileTest.exists?(maker), "refresh param also ran command")
+ # Now reset refresh, and make sure it wins
+ assert_nothing_raised("Could not set refresh parameter") do
+ exec[:refresh] = "touch #{refresher}"
+ end
+ assert_nothing_raised do
+ exec.refresh
end
- if Puppet.features.root?
- def test_autorequire_user
- user = Puppet::Type.type(:user).new(:name => "yay")
- exec = Puppet::Type.type(:exec).new(:command => "/bin/echo fun", :user => "yay")
-
- rels = nil
- assert_nothing_raised("Could not evaluate autorequire") do
- rels = exec.autorequire
- end
- assert(rels.find { |r| r.source == user and r.target == exec }, "Exec did not autorequire user")
- end
+ # Make sure it created the normal file
+ assert(FileTest.exists?(refresher), "refresh param was ignored")
+ assert(! FileTest.exists?(maker), "refresh param also ran command")
+ end
+
+ if Puppet.features.root?
+ def test_autorequire_user
+ user = Puppet::Type.type(:user).new(:name => "yay")
+ exec = Puppet::Type.type(:exec).new(:command => "/bin/echo fun", :user => "yay")
+
+ rels = nil
+ assert_nothing_raised("Could not evaluate autorequire") do
+ rels = exec.autorequire
+ end
+ assert(rels.find { |r| r.source == user and r.target == exec }, "Exec did not autorequire user")
end
+ end
end
diff --git a/test/ral/type/file.rb b/test/ral/type/file.rb
index 06795de..6322529 100755
--- a/test/ral/type/file.rb
+++ b/test/ral/type/file.rb
@@ -8,905 +8,905 @@ require 'fileutils'
require 'mocha'
class TestFile < Test::Unit::TestCase
- include PuppetTest::Support::Utils
- include PuppetTest::FileTesting
-
- def mkfile(hash)
- file = nil
- assert_nothing_raised {
- file = Puppet::Type.type(:file).new(hash)
- }
- file
- end
-
- def mktestfile
- tmpfile = tempfile
- File.open(tmpfile, "w") { |f| f.puts rand(100) }
- @@tmpfiles.push tmpfile
- mkfile(:name => tmpfile)
- end
-
- def setup
- super
- @file = Puppet::Type.type(:file)
- $method = @method_name
- Puppet[:filetimeout] = -1
- Facter.stubs(:to_hash).returns({})
- end
-
- def teardown
- system("rm -rf #{Puppet[:statefile]}")
- super
- end
-
- def initstorage
- Puppet::Util::Storage.init
- Puppet::Util::Storage.load
- end
-
- def clearstorage
- Puppet::Util::Storage.store
- Puppet::Util::Storage.clear
- end
-
- def test_owner
- file = mktestfile
-
- users = {}
- count = 0
-
- # collect five users
- Etc.passwd { |passwd|
- if count > 5
- break
- else
- count += 1
- end
- users[passwd.uid] = passwd.name
- }
-
- fake = {}
- # find a fake user
- while true
- a = rand(1000)
- begin
- Etc.getpwuid(a)
- rescue
- fake[a] = "fakeuser"
- break
- end
- end
-
- uid, name = users.shift
- us = {}
- us[uid] = name
- users.each { |uid, name|
- assert_apply(file)
- assert_nothing_raised {
- file[:owner] = name
- }
- assert_nothing_raised {
- file.retrieve
- }
- assert_apply(file)
- }
- end
-
- def test_group
- file = mktestfile
- [%x{groups}.chomp.split(/ /), Process.groups].flatten.each { |group|
- assert_nothing_raised {
- file[:group] = group
- }
- assert(file.property(:group))
- assert(file.property(:group).should)
- }
- end
-
- def test_groups_fails_when_invalid
- assert_raise(Puppet::Error, "did not fail when the group was empty") do
- Puppet::Type.type(:file).new :path => "/some/file", :group => ""
- end
- end
-
- if Puppet.features.root?
- def test_createasuser
- dir = tmpdir
-
- user = nonrootuser
- path = File.join(tmpdir, "createusertesting")
- @@tmpfiles << path
-
- file = nil
- assert_nothing_raised {
-
- file = Puppet::Type.type(:file).new(
+ include PuppetTest::Support::Utils
+ include PuppetTest::FileTesting
+
+ def mkfile(hash)
+ file = nil
+ assert_nothing_raised {
+ file = Puppet::Type.type(:file).new(hash)
+ }
+ file
+ end
+
+ def mktestfile
+ tmpfile = tempfile
+ File.open(tmpfile, "w") { |f| f.puts rand(100) }
+ @@tmpfiles.push tmpfile
+ mkfile(:name => tmpfile)
+ end
+
+ def setup
+ super
+ @file = Puppet::Type.type(:file)
+ $method = @method_name
+ Puppet[:filetimeout] = -1
+ Facter.stubs(:to_hash).returns({})
+ end
+
+ def teardown
+ system("rm -rf #{Puppet[:statefile]}")
+ super
+ end
+
+ def initstorage
+ Puppet::Util::Storage.init
+ Puppet::Util::Storage.load
+ end
+
+ def clearstorage
+ Puppet::Util::Storage.store
+ Puppet::Util::Storage.clear
+ end
+
+ def test_owner
+ file = mktestfile
+
+ users = {}
+ count = 0
+
+ # collect five users
+ Etc.passwd { |passwd|
+ if count > 5
+ break
+ else
+ count += 1
+ end
+ users[passwd.uid] = passwd.name
+ }
+
+ fake = {}
+ # find a fake user
+ while true
+ a = rand(1000)
+ begin
+ Etc.getpwuid(a)
+ rescue
+ fake[a] = "fakeuser"
+ break
+ end
+ end
+
+ uid, name = users.shift
+ us = {}
+ us[uid] = name
+ users.each { |uid, name|
+ assert_apply(file)
+ assert_nothing_raised {
+ file[:owner] = name
+ }
+ assert_nothing_raised {
+ file.retrieve
+ }
+ assert_apply(file)
+ }
+ end
+
+ def test_group
+ file = mktestfile
+ [%x{groups}.chomp.split(/ /), Process.groups].flatten.each { |group|
+ assert_nothing_raised {
+ file[:group] = group
+ }
+ assert(file.property(:group))
+ assert(file.property(:group).should)
+ }
+ end
+
+ def test_groups_fails_when_invalid
+ assert_raise(Puppet::Error, "did not fail when the group was empty") do
+ Puppet::Type.type(:file).new :path => "/some/file", :group => ""
+ end
+ end
+
+ if Puppet.features.root?
+ def test_createasuser
+ dir = tmpdir
+
+ user = nonrootuser
+ path = File.join(tmpdir, "createusertesting")
+ @@tmpfiles << path
+
+ file = nil
+ assert_nothing_raised {
+
+ file = Puppet::Type.type(:file).new(
- :path => path,
- :owner => user.name,
- :ensure => "file",
+ :path => path,
+ :owner => user.name,
+ :ensure => "file",
- :mode => "755"
- )
- }
+ :mode => "755"
+ )
+ }
- comp = mk_catalog("createusertest", file)
+ comp = mk_catalog("createusertest", file)
- assert_events([:file_created], comp)
- end
+ assert_events([:file_created], comp)
+ end
- def test_nofollowlinks
- basedir = tempfile
- Dir.mkdir(basedir)
- file = File.join(basedir, "file")
- link = File.join(basedir, "link")
+ def test_nofollowlinks
+ basedir = tempfile
+ Dir.mkdir(basedir)
+ file = File.join(basedir, "file")
+ link = File.join(basedir, "link")
- File.open(file, "w", 0644) { |f| f.puts "yayness"; f.flush }
- File.symlink(file, link)
+ File.open(file, "w", 0644) { |f| f.puts "yayness"; f.flush }
+ File.symlink(file, link)
- # First test 'user'
- user = nonrootuser
+ # First test 'user'
+ user = nonrootuser
- inituser = File.lstat(link).uid
- File.lchown(inituser, nil, link)
+ inituser = File.lstat(link).uid
+ File.lchown(inituser, nil, link)
- obj = nil
- assert_nothing_raised {
+ obj = nil
+ assert_nothing_raised {
- obj = Puppet::Type.type(:file).new(
+ obj = Puppet::Type.type(:file).new(
- :title => link,
+ :title => link,
- :owner => user.name
- )
- }
- obj.retrieve
-
- # Make sure it defaults to managing the link
- assert_events([:file_changed], obj)
- assert_equal(user.uid, File.lstat(link).uid)
- assert_equal(inituser, File.stat(file).uid)
- File.chown(inituser, nil, file)
- File.lchown(inituser, nil, link)
-
- # Try following
- obj[:links] = :follow
- assert_events([:file_changed], obj)
- assert_equal(user.uid, File.stat(file).uid)
- assert_equal(inituser, File.lstat(link).uid)
-
- # And then explicitly managing
- File.chown(inituser, nil, file)
- File.lchown(inituser, nil, link)
- obj[:links] = :manage
- assert_events([:file_changed], obj)
- assert_equal(user.uid, File.lstat(link).uid)
- assert_equal(inituser, File.stat(file).uid)
-
- obj.delete(:owner)
- obj[:links] = :follow
-
- # And then test 'group'
- group = nonrootgroup
-
- initgroup = File.stat(file).gid
- obj[:group] = group.name
-
- obj[:links] = :follow
- assert_events([:file_changed], obj)
- assert_equal(group.gid, File.stat(file).gid)
- File.chown(nil, initgroup, file)
- File.lchown(nil, initgroup, link)
-
- obj[:links] = :manage
- assert_events([:file_changed], obj)
- assert_equal(group.gid, File.lstat(link).gid)
- assert_equal(initgroup, File.stat(file).gid)
+ :owner => user.name
+ )
+ }
+ obj.retrieve
+
+ # Make sure it defaults to managing the link
+ assert_events([:file_changed], obj)
+ assert_equal(user.uid, File.lstat(link).uid)
+ assert_equal(inituser, File.stat(file).uid)
+ File.chown(inituser, nil, file)
+ File.lchown(inituser, nil, link)
+
+ # Try following
+ obj[:links] = :follow
+ assert_events([:file_changed], obj)
+ assert_equal(user.uid, File.stat(file).uid)
+ assert_equal(inituser, File.lstat(link).uid)
+
+ # And then explicitly managing
+ File.chown(inituser, nil, file)
+ File.lchown(inituser, nil, link)
+ obj[:links] = :manage
+ assert_events([:file_changed], obj)
+ assert_equal(user.uid, File.lstat(link).uid)
+ assert_equal(inituser, File.stat(file).uid)
+
+ obj.delete(:owner)
+ obj[:links] = :follow
+
+ # And then test 'group'
+ group = nonrootgroup
+
+ initgroup = File.stat(file).gid
+ obj[:group] = group.name
+
+ obj[:links] = :follow
+ assert_events([:file_changed], obj)
+ assert_equal(group.gid, File.stat(file).gid)
+ File.chown(nil, initgroup, file)
+ File.lchown(nil, initgroup, link)
+
+ obj[:links] = :manage
+ assert_events([:file_changed], obj)
+ assert_equal(group.gid, File.lstat(link).gid)
+ assert_equal(initgroup, File.stat(file).gid)
+ end
+
+ def test_ownerasroot
+ file = mktestfile
+
+ users = {}
+ count = 0
+
+ # collect five users
+ Etc.passwd { |passwd|
+ if count > 5
+ break
+ else
+ count += 1
end
-
- def test_ownerasroot
- file = mktestfile
-
- users = {}
- count = 0
-
- # collect five users
- Etc.passwd { |passwd|
- if count > 5
- break
- else
- count += 1
- end
- next if passwd.uid < 0
- users[passwd.uid] = passwd.name
- }
-
- fake = {}
- # find a fake user
- while true
- a = rand(1000)
- begin
- Etc.getpwuid(a)
- rescue
- fake[a] = "fakeuser"
- break
- end
- end
-
- users.each { |uid, name|
- assert_nothing_raised {
- file[:owner] = name
- }
- assert_apply(file)
- currentvalue = file.retrieve
- assert(file.insync?(currentvalue))
- assert_nothing_raised {
- file[:owner] = uid
- }
- assert_apply(file)
- currentvalue = file.retrieve
- # make sure changing to number doesn't cause a sync
- assert(file.insync?(currentvalue))
- }
-
- # We no longer raise an error here, because we check at run time
- #fake.each { |uid, name|
- # assert_raise(Puppet::Error) {
- # file[:owner] = name
- # }
- # assert_raise(Puppet::Error) {
- # file[:owner] = uid
- # }
- #}
+ next if passwd.uid < 0
+ users[passwd.uid] = passwd.name
+ }
+
+ fake = {}
+ # find a fake user
+ while true
+ a = rand(1000)
+ begin
+ Etc.getpwuid(a)
+ rescue
+ fake[a] = "fakeuser"
+ break
end
+ end
- def test_groupasroot
- file = mktestfile
- [%x{groups}.chomp.split(/ /), Process.groups].flatten.each { |group|
- next unless Puppet::Util.gid(group) # grr.
- assert_nothing_raised {
- file[:group] = group
- }
- assert(file.property(:group))
- assert(file.property(:group).should)
- assert_apply(file)
- currentvalue = file.retrieve
- assert(file.insync?(currentvalue))
- assert_nothing_raised {
- file.delete(:group)
- }
- }
- end
+ users.each { |uid, name|
+ assert_nothing_raised {
+ file[:owner] = name
+ }
+ assert_apply(file)
+ currentvalue = file.retrieve
+ assert(file.insync?(currentvalue))
+ assert_nothing_raised {
+ file[:owner] = uid
+ }
+ assert_apply(file)
+ currentvalue = file.retrieve
+ # make sure changing to number doesn't cause a sync
+ assert(file.insync?(currentvalue))
+ }
+
+ # We no longer raise an error here, because we check at run time
+ #fake.each { |uid, name|
+ # assert_raise(Puppet::Error) {
+ # file[:owner] = name
+ # }
+ # assert_raise(Puppet::Error) {
+ # file[:owner] = uid
+ # }
+ #}
+ end
+
+ def test_groupasroot
+ file = mktestfile
+ [%x{groups}.chomp.split(/ /), Process.groups].flatten.each { |group|
+ next unless Puppet::Util.gid(group) # grr.
+ assert_nothing_raised {
+ file[:group] = group
+ }
+ assert(file.property(:group))
+ assert(file.property(:group).should)
+ assert_apply(file)
+ currentvalue = file.retrieve
+ assert(file.insync?(currentvalue))
+ assert_nothing_raised {
+ file.delete(:group)
+ }
+ }
+ end
- if Facter.value(:operatingsystem) == "Darwin"
- def test_sillyowner
- file = tempfile
- File.open(file, "w") { |f| f.puts "" }
- File.chown(-2, nil, file)
+ if Facter.value(:operatingsystem) == "Darwin"
+ def test_sillyowner
+ file = tempfile
+ File.open(file, "w") { |f| f.puts "" }
+ File.chown(-2, nil, file)
- assert(File.stat(file).uid > 120000, "eh?")
- user = nonrootuser
+ assert(File.stat(file).uid > 120000, "eh?")
+ user = nonrootuser
- obj = Puppet::Type.newfile(
+ obj = Puppet::Type.newfile(
- :path => file,
+ :path => file,
- :owner => user.name
- )
+ :owner => user.name
+ )
- assert_apply(obj)
+ assert_apply(obj)
- assert_equal(user.uid, File.stat(file).uid)
- end
- end
- else
- $stderr.puts "Run as root for complete owner and group testing"
+ assert_equal(user.uid, File.stat(file).uid)
+ end
end
+ else
+ $stderr.puts "Run as root for complete owner and group testing"
+ end
- def test_create
- %w{a b c d}.collect { |name| tempfile + name.to_s }.each { |path|
- file =nil
- assert_nothing_raised {
+ def test_create
+ %w{a b c d}.collect { |name| tempfile + name.to_s }.each { |path|
+ file =nil
+ assert_nothing_raised {
- file = Puppet::Type.type(:file).new(
+ file = Puppet::Type.type(:file).new(
- :name => path,
+ :name => path,
- :ensure => "file"
- )
- }
- assert_events([:file_created], file)
- assert_events([], file)
- assert(FileTest.file?(path), "File does not exist")
- @@tmpfiles.push path
- }
- end
-
- def test_create_dir
- basedir = tempfile
- Dir.mkdir(basedir)
- %w{a b c d}.collect { |name| "#{basedir}/#{name}" }.each { |path|
- file = nil
- assert_nothing_raised {
-
- file = Puppet::Type.type(:file).new(
+ :ensure => "file"
+ )
+ }
+ assert_events([:file_created], file)
+ assert_events([], file)
+ assert(FileTest.file?(path), "File does not exist")
+ @@tmpfiles.push path
+ }
+ end
+
+ def test_create_dir
+ basedir = tempfile
+ Dir.mkdir(basedir)
+ %w{a b c d}.collect { |name| "#{basedir}/#{name}" }.each { |path|
+ file = nil
+ assert_nothing_raised {
+
+ file = Puppet::Type.type(:file).new(
- :name => path,
+ :name => path,
- :ensure => "directory"
- )
- }
- assert(! FileTest.directory?(path), "Directory #{path} already exists")
- assert_events([:directory_created], file)
- assert_events([], file)
- assert(FileTest.directory?(path))
- @@tmpfiles.push path
- }
- end
-
- def test_modes
- file = mktestfile
- # Set it to something else initially
- File.chmod(0775, file.title)
- [0644,0755,0777,0641].each { |mode|
- assert_nothing_raised {
- file[:mode] = mode
- }
- assert_events([:mode_changed], file)
- assert_events([], file)
-
- assert_nothing_raised {
- file.delete(:mode)
- }
- }
- end
-
- def cyclefile(path)
- # i had problems with using :name instead of :path
- [:name,:path].each { |param|
- file = nil
- changes = nil
- comp = nil
- trans = nil
-
- initstorage
- assert_nothing_raised {
-
- file = Puppet::Type.type(:file).new(
+ :ensure => "directory"
+ )
+ }
+ assert(! FileTest.directory?(path), "Directory #{path} already exists")
+ assert_events([:directory_created], file)
+ assert_events([], file)
+ assert(FileTest.directory?(path))
+ @@tmpfiles.push path
+ }
+ end
+
+ def test_modes
+ file = mktestfile
+ # Set it to something else initially
+ File.chmod(0775, file.title)
+ [0644,0755,0777,0641].each { |mode|
+ assert_nothing_raised {
+ file[:mode] = mode
+ }
+ assert_events([:mode_changed], file)
+ assert_events([], file)
+
+ assert_nothing_raised {
+ file.delete(:mode)
+ }
+ }
+ end
+
+ def cyclefile(path)
+ # i had problems with using :name instead of :path
+ [:name,:path].each { |param|
+ file = nil
+ changes = nil
+ comp = nil
+ trans = nil
+
+ initstorage
+ assert_nothing_raised {
+
+ file = Puppet::Type.type(:file).new(
- param => path,
- :recurse => true,
+ param => path,
+ :recurse => true,
- :checksum => "md5"
- )
- }
- comp = Puppet::Type.type(:component).new(
- :name => "component"
- )
- comp.push file
- assert_nothing_raised {
- trans = comp.evaluate
- }
- assert_nothing_raised {
- trans.evaluate
- }
- clearstorage
- Puppet::Type.allclear
- }
- end
-
- def test_filetype_retrieval
- file = nil
-
- # Verify it retrieves files of type directory
- assert_nothing_raised {
-
- file = Puppet::Type.type(:file).new(
+ :checksum => "md5"
+ )
+ }
+ comp = Puppet::Type.type(:component).new(
+ :name => "component"
+ )
+ comp.push file
+ assert_nothing_raised {
+ trans = comp.evaluate
+ }
+ assert_nothing_raised {
+ trans.evaluate
+ }
+ clearstorage
+ Puppet::Type.allclear
+ }
+ end
+
+ def test_filetype_retrieval
+ file = nil
+
+ # Verify it retrieves files of type directory
+ assert_nothing_raised {
+
+ file = Puppet::Type.type(:file).new(
- :name => tmpdir,
+ :name => tmpdir,
- :check => :type
- )
- }
+ :check => :type
+ )
+ }
- assert_equal("directory", file.property(:type).retrieve)
+ assert_equal("directory", file.property(:type).retrieve)
- # And then check files
- assert_nothing_raised {
+ # And then check files
+ assert_nothing_raised {
- file = Puppet::Type.type(:file).new(
+ file = Puppet::Type.type(:file).new(
- :name => tempfile,
+ :name => tempfile,
- :ensure => "file"
- )
- }
+ :ensure => "file"
+ )
+ }
- assert_apply(file)
- file[:check] = "type"
- assert_apply(file)
+ assert_apply(file)
+ file[:check] = "type"
+ assert_apply(file)
- assert_equal("file", file.property(:type).retrieve)
- end
+ assert_equal("file", file.property(:type).retrieve)
+ end
- def test_path
- dir = tempfile
+ def test_path
+ dir = tempfile
- path = File.join(dir, "subdir")
+ path = File.join(dir, "subdir")
- assert_nothing_raised("Could not make file") {
- FileUtils.mkdir_p(File.dirname(path))
- File.open(path, "w") { |f| f.puts "yayness" }
- }
+ assert_nothing_raised("Could not make file") {
+ FileUtils.mkdir_p(File.dirname(path))
+ File.open(path, "w") { |f| f.puts "yayness" }
+ }
- file = nil
- dirobj = nil
- assert_nothing_raised("Could not make file object") {
+ file = nil
+ dirobj = nil
+ assert_nothing_raised("Could not make file object") {
- dirobj = Puppet::Type.type(:file).new(
+ dirobj = Puppet::Type.type(:file).new(
- :path => dir,
- :recurse => true,
+ :path => dir,
+ :recurse => true,
- :check => %w{mode owner group}
- )
- }
- catalog = mk_catalog dirobj
- transaction = Puppet::Transaction.new(catalog)
- transaction.eval_generate(dirobj)
+ :check => %w{mode owner group}
+ )
+ }
+ catalog = mk_catalog dirobj
+ transaction = Puppet::Transaction.new(catalog)
+ transaction.eval_generate(dirobj)
- #assert_nothing_raised {
- # dirobj.eval_generate
- #}
+ #assert_nothing_raised {
+ # dirobj.eval_generate
+ #}
- file = catalog.resource(:file, path)
+ file = catalog.resource(:file, path)
- assert(file, "Could not retrieve file object")
+ assert(file, "Could not retrieve file object")
- assert_equal("/#{file.ref}", file.path)
- end
+ assert_equal("/#{file.ref}", file.path)
+ end
- def test_autorequire
- basedir = tempfile
- subfile = File.join(basedir, "subfile")
+ def test_autorequire
+ basedir = tempfile
+ subfile = File.join(basedir, "subfile")
- baseobj = Puppet::Type.type(:file).new(
+ baseobj = Puppet::Type.type(:file).new(
- :name => basedir,
+ :name => basedir,
- :ensure => "directory"
- )
+ :ensure => "directory"
+ )
- subobj = Puppet::Type.type(:file).new(
+ subobj = Puppet::Type.type(:file).new(
- :name => subfile,
+ :name => subfile,
- :ensure => "file"
- )
- catalog = mk_catalog(baseobj, subobj)
- edge = nil
- assert_nothing_raised do
- edge = subobj.autorequire.shift
- end
- assert_equal(baseobj, edge.source, "file did not require its parent dir")
- assert_equal(subobj, edge.target, "file did not require its parent dir")
- end
-
- # Unfortunately, I know this fails
- def disabled_test_recursivemkdir
- path = tempfile
- subpath = File.join(path, "this", "is", "a", "dir")
- file = nil
- assert_nothing_raised {
-
- file = Puppet::Type.type(:file).new(
+ :ensure => "file"
+ )
+ catalog = mk_catalog(baseobj, subobj)
+ edge = nil
+ assert_nothing_raised do
+ edge = subobj.autorequire.shift
+ end
+ assert_equal(baseobj, edge.source, "file did not require its parent dir")
+ assert_equal(subobj, edge.target, "file did not require its parent dir")
+ end
+
+ # Unfortunately, I know this fails
+ def disabled_test_recursivemkdir
+ path = tempfile
+ subpath = File.join(path, "this", "is", "a", "dir")
+ file = nil
+ assert_nothing_raised {
+
+ file = Puppet::Type.type(:file).new(
- :name => subpath,
- :ensure => "directory",
+ :name => subpath,
+ :ensure => "directory",
- :recurse => true
- )
- }
+ :recurse => true
+ )
+ }
- comp = mk_catalog("yay", file)
- comp.finalize
- assert_apply(comp)
- #assert_events([:directory_created], comp)
+ comp = mk_catalog("yay", file)
+ comp.finalize
+ assert_apply(comp)
+ #assert_events([:directory_created], comp)
- assert(FileTest.directory?(subpath), "Did not create directory")
- end
+ assert(FileTest.directory?(subpath), "Did not create directory")
+ end
- # Make sure that content updates the checksum on the same run
- def test_checksumchange_for_content
- dest = tempfile
- File.open(dest, "w") { |f| f.puts "yayness" }
+ # Make sure that content updates the checksum on the same run
+ def test_checksumchange_for_content
+ dest = tempfile
+ File.open(dest, "w") { |f| f.puts "yayness" }
- file = nil
- assert_nothing_raised {
+ file = nil
+ assert_nothing_raised {
- file = Puppet::Type.type(:file).new(
+ file = Puppet::Type.type(:file).new(
- :name => dest,
- :checksum => "md5",
- :content => "This is some content",
+ :name => dest,
+ :checksum => "md5",
+ :content => "This is some content",
- :backup => false
- )
- }
+ :backup => false
+ )
+ }
- file.retrieve
+ file.retrieve
- assert_events([:content_changed], file)
- file.retrieve
- assert_events([], file)
- end
+ assert_events([:content_changed], file)
+ file.retrieve
+ assert_events([], file)
+ end
- # Make sure that content updates the checksum on the same run
- def test_checksumchange_for_ensure
- dest = tempfile
+ # Make sure that content updates the checksum on the same run
+ def test_checksumchange_for_ensure
+ dest = tempfile
- file = nil
- assert_nothing_raised {
+ file = nil
+ assert_nothing_raised {
- file = Puppet::Type.type(:file).new(
+ file = Puppet::Type.type(:file).new(
- :name => dest,
- :checksum => "md5",
+ :name => dest,
+ :checksum => "md5",
- :ensure => "file"
- )
- }
+ :ensure => "file"
+ )
+ }
- file.retrieve
+ file.retrieve
- assert_events([:file_created], file)
- file.retrieve
- assert_events([], file)
- end
+ assert_events([:file_created], file)
+ file.retrieve
+ assert_events([], file)
+ end
- def test_nameandpath
- path = tempfile
+ def test_nameandpath
+ path = tempfile
- file = nil
- assert_nothing_raised {
+ file = nil
+ assert_nothing_raised {
- file = Puppet::Type.type(:file).new(
+ file = Puppet::Type.type(:file).new(
- :title => "fileness",
- :path => path,
+ :title => "fileness",
+ :path => path,
- :content => "this is some content"
- )
- }
+ :content => "this is some content"
+ )
+ }
- assert_apply(file)
+ assert_apply(file)
- assert(FileTest.exists?(path))
- end
+ assert(FileTest.exists?(path))
+ end
- # Make sure that a missing group isn't fatal at object instantiation time.
- def test_missinggroup
- file = nil
- assert_nothing_raised {
+ # Make sure that a missing group isn't fatal at object instantiation time.
+ def test_missinggroup
+ file = nil
+ assert_nothing_raised {
- file = Puppet::Type.type(:file).new(
+ file = Puppet::Type.type(:file).new(
- :path => tempfile,
+ :path => tempfile,
- :group => "fakegroup"
- )
- }
+ :group => "fakegroup"
+ )
+ }
- assert(file.property(:group), "Group property failed")
- end
+ assert(file.property(:group), "Group property failed")
+ end
- def test_modecreation
- path = tempfile
+ def test_modecreation
+ path = tempfile
- file = Puppet::Type.type(:file).new(
+ file = Puppet::Type.type(:file).new(
- :path => path,
- :ensure => "file",
+ :path => path,
+ :ensure => "file",
- :mode => "0777"
- )
- assert_equal(0777, file.should(:mode), "Mode did not get set correctly")
- assert_apply(file)
- assert_equal(0777, File.stat(path).mode & 007777, "file mode is incorrect")
- File.unlink(path)
- file[:ensure] = "directory"
- assert_apply(file)
- assert_equal(0777, File.stat(path).mode & 007777, "directory mode is incorrect")
- end
-
- # If both 'ensure' and 'content' are used, make sure that all of the other
- # properties are handled correctly.
- def test_contentwithmode
- path = tempfile
-
- file = nil
- assert_nothing_raised {
-
- file = Puppet::Type.type(:file).new(
+ :mode => "0777"
+ )
+ assert_equal(0777, file.should(:mode), "Mode did not get set correctly")
+ assert_apply(file)
+ assert_equal(0777, File.stat(path).mode & 007777, "file mode is incorrect")
+ File.unlink(path)
+ file[:ensure] = "directory"
+ assert_apply(file)
+ assert_equal(0777, File.stat(path).mode & 007777, "directory mode is incorrect")
+ end
+
+ # If both 'ensure' and 'content' are used, make sure that all of the other
+ # properties are handled correctly.
+ def test_contentwithmode
+ path = tempfile
+
+ file = nil
+ assert_nothing_raised {
+
+ file = Puppet::Type.type(:file).new(
- :path => path,
- :ensure => "file",
- :content => "some text\n",
+ :path => path,
+ :ensure => "file",
+ :content => "some text\n",
- :mode => 0755
- )
- }
+ :mode => 0755
+ )
+ }
- assert_apply(file)
- assert_equal("%o" % 0755, "%o" % (File.stat(path).mode & 007777))
- end
+ assert_apply(file)
+ assert_equal("%o" % 0755, "%o" % (File.stat(path).mode & 007777))
+ end
- def test_replacefilewithlink
- path = tempfile
- link = tempfile
+ def test_replacefilewithlink
+ path = tempfile
+ link = tempfile
- File.open(path, "w") { |f| f.puts "yay" }
- File.open(link, "w") { |f| f.puts "a file" }
+ File.open(path, "w") { |f| f.puts "yay" }
+ File.open(link, "w") { |f| f.puts "a file" }
- file = nil
- assert_nothing_raised {
+ file = nil
+ assert_nothing_raised {
- file = Puppet::Type.type(:file).new(
+ file = Puppet::Type.type(:file).new(
- :ensure => path,
- :path => link,
+ :ensure => path,
+ :path => link,
- :backup => false
- )
- }
+ :backup => false
+ )
+ }
- assert_events([:link_created], file)
+ assert_events([:link_created], file)
- assert(FileTest.symlink?(link), "Link was not created")
+ assert(FileTest.symlink?(link), "Link was not created")
- assert_equal(path, File.readlink(link), "Link was created incorrectly")
- end
+ assert_equal(path, File.readlink(link), "Link was created incorrectly")
+ end
- def test_file_with_spaces
- dir = tempfile
- Dir.mkdir(dir)
- source = File.join(dir, "file spaces")
- dest = File.join(dir, "another space")
+ def test_file_with_spaces
+ dir = tempfile
+ Dir.mkdir(dir)
+ source = File.join(dir, "file spaces")
+ dest = File.join(dir, "another space")
- File.open(source, "w") { |f| f.puts :yay }
+ File.open(source, "w") { |f| f.puts :yay }
- obj = Puppet::Type.type(:file).new(
+ obj = Puppet::Type.type(:file).new(
- :path => dest,
+ :path => dest,
- :source => source
- )
- assert(obj, "Did not create file")
-
- assert_apply(obj)
-
- assert(FileTest.exists?(dest), "File did not get created")
- end
-
- # Testing #274. Make sure target can be used without 'ensure'.
- def test_target_without_ensure
- source = tempfile
- dest = tempfile
- File.open(source, "w") { |f| f.puts "funtest" }
-
- obj = nil
- assert_nothing_raised {
- obj = Puppet::Type.newfile(:path => dest, :target => source)
- }
-
- assert_apply(obj)
- end
-
- def test_autorequire_owner_and_group
- file = tempfile
- comp = nil
- user = nil
- group =nil
- home = nil
- ogroup = nil
- assert_nothing_raised {
-
- user = Puppet::Type.type(:user).new(
+ :source => source
+ )
+ assert(obj, "Did not create file")
+
+ assert_apply(obj)
+
+ assert(FileTest.exists?(dest), "File did not get created")
+ end
+
+ # Testing #274. Make sure target can be used without 'ensure'.
+ def test_target_without_ensure
+ source = tempfile
+ dest = tempfile
+ File.open(source, "w") { |f| f.puts "funtest" }
+
+ obj = nil
+ assert_nothing_raised {
+ obj = Puppet::Type.newfile(:path => dest, :target => source)
+ }
+
+ assert_apply(obj)
+ end
+
+ def test_autorequire_owner_and_group
+ file = tempfile
+ comp = nil
+ user = nil
+ group =nil
+ home = nil
+ ogroup = nil
+ assert_nothing_raised {
+
+ user = Puppet::Type.type(:user).new(
- :name => "pptestu",
- :home => file,
+ :name => "pptestu",
+ :home => file,
- :gid => "pptestg"
- )
+ :gid => "pptestg"
+ )
- home = Puppet::Type.type(:file).new(
+ home = Puppet::Type.type(:file).new(
- :path => file,
- :owner => "pptestu",
- :group => "pptestg",
+ :path => file,
+ :owner => "pptestu",
+ :group => "pptestg",
- :ensure => "directory"
- )
- group = Puppet::Type.type(:group).new(
- :name => "pptestg"
- )
- comp = mk_catalog(user, group, home)
- }
-
- # Now make sure we get a relationship for each of these
- rels = nil
- assert_nothing_raised { rels = home.autorequire }
- assert(rels.detect { |e| e.source == user }, "owner was not autorequired")
- assert(rels.detect { |e| e.source == group }, "group was not autorequired")
- end
-
- # Testing #309 -- //my/file => /my/file
- def test_slash_deduplication
- ["/my/////file/for//testing", "/my/file/for/testing///",
- "/my/file/for/testing"].each do |path|
- file = nil
- assert_nothing_raised do
- file = Puppet::Type.newfile(:path => path)
- end
-
- assert_equal("/my/file/for/testing", file[:path])
+ :ensure => "directory"
+ )
+ group = Puppet::Type.type(:group).new(
+ :name => "pptestg"
+ )
+ comp = mk_catalog(user, group, home)
+ }
+
+ # Now make sure we get a relationship for each of these
+ rels = nil
+ assert_nothing_raised { rels = home.autorequire }
+ assert(rels.detect { |e| e.source == user }, "owner was not autorequired")
+ assert(rels.detect { |e| e.source == group }, "group was not autorequired")
+ end
+
+ # Testing #309 -- //my/file => /my/file
+ def test_slash_deduplication
+ ["/my/////file/for//testing", "/my/file/for/testing///",
+ "/my/file/for/testing"].each do |path|
+ file = nil
+ assert_nothing_raised do
+ file = Puppet::Type.newfile(:path => path)
+ end
+
+ assert_equal("/my/file/for/testing", file[:path])
+ end
+ end
+
+ if Process.uid == 0
+ # Testing #364.
+ def test_writing_in_directories_with_no_write_access
+ # Make a directory that our user does not have access to
+ dir = tempfile
+ Dir.mkdir(dir)
+
+ # Get a fake user
+ user = nonrootuser
+ # and group
+ group = nonrootgroup
+
+ # First try putting a file in there
+ path = File.join(dir, "file")
+ file = Puppet::Type.newfile :path => path, :owner => user.name, :group => group.name, :content => "testing"
+
+ # Make sure we can create it
+ assert_apply(file)
+ assert(FileTest.exists?(path), "File did not get created")
+ # And that it's owned correctly
+ assert_equal(user.uid, File.stat(path).uid, "File has the wrong owner")
+ assert_equal(group.gid, File.stat(path).gid, "File has the wrong group")
+
+ assert_equal("testing", File.read(path), "file has the wrong content")
+
+ # Now make a dir
+ subpath = File.join(dir, "subdir")
+ subdir = Puppet::Type.newfile :path => subpath, :owner => user.name, :group => group.name, :ensure => :directory
+ # Make sure we can create it
+ assert_apply(subdir)
+ assert(FileTest.directory?(subpath), "File did not get created")
+ # And that it's owned correctly
+ assert_equal(user.uid, File.stat(subpath).uid, "File has the wrong owner")
+ assert_equal(group.gid, File.stat(subpath).gid, "File has the wrong group")
+
+ assert_equal("testing", File.read(path), "file has the wrong content")
+ end
+ end
+
+ # #366
+ def test_replace_aliases
+ file = Puppet::Type.newfile :path => tempfile
+ file[:replace] = :yes
+ assert_equal(:true, file[:replace], ":replace did not alias :true to :yes")
+ file[:replace] = :no
+ assert_equal(:false, file[:replace], ":replace did not alias :false to :no")
+ end
+
+ def test_pathbuilder
+ dir = tempfile
+ Dir.mkdir(dir)
+ file = File.join(dir, "file")
+ File.open(file, "w") { |f| f.puts "" }
+ obj = Puppet::Type.newfile :path => dir, :recurse => true, :mode => 0755
+ catalog = mk_catalog obj
+ transaction = Puppet::Transaction.new(catalog)
+
+ assert_equal("/#{obj.ref}", obj.path)
+
+ list = transaction.eval_generate(obj)
+ fileobj = catalog.resource(:file, file)
+ assert(fileobj, "did not generate file object")
+ assert_equal("/#{fileobj.ref}", fileobj.path, "did not generate correct subfile path")
+ end
+
+ # Testing #403
+ def test_removal_with_content_set
+ path = tempfile
+ File.open(path, "w") { |f| f.puts "yay" }
+ file = Puppet::Type.newfile(:name => path, :ensure => :absent, :content => "foo", :backup => false)
+
+ assert_apply(file)
+ assert(! FileTest.exists?(path), "File was not removed")
+ end
+
+ # Testing #438
+ def test_creating_properties_conflict
+ file = tempfile
+ first = tempfile
+ second = tempfile
+ params = [:content, :source, :target]
+ params.each do |param|
+ assert_nothing_raised("#{param} conflicted with ensure") do
+ Puppet::Type.newfile(:path => file, param => first, :ensure => :file)
+ end
+ params.each do |other|
+ next if other == param
+ assert_raise(Puppet::Error, "#{param} and #{other} did not conflict") do
+ Puppet::Type.newfile(:path => file, other => first, param => second)
end
- end
-
- if Process.uid == 0
- # Testing #364.
- def test_writing_in_directories_with_no_write_access
- # Make a directory that our user does not have access to
- dir = tempfile
- Dir.mkdir(dir)
-
- # Get a fake user
- user = nonrootuser
- # and group
- group = nonrootgroup
-
- # First try putting a file in there
- path = File.join(dir, "file")
- file = Puppet::Type.newfile :path => path, :owner => user.name, :group => group.name, :content => "testing"
-
- # Make sure we can create it
- assert_apply(file)
- assert(FileTest.exists?(path), "File did not get created")
- # And that it's owned correctly
- assert_equal(user.uid, File.stat(path).uid, "File has the wrong owner")
- assert_equal(group.gid, File.stat(path).gid, "File has the wrong group")
-
- assert_equal("testing", File.read(path), "file has the wrong content")
-
- # Now make a dir
- subpath = File.join(dir, "subdir")
- subdir = Puppet::Type.newfile :path => subpath, :owner => user.name, :group => group.name, :ensure => :directory
- # Make sure we can create it
- assert_apply(subdir)
- assert(FileTest.directory?(subpath), "File did not get created")
- # And that it's owned correctly
- assert_equal(user.uid, File.stat(subpath).uid, "File has the wrong owner")
- assert_equal(group.gid, File.stat(subpath).gid, "File has the wrong group")
-
- assert_equal("testing", File.read(path), "file has the wrong content")
- end
- end
-
- # #366
- def test_replace_aliases
- file = Puppet::Type.newfile :path => tempfile
- file[:replace] = :yes
- assert_equal(:true, file[:replace], ":replace did not alias :true to :yes")
- file[:replace] = :no
- assert_equal(:false, file[:replace], ":replace did not alias :false to :no")
- end
-
- def test_pathbuilder
- dir = tempfile
- Dir.mkdir(dir)
- file = File.join(dir, "file")
- File.open(file, "w") { |f| f.puts "" }
- obj = Puppet::Type.newfile :path => dir, :recurse => true, :mode => 0755
- catalog = mk_catalog obj
- transaction = Puppet::Transaction.new(catalog)
-
- assert_equal("/#{obj.ref}", obj.path)
-
- list = transaction.eval_generate(obj)
- fileobj = catalog.resource(:file, file)
- assert(fileobj, "did not generate file object")
- assert_equal("/#{fileobj.ref}", fileobj.path, "did not generate correct subfile path")
- end
-
- # Testing #403
- def test_removal_with_content_set
- path = tempfile
- File.open(path, "w") { |f| f.puts "yay" }
- file = Puppet::Type.newfile(:name => path, :ensure => :absent, :content => "foo", :backup => false)
-
- assert_apply(file)
- assert(! FileTest.exists?(path), "File was not removed")
- end
-
- # Testing #438
- def test_creating_properties_conflict
- file = tempfile
- first = tempfile
- second = tempfile
- params = [:content, :source, :target]
- params.each do |param|
- assert_nothing_raised("#{param} conflicted with ensure") do
- Puppet::Type.newfile(:path => file, param => first, :ensure => :file)
- end
- params.each do |other|
- next if other == param
- assert_raise(Puppet::Error, "#{param} and #{other} did not conflict") do
- Puppet::Type.newfile(:path => file, other => first, param => second)
- end
- end
+ end
+ end
+ end
+
+ # Testing #508
+ if Process.uid == 0
+ def test_files_replace_with_right_attrs
+ source = tempfile
+ File.open(source, "w") { |f|
+ f.puts "some text"
+ }
+ File.chmod(0755, source)
+ user = nonrootuser
+ group = nonrootgroup
+ path = tempfile
+ good = {:uid => user.uid, :gid => group.gid, :mode => 0640}
+
+ run = Proc.new do |obj, msg|
+ assert_apply(obj)
+ stat = File.stat(obj[:path])
+ good.each do |should, sval|
+ if should == :mode
+ current = filemode(obj[:path])
+ else
+ current = stat.send(should)
end
+ assert_equal(sval, current, "Attr #{should} was not correct #{msg}")
+ end
end
- # Testing #508
- if Process.uid == 0
- def test_files_replace_with_right_attrs
- source = tempfile
- File.open(source, "w") { |f|
- f.puts "some text"
- }
- File.chmod(0755, source)
- user = nonrootuser
- group = nonrootgroup
- path = tempfile
- good = {:uid => user.uid, :gid => group.gid, :mode => 0640}
-
- run = Proc.new do |obj, msg|
- assert_apply(obj)
- stat = File.stat(obj[:path])
- good.each do |should, sval|
- if should == :mode
- current = filemode(obj[:path])
- else
- current = stat.send(should)
- end
- assert_equal(sval, current, "Attr #{should} was not correct #{msg}")
- end
- end
-
- file = Puppet::Type.newfile(
- :path => path, :owner => user.name,
+ file = Puppet::Type.newfile(
+ :path => path, :owner => user.name,
- :group => group.name, :mode => 0640, :backup => false)
- {:source => source, :content => "some content"}.each do |attr, value|
- file[attr] = value
- # First create the file
- run.call(file, "upon creation with #{attr}")
-
- # Now change something so that we replace the file
- case attr
- when :source
- File.open(source, "w") { |f| f.puts "some different text" }
- when :content; file[:content] = "something completely different"
- else
- raise "invalid attr #{attr}"
- end
-
- # Run it again
- run.call(file, "after modification with #{attr}")
-
- # Now remove the file and the attr
- file.delete(attr)
- File.unlink(path)
- end
- end
- end
-
- def test_root_dir_is_named_correctly
- obj = Puppet::Type.newfile(:path => '/', :mode => 0755)
- assert_equal("/", obj.title, "/ directory was changed to empty string")
- end
+ :group => group.name, :mode => 0640, :backup => false)
+ {:source => source, :content => "some content"}.each do |attr, value|
+ file[attr] = value
+ # First create the file
+ run.call(file, "upon creation with #{attr}")
+
+ # Now change something so that we replace the file
+ case attr
+ when :source
+ File.open(source, "w") { |f| f.puts "some different text" }
+ when :content; file[:content] = "something completely different"
+ else
+ raise "invalid attr #{attr}"
+ end
+
+ # Run it again
+ run.call(file, "after modification with #{attr}")
+
+ # Now remove the file and the attr
+ file.delete(attr)
+ File.unlink(path)
+ end
+ end
+ end
+
+ def test_root_dir_is_named_correctly
+ obj = Puppet::Type.newfile(:path => '/', :mode => 0755)
+ assert_equal("/", obj.title, "/ directory was changed to empty string")
+ end
end
diff --git a/test/ral/type/file/target.rb b/test/ral/type/file/target.rb
index ac3b747..339e47d 100755
--- a/test/ral/type/file/target.rb
+++ b/test/ral/type/file/target.rb
@@ -7,353 +7,353 @@ require 'puppettest/support/utils'
require 'fileutils'
class TestFileTarget < Test::Unit::TestCase
- include PuppetTest::Support::Utils
- include PuppetTest::FileTesting
+ include PuppetTest::Support::Utils
+ include PuppetTest::FileTesting
- def setup
- super
- @file = Puppet::Type.type(:file)
- end
+ def setup
+ super
+ @file = Puppet::Type.type(:file)
+ end
- # Make sure we can create symlinks
- def test_symlinks
- path = tempfile
- link = tempfile
+ # Make sure we can create symlinks
+ def test_symlinks
+ path = tempfile
+ link = tempfile
- File.open(path, "w") { |f| f.puts "yay" }
+ File.open(path, "w") { |f| f.puts "yay" }
- file = nil
- assert_nothing_raised {
+ file = nil
+ assert_nothing_raised {
- file = Puppet::Type.type(:file).new(
+ file = Puppet::Type.type(:file).new(
- :title => "somethingelse",
- :ensure => path,
+ :title => "somethingelse",
+ :ensure => path,
- :path => link
- )
- }
+ :path => link
+ )
+ }
- assert_events([:link_created], file)
+ assert_events([:link_created], file)
- assert(FileTest.symlink?(link), "Link was not created")
+ assert(FileTest.symlink?(link), "Link was not created")
- assert_equal(path, File.readlink(link), "Link was created incorrectly")
+ assert_equal(path, File.readlink(link), "Link was created incorrectly")
- # Make sure running it again works
- assert_events([], file)
- assert_events([], file)
- assert_events([], file)
- end
+ # Make sure running it again works
+ assert_events([], file)
+ assert_events([], file)
+ assert_events([], file)
+ end
- def test_simplerecursivelinking
- source = tempfile
- path = tempfile
- subdir = File.join(source, "subdir")
- file = File.join(subdir, "file")
+ def test_simplerecursivelinking
+ source = tempfile
+ path = tempfile
+ subdir = File.join(source, "subdir")
+ file = File.join(subdir, "file")
- system("mkdir -p #{subdir}")
- system("touch #{file}")
+ system("mkdir -p #{subdir}")
+ system("touch #{file}")
- link = Puppet::Type.type(:file).new(
+ link = Puppet::Type.type(:file).new(
- :ensure => source,
- :path => path,
+ :ensure => source,
+ :path => path,
- :recurse => true
- )
-
- catalog = mk_catalog(link)
- catalog.apply
-
- sublink = File.join(path, "subdir")
- linkpath = File.join(sublink, "file")
- assert(File.directory?(path), "dest is not a dir")
- assert(File.directory?(sublink), "subdest is not a dir")
- assert(File.symlink?(linkpath), "path is not a link")
- assert_equal(file, File.readlink(linkpath))
-
- # Use classes for comparison, because the resource inspection is so large
- assert_events([], link, "Link is not in sync")
+ :recurse => true
+ )
+
+ catalog = mk_catalog(link)
+ catalog.apply
+
+ sublink = File.join(path, "subdir")
+ linkpath = File.join(sublink, "file")
+ assert(File.directory?(path), "dest is not a dir")
+ assert(File.directory?(sublink), "subdest is not a dir")
+ assert(File.symlink?(linkpath), "path is not a link")
+ assert_equal(file, File.readlink(linkpath))
+
+ # Use classes for comparison, because the resource inspection is so large
+ assert_events([], link, "Link is not in sync")
+ end
+
+ def test_recursivelinking
+ source = tempfile
+ dest = tempfile
+
+ files = []
+ dirs = []
+
+ # Make a bunch of files and dirs
+ Dir.mkdir(source)
+ Dir.chdir(source) do
+ system("mkdir -p #{"some/path/of/dirs"}")
+ system("mkdir -p #{"other/path/of/dirs"}")
+ system("touch #{"file"}")
+ system("touch #{"other/file"}")
+ system("touch #{"some/path/of/file"}")
+ system("touch #{"some/path/of/dirs/file"}")
+ system("touch #{"other/path/of/file"}")
+
+ files = %x{find . -type f}.chomp.split(/\n/)
+ dirs = %x{find . -type d}.chomp.split(/\n/).reject{|d| d =~ /^\.+$/ }
end
- def test_recursivelinking
- source = tempfile
- dest = tempfile
+ link = nil
+ assert_nothing_raised {
- files = []
- dirs = []
-
- # Make a bunch of files and dirs
- Dir.mkdir(source)
- Dir.chdir(source) do
- system("mkdir -p #{"some/path/of/dirs"}")
- system("mkdir -p #{"other/path/of/dirs"}")
- system("touch #{"file"}")
- system("touch #{"other/file"}")
- system("touch #{"some/path/of/file"}")
- system("touch #{"some/path/of/dirs/file"}")
- system("touch #{"other/path/of/file"}")
-
- files = %x{find . -type f}.chomp.split(/\n/)
- dirs = %x{find . -type d}.chomp.split(/\n/).reject{|d| d =~ /^\.+$/ }
- end
-
- link = nil
- assert_nothing_raised {
-
- link = Puppet::Type.type(:file).new(
+ link = Puppet::Type.type(:file).new(
- :ensure => source,
- :path => dest,
+ :ensure => source,
+ :path => dest,
- :recurse => true
- )
- }
-
- assert_apply(link)
-
- files.each do |f|
- f.sub!(/^\.#{File::SEPARATOR}/, '')
- path = File.join(dest, f)
- assert(FileTest.exists?(path), "Link #{path} was not created")
- assert(FileTest.symlink?(path), "#{f} is not a link")
- target = File.readlink(path)
- assert_equal(File.join(source, f), target)
- end
-
- dirs.each do |d|
- d.sub!(/^\.#{File::SEPARATOR}/, '')
- path = File.join(dest, d)
- assert(FileTest.exists?(path), "Dir #{path} was not created")
- assert(FileTest.directory?(path), "#{d} is not a directory")
- end
+ :recurse => true
+ )
+ }
+
+ assert_apply(link)
+
+ files.each do |f|
+ f.sub!(/^\.#{File::SEPARATOR}/, '')
+ path = File.join(dest, f)
+ assert(FileTest.exists?(path), "Link #{path} was not created")
+ assert(FileTest.symlink?(path), "#{f} is not a link")
+ target = File.readlink(path)
+ assert_equal(File.join(source, f), target)
+ end
+
+ dirs.each do |d|
+ d.sub!(/^\.#{File::SEPARATOR}/, '')
+ path = File.join(dest, d)
+ assert(FileTest.exists?(path), "Dir #{path} was not created")
+ assert(FileTest.directory?(path), "#{d} is not a directory")
end
+ end
- def test_localrelativelinks
- dir = tempfile
- Dir.mkdir(dir)
- source = File.join(dir, "source")
- File.open(source, "w") { |f| f.puts "yay" }
- dest = File.join(dir, "link")
+ def test_localrelativelinks
+ dir = tempfile
+ Dir.mkdir(dir)
+ source = File.join(dir, "source")
+ File.open(source, "w") { |f| f.puts "yay" }
+ dest = File.join(dir, "link")
- link = nil
- assert_nothing_raised {
+ link = nil
+ assert_nothing_raised {
- link = Puppet::Type.type(:file).new(
+ link = Puppet::Type.type(:file).new(
- :path => dest,
+ :path => dest,
- :ensure => "source"
- )
- }
-
- assert_events([:link_created], link)
- assert(FileTest.symlink?(dest), "Did not create link")
- assert_equal("source", File.readlink(dest))
- assert_equal("yay\n", File.read(dest))
- end
+ :ensure => "source"
+ )
+ }
+
+ assert_events([:link_created], link)
+ assert(FileTest.symlink?(dest), "Did not create link")
+ assert_equal("source", File.readlink(dest))
+ assert_equal("yay\n", File.read(dest))
+ end
- def test_recursivelinkingmissingtarget
- source = tempfile
- dest = tempfile
+ def test_recursivelinkingmissingtarget
+ source = tempfile
+ dest = tempfile
- resources = []
+ resources = []
- resources << Puppet::Type.type(:exec).new(
+ resources << Puppet::Type.type(:exec).new(
- :command => "mkdir #{source}; touch #{source}/file",
- :title => "yay",
+ :command => "mkdir #{source}; touch #{source}/file",
+ :title => "yay",
- :path => ENV["PATH"]
- )
+ :path => ENV["PATH"]
+ )
- resources << Puppet::Type.type(:file).new(
+ resources << Puppet::Type.type(:file).new(
- :ensure => source,
- :path => dest,
- :recurse => true,
+ :ensure => source,
+ :path => dest,
+ :recurse => true,
- :require => resources[0]
- )
+ :require => resources[0]
+ )
- assert_apply(*resources)
+ assert_apply(*resources)
- link = File.join(dest, "file")
- assert(FileTest.symlink?(link), "Did not make link")
- assert_equal(File.join(source, "file"), File.readlink(link))
- end
+ link = File.join(dest, "file")
+ assert(FileTest.symlink?(link), "Did not make link")
+ assert_equal(File.join(source, "file"), File.readlink(link))
+ end
- def test_insync?
- source = tempfile
- dest = tempfile
+ def test_insync?
+ source = tempfile
+ dest = tempfile
- obj = @file.create(:path => source, :target => dest)
+ obj = @file.create(:path => source, :target => dest)
- prop = obj.send(:property, :target)
- prop.send(:instance_variable_set, "@should", [:nochange])
+ prop = obj.send(:property, :target)
+ prop.send(:instance_variable_set, "@should", [:nochange])
- assert(
- prop.insync?(prop.retrieve),
+ assert(
+ prop.insync?(prop.retrieve),
- "Property not in sync with should == :nochange")
+ "Property not in sync with should == :nochange")
- prop = obj.send(:property, :target)
- prop.send(:instance_variable_set, "@should", [:notlink])
+ prop = obj.send(:property, :target)
+ prop.send(:instance_variable_set, "@should", [:notlink])
- assert(
- prop.insync?(prop.retrieve),
+ assert(
+ prop.insync?(prop.retrieve),
- "Property not in sync with should == :nochange")
+ "Property not in sync with should == :nochange")
- # Lastly, make sure that we don't try to do anything when we're
- # recursing, since 'ensure' does the work.
- obj[:recurse] = true
- prop.should = dest
+ # Lastly, make sure that we don't try to do anything when we're
+ # recursing, since 'ensure' does the work.
+ obj[:recurse] = true
+ prop.should = dest
- assert(
- prop.insync?(prop.retrieve),
+ assert(
+ prop.insync?(prop.retrieve),
- "Still out of sync during recursion")
- end
+ "Still out of sync during recursion")
+ end
- def test_replacedirwithlink
- Puppet[:trace] = false
- path = tempfile
- link = tempfile
+ def test_replacedirwithlink
+ Puppet[:trace] = false
+ path = tempfile
+ link = tempfile
- File.open(path, "w") { |f| f.puts "yay" }
- Dir.mkdir(link)
- File.open(File.join(link, "yay"), "w") do |f| f.puts "boo" end
+ File.open(path, "w") { |f| f.puts "yay" }
+ Dir.mkdir(link)
+ File.open(File.join(link, "yay"), "w") do |f| f.puts "boo" end
- file = nil
- assert_nothing_raised {
+ file = nil
+ assert_nothing_raised {
- file = Puppet::Type.type(:file).new(
+ file = Puppet::Type.type(:file).new(
- :ensure => path,
- :path => link,
+ :ensure => path,
+ :path => link,
- :backup => false
- )
- }
+ :backup => false
+ )
+ }
- # First run through without :force
- assert_events([], file)
+ # First run through without :force
+ assert_events([], file)
- assert(FileTest.directory?(link), "Link replaced dir without force")
+ assert(FileTest.directory?(link), "Link replaced dir without force")
- assert_nothing_raised { file[:force] = true }
+ assert_nothing_raised { file[:force] = true }
- assert_events([:link_created], file)
+ assert_events([:link_created], file)
- assert(FileTest.symlink?(link), "Link was not created")
+ assert(FileTest.symlink?(link), "Link was not created")
- assert_equal(path, File.readlink(link), "Link was created incorrectly")
- end
+ assert_equal(path, File.readlink(link), "Link was created incorrectly")
+ end
- def test_replace_links_with_files
- base = tempfile
+ def test_replace_links_with_files
+ base = tempfile
- Dir.mkdir(base)
+ Dir.mkdir(base)
- file = File.join(base, "file")
- link = File.join(base, "link")
- File.open(file, "w") { |f| f.puts "yayness" }
- File.symlink(file, link)
+ file = File.join(base, "file")
+ link = File.join(base, "link")
+ File.open(file, "w") { |f| f.puts "yayness" }
+ File.symlink(file, link)
- obj = Puppet::Type.type(:file).new(
+ obj = Puppet::Type.type(:file).new(
- :path => link,
+ :path => link,
- :ensure => "file"
- )
+ :ensure => "file"
+ )
- assert_apply(obj)
+ assert_apply(obj)
- assert_equal(
- "yayness\n", File.read(file),
+ assert_equal(
+ "yayness\n", File.read(file),
- "Original file got changed")
- assert_equal("file", File.lstat(link).ftype, "File is still a link")
- end
+ "Original file got changed")
+ assert_equal("file", File.lstat(link).ftype, "File is still a link")
+ end
- def test_no_erase_linkedto_files
- base = tempfile
+ def test_no_erase_linkedto_files
+ base = tempfile
- Dir.mkdir(base)
+ Dir.mkdir(base)
- dirs = {}
- %w{other source target}.each do |d|
- dirs[d] = File.join(base, d)
- Dir.mkdir(dirs[d])
- end
+ dirs = {}
+ %w{other source target}.each do |d|
+ dirs[d] = File.join(base, d)
+ Dir.mkdir(dirs[d])
+ end
- file = File.join(dirs["other"], "file")
- sourcefile = File.join(dirs["source"], "sourcefile")
- link = File.join(dirs["target"], "sourcefile")
+ file = File.join(dirs["other"], "file")
+ sourcefile = File.join(dirs["source"], "sourcefile")
+ link = File.join(dirs["target"], "sourcefile")
- File.open(file, "w") { |f| f.puts "other" }
- File.open(sourcefile, "w") { |f| f.puts "source" }
- File.symlink(file, link)
+ File.open(file, "w") { |f| f.puts "other" }
+ File.open(sourcefile, "w") { |f| f.puts "source" }
+ File.symlink(file, link)
- obj = Puppet::Type.type(:file).new(
+ obj = Puppet::Type.type(:file).new(
- :path => dirs["target"],
- :ensure => :file,
- :source => dirs["source"],
+ :path => dirs["target"],
+ :ensure => :file,
+ :source => dirs["source"],
- :recurse => true
- )
- config = mk_catalog obj
- config.apply
+ :recurse => true
+ )
+ config = mk_catalog obj
+ config.apply
- newfile = File.join(dirs["target"], "sourcefile")
+ newfile = File.join(dirs["target"], "sourcefile")
- assert(File.directory?(dirs["target"]), "Dir did not get created")
- assert(File.file?(newfile), "File did not get copied")
+ assert(File.directory?(dirs["target"]), "Dir did not get created")
+ assert(File.file?(newfile), "File did not get copied")
- assert_equal(File.read(sourcefile), File.read(newfile),
- "File did not get copied correctly.")
+ assert_equal(File.read(sourcefile), File.read(newfile),
+ "File did not get copied correctly.")
- assert_equal(
- "other\n", File.read(file),
+ assert_equal(
+ "other\n", File.read(file),
- "Original file got changed")
- assert_equal("file", File.lstat(link).ftype, "File is still a link")
- end
+ "Original file got changed")
+ assert_equal("file", File.lstat(link).ftype, "File is still a link")
+ end
- def test_replace_links
- dest = tempfile
- otherdest = tempfile
- link = tempfile
+ def test_replace_links
+ dest = tempfile
+ otherdest = tempfile
+ link = tempfile
- File.open(dest, "w") { |f| f.puts "boo" }
- File.open(otherdest, "w") { |f| f.puts "yay" }
+ File.open(dest, "w") { |f| f.puts "boo" }
+ File.open(otherdest, "w") { |f| f.puts "yay" }
- obj = Puppet::Type.type(:file).new(
+ obj = Puppet::Type.type(:file).new(
- :path => link,
+ :path => link,
- :ensure => otherdest
- )
+ :ensure => otherdest
+ )
- assert_apply(obj)
+ assert_apply(obj)
- assert_equal(otherdest, File.readlink(link), "Link did not get created")
+ assert_equal(otherdest, File.readlink(link), "Link did not get created")
- obj[:ensure] = dest
+ obj[:ensure] = dest
- assert_apply(obj)
+ assert_apply(obj)
- assert_equal(dest, File.readlink(link), "Link did not get changed")
- end
+ assert_equal(dest, File.readlink(link), "Link did not get changed")
+ end
end
diff --git a/test/ral/type/fileignoresource.rb b/test/ral/type/fileignoresource.rb
index 89e51a7..3254fe2 100755
--- a/test/ral/type/fileignoresource.rb
+++ b/test/ral/type/fileignoresource.rb
@@ -8,258 +8,258 @@ require 'cgi'
require 'fileutils'
class TestFileIgnoreSources < Test::Unit::TestCase
- include PuppetTest::Support::Utils
- include PuppetTest::FileTesting
-
- def setup
- super
- begin
- initstorage
- rescue
- system("rm -rf #{Puppet[:statefile]}")
- end
-
- Facter.stubs(:to_hash).returns({})
+ include PuppetTest::Support::Utils
+ include PuppetTest::FileTesting
+
+ def setup
+ super
+ begin
+ initstorage
+ rescue
+ system("rm -rf #{Puppet[:statefile]}")
end
+ Facter.stubs(:to_hash).returns({})
+ end
+
#This is not needed unless using md5 (correct me if I'm wrong)
- def initstorage
- Puppet::Util::Storage.init
- Puppet::Util::Storage.load
- end
+ def initstorage
+ Puppet::Util::Storage.init
+ Puppet::Util::Storage.load
+ end
- def clearstorage
- Puppet::Util::Storage.store
- Puppet::Util::Storage.clear
- end
+ def clearstorage
+ Puppet::Util::Storage.store
+ Puppet::Util::Storage.clear
+ end
- def test_ignore_simple_source
+ def test_ignore_simple_source
- #Temp directory to run tests in
- path = tempfile
- @@tmpfiles.push path
+ #Temp directory to run tests in
+ path = tempfile
+ @@tmpfiles.push path
- #source directory
- sourcedir = "sourcedir"
- sourcefile1 = "sourcefile1"
- sourcefile2 = "sourcefile2"
+ #source directory
+ sourcedir = "sourcedir"
+ sourcefile1 = "sourcefile1"
+ sourcefile2 = "sourcefile2"
- frompath = File.join(path,sourcedir)
- FileUtils.mkdir_p frompath
+ frompath = File.join(path,sourcedir)
+ FileUtils.mkdir_p frompath
- topath = File.join(path,"destdir")
- FileUtils.mkdir topath
+ topath = File.join(path,"destdir")
+ FileUtils.mkdir topath
- #initialize variables before block
- tofile = nil
- trans = nil
+ #initialize variables before block
+ tofile = nil
+ trans = nil
- #create source files
+ #create source files
- File.open(
- File.join(frompath,sourcefile1),
+ File.open(
+ File.join(frompath,sourcefile1),
- File::WRONLY|File::CREAT|File::APPEND) { |of|
- of.puts "yayness"
- }
+ File::WRONLY|File::CREAT|File::APPEND) { |of|
+ of.puts "yayness"
+ }
- File.open(
- File.join(frompath,sourcefile2),
+ File.open(
+ File.join(frompath,sourcefile2),
- File::WRONLY|File::CREAT|File::APPEND) { |of|
- of.puts "even yayer"
- }
+ File::WRONLY|File::CREAT|File::APPEND) { |of|
+ of.puts "even yayer"
+ }
- #makes Puppet file Object
- assert_nothing_raised {
+ #makes Puppet file Object
+ assert_nothing_raised {
- tofile = Puppet::Type.type(:file).new(
+ tofile = Puppet::Type.type(:file).new(
- :name => topath,
- :source => frompath,
- :recurse => true,
+ :name => topath,
+ :source => frompath,
+ :recurse => true,
- :ignore => "sourcefile2"
- )
- }
+ :ignore => "sourcefile2"
+ )
+ }
- config = mk_catalog(tofile)
- config.apply
+ config = mk_catalog(tofile)
+ config.apply
- #topath should exist as a directory with sourcedir as a directory
+ #topath should exist as a directory with sourcedir as a directory
- #This file should exist
- assert(FileTest.exists?(File.join(topath,sourcefile1)))
+ #This file should exist
+ assert(FileTest.exists?(File.join(topath,sourcefile1)))
- #This file should not
- assert(!(FileTest.exists?(File.join(topath,sourcefile2))))
- end
+ #This file should not
+ assert(!(FileTest.exists?(File.join(topath,sourcefile2))))
+ end
- def test_ignore_with_wildcard
- #Temp directory to run tests in
- path = tempfile
- @@tmpfiles.push path
+ def test_ignore_with_wildcard
+ #Temp directory to run tests in
+ path = tempfile
+ @@tmpfiles.push path
- #source directory
- sourcedir = "sourcedir"
- subdir = "subdir"
- subdir2 = "subdir2"
- sourcefile1 = "sourcefile1"
- sourcefile2 = "sourcefile2"
+ #source directory
+ sourcedir = "sourcedir"
+ subdir = "subdir"
+ subdir2 = "subdir2"
+ sourcefile1 = "sourcefile1"
+ sourcefile2 = "sourcefile2"
- frompath = File.join(path,sourcedir)
- FileUtils.mkdir_p frompath
+ frompath = File.join(path,sourcedir)
+ FileUtils.mkdir_p frompath
- FileUtils.mkdir_p(File.join(frompath, subdir))
- FileUtils.mkdir_p(File.join(frompath, subdir2))
- dir = Dir.glob(File.join(path,"**/*"))
+ FileUtils.mkdir_p(File.join(frompath, subdir))
+ FileUtils.mkdir_p(File.join(frompath, subdir2))
+ dir = Dir.glob(File.join(path,"**/*"))
- topath = File.join(path,"destdir")
- FileUtils.mkdir topath
+ topath = File.join(path,"destdir")
+ FileUtils.mkdir topath
- #initialize variables before block
- tofile = nil
- trans = nil
+ #initialize variables before block
+ tofile = nil
+ trans = nil
- #create source files
+ #create source files
- dir.each { |dir|
+ dir.each { |dir|
- File.open(
- File.join(dir,sourcefile1),
+ File.open(
+ File.join(dir,sourcefile1),
- File::WRONLY|File::CREAT|File::APPEND) { |of|
- of.puts "yayness"
- }
+ File::WRONLY|File::CREAT|File::APPEND) { |of|
+ of.puts "yayness"
+ }
- File.open(
- File.join(dir,sourcefile2),
+ File.open(
+ File.join(dir,sourcefile2),
- File::WRONLY|File::CREAT|File::APPEND) { |of|
- of.puts "even yayer"
- }
+ File::WRONLY|File::CREAT|File::APPEND) { |of|
+ of.puts "even yayer"
+ }
- }
+ }
- #makes Puppet file Object
- assert_nothing_raised {
+ #makes Puppet file Object
+ assert_nothing_raised {
- tofile = Puppet::Type.type(:file).new(
+ tofile = Puppet::Type.type(:file).new(
- :name => topath,
- :source => frompath,
- :recurse => true,
+ :name => topath,
+ :source => frompath,
+ :recurse => true,
- :ignore => "*2"
- )
- }
+ :ignore => "*2"
+ )
+ }
- config = mk_catalog(tofile)
- config.apply
+ config = mk_catalog(tofile)
+ config.apply
- #topath should exist as a directory with sourcedir as a directory
+ #topath should exist as a directory with sourcedir as a directory
- #This file should exist
- assert(FileTest.exists?(File.join(topath,sourcefile1)))
- assert(FileTest.exists?(File.join(topath,subdir)))
- assert(FileTest.exists?(File.join(File.join(topath,subdir),sourcefile1)))
+ #This file should exist
+ assert(FileTest.exists?(File.join(topath,sourcefile1)))
+ assert(FileTest.exists?(File.join(topath,subdir)))
+ assert(FileTest.exists?(File.join(File.join(topath,subdir),sourcefile1)))
- #This file should not
- assert(!(FileTest.exists?(File.join(topath,sourcefile2))))
- assert(!(FileTest.exists?(File.join(topath,subdir2))))
- assert(!(FileTest.exists?(File.join(File.join(topath,subdir),sourcefile2))))
- end
+ #This file should not
+ assert(!(FileTest.exists?(File.join(topath,sourcefile2))))
+ assert(!(FileTest.exists?(File.join(topath,subdir2))))
+ assert(!(FileTest.exists?(File.join(File.join(topath,subdir),sourcefile2))))
+ end
- def test_ignore_array
- #Temp directory to run tests in
- path = tempfile
- @@tmpfiles.push path
+ def test_ignore_array
+ #Temp directory to run tests in
+ path = tempfile
+ @@tmpfiles.push path
- #source directory
- sourcedir = "sourcedir"
- subdir = "subdir"
- subdir2 = "subdir2"
- subdir3 = "anotherdir"
- sourcefile1 = "sourcefile1"
- sourcefile2 = "sourcefile2"
+ #source directory
+ sourcedir = "sourcedir"
+ subdir = "subdir"
+ subdir2 = "subdir2"
+ subdir3 = "anotherdir"
+ sourcefile1 = "sourcefile1"
+ sourcefile2 = "sourcefile2"
- frompath = File.join(path,sourcedir)
- FileUtils.mkdir_p frompath
+ frompath = File.join(path,sourcedir)
+ FileUtils.mkdir_p frompath
- FileUtils.mkdir_p(File.join(frompath, subdir))
- FileUtils.mkdir_p(File.join(frompath, subdir2))
- FileUtils.mkdir_p(File.join(frompath, subdir3))
- sourcedir = Dir.glob(File.join(path,"**/*"))
+ FileUtils.mkdir_p(File.join(frompath, subdir))
+ FileUtils.mkdir_p(File.join(frompath, subdir2))
+ FileUtils.mkdir_p(File.join(frompath, subdir3))
+ sourcedir = Dir.glob(File.join(path,"**/*"))
- topath = File.join(path,"destdir")
- FileUtils.mkdir topath
+ topath = File.join(path,"destdir")
+ FileUtils.mkdir topath
- #initialize variables before block
- tofile = nil
- trans = nil
+ #initialize variables before block
+ tofile = nil
+ trans = nil
- #create source files
+ #create source files
- sourcedir.each { |dir|
+ sourcedir.each { |dir|
- File.open(
- File.join(dir,sourcefile1),
+ File.open(
+ File.join(dir,sourcefile1),
- File::WRONLY|File::CREAT|File::APPEND) { |of|
- of.puts "yayness"
- }
+ File::WRONLY|File::CREAT|File::APPEND) { |of|
+ of.puts "yayness"
+ }
- File.open(
- File.join(dir,sourcefile2),
+ File.open(
+ File.join(dir,sourcefile2),
- File::WRONLY|File::CREAT|File::APPEND) { |of|
- of.puts "even yayer"
- }
+ File::WRONLY|File::CREAT|File::APPEND) { |of|
+ of.puts "even yayer"
+ }
- }
+ }
- #makes Puppet file Object
- assert_nothing_raised {
+ #makes Puppet file Object
+ assert_nothing_raised {
- tofile = Puppet::Type.type(:file).new(
+ tofile = Puppet::Type.type(:file).new(
- :name => topath,
- :source => frompath,
- :recurse => true,
+ :name => topath,
+ :source => frompath,
+ :recurse => true,
- :ignore => ["*2", "an*"]
- # :ignore => ["*2", "an*", "nomatch"]
- )
- }
+ :ignore => ["*2", "an*"]
+ # :ignore => ["*2", "an*", "nomatch"]
+ )
+ }
- config = mk_catalog(tofile)
- config.apply
+ config = mk_catalog(tofile)
+ config.apply
- #topath should exist as a directory with sourcedir as a directory
+ #topath should exist as a directory with sourcedir as a directory
- # This file should exist
- # proper files in destination
- assert(FileTest.exists?(File.join(topath,sourcefile1)), "file1 not in destdir")
- assert(FileTest.exists?(File.join(topath,subdir)), "subdir1 not in destdir")
- assert(FileTest.exists?(File.join(File.join(topath,subdir),sourcefile1)), "file1 not in subdir")
- # proper files in source
- assert(FileTest.exists?(File.join(frompath,subdir)), "subdir not in source")
- assert(FileTest.exists?(File.join(frompath,subdir2)), "subdir2 not in source")
- assert(FileTest.exists?(File.join(frompath,subdir3)), "subdir3 not in source")
+ # This file should exist
+ # proper files in destination
+ assert(FileTest.exists?(File.join(topath,sourcefile1)), "file1 not in destdir")
+ assert(FileTest.exists?(File.join(topath,subdir)), "subdir1 not in destdir")
+ assert(FileTest.exists?(File.join(File.join(topath,subdir),sourcefile1)), "file1 not in subdir")
+ # proper files in source
+ assert(FileTest.exists?(File.join(frompath,subdir)), "subdir not in source")
+ assert(FileTest.exists?(File.join(frompath,subdir2)), "subdir2 not in source")
+ assert(FileTest.exists?(File.join(frompath,subdir3)), "subdir3 not in source")
- # This file should not
- assert(!(FileTest.exists?(File.join(topath,sourcefile2))), "file2 in dest")
- assert(!(FileTest.exists?(File.join(topath,subdir2))), "subdir2 in dest")
- assert(!(FileTest.exists?(File.join(topath,subdir3))), "anotherdir in dest")
- assert(!(FileTest.exists?(File.join(File.join(topath,subdir),sourcefile2))), "file2 in dest/sub")
- end
+ # This file should not
+ assert(!(FileTest.exists?(File.join(topath,sourcefile2))), "file2 in dest")
+ assert(!(FileTest.exists?(File.join(topath,subdir2))), "subdir2 in dest")
+ assert(!(FileTest.exists?(File.join(topath,subdir3))), "anotherdir in dest")
+ assert(!(FileTest.exists?(File.join(File.join(topath,subdir),sourcefile2))), "file2 in dest/sub")
+ end
end
diff --git a/test/ral/type/filesources.rb b/test/ral/type/filesources.rb
index 605704b..dd73cea 100755
--- a/test/ral/type/filesources.rb
+++ b/test/ral/type/filesources.rb
@@ -9,502 +9,502 @@ require 'fileutils'
require 'mocha'
class TestFileSources < Test::Unit::TestCase
- include PuppetTest::Support::Utils
- include PuppetTest::FileTesting
- def setup
- super
- if defined?(@port)
- @port += 1
- else
- @port = 12345
- end
- @file = Puppet::Type.type(:file)
- Puppet[:filetimeout] = -1
- Puppet::Util::SUIDManager.stubs(:asuser).yields
- Facter.stubs(:to_hash).returns({})
- end
-
- def teardown
- super
- Puppet::Network::HttpPool.clear_http_instances
- end
-
- def use_storage
- initstorage
- rescue
- system("rm -rf #{Puppet[:statefile]}")
- end
-
- def initstorage
- Puppet::Util::Storage.init
- Puppet::Util::Storage.load
- end
-
- # Make a simple recursive tree.
- def mk_sourcetree
- source = tempfile
- sourcefile = File.join(source, "file")
- Dir.mkdir source
- File.open(sourcefile, "w") { |f| f.puts "yay" }
-
- dest = tempfile
- destfile = File.join(dest, "file")
- return source, dest, sourcefile, destfile
+ include PuppetTest::Support::Utils
+ include PuppetTest::FileTesting
+ def setup
+ super
+ if defined?(@port)
+ @port += 1
+ else
+ @port = 12345
end
-
- def recursive_source_test(fromdir, todir)
- initstorage
- tofile = nil
- trans = nil
-
-
- tofile = Puppet::Type.type(:file).new(
+ @file = Puppet::Type.type(:file)
+ Puppet[:filetimeout] = -1
+ Puppet::Util::SUIDManager.stubs(:asuser).yields
+ Facter.stubs(:to_hash).returns({})
+ end
+
+ def teardown
+ super
+ Puppet::Network::HttpPool.clear_http_instances
+ end
+
+ def use_storage
+ initstorage
+ rescue
+ system("rm -rf #{Puppet[:statefile]}")
+ end
+
+ def initstorage
+ Puppet::Util::Storage.init
+ Puppet::Util::Storage.load
+ end
+
+ # Make a simple recursive tree.
+ def mk_sourcetree
+ source = tempfile
+ sourcefile = File.join(source, "file")
+ Dir.mkdir source
+ File.open(sourcefile, "w") { |f| f.puts "yay" }
+
+ dest = tempfile
+ destfile = File.join(dest, "file")
+ return source, dest, sourcefile, destfile
+ end
+
+ def recursive_source_test(fromdir, todir)
+ initstorage
+ tofile = nil
+ trans = nil
+
+
+ tofile = Puppet::Type.type(:file).new(
- :path => todir,
- :recurse => true,
- :backup => false,
+ :path => todir,
+ :recurse => true,
+ :backup => false,
- :source => fromdir
- )
- catalog = mk_catalog(tofile)
- catalog.apply
-
- assert(FileTest.exists?(todir), "Created dir #{todir} does not exist")
- end
-
- def run_complex_sources(networked = false)
- path = tempfile
+ :source => fromdir
+ )
+ catalog = mk_catalog(tofile)
+ catalog.apply
- # first create the source directory
- FileUtils.mkdir_p path
+ assert(FileTest.exists?(todir), "Created dir #{todir} does not exist")
+ end
- # okay, let's create a directory structure
- fromdir = File.join(path,"fromdir")
- Dir.mkdir(fromdir)
- FileUtils.cd(fromdir) {
- File.open("one", "w") { |f| f.puts "onefile"}
- File.open("two", "w") { |f| f.puts "twofile"}
- }
+ def run_complex_sources(networked = false)
+ path = tempfile
- todir = File.join(path, "todir")
- source = fromdir
- source = "puppet://localhost/#{networked}#{fromdir}" if networked
- recursive_source_test(source, todir)
+ # first create the source directory
+ FileUtils.mkdir_p path
- [fromdir,todir, File.join(todir, "one"), File.join(todir, "two")]
- end
+ # okay, let's create a directory structure
+ fromdir = File.join(path,"fromdir")
+ Dir.mkdir(fromdir)
+ FileUtils.cd(fromdir) {
+ File.open("one", "w") { |f| f.puts "onefile"}
+ File.open("two", "w") { |f| f.puts "twofile"}
+ }
- def test_complex_sources_twice
- fromdir, todir, one, two = run_complex_sources
- assert_trees_equal(fromdir,todir)
- recursive_source_test(fromdir, todir)
- assert_trees_equal(fromdir,todir)
- # Now remove the whole tree and try it again.
- [one, two].each do |f| File.unlink(f) end
- Dir.rmdir(todir)
- recursive_source_test(fromdir, todir)
- assert_trees_equal(fromdir,todir)
- end
+ todir = File.join(path, "todir")
+ source = fromdir
+ source = "puppet://localhost/#{networked}#{fromdir}" if networked
+ recursive_source_test(source, todir)
- def test_sources_with_deleted_destfiles
- fromdir, todir, one, two = run_complex_sources
- assert(FileTest.exists?(todir))
+ [fromdir,todir, File.join(todir, "one"), File.join(todir, "two")]
+ end
- # then delete a file
- File.unlink(two)
+ def test_complex_sources_twice
+ fromdir, todir, one, two = run_complex_sources
+ assert_trees_equal(fromdir,todir)
+ recursive_source_test(fromdir, todir)
+ assert_trees_equal(fromdir,todir)
+ # Now remove the whole tree and try it again.
+ [one, two].each do |f| File.unlink(f) end
+ Dir.rmdir(todir)
+ recursive_source_test(fromdir, todir)
+ assert_trees_equal(fromdir,todir)
+ end
- # and run
- recursive_source_test(fromdir, todir)
+ def test_sources_with_deleted_destfiles
+ fromdir, todir, one, two = run_complex_sources
+ assert(FileTest.exists?(todir))
- assert(FileTest.exists?(two), "Deleted file was not recopied")
+ # then delete a file
+ File.unlink(two)
- # and make sure they're still equal
- assert_trees_equal(fromdir,todir)
- end
+ # and run
+ recursive_source_test(fromdir, todir)
- def test_sources_with_readonly_destfiles
- fromdir, todir, one, two = run_complex_sources
- assert(FileTest.exists?(todir))
- File.chmod(0600, one)
- recursive_source_test(fromdir, todir)
+ assert(FileTest.exists?(two), "Deleted file was not recopied")
- # and make sure they're still equal
- assert_trees_equal(fromdir,todir)
+ # and make sure they're still equal
+ assert_trees_equal(fromdir,todir)
+ end
- # Now try it with the directory being read-only
- File.chmod(0111, todir)
- recursive_source_test(fromdir, todir)
+ def test_sources_with_readonly_destfiles
+ fromdir, todir, one, two = run_complex_sources
+ assert(FileTest.exists?(todir))
+ File.chmod(0600, one)
+ recursive_source_test(fromdir, todir)
- # and make sure they're still equal
- assert_trees_equal(fromdir,todir)
- end
+ # and make sure they're still equal
+ assert_trees_equal(fromdir,todir)
- def test_sources_with_modified_dest_files
- fromdir, todir, one, two = run_complex_sources
+ # Now try it with the directory being read-only
+ File.chmod(0111, todir)
+ recursive_source_test(fromdir, todir)
- assert(FileTest.exists?(todir))
+ # and make sure they're still equal
+ assert_trees_equal(fromdir,todir)
+ end
- # Modify a dest file
- File.open(two, "w") { |f| f.puts "something else" }
+ def test_sources_with_modified_dest_files
+ fromdir, todir, one, two = run_complex_sources
- recursive_source_test(fromdir, todir)
+ assert(FileTest.exists?(todir))
- # and make sure they're still equal
- assert_trees_equal(fromdir,todir)
- end
+ # Modify a dest file
+ File.open(two, "w") { |f| f.puts "something else" }
- def test_sources_with_added_destfiles
- fromdir, todir = run_complex_sources
- assert(FileTest.exists?(todir))
- # and finally, add some new files
- add_random_files(todir)
+ recursive_source_test(fromdir, todir)
- recursive_source_test(fromdir, todir)
+ # and make sure they're still equal
+ assert_trees_equal(fromdir,todir)
+ end
- fromtree = file_list(fromdir)
- totree = file_list(todir)
+ def test_sources_with_added_destfiles
+ fromdir, todir = run_complex_sources
+ assert(FileTest.exists?(todir))
+ # and finally, add some new files
+ add_random_files(todir)
- assert(fromtree != totree, "Trees are incorrectly equal")
+ recursive_source_test(fromdir, todir)
- # then remove our new files
- FileUtils.cd(todir) {
- %x{find . 2>/dev/null}.chomp.split(/\n/).each { |file|
- if file =~ /file[0-9]+/
- FileUtils.rm_rf(file)
- end
- }
- }
+ fromtree = file_list(fromdir)
+ totree = file_list(todir)
- # and make sure they're still equal
- assert_trees_equal(fromdir,todir)
- end
+ assert(fromtree != totree, "Trees are incorrectly equal")
- # Make sure added files get correctly caught during recursion
- def test_RecursionWithAddedFiles
- basedir = tempfile
- Dir.mkdir(basedir)
- @@tmpfiles << basedir
- file1 = File.join(basedir, "file1")
- file2 = File.join(basedir, "file2")
- subdir1 = File.join(basedir, "subdir1")
- file3 = File.join(subdir1, "file")
- File.open(file1, "w") { |f| f.puts "yay" }
- rootobj = nil
- assert_nothing_raised {
-
- rootobj = Puppet::Type.type(:file).new(
+ # then remove our new files
+ FileUtils.cd(todir) {
+ %x{find . 2>/dev/null}.chomp.split(/\n/).each { |file|
+ if file =~ /file[0-9]+/
+ FileUtils.rm_rf(file)
+ end
+ }
+ }
+
+ # and make sure they're still equal
+ assert_trees_equal(fromdir,todir)
+ end
+
+ # Make sure added files get correctly caught during recursion
+ def test_RecursionWithAddedFiles
+ basedir = tempfile
+ Dir.mkdir(basedir)
+ @@tmpfiles << basedir
+ file1 = File.join(basedir, "file1")
+ file2 = File.join(basedir, "file2")
+ subdir1 = File.join(basedir, "subdir1")
+ file3 = File.join(subdir1, "file")
+ File.open(file1, "w") { |f| f.puts "yay" }
+ rootobj = nil
+ assert_nothing_raised {
+
+ rootobj = Puppet::Type.type(:file).new(
- :name => basedir,
- :recurse => true,
- :check => %w{type owner},
+ :name => basedir,
+ :recurse => true,
+ :check => %w{type owner},
- :mode => 0755
- )
- }
-
- assert_apply(rootobj)
- assert_equal(0755, filemode(file1))
-
- File.open(file2, "w") { |f| f.puts "rah" }
- assert_apply(rootobj)
- assert_equal(0755, filemode(file2))
-
- Dir.mkdir(subdir1)
- File.open(file3, "w") { |f| f.puts "foo" }
- assert_apply(rootobj)
- assert_equal(0755, filemode(file3))
- end
-
- def mkfileserverconf(mounts)
- file = tempfile
- File.open(file, "w") { |f|
- mounts.each { |path, name|
- f.puts "[#{name}]\n\tpath #{path}\n\tallow *\n"
- }
- }
-
- @@tmpfiles << file
- file
- end
-
- def test_unmountedNetworkSources
- server = nil
- mounts = {
- "/" => "root",
- "/noexistokay" => "noexist"
- }
-
- fileserverconf = mkfileserverconf(mounts)
-
- Puppet[:autosign] = true
- Puppet[:masterport] = @port
- Puppet[:certdnsnames] = "localhost"
-
- serverpid = nil
- assert_nothing_raised("Could not start on port #{@port}") {
-
- server = Puppet::Network::HTTPServer::WEBrick.new(
+ :mode => 0755
+ )
+ }
+
+ assert_apply(rootobj)
+ assert_equal(0755, filemode(file1))
+
+ File.open(file2, "w") { |f| f.puts "rah" }
+ assert_apply(rootobj)
+ assert_equal(0755, filemode(file2))
+
+ Dir.mkdir(subdir1)
+ File.open(file3, "w") { |f| f.puts "foo" }
+ assert_apply(rootobj)
+ assert_equal(0755, filemode(file3))
+ end
+
+ def mkfileserverconf(mounts)
+ file = tempfile
+ File.open(file, "w") { |f|
+ mounts.each { |path, name|
+ f.puts "[#{name}]\n\tpath #{path}\n\tallow *\n"
+ }
+ }
+
+ @@tmpfiles << file
+ file
+ end
+
+ def test_unmountedNetworkSources
+ server = nil
+ mounts = {
+ "/" => "root",
+ "/noexistokay" => "noexist"
+ }
+
+ fileserverconf = mkfileserverconf(mounts)
+
+ Puppet[:autosign] = true
+ Puppet[:masterport] = @port
+ Puppet[:certdnsnames] = "localhost"
+
+ serverpid = nil
+ assert_nothing_raised("Could not start on port #{@port}") {
+
+ server = Puppet::Network::HTTPServer::WEBrick.new(
- :Port => @port,
+ :Port => @port,
- :Handlers => {
- :CA => {}, # so that certs autogenerate
- :FileServer => {
- :Config => fileserverconf
- }
- }
- )
-
+ :Handlers => {
+ :CA => {}, # so that certs autogenerate
+ :FileServer => {
+ :Config => fileserverconf
+ }
}
+ )
- serverpid = fork {
- assert_nothing_raised {
- #trap(:INT) { server.shutdown; Kernel.exit! }
- trap(:INT) { server.shutdown }
- server.start
- }
- }
- @@tmppids << serverpid
+ }
- sleep(1)
+ serverpid = fork {
+ assert_nothing_raised {
+ #trap(:INT) { server.shutdown; Kernel.exit! }
+ trap(:INT) { server.shutdown }
+ server.start
+ }
+ }
+ @@tmppids << serverpid
- name = File.join(tmpdir, "nosourcefile")
+ sleep(1)
- file = Puppet::Type.type(:file).new(
+ name = File.join(tmpdir, "nosourcefile")
+
+ file = Puppet::Type.type(:file).new(
- :source => "puppet://localhost/noexist/file",
+ :source => "puppet://localhost/noexist/file",
- :name => name
- )
+ :name => name
+ )
- assert_raise Puppet::Error do
- file.retrieve
- end
+ assert_raise Puppet::Error do
+ file.retrieve
+ end
- comp = mk_catalog(file)
- comp.apply
+ comp = mk_catalog(file)
+ comp.apply
- assert(!FileTest.exists?(name), "File with no source exists anyway")
- end
+ assert(!FileTest.exists?(name), "File with no source exists anyway")
+ end
- def test_sourcepaths
- files = []
- 3.times {
- files << tempfile
- }
+ def test_sourcepaths
+ files = []
+ 3.times {
+ files << tempfile
+ }
- to = tempfile
+ to = tempfile
- File.open(files[-1], "w") { |f| f.puts "yee-haw" }
+ File.open(files[-1], "w") { |f| f.puts "yee-haw" }
- file = nil
- assert_nothing_raised {
+ file = nil
+ assert_nothing_raised {
- file = Puppet::Type.type(:file).new(
+ file = Puppet::Type.type(:file).new(
- :name => to,
+ :name => to,
- :source => files
- )
- }
+ :source => files
+ )
+ }
- comp = mk_catalog(file)
- assert_events([:file_created], comp)
+ comp = mk_catalog(file)
+ assert_events([:file_created], comp)
- assert(File.exists?(to), "File does not exist")
+ assert(File.exists?(to), "File does not exist")
- txt = nil
- File.open(to) { |f| txt = f.read.chomp }
+ txt = nil
+ File.open(to) { |f| txt = f.read.chomp }
- assert_equal("yee-haw", txt, "Contents do not match")
- end
+ assert_equal("yee-haw", txt, "Contents do not match")
+ end
- # Make sure that source-copying updates the checksum on the same run
- def test_sourcebeatsensure
- source = tempfile
- dest = tempfile
- File.open(source, "w") { |f| f.puts "yay" }
+ # Make sure that source-copying updates the checksum on the same run
+ def test_sourcebeatsensure
+ source = tempfile
+ dest = tempfile
+ File.open(source, "w") { |f| f.puts "yay" }
- file = nil
- assert_nothing_raised {
+ file = nil
+ assert_nothing_raised {
- file = Puppet::Type.type(:file).new(
+ file = Puppet::Type.type(:file).new(
- :name => dest,
- :ensure => "file",
+ :name => dest,
+ :ensure => "file",
- :source => source
- )
- }
+ :source => source
+ )
+ }
- file.retrieve
+ file.retrieve
- assert_events([:file_created], file)
- file.retrieve
- assert_events([], file)
- assert_events([], file)
- end
+ assert_events([:file_created], file)
+ file.retrieve
+ assert_events([], file)
+ assert_events([], file)
+ end
- def test_sourcewithlinks
- source = tempfile
- link = tempfile
- dest = tempfile
+ def test_sourcewithlinks
+ source = tempfile
+ link = tempfile
+ dest = tempfile
- File.open(source, "w") { |f| f.puts "yay" }
- File.symlink(source, link)
+ File.open(source, "w") { |f| f.puts "yay" }
+ File.symlink(source, link)
- file = Puppet::Type.type(:file).new(:name => dest, :source => link)
+ file = Puppet::Type.type(:file).new(:name => dest, :source => link)
- catalog = mk_catalog(file)
+ catalog = mk_catalog(file)
- # Default to managing links
- catalog.apply
- assert(FileTest.symlink?(dest), "Did not create link")
+ # Default to managing links
+ catalog.apply
+ assert(FileTest.symlink?(dest), "Did not create link")
- # Now follow the links
- file[:links] = :follow
- catalog.apply
- assert(FileTest.file?(dest), "Destination is not a file")
- end
+ # Now follow the links
+ file[:links] = :follow
+ catalog.apply
+ assert(FileTest.file?(dest), "Destination is not a file")
+ end
- # Make sure files aren't replaced when replace is false, but otherwise
- # are.
- def test_replace
- dest = tempfile
+ # Make sure files aren't replaced when replace is false, but otherwise
+ # are.
+ def test_replace
+ dest = tempfile
- file = Puppet::Type.newfile(
+ file = Puppet::Type.newfile(
- :path => dest,
- :content => "foobar",
+ :path => dest,
+ :content => "foobar",
- :recurse => true
- )
+ :recurse => true
+ )
- assert_apply(file)
+ assert_apply(file)
- File.open(dest, "w") { |f| f.puts "yayness" }
+ File.open(dest, "w") { |f| f.puts "yayness" }
- file[:replace] = false
+ file[:replace] = false
- assert_apply(file)
+ assert_apply(file)
- # Make sure it doesn't change.
- assert_equal("yayness\n", File.read(dest), "File got replaced when :replace was false")
+ # Make sure it doesn't change.
+ assert_equal("yayness\n", File.read(dest), "File got replaced when :replace was false")
- file[:replace] = true
- assert_apply(file)
+ file[:replace] = true
+ assert_apply(file)
- # Make sure it changes.
- assert_equal("foobar", File.read(dest), "File was not replaced when :replace was true")
- end
+ # Make sure it changes.
+ assert_equal("foobar", File.read(dest), "File was not replaced when :replace was true")
+ end
- def test_sourceselect
- dest = tempfile
- sources = []
- 2.times { |i|
- i = i + 1
- source = tempfile
- sources << source
- file = File.join(source, "file#{i}")
- Dir.mkdir(source)
- File.open(file, "w") { |f| f.print "yay" }
- }
- file1 = File.join(dest, "file1")
- file2 = File.join(dest, "file2")
- file3 = File.join(dest, "file3")
-
- # Now make different files with the same name in each source dir
- sources.each_with_index do |source, i|
- File.open(File.join(source, "file3"), "w") { |f|
- f.print i.to_s
- }
- end
+ def test_sourceselect
+ dest = tempfile
+ sources = []
+ 2.times { |i|
+ i = i + 1
+ source = tempfile
+ sources << source
+ file = File.join(source, "file#{i}")
+ Dir.mkdir(source)
+ File.open(file, "w") { |f| f.print "yay" }
+ }
+ file1 = File.join(dest, "file1")
+ file2 = File.join(dest, "file2")
+ file3 = File.join(dest, "file3")
+ # Now make different files with the same name in each source dir
+ sources.each_with_index do |source, i|
+ File.open(File.join(source, "file3"), "w") { |f|
+ f.print i.to_s
+ }
+ end
- obj = Puppet::Type.newfile(
- :path => dest, :recurse => true,
+
+ obj = Puppet::Type.newfile(
+ :path => dest, :recurse => true,
- :source => sources)
+ :source => sources)
- assert_equal(:first, obj[:sourceselect], "sourceselect has the wrong default")
- # First, make sure we default to just copying file1
- assert_apply(obj)
+ assert_equal(:first, obj[:sourceselect], "sourceselect has the wrong default")
+ # First, make sure we default to just copying file1
+ assert_apply(obj)
- assert(FileTest.exists?(file1), "File from source 1 was not copied")
- assert(! FileTest.exists?(file2), "File from source 2 was copied")
- assert(FileTest.exists?(file3), "File from source 1 was not copied")
- assert_equal("0", File.read(file3), "file3 got wrong contents")
+ assert(FileTest.exists?(file1), "File from source 1 was not copied")
+ assert(! FileTest.exists?(file2), "File from source 2 was copied")
+ assert(FileTest.exists?(file3), "File from source 1 was not copied")
+ assert_equal("0", File.read(file3), "file3 got wrong contents")
- # Now reset sourceselect
- assert_nothing_raised do
- obj[:sourceselect] = :all
- end
- File.unlink(file1)
- File.unlink(file3)
- Puppet.err :yay
- assert_apply(obj)
-
- assert(FileTest.exists?(file1), "File from source 1 was not copied")
- assert(FileTest.exists?(file2), "File from source 2 was copied")
- assert(FileTest.exists?(file3), "File from source 1 was not copied")
- assert_equal("0", File.read(file3), "file3 got wrong contents")
+ # Now reset sourceselect
+ assert_nothing_raised do
+ obj[:sourceselect] = :all
+ end
+ File.unlink(file1)
+ File.unlink(file3)
+ Puppet.err :yay
+ assert_apply(obj)
+
+ assert(FileTest.exists?(file1), "File from source 1 was not copied")
+ assert(FileTest.exists?(file2), "File from source 2 was copied")
+ assert(FileTest.exists?(file3), "File from source 1 was not copied")
+ assert_equal("0", File.read(file3), "file3 got wrong contents")
+ end
+
+ def test_recursive_sourceselect
+ dest = tempfile
+ source1 = tempfile
+ source2 = tempfile
+ files = []
+ [source1, source2, File.join(source1, "subdir"), File.join(source2, "subdir")].each_with_index do |dir, i|
+ Dir.mkdir(dir)
+ # Make a single file in each directory
+ file = File.join(dir, "file#{i}")
+ File.open(file, "w") { |f| f.puts "yay#{i}"}
+
+ # Now make a second one in each directory
+ file = File.join(dir, "second-file#{i}")
+ File.open(file, "w") { |f| f.puts "yaysecond-#{i}"}
+ files << file
end
- def test_recursive_sourceselect
- dest = tempfile
- source1 = tempfile
- source2 = tempfile
- files = []
- [source1, source2, File.join(source1, "subdir"), File.join(source2, "subdir")].each_with_index do |dir, i|
- Dir.mkdir(dir)
- # Make a single file in each directory
- file = File.join(dir, "file#{i}")
- File.open(file, "w") { |f| f.puts "yay#{i}"}
-
- # Now make a second one in each directory
- file = File.join(dir, "second-file#{i}")
- File.open(file, "w") { |f| f.puts "yaysecond-#{i}"}
- files << file
- end
-
- obj = Puppet::Type.newfile(:path => dest, :source => [source1, source2], :sourceselect => :all, :recurse => true)
+ obj = Puppet::Type.newfile(:path => dest, :source => [source1, source2], :sourceselect => :all, :recurse => true)
- assert_apply(obj)
+ assert_apply(obj)
- ["file0", "file1", "second-file0", "second-file1", "subdir/file2", "subdir/second-file2", "subdir/file3", "subdir/second-file3"].each do |file|
- path = File.join(dest, file)
- assert(FileTest.exists?(path), "did not create #{file}")
+ ["file0", "file1", "second-file0", "second-file1", "subdir/file2", "subdir/second-file2", "subdir/file3", "subdir/second-file3"].each do |file|
+ path = File.join(dest, file)
+ assert(FileTest.exists?(path), "did not create #{file}")
- assert_equal("yay#{File.basename(file).sub("file", '')}\n", File.read(path), "file was not copied correctly")
- end
+ assert_equal("yay#{File.basename(file).sub("file", '')}\n", File.read(path), "file was not copied correctly")
end
+ end
- # #594
- def test_purging_missing_remote_files
- source = tempfile
- dest = tempfile
- s1 = File.join(source, "file1")
- s2 = File.join(source, "file2")
- d1 = File.join(dest, "file1")
- d2 = File.join(dest, "file2")
- Dir.mkdir(source)
- [s1, s2].each { |name| File.open(name, "w") { |file| file.puts "something" } }
+ # #594
+ def test_purging_missing_remote_files
+ source = tempfile
+ dest = tempfile
+ s1 = File.join(source, "file1")
+ s2 = File.join(source, "file2")
+ d1 = File.join(dest, "file1")
+ d2 = File.join(dest, "file2")
+ Dir.mkdir(source)
+ [s1, s2].each { |name| File.open(name, "w") { |file| file.puts "something" } }
- # We have to add a second parameter, because that's the only way to expose the "bug".
- file = Puppet::Type.newfile(:path => dest, :source => source, :recurse => true, :purge => true, :mode => "755")
+ # We have to add a second parameter, because that's the only way to expose the "bug".
+ file = Puppet::Type.newfile(:path => dest, :source => source, :recurse => true, :purge => true, :mode => "755")
- assert_apply(file)
+ assert_apply(file)
- assert(FileTest.exists?(d1), "File1 was not copied")
- assert(FileTest.exists?(d2), "File2 was not copied")
+ assert(FileTest.exists?(d1), "File1 was not copied")
+ assert(FileTest.exists?(d2), "File2 was not copied")
- File.unlink(s2)
+ File.unlink(s2)
- assert_apply(file)
+ assert_apply(file)
- assert(FileTest.exists?(d1), "File1 was not kept")
- assert(! FileTest.exists?(d2), "File2 was not purged")
- end
+ assert(FileTest.exists?(d1), "File1 was not kept")
+ assert(! FileTest.exists?(d2), "File2 was not purged")
+ end
end
diff --git a/test/ral/type/host.rb b/test/ral/type/host.rb
index d05d67c..1b5bb01 100755
--- a/test/ral/type/host.rb
+++ b/test/ral/type/host.rb
@@ -7,174 +7,174 @@ require 'test/unit'
require 'facter'
class TestHost < Test::Unit::TestCase
- include PuppetTest
+ include PuppetTest
- def setup
- super
- @hosttype = Puppet::Type.type(:host)
+ def setup
+ super
+ @hosttype = Puppet::Type.type(:host)
- @provider = @hosttype.defaultprovider
+ @provider = @hosttype.defaultprovider
- # Make sure they are using the parsed provider
- unless @provider.name == :parsed
- @hosttype.defaultprovider = @hosttype.provider(:parsed)
- end
+ # Make sure they are using the parsed provider
+ unless @provider.name == :parsed
+ @hosttype.defaultprovider = @hosttype.provider(:parsed)
+ end
- cleanup do @hosttype.defaultprovider = nil end
+ cleanup do @hosttype.defaultprovider = nil end
- if @provider.respond_to?(:default_target=)
- @default_file = @provider.default_target
- cleanup do
- @provider.default_target = @default_file
- end
- @target = tempfile
- @provider.default_target = @target
- end
+ if @provider.respond_to?(:default_target=)
+ @default_file = @provider.default_target
+ cleanup do
+ @provider.default_target = @default_file
+ end
+ @target = tempfile
+ @provider.default_target = @target
end
+ end
- def mkhost
- if defined?(@hcount)
- @hcount += 1
- else
- @hcount = 1
- end
+ def mkhost
+ if defined?(@hcount)
+ @hcount += 1
+ else
+ @hcount = 1
+ end
- @catalog ||= mk_catalog
+ @catalog ||= mk_catalog
- host = nil
- assert_nothing_raised {
+ host = nil
+ assert_nothing_raised {
- host = Puppet::Type.type(:host).new(
+ host = Puppet::Type.type(:host).new(
- :name => "fakehost#{@hcount}",
- :ip => "192.168.27.#{@hcount}",
- :alias => "alias#{@hcount}",
+ :name => "fakehost#{@hcount}",
+ :ip => "192.168.27.#{@hcount}",
+ :alias => "alias#{@hcount}",
- :catalog => @catalog
- )
- }
-
- host
- end
+ :catalog => @catalog
+ )
+ }
- def test_list
- list = nil
- assert_nothing_raised do
- list = @hosttype.defaultprovider.instances
- end
+ host
+ end
- assert_equal(0, list.length, "Found hosts in empty file somehow")
+ def test_list
+ list = nil
+ assert_nothing_raised do
+ list = @hosttype.defaultprovider.instances
end
+ assert_equal(0, list.length, "Found hosts in empty file somehow")
+ end
+
- def test_simplehost
- host = nil
+ def test_simplehost
+ host = nil
- assert_nothing_raised {
+ assert_nothing_raised {
- host = Puppet::Type.type(:host).new(
+ host = Puppet::Type.type(:host).new(
- :name => "culain",
+ :name => "culain",
- :ip => "192.168.0.3"
- )
- }
+ :ip => "192.168.0.3"
+ )
+ }
- current_values = nil
- assert_nothing_raised { current_values = host.retrieve }
- assert_events([:host_created], host)
+ current_values = nil
+ assert_nothing_raised { current_values = host.retrieve }
+ assert_events([:host_created], host)
- assert_nothing_raised { current_values = host.retrieve }
+ assert_nothing_raised { current_values = host.retrieve }
- assert_equal(:present, current_values[host.property(:ensure)])
+ assert_equal(:present, current_values[host.property(:ensure)])
- host[:ensure] = :absent
+ host[:ensure] = :absent
- assert_events([:host_removed], host)
+ assert_events([:host_removed], host)
- assert_nothing_raised { current_values = host.retrieve }
+ assert_nothing_raised { current_values = host.retrieve }
- assert_equal(:absent, current_values[host.property(:ensure)])
- end
+ assert_equal(:absent, current_values[host.property(:ensure)])
+ end
- def test_moddinghost
- host = mkhost
- cleanup do
- host[:ensure] = :absent
- assert_apply(host)
- end
+ def test_moddinghost
+ host = mkhost
+ cleanup do
+ host[:ensure] = :absent
+ assert_apply(host)
+ end
- assert_events([:host_created], host)
+ assert_events([:host_created], host)
- current_values = nil
- assert_nothing_raised {
- current_values = host.retrieve
- }
+ current_values = nil
+ assert_nothing_raised {
+ current_values = host.retrieve
+ }
- # This was a hard bug to track down.
- assert_instance_of(String, current_values[host.property(:ip)])
+ # This was a hard bug to track down.
+ assert_instance_of(String, current_values[host.property(:ip)])
- host[:ensure] = :absent
- assert_events([:host_removed], host)
- end
+ host[:ensure] = :absent
+ assert_events([:host_removed], host)
+ end
- def test_invalid_ipaddress
- host = mkhost
+ def test_invalid_ipaddress
+ host = mkhost
- assert_raise(Puppet::Error) {
- host[:ip] = "abc.def.ghi.jkl"
- }
- end
+ assert_raise(Puppet::Error) {
+ host[:ip] = "abc.def.ghi.jkl"
+ }
+ end
- def test_invalid_hostname
- host = mkhost
+ def test_invalid_hostname
+ host = mkhost
- assert_raise(Puppet::Error) {
- host[:name] = "!invalid.hostname.$PID$"
- }
+ assert_raise(Puppet::Error) {
+ host[:name] = "!invalid.hostname.$PID$"
+ }
- assert_raise(Puppet::Error) {
- host[:name] = "-boo"
- }
+ assert_raise(Puppet::Error) {
+ host[:name] = "-boo"
+ }
- assert_raise(Puppet::Error) {
- host[:name] = "boo-.ness"
- }
+ assert_raise(Puppet::Error) {
+ host[:name] = "boo-.ness"
+ }
- assert_raise(Puppet::Error) {
- host[:name] = "boo..ness"
- }
- end
+ assert_raise(Puppet::Error) {
+ host[:name] = "boo..ness"
+ }
+ end
- def test_valid_hostname
- host = mkhost
+ def test_valid_hostname
+ host = mkhost
- assert_nothing_raised {
- host[:name] = "yayness"
- }
+ assert_nothing_raised {
+ host[:name] = "yayness"
+ }
- assert_nothing_raised {
- host[:name] = "yay-ness"
- }
+ assert_nothing_raised {
+ host[:name] = "yay-ness"
+ }
- assert_nothing_raised {
- host[:name] = "yay.ness"
- }
+ assert_nothing_raised {
+ host[:name] = "yay.ness"
+ }
- assert_nothing_raised {
- host[:name] = "yay.ne-ss"
- }
+ assert_nothing_raised {
+ host[:name] = "yay.ne-ss"
+ }
- assert_nothing_raised {
- host[:name] = "y.ay-ne-ss.com"
- }
+ assert_nothing_raised {
+ host[:name] = "y.ay-ne-ss.com"
+ }
- assert_nothing_raised {
- host[:name] = "y4y.n3-ss"
- }
+ assert_nothing_raised {
+ host[:name] = "y4y.n3-ss"
+ }
- assert_nothing_raised {
- host[:name] = "y"
- }
- end
+ assert_nothing_raised {
+ host[:name] = "y"
+ }
+ end
end
diff --git a/test/ral/type/mailalias.rb b/test/ral/type/mailalias.rb
index 4d98a8f..634ff2a 100755
--- a/test/ral/type/mailalias.rb
+++ b/test/ral/type/mailalias.rb
@@ -6,40 +6,40 @@ require 'puppettest'
require 'mocha'
class TestMailAlias < Test::Unit::TestCase
- include PuppetTest
+ include PuppetTest
- def setup
- super
- @type = Puppet::Type.type(:mailalias)
+ def setup
+ super
+ @type = Puppet::Type.type(:mailalias)
- @provider = @type.defaultprovider
+ @provider = @type.defaultprovider
- # Make sure they are using the parsed provider
- unless @provider.name == :aliases
- @type.defaultprovider = @type.provider(:aliases)
- end
+ # Make sure they are using the parsed provider
+ unless @provider.name == :aliases
+ @type.defaultprovider = @type.provider(:aliases)
+ end
- cleanup do @type.defaultprovider = nil end
+ cleanup do @type.defaultprovider = nil end
- if @provider.respond_to?(:default_target=)
- @default_file = @provider.default_target
- cleanup do
- @provider.default_target = @default_file
- end
- @target = tempfile
- @provider.default_target = @target
- end
+ if @provider.respond_to?(:default_target=)
+ @default_file = @provider.default_target
+ cleanup do
+ @provider.default_target = @default_file
+ end
+ @target = tempfile
+ @provider.default_target = @target
end
-
- # This isn't much of a test, but then, it's not much of a type.
- def test_recipient_arrays
- resource = @type.new(:name => "luke", :recipient => "yay", :target => tempfile)
- values = resource.retrieve_resource
- assert_equal(:absent, values[:recipient])
- resource.property(:recipient).expects(:set).with(%w{yay})
- assert_nothing_raised("Could not sync mailalias") do
- resource.property(:recipient).sync
- end
+ end
+
+ # This isn't much of a test, but then, it's not much of a type.
+ def test_recipient_arrays
+ resource = @type.new(:name => "luke", :recipient => "yay", :target => tempfile)
+ values = resource.retrieve_resource
+ assert_equal(:absent, values[:recipient])
+ resource.property(:recipient).expects(:set).with(%w{yay})
+ assert_nothing_raised("Could not sync mailalias") do
+ resource.property(:recipient).sync
end
+ end
end
diff --git a/test/ral/type/resources.rb b/test/ral/type/resources.rb
index d6c6c60..f36df7f 100755
--- a/test/ral/type/resources.rb
+++ b/test/ral/type/resources.rb
@@ -8,101 +8,101 @@ require File.dirname(__FILE__) + '/../../lib/puppettest'
require 'puppettest'
class TestResources < Test::Unit::TestCase
- include PuppetTest
-
- def add_purge_lister
- # Now define the list method
- class << @purgetype
- def instances
- $purgemembers.values
- end
- end
- end
-
- def mk_purger(managed = false)
- @purgenum ||= 0
- @purgenum += 1
- obj = @purgetype.create :name => "purger#{@purgenum}"
- $purgemembers[obj[:name]] = obj
- obj[:fake] = "testing" if managed
- obj
+ include PuppetTest
+
+ def add_purge_lister
+ # Now define the list method
+ class << @purgetype
+ def instances
+ $purgemembers.values
+ end
end
-
- def mkpurgertype
- # Create a purgeable type
- $purgemembers = {}
- @purgetype = Puppet::Type.newtype(:purgetest) do
- newparam(:name, :namevar => true) {}
- newproperty(:ensure) do
- newvalue(:absent) do
- $purgemembers[@parent[:name]] = @parent
- end
- newvalue(:present) do
- $purgemembers.delete(@parent[:name])
- end
- end
- newproperty(:fake) do
- def sync
- :faked
- end
- end
+ end
+
+ def mk_purger(managed = false)
+ @purgenum ||= 0
+ @purgenum += 1
+ obj = @purgetype.create :name => "purger#{@purgenum}"
+ $purgemembers[obj[:name]] = obj
+ obj[:fake] = "testing" if managed
+ obj
+ end
+
+ def mkpurgertype
+ # Create a purgeable type
+ $purgemembers = {}
+ @purgetype = Puppet::Type.newtype(:purgetest) do
+ newparam(:name, :namevar => true) {}
+ newproperty(:ensure) do
+ newvalue(:absent) do
+ $purgemembers[@parent[:name]] = @parent
end
- cleanup do
- Puppet::Type.rmtype(:purgetest)
+ newvalue(:present) do
+ $purgemembers.delete(@parent[:name])
end
+ end
+ newproperty(:fake) do
+ def sync
+ :faked
+ end
+ end
end
-
- def setup
- super
- @type = Puppet::Type.type(:resources)
+ cleanup do
+ Puppet::Type.rmtype(:purgetest)
end
-
- # Part of #408.
- def test_check
- # First check a non-user
- res = Puppet::Type.type(:resources).new :name => :package
- assert_nil(res[:unless_system_user], "got bad default for package")
-
-
- assert_nothing_raised {
- assert(res.check("A String"), "String failed check")
- assert(res.check(Puppet::Type.type(:file).new(:path => tempfile)), "File failed check")
- assert(res.check(Puppet::Type.type(:user).new(:name => "yayness")), "User failed check in package")
- }
-
- # Now create a user manager
- res = Puppet::Type.type(:resources).new :name => :user
-
- # Make sure the default is 500
- assert_equal(500, res[:unless_system_user], "got bad default")
-
- # Now make sure root fails the test
- @user = Puppet::Type.type(:user)
- assert_nothing_raised {
- assert(! res.check(@user.create(:name => "root")), "root passed check")
- assert(! res.check(@user.create(:name => "nobody")), "nobody passed check")
- }
-
- # Now find a user between 0 and the limit
- low = high = nil
- Etc.passwd { |entry|
- if ! low and (entry.uid > 10 and entry.uid < 500)
- low = entry.name
- else
- # We'll reset the limit, since we can't really guarantee that
- # there are any users with uid > 500
- if ! high and entry.uid > 100 and ! res.system_users.include?(entry.name)
- high = entry.name
- break
- end
- end
- }
-
- assert(! res.check(@user.create(:name => low)), "low user #{low} passed check") if low
- if high
- res[:unless_system_user] = 50
- assert(res.check(@user.create(:name => high)), "high user #{high} failed check")
+ end
+
+ def setup
+ super
+ @type = Puppet::Type.type(:resources)
+ end
+
+ # Part of #408.
+ def test_check
+ # First check a non-user
+ res = Puppet::Type.type(:resources).new :name => :package
+ assert_nil(res[:unless_system_user], "got bad default for package")
+
+
+ assert_nothing_raised {
+ assert(res.check("A String"), "String failed check")
+ assert(res.check(Puppet::Type.type(:file).new(:path => tempfile)), "File failed check")
+ assert(res.check(Puppet::Type.type(:user).new(:name => "yayness")), "User failed check in package")
+ }
+
+ # Now create a user manager
+ res = Puppet::Type.type(:resources).new :name => :user
+
+ # Make sure the default is 500
+ assert_equal(500, res[:unless_system_user], "got bad default")
+
+ # Now make sure root fails the test
+ @user = Puppet::Type.type(:user)
+ assert_nothing_raised {
+ assert(! res.check(@user.create(:name => "root")), "root passed check")
+ assert(! res.check(@user.create(:name => "nobody")), "nobody passed check")
+ }
+
+ # Now find a user between 0 and the limit
+ low = high = nil
+ Etc.passwd { |entry|
+ if ! low and (entry.uid > 10 and entry.uid < 500)
+ low = entry.name
+ else
+ # We'll reset the limit, since we can't really guarantee that
+ # there are any users with uid > 500
+ if ! high and entry.uid > 100 and ! res.system_users.include?(entry.name)
+ high = entry.name
+ break
end
+ end
+ }
+
+ assert(! res.check(@user.create(:name => low)), "low user #{low} passed check") if low
+ if high
+ res[:unless_system_user] = 50
+ assert(res.check(@user.create(:name => high)), "high user #{high} failed check")
end
+ end
end
diff --git a/test/ral/type/service.rb b/test/ral/type/service.rb
index d12a94c..9e64690 100755
--- a/test/ral/type/service.rb
+++ b/test/ral/type/service.rb
@@ -6,33 +6,33 @@ require 'puppettest'
require 'mocha'
class TestServiceType < Test::Unit::TestCase
- include PuppetTest
+ include PuppetTest
- # #199
- def test_no_refresh_when_starting
- service = Puppet::Type.type(:service).new :name => "hopefully_this_isnt_in_the_process_table",
- :ensure => :running, :provider => :base
+ # #199
+ def test_no_refresh_when_starting
+ service = Puppet::Type.type(:service).new :name => "hopefully_this_isnt_in_the_process_table",
+ :ensure => :running, :provider => :base
- assert_equal :running, service.instance_eval('@parameters[:ensure]').should
- assert_not_equal :running, service.instance_eval('@parameters[:ensure]').retrieve, "You have something called #{service.name} in your process table"
+ assert_equal :running, service.instance_eval('@parameters[:ensure]').should
+ assert_not_equal :running, service.instance_eval('@parameters[:ensure]').retrieve, "You have something called #{service.name} in your process table"
- # First make sure it does not refresh
- service.provider.expects(:restart).never
+ # First make sure it does not refresh
+ service.provider.expects(:restart).never
- assert_nothing_raised do
- service.refresh
- end
+ assert_nothing_raised do
+ service.refresh
end
+ end
- def test_refresh_normally
- service = Puppet::Type.type(:service).new :name => "testing",
- :ensure => :running, :provider => :base, :status => "cat /dev/null"
+ def test_refresh_normally
+ service = Puppet::Type.type(:service).new :name => "testing",
+ :ensure => :running, :provider => :base, :status => "cat /dev/null"
- service.provider.expects(:restart)
+ service.provider.expects(:restart)
- assert_nothing_raised do
- service.refresh
- end
+ assert_nothing_raised do
+ service.refresh
end
+ end
end
diff --git a/test/ral/type/sshkey.rb b/test/ral/type/sshkey.rb
index a23ddf1..725f188 100755
--- a/test/ral/type/sshkey.rb
+++ b/test/ral/type/sshkey.rb
@@ -6,143 +6,143 @@ require 'puppettest'
require 'facter'
class TestSSHKey < Test::Unit::TestCase
- include PuppetTest
- def setup
- super
- # god i'm lazy
- @sshkeytype = Puppet::Type.type(:sshkey)
-
- @provider = @sshkeytype.defaultprovider
-
- # Make sure they are using the parsed provider
- unless @provider.name == :parsed
- @sshkeytype.defaultprovider = @sshkeytype.provider(:parsed)
- end
-
- cleanup do @sshkeytype.defaultprovider = nil end
-
- if @provider.respond_to?(:default_target)
- oldpath = @provider.default_target
- cleanup do
- @provider.default_target = oldpath
- end
- @provider.default_target = tempfile
- end
- end
-
- def teardown
- super
- @provider.clear if @provider.respond_to?(:clear)
- end
-
- def mkkey
- key = nil
+ include PuppetTest
+ def setup
+ super
+ # god i'm lazy
+ @sshkeytype = Puppet::Type.type(:sshkey)
- if defined?(@kcount)
- @kcount += 1
- else
- @kcount = 1
- end
+ @provider = @sshkeytype.defaultprovider
- @catalog ||= mk_catalog
-
-
- key = @sshkeytype.new(
-
- :name => "host#{@kcount}.madstop.com",
- :key => "#{@kcount}AAAAB3NzaC1kc3MAAACBAMnhSiku76y3EGkNCDsUlvpO8tRgS9wL4Eh54WZfQ2lkxqfd2uT/RTT9igJYDtm/+UHuBRdNGpJYW1Nw2i2JUQgQEEuitx4QKALJrBotejGOAWxxVk6xsh9xA0OW8Q3ZfuX2DDitfeC8ZTCl4xodUMD8feLtP+zEf8hxaNamLlt/AAAAFQDYJyf3vMCWRLjTWnlxLtOyj/bFpwAAAIEAmRxxXb4jjbbui9GYlZAHK00689DZuX0EabHNTl2yGO5KKxGC6Esm7AtjBd+onfu4Rduxut3jdI8GyQCIW8WypwpJofCIyDbTUY4ql0AQUr3JpyVytpnMijlEyr41FfIb4tnDqnRWEsh2H7N7peW+8DWZHDFnYopYZJ9Yu4/jHRYAAACAERG50e6aRRb43biDr7Ab9NUCgM9bC0SQscI/xdlFjac0B/kSWJYTGVARWBDWug705hTnlitY9cLC5Ey/t/OYOjylTavTEfd/bh/8FkAYO+pWdW3hx6p97TBffK0b6nrc6OORT2uKySbbKOn0681nNQh4a6ueR3JRppNkRPnTk5c=",
- :type => "ssh-dss",
- :alias => ["192.168.0.#{@kcount}"],
-
- :catalog => @catalog
- )
+ # Make sure they are using the parsed provider
+ unless @provider.name == :parsed
+ @sshkeytype.defaultprovider = @sshkeytype.provider(:parsed)
+ end
- @catalog.add_resource(key)
+ cleanup do @sshkeytype.defaultprovider = nil end
- key
+ if @provider.respond_to?(:default_target)
+ oldpath = @provider.default_target
+ cleanup do
+ @provider.default_target = oldpath
+ end
+ @provider.default_target = tempfile
end
+ end
- def test_instances
- list = nil
- assert_nothing_raised {
- list = Puppet::Type.type(:sshkey).instances
- }
+ def teardown
+ super
+ @provider.clear if @provider.respond_to?(:clear)
+ end
- count = 0
- list.each do |h|
- count += 1
- end
+ def mkkey
+ key = nil
- assert_equal(0, count, "Found sshkeys in empty file somehow")
+ if defined?(@kcount)
+ @kcount += 1
+ else
+ @kcount = 1
end
- def test_simplekey
- key = mkkey
- file = tempfile
- key[:target] = file
- key[:provider] = :parsed
-
- assert_apply(key)
+ @catalog ||= mk_catalog
- assert_events([], key, "created events on in-sync key")
- assert(key.provider.exists?, "Key did not get created")
-
- # Now create a new key object
- name = key.name
- key = nil
+ key = @sshkeytype.new(
+
+ :name => "host#{@kcount}.madstop.com",
+ :key => "#{@kcount}AAAAB3NzaC1kc3MAAACBAMnhSiku76y3EGkNCDsUlvpO8tRgS9wL4Eh54WZfQ2lkxqfd2uT/RTT9igJYDtm/+UHuBRdNGpJYW1Nw2i2JUQgQEEuitx4QKALJrBotejGOAWxxVk6xsh9xA0OW8Q3ZfuX2DDitfeC8ZTCl4xodUMD8feLtP+zEf8hxaNamLlt/AAAAFQDYJyf3vMCWRLjTWnlxLtOyj/bFpwAAAIEAmRxxXb4jjbbui9GYlZAHK00689DZuX0EabHNTl2yGO5KKxGC6Esm7AtjBd+onfu4Rduxut3jdI8GyQCIW8WypwpJofCIyDbTUY4ql0AQUr3JpyVytpnMijlEyr41FfIb4tnDqnRWEsh2H7N7peW+8DWZHDFnYopYZJ9Yu4/jHRYAAACAERG50e6aRRb43biDr7Ab9NUCgM9bC0SQscI/xdlFjac0B/kSWJYTGVARWBDWug705hTnlitY9cLC5Ey/t/OYOjylTavTEfd/bh/8FkAYO+pWdW3hx6p97TBffK0b6nrc6OORT2uKySbbKOn0681nNQh4a6ueR3JRppNkRPnTk5c=",
+ :type => "ssh-dss",
+ :alias => ["192.168.0.#{@kcount}"],
+
+ :catalog => @catalog
+ )
- key = @sshkeytype.new :name => name, :target => file, :provider => :parsed
- key.retrieve
+ @catalog.add_resource(key)
- assert(key.provider.exists?, "key thinks it does not exist")
+ key
+ end
- end
+ def test_instances
+ list = nil
+ assert_nothing_raised {
+ list = Puppet::Type.type(:sshkey).instances
+ }
- def test_removal
- sshkey = mkkey
- assert_nothing_raised {
- sshkey[:ensure] = :present
- }
- assert_events([:sshkey_created], sshkey)
-
- assert(sshkey.provider.exists?, "key was not created")
- assert_nothing_raised {
- sshkey[:ensure] = :absent
- }
-
- assert_events([:sshkey_removed], sshkey)
- assert(! sshkey.provider.exists?, "Key was not deleted")
- assert_events([], sshkey)
+ count = 0
+ list.each do |h|
+ count += 1
end
- # Make sure changes actually modify the file.
- def test_modifyingfile
- keys = []
- names = []
- 3.times {
- k = mkkey
- #h[:ensure] = :present
- #h.retrieve
- keys << k
- names << k.name
- }
- assert_apply(*keys)
- keys.clear
-
- @catalog.clear(true)
- @catalog = nil
-
- newkey = mkkey
- #newkey[:ensure] = :present
- names << newkey.name
- assert_apply(newkey)
-
- # Verify we can retrieve that info
- assert_nothing_raised("Could not retrieve after second write") {
- newkey.provider.prefetch
- }
-
- assert(newkey.provider.exists?, "Did not see key in file")
- end
+ assert_equal(0, count, "Found sshkeys in empty file somehow")
+ end
+
+ def test_simplekey
+ key = mkkey
+ file = tempfile
+ key[:target] = file
+ key[:provider] = :parsed
+
+ assert_apply(key)
+
+ assert_events([], key, "created events on in-sync key")
+
+ assert(key.provider.exists?, "Key did not get created")
+
+ # Now create a new key object
+ name = key.name
+ key = nil
+
+ key = @sshkeytype.new :name => name, :target => file, :provider => :parsed
+ key.retrieve
+
+ assert(key.provider.exists?, "key thinks it does not exist")
+
+ end
+
+ def test_removal
+ sshkey = mkkey
+ assert_nothing_raised {
+ sshkey[:ensure] = :present
+ }
+ assert_events([:sshkey_created], sshkey)
+
+ assert(sshkey.provider.exists?, "key was not created")
+ assert_nothing_raised {
+ sshkey[:ensure] = :absent
+ }
+
+ assert_events([:sshkey_removed], sshkey)
+ assert(! sshkey.provider.exists?, "Key was not deleted")
+ assert_events([], sshkey)
+ end
+
+ # Make sure changes actually modify the file.
+ def test_modifyingfile
+ keys = []
+ names = []
+ 3.times {
+ k = mkkey
+ #h[:ensure] = :present
+ #h.retrieve
+ keys << k
+ names << k.name
+ }
+ assert_apply(*keys)
+ keys.clear
+
+ @catalog.clear(true)
+ @catalog = nil
+
+ newkey = mkkey
+ #newkey[:ensure] = :present
+ names << newkey.name
+ assert_apply(newkey)
+
+ # Verify we can retrieve that info
+ assert_nothing_raised("Could not retrieve after second write") {
+ newkey.provider.prefetch
+ }
+
+ assert(newkey.provider.exists?, "Did not see key in file")
+ end
end
diff --git a/test/ral/type/user.rb b/test/ral/type/user.rb
index 9927d70..dee6a91 100755
--- a/test/ral/type/user.rb
+++ b/test/ral/type/user.rb
@@ -6,162 +6,162 @@ require 'puppettest'
require 'etc'
class TestUser < Test::Unit::TestCase
- include PuppetTest
-
- p = Puppet::Type.type(:user).provide :fake, :parent => PuppetTest::FakeProvider do
- @name = :fake
- apimethods
- def create
- @ensure = :present
- @resource.send(:properties).each do |property|
- next if property.name == :ensure
- property.sync
- end
- end
+ include PuppetTest
+
+ p = Puppet::Type.type(:user).provide :fake, :parent => PuppetTest::FakeProvider do
+ @name = :fake
+ apimethods
+ def create
+ @ensure = :present
+ @resource.send(:properties).each do |property|
+ next if property.name == :ensure
+ property.sync
+ end
+ end
- def delete
- @ensure = :absent
- @resource.send(:properties).each do |property|
- send(property.name.to_s + "=", :absent)
- end
- end
+ def delete
+ @ensure = :absent
+ @resource.send(:properties).each do |property|
+ send(property.name.to_s + "=", :absent)
+ end
+ end
- def exists?
- if @ensure == :present
- true
- else
- false
- end
- end
+ def exists?
+ if @ensure == :present
+ true
+ else
+ false
+ end
end
+ end
- FakeUserProvider = p
+ FakeUserProvider = p
- @@fakeproviders[:group] = p
+ @@fakeproviders[:group] = p
- def findshell(old = nil)
- %w{/bin/sh /bin/bash /sbin/sh /bin/ksh /bin/zsh /bin/csh /bin/tcsh
- /usr/bin/sh /usr/bin/bash /usr/bin/ksh /usr/bin/zsh /usr/bin/csh
- /usr/bin/tcsh}.find { |shell|
- if old
- FileTest.exists?(shell) and shell != old
- else
- FileTest.exists?(shell)
- end
- }
- end
+ def findshell(old = nil)
+ %w{/bin/sh /bin/bash /sbin/sh /bin/ksh /bin/zsh /bin/csh /bin/tcsh
+ /usr/bin/sh /usr/bin/bash /usr/bin/ksh /usr/bin/zsh /usr/bin/csh
+ /usr/bin/tcsh}.find { |shell|
+ if old
+ FileTest.exists?(shell) and shell != old
+ else
+ FileTest.exists?(shell)
+ end
+ }
+ end
- def setup
- super
- Puppet::Type.type(:user).defaultprovider = FakeUserProvider
- end
+ def setup
+ super
+ Puppet::Type.type(:user).defaultprovider = FakeUserProvider
+ end
- def teardown
- Puppet::Type.type(:user).defaultprovider = nil
- super
- end
+ def teardown
+ Puppet::Type.type(:user).defaultprovider = nil
+ super
+ end
- def mkuser(name)
- user = nil
- assert_nothing_raised {
+ def mkuser(name)
+ user = nil
+ assert_nothing_raised {
- user = Puppet::Type.type(:user).new(
+ user = Puppet::Type.type(:user).new(
- :name => name,
- :comment => "Puppet Testing User",
- :gid => Puppet::Util::SUIDManager.gid,
- :shell => findshell,
+ :name => name,
+ :comment => "Puppet Testing User",
+ :gid => Puppet::Util::SUIDManager.gid,
+ :shell => findshell,
- :home => "/home/#{name}"
- )
- }
+ :home => "/home/#{name}"
+ )
+ }
- assert(user, "Did not create user")
+ assert(user, "Did not create user")
- user
- end
+ user
+ end
- def test_autorequire
- file = tempfile
- comp = nil
- user = nil
- group =nil
- home = nil
- ogroup = nil
- assert_nothing_raised {
+ def test_autorequire
+ file = tempfile
+ comp = nil
+ user = nil
+ group =nil
+ home = nil
+ ogroup = nil
+ assert_nothing_raised {
- user = Puppet::Type.type(:user).new(
+ user = Puppet::Type.type(:user).new(
- :name => "pptestu",
- :home => file,
- :gid => "pptestg",
+ :name => "pptestu",
+ :home => file,
+ :gid => "pptestg",
- :groups => "yayness"
- )
+ :groups => "yayness"
+ )
- home = Puppet::Type.type(:file).new(
+ home = Puppet::Type.type(:file).new(
- :path => file,
- :owner => "pptestu",
+ :path => file,
+ :owner => "pptestu",
- :ensure => "directory"
- )
- group = Puppet::Type.type(:group).new(
- :name => "pptestg"
- )
- ogroup = Puppet::Type.type(:group).new(
- :name => "yayness"
- )
- comp = mk_catalog(user, group, home, ogroup)
- }
-
- rels = nil
- assert_nothing_raised { rels = user.autorequire }
-
- assert(rels.detect { |r| r.source == group }, "User did not require group")
- assert(rels.detect { |r| r.source == ogroup }, "User did not require other groups")
- assert_nothing_raised { rels = home.autorequire }
- assert(rels.detect { |r| r.source == user }, "Homedir did not require user")
+ :ensure => "directory"
+ )
+ group = Puppet::Type.type(:group).new(
+ :name => "pptestg"
+ )
+ ogroup = Puppet::Type.type(:group).new(
+ :name => "yayness"
+ )
+ comp = mk_catalog(user, group, home, ogroup)
+ }
+
+ rels = nil
+ assert_nothing_raised { rels = user.autorequire }
+
+ assert(rels.detect { |r| r.source == group }, "User did not require group")
+ assert(rels.detect { |r| r.source == ogroup }, "User did not require other groups")
+ assert_nothing_raised { rels = home.autorequire }
+ assert(rels.detect { |r| r.source == user }, "Homedir did not require user")
+ end
+
+ # Testing #455
+ def test_autorequire_with_no_group_should
+ user = Puppet::Type.type(:user).new(:name => "yaytest", :check => :all)
+ catalog = mk_catalog(user)
+
+ assert_nothing_raised do
+ user.autorequire
end
- # Testing #455
- def test_autorequire_with_no_group_should
- user = Puppet::Type.type(:user).new(:name => "yaytest", :check => :all)
- catalog = mk_catalog(user)
+ user[:ensure] = :absent
- assert_nothing_raised do
- user.autorequire
- end
-
- user[:ensure] = :absent
+ assert(user.property(:groups).insync?(nil),
+ "Groups state considered out of sync with no :should value")
+ end
- assert(user.property(:groups).insync?(nil),
- "Groups state considered out of sync with no :should value")
- end
+ # Make sure the 'managehome' param can only be set when the provider
+ # has that feature. Uses a patch from #432.
+ def test_managehome
+ user = Puppet::Type.type(:user).new(:name => "yaytest", :check => :all)
- # Make sure the 'managehome' param can only be set when the provider
- # has that feature. Uses a patch from #432.
- def test_managehome
- user = Puppet::Type.type(:user).new(:name => "yaytest", :check => :all)
+ prov = user.provider
- prov = user.provider
+ home = false
+ prov.class.meta_def(:manages_homedir?) { home }
- home = false
- prov.class.meta_def(:manages_homedir?) { home }
-
- assert_nothing_raised("failed on false managehome") do
- user[:managehome] = false
- end
+ assert_nothing_raised("failed on false managehome") do
+ user[:managehome] = false
+ end
- assert_raise(Puppet::Error, "did not fail when managehome? is false") do
- user[:managehome] = true
- end
+ assert_raise(Puppet::Error, "did not fail when managehome? is false") do
+ user[:managehome] = true
+ end
- home = true
- assert(prov.class.manages_homedir?, "provider did not enable homedir")
- assert_nothing_raised("failed when managehome is true") do
- user[:managehome] = true
- end
+ home = true
+ assert(prov.class.manages_homedir?, "provider did not enable homedir")
+ assert_nothing_raised("failed when managehome is true") do
+ user[:managehome] = true
end
+ end
end
diff --git a/test/ral/type/yumrepo.rb b/test/ral/type/yumrepo.rb
index 5469ae4..bbc1562 100755
--- a/test/ral/type/yumrepo.rb
+++ b/test/ral/type/yumrepo.rb
@@ -6,102 +6,102 @@ require 'puppettest'
require 'fileutils'
class TestYumRepo < Test::Unit::TestCase
- include PuppetTest
-
- def setup
- super
- @yumdir = tempfile
- Dir.mkdir(@yumdir)
- @yumconf = File.join(@yumdir, "yum.conf")
- File.open(@yumconf, "w") do |f|
- f.print "[main]\nreposdir=#{@yumdir} /no/such/dir\n"
- end
- Puppet::Type.type(:yumrepo).yumconf = @yumconf
-
- # It needs to be reset each time, otherwise the cache is used.
- Puppet::Type.type(:yumrepo).inifile = nil
+ include PuppetTest
+
+ def setup
+ super
+ @yumdir = tempfile
+ Dir.mkdir(@yumdir)
+ @yumconf = File.join(@yumdir, "yum.conf")
+ File.open(@yumconf, "w") do |f|
+ f.print "[main]\nreposdir=#{@yumdir} /no/such/dir\n"
end
-
- # Modify one existing section
- def test_modify
- copy_datafiles
- devel = make_repo("development", { :descr => "New description" })
- current_values = devel.retrieve
-
- assert_equal("development", devel[:name])
- assert_equal('Fedora Core $releasever - Development Tree', current_values[devel.property(:descr)])
- assert_equal('New description', devel.property(:descr).should)
- assert_apply(devel)
-
- inifile = Puppet::Type.type(:yumrepo).read
- assert_equal('New description', inifile['development']['name'])
- assert_equal('Fedora Core $releasever - $basearch - Base', inifile['base']['name'])
- assert_equal("foo\n bar\n baz", inifile['base']['exclude'])
- assert_equal(['base', 'development', 'main'], all_sections(inifile))
- end
-
- # Create a new section
- def test_create
- values = {
- :descr => "Fedora Core $releasever - $basearch - Base",
- :baseurl => "http://example.com/yum/$releasever/$basearch/os/",
- :enabled => "1",
- :gpgcheck => "1",
- :includepkgs => "absent",
- :gpgkey => "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora",
- :proxy => "http://proxy.example.com:80/",
- :proxy_username => "username",
- :proxy_password => "password"
- }
- repo = make_repo("base", values)
-
- assert_apply(repo)
- inifile = Puppet::Type.type(:yumrepo).read
- sections = all_sections(inifile)
- assert_equal(['base', 'main'], sections)
- text = inifile["base"].format
- assert_equal(CREATE_EXP, text)
- end
-
- # Delete mirrorlist by setting it to :absent and enable baseurl
- def test_absent
- copy_datafiles
- baseurl = 'http://example.com/'
-
- devel = make_repo(
- "development",
- { :mirrorlist => 'absent',
-
- :baseurl => baseurl })
- devel.retrieve
- assert_apply(devel)
- inifile = Puppet::Type.type(:yumrepo).read
- sec = inifile["development"]
- assert_nil(sec["mirrorlist"])
- assert_equal(baseurl, sec["baseurl"])
- end
-
- def make_repo(name, hash={})
- hash[:name] = name
- Puppet::Type.type(:yumrepo).new(hash)
- end
-
- def all_sections(inifile)
- sections = []
- inifile.each_section { |section| sections << section.name }
- sections.sort
- end
-
- def copy_datafiles
- fakedata("data/types/yumrepos").select { |file|
- file =~ /\.repo$/
- }.each { |src|
- dst = File::join(@yumdir, File::basename(src))
- FileUtils::copy(src, dst)
- }
- end
-
- CREATE_EXP = <<'EOF'
+ Puppet::Type.type(:yumrepo).yumconf = @yumconf
+
+ # It needs to be reset each time, otherwise the cache is used.
+ Puppet::Type.type(:yumrepo).inifile = nil
+ end
+
+ # Modify one existing section
+ def test_modify
+ copy_datafiles
+ devel = make_repo("development", { :descr => "New description" })
+ current_values = devel.retrieve
+
+ assert_equal("development", devel[:name])
+ assert_equal('Fedora Core $releasever - Development Tree', current_values[devel.property(:descr)])
+ assert_equal('New description', devel.property(:descr).should)
+ assert_apply(devel)
+
+ inifile = Puppet::Type.type(:yumrepo).read
+ assert_equal('New description', inifile['development']['name'])
+ assert_equal('Fedora Core $releasever - $basearch - Base', inifile['base']['name'])
+ assert_equal("foo\n bar\n baz", inifile['base']['exclude'])
+ assert_equal(['base', 'development', 'main'], all_sections(inifile))
+ end
+
+ # Create a new section
+ def test_create
+ values = {
+ :descr => "Fedora Core $releasever - $basearch - Base",
+ :baseurl => "http://example.com/yum/$releasever/$basearch/os/",
+ :enabled => "1",
+ :gpgcheck => "1",
+ :includepkgs => "absent",
+ :gpgkey => "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora",
+ :proxy => "http://proxy.example.com:80/",
+ :proxy_username => "username",
+ :proxy_password => "password"
+ }
+ repo = make_repo("base", values)
+
+ assert_apply(repo)
+ inifile = Puppet::Type.type(:yumrepo).read
+ sections = all_sections(inifile)
+ assert_equal(['base', 'main'], sections)
+ text = inifile["base"].format
+ assert_equal(CREATE_EXP, text)
+ end
+
+ # Delete mirrorlist by setting it to :absent and enable baseurl
+ def test_absent
+ copy_datafiles
+ baseurl = 'http://example.com/'
+
+ devel = make_repo(
+ "development",
+ { :mirrorlist => 'absent',
+
+ :baseurl => baseurl })
+ devel.retrieve
+ assert_apply(devel)
+ inifile = Puppet::Type.type(:yumrepo).read
+ sec = inifile["development"]
+ assert_nil(sec["mirrorlist"])
+ assert_equal(baseurl, sec["baseurl"])
+ end
+
+ def make_repo(name, hash={})
+ hash[:name] = name
+ Puppet::Type.type(:yumrepo).new(hash)
+ end
+
+ def all_sections(inifile)
+ sections = []
+ inifile.each_section { |section| sections << section.name }
+ sections.sort
+ end
+
+ def copy_datafiles
+ fakedata("data/types/yumrepos").select { |file|
+ file =~ /\.repo$/
+ }.each { |src|
+ dst = File::join(@yumdir, File::basename(src))
+ FileUtils::copy(src, dst)
+ }
+ end
+
+ CREATE_EXP = <<'EOF'
[base]
name=Fedora Core $releasever - $basearch - Base
baseurl=http://example.com/yum/$releasever/$basearch/os/
diff --git a/test/ral/type/zone.rb b/test/ral/type/zone.rb
index 2144016..59de990 100755
--- a/test/ral/type/zone.rb
+++ b/test/ral/type/zone.rb
@@ -6,152 +6,152 @@ require 'puppettest'
require 'puppet/type/zone'
class TestZone < PuppetTest::TestCase
- confine "Zones are only functional on Solaris" => (Facter["operatingsystem"].value == "Solaris")
+ confine "Zones are only functional on Solaris" => (Facter["operatingsystem"].value == "Solaris")
- def setup
- super
- @@zones = []
- end
-
- def mkzone(name)
- zone = nil
+ def setup
+ super
+ @@zones = []
+ end
- base = tempfile
- Dir.mkdir(base)
- File.chmod(0700, base)
- root = File.join(base, "zonebase")
- assert_nothing_raised {
+ def mkzone(name)
+ zone = nil
- zone = Puppet::Type.type(:zone).new(
+ base = tempfile
+ Dir.mkdir(base)
+ File.chmod(0700, base)
+ root = File.join(base, "zonebase")
+ assert_nothing_raised {
- :name => name,
- :path => root,
+ zone = Puppet::Type.type(:zone).new(
- :ensure => "configured" # don't want to install zones automatically
- )
- }
+ :name => name,
+ :path => root,
- @@zones << name
+ :ensure => "configured" # don't want to install zones automatically
+ )
+ }
- zone
- end
+ @@zones << name
- def test_instances
- list = nil
- assert_nothing_raised {
- list = Puppet::Type.type(:zone).instances
- }
+ zone
+ end
- assert(! list.empty?, "Got no zones back")
+ def test_instances
+ list = nil
+ assert_nothing_raised {
+ list = Puppet::Type.type(:zone).instances
+ }
- assert(list.find { |z| z[:name] == "global" }, "Could not find global zone")
- end
+ assert(! list.empty?, "Got no zones back")
- def test_state_sequence
- zone = mkzone("slicetest")
+ assert(list.find { |z| z[:name] == "global" }, "Could not find global zone")
+ end
- property = zone.property(:ensure)
+ def test_state_sequence
+ zone = mkzone("slicetest")
- slice = nil
- assert_nothing_raised {
- slice = property.class.state_sequence(:absent, :installed).collect do |o|
- o[:name]
- end
- }
+ property = zone.property(:ensure)
+ slice = nil
+ assert_nothing_raised {
+ slice = property.class.state_sequence(:absent, :installed).collect do |o|
+ o[:name]
+ end
+ }
- assert_equal([:configured, :installed], slice)
- assert_nothing_raised {
- slice = property.class.state_sequence(:running, :installed).collect do |o|
- o[:name]
- end
- }
+ assert_equal([:configured, :installed], slice)
+ assert_nothing_raised {
+ slice = property.class.state_sequence(:running, :installed).collect do |o|
+ o[:name]
+ end
+ }
- assert_equal(slice, [:installed])
- end
+ assert_equal(slice, [:installed])
- # Make sure the ensure stuff behaves as we expect
- def test_zoneensure
- zone = mkzone("ensurezone")
+ end
- property = zone.property(:ensure)
+ # Make sure the ensure stuff behaves as we expect
+ def test_zoneensure
+ zone = mkzone("ensurezone")
- assert(property, "Did not get ensure property")
+ property = zone.property(:ensure)
- values = nil
- assert_nothing_raised {
- values = zone.retrieve
- }
+ assert(property, "Did not get ensure property")
- assert(! property.insync?(values[property]), "Property is somehow in sync")
+ values = nil
+ assert_nothing_raised {
+ values = zone.retrieve
+ }
- assert(property.up?, "Property incorrectly thinks it is not moving up")
+ assert(! property.insync?(values[property]), "Property is somehow in sync")
- zone[:ensure] = :installed
- assert(property.up?, "Property incorrectly thinks it is not moving up")
- zone[:ensure] = :absent
- assert(! property.up?, "Property incorrectly thinks it is moving up")
- end
+ assert(property.up?, "Property incorrectly thinks it is not moving up")
- # Make sure all mentioned methods actually exist.
- def test_zonemethods_exist
- methods = []
- zone = mkzone("methodtest")
+ zone[:ensure] = :installed
+ assert(property.up?, "Property incorrectly thinks it is not moving up")
+ zone[:ensure] = :absent
+ assert(! property.up?, "Property incorrectly thinks it is moving up")
+ end
- property = zone.property(:ensure)
- assert_nothing_raised {
- property.class.state_sequence(:absent, :running).each do |st|
- [:up, :down].each do |m|
- methods << st[m] if st[m]
- end
- end
- }
+ # Make sure all mentioned methods actually exist.
+ def test_zonemethods_exist
+ methods = []
+ zone = mkzone("methodtest")
- methods.each do |m|
- Puppet::Type.type(:zone).suitableprovider.each do |prov|
+ property = zone.property(:ensure)
+ assert_nothing_raised {
+ property.class.state_sequence(:absent, :running).each do |st|
+ [:up, :down].each do |m|
+ methods << st[m] if st[m]
+ end
+ end
+ }
- assert(
- prov.method_defined?(m),
+ methods.each do |m|
+ Puppet::Type.type(:zone).suitableprovider.each do |prov|
- "Zone provider #{prov.name} does not define method #{m}")
- end
- end
+ assert(
+ prov.method_defined?(m),
+ "Zone provider #{prov.name} does not define method #{m}")
+ end
end
- # Make sure our property generates the correct text.
- def test_inherit_property
- zone = mkzone("configtesting")
- zone[:ensure] = :configured
+ end
+
+ # Make sure our property generates the correct text.
+ def test_inherit_property
+ zone = mkzone("configtesting")
+ zone[:ensure] = :configured
- assert_nothing_raised {
- zone[:inherit] = "/usr"
- }
- property = zone.property(:inherit)
- assert(zone, "Did not get 'inherit' property")
+ assert_nothing_raised {
+ zone[:inherit] = "/usr"
+ }
+ property = zone.property(:inherit)
+ assert(zone, "Did not get 'inherit' property")
- assert_equal(
- "add inherit-pkg-dir\nset dir=/usr\nend", property.configtext,
+ assert_equal(
+ "add inherit-pkg-dir\nset dir=/usr\nend", property.configtext,
- "Got incorrect config text")
+ "Got incorrect config text")
- zone.provider.inherit = "/usr"
+ zone.provider.inherit = "/usr"
- assert_equal(
- "", property.configtext,
+ assert_equal(
+ "", property.configtext,
- "Got incorrect config text")
+ "Got incorrect config text")
- # Now we want multiple directories
- property.should = %w{/usr /sbin /lib}
+ # Now we want multiple directories
+ property.should = %w{/usr /sbin /lib}
- # The statements are sorted
- text = "add inherit-pkg-dir
+ # The statements are sorted
+ text = "add inherit-pkg-dir
set dir=/lib
end
add inherit-pkg-dir
@@ -159,70 +159,70 @@ set dir=/sbin
end"
- assert_equal(
- text, property.configtext,
+ assert_equal(
+ text, property.configtext,
- "Got incorrect config text")
+ "Got incorrect config text")
- zone.provider.inherit = %w{/usr /sbin /lib}
- property.should = %w{/usr /sbin}
+ zone.provider.inherit = %w{/usr /sbin /lib}
+ property.should = %w{/usr /sbin}
- text = "remove inherit-pkg-dir dir=/lib"
+ text = "remove inherit-pkg-dir dir=/lib"
- assert_equal(
- text, property.configtext,
+ assert_equal(
+ text, property.configtext,
- "Got incorrect config text")
- end
+ "Got incorrect config text")
+ end
end
class TestZoneAsRoot < TestZone
- confine "Not running Zone creation tests" => Puppet.features.root?
- confine "Zones are only functional on Solaris" => (Facter["operatingsystem"].value == "Solaris")
-
- def teardown
- current = %x{zoneadm list -cp}.split("\n").inject({}) { |h, line|
- ary = line.split(":")
- h[ary[1]] = ary[2]
- h
- }
-
- # Get rid of any lingering zones
- @@zones.each do |zone|
- next unless current.include? zone
-
- obj = Puppet::Type.type(:zone).new(:name => zone)
- obj[:ensure] = :absent
- assert_apply(obj)
- end
-
- # We can't delete the temp files until the zones are stopped and removed.
- super
+ confine "Not running Zone creation tests" => Puppet.features.root?
+ confine "Zones are only functional on Solaris" => (Facter["operatingsystem"].value == "Solaris")
+
+ def teardown
+ current = %x{zoneadm list -cp}.split("\n").inject({}) { |h, line|
+ ary = line.split(":")
+ h[ary[1]] = ary[2]
+ h
+ }
+
+ # Get rid of any lingering zones
+ @@zones.each do |zone|
+ next unless current.include? zone
+
+ obj = Puppet::Type.type(:zone).new(:name => zone)
+ obj[:ensure] = :absent
+ assert_apply(obj)
end
- # Make sure our ensure process actually works.
- def test_ensure_sync
- zone = mkzone("ensuretesting")
- zone[:ensure] = :configured
+ # We can't delete the temp files until the zones are stopped and removed.
+ super
+ end
+ # Make sure our ensure process actually works.
+ def test_ensure_sync
+ zone = mkzone("ensuretesting")
- assert_apply(zone)
+ zone[:ensure] = :configured
- assert(zone.insync?(zone.retrieve), "Zone is not insync")
- end
+ assert_apply(zone)
+
+ assert(zone.insync?(zone.retrieve), "Zone is not insync")
+ end
- def test_getconfig
- zone = mkzone("configtesting")
+ def test_getconfig
+ zone = mkzone("configtesting")
- base = tempfile
- zone[:path] = base
+ base = tempfile
+ zone[:path] = base
- ip = "192.168.0.1"
- interface = "bge0"
- zone[:ip] = "#{interface}:#{ip}"
+ ip = "192.168.0.1"
+ interface = "bge0"
+ zone[:ip] = "#{interface}:#{ip}"
- IO.popen("zonecfg -z configtesting -f -", "w") do |f|
- f.puts %{create -b
+ IO.popen("zonecfg -z configtesting -f -", "w") do |f|
+ f.puts %{create -b
set zonepath=#{tempfile}
set autoboot=true
add inherit-pkg-dir
@@ -245,203 +245,203 @@ set address=#{ip}
set physical=bge0
end
}
- end
+ end
- assert_equal(0, $CHILD_STATUS, "Did not successfully create zone")
+ assert_equal(0, $CHILD_STATUS, "Did not successfully create zone")
- hash = nil
- assert_nothing_raised {
- hash = zone.provider.send(:getconfig)
- }
+ hash = nil
+ assert_nothing_raised {
+ hash = zone.provider.send(:getconfig)
+ }
- zone[:check] = [:inherit, :autoboot]
+ zone[:check] = [:inherit, :autoboot]
- values = nil
- assert_nothing_raised("Could not retrieve zone values") do
- values = zone.retrieve.inject({}) { |result, newvals| result[newvals[0].name] = newvals[1]; result }
- end
+ values = nil
+ assert_nothing_raised("Could not retrieve zone values") do
+ values = zone.retrieve.inject({}) { |result, newvals| result[newvals[0].name] = newvals[1]; result }
+ end
- # And make sure it gets set correctly.
+ # And make sure it gets set correctly.
- assert_equal(
- %w{/sbin /usr /opt/csw /lib /platform}.sort,
+ assert_equal(
+ %w{/sbin /usr /opt/csw /lib /platform}.sort,
- values[:inherit].sort, "Inherited dirs did not get collected correctly."
- )
+ values[:inherit].sort, "Inherited dirs did not get collected correctly."
+ )
- assert_equal(
- ["#{interface}:#{ip}"], values[:ip],
+ assert_equal(
+ ["#{interface}:#{ip}"], values[:ip],
- "IP addresses did not get collected correctly.")
+ "IP addresses did not get collected correctly.")
- assert_equal(
- :true, values[:autoboot],
+ assert_equal(
+ :true, values[:autoboot],
- "Autoboot did not get collected correctly.")
- end
+ "Autoboot did not get collected correctly.")
+ end
- # Make sure we can do all the various and sundry configuring things.
- def test_configuring_zones
- zone = mkzone("configtesting")
+ # Make sure we can do all the various and sundry configuring things.
+ def test_configuring_zones
+ zone = mkzone("configtesting")
- assert_nothing_raised {
- zone[:inherit] = "/usr"
- }
+ assert_nothing_raised {
+ zone[:inherit] = "/usr"
+ }
- zone[:ensure] = :configured
+ zone[:ensure] = :configured
- assert_apply(zone)
+ assert_apply(zone)
- assert(zone.insync?(zone.retrieve), "Zone is not insync")
+ assert(zone.insync?(zone.retrieve), "Zone is not insync")
- # Now add a new directory to inherit
- assert_nothing_raised {
- zone[:inherit] = ["/sbin", "/usr"]
- }
- assert_apply(zone)
+ # Now add a new directory to inherit
+ assert_nothing_raised {
+ zone[:inherit] = ["/sbin", "/usr"]
+ }
+ assert_apply(zone)
- assert(zone.insync?(zone.retrieve), "Zone is not insync")
+ assert(zone.insync?(zone.retrieve), "Zone is not insync")
- assert(
- %x{/usr/sbin/zonecfg -z #{zone[:name]} info} =~ /dir: \/sbin/,
+ assert(
+ %x{/usr/sbin/zonecfg -z #{zone[:name]} info} =~ /dir: \/sbin/,
- "sbin was not added")
+ "sbin was not added")
- # And then remove it.
- assert_nothing_raised {
- zone[:inherit] = "/usr"
- }
- assert_apply(zone)
+ # And then remove it.
+ assert_nothing_raised {
+ zone[:inherit] = "/usr"
+ }
+ assert_apply(zone)
- assert(zone.insync?(zone.retrieve), "Zone is not insync")
+ assert(zone.insync?(zone.retrieve), "Zone is not insync")
- assert(
- %x{/usr/sbin/zonecfg -z #{zone[:name]} info} !~ /dir: \/sbin/,
+ assert(
+ %x{/usr/sbin/zonecfg -z #{zone[:name]} info} !~ /dir: \/sbin/,
- "sbin was not removed")
+ "sbin was not removed")
- # Now add an ip adddress. Fortunately (or not), zonecfg doesn't verify
- # that the interface exists.
- zone[:ip] = "hme0:192.168.0.1"
+ # Now add an ip adddress. Fortunately (or not), zonecfg doesn't verify
+ # that the interface exists.
+ zone[:ip] = "hme0:192.168.0.1"
- assert(! zone.insync?(zone.retrieve), "Zone is marked as in sync")
+ assert(! zone.insync?(zone.retrieve), "Zone is marked as in sync")
- assert_apply(zone)
- assert(zone.insync?(zone.retrieve), "Zone is not in sync")
+ assert_apply(zone)
+ assert(zone.insync?(zone.retrieve), "Zone is not in sync")
- assert(
- %x{/usr/sbin/zonecfg -z #{zone[:name]} info} =~ /192.168.0.1/,
+ assert(
+ %x{/usr/sbin/zonecfg -z #{zone[:name]} info} =~ /192.168.0.1/,
- "ip was not added")
- zone[:ip] = ["hme1:192.168.0.2", "hme0:192.168.0.1"]
- assert_apply(zone)
- assert(zone.insync?(zone.retrieve), "Zone is not in sync")
- assert(%x{/usr/sbin/zonecfg -z #{zone[:name]} info} =~ /192.168.0.2/, "ip was not added")
- zone[:ip] = ["hme1:192.168.0.2"]
- assert_apply(zone)
- zone.retrieve
- assert(%x{/usr/sbin/zonecfg -z #{zone[:name]} info} !~ /192.168.0.1/, "ip was not removed")
- end
+ "ip was not added")
+ zone[:ip] = ["hme1:192.168.0.2", "hme0:192.168.0.1"]
+ assert_apply(zone)
+ assert(zone.insync?(zone.retrieve), "Zone is not in sync")
+ assert(%x{/usr/sbin/zonecfg -z #{zone[:name]} info} =~ /192.168.0.2/, "ip was not added")
+ zone[:ip] = ["hme1:192.168.0.2"]
+ assert_apply(zone)
+ zone.retrieve
+ assert(%x{/usr/sbin/zonecfg -z #{zone[:name]} info} !~ /192.168.0.1/, "ip was not removed")
+ end
- # Test creating and removing a zone, but only up to the configured property,
- # so it's faster.
- def test_smallcreate
- zone = mkzone("smallcreate")
- # Include a bunch of stuff so the zone isn't as large
- dirs = %w{/usr /sbin /lib /platform}
+ # Test creating and removing a zone, but only up to the configured property,
+ # so it's faster.
+ def test_smallcreate
+ zone = mkzone("smallcreate")
+ # Include a bunch of stuff so the zone isn't as large
+ dirs = %w{/usr /sbin /lib /platform}
- %w{/opt/csw}.each do |dir|
- dirs << dir if FileTest.exists? dir
- end
- zone[:inherit] = dirs
+ %w{/opt/csw}.each do |dir|
+ dirs << dir if FileTest.exists? dir
+ end
+ zone[:inherit] = dirs
- assert(zone, "Did not make zone")
+ assert(zone, "Did not make zone")
- zone[:ensure] = :configured
+ zone[:ensure] = :configured
- assert(! zone.insync?(zone.retrieve), "Zone is incorrectly in sync")
+ assert(! zone.insync?(zone.retrieve), "Zone is incorrectly in sync")
- assert_apply(zone)
+ assert_apply(zone)
- assert(zone.insync?(zone.retrieve), "Zone is incorrectly out of sync")
+ assert(zone.insync?(zone.retrieve), "Zone is incorrectly out of sync")
- zone[:ensure] = :absent
+ zone[:ensure] = :absent
- assert_apply(zone)
+ assert_apply(zone)
- currentvalues = zone.retrieve
+ currentvalues = zone.retrieve
- assert_equal(:absent, currentvalues[zone.property(:ensure)],
- "Zone is not absent")
- end
+ assert_equal(:absent, currentvalues[zone.property(:ensure)],
+ "Zone is not absent")
+ end
- # Just go through each method linearly and make sure it works.
- def test_each_method
- zone = mkzone("methodtesting")
- dirs = %w{/usr /sbin /lib /platform}
+ # Just go through each method linearly and make sure it works.
+ def test_each_method
+ zone = mkzone("methodtesting")
+ dirs = %w{/usr /sbin /lib /platform}
- %w{/opt/csw}.each do |dir|
- dirs << dir if FileTest.exists? dir
- end
- zone[:inherit] = dirs
-
- [[:configure, :configured],
- [:install, :installed],
- [:start, :running],
- [:stop, :installed],
- [:uninstall, :configured],
- [:unconfigure, :absent]
- ].each do |method, property|
- Puppet.info "Testing #{method}"
- current_values = nil
- assert_nothing_raised {
- current_values = zone.retrieve
- }
- assert_nothing_raised {
- zone.provider.send(method)
- }
- current_values = nil
- assert_nothing_raised {
- current_values = zone.retrieve
- }
- assert_equal(property, current_values[zone.property(:ensure)], "Method #{method} did not correctly set property #{property}")
- end
+ %w{/opt/csw}.each do |dir|
+ dirs << dir if FileTest.exists? dir
+ end
+ zone[:inherit] = dirs
+
+ [[:configure, :configured],
+ [:install, :installed],
+ [:start, :running],
+ [:stop, :installed],
+ [:uninstall, :configured],
+ [:unconfigure, :absent]
+ ].each do |method, property|
+ Puppet.info "Testing #{method}"
+ current_values = nil
+ assert_nothing_raised {
+ current_values = zone.retrieve
+ }
+ assert_nothing_raised {
+ zone.provider.send(method)
+ }
+ current_values = nil
+ assert_nothing_raised {
+ current_values = zone.retrieve
+ }
+ assert_equal(property, current_values[zone.property(:ensure)], "Method #{method} did not correctly set property #{property}")
end
+ end
- def test_mkzone
- zone = mkzone("testmaking")
- # Include a bunch of stuff so the zone isn't as large
- dirs = %w{/usr /sbin /lib /platform}
+ def test_mkzone
+ zone = mkzone("testmaking")
+ # Include a bunch of stuff so the zone isn't as large
+ dirs = %w{/usr /sbin /lib /platform}
- %w{/opt/csw}.each do |dir|
- dirs << dir if FileTest.exists? dir
- end
- zone[:inherit] = dirs
+ %w{/opt/csw}.each do |dir|
+ dirs << dir if FileTest.exists? dir
+ end
+ zone[:inherit] = dirs
- assert(zone, "Did not make zone")
+ assert(zone, "Did not make zone")
- [:configured, :installed, :running, :installed, :absent].each do |value|
- assert_nothing_raised {
- zone[:ensure] = value
- }
- assert(! zone.insync?(zone.retrieve), "Zone is incorrectly in sync")
+ [:configured, :installed, :running, :installed, :absent].each do |value|
+ assert_nothing_raised {
+ zone[:ensure] = value
+ }
+ assert(! zone.insync?(zone.retrieve), "Zone is incorrectly in sync")
- assert_apply(zone)
+ assert_apply(zone)
- assert_nothing_raised {
- assert(zone.insync?(zone.retrieve), "Zone is incorrectly out of sync")
- }
- end
+ assert_nothing_raised {
+ assert(zone.insync?(zone.retrieve), "Zone is incorrectly out of sync")
+ }
+ end
- currentvalues = zone.retrieve
+ currentvalues = zone.retrieve
- assert_equal(:absent, currentvalues[zone.property(:ensure)],
- "Zone is not absent")
- end
+ assert_equal(:absent, currentvalues[zone.property(:ensure)],
+ "Zone is not absent")
+ end
end
diff --git a/test/util/classgen.rb b/test/util/classgen.rb
index 83b6481..5560764 100755
--- a/test/util/classgen.rb
+++ b/test/util/classgen.rb
@@ -6,236 +6,236 @@ require 'puppet'
require 'puppettest'
class TestPuppetUtilClassGen < Test::Unit::TestCase
- include PuppetTest
+ include PuppetTest
- class FakeBase
- class << self
- attr_accessor :name
- end
+ class FakeBase
+ class << self
+ attr_accessor :name
end
+ end
- class GenTest
- class << self
- include Puppet::Util::ClassGen
- end
+ class GenTest
+ class << self
+ include Puppet::Util::ClassGen
end
+ end
- def testclasses(name)
- sub = Class.new(GenTest) do @name = "base#{name.to_s}" end
- self.class.const_set("Base#{name.to_s}", sub)
+ def testclasses(name)
+ sub = Class.new(GenTest) do @name = "base#{name.to_s}" end
+ self.class.const_set("Base#{name.to_s}", sub)
- klass = Class.new(FakeBase) do @name = "gen#{name.to_s}"end
+ klass = Class.new(FakeBase) do @name = "gen#{name.to_s}"end
- return sub, klass
- end
+ return sub, klass
+ end
- def test_handleclassconst
- sub, klass = testclasses("const")
- const = nil
- assert_nothing_raised do
- const = sub.send(:handleclassconst, klass, klass.name, {})
- end
+ def test_handleclassconst
+ sub, klass = testclasses("const")
+ const = nil
+ assert_nothing_raised do
+ const = sub.send(:handleclassconst, klass, klass.name, {})
+ end
- # make sure the constant is set
- assert(defined?(Baseconst::Genconst), "const was not defined")
- assert_equal(Baseconst::Genconst.object_id, klass.object_id)
+ # make sure the constant is set
+ assert(defined?(Baseconst::Genconst), "const was not defined")
+ assert_equal(Baseconst::Genconst.object_id, klass.object_id)
- # Now make sure don't replace by default
- newklass = Class.new(FakeBase) do @name = klass.name end
- assert_raise(Puppet::ConstantAlreadyDefined) do
- const = sub.send(:handleclassconst, newklass, klass.name, {})
- end
- assert_equal(Baseconst::Genconst.object_id, klass.object_id)
+ # Now make sure don't replace by default
+ newklass = Class.new(FakeBase) do @name = klass.name end
+ assert_raise(Puppet::ConstantAlreadyDefined) do
+ const = sub.send(:handleclassconst, newklass, klass.name, {})
+ end
+ assert_equal(Baseconst::Genconst.object_id, klass.object_id)
- # Now make sure we can replace it
- assert_nothing_raised do
- const = sub.send(:handleclassconst, newklass, klass.name, :overwrite => true)
- end
- assert_equal(Baseconst::Genconst.object_id, newklass.object_id)
+ # Now make sure we can replace it
+ assert_nothing_raised do
+ const = sub.send(:handleclassconst, newklass, klass.name, :overwrite => true)
+ end
+ assert_equal(Baseconst::Genconst.object_id, newklass.object_id)
- # Now make sure we can choose our own constant
- assert_nothing_raised do
+ # Now make sure we can choose our own constant
+ assert_nothing_raised do
- const = sub.send(
- :handleclassconst, newklass, klass.name,
+ const = sub.send(
+ :handleclassconst, newklass, klass.name,
- :constant => "Fooness")
- end
- assert(defined?(Baseconst::Fooness), "Specified constant was not defined")
+ :constant => "Fooness")
+ end
+ assert(defined?(Baseconst::Fooness), "Specified constant was not defined")
- # And make sure prefixes work
- assert_nothing_raised do
+ # And make sure prefixes work
+ assert_nothing_raised do
- const = sub.send(
- :handleclassconst, newklass, klass.name,
+ const = sub.send(
+ :handleclassconst, newklass, klass.name,
- :prefix => "Test")
- end
- assert(defined?(Baseconst::TestGenconst), "prefix was not used")
+ :prefix => "Test")
end
+ assert(defined?(Baseconst::TestGenconst), "prefix was not used")
+ end
- def test_initclass_preinit
- sub, klass = testclasses("preinit")
+ def test_initclass_preinit
+ sub, klass = testclasses("preinit")
- class << klass
- attr_accessor :set
- def preinit
- @set = true
- end
- end
+ class << klass
+ attr_accessor :set
+ def preinit
+ @set = true
+ end
+ end
- assert(!klass.set, "Class was already initialized")
+ assert(!klass.set, "Class was already initialized")
- assert_nothing_raised do sub.send(:initclass, klass, {}) end
+ assert_nothing_raised do sub.send(:initclass, klass, {}) end
- assert(klass.set, "Class was not initialized")
- end
+ assert(klass.set, "Class was not initialized")
+ end
- def test_initclass_initvars
- sub, klass = testclasses("initvars")
+ def test_initclass_initvars
+ sub, klass = testclasses("initvars")
- class << klass
- attr_accessor :set
- def initvars
- @set = true
- end
- end
+ class << klass
+ attr_accessor :set
+ def initvars
+ @set = true
+ end
+ end
- assert(!klass.set, "Class was already initialized")
+ assert(!klass.set, "Class was already initialized")
- assert_nothing_raised do sub.send(:initclass, klass, {}) end
+ assert_nothing_raised do sub.send(:initclass, klass, {}) end
- assert(klass.set, "Class was not initialized")
- end
+ assert(klass.set, "Class was not initialized")
+ end
- def test_initclass_attributes
- sub, klass = testclasses("attributes")
+ def test_initclass_attributes
+ sub, klass = testclasses("attributes")
- class << klass
- attr_accessor :one, :two, :three
- end
+ class << klass
+ attr_accessor :one, :two, :three
+ end
- assert(!klass.one, "'one' was already set")
+ assert(!klass.one, "'one' was already set")
- assert_nothing_raised do sub.send(
- :initclass, klass,
+ assert_nothing_raised do sub.send(
+ :initclass, klass,
- :attributes => {:one => :a, :two => :b}) end
+ :attributes => {:one => :a, :two => :b}) end
- assert_equal(:a, klass.one, "Class was initialized incorrectly")
- assert_equal(:b, klass.two, "Class was initialized incorrectly")
- assert_nil(klass.three, "Class was initialized incorrectly")
- end
+ assert_equal(:a, klass.one, "Class was initialized incorrectly")
+ assert_equal(:b, klass.two, "Class was initialized incorrectly")
+ assert_nil(klass.three, "Class was initialized incorrectly")
+ end
- def test_initclass_include_and_extend
- sub, klass = testclasses("include_and_extend")
+ def test_initclass_include_and_extend
+ sub, klass = testclasses("include_and_extend")
- incl = Module.new do
- attr_accessor :included
- end
- self.class.const_set("Incl", incl)
+ incl = Module.new do
+ attr_accessor :included
+ end
+ self.class.const_set("Incl", incl)
- ext = Module.new do
- attr_accessor :extended
- end
- self.class.const_set("Ext", ext)
+ ext = Module.new do
+ attr_accessor :extended
+ end
+ self.class.const_set("Ext", ext)
- assert(! klass.respond_to?(:extended), "Class already responds to extended")
- assert(! klass.new.respond_to?(:included), "Class already responds to included")
+ assert(! klass.respond_to?(:extended), "Class already responds to extended")
+ assert(! klass.new.respond_to?(:included), "Class already responds to included")
- assert_nothing_raised do sub.send(
- :initclass, klass,
+ assert_nothing_raised do sub.send(
+ :initclass, klass,
- :include => incl, :extend => ext)
- end
-
- assert(klass.respond_to?(:extended), "Class did not get extended")
- assert(klass.new.respond_to?(:included), "Class did not include")
+ :include => incl, :extend => ext)
end
- def test_genclass
- hash = {}
- array = []
+ assert(klass.respond_to?(:extended), "Class did not get extended")
+ assert(klass.new.respond_to?(:included), "Class did not include")
+ end
- name = "yayness"
- klass = nil
- assert_nothing_raised {
- klass = GenTest.genclass(name, :array => array, :hash => hash, :parent => FakeBase) do
- class << self
- attr_accessor :name
- end
- end
- }
+ def test_genclass
+ hash = {}
+ array = []
- assert(klass.respond_to?(:name=), "Class did not execute block")
+ name = "yayness"
+ klass = nil
+ assert_nothing_raised {
+ klass = GenTest.genclass(name, :array => array, :hash => hash, :parent => FakeBase) do
+ class << self
+ attr_accessor :name
+ end
+ end
+ }
+
+ assert(klass.respond_to?(:name=), "Class did not execute block")
- assert(
- hash.include?(klass.name),
+ assert(
+ hash.include?(klass.name),
- "Class did not get added to hash")
+ "Class did not get added to hash")
- assert(
- array.include?(klass),
+ assert(
+ array.include?(klass),
- "Class did not get added to array")
- assert_equal(klass.superclass, FakeBase, "Parent class was wrong")
+ "Class did not get added to array")
+ assert_equal(klass.superclass, FakeBase, "Parent class was wrong")
+ end
+
+ # Make sure we call a preinithook, if there is one.
+ def test_inithooks
+ newclass = Class.new(FakeBase) do
+ class << self
+ attr_accessor :preinited, :postinited
+ end
+ def self.preinit
+ self.preinited = true
+ end
+ def self.postinit
+ self.postinited = true
+ end
end
- # Make sure we call a preinithook, if there is one.
- def test_inithooks
- newclass = Class.new(FakeBase) do
- class << self
- attr_accessor :preinited, :postinited
- end
- def self.preinit
- self.preinited = true
- end
- def self.postinit
- self.postinited = true
- end
- end
+ klass = nil
+ assert_nothing_raised {
+ klass = GenTest.genclass(:funtest, :parent => newclass)
+ }
- klass = nil
- assert_nothing_raised {
- klass = GenTest.genclass(:funtest, :parent => newclass)
- }
-
- assert(klass.preinited, "prehook did not get called")
- assert(klass.postinited, "posthook did not get called")
- end
+ assert(klass.preinited, "prehook did not get called")
+ assert(klass.postinited, "posthook did not get called")
+ end
- def test_modulegen
- hash = {}
- array = []
+ def test_modulegen
+ hash = {}
+ array = []
- name = "modness"
- mod = nil
- assert_nothing_raised {
- mod = GenTest.genmodule(name, :array => array, :hash => hash) do
- class << self
- attr_accessor :yaytest
- end
+ name = "modness"
+ mod = nil
+ assert_nothing_raised {
+ mod = GenTest.genmodule(name, :array => array, :hash => hash) do
+ class << self
+ attr_accessor :yaytest
+ end
- @yaytest = true
- end
- }
+ @yaytest = true
+ end
+ }
- assert(mod.respond_to?(:yaytest), "Class did not execute block")
+ assert(mod.respond_to?(:yaytest), "Class did not execute block")
- assert_instance_of(Module, mod)
- assert(hash.include?(mod.name), "Class did not get added to hash")
- assert(array.include?(mod), "Class did not get added to array")
- end
+ assert_instance_of(Module, mod)
+ assert(hash.include?(mod.name), "Class did not get added to hash")
+ assert(array.include?(mod), "Class did not get added to array")
+ end
- def test_genconst_string
- const = nil
- assert_nothing_raised do
- const = GenTest.send(:genconst_string, :testing, :prefix => "Yayness")
- end
- assert_equal("YaynessTesting", const)
+ def test_genconst_string
+ const = nil
+ assert_nothing_raised do
+ const = GenTest.send(:genconst_string, :testing, :prefix => "Yayness")
end
+ assert_equal("YaynessTesting", const)
+ end
end
diff --git a/test/util/execution.rb b/test/util/execution.rb
index be85d65..e650958 100755
--- a/test/util/execution.rb
+++ b/test/util/execution.rb
@@ -6,28 +6,28 @@ require 'puppet'
require 'puppettest'
class TestPuppetUtilExecution < Test::Unit::TestCase
- include PuppetTest
+ include PuppetTest
- def test_withenv
- ENV["testing"] = "yay"
+ def test_withenv
+ ENV["testing"] = "yay"
- assert_nothing_raised do
- Puppet::Util::Execution.withenv :testing => "foo" do
- $ran = ENV["testing"]
- end
- end
-
- assert_equal("yay", ENV["testing"])
- assert_equal("foo", $ran)
+ assert_nothing_raised do
+ Puppet::Util::Execution.withenv :testing => "foo" do
+ $ran = ENV["testing"]
+ end
+ end
- ENV["rah"] = "yay"
- assert_raise(ArgumentError) do
- Puppet::Util::Execution.withenv :testing => "foo" do
- raise ArgumentError, "yay"
- end
- end
+ assert_equal("yay", ENV["testing"])
+ assert_equal("foo", $ran)
- assert_equal("yay", ENV["rah"])
+ ENV["rah"] = "yay"
+ assert_raise(ArgumentError) do
+ Puppet::Util::Execution.withenv :testing => "foo" do
+ raise ArgumentError, "yay"
+ end
end
+
+ assert_equal("yay", ENV["rah"])
+ end
end
diff --git a/test/util/fileparsing.rb b/test/util/fileparsing.rb
index eaf57ce..05ed80a 100755
--- a/test/util/fileparsing.rb
+++ b/test/util/fileparsing.rb
@@ -8,718 +8,718 @@ require 'puppet'
require 'puppet/util/fileparsing'
class TestUtilFileParsing < Test::Unit::TestCase
- include PuppetTest
- include PuppetTest::FileParsing
+ include PuppetTest
+ include PuppetTest::FileParsing
- class FParser
- include Puppet::Util::FileParsing
- end
+ class FParser
+ include Puppet::Util::FileParsing
+ end
- def setup
- super
- @parser = FParser.new
- end
+ def setup
+ super
+ @parser = FParser.new
+ end
- def test_lines
- assert_equal("\n", @parser.line_separator, "Default separator was incorrect")
+ def test_lines
+ assert_equal("\n", @parser.line_separator, "Default separator was incorrect")
- {"\n" => ["one two\nthree four", "one two\nthree four\n"],
- "\t" => ["one two\tthree four", "one two\tthree four\t"],
- }.each do |sep, tests|
- assert_nothing_raised do
- @parser.line_separator = sep
- end
+ {"\n" => ["one two\nthree four", "one two\nthree four\n"],
+ "\t" => ["one two\tthree four", "one two\tthree four\t"],
+ }.each do |sep, tests|
+ assert_nothing_raised do
+ @parser.line_separator = sep
+ end
- assert_equal(
- sep, @parser.line_separator,
+ assert_equal(
+ sep, @parser.line_separator,
- "Did not set separator")
+ "Did not set separator")
- tests.each do |test|
- assert_equal(["one two", "three four"], @parser.lines(test), "Incorrectly parsed #{test.inspect}")
- end
- end
+ tests.each do |test|
+ assert_equal(["one two", "three four"], @parser.lines(test), "Incorrectly parsed #{test.inspect}")
+ end
end
+ end
- # Make sure parse calls the appropriate methods or errors out
- def test_parse
- @parser.meta_def(:parse_line) do |line|
- line.split(/\s+/)
- end
-
- text = "one line\ntwo line"
- should = [%w{one line}, %w{two line}]
- ret = nil
- assert_nothing_raised do
- ret = @parser.parse(text)
- end
+ # Make sure parse calls the appropriate methods or errors out
+ def test_parse
+ @parser.meta_def(:parse_line) do |line|
+ line.split(/\s+/)
+ end
- assert_equal(should, ret)
+ text = "one line\ntwo line"
+ should = [%w{one line}, %w{two line}]
+ ret = nil
+ assert_nothing_raised do
+ ret = @parser.parse(text)
end
- # Make sure we correctly handle different kinds of text lines.
- def test_text_line
- comment = "# this is a comment"
+ assert_equal(should, ret)
+ end
- # Make sure it fails if no regex is passed
- assert_raise(ArgumentError) do
- @parser.text_line :comment
- end
+ # Make sure we correctly handle different kinds of text lines.
+ def test_text_line
+ comment = "# this is a comment"
- # define a text matching comment record
- assert_nothing_raised do
- @parser.text_line :comment, :match => /^#/
- end
+ # Make sure it fails if no regex is passed
+ assert_raise(ArgumentError) do
+ @parser.text_line :comment
+ end
- # Make sure it matches
- assert_nothing_raised do
+ # define a text matching comment record
+ assert_nothing_raised do
+ @parser.text_line :comment, :match => /^#/
+ end
- assert_equal(
- {:record_type => :comment, :line => comment},
+ # Make sure it matches
+ assert_nothing_raised do
- @parser.parse_line(comment))
- end
+ assert_equal(
+ {:record_type => :comment, :line => comment},
- # But not something else
- assert_nothing_raised do
- assert_nil(@parser.parse_line("some other text"))
- end
+ @parser.parse_line(comment))
+ end
- # Now define another type and make sure we get the right one back
- assert_nothing_raised do
- @parser.text_line :blank, :match => /^\s*$/
- end
+ # But not something else
+ assert_nothing_raised do
+ assert_nil(@parser.parse_line("some other text"))
+ end
- # The comment should still match
- assert_nothing_raised do
+ # Now define another type and make sure we get the right one back
+ assert_nothing_raised do
+ @parser.text_line :blank, :match => /^\s*$/
+ end
- assert_equal(
- {:record_type => :comment, :line => comment},
+ # The comment should still match
+ assert_nothing_raised do
- @parser.parse_line(comment))
- end
+ assert_equal(
+ {:record_type => :comment, :line => comment},
- # As should our new line type
- assert_nothing_raised do
+ @parser.parse_line(comment))
+ end
- assert_equal(
- {:record_type => :blank, :line => ""},
+ # As should our new line type
+ assert_nothing_raised do
- @parser.parse_line(""))
- end
+ assert_equal(
+ {:record_type => :blank, :line => ""},
+ @parser.parse_line(""))
end
- def test_parse_line
- Puppet[:trace] = false
-
- comment = "# this is a comment"
+ end
- # Make sure it fails if we don't have any record types defined
- assert_raise(Puppet::DevError) do
- @parser.parse_line(comment)
- end
+ def test_parse_line
+ Puppet[:trace] = false
- # Now define a text matching comment record
- assert_nothing_raised do
- @parser.text_line :comment, :match => /^#/
- end
+ comment = "# this is a comment"
- # And make sure we can't define another one with the same name
- assert_raise(ArgumentError) do
- @parser.text_line :comment, :match => /^"/
- end
-
- result = nil
- assert_nothing_raised("Did not parse text line") do
- result = @parser.parse_line comment
- end
+ # Make sure it fails if we don't have any record types defined
+ assert_raise(Puppet::DevError) do
+ @parser.parse_line(comment)
+ end
- assert_equal({:record_type => :comment, :line => comment}, result)
+ # Now define a text matching comment record
+ assert_nothing_raised do
+ @parser.text_line :comment, :match => /^#/
+ end
- # Make sure we just return nil on unmatched lines.
- assert_nothing_raised("Did not parse text line") do
- result = @parser.parse_line "No match for this"
- end
+ # And make sure we can't define another one with the same name
+ assert_raise(ArgumentError) do
+ @parser.text_line :comment, :match => /^"/
+ end
- assert_nil(result, "Somehow matched an empty line")
+ result = nil
+ assert_nothing_raised("Did not parse text line") do
+ result = @parser.parse_line comment
+ end
- # Now define another type of comment, and make sure both types get
- # correctly returned as comments
- assert_nothing_raised do
- @parser.text_line :comment2, :match => /^"/
- end
+ assert_equal({:record_type => :comment, :line => comment}, result)
- assert_nothing_raised("Did not parse old comment") do
- assert_equal({:record_type => :comment, :line => comment}, @parser.parse_line(comment))
- end
- comment = '" another type of comment'
- assert_nothing_raised("Did not parse new comment") do
- assert_equal({:record_type => :comment2, :line => comment}, @parser.parse_line(comment))
- end
+ # Make sure we just return nil on unmatched lines.
+ assert_nothing_raised("Did not parse text line") do
+ result = @parser.parse_line "No match for this"
+ end
- # Now define two overlapping record types and make sure we keep the
- # correct order. We do first match, not longest match.
- assert_nothing_raised do
- @parser.text_line :one, :match => /^y/
- @parser.text_line :two, :match => /^yay/
- end
+ assert_nil(result, "Somehow matched an empty line")
- assert_nothing_raised do
- assert_equal({:record_type => :one, :line => "yayness"}, @parser.parse_line("yayness"))
- end
+ # Now define another type of comment, and make sure both types get
+ # correctly returned as comments
+ assert_nothing_raised do
+ @parser.text_line :comment2, :match => /^"/
+ end
+ assert_nothing_raised("Did not parse old comment") do
+ assert_equal({:record_type => :comment, :line => comment}, @parser.parse_line(comment))
+ end
+ comment = '" another type of comment'
+ assert_nothing_raised("Did not parse new comment") do
+ assert_equal({:record_type => :comment2, :line => comment}, @parser.parse_line(comment))
end
- def test_record_line
- tabrecord = "tab separated content"
- spacerecord = "space separated content"
+ # Now define two overlapping record types and make sure we keep the
+ # correct order. We do first match, not longest match.
+ assert_nothing_raised do
+ @parser.text_line :one, :match => /^y/
+ @parser.text_line :two, :match => /^yay/
+ end
- # Make sure we always require an appropriate set of options
- [{:separator => "\t"}, {}, {:fields => %w{record_type}}].each do |opts|
- assert_raise(ArgumentError, "Accepted #{opts.inspect}") do
- @parser.record_line :record, opts
- end
- end
+ assert_nothing_raised do
+ assert_equal({:record_type => :one, :line => "yayness"}, @parser.parse_line("yayness"))
+ end
- # Verify that our default separator is tabs
- tabs = nil
- assert_nothing_raised do
- tabs = @parser.record_line :tabs, :fields => [:name, :first, :second]
- end
+ end
- # Make sure out tab line gets matched
- tabshould = {:record_type => :tabs, :name => "tab", :first => "separated", :second => "content"}
- assert_nothing_raised do
- assert_equal(tabshould, @parser.handle_record_line(tabrecord, tabs))
- end
+ def test_record_line
+ tabrecord = "tab separated content"
+ spacerecord = "space separated content"
- # Now add our space-separated record type
- spaces = nil
- assert_nothing_raised do
- spaces = @parser.record_line :spaces, :fields => [:name, :first, :second]
- end
+ # Make sure we always require an appropriate set of options
+ [{:separator => "\t"}, {}, {:fields => %w{record_type}}].each do |opts|
+ assert_raise(ArgumentError, "Accepted #{opts.inspect}") do
+ @parser.record_line :record, opts
+ end
+ end
- # Now make sure both lines parse correctly
- spaceshould = {:record_type => :spaces, :name => "space", :first => "separated", :second => "content"}
+ # Verify that our default separator is tabs
+ tabs = nil
+ assert_nothing_raised do
+ tabs = @parser.record_line :tabs, :fields => [:name, :first, :second]
+ end
- assert_nothing_raised do
- assert_equal(tabshould, @parser.handle_record_line(tabrecord, tabs))
- assert_equal(spaceshould, @parser.handle_record_line(spacerecord, spaces))
- end
+ # Make sure out tab line gets matched
+ tabshould = {:record_type => :tabs, :name => "tab", :first => "separated", :second => "content"}
+ assert_nothing_raised do
+ assert_equal(tabshould, @parser.handle_record_line(tabrecord, tabs))
end
- def test_to_line
- @parser.text_line :comment, :match => /^#/
- @parser.text_line :blank, :match => /^\s*$/
- @parser.record_line :record, :fields => %w{name one two}, :joiner => "\t"
-
- johnny = {:record_type => :record, :name => "johnny", :one => "home",
- :two => "yay"}
- bill = {:record_type => :record, :name => "bill", :one => "work",
- :two => "boo"}
-
- records = {
- :comment => {:record_type => :comment, :line => "# This is a file"},
- :blank => {:record_type => :blank, :line => ""},
- :johnny => johnny,
- :bill => bill
- }
-
- lines = {
- :comment => "# This is a file",
- :blank => "",
- :johnny => "johnny home yay",
- :bill => "bill work boo"
- }
-
- records.each do |name, details|
- result = nil
- assert_nothing_raised do
- result = @parser.to_line(details)
- end
-
- assert_equal(lines[name], result)
- end
- order = [:comment, :blank, :johnny, :bill]
+ # Now add our space-separated record type
+ spaces = nil
+ assert_nothing_raised do
+ spaces = @parser.record_line :spaces, :fields => [:name, :first, :second]
+ end
- file = order.collect { |name| lines[name] }.join("\n")
+ # Now make sure both lines parse correctly
+ spaceshould = {:record_type => :spaces, :name => "space", :first => "separated", :second => "content"}
- ordered_records = order.collect { |name| records[name] }
+ assert_nothing_raised do
+ assert_equal(tabshould, @parser.handle_record_line(tabrecord, tabs))
+ assert_equal(spaceshould, @parser.handle_record_line(spacerecord, spaces))
+ end
+ end
+
+ def test_to_line
+ @parser.text_line :comment, :match => /^#/
+ @parser.text_line :blank, :match => /^\s*$/
+ @parser.record_line :record, :fields => %w{name one two}, :joiner => "\t"
+
+ johnny = {:record_type => :record, :name => "johnny", :one => "home",
+ :two => "yay"}
+ bill = {:record_type => :record, :name => "bill", :one => "work",
+ :two => "boo"}
+
+ records = {
+ :comment => {:record_type => :comment, :line => "# This is a file"},
+ :blank => {:record_type => :blank, :line => ""},
+ :johnny => johnny,
+ :bill => bill
+ }
+
+ lines = {
+ :comment => "# This is a file",
+ :blank => "",
+ :johnny => "johnny home yay",
+ :bill => "bill work boo"
+ }
+
+ records.each do |name, details|
+ result = nil
+ assert_nothing_raised do
+ result = @parser.to_line(details)
+ end
+
+ assert_equal(lines[name], result)
+ end
+ order = [:comment, :blank, :johnny, :bill]
- # Make sure we default to a trailing separator
- assert_equal(true, @parser.trailing_separator, "Did not default to a trailing separtor")
+ file = order.collect { |name| lines[name] }.join("\n")
- # Start without a trailing separator
- @parser.trailing_separator = false
- assert_nothing_raised do
- assert_equal(file, @parser.to_file(ordered_records))
- end
+ ordered_records = order.collect { |name| records[name] }
- # Now with a trailing separator
- file += "\n"
- @parser.trailing_separator = true
- assert_nothing_raised do
- assert_equal(file, @parser.to_file(ordered_records))
- end
+ # Make sure we default to a trailing separator
+ assert_equal(true, @parser.trailing_separator, "Did not default to a trailing separtor")
- # Now try it with a different separator, so we're not just catching
- # defaults
- file.gsub!("\n", "\t")
- @parser.line_separator = "\t"
- assert_nothing_raised do
- assert_equal(file, @parser.to_file(ordered_records))
- end
+ # Start without a trailing separator
+ @parser.trailing_separator = false
+ assert_nothing_raised do
+ assert_equal(file, @parser.to_file(ordered_records))
end
- # Make sure fields that are marked absent get replaced with the appropriate
- # string.
- def test_absent_fields
- record = nil
- assert_nothing_raised do
- record = @parser.record_line :record, :fields => %w{one two three},
- :optional => %w{two three}
- end
- assert_equal("", record.absent, "Did not set a default absent string")
+ # Now with a trailing separator
+ file += "\n"
+ @parser.trailing_separator = true
+ assert_nothing_raised do
+ assert_equal(file, @parser.to_file(ordered_records))
+ end
- result = nil
- assert_nothing_raised do
+ # Now try it with a different separator, so we're not just catching
+ # defaults
+ file.gsub!("\n", "\t")
+ @parser.line_separator = "\t"
+ assert_nothing_raised do
+ assert_equal(file, @parser.to_file(ordered_records))
+ end
+ end
+
+ # Make sure fields that are marked absent get replaced with the appropriate
+ # string.
+ def test_absent_fields
+ record = nil
+ assert_nothing_raised do
+ record = @parser.record_line :record, :fields => %w{one two three},
+ :optional => %w{two three}
+ end
+ assert_equal("", record.absent, "Did not set a default absent string")
- result = @parser.to_line(
- :record_type => :record,
+ result = nil
+ assert_nothing_raised do
- :one => "a", :two => :absent, :three => "b")
- end
+ result = @parser.to_line(
+ :record_type => :record,
- assert_equal("a b", result, "Absent was not correctly replaced")
+ :one => "a", :two => :absent, :three => "b")
+ end
- # Now try using a different replacement character
- record.absent = "*" # Because cron is a pain in my ass
- assert_nothing_raised do
- result = @parser.to_line(:record_type => :record, :one => "a", :two => :absent, :three => "b")
- end
+ assert_equal("a b", result, "Absent was not correctly replaced")
- assert_equal("a * b", result, "Absent was not correctly replaced")
+ # Now try using a different replacement character
+ record.absent = "*" # Because cron is a pain in my ass
+ assert_nothing_raised do
+ result = @parser.to_line(:record_type => :record, :one => "a", :two => :absent, :three => "b")
+ end
- # Make sure we deal correctly with the string 'absent'
- assert_nothing_raised do
+ assert_equal("a * b", result, "Absent was not correctly replaced")
- result = @parser.to_line(
- :record_type => :record,
+ # Make sure we deal correctly with the string 'absent'
+ assert_nothing_raised do
- :one => "a", :two => "b", :three => 'absent')
- end
+ result = @parser.to_line(
+ :record_type => :record,
- assert_equal("a b absent", result, "Replaced string 'absent'")
+ :one => "a", :two => "b", :three => 'absent')
+ end
- # And, of course, make sure we can swap things around.
- assert_nothing_raised do
+ assert_equal("a b absent", result, "Replaced string 'absent'")
- result = @parser.to_line(
- :record_type => :record,
+ # And, of course, make sure we can swap things around.
+ assert_nothing_raised do
- :one => "a", :two => "b", :three => :absent)
- end
+ result = @parser.to_line(
+ :record_type => :record,
- assert_equal("a b *", result, "Absent was not correctly replaced")
+ :one => "a", :two => "b", :three => :absent)
end
- # Make sure we can specify a different join character than split character
- def test_split_join_record_line
- check = proc do |start, record, final|
- # Check parsing first
- result = @parser.parse_line(start)
- [:one, :two].each do |param|
+ assert_equal("a b *", result, "Absent was not correctly replaced")
+ end
- assert_equal(
- record[param], result[param],
+ # Make sure we can specify a different join character than split character
+ def test_split_join_record_line
+ check = proc do |start, record, final|
+ # Check parsing first
+ result = @parser.parse_line(start)
+ [:one, :two].each do |param|
- "Did not correctly parse #{start.inspect}")
- end
+ assert_equal(
+ record[param], result[param],
- # And generating
- assert_equal(final, @parser.to_line(result), "Did not correctly generate #{final.inspect} from #{record.inspect}")
- end
+ "Did not correctly parse #{start.inspect}")
+ end
- # First try it with symmetric characters
- @parser.record_line :symmetric, :fields => %w{one two},
- :separator => " "
+ # And generating
+ assert_equal(final, @parser.to_line(result), "Did not correctly generate #{final.inspect} from #{record.inspect}")
+ end
- check.call "a b", {:one => "a", :two => "b"}, "a b"
- @parser.clear_records
+ # First try it with symmetric characters
+ @parser.record_line :symmetric, :fields => %w{one two},
+ :separator => " "
- # Now assymetric but both strings
- @parser.record_line :asymmetric, :fields => %w{one two},
- :separator => "\t", :joiner => " "
+ check.call "a b", {:one => "a", :two => "b"}, "a b"
+ @parser.clear_records
- check.call "a\tb", {:one => "a", :two => "b"}, "a b"
- @parser.clear_records
+ # Now assymetric but both strings
+ @parser.record_line :asymmetric, :fields => %w{one two},
+ :separator => "\t", :joiner => " "
- # And assymmetric with a regex
- @parser.record_line :asymmetric2, :fields => %w{one two},
- :separator => /\s+/, :joiner => " "
+ check.call "a\tb", {:one => "a", :two => "b"}, "a b"
+ @parser.clear_records
- check.call "a\tb", {:one => "a", :two => "b"}, "a b"
- check.call "a b", {:one => "a", :two => "b"}, "a b"
- end
+ # And assymmetric with a regex
+ @parser.record_line :asymmetric2, :fields => %w{one two},
+ :separator => /\s+/, :joiner => " "
- # Make sure we correctly regenerate files.
- def test_to_file
- @parser.text_line :comment, :match => /^#/
- @parser.text_line :blank, :match => /^\s*$/
- @parser.record_line :record, :fields => %w{name one two}
+ check.call "a\tb", {:one => "a", :two => "b"}, "a b"
+ check.call "a b", {:one => "a", :two => "b"}, "a b"
+ end
- text = "# This is a comment
+ # Make sure we correctly regenerate files.
+ def test_to_file
+ @parser.text_line :comment, :match => /^#/
+ @parser.text_line :blank, :match => /^\s*$/
+ @parser.record_line :record, :fields => %w{name one two}
+
+ text = "# This is a comment
johnny one two
billy three four\n"
# Just parse and generate, to make sure it's isomorphic.
assert_nothing_raised do
- assert_equal(text, @parser.to_file(@parser.parse(text)),
- "parsing was not isomorphic")
- end
+ assert_equal(text, @parser.to_file(@parser.parse(text)),
+ "parsing was not isomorphic")
end
+ end
- def test_valid_attrs
- @parser.record_line :record, :fields => %w{one two three}
-
-
- assert(
- @parser.valid_attr?(:record, :one),
-
- "one was considered invalid")
+ def test_valid_attrs
+ @parser.record_line :record, :fields => %w{one two three}
- assert(
- @parser.valid_attr?(:record, :ensure),
+ assert(
+ @parser.valid_attr?(:record, :one),
- "ensure was considered invalid")
+ "one was considered invalid")
- assert(
- ! @parser.valid_attr?(:record, :four),
+ assert(
+ @parser.valid_attr?(:record, :ensure),
- "four was considered valid")
- end
+ "ensure was considered invalid")
- def test_record_blocks
- options = nil
- assert_nothing_raised do
- # Just do a simple test
- options = @parser.record_line :record,
- :fields => %w{name alias info} do |line|
- line = line.dup
- ret = {}
- if line.sub!(/(\w+)\s*/, '')
- ret[:name] = $1
- else
- return nil
- end
- if line.sub!(/(#.+)/, '')
- desc = $1.sub(/^#\s*/, '')
- ret[:description] = desc unless desc == ""
- end
+ assert(
+ ! @parser.valid_attr?(:record, :four),
- ret[:alias] = line.split(/\s+/) if line != ""
+ "four was considered valid")
+ end
- return ret
- end
+ def test_record_blocks
+ options = nil
+ assert_nothing_raised do
+ # Just do a simple test
+ options = @parser.record_line :record,
+ :fields => %w{name alias info} do |line|
+ line = line.dup
+ ret = {}
+ if line.sub!(/(\w+)\s*/, '')
+ ret[:name] = $1
+ else
+ return nil
end
- values = {
- :name => "tcpmux",
- :description => "TCP port service multiplexer",
- :alias => ["sink"]
- }
-
- {
-
- "tcpmux " => [:name],
- "tcpmux" => [:name],
- "tcpmux sink" => [:name, :port, :protocols, :alias],
- "tcpmux # TCP port service multiplexer" =>
- [:name, :description, :port, :protocols],
- "tcpmux sink # TCP port service multiplexer" =>
- [:name, :description, :port, :alias, :protocols],
- "tcpmux sink null # TCP port service multiplexer" =>
- [:name, :description, :port, :alias, :protocols],
- }.each do |line, should|
- result = nil
- assert_nothing_raised do
- result = @parser.handle_record_line(line, options)
- end
- assert(result, "Did not get a result back for '#{line}'")
- should.each do |field|
- if field == :alias and line =~ /null/
- assert_equal(%w{sink null}, result[field], "Field #{field} was not right in '#{line}'")
- else
- assert_equal(values[field], result[field], "Field #{field} was not right in '#{line}'")
- end
- end
+ if line.sub!(/(#.+)/, '')
+ desc = $1.sub(/^#\s*/, '')
+ ret[:description] = desc unless desc == ""
end
+ ret[:alias] = line.split(/\s+/) if line != ""
+ return ret
+ end
end
- # Make sure we correctly handle optional fields. We'll skip this
- # functionality until we really know we need it.
- def test_optional_fields
- assert_nothing_raised do
- @parser.record_line :record,
- :fields => %w{one two three four},
- :optional => %w{three four},
- :absent => "*",
- :separator => " " # A single space
- end
+ values = {
+ :name => "tcpmux",
+ :description => "TCP port service multiplexer",
+ :alias => ["sink"]
+ }
+
+ {
+
+ "tcpmux " => [:name],
+ "tcpmux" => [:name],
+ "tcpmux sink" => [:name, :port, :protocols, :alias],
+ "tcpmux # TCP port service multiplexer" =>
+ [:name, :description, :port, :protocols],
+ "tcpmux sink # TCP port service multiplexer" =>
+ [:name, :description, :port, :alias, :protocols],
+ "tcpmux sink null # TCP port service multiplexer" =>
+ [:name, :description, :port, :alias, :protocols],
+ }.each do |line, should|
+ result = nil
+ assert_nothing_raised do
+ result = @parser.handle_record_line(line, options)
+ end
+ assert(result, "Did not get a result back for '#{line}'")
+ should.each do |field|
+ if field == :alias and line =~ /null/
+ assert_equal(%w{sink null}, result[field], "Field #{field} was not right in '#{line}'")
+ else
+ assert_equal(values[field], result[field], "Field #{field} was not right in '#{line}'")
+ end
+ end
+ end
- { "a b c d" => [],
- "a b * d" => [:three],
- "a b * *" => [:three, :four],
- "a b c *" => [:four]
- }.each do |line, absentees|
- record = nil
- assert_nothing_raised do
- record = @parser.parse_line(line)
- end
-
- # Absent field is :absent, not "*" inside the record
- absentees.each do |absentee|
- assert_equal(:absent, record[absentee])
- end
-
- # Now regenerate the line
- newline = nil
- assert_nothing_raised do
- newline = @parser.to_line(record)
- end
-
- # And make sure they're equal
- assert_equal(line, newline)
- end
- # Now make sure it pukes if we don't provide the required fields
- assert_raise(ArgumentError) do
- @parser.to_line(:record_type => :record, :one => "yay")
- end
+ end
+
+ # Make sure we correctly handle optional fields. We'll skip this
+ # functionality until we really know we need it.
+ def test_optional_fields
+ assert_nothing_raised do
+ @parser.record_line :record,
+ :fields => %w{one two three four},
+ :optional => %w{three four},
+ :absent => "*",
+ :separator => " " # A single space
end
- def test_record_rts
- # Start with the default
- assert_nothing_raised do
- @parser.record_line :record,
- :fields => %w{one two three four},
- :optional => %w{three four}
- end
+ { "a b c d" => [],
+ "a b * d" => [:three],
+ "a b * *" => [:three, :four],
+ "a b c *" => [:four]
+ }.each do |line, absentees|
+ record = nil
+ assert_nothing_raised do
+ record = @parser.parse_line(line)
+ end
+
+ # Absent field is :absent, not "*" inside the record
+ absentees.each do |absentee|
+ assert_equal(:absent, record[absentee])
+ end
+
+ # Now regenerate the line
+ newline = nil
+ assert_nothing_raised do
+ newline = @parser.to_line(record)
+ end
+
+ # And make sure they're equal
+ assert_equal(line, newline)
+ end
+ # Now make sure it pukes if we don't provide the required fields
+ assert_raise(ArgumentError) do
+ @parser.to_line(:record_type => :record, :one => "yay")
+ end
+ end
+
+ def test_record_rts
+ # Start with the default
+ assert_nothing_raised do
+ @parser.record_line :record,
+ :fields => %w{one two three four},
+ :optional => %w{three four}
+ end
- assert_equal(
- "a b ",
- @parser.to_line(:record_type => :record, :one => "a", :two => "b")
- )
+ assert_equal(
+ "a b ",
- # Now say yes to removing
- @parser.clear_records
- assert_nothing_raised do
- @parser.record_line :record,
- :fields => %w{one two three four},
- :optional => %w{three four},
- :rts => true
- end
+ @parser.to_line(:record_type => :record, :one => "a", :two => "b")
+ )
+ # Now say yes to removing
+ @parser.clear_records
+ assert_nothing_raised do
+ @parser.record_line :record,
+ :fields => %w{one two three four},
+ :optional => %w{three four},
+ :rts => true
+ end
- assert_equal(
- "a b",
- @parser.to_line(:record_type => :record, :one => "a", :two => "b")
- )
+ assert_equal(
+ "a b",
- # Lastly, try a regex
- @parser.clear_records
- assert_nothing_raised do
- @parser.record_line :record,
- :fields => %w{one two three four},
- :optional => %w{three four},
- :absent => "*",
- :rts => /[ *]+$/
- end
+ @parser.to_line(:record_type => :record, :one => "a", :two => "b")
+ )
+ # Lastly, try a regex
+ @parser.clear_records
+ assert_nothing_raised do
+ @parser.record_line :record,
+ :fields => %w{one two three four},
+ :optional => %w{three four},
+ :absent => "*",
+ :rts => /[ *]+$/
+ end
- assert_equal(
- "a b",
- @parser.to_line(:record_type => :record, :one => "a", :two => "b")
- )
- end
+ assert_equal(
+ "a b",
- # Make sure the last field can contain the separator, as crontabs do, and
- # that we roll them all up by default.
- def test_field_rollups
- @parser.record_line :yes, :fields => %w{name one two}
+ @parser.to_line(:record_type => :record, :one => "a", :two => "b")
+ )
+ end
- result = nil
- assert_nothing_raised do
- result = @parser.send(:parse_line, "Name One Two Three")
- end
+ # Make sure the last field can contain the separator, as crontabs do, and
+ # that we roll them all up by default.
+ def test_field_rollups
+ @parser.record_line :yes, :fields => %w{name one two}
- assert_equal(
- "Two Three", result[:two],
+ result = nil
+ assert_nothing_raised do
+ result = @parser.send(:parse_line, "Name One Two Three")
+ end
- "Did not roll up last fields by default")
+ assert_equal(
+ "Two Three", result[:two],
- @parser = FParser.new
- assert_nothing_raised("Could not create record that rolls up fields") do
- @parser.record_line :no, :fields => %w{name one two}, :rollup => false
- end
+ "Did not roll up last fields by default")
- result = nil
- assert_nothing_raised do
- result = @parser.send(:parse_line, "Name One Two Three")
- end
+ @parser = FParser.new
+ assert_nothing_raised("Could not create record that rolls up fields") do
+ @parser.record_line :no, :fields => %w{name one two}, :rollup => false
+ end
+
+ result = nil
+ assert_nothing_raised do
+ result = @parser.send(:parse_line, "Name One Two Three")
+ end
+
+ assert_equal(
+ "Two", result[:two],
- assert_equal(
- "Two", result[:two],
+ "Rolled up last fields when rollup => false")
+ end
- "Rolled up last fields when rollup => false")
+ def test_text_blocks
+ record = nil
+ assert_nothing_raised do
+ record = @parser.text_line :name, :match => %r{^#} do |line|
+ {:line => line.upcase}
+ end
end
- def test_text_blocks
- record = nil
- assert_nothing_raised do
- record = @parser.text_line :name, :match => %r{^#} do |line|
- {:line => line.upcase}
- end
- end
+ assert(
+ record.respond_to?(:process),
- assert(
- record.respond_to?(:process),
+ "Block was not used with text line")
- "Block was not used with text line")
+ assert_equal("YAYNESS", record.process("yayness")[:line],
+ "Did not call process method")
+ end
- assert_equal("YAYNESS", record.process("yayness")[:line],
- "Did not call process method")
+ def test_hooks
+ record = nil
+ # First try it with a normal record
+ assert_nothing_raised("Could not set hooks") do
+ record = @parser.record_line :yay, :fields => %w{one two},
+ :post_parse => proc { |hash| hash[:posted] = true },
+ :pre_gen => proc { |hash| hash[:one] = hash[:one].upcase },
+ :to_line => proc { |hash| "# Line\n" + join(hash) }
end
- def test_hooks
- record = nil
- # First try it with a normal record
- assert_nothing_raised("Could not set hooks") do
- record = @parser.record_line :yay, :fields => %w{one two},
- :post_parse => proc { |hash| hash[:posted] = true },
- :pre_gen => proc { |hash| hash[:one] = hash[:one].upcase },
- :to_line => proc { |hash| "# Line\n" + join(hash) }
- end
-
- assert(record.respond_to?(:post_parse), "did not create method for post-hook")
- assert(record.respond_to?(:pre_gen), "did not create method for pre-hook")
+ assert(record.respond_to?(:post_parse), "did not create method for post-hook")
+ assert(record.respond_to?(:pre_gen), "did not create method for pre-hook")
- result = nil
- assert_nothing_raised("Could not process line with hooks") do
- result = @parser.parse_line("one two")
- end
+ result = nil
+ assert_nothing_raised("Could not process line with hooks") do
+ result = @parser.parse_line("one two")
+ end
- assert(result[:posted], "Did not run post-hook")
- old_result = result
+ assert(result[:posted], "Did not run post-hook")
+ old_result = result
- # Now make sure our pre-gen hook is called
- assert_nothing_raised("Could not generate line with hooks") do
- result = @parser.to_line(result)
- end
- assert_equal("# Line\nONE two", result, "did not call pre-gen hook")
- assert_equal("one", old_result[:one], "passed original hash to pre hook")
+ # Now make sure our pre-gen hook is called
+ assert_nothing_raised("Could not generate line with hooks") do
+ result = @parser.to_line(result)
end
+ assert_equal("# Line\nONE two", result, "did not call pre-gen hook")
+ assert_equal("one", old_result[:one], "passed original hash to pre hook")
+ end
end
class TestUtilFileRecord < Test::Unit::TestCase
- include PuppetTest
- include PuppetTest::FileParsing
-
- Record = Puppet::Util::FileParsing::FileRecord
- def test_new_filerecord
- [ [:fake, {}],
- [nil, ]
- ].each do |args|
- assert_raise(ArgumentError, "Did not fail on #{args.inspect}") do
- Record.new(*args)
- end
- end
-
- # Make sure the fields get turned into symbols
- record = nil
- assert_nothing_raised do
- record = Record.new(:record, :fields => %w{one two})
- end
- assert_equal([:one, :two], record.fields, "Did not symbolize fields")
+ include PuppetTest
+ include PuppetTest::FileParsing
+
+ Record = Puppet::Util::FileParsing::FileRecord
+ def test_new_filerecord
+ [ [:fake, {}],
+ [nil, ]
+ ].each do |args|
+ assert_raise(ArgumentError, "Did not fail on #{args.inspect}") do
+ Record.new(*args)
+ end
+ end
- # Make sure we fail on invalid fields
- [:record_type, :target, :on_disk].each do |field|
- assert_raise(ArgumentError, "Did not fail on invalid field #{field}") {
- Record.new(:record, :fields => [field])
- }
- end
+ # Make sure the fields get turned into symbols
+ record = nil
+ assert_nothing_raised do
+ record = Record.new(:record, :fields => %w{one two})
end
+ assert_equal([:one, :two], record.fields, "Did not symbolize fields")
- def test_defaults
- record = Record.new(:text, :match => %r{^#})
- [:absent, :separator, :joiner, :optional].each do |field|
- assert_nil(record.send(field), "#{field} was not nil")
- end
+ # Make sure we fail on invalid fields
+ [:record_type, :target, :on_disk].each do |field|
+ assert_raise(ArgumentError, "Did not fail on invalid field #{field}") {
+ Record.new(:record, :fields => [field])
+ }
+ end
+ end
- record = Record.new(:record, :fields => %w{fields})
- {:absent => "", :separator => /\s+/, :joiner => " ", :optional => []}.each do |field, default|
- assert_equal(default, record.send(field), "#{field} was not default")
- end
+ def test_defaults
+ record = Record.new(:text, :match => %r{^#})
+ [:absent, :separator, :joiner, :optional].each do |field|
+ assert_nil(record.send(field), "#{field} was not nil")
end
- def test_block
- record = nil
- assert_nothing_raised("Could not pass a block when creating record") do
- record = Record.new(:record, :fields => %w{one}) do |line|
- return line.upcase
- end
- end
+ record = Record.new(:record, :fields => %w{fields})
+ {:absent => "", :separator => /\s+/, :joiner => " ", :optional => []}.each do |field, default|
+ assert_equal(default, record.send(field), "#{field} was not default")
+ end
+ end
+
+ def test_block
+ record = nil
+ assert_nothing_raised("Could not pass a block when creating record") do
+ record = Record.new(:record, :fields => %w{one}) do |line|
+ return line.upcase
+ end
+ end
- line = "This is a line"
+ line = "This is a line"
- assert(
- record.respond_to?(:process),
+ assert(
+ record.respond_to?(:process),
- "Record did not define :process method")
+ "Record did not define :process method")
- assert_equal(
- line.upcase, record.process(line),
+ assert_equal(
+ line.upcase, record.process(line),
- "Record did not process line correctly")
- end
+ "Record did not process line correctly")
+ end
- # Make sure we can declare that we want the block to be instance-eval'ed instead of
- # defining the 'process' method.
- def test_instance_block
- record = nil
- assert_nothing_raised("Could not pass a block when creating record") do
- record = Record.new(:record, :block_eval => :instance, :fields => %w{one}) do
- def process(line)
- line.upcase
- end
+ # Make sure we can declare that we want the block to be instance-eval'ed instead of
+ # defining the 'process' method.
+ def test_instance_block
+ record = nil
+ assert_nothing_raised("Could not pass a block when creating record") do
+ record = Record.new(:record, :block_eval => :instance, :fields => %w{one}) do
+ def process(line)
+ line.upcase
+ end
- def to_line(details)
- details.upcase
- end
- end
+ def to_line(details)
+ details.upcase
end
+ end
+ end
- assert(record.respond_to?(:process), "Block was not instance-eval'ed and process was not defined")
- assert(record.respond_to?(:to_line), "Block was not instance-eval'ed and to_line was not defined")
+ assert(record.respond_to?(:process), "Block was not instance-eval'ed and process was not defined")
+ assert(record.respond_to?(:to_line), "Block was not instance-eval'ed and to_line was not defined")
- line = "some text"
- assert_equal(line.upcase, record.process(line), "Instance-eval'ed record did not call :process correctly")
- assert_equal(line.upcase, record.to_line(line), "Instance-eval'ed record did not call :to_line correctly")
- end
+ line = "some text"
+ assert_equal(line.upcase, record.process(line), "Instance-eval'ed record did not call :process correctly")
+ assert_equal(line.upcase, record.to_line(line), "Instance-eval'ed record did not call :to_line correctly")
+ end
end
diff --git a/test/util/inifile.rb b/test/util/inifile.rb
index f465dfd..78831ca 100755
--- a/test/util/inifile.rb
+++ b/test/util/inifile.rb
@@ -7,132 +7,132 @@ require 'puppet/util/inifile'
require 'puppettest'
class TestFileType < Test::Unit::TestCase
- include PuppetTest
-
- def setup
- super
- @file = Puppet::Util::IniConfig::File.new
- end
-
- def teardown
- @file = nil
- super
- end
-
- def test_simple
- fname = mkfile("[main]\nkey1=value1\n# Comment\nkey2=value=2")
- assert_nothing_raised {
- @file.read(fname)
- }
- s = get_section('main')
- assert_entries(s, { 'key1' => 'value1', 'key2' => 'value=2' })
- @file['main']['key2'] = 'newvalue2'
- @file['main']['key3'] = 'newvalue3'
- text = s.format
-
- assert_equal(
- "[main]\nkey1=value1\n# Comment\nkey2=newvalue2\nkey3=newvalue3\n",
-
- s.format)
- end
-
- def test_multi
- fmain = mkfile("[main]\nkey1=main.value1\n# Comment\nkey2=main.value2")
- fsub = mkfile("[sub1]\nkey1=sub1 value1\n\n[sub2]\nkey1=sub2.value1")
- main_mtime = File::stat(fmain).mtime
- assert_nothing_raised {
- @file.read(fmain)
- @file.read(fsub)
- }
- main = get_section('main')
-
- assert_entries(
- main,
-
- { 'key1' => 'main.value1', 'key2' => 'main.value2' })
- sub1 = get_section('sub1')
- assert_entries(sub1, { 'key1' => 'sub1 value1' })
- sub2 = get_section('sub2')
- assert_entries(sub2, { 'key1' => 'sub2.value1' })
- [main, sub1, sub2].each { |s| assert( !s.dirty? ) }
- sub1['key1'] = 'sub1 newvalue1'
- sub2['key2'] = 'sub2 newvalue2'
- assert(! main.dirty?)
- [sub1, sub2].each { |s| assert( s.dirty? ) }
- @file.store
- [main, sub1, sub2].each { |s| assert( !s.dirty? ) }
- assert( File.exists?(fmain) )
- assert( File.exists?(fsub) )
- assert_equal(main_mtime, File::stat(fmain).mtime)
- subtext = File.read(fsub)
-
- assert_equal(
- "[sub1]\nkey1=sub1 newvalue1\n\n[sub2]\nkey1=sub2.value1\nkey2=sub2 newvalue2\n",
-
- subtext)
- end
-
- def test_format_nil
- fname = mkfile("[main]\nkey1=value1\n# Comment\nkey2=value2\n# Comment2\n")
- assert_nothing_raised {
- @file.read(fname)
- }
- s = get_section('main')
- s['key2'] = nil
- s['key3'] = nil
- text = s.format
-
- assert_equal(
- "[main]\nkey1=value1\n# Comment\n# Comment2\n",
-
- s.format)
- end
-
- def test_whitespace
- # FIXME: Should we really accept keys preceded by whitespace ?
- fname = mkfile("[main]\n key1=v1\nkey2 =v2\n")
- assert_nothing_raised {
- @file.read(fname)
- }
- s = get_section('main')
- assert_equal('v1', s['key1'])
- assert_equal('v2', s['key2'])
- # FIXME: We are losing whitespace around keys
- assert_equal("[main]\nkey1=v1\nkey2=v2\n", s.format)
- end
-
- def test_continuation
- cont = "[main]\nkey1=v1\nkey2=v2a\n v2b\nkey3=\n\tv3a\n v3b\n"
- fname = mkfile(cont)
- assert_nothing_raised {
- @file.read(fname)
- }
- s = get_section('main')
- assert_equal('v1', s['key1'])
- assert_equal("v2a\n v2b", s['key2'])
- assert_equal("\n\tv3a\n v3b", s['key3'])
- assert_equal(cont, s.format)
- end
-
- def assert_entries(section, hash)
- hash.each do |k, v|
-
- assert_equal(
- v, section[k],
-
- "Expected <#{v}> for #{section.name}[#{k}] but got <#{section[k]}>")
- end
- end
-
- def get_section(name)
- result = @file[name]
- assert_not_nil(result)
- result
- end
-
- def mkfile(content)
- file = tempfile
- File.open(file, "w") { |f| f.print(content) }
- file
+ include PuppetTest
+
+ def setup
+ super
+ @file = Puppet::Util::IniConfig::File.new
+ end
+
+ def teardown
+ @file = nil
+ super
+ end
+
+ def test_simple
+ fname = mkfile("[main]\nkey1=value1\n# Comment\nkey2=value=2")
+ assert_nothing_raised {
+ @file.read(fname)
+ }
+ s = get_section('main')
+ assert_entries(s, { 'key1' => 'value1', 'key2' => 'value=2' })
+ @file['main']['key2'] = 'newvalue2'
+ @file['main']['key3'] = 'newvalue3'
+ text = s.format
+
+ assert_equal(
+ "[main]\nkey1=value1\n# Comment\nkey2=newvalue2\nkey3=newvalue3\n",
+
+ s.format)
+ end
+
+ def test_multi
+ fmain = mkfile("[main]\nkey1=main.value1\n# Comment\nkey2=main.value2")
+ fsub = mkfile("[sub1]\nkey1=sub1 value1\n\n[sub2]\nkey1=sub2.value1")
+ main_mtime = File::stat(fmain).mtime
+ assert_nothing_raised {
+ @file.read(fmain)
+ @file.read(fsub)
+ }
+ main = get_section('main')
+
+ assert_entries(
+ main,
+
+ { 'key1' => 'main.value1', 'key2' => 'main.value2' })
+ sub1 = get_section('sub1')
+ assert_entries(sub1, { 'key1' => 'sub1 value1' })
+ sub2 = get_section('sub2')
+ assert_entries(sub2, { 'key1' => 'sub2.value1' })
+ [main, sub1, sub2].each { |s| assert( !s.dirty? ) }
+ sub1['key1'] = 'sub1 newvalue1'
+ sub2['key2'] = 'sub2 newvalue2'
+ assert(! main.dirty?)
+ [sub1, sub2].each { |s| assert( s.dirty? ) }
+ @file.store
+ [main, sub1, sub2].each { |s| assert( !s.dirty? ) }
+ assert( File.exists?(fmain) )
+ assert( File.exists?(fsub) )
+ assert_equal(main_mtime, File::stat(fmain).mtime)
+ subtext = File.read(fsub)
+
+ assert_equal(
+ "[sub1]\nkey1=sub1 newvalue1\n\n[sub2]\nkey1=sub2.value1\nkey2=sub2 newvalue2\n",
+
+ subtext)
+ end
+
+ def test_format_nil
+ fname = mkfile("[main]\nkey1=value1\n# Comment\nkey2=value2\n# Comment2\n")
+ assert_nothing_raised {
+ @file.read(fname)
+ }
+ s = get_section('main')
+ s['key2'] = nil
+ s['key3'] = nil
+ text = s.format
+
+ assert_equal(
+ "[main]\nkey1=value1\n# Comment\n# Comment2\n",
+
+ s.format)
+ end
+
+ def test_whitespace
+ # FIXME: Should we really accept keys preceded by whitespace ?
+ fname = mkfile("[main]\n key1=v1\nkey2 =v2\n")
+ assert_nothing_raised {
+ @file.read(fname)
+ }
+ s = get_section('main')
+ assert_equal('v1', s['key1'])
+ assert_equal('v2', s['key2'])
+ # FIXME: We are losing whitespace around keys
+ assert_equal("[main]\nkey1=v1\nkey2=v2\n", s.format)
+ end
+
+ def test_continuation
+ cont = "[main]\nkey1=v1\nkey2=v2a\n v2b\nkey3=\n\tv3a\n v3b\n"
+ fname = mkfile(cont)
+ assert_nothing_raised {
+ @file.read(fname)
+ }
+ s = get_section('main')
+ assert_equal('v1', s['key1'])
+ assert_equal("v2a\n v2b", s['key2'])
+ assert_equal("\n\tv3a\n v3b", s['key3'])
+ assert_equal(cont, s.format)
+ end
+
+ def assert_entries(section, hash)
+ hash.each do |k, v|
+
+ assert_equal(
+ v, section[k],
+
+ "Expected <#{v}> for #{section.name}[#{k}] but got <#{section[k]}>")
end
+ end
+
+ def get_section(name)
+ result = @file[name]
+ assert_not_nil(result)
+ result
+ end
+
+ def mkfile(content)
+ file = tempfile
+ File.open(file, "w") { |f| f.print(content) }
+ file
+ end
end
diff --git a/test/util/instance_loader.rb b/test/util/instance_loader.rb
index a7ea415..2e3dcb3 100755
--- a/test/util/instance_loader.rb
+++ b/test/util/instance_loader.rb
@@ -7,46 +7,46 @@ require 'puppet/util/instance_loader'
require 'puppettest'
class TestInstanceloader < Test::Unit::TestCase
- include PuppetTest
+ include PuppetTest
- def setup
- super
- @loader = Class.new do
- extend Puppet::Util::InstanceLoader
+ def setup
+ super
+ @loader = Class.new do
+ extend Puppet::Util::InstanceLoader
- def self.newstuff(name, value)
- instance_hash(:stuff)[name] = value
- end
- end
+ def self.newstuff(name, value)
+ instance_hash(:stuff)[name] = value
+ end
+ end
- assert_nothing_raised("Could not create instance loader") do
- @loader.instance_load(:stuff, "puppet/stuff")
- end
+ assert_nothing_raised("Could not create instance loader") do
+ @loader.instance_load(:stuff, "puppet/stuff")
end
+ end
- # Make sure we correctly create our autoload instance. This covers the basics.
- def test_autoload
- # Make sure we can retrieve the loader
- assert_instance_of(Puppet::Util::Autoload, @loader.instance_loader(:stuff), "Could not get instance loader")
+ # Make sure we correctly create our autoload instance. This covers the basics.
+ def test_autoload
+ # Make sure we can retrieve the loader
+ assert_instance_of(Puppet::Util::Autoload, @loader.instance_loader(:stuff), "Could not get instance loader")
- # Make sure we can get the instance hash
- assert(@loader.instance_hash(:stuff), "Could not get instance hash")
+ # Make sure we can get the instance hash
+ assert(@loader.instance_hash(:stuff), "Could not get instance hash")
- # Make sure it defines the instance retrieval method
- assert(@loader.respond_to?(:stuff), "Did not define instance retrieval method")
- end
+ # Make sure it defines the instance retrieval method
+ assert(@loader.respond_to?(:stuff), "Did not define instance retrieval method")
+ end
- def test_loaded_instances
- assert_equal([], @loader.loaded_instances(:stuff), "Incorrect loaded instances")
+ def test_loaded_instances
+ assert_equal([], @loader.loaded_instances(:stuff), "Incorrect loaded instances")
- @loader.newstuff(:testing, "a value")
+ @loader.newstuff(:testing, "a value")
- assert_equal([:testing], @loader.loaded_instances(:stuff), "Incorrect loaded instances")
+ assert_equal([:testing], @loader.loaded_instances(:stuff), "Incorrect loaded instances")
- assert_equal("a value", @loader.loaded_instance(:stuff, :testing), "Got incorrect loaded instance")
- end
+ assert_equal("a value", @loader.loaded_instance(:stuff, :testing), "Got incorrect loaded instance")
+ end
- def test_instance_loading
- end
+ def test_instance_loading
+ end
end
diff --git a/test/util/log.rb b/test/util/log.rb
index 8d5c8c5..4dbd3c6 100755
--- a/test/util/log.rb
+++ b/test/util/log.rb
@@ -7,213 +7,213 @@ require 'puppet/util/log'
require 'puppettest'
class TestLog < Test::Unit::TestCase
- include PuppetTest
-
- def setup
- super
- @oldloglevel = Puppet::Util::Log.level
- Puppet::Util::Log.close_all
- end
-
- def teardown
- super
- Puppet::Util::Log.close_all
- Puppet::Util::Log.level = @oldloglevel
- end
-
- def getlevels
- levels = nil
- assert_nothing_raised {
- levels = []
- Puppet::Util::Log.eachlevel { |level| levels << level }
- }
- # Don't test the top levels; too annoying
- levels.reject { |level| level == :emerg or level == :crit }
- end
-
- def mkmsgs(levels)
- levels.collect { |level|
- next if level == :alert
- assert_nothing_raised {
-
- Puppet::Util::Log.new(
+ include PuppetTest
+
+ def setup
+ super
+ @oldloglevel = Puppet::Util::Log.level
+ Puppet::Util::Log.close_all
+ end
+
+ def teardown
+ super
+ Puppet::Util::Log.close_all
+ Puppet::Util::Log.level = @oldloglevel
+ end
+
+ def getlevels
+ levels = nil
+ assert_nothing_raised {
+ levels = []
+ Puppet::Util::Log.eachlevel { |level| levels << level }
+ }
+ # Don't test the top levels; too annoying
+ levels.reject { |level| level == :emerg or level == :crit }
+ end
+
+ def mkmsgs(levels)
+ levels.collect { |level|
+ next if level == :alert
+ assert_nothing_raised {
+
+ Puppet::Util::Log.new(
- :level => level,
- :source => "Test",
+ :level => level,
+ :source => "Test",
- :message => "Unit test for #{level}"
- )
- }
- }
- end
-
- def test_logfile
- fact = nil
- levels = nil
- Puppet::Util::Log.level = :debug
- levels = getlevels
- logfile = tempfile
- fact = nil
- assert_nothing_raised {
- Puppet::Util::Log.newdestination(logfile)
- }
- msgs = mkmsgs(levels)
- assert(msgs.length == levels.length)
- Puppet::Util::Log.close_all
- count = 0
-
- assert(FileTest.exists?(logfile), "Did not create logfile")
-
- assert_nothing_raised {
- File.open(logfile) { |of|
- count = of.readlines.length
- }
- }
- assert(count == levels.length - 1) # skip alert
- end
-
- def test_syslog
- levels = nil
- assert_nothing_raised {
- levels = getlevels.reject { |level|
- level == :emerg || level == :crit
- }
- }
- assert_nothing_raised {
- Puppet::Util::Log.newdestination("syslog")
- }
- # there's really no way to verify that we got syslog messages...
- msgs = mkmsgs(levels)
- assert(msgs.length == levels.length)
- end
-
- def test_levelmethods
- assert_nothing_raised {
- Puppet::Util::Log.newdestination("/dev/null")
- }
- getlevels.each { |level|
- assert_nothing_raised {
- Puppet.send(level,"Testing for #{level}")
- }
- }
- end
-
- def test_output
- Puppet::Util::Log.level = :notice
- assert(Puppet.err("This is an error").is_a?(Puppet::Util::Log))
- assert(Puppet.debug("This is debugging").nil?)
- Puppet::Util::Log.level = :debug
- assert(Puppet.err("This is an error").is_a?(Puppet::Util::Log))
- assert(Puppet.debug("This is debugging").is_a?(Puppet::Util::Log))
- end
-
- def test_creatingdirs
- dir = tempfile
- file = File.join(dir, "logfile")
- Puppet::Util::Log.newdestination file
- Puppet.info "testing logs"
- assert(FileTest.directory?(dir))
- assert(FileTest.file?(file))
- end
-
- # Verify that we can pass strings that match printf args
- def test_percentlogs
- Puppet::Util::Log.newdestination :syslog
-
- assert_nothing_raised {
-
- Puppet::Util::Log.new(
+ :message => "Unit test for #{level}"
+ )
+ }
+ }
+ end
+
+ def test_logfile
+ fact = nil
+ levels = nil
+ Puppet::Util::Log.level = :debug
+ levels = getlevels
+ logfile = tempfile
+ fact = nil
+ assert_nothing_raised {
+ Puppet::Util::Log.newdestination(logfile)
+ }
+ msgs = mkmsgs(levels)
+ assert(msgs.length == levels.length)
+ Puppet::Util::Log.close_all
+ count = 0
+
+ assert(FileTest.exists?(logfile), "Did not create logfile")
+
+ assert_nothing_raised {
+ File.open(logfile) { |of|
+ count = of.readlines.length
+ }
+ }
+ assert(count == levels.length - 1) # skip alert
+ end
+
+ def test_syslog
+ levels = nil
+ assert_nothing_raised {
+ levels = getlevels.reject { |level|
+ level == :emerg || level == :crit
+ }
+ }
+ assert_nothing_raised {
+ Puppet::Util::Log.newdestination("syslog")
+ }
+ # there's really no way to verify that we got syslog messages...
+ msgs = mkmsgs(levels)
+ assert(msgs.length == levels.length)
+ end
+
+ def test_levelmethods
+ assert_nothing_raised {
+ Puppet::Util::Log.newdestination("/dev/null")
+ }
+ getlevels.each { |level|
+ assert_nothing_raised {
+ Puppet.send(level,"Testing for #{level}")
+ }
+ }
+ end
+
+ def test_output
+ Puppet::Util::Log.level = :notice
+ assert(Puppet.err("This is an error").is_a?(Puppet::Util::Log))
+ assert(Puppet.debug("This is debugging").nil?)
+ Puppet::Util::Log.level = :debug
+ assert(Puppet.err("This is an error").is_a?(Puppet::Util::Log))
+ assert(Puppet.debug("This is debugging").is_a?(Puppet::Util::Log))
+ end
+
+ def test_creatingdirs
+ dir = tempfile
+ file = File.join(dir, "logfile")
+ Puppet::Util::Log.newdestination file
+ Puppet.info "testing logs"
+ assert(FileTest.directory?(dir))
+ assert(FileTest.file?(file))
+ end
+
+ # Verify that we can pass strings that match printf args
+ def test_percentlogs
+ Puppet::Util::Log.newdestination :syslog
+
+ assert_nothing_raised {
+
+ Puppet::Util::Log.new(
- :level => :info,
+ :level => :info,
- :message => "A message with %s in it"
- )
- }
- end
+ :message => "A message with %s in it"
+ )
+ }
+ end
- # Verify that the error and source are always strings
- def test_argsAreStrings
- msg = nil
+ # Verify that the error and source are always strings
+ def test_argsAreStrings
+ msg = nil
- file = Puppet::Type.type(:file).new(
+ file = Puppet::Type.type(:file).new(
- :path => tempfile,
+ :path => tempfile,
- :check => %w{owner group}
- )
- assert_nothing_raised {
- msg = Puppet::Util::Log.new(:level => :info, :message => "This is a message")
- }
- assert_nothing_raised {
- msg.source = file
- }
-
- assert_instance_of(String, msg.to_s)
- assert_instance_of(String, msg.source)
- end
-
- def test_destination_matching
- dest = nil
- assert_nothing_raised {
- dest = Puppet::Util::Log.newdesttype("Destine") do
- def handle(msg)
- puts msg
- end
- end
- }
-
- [:destine, "Destine", "destine"].each do |name|
- assert(dest.match?(name), "Did not match #{name.inspect}")
+ :check => %w{owner group}
+ )
+ assert_nothing_raised {
+ msg = Puppet::Util::Log.new(:level => :info, :message => "This is a message")
+ }
+ assert_nothing_raised {
+ msg.source = file
+ }
+
+ assert_instance_of(String, msg.to_s)
+ assert_instance_of(String, msg.source)
+ end
+
+ def test_destination_matching
+ dest = nil
+ assert_nothing_raised {
+ dest = Puppet::Util::Log.newdesttype("Destine") do
+ def handle(msg)
+ puts msg
end
+ end
+ }
- assert_nothing_raised {
- dest.match(:yayness)
- }
- assert(dest.match("Yayness"), "Did not match yayness")
- Puppet::Util::Log.close(dest)
+ [:destine, "Destine", "destine"].each do |name|
+ assert(dest.match?(name), "Did not match #{name.inspect}")
end
- def test_autoflush
- file = tempfile
- Puppet::Util::Log.close(:console)
- Puppet::Util::Log.newdestination(file)
- Puppet.warning "A test"
- assert(File.read(file) !~ /A test/, "File defualted to autoflush")
- Puppet::Util::Log.flush
- assert(File.read(file) =~ /A test/, "File did not flush")
- Puppet::Util::Log.close(file)
-
- # Now try one with autoflush enabled
- Puppet[:autoflush] = true
- file = tempfile
- Puppet::Util::Log.newdestination(file)
- Puppet.warning "A test"
- assert(File.read(file) =~ /A test/, "File did not autoflush")
- Puppet::Util::Log.close(file)
- end
-
- def test_reopen
- Puppet[:autoflush] = true
- file = tempfile
- Puppet::Util::Log.close(:console)
- Puppet::Util::Log.newdestination(file)
- Puppet.warning "A test"
- assert(File.read(file) =~ /A test/,
- "File did not flush")
- # Rename the file
- newfile = file + ".old"
- File.rename(file, newfile)
-
- # Send another log
- Puppet.warning "Another test"
- assert(File.read(newfile) =~ /Another test/,
- "File did not rename")
-
- # Now reopen the log
- Puppet::Util::Log.reopen
- Puppet.warning "Reopen test"
- assert(File.read(file) =~ /Reopen test/, "File did not reopen")
- Puppet::Util::Log.close(file)
- end
+ assert_nothing_raised {
+ dest.match(:yayness)
+ }
+ assert(dest.match("Yayness"), "Did not match yayness")
+ Puppet::Util::Log.close(dest)
+ end
+
+ def test_autoflush
+ file = tempfile
+ Puppet::Util::Log.close(:console)
+ Puppet::Util::Log.newdestination(file)
+ Puppet.warning "A test"
+ assert(File.read(file) !~ /A test/, "File defualted to autoflush")
+ Puppet::Util::Log.flush
+ assert(File.read(file) =~ /A test/, "File did not flush")
+ Puppet::Util::Log.close(file)
+
+ # Now try one with autoflush enabled
+ Puppet[:autoflush] = true
+ file = tempfile
+ Puppet::Util::Log.newdestination(file)
+ Puppet.warning "A test"
+ assert(File.read(file) =~ /A test/, "File did not autoflush")
+ Puppet::Util::Log.close(file)
+ end
+
+ def test_reopen
+ Puppet[:autoflush] = true
+ file = tempfile
+ Puppet::Util::Log.close(:console)
+ Puppet::Util::Log.newdestination(file)
+ Puppet.warning "A test"
+ assert(File.read(file) =~ /A test/,
+ "File did not flush")
+ # Rename the file
+ newfile = file + ".old"
+ File.rename(file, newfile)
+
+ # Send another log
+ Puppet.warning "Another test"
+ assert(File.read(newfile) =~ /Another test/,
+ "File did not rename")
+
+ # Now reopen the log
+ Puppet::Util::Log.reopen
+ Puppet.warning "Reopen test"
+ assert(File.read(file) =~ /Reopen test/, "File did not reopen")
+ Puppet::Util::Log.close(file)
+ end
end
diff --git a/test/util/metrics.rb b/test/util/metrics.rb
index 2575330..1fd57f2 100755
--- a/test/util/metrics.rb
+++ b/test/util/metrics.rb
@@ -8,65 +8,65 @@ require 'puppettest'
require 'puppet/type'
class TestMetric < PuppetTest::TestCase
- confine "Missing RRDtool library" => Puppet.features.rrd?
- include PuppetTest
+ confine "Missing RRDtool library" => Puppet.features.rrd?
+ include PuppetTest
- def gendata
- totalmax = 1000
- changemax = 1000
- eventmax = 10
- maxdiff = 10
+ def gendata
+ totalmax = 1000
+ changemax = 1000
+ eventmax = 10
+ maxdiff = 10
- types = [Puppet::Type.type(:file), Puppet::Type.type(:package), Puppet::Type.type(:package)]
- data = [:total, :managed, :outofsync, :changed, :totalchanges]
- events = [:file_changed, :package_installed, :service_started]
+ types = [Puppet::Type.type(:file), Puppet::Type.type(:package), Puppet::Type.type(:package)]
+ data = [:total, :managed, :outofsync, :changed, :totalchanges]
+ events = [:file_changed, :package_installed, :service_started]
- # if this is the first set of data points...
- typedata = Hash.new { |typehash,type|
- typehash[type] = Hash.new(0)
- }
- eventdata = Hash.new(0)
- typedata = {}
- typedata[:total] = rand(totalmax)
- typedata[:managed] = rand(typedata[:total])
- typedata[:outofsync] = rand(typedata[:managed])
- typedata[:changed] = rand(typedata[:outofsync])
- typedata[:totalchanges] = rand(changemax)
+ # if this is the first set of data points...
+ typedata = Hash.new { |typehash,type|
+ typehash[type] = Hash.new(0)
+ }
+ eventdata = Hash.new(0)
+ typedata = {}
+ typedata[:total] = rand(totalmax)
+ typedata[:managed] = rand(typedata[:total])
+ typedata[:outofsync] = rand(typedata[:managed])
+ typedata[:changed] = rand(typedata[:outofsync])
+ typedata[:totalchanges] = rand(changemax)
- events.each { |event|
- eventdata[event] = rand(eventmax)
- }
+ events.each { |event|
+ eventdata[event] = rand(eventmax)
+ }
- {:typedata => typedata, :eventdata => eventdata}
- end
+ {:typedata => typedata, :eventdata => eventdata}
+ end
- def rundata(report, time)
- assert_nothing_raised {
- gendata.each do |name, data|
- report.newmetric(name, data)
- end
- report.metrics.each { |n, m| m.store(time) }
- }
- end
+ def rundata(report, time)
+ assert_nothing_raised {
+ gendata.each do |name, data|
+ report.newmetric(name, data)
+ end
+ report.metrics.each { |n, m| m.store(time) }
+ }
+ end
- def test_fakedata
- report = Puppet::Transaction::Report.new
- time = Time.now.to_i
- start = time
- 10.times {
- rundata(report, time)
- time += 300
- }
- rundata(report, time)
+ def test_fakedata
+ report = Puppet::Transaction::Report.new
+ time = Time.now.to_i
+ start = time
+ 10.times {
+ rundata(report, time)
+ time += 300
+ }
+ rundata(report, time)
- report.metrics.each do |n, m| m.graph end
+ report.metrics.each do |n, m| m.graph end
- File.open(File.join(Puppet[:rrddir],"index.html"),"w") { |of|
- of.puts "<html><body>"
- report.metrics.each { |name, metric|
- of.puts "<img src=#{metric.name}.png><br>"
- }
- }
- end
+ File.open(File.join(Puppet[:rrddir],"index.html"),"w") { |of|
+ of.puts "<html><body>"
+ report.metrics.each { |name, metric|
+ of.puts "<img src=#{metric.name}.png><br>"
+ }
+ }
+ end
end
diff --git a/test/util/package.rb b/test/util/package.rb
index c252db1..b2bb6df 100755
--- a/test/util/package.rb
+++ b/test/util/package.rb
@@ -7,19 +7,19 @@ require 'puppet/util/package'
require 'puppettest'
class TestPuppetUtilPackage < Test::Unit::TestCase
- include PuppetTest
- include Puppet::Util::Package
+ include PuppetTest
+ include Puppet::Util::Package
- def test_versioncmp
- ary = %w{ 1.1.6 2.3 1.1a 3.0 1.5 1 2.4 1.1-4 2.3.1 1.2 2.3.0 1.1-3 2.4b 2.4 2.40.2 2.3a.1 3.1 0002 1.1-5 1.1.a 1.06}
+ def test_versioncmp
+ ary = %w{ 1.1.6 2.3 1.1a 3.0 1.5 1 2.4 1.1-4 2.3.1 1.2 2.3.0 1.1-3 2.4b 2.4 2.40.2 2.3a.1 3.1 0002 1.1-5 1.1.a 1.06}
- newary = nil
- assert_nothing_raised do
- newary = ary.sort { |a, b|
- versioncmp(a,b)
- }
- end
- assert_equal(["0002", "1", "1.06", "1.1-3", "1.1-4", "1.1-5", "1.1.6", "1.1.a", "1.1a", "1.2", "1.5", "2.3", "2.3.0", "2.3.1", "2.3a.1", "2.4", "2.4", "2.4b", "2.40.2", "3.0", "3.1"], newary)
+ newary = nil
+ assert_nothing_raised do
+ newary = ary.sort { |a, b|
+ versioncmp(a,b)
+ }
end
+ assert_equal(["0002", "1", "1.06", "1.1-3", "1.1-4", "1.1-5", "1.1.6", "1.1.a", "1.1a", "1.2", "1.5", "2.3", "2.3.0", "2.3.1", "2.3a.1", "2.4", "2.4", "2.4b", "2.40.2", "3.0", "3.1"], newary)
+ end
end
diff --git a/test/util/pidlock.rb b/test/util/pidlock.rb
index 8d22ead..764c743 100755
--- a/test/util/pidlock.rb
+++ b/test/util/pidlock.rb
@@ -7,120 +7,120 @@ require 'fileutils'
Puppet.debug = false
class TestPuppetUtilPidlock < Test::Unit::TestCase
- include PuppetTest
-
- def setup
- super
- @workdir = tstdir
- end
-
- def teardown
- super
- FileUtils.rm_rf(@workdir)
- end
-
- def test_00_basic_create
- l = nil
- assert_nothing_raised { l = Puppet::Util::Pidlock.new(@workdir + '/nothingmuch') }
-
- assert_equal Puppet::Util::Pidlock, l.class
-
- assert_equal @workdir + '/nothingmuch', l.lockfile
- end
-
- def test_10_uncontended_lock
- l = Puppet::Util::Pidlock.new(@workdir + '/test_lock')
-
- assert !l.locked?
- assert !l.mine?
- assert l.lock
- assert l.locked?
- assert l.mine?
- assert !l.anonymous?
- # It's OK to call lock multiple times
- assert l.lock
- assert l.unlock
- assert !l.locked?
- assert !l.mine?
- end
-
- def test_20_someone_elses_lock
- childpid = nil
- l = Puppet::Util::Pidlock.new(@workdir + '/someone_elses_lock')
-
- # First, we need a PID that's guaranteed to be (a) used, (b) someone
- # else's, and (c) around for the life of this test.
- childpid = fork { loop do; sleep 10; end }
-
- File.open(l.lockfile, 'w') { |fd| fd.write(childpid) }
-
- assert l.locked?
- assert !l.mine?
- assert !l.lock
- assert l.locked?
- assert !l.mine?
- assert !l.unlock
- assert l.locked?
- assert !l.mine?
- ensure
- Process.kill("KILL", childpid) unless childpid.nil?
- end
-
- def test_30_stale_lock
- # This is a bit hard to guarantee, but we need a PID that is definitely
- # unused, and will stay so for the the life of this test. Our best
- # bet is to create a process, get it's PID, let it die, and *then*
- # lock on it.
- childpid = fork { exit }
-
- # Now we can't continue until we're sure that the PID is dead
- Process.wait(childpid)
-
- l = Puppet::Util::Pidlock.new(@workdir + '/stale_lock')
-
- # locked? should clear the lockfile
- File.open(l.lockfile, 'w') { |fd| fd.write(childpid) }
- assert File.exists?(l.lockfile)
- assert !l.locked?
- assert !File.exists?(l.lockfile)
-
- # lock should replace the lockfile with our own
- File.open(l.lockfile, 'w') { |fd| fd.write(childpid) }
- assert File.exists?(l.lockfile)
- assert l.lock
- assert l.locked?
- assert l.mine?
-
- # unlock should fail, and should *not* molest the existing lockfile,
- # despite it being stale
- File.open(l.lockfile, 'w') { |fd| fd.write(childpid) }
- assert File.exists?(l.lockfile)
- assert !l.unlock
- assert File.exists?(l.lockfile)
- end
-
- def test_40_not_locked_at_all
- l = Puppet::Util::Pidlock.new(@workdir + '/not_locked')
-
- assert !l.locked?
- # We can't unlock if we don't hold the lock
- assert !l.unlock
- end
-
- def test_50_anonymous_lock
- l = Puppet::Util::Pidlock.new(@workdir + '/anonymous_lock')
-
- assert !l.locked?
- assert l.lock(:anonymous => true)
- assert l.locked?
- assert l.anonymous?
- assert !l.mine?
- assert "", File.read(l.lockfile)
- assert !l.unlock
- assert l.locked?
- assert l.anonymous?
- assert l.unlock(:anonymous => true)
- assert !File.exists?(l.lockfile)
- end
+ include PuppetTest
+
+ def setup
+ super
+ @workdir = tstdir
+ end
+
+ def teardown
+ super
+ FileUtils.rm_rf(@workdir)
+ end
+
+ def test_00_basic_create
+ l = nil
+ assert_nothing_raised { l = Puppet::Util::Pidlock.new(@workdir + '/nothingmuch') }
+
+ assert_equal Puppet::Util::Pidlock, l.class
+
+ assert_equal @workdir + '/nothingmuch', l.lockfile
+ end
+
+ def test_10_uncontended_lock
+ l = Puppet::Util::Pidlock.new(@workdir + '/test_lock')
+
+ assert !l.locked?
+ assert !l.mine?
+ assert l.lock
+ assert l.locked?
+ assert l.mine?
+ assert !l.anonymous?
+ # It's OK to call lock multiple times
+ assert l.lock
+ assert l.unlock
+ assert !l.locked?
+ assert !l.mine?
+ end
+
+ def test_20_someone_elses_lock
+ childpid = nil
+ l = Puppet::Util::Pidlock.new(@workdir + '/someone_elses_lock')
+
+ # First, we need a PID that's guaranteed to be (a) used, (b) someone
+ # else's, and (c) around for the life of this test.
+ childpid = fork { loop do; sleep 10; end }
+
+ File.open(l.lockfile, 'w') { |fd| fd.write(childpid) }
+
+ assert l.locked?
+ assert !l.mine?
+ assert !l.lock
+ assert l.locked?
+ assert !l.mine?
+ assert !l.unlock
+ assert l.locked?
+ assert !l.mine?
+ ensure
+ Process.kill("KILL", childpid) unless childpid.nil?
+ end
+
+ def test_30_stale_lock
+ # This is a bit hard to guarantee, but we need a PID that is definitely
+ # unused, and will stay so for the the life of this test. Our best
+ # bet is to create a process, get it's PID, let it die, and *then*
+ # lock on it.
+ childpid = fork { exit }
+
+ # Now we can't continue until we're sure that the PID is dead
+ Process.wait(childpid)
+
+ l = Puppet::Util::Pidlock.new(@workdir + '/stale_lock')
+
+ # locked? should clear the lockfile
+ File.open(l.lockfile, 'w') { |fd| fd.write(childpid) }
+ assert File.exists?(l.lockfile)
+ assert !l.locked?
+ assert !File.exists?(l.lockfile)
+
+ # lock should replace the lockfile with our own
+ File.open(l.lockfile, 'w') { |fd| fd.write(childpid) }
+ assert File.exists?(l.lockfile)
+ assert l.lock
+ assert l.locked?
+ assert l.mine?
+
+ # unlock should fail, and should *not* molest the existing lockfile,
+ # despite it being stale
+ File.open(l.lockfile, 'w') { |fd| fd.write(childpid) }
+ assert File.exists?(l.lockfile)
+ assert !l.unlock
+ assert File.exists?(l.lockfile)
+ end
+
+ def test_40_not_locked_at_all
+ l = Puppet::Util::Pidlock.new(@workdir + '/not_locked')
+
+ assert !l.locked?
+ # We can't unlock if we don't hold the lock
+ assert !l.unlock
+ end
+
+ def test_50_anonymous_lock
+ l = Puppet::Util::Pidlock.new(@workdir + '/anonymous_lock')
+
+ assert !l.locked?
+ assert l.lock(:anonymous => true)
+ assert l.locked?
+ assert l.anonymous?
+ assert !l.mine?
+ assert "", File.read(l.lockfile)
+ assert !l.unlock
+ assert l.locked?
+ assert l.anonymous?
+ assert l.unlock(:anonymous => true)
+ assert !File.exists?(l.lockfile)
+ end
end
diff --git a/test/util/settings.rb b/test/util/settings.rb
index d05f555..ffcfbbf 100755
--- a/test/util/settings.rb
+++ b/test/util/settings.rb
@@ -8,627 +8,627 @@ require 'puppet/util/settings'
require 'puppettest/parsertesting'
class TestSettings < Test::Unit::TestCase
- include PuppetTest
- include PuppetTest::ParserTesting
- Setting = Puppet::Util::Settings::Setting
- BooleanSetting = Puppet::Util::Settings::BooleanSetting
-
- def setup
- super
- @config = mkconfig
- end
+ include PuppetTest
+ include PuppetTest::ParserTesting
+ Setting = Puppet::Util::Settings::Setting
+ BooleanSetting = Puppet::Util::Settings::BooleanSetting
+
+ def setup
+ super
+ @config = mkconfig
+ end
+
+ def set_configs(config = nil)
+ config ||= @config
+
+ config.setdefaults(
+ "main",
+ :one => ["a", "one"],
+ :two => ["a", "two"],
+ :yay => ["/default/path", "boo"],
+ :mkusers => [true, "uh, yeah"],
+
+ :name => ["testing", "a"]
+ )
+
+
+ config.setdefaults(
+ "section1",
+ :attr => ["a", "one"],
+ :attrdir => ["/another/dir", "two"],
+
+ :attr3 => ["$attrdir/maybe", "boo"]
+ )
+ end
+
+ def check_for_users
+ count = Puppet::Type.type(:user).inject(0) { |c,o|
+ c + 1
+ }
+ assert(count > 0, "Found no users")
+ end
- def set_configs(config = nil)
- config ||= @config
+ def test_to_config
+ set_configs
- config.setdefaults(
- "main",
- :one => ["a", "one"],
- :two => ["a", "two"],
- :yay => ["/default/path", "boo"],
- :mkusers => [true, "uh, yeah"],
+ newc = mkconfig
+ set_configs(newc)
- :name => ["testing", "a"]
- )
+ # Reset all of the values, so we know they're changing.
+ newc.each do |name, obj|
+ next if name == :name
+ newc[name] = true
+ end
+ newfile = tempfile
+ File.open(newfile, "w") { |f|
+ @config.to_config.split("\n").each do |line|
+ # Uncomment the settings, so they actually take.
+ if line =~ / = /
+ f.puts line.sub(/^\s*#/, '')
+ else
+ f.puts line
+ end
+ end
+ }
- config.setdefaults(
- "section1",
- :attr => ["a", "one"],
- :attrdir => ["/another/dir", "two"],
+ newc.setdefaults :section, :config => [newfile, "eh"]
- :attr3 => ["$attrdir/maybe", "boo"]
- )
- end
+ assert_nothing_raised("Could not parse generated configuration") {
+ newc.parse
+ }
- def check_for_users
- count = Puppet::Type.type(:user).inject(0) { |c,o|
- c + 1
- }
- assert(count > 0, "Found no users")
+ @config.each do |name, object|
+ assert_equal(@config[name], newc[name], "Parameter #{name} is not the same")
end
+ end
- def test_to_config
- set_configs
-
- newc = mkconfig
- set_configs(newc)
+ def mkconfig
+ c = Puppet::Util::Settings.new
+ c.setdefaults :main, :noop => [false, "foo"]
+ c
+ end
- # Reset all of the values, so we know they're changing.
- newc.each do |name, obj|
- next if name == :name
- newc[name] = true
- end
+ def test_addbools
+ assert_nothing_raised {
+ @config.setdefaults(:testing, :booltest => [true, "testing"])
+ }
- newfile = tempfile
- File.open(newfile, "w") { |f|
- @config.to_config.split("\n").each do |line|
- # Uncomment the settings, so they actually take.
- if line =~ / = /
- f.puts line.sub(/^\s*#/, '')
- else
- f.puts line
- end
- end
- }
+ assert(@config[:booltest])
+ @config = mkconfig
- newc.setdefaults :section, :config => [newfile, "eh"]
+ assert_nothing_raised {
+ @config.setdefaults(:testing, :booltest => ["true", "testing"])
+ }
- assert_nothing_raised("Could not parse generated configuration") {
- newc.parse
- }
+ assert(@config[:booltest])
- @config.each do |name, object|
- assert_equal(@config[name], newc[name], "Parameter #{name} is not the same")
- end
- end
+ assert_nothing_raised {
+ @config[:booltest] = false
+ }
- def mkconfig
- c = Puppet::Util::Settings.new
- c.setdefaults :main, :noop => [false, "foo"]
- c
- end
+ assert(! @config[:booltest], "Booltest is not false")
- def test_addbools
- assert_nothing_raised {
- @config.setdefaults(:testing, :booltest => [true, "testing"])
- }
+ assert_nothing_raised {
+ @config[:booltest] = "false"
+ }
- assert(@config[:booltest])
- @config = mkconfig
+ assert(! @config[:booltest], "Booltest is not false")
- assert_nothing_raised {
- @config.setdefaults(:testing, :booltest => ["true", "testing"])
- }
+ assert_raise(ArgumentError) {
+ @config[:booltest] = "yayness"
+ }
- assert(@config[:booltest])
+ assert_raise(ArgumentError) {
+ @config[:booltest] = "/some/file"
+ }
+ end
- assert_nothing_raised {
- @config[:booltest] = false
- }
+ def test_strings
+ val = "this is a string"
+ assert_nothing_raised {
+ @config.setdefaults(:testing, :strtest => [val, "testing"])
+ }
- assert(! @config[:booltest], "Booltest is not false")
+ assert_equal(val, @config[:strtest])
- assert_nothing_raised {
- @config[:booltest] = "false"
- }
+ # Verify that variables are interpolated
+ assert_nothing_raised {
+ @config.setdefaults(:testing, :another => ["another $strtest", "testing"])
+ }
- assert(! @config[:booltest], "Booltest is not false")
+ assert_equal("another #{val}", @config[:another])
+ end
- assert_raise(ArgumentError) {
- @config[:booltest] = "yayness"
- }
+ def test_files
+ c = mkconfig
- assert_raise(ArgumentError) {
- @config[:booltest] = "/some/file"
- }
- end
+ parent = "/puppet"
+ assert_nothing_raised {
+ @config.setdefaults(:testing, :parentdir => [parent, "booh"])
+ }
- def test_strings
- val = "this is a string"
- assert_nothing_raised {
- @config.setdefaults(:testing, :strtest => [val, "testing"])
- }
+ assert_nothing_raised {
+ @config.setdefaults(:testing, :child => ["$parent/child", "rah"])
+ }
- assert_equal(val, @config[:strtest])
+ assert_equal(parent, @config[:parentdir])
+ assert_equal("/puppet/child", File.join(@config[:parentdir], "child"))
+ end
- # Verify that variables are interpolated
- assert_nothing_raised {
- @config.setdefaults(:testing, :another => ["another $strtest", "testing"])
- }
+ def test_getset
+ initial = "an initial value"
+ assert_raise(ArgumentError) {
+ @config[:yayness] = initial
+ }
- assert_equal("another #{val}", @config[:another])
- end
+ default = "this is a default"
+ assert_nothing_raised {
+ @config.setdefaults(:testing, :yayness => [default, "rah"])
+ }
- def test_files
- c = mkconfig
+ assert_equal(default, @config[:yayness])
- parent = "/puppet"
- assert_nothing_raised {
- @config.setdefaults(:testing, :parentdir => [parent, "booh"])
- }
+ assert_nothing_raised {
+ @config[:yayness] = initial
+ }
- assert_nothing_raised {
- @config.setdefaults(:testing, :child => ["$parent/child", "rah"])
- }
+ assert_equal(initial, @config[:yayness])
- assert_equal(parent, @config[:parentdir])
- assert_equal("/puppet/child", File.join(@config[:parentdir], "child"))
- end
+ assert_nothing_raised {
+ @config.clear
+ }
- def test_getset
- initial = "an initial value"
- assert_raise(ArgumentError) {
- @config[:yayness] = initial
- }
+ assert_equal(default, @config[:yayness], "'clear' did not remove old values")
- default = "this is a default"
- assert_nothing_raised {
- @config.setdefaults(:testing, :yayness => [default, "rah"])
- }
+ assert_nothing_raised {
+ @config[:yayness] = "not default"
+ }
+ assert_equal("not default", @config[:yayness])
+ end
- assert_equal(default, @config[:yayness])
+ def test_parse_file
+ text = %{
+ one = this is a test
+ two = another test
+ owner = root
+ group = root
+ yay = /a/path
- assert_nothing_raised {
- @config[:yayness] = initial
- }
+ [main]
+ four = five
+ six = seven
- assert_equal(initial, @config[:yayness])
+[section1]
+ attr = value
+ owner = puppet
+ group = puppet
+ attrdir = /some/dir
+ attr3 = $attrdir/other
+ }
- assert_nothing_raised {
- @config.clear
- }
+ file = tempfile
+ File.open(file, "w") { |f| f.puts text }
- assert_equal(default, @config[:yayness], "'clear' did not remove old values")
+ result = nil
+ assert_nothing_raised {
+ result = @config.send(:parse_file, file)
+ }
- assert_nothing_raised {
- @config[:yayness] = "not default"
- }
- assert_equal("not default", @config[:yayness])
+ main = result[:main]
+ assert(main, "Did not get section for main")
+ {
+ :one => "this is a test",
+ :two => "another test",
+ :owner => "root",
+ :group => "root",
+ :yay => "/a/path",
+ :four => "five",
+ :six => "seven"
+ }.each do |param, value|
+ assert_equal(value, main[param], "Param #{param} was not set correctly in main")
end
- def test_parse_file
- text = %{
- one = this is a test
- two = another test
- owner = root
- group = root
- yay = /a/path
+ section1 = result[:section1]
+ assert(section1, "Did not get section1")
+
+ {
+ :attr => "value",
+ :owner => "puppet",
+ :group => "puppet",
+ :attrdir => "/some/dir",
+ :attr3 => "$attrdir/other"
+ }.each do |param, value|
+ assert_equal(value, section1[param], "Param #{param} was not set correctly in section1")
+ end
+ end
- [main]
- four = five
- six = seven
+ def test_arghandling
+ c = mkconfig
-[section1]
- attr = value
- owner = puppet
- group = puppet
- attrdir = /some/dir
- attr3 = $attrdir/other
- }
+ assert_nothing_raised {
- file = tempfile
- File.open(file, "w") { |f| f.puts text }
+ @config.setdefaults(
+ "testing",
+ :onboolean => [true, "An on bool"],
+ :offboolean => [false, "An off bool"],
+ :string => ["a string", "A string arg"],
- result = nil
- assert_nothing_raised {
- result = @config.send(:parse_file, file)
- }
+ :file => ["/path/to/file", "A file arg"]
+ )
+ }
- main = result[:main]
- assert(main, "Did not get section for main")
- {
- :one => "this is a test",
- :two => "another test",
- :owner => "root",
- :group => "root",
- :yay => "/a/path",
- :four => "five",
- :six => "seven"
- }.each do |param, value|
- assert_equal(value, main[param], "Param #{param} was not set correctly in main")
+ data = {
+ :onboolean => [true, false],
+ :offboolean => [true, false],
+ :string => ["one string", "another string"],
+ :file => %w{/a/file /another/file}
+ }
+ data.each { |param, values|
+ values.each { |val|
+ opt = nil
+ arg = nil
+ if @config.boolean?(param)
+ if val
+ opt = "--#{param}"
+ else
+ opt = "--no-#{param}"
+ end
+ else
+ opt = "--#{param}"
+ arg = val
end
- section1 = result[:section1]
- assert(section1, "Did not get section1")
-
- {
- :attr => "value",
- :owner => "puppet",
- :group => "puppet",
- :attrdir => "/some/dir",
- :attr3 => "$attrdir/other"
- }.each do |param, value|
- assert_equal(value, section1[param], "Param #{param} was not set correctly in section1")
- end
- end
+ assert_nothing_raised("Could not handle arg #{opt} with value #{val}") {
- def test_arghandling
- c = mkconfig
+ @config.handlearg(opt, arg)
+ }
+ }
+ }
+ end
- assert_nothing_raised {
+ def test_addargs
- @config.setdefaults(
- "testing",
- :onboolean => [true, "An on bool"],
- :offboolean => [false, "An off bool"],
- :string => ["a string", "A string arg"],
+ @config.setdefaults(
+ "testing",
+ :onboolean => [true, "An on bool"],
+ :offboolean => [false, "An off bool"],
+ :string => ["a string", "A string arg"],
- :file => ["/path/to/file", "A file arg"]
- )
- }
+ :file => ["/path/to/file", "A file arg"]
+ )
- data = {
- :onboolean => [true, false],
- :offboolean => [true, false],
- :string => ["one string", "another string"],
- :file => %w{/a/file /another/file}
- }
- data.each { |param, values|
- values.each { |val|
- opt = nil
- arg = nil
- if @config.boolean?(param)
- if val
- opt = "--#{param}"
- else
- opt = "--no-#{param}"
- end
- else
- opt = "--#{param}"
- arg = val
- end
-
- assert_nothing_raised("Could not handle arg #{opt} with value #{val}") {
-
- @config.handlearg(opt, arg)
- }
- }
- }
+ should = []
+ @config.each { |name, element|
+ element.expects(:getopt_args).returns([name])
+ should << name
+ }
+ result = []
+ assert_nothing_raised("Add args failed") do
+ @config.addargs(result)
end
+ assert_equal(should, result, "Did not call addargs correctly.")
- def test_addargs
+ end
- @config.setdefaults(
- "testing",
- :onboolean => [true, "An on bool"],
- :offboolean => [false, "An off bool"],
- :string => ["a string", "A string arg"],
+ def test_addargs_functional
+ @config = Puppet::Util::Settings.new
- :file => ["/path/to/file", "A file arg"]
- )
- should = []
- @config.each { |name, element|
- element.expects(:getopt_args).returns([name])
- should << name
- }
- result = []
- assert_nothing_raised("Add args failed") do
- @config.addargs(result)
- end
- assert_equal(should, result, "Did not call addargs correctly.")
+ @config.setdefaults(
+ "testing",
+ :onboolean => [true, "An on bool"],
+ :string => ["a string", "A string arg"]
+ )
+ result = []
+ should = []
+ assert_nothing_raised("Add args failed") do
+ @config.addargs(result)
end
-
- def test_addargs_functional
- @config = Puppet::Util::Settings.new
-
-
- @config.setdefaults(
- "testing",
- :onboolean => [true, "An on bool"],
-
- :string => ["a string", "A string arg"]
- )
- result = []
- should = []
- assert_nothing_raised("Add args failed") do
- @config.addargs(result)
- end
- @config.each do |name, element|
- if name == :onboolean
- should << ["--onboolean", GetoptLong::NO_ARGUMENT]
- should << ["--no-onboolean", GetoptLong::NO_ARGUMENT]
- elsif name == :string
- should << ["--string", GetoptLong::REQUIRED_ARGUMENT]
- end
- end
- assert_equal(should, result, "Add args functional test failed")
+ @config.each do |name, element|
+ if name == :onboolean
+ should << ["--onboolean", GetoptLong::NO_ARGUMENT]
+ should << ["--no-onboolean", GetoptLong::NO_ARGUMENT]
+ elsif name == :string
+ should << ["--string", GetoptLong::REQUIRED_ARGUMENT]
+ end
end
+ assert_equal(should, result, "Add args functional test failed")
+ end
- def test_groupsetting
- cfile = tempfile
+ def test_groupsetting
+ cfile = tempfile
- group = "yayness"
+ group = "yayness"
- File.open(cfile, "w") do |f|
- f.puts "[main]
- group = #{group}
- "
- end
+ File.open(cfile, "w") do |f|
+ f.puts "[main]
+ group = #{group}
+ "
+ end
- config = mkconfig
- config.setdefaults(Puppet[:name], :group => ["puppet", "a group"], :config => [cfile, "eh"])
+ config = mkconfig
+ config.setdefaults(Puppet[:name], :group => ["puppet", "a group"], :config => [cfile, "eh"])
- assert_nothing_raised {
- config.parse
- }
+ assert_nothing_raised {
+ config.parse
+ }
- assert_equal(group, config[:group], "Group did not take")
- end
+ assert_equal(group, config[:group], "Group did not take")
+ end
- # provide a method to modify and create files w/out specifying the info
- # already stored in a config
- def test_writingfiles
- File.umask(0022)
+ # provide a method to modify and create files w/out specifying the info
+ # already stored in a config
+ def test_writingfiles
+ File.umask(0022)
- path = tempfile
- mode = 0644
+ path = tempfile
+ mode = 0644
- config = mkconfig
+ config = mkconfig
- args = { :default => path, :mode => mode, :desc => "yay" }
+ args = { :default => path, :mode => mode, :desc => "yay" }
- user = nonrootuser
- group = nonrootgroup
+ user = nonrootuser
+ group = nonrootgroup
- if Puppet.features.root?
- args[:owner] = user.name
- args[:group] = group.name
- end
+ if Puppet.features.root?
+ args[:owner] = user.name
+ args[:group] = group.name
+ end
- config.setdefaults(:testing, :myfile => args)
+ config.setdefaults(:testing, :myfile => args)
- assert_nothing_raised {
- config.write(:myfile) do |file|
- file.puts "yay"
- end
- }
+ assert_nothing_raised {
+ config.write(:myfile) do |file|
+ file.puts "yay"
+ end
+ }
- assert_equal(mode, filemode(path), "Modes are not equal")
+ assert_equal(mode, filemode(path), "Modes are not equal")
- # OS X is broken in how it chgrps files
- if Puppet.features.root?
- assert_equal(user.uid, File.stat(path).uid, "UIDS are not equal")
+ # OS X is broken in how it chgrps files
+ if Puppet.features.root?
+ assert_equal(user.uid, File.stat(path).uid, "UIDS are not equal")
- case Facter["operatingsystem"].value
- when /BSD/, "Darwin" # nothing
- else
- assert_equal(group.gid, File.stat(path).gid, "GIDS are not equal")
- end
- end
+ case Facter["operatingsystem"].value
+ when /BSD/, "Darwin" # nothing
+ else
+ assert_equal(group.gid, File.stat(path).gid, "GIDS are not equal")
+ end
end
+ end
- def test_mkdir
- File.umask(0022)
+ def test_mkdir
+ File.umask(0022)
- path = tempfile
- mode = 0755
+ path = tempfile
+ mode = 0755
- config = mkconfig
+ config = mkconfig
- args = { :default => path, :mode => mode, :desc => "a file" }
+ args = { :default => path, :mode => mode, :desc => "a file" }
- user = nonrootuser
- group = nonrootgroup
+ user = nonrootuser
+ group = nonrootgroup
- if Puppet.features.root?
- args[:owner] = user.name
- args[:group] = group.name
- end
+ if Puppet.features.root?
+ args[:owner] = user.name
+ args[:group] = group.name
+ end
- config.setdefaults(:testing, :mydir => args)
+ config.setdefaults(:testing, :mydir => args)
- assert_nothing_raised {
- config.mkdir(:mydir)
- }
+ assert_nothing_raised {
+ config.mkdir(:mydir)
+ }
- assert_equal(mode, filemode(path), "Modes are not equal")
+ assert_equal(mode, filemode(path), "Modes are not equal")
- # OS X and *BSD is broken in how it chgrps files
- if Puppet.features.root?
- assert_equal(user.uid, File.stat(path).uid, "UIDS are not equal")
+ # OS X and *BSD is broken in how it chgrps files
+ if Puppet.features.root?
+ assert_equal(user.uid, File.stat(path).uid, "UIDS are not equal")
- case Facter["operatingsystem"].value
- when /BSD/, "Darwin" # nothing
- else
- assert_equal(group.gid, File.stat(path).gid, "GIDS are not equal")
- end
- end
+ case Facter["operatingsystem"].value
+ when /BSD/, "Darwin" # nothing
+ else
+ assert_equal(group.gid, File.stat(path).gid, "GIDS are not equal")
+ end
end
+ end
- # Make sure that tags are ignored when configuring
- def test_configs_ignore_tags
- config = mkconfig
- file = tempfile
+ # Make sure that tags are ignored when configuring
+ def test_configs_ignore_tags
+ config = mkconfig
+ file = tempfile
- config.setdefaults(
- :mysection,
+ config.setdefaults(
+ :mysection,
- :mydir => [file, "a file"]
- )
+ :mydir => [file, "a file"]
+ )
- Puppet[:tags] = "yayness"
+ Puppet[:tags] = "yayness"
- assert_nothing_raised {
- config.use(:mysection)
- }
-
- assert(FileTest.directory?(file), "Directory did not get created")
+ assert_nothing_raised {
+ config.use(:mysection)
+ }
+ assert(FileTest.directory?(file), "Directory did not get created")
- assert_equal(
- "yayness", Puppet[:tags],
- "Tags got changed during config")
- end
+ assert_equal(
+ "yayness", Puppet[:tags],
- def test_configs_replace_in_url
- config = mkconfig
+ "Tags got changed during config")
+ end
- config.setdefaults(:mysection, :host => ["yayness", "yay"])
- config.setdefaults(:mysection, :url => ["http://$host/rahness", "yay"])
+ def test_configs_replace_in_url
+ config = mkconfig
- val = nil
- assert_nothing_raised {
- val = config[:url]
- }
+ config.setdefaults(:mysection, :host => ["yayness", "yay"])
+ config.setdefaults(:mysection, :url => ["http://$host/rahness", "yay"])
+ val = nil
+ assert_nothing_raised {
+ val = config[:url]
+ }
- assert_equal(
- "http://yayness/rahness", val,
- "Settings got messed up")
- end
-
- def test_correct_type_assumptions
- file = Puppet::Util::Settings::FileSetting
- setting = Puppet::Util::Settings::Setting
- bool = Puppet::Util::Settings::BooleanSetting
-
- # We have to keep these ordered, unfortunately.
- [
- ["/this/is/a/file", file],
- ["true", bool],
- [true, bool],
- ["false", bool],
- ["server", setting],
- ["http://$server/yay", setting],
- ["$server/yayness", file],
- ["$server/yayness.conf", file]
- ].each do |ary|
- config = mkconfig
- value, type = ary
- name = value.to_s + "_setting"
- assert_nothing_raised {
- config.setdefaults(:yayness, name => { :default => value, :desc => name.to_s})
- }
- elem = config.setting(name)
-
-
- assert_instance_of(
- type, elem,
-
- "#{value.inspect} got created as wrong type")
- end
+ assert_equal(
+ "http://yayness/rahness", val,
+
+ "Settings got messed up")
+ end
+
+ def test_correct_type_assumptions
+ file = Puppet::Util::Settings::FileSetting
+ setting = Puppet::Util::Settings::Setting
+ bool = Puppet::Util::Settings::BooleanSetting
+
+ # We have to keep these ordered, unfortunately.
+ [
+ ["/this/is/a/file", file],
+ ["true", bool],
+ [true, bool],
+ ["false", bool],
+ ["server", setting],
+ ["http://$server/yay", setting],
+ ["$server/yayness", file],
+ ["$server/yayness.conf", file]
+ ].each do |ary|
+ config = mkconfig
+ value, type = ary
+ name = value.to_s + "_setting"
+ assert_nothing_raised {
+ config.setdefaults(:yayness, name => { :default => value, :desc => name.to_s})
+ }
+ elem = config.setting(name)
+
+
+ assert_instance_of(
+ type, elem,
+
+ "#{value.inspect} got created as wrong type")
end
-
- def test_parse_removes_quotes
- config = mkconfig
- config.setdefaults(:mysection, :singleq => ["single", "yay"])
- config.setdefaults(:mysection, :doubleq => ["double", "yay"])
- config.setdefaults(:mysection, :none => ["noquote", "yay"])
- config.setdefaults(:mysection, :middle => ["midquote", "yay"])
-
- file = tempfile
- # Set one parameter in the file
- File.open(file, "w") { |f|
- f.puts %{[main]\n
- singleq = 'one'
- doubleq = "one"
- none = one
- middle = mid"quote
+ end
+
+ def test_parse_removes_quotes
+ config = mkconfig
+ config.setdefaults(:mysection, :singleq => ["single", "yay"])
+ config.setdefaults(:mysection, :doubleq => ["double", "yay"])
+ config.setdefaults(:mysection, :none => ["noquote", "yay"])
+ config.setdefaults(:mysection, :middle => ["midquote", "yay"])
+
+ file = tempfile
+ # Set one parameter in the file
+ File.open(file, "w") { |f|
+ f.puts %{[main]\n
+ singleq = 'one'
+ doubleq = "one"
+ none = one
+ middle = mid"quote
}
- }
+ }
- config.setdefaults(:mysection, :config => [file, "eh"])
+ config.setdefaults(:mysection, :config => [file, "eh"])
- assert_nothing_raised {
- config.parse
- }
+ assert_nothing_raised {
+ config.parse
+ }
- %w{singleq doubleq none}.each do |p|
- assert_equal("one", config[p], "#{p} did not match")
- end
- assert_equal('mid"quote', config["middle"], "middle did not match")
+ %w{singleq doubleq none}.each do |p|
+ assert_equal("one", config[p], "#{p} did not match")
end
+ assert_equal('mid"quote', config["middle"], "middle did not match")
+ end
- # Test that config parameters correctly call passed-in blocks when the value
- # is set.
- def test_paramblocks
- config = mkconfig
-
- testing = nil
- assert_nothing_raised do
- config.setdefaults :test, :blocktest => {:default => "yay", :desc => "boo", :hook => proc { |value| testing = value }}
- end
- elem = config.setting(:blocktest)
-
- assert_nothing_raised do
- assert_equal("yay", elem.value)
- end
-
- assert_nothing_raised do
- config[:blocktest] = "yaytest"
- end
-
- assert_nothing_raised do
- assert_equal("yaytest", elem.value)
- end
- assert_equal("yaytest", testing)
+ # Test that config parameters correctly call passed-in blocks when the value
+ # is set.
+ def test_paramblocks
+ config = mkconfig
- assert_nothing_raised do
- config[:blocktest] = "another"
- end
+ testing = nil
+ assert_nothing_raised do
+ config.setdefaults :test, :blocktest => {:default => "yay", :desc => "boo", :hook => proc { |value| testing = value }}
+ end
+ elem = config.setting(:blocktest)
- assert_nothing_raised do
- assert_equal("another", elem.value)
- end
- assert_equal("another", testing)
-
- # Now verify it works from setdefault
- assert_nothing_raised do
- config.setdefaults :test,
- :blocktest2 => {
- :default => "yay",
- :desc => "yay",
- :hook => proc { |v| testing = v }
- }
- end
+ assert_nothing_raised do
+ assert_equal("yay", elem.value)
+ end
- assert_equal("yay", config[:blocktest2])
+ assert_nothing_raised do
+ config[:blocktest] = "yaytest"
+ end
- assert_nothing_raised do
- config[:blocktest2] = "footest"
- end
- assert_equal("footest", config[:blocktest2])
- assert_equal("footest", testing)
+ assert_nothing_raised do
+ assert_equal("yaytest", elem.value)
end
+ assert_equal("yaytest", testing)
- def test_no_modify_root
- config = mkconfig
+ assert_nothing_raised do
+ config[:blocktest] = "another"
+ end
- config.setdefaults(
- :yay,
- :mydir => {:default => tempfile,
+ assert_nothing_raised do
+ assert_equal("another", elem.value)
+ end
+ assert_equal("another", testing)
+
+ # Now verify it works from setdefault
+ assert_nothing_raised do
+ config.setdefaults :test,
+ :blocktest2 => {
+ :default => "yay",
+ :desc => "yay",
+ :hook => proc { |v| testing = v }
+ }
+ end
- :mode => 0644,
- :owner => "root",
- :group => "service",
- :desc => "yay"
- },
- :mkusers => [false, "yay"]
- )
+ assert_equal("yay", config[:blocktest2])
- assert_nothing_raised do
- config.use(:yay)
- end
+ assert_nothing_raised do
+ config[:blocktest2] = "footest"
+ end
+ assert_equal("footest", config[:blocktest2])
+ assert_equal("footest", testing)
+ end
+
+ def test_no_modify_root
+ config = mkconfig
+
+ config.setdefaults(
+ :yay,
+ :mydir => {:default => tempfile,
+
+ :mode => 0644,
+ :owner => "root",
+ :group => "service",
+ :desc => "yay"
+ },
+ :mkusers => [false, "yay"]
+ )
+
+ assert_nothing_raised do
+ config.use(:yay)
+ end
- # Now enable it so they'll be added
- config[:mkusers] = true
+ # Now enable it so they'll be added
+ config[:mkusers] = true
- comp = config.to_catalog
+ comp = config.to_catalog
- comp.vertices.find_all { |r| r.class.name == :user }.each do |u|
- assert(u.name != "root", "Tried to manage root user")
- end
- comp.vertices.find_all { |r| r.class.name == :group }.each do |u|
- assert(u.name != "root", "Tried to manage root group")
- assert(u.name != "wheel", "Tried to manage wheel group")
- end
+ comp.vertices.find_all { |r| r.class.name == :user }.each do |u|
+ assert(u.name != "root", "Tried to manage root user")
+ end
+ comp.vertices.find_all { |r| r.class.name == :group }.each do |u|
+ assert(u.name != "root", "Tried to manage root group")
+ assert(u.name != "wheel", "Tried to manage wheel group")
+ end
# assert(yay, "Did not find yay component")
# yay.each do |c|
@@ -638,136 +638,136 @@ class TestSettings < Test::Unit::TestCase
# "Found root user")
# assert(! yay.find { |o| o.class.name == :group and o.name == "root" },
# "Found root group")
- end
-
- # #415
- def test_remove_trailing_spaces
- config = mkconfig
- file = tempfile
- File.open(file, "w") { |f| f.puts "rah = something " }
+ end
+
+ # #415
+ def test_remove_trailing_spaces
+ config = mkconfig
+ file = tempfile
+ File.open(file, "w") { |f| f.puts "rah = something " }
+
+ config.setdefaults(:yay, :config => [file, "eh"], :rah => ["testing", "a desc"])
+
+ assert_nothing_raised { config.parse }
+ assert_equal("something", config[:rah], "did not remove trailing whitespace in parsing")
+ end
+
+ # #484
+ def test_parsing_unknown_variables
+ logstore
+ config = mkconfig
+ file = tempfile
+ File.open(file, "w") { |f|
+ f.puts %{[main]\n
+ one = one
+ two = yay
+ }
+ }
- config.setdefaults(:yay, :config => [file, "eh"], :rah => ["testing", "a desc"])
+ config.setdefaults(:mysection, :config => [file, "eh"], :one => ["yay", "yay"])
- assert_nothing_raised { config.parse }
- assert_equal("something", config[:rah], "did not remove trailing whitespace in parsing")
+ assert_nothing_raised("Unknown parameter threw an exception") do
+ config.parse
end
+ end
- # #484
- def test_parsing_unknown_variables
- logstore
- config = mkconfig
- file = tempfile
- File.open(file, "w") { |f|
- f.puts %{[main]\n
- one = one
- two = yay
- }
- }
+ def test_multiple_interpolations
- config.setdefaults(:mysection, :config => [file, "eh"], :one => ["yay", "yay"])
+ @config.setdefaults(
+ :section,
+ :one => ["oneval", "yay"],
+ :two => ["twoval", "yay"],
- assert_nothing_raised("Unknown parameter threw an exception") do
- config.parse
- end
- end
+ :three => ["$one/$two", "yay"]
+ )
- def test_multiple_interpolations
- @config.setdefaults(
- :section,
- :one => ["oneval", "yay"],
- :two => ["twoval", "yay"],
+ assert_equal(
+ "oneval/twoval", @config[:three],
- :three => ["$one/$two", "yay"]
- )
+ "Did not interpolate multiple variables")
+ end
+ # Make sure we can replace ${style} var names
+ def test_curly_replacements
- assert_equal(
- "oneval/twoval", @config[:three],
+ @config.setdefaults(
+ :section,
+ :one => ["oneval", "yay"],
+ :two => ["twoval", "yay"],
- "Did not interpolate multiple variables")
- end
+ :three => ["$one/${two}/${one}/$two", "yay"]
+ )
- # Make sure we can replace ${style} var names
- def test_curly_replacements
- @config.setdefaults(
- :section,
- :one => ["oneval", "yay"],
- :two => ["twoval", "yay"],
-
- :three => ["$one/${two}/${one}/$two", "yay"]
- )
+ assert_equal(
+ "oneval/twoval/oneval/twoval", @config[:three],
+ "Did not interpolate curlied variables")
+ end
- assert_equal(
- "oneval/twoval/oneval/twoval", @config[:three],
-
- "Did not interpolate curlied variables")
+ # Test to make sure that we can set and get a short name
+ def test_setting_short_name
+ setting= nil
+ assert_nothing_raised("Could not create setting") do
+ setting= Setting.new :short => "n", :desc => "anything", :settings => Puppet::Util::Settings.new
end
+ assert_equal("n", setting.short, "Short value is not retained")
- # Test to make sure that we can set and get a short name
- def test_setting_short_name
- setting= nil
- assert_nothing_raised("Could not create setting") do
- setting= Setting.new :short => "n", :desc => "anything", :settings => Puppet::Util::Settings.new
- end
- assert_equal("n", setting.short, "Short value is not retained")
-
- assert_raise(ArgumentError,"Allowed multicharactered short names.") do
- setting= Setting.new :short => "no", :desc => "anything", :settings => Puppet::Util::Settings.new
- end
+ assert_raise(ArgumentError,"Allowed multicharactered short names.") do
+ setting= Setting.new :short => "no", :desc => "anything", :settings => Puppet::Util::Settings.new
end
+ end
- # Test to make sure that no two celements have the same short name
- def test_celement_short_name_not_duplicated
- config = mkconfig
- assert_nothing_raised("Could not create celement with short name.") do
+ # Test to make sure that no two celements have the same short name
+ def test_celement_short_name_not_duplicated
+ config = mkconfig
+ assert_nothing_raised("Could not create celement with short name.") do
- config.setdefaults(
- :main,
+ config.setdefaults(
+ :main,
- :one => { :default => "blah", :desc => "anything", :short => "o" })
- end
- assert_nothing_raised("Could not create second celement with short name.") do
+ :one => { :default => "blah", :desc => "anything", :short => "o" })
+ end
+ assert_nothing_raised("Could not create second celement with short name.") do
- config.setdefaults(
- :main,
+ config.setdefaults(
+ :main,
- :two => { :default => "blah", :desc => "anything", :short => "i" })
- end
- assert_raise(ArgumentError, "Could create second celement with duplicate short name.") do
+ :two => { :default => "blah", :desc => "anything", :short => "i" })
+ end
+ assert_raise(ArgumentError, "Could create second celement with duplicate short name.") do
- config.setdefaults(
- :main,
+ config.setdefaults(
+ :main,
- :three => { :default => "blah", :desc => "anything", :short => "i" })
- end
- # make sure that when the above raises an expection that the config is not included
- assert(!config.include?(:three), "Invalid configuration item was retained")
+ :three => { :default => "blah", :desc => "anything", :short => "i" })
end
+ # make sure that when the above raises an expection that the config is not included
+ assert(!config.include?(:three), "Invalid configuration item was retained")
+ end
- # Tell getopt which arguments are valid
- def test_get_getopt_args
- element = Setting.new :name => "foo", :desc => "anything", :settings => Puppet::Util::Settings.new
- assert_equal([["--foo", GetoptLong::REQUIRED_ARGUMENT]], element.getopt_args, "Did not produce appropriate getopt args")
+ # Tell getopt which arguments are valid
+ def test_get_getopt_args
+ element = Setting.new :name => "foo", :desc => "anything", :settings => Puppet::Util::Settings.new
+ assert_equal([["--foo", GetoptLong::REQUIRED_ARGUMENT]], element.getopt_args, "Did not produce appropriate getopt args")
- element.short = "n"
- assert_equal([["--foo", "-n", GetoptLong::REQUIRED_ARGUMENT]], element.getopt_args, "Did not produce appropriate getopt args")
+ element.short = "n"
+ assert_equal([["--foo", "-n", GetoptLong::REQUIRED_ARGUMENT]], element.getopt_args, "Did not produce appropriate getopt args")
- element = BooleanSetting.new :name => "foo", :desc => "anything", :settings => Puppet::Util::Settings.new
+ element = BooleanSetting.new :name => "foo", :desc => "anything", :settings => Puppet::Util::Settings.new
- assert_equal(
- [["--foo", GetoptLong::NO_ARGUMENT], ["--no-foo", GetoptLong::NO_ARGUMENT]],
+ assert_equal(
+ [["--foo", GetoptLong::NO_ARGUMENT], ["--no-foo", GetoptLong::NO_ARGUMENT]],
- element.getopt_args, "Did not produce appropriate getopt args")
+ element.getopt_args, "Did not produce appropriate getopt args")
- element.short = "n"
+ element.short = "n"
- assert_equal(
- [["--foo", "-n", GetoptLong::NO_ARGUMENT],["--no-foo", GetoptLong::NO_ARGUMENT]],
+ assert_equal(
+ [["--foo", "-n", GetoptLong::NO_ARGUMENT],["--no-foo", GetoptLong::NO_ARGUMENT]],
- element.getopt_args, "Did not produce appropriate getopt args")
- end
+ element.getopt_args, "Did not produce appropriate getopt args")
+ end
end
diff --git a/test/util/storage.rb b/test/util/storage.rb
index cde5d64..f4836ce 100755
--- a/test/util/storage.rb
+++ b/test/util/storage.rb
@@ -6,76 +6,76 @@ require 'puppet'
require 'puppettest'
class TestStorage < Test::Unit::TestCase
- include PuppetTest
+ include PuppetTest
- def mkfile
- path = tempfile
- File.open(path, "w") { |f| f.puts :yayness }
+ def mkfile
+ path = tempfile
+ File.open(path, "w") { |f| f.puts :yayness }
- f = Puppet::Type.type(:file).new(
+ f = Puppet::Type.type(:file).new(
- :name => path,
+ :name => path,
- :check => %w{checksum type}
- )
-
- f
- end
-
- def test_storeandretrieve
- path = tempfile
-
- f = mkfile
-
- # Load first, since that's what we do in the code base; this creates
- # all of the necessary directories.
- assert_nothing_raised {
- Puppet::Util::Storage.load
- }
-
- hash = {:a => :b, :c => :d}
-
- state = nil
- assert_nothing_raised {
- state = Puppet::Util::Storage.cache(f)
- }
-
- assert(!state.include?("name"))
-
- assert_nothing_raised {
- state["name"] = hash
- }
-
- assert_nothing_raised {
- Puppet::Util::Storage.store
- }
- assert_nothing_raised {
- Puppet::Util::Storage.clear
- }
- assert_nothing_raised {
- Puppet::Util::Storage.load
- }
-
- # Reset it
- state = nil
- assert_nothing_raised {
- state = Puppet::Util::Storage.cache(f)
- }
-
- assert_equal(state["name"], hash)
- end
-
- def test_emptyrestore
- Puppet::Util::Storage.load
- Puppet::Util::Storage.store
- Puppet::Util::Storage.clear
- Puppet::Util::Storage.load
-
- f = mkfile
- state = Puppet::Util::Storage.cache(f)
- assert_same Hash, state.class
- assert_equal 0, state.size
- end
+ :check => %w{checksum type}
+ )
+
+ f
+ end
+
+ def test_storeandretrieve
+ path = tempfile
+
+ f = mkfile
+
+ # Load first, since that's what we do in the code base; this creates
+ # all of the necessary directories.
+ assert_nothing_raised {
+ Puppet::Util::Storage.load
+ }
+
+ hash = {:a => :b, :c => :d}
+
+ state = nil
+ assert_nothing_raised {
+ state = Puppet::Util::Storage.cache(f)
+ }
+
+ assert(!state.include?("name"))
+
+ assert_nothing_raised {
+ state["name"] = hash
+ }
+
+ assert_nothing_raised {
+ Puppet::Util::Storage.store
+ }
+ assert_nothing_raised {
+ Puppet::Util::Storage.clear
+ }
+ assert_nothing_raised {
+ Puppet::Util::Storage.load
+ }
+
+ # Reset it
+ state = nil
+ assert_nothing_raised {
+ state = Puppet::Util::Storage.cache(f)
+ }
+
+ assert_equal(state["name"], hash)
+ end
+
+ def test_emptyrestore
+ Puppet::Util::Storage.load
+ Puppet::Util::Storage.store
+ Puppet::Util::Storage.clear
+ Puppet::Util::Storage.load
+
+ f = mkfile
+ state = Puppet::Util::Storage.cache(f)
+ assert_same Hash, state.class
+ assert_equal 0, state.size
+ end
end
diff --git a/test/util/subclass_loader.rb b/test/util/subclass_loader.rb
index 946bc2b..957b6cc 100755
--- a/test/util/subclass_loader.rb
+++ b/test/util/subclass_loader.rb
@@ -6,84 +6,84 @@ require 'puppettest'
require 'puppet/util/subclass_loader'
class TestPuppetUtilSubclassLoader < Test::Unit::TestCase
- include PuppetTest
-
- class LoadTest
- extend Puppet::Util::SubclassLoader
- handle_subclasses :faker, "puppet/fakeloaders"
+ include PuppetTest
+
+ class LoadTest
+ extend Puppet::Util::SubclassLoader
+ handle_subclasses :faker, "puppet/fakeloaders"
+ end
+
+ def mk_subclass(name, path, parent)
+ # Make a fake client
+ unless defined?(@basedir)
+ @basedir ||= tempfile
+ $LOAD_PATH << @basedir
+ cleanup { $LOAD_PATH.delete(@basedir) if $LOAD_PATH.include?(@basedir) }
end
- def mk_subclass(name, path, parent)
- # Make a fake client
- unless defined?(@basedir)
- @basedir ||= tempfile
- $LOAD_PATH << @basedir
- cleanup { $LOAD_PATH.delete(@basedir) if $LOAD_PATH.include?(@basedir) }
- end
-
- libdir = File.join([@basedir, path.split(File::SEPARATOR)].flatten)
- FileUtils.mkdir_p(libdir)
-
- file = File.join(libdir, "#{name}.rb")
- File.open(file, "w") do |f|
- f.puts %{class #{parent}::#{name.to_s.capitalize} < #{parent}; end}
- end
- end
+ libdir = File.join([@basedir, path.split(File::SEPARATOR)].flatten)
+ FileUtils.mkdir_p(libdir)
- def test_subclass_loading
- # Make a fake client
- mk_subclass("fake", "puppet/fakeloaders", "TestPuppetUtilSubclassLoader::LoadTest")
+ file = File.join(libdir, "#{name}.rb")
+ File.open(file, "w") do |f|
+ f.puts %{class #{parent}::#{name.to_s.capitalize} < #{parent}; end}
+ end
+ end
+ def test_subclass_loading
+ # Make a fake client
+ mk_subclass("fake", "puppet/fakeloaders", "TestPuppetUtilSubclassLoader::LoadTest")
- fake = nil
- assert_nothing_raised do
- fake = LoadTest.faker(:fake)
- end
- assert_nothing_raised do
- assert_equal(fake, LoadTest.fake, "Did not get subclass back from main method")
- end
- assert(fake, "did not load subclass")
- # Now make sure the subclass behaves correctly
- assert_equal(:Fake, fake.name, "name was not calculated correctly")
+ fake = nil
+ assert_nothing_raised do
+ fake = LoadTest.faker(:fake)
end
-
- def test_multiple_subclasses
- sub1 = Class.new(LoadTest)
- Object.const_set("Sub1", sub1)
- sub2 = Class.new(sub1)
- Object.const_set("Sub2", sub2)
- assert_equal(sub2, LoadTest.sub2, "did not get subclass of subclass")
+ assert_nothing_raised do
+ assert_equal(fake, LoadTest.fake, "Did not get subclass back from main method")
end
+ assert(fake, "did not load subclass")
+
+ # Now make sure the subclass behaves correctly
+ assert_equal(:Fake, fake.name, "name was not calculated correctly")
+ end
+
+ def test_multiple_subclasses
+ sub1 = Class.new(LoadTest)
+ Object.const_set("Sub1", sub1)
+ sub2 = Class.new(sub1)
+ Object.const_set("Sub2", sub2)
+ assert_equal(sub2, LoadTest.sub2, "did not get subclass of subclass")
+ end
+
+ # I started out using a class variable to mark the loader,
+ # but it's shared among all classes that include this module,
+ # so it didn't work. This is testing whether I get the behaviour
+ # that I want.
+ def test_multiple_classes_using_module
+ other = Class.new do
+ extend Puppet::Util::SubclassLoader
+ handle_subclasses :other, "puppet/other"
+ end
+ Object.const_set("OtherLoader", other)
+
+ mk_subclass("multipletest", "puppet/other", "OtherLoader")
+ mk_subclass("multipletest", "puppet/fakeloaders", "TestPuppetUtilSubclassLoader::LoadTest")
+ #system("find #{@basedir}")
+ #puts File.read(File.join(@basedir, "puppet/fakeloaders/multipletest.rb"))
+ #puts File.read(File.join(@basedir, "puppet/other/multipletest.rb"))
- # I started out using a class variable to mark the loader,
- # but it's shared among all classes that include this module,
- # so it didn't work. This is testing whether I get the behaviour
- # that I want.
- def test_multiple_classes_using_module
- other = Class.new do
- extend Puppet::Util::SubclassLoader
- handle_subclasses :other, "puppet/other"
- end
- Object.const_set("OtherLoader", other)
-
- mk_subclass("multipletest", "puppet/other", "OtherLoader")
- mk_subclass("multipletest", "puppet/fakeloaders", "TestPuppetUtilSubclassLoader::LoadTest")
- #system("find #{@basedir}")
- #puts File.read(File.join(@basedir, "puppet/fakeloaders/multipletest.rb"))
- #puts File.read(File.join(@basedir, "puppet/other/multipletest.rb"))
-
- othersub = mainsub = nil
- assert_nothing_raised("Could not look up other sub") do
- othersub = OtherLoader.other(:multipletest)
- end
- assert_nothing_raised("Could not look up main sub") do
- mainsub = LoadTest.faker(:multipletest)
- end
- assert(othersub, "did not get other sub")
- assert(mainsub, "did not get main sub")
- assert(othersub.ancestors.include?(OtherLoader), "othersub is not a subclass of otherloader")
- assert(mainsub.ancestors.include?(LoadTest), "mainsub is not a subclass of loadtest")
+ othersub = mainsub = nil
+ assert_nothing_raised("Could not look up other sub") do
+ othersub = OtherLoader.other(:multipletest)
+ end
+ assert_nothing_raised("Could not look up main sub") do
+ mainsub = LoadTest.faker(:multipletest)
end
+ assert(othersub, "did not get other sub")
+ assert(mainsub, "did not get main sub")
+ assert(othersub.ancestors.include?(OtherLoader), "othersub is not a subclass of otherloader")
+ assert(mainsub.ancestors.include?(LoadTest), "mainsub is not a subclass of loadtest")
+ end
end
diff --git a/test/util/utiltest.rb b/test/util/utiltest.rb
index 45c4872..0e55e1d 100755
--- a/test/util/utiltest.rb
+++ b/test/util/utiltest.rb
@@ -6,231 +6,231 @@ require 'puppettest'
require 'mocha'
class TestPuppetUtil < Test::Unit::TestCase
- include PuppetTest
+ include PuppetTest
- def test_withumask
- oldmask = File.umask
+ def test_withumask
+ oldmask = File.umask
- path = tempfile
+ path = tempfile
- # FIXME this fails on FreeBSD with a mode of 01777
- Puppet::Util.withumask(000) do
- Dir.mkdir(path, 0777)
- end
+ # FIXME this fails on FreeBSD with a mode of 01777
+ Puppet::Util.withumask(000) do
+ Dir.mkdir(path, 0777)
+ end
+
+ assert(File.stat(path).mode & 007777 == 0777, "File has the incorrect mode")
+ assert_equal(oldmask, File.umask, "Umask was not reset")
+ end
+
+ def test_benchmark
+ path = tempfile
+ str = "yayness"
+ File.open(path, "w") do |f| f.print "yayness" end
+
+ # First test it with the normal args
+ assert_nothing_raised do
+ val = nil
+ result = Puppet::Util.benchmark(:notice, "Read file") do
+ val = File.read(path)
+ end
+
+ assert_equal(str, val)
+
+ assert_instance_of(Float, result)
- assert(File.stat(path).mode & 007777 == 0777, "File has the incorrect mode")
- assert_equal(oldmask, File.umask, "Umask was not reset")
end
- def test_benchmark
- path = tempfile
- str = "yayness"
- File.open(path, "w") do |f| f.print "yayness" end
+ # Now test it with a passed object
+ assert_nothing_raised do
+ val = nil
+ Puppet::Util.benchmark(Puppet, :notice, "Read file") do
+ val = File.read(path)
+ end
- # First test it with the normal args
- assert_nothing_raised do
- val = nil
- result = Puppet::Util.benchmark(:notice, "Read file") do
- val = File.read(path)
- end
+ assert_equal(str, val)
+ end
+ end
+
+ def test_proxy
+ klass = Class.new do
+ attr_accessor :hash
+ class << self
+ attr_accessor :ohash
+ end
+ end
+ klass.send(:include, Puppet::Util)
- assert_equal(str, val)
+ klass.ohash = {}
- assert_instance_of(Float, result)
+ inst = klass.new
+ inst.hash = {}
+ assert_nothing_raised do
+ Puppet::Util.proxy klass, :hash, "[]", "[]=", :clear, :delete
+ end
- end
+ assert_nothing_raised do
+ Puppet::Util.classproxy klass, :ohash, "[]", "[]=", :clear, :delete
+ end
- # Now test it with a passed object
- assert_nothing_raised do
- val = nil
- Puppet::Util.benchmark(Puppet, :notice, "Read file") do
- val = File.read(path)
- end
+ assert_nothing_raised do
+ inst[:yay] = "boo"
+ inst["cool"] = :yayness
+ end
- assert_equal(str, val)
- end
+ [:yay, "cool"].each do |var|
+ assert_equal(inst.hash[var], inst[var], "Var #{var} did not take")
end
- def test_proxy
- klass = Class.new do
- attr_accessor :hash
- class << self
- attr_accessor :ohash
- end
- end
- klass.send(:include, Puppet::Util)
-
- klass.ohash = {}
-
- inst = klass.new
- inst.hash = {}
- assert_nothing_raised do
- Puppet::Util.proxy klass, :hash, "[]", "[]=", :clear, :delete
- end
-
- assert_nothing_raised do
- Puppet::Util.classproxy klass, :ohash, "[]", "[]=", :clear, :delete
- end
-
- assert_nothing_raised do
- inst[:yay] = "boo"
- inst["cool"] = :yayness
- end
-
- [:yay, "cool"].each do |var|
- assert_equal(inst.hash[var], inst[var], "Var #{var} did not take")
- end
-
- assert_nothing_raised do
- klass[:Yay] = "boo"
- klass["Cool"] = :yayness
- end
-
- [:Yay, "Cool"].each do |var|
- assert_equal(inst.hash[var], inst[var], "Var #{var} did not take")
- end
- end
-
- def test_symbolize
- ret = nil
- assert_nothing_raised {
- ret = Puppet::Util.symbolize("yayness")
- }
-
- assert_equal(:yayness, ret)
-
- assert_nothing_raised {
- ret = Puppet::Util.symbolize(:yayness)
- }
-
- assert_equal(:yayness, ret)
-
- assert_nothing_raised {
- ret = Puppet::Util.symbolize(43)
- }
-
- assert_equal(43, ret)
-
- assert_nothing_raised {
- ret = Puppet::Util.symbolize(nil)
- }
-
- assert_equal(nil, ret)
- end
-
- def test_execute
- command = tempfile
- File.open(command, "w") { |f|
- f.puts %{#!/bin/sh\n/bin/echo "$1">&1; echo "$2">&2}
- }
- File.chmod(0755, command)
- output = nil
- assert_nothing_raised do
- output = Puppet::Util.execute([command, "yaytest", "funtest"])
- end
- assert_equal("yaytest\nfuntest\n", output)
-
- # Now try it with a single quote
- assert_nothing_raised do
- output = Puppet::Util.execute([command, "yay'test", "funtest"])
- end
- assert_equal("yay'test\nfuntest\n", output)
-
- # Now make sure we can squelch output (#565)
- assert_nothing_raised do
- output = Puppet::Util.execute([command, "yay'test", "funtest"], :squelch => true)
- end
- assert_equal(nil, output)
-
- # Now test that we correctly fail if the command returns non-zero
- assert_raise(Puppet::ExecutionFailure) do
- out = Puppet::Util.execute(["touch", "/no/such/file/could/exist"])
- end
-
- # And that we can tell it not to fail
- assert_nothing_raised do
- out = Puppet::Util.execute(["touch", "/no/such/file/could/exist"], :failonfail => false)
- end
-
- if Process.uid == 0
- # Make sure we correctly set our uid and gid
- user = nonrootuser
- group = nonrootgroup
- file = tempfile
- assert_nothing_raised do
- Puppet::Util.execute(["touch", file], :uid => user.name, :gid => group.name)
- end
- assert(FileTest.exists?(file), "file was not created")
- assert_equal(user.uid, File.stat(file).uid, "uid was not set correctly")
-
- # We can't really check the gid, because it just behaves too
- # inconsistently everywhere.
- # assert_equal(group.gid, File.stat(file).gid,
- # "gid was not set correctly")
- end
-
- # (#565) Test the case of patricide.
- patricidecommand = tempfile
- File.open(patricidecommand, "w") { |f|
- f.puts %{#!/bin/bash\n/bin/bash -c 'kill -TERM \$PPID' &;\n while [ 1 ]; do echo -n ''; done;\n}
- }
- File.chmod(0755, patricidecommand)
- assert_nothing_raised do
- output = Puppet::Util.execute([patricidecommand], :squelch => true)
- end
- assert_equal(nil, output)
- # See what happens if we try and read the pipe to the command...
- assert_raise(Puppet::ExecutionFailure) do
- output = Puppet::Util.execute([patricidecommand])
- end
- assert_nothing_raised do
- output = Puppet::Util.execute([patricidecommand], :failonfail => false)
- end
- end
-
- def test_lang_environ_in_execute
- orig_lang = ENV["LANG"]
- orig_lc_all = ENV["LC_ALL"]
- orig_lc_messages = ENV["LC_MESSAGES"]
- orig_language = ENV["LANGUAGE"]
-
- cleanup do
- ENV["LANG"] = orig_lang
- ENV["LC_ALL"] = orig_lc_all
- ENV["LC_MESSAGES"] = orig_lc_messages
- ENV["LANGUAGE"] = orig_lc_messages
- end
-
- # Mmm, we love gettext(3)
- ENV["LANG"] = "en_US"
- ENV["LC_ALL"] = "en_US"
- ENV["LC_MESSAGES"] = "en_US"
- ENV["LANGUAGE"] = "en_US"
-
- %w{LANG LC_ALL LC_MESSAGES LANGUAGE}.each do |env|
-
- assert_equal(
- 'C',
- Puppet::Util.execute(['ruby', '-e', "print ENV['#{env}']"]),
-
- "Environment var #{env} wasn't set to 'C'")
-
- assert_equal 'en_US', ENV[env], "Environment var #{env} not set back correctly"
- end
-
- end
-
- # Check whether execute accepts strings in addition to arrays.
- def test_string_exec
- cmd = "/bin/echo howdy"
- output = nil
- assert_raise(ArgumentError) {
- output = Puppet::Util.execute(cmd)
- }
- #assert_equal("howdy\n", output)
- #assert_raise(RuntimeError) {
- # Puppet::Util.execute(cmd, 0, 0)
- #}
+ assert_nothing_raised do
+ klass[:Yay] = "boo"
+ klass["Cool"] = :yayness
+ end
+
+ [:Yay, "Cool"].each do |var|
+ assert_equal(inst.hash[var], inst[var], "Var #{var} did not take")
+ end
+ end
+
+ def test_symbolize
+ ret = nil
+ assert_nothing_raised {
+ ret = Puppet::Util.symbolize("yayness")
+ }
+
+ assert_equal(:yayness, ret)
+
+ assert_nothing_raised {
+ ret = Puppet::Util.symbolize(:yayness)
+ }
+
+ assert_equal(:yayness, ret)
+
+ assert_nothing_raised {
+ ret = Puppet::Util.symbolize(43)
+ }
+
+ assert_equal(43, ret)
+
+ assert_nothing_raised {
+ ret = Puppet::Util.symbolize(nil)
+ }
+
+ assert_equal(nil, ret)
+ end
+
+ def test_execute
+ command = tempfile
+ File.open(command, "w") { |f|
+ f.puts %{#!/bin/sh\n/bin/echo "$1">&1; echo "$2">&2}
+ }
+ File.chmod(0755, command)
+ output = nil
+ assert_nothing_raised do
+ output = Puppet::Util.execute([command, "yaytest", "funtest"])
end
+ assert_equal("yaytest\nfuntest\n", output)
+
+ # Now try it with a single quote
+ assert_nothing_raised do
+ output = Puppet::Util.execute([command, "yay'test", "funtest"])
+ end
+ assert_equal("yay'test\nfuntest\n", output)
+
+ # Now make sure we can squelch output (#565)
+ assert_nothing_raised do
+ output = Puppet::Util.execute([command, "yay'test", "funtest"], :squelch => true)
+ end
+ assert_equal(nil, output)
+
+ # Now test that we correctly fail if the command returns non-zero
+ assert_raise(Puppet::ExecutionFailure) do
+ out = Puppet::Util.execute(["touch", "/no/such/file/could/exist"])
+ end
+
+ # And that we can tell it not to fail
+ assert_nothing_raised do
+ out = Puppet::Util.execute(["touch", "/no/such/file/could/exist"], :failonfail => false)
+ end
+
+ if Process.uid == 0
+ # Make sure we correctly set our uid and gid
+ user = nonrootuser
+ group = nonrootgroup
+ file = tempfile
+ assert_nothing_raised do
+ Puppet::Util.execute(["touch", file], :uid => user.name, :gid => group.name)
+ end
+ assert(FileTest.exists?(file), "file was not created")
+ assert_equal(user.uid, File.stat(file).uid, "uid was not set correctly")
+
+ # We can't really check the gid, because it just behaves too
+ # inconsistently everywhere.
+ # assert_equal(group.gid, File.stat(file).gid,
+ # "gid was not set correctly")
+ end
+
+ # (#565) Test the case of patricide.
+ patricidecommand = tempfile
+ File.open(patricidecommand, "w") { |f|
+ f.puts %{#!/bin/bash\n/bin/bash -c 'kill -TERM \$PPID' &;\n while [ 1 ]; do echo -n ''; done;\n}
+ }
+ File.chmod(0755, patricidecommand)
+ assert_nothing_raised do
+ output = Puppet::Util.execute([patricidecommand], :squelch => true)
+ end
+ assert_equal(nil, output)
+ # See what happens if we try and read the pipe to the command...
+ assert_raise(Puppet::ExecutionFailure) do
+ output = Puppet::Util.execute([patricidecommand])
+ end
+ assert_nothing_raised do
+ output = Puppet::Util.execute([patricidecommand], :failonfail => false)
+ end
+ end
+
+ def test_lang_environ_in_execute
+ orig_lang = ENV["LANG"]
+ orig_lc_all = ENV["LC_ALL"]
+ orig_lc_messages = ENV["LC_MESSAGES"]
+ orig_language = ENV["LANGUAGE"]
+
+ cleanup do
+ ENV["LANG"] = orig_lang
+ ENV["LC_ALL"] = orig_lc_all
+ ENV["LC_MESSAGES"] = orig_lc_messages
+ ENV["LANGUAGE"] = orig_lc_messages
+ end
+
+ # Mmm, we love gettext(3)
+ ENV["LANG"] = "en_US"
+ ENV["LC_ALL"] = "en_US"
+ ENV["LC_MESSAGES"] = "en_US"
+ ENV["LANGUAGE"] = "en_US"
+
+ %w{LANG LC_ALL LC_MESSAGES LANGUAGE}.each do |env|
+
+ assert_equal(
+ 'C',
+ Puppet::Util.execute(['ruby', '-e', "print ENV['#{env}']"]),
+
+ "Environment var #{env} wasn't set to 'C'")
+
+ assert_equal 'en_US', ENV[env], "Environment var #{env} not set back correctly"
+ end
+
+ end
+
+ # Check whether execute accepts strings in addition to arrays.
+ def test_string_exec
+ cmd = "/bin/echo howdy"
+ output = nil
+ assert_raise(ArgumentError) {
+ output = Puppet::Util.execute(cmd)
+ }
+ #assert_equal("howdy\n", output)
+ #assert_raise(RuntimeError) {
+ # Puppet::Util.execute(cmd, 0, 0)
+ #}
+ end
end
--
Puppet packaging for Debian
More information about the Pkg-puppet-devel
mailing list